For better or worse, class-fields is pretty much a given. However, it doesn't provide any support for protected access. One of the reasons why is due to the risk of loose scoping that would allow an inheriting class' methods to leak the protected data of a sibling class instance. This problem can be completely mitigated with Symbol-keyed, out-of-line accessors. The idea is that for any pair of base class and subclass, protected field access will follow this convention:
SubClass.#field -> SubClass.[[ProtectedFields]][fieldSymbol] -> BaseClass.[[ProtectedFields]].field
where [[ProtectedFields]] is an instance-bound object attached to each class instance, and containing protected fields/methods/accessors for the owning class and only accessors for the subclasses. Since leaking would be possible if SubClass instances had direct access to protected members of BaseClass, subclass instances of bases with protected data will contain private accessors that reference a symbol-keyed accessors in their [[ProtectedFields]], which in turn will reference the base class' field.
Since the subclass will use a class-unique symbol to refer to a protected field, it will be impossible for a sibling of the subclass to leak the protected data of the subclass.
An example of the logic to perform this using ES6 code exists here.