feat: Symbol properties
Prerequisites
- [X] I have read the Contributing Guidelines.
- [X] I agree to follow the Code of Conduct.
- [X] I have searched for existing issues that already include this feature request, without success.
Describe the Feature Request
Symbol properties are a great way to have a publicly available private API.
The value of a Symbol property can only be set by those who have access to the Symbol reference. This way you could control who would be able to set certain properties.
Describe the Use Case
This feature would be great for design systems, particularly in composition scenarios where the author needs to make component adjustments that regular consumers should not have the ability to perform.
For example: to ensure brand consistency, colors and spacings must remain unchanged. Similarly, for accessibility considerations, labels or specific ARIA attributes must remain unchanged. But, when the author is creating more complex, composite components, they may need to make specific adjustments that should otherwise not be possible (at least through a public API).
Describe Preferred Solution
The ideal solution would be if @Prop could accept Symbols. See the code snippets below.
// foo-element.tsx
import { h, Component } from '@stencil/core';
import { mySymbol } from '../my-private-symbol';
@Component({
tag: 'foo-element',
shadow: true,
})
export class FooElement {
render() {
const props = { [mySymbol]: 'world' };
return <bar-element {...props}></bar-element>;
}
}
// bar-element.tsx
import { h, Component, Prop } from '@stencil/core';
import { mySymbol } from '../my-private-symbol';
@Component({
tag: 'bar-element',
shadow: true,
})
export class BarElement {
@Prop() public [mySymbol]: string;
render() {
return <div>Hello {this[mySymbol]}</div>;
}
}
In short:
- Both components import the same Symbol
- Component 1 (foo-element) assigns a Symbol property to bar-element with the value
world. - Component 2 (bar-element) renders
Helloand the Symbol property, resulting inHello world.
Describe Alternatives
An alternative is a "symbol" property for @Prop's PropOptions.
export class BarElement {
@Prop({ symbol: mySymbol }) public myProperty: string;
render() {
return <div>Hello {this.myProperty}</div>;
}
}
Pros:
- Prevents a dynamic property name (just in case that would be a technical challenge for this feature request).
- The property looks nicer in the template.
Cons:
- It's confusing. You could think you'd have to assign your value to
myProperty, which is incorrect. - More magic. The preferred solution stays close to the platform.
Related Code
No response
Additional Information
No response