bug: attachInternals should be usable without formAssociated
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 report this problem, without success.
Stencil Version
4.33
Current Behavior
@AttachInternals() internals!: ElementInternals;
cannot be used without
formAssociated: true in the metadata.
because of a condition in the compiler
Expected Behavior
@AttachInternals() internals!: ElementInternals;
should work without formAssociated: true in the metadata.
CustomStateSet can now be used without formAssociated for components that are not formAssociated.
Future improvement: Add stencil support for custom state / :state().
System Info
Steps to Reproduce
add
@AttachInternals() internals!: ElementInternals;
to a component, an console error will be shown
Code Reproduction URL
Additional Information
Will commit a fix for it, the solution is quite easy: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/attachInternals
@pfteter looking at the code I think the original author wanted to ensure that element internals can only be accessed when the formAssociated flag is set. Can you point to references that state the opposite?
I will formulate it differently:
How can I use/ add a custom state(CustomStateSet / :state()) to a component that is not a form component without associating it with a form in stencil so that it does't throws an error in the console ?
https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet
CustomStateSet / CSS :state() is quite a new thing for custom elements where you don't need to use class or {reflect: true} to style or a component.
forms are just one use case for the technology. I guess at the time the code was written there was only formAssociated that was used with attachInternals().
attachInternals() is just a JS technology that enables formAssociated but it's not exclusive to it.
Here is a nice example in the html living standard for the usage of attachInternals without formAssociated: https://html.spec.whatwg.org/multipage/custom-elements.html#exposing-custom-element-states
for custom elements state.
That is also the use case I need it for. I don't want to make my component to be a form component since it's not one.
Sorry I don't have a w3c or whatwg reference that explicitly says it but I have references to w3c and whatwg where it's used without it.
Another example is the AOM(Accessibility Object Model): https://wicg.github.io/aom/demos
see slide 22: https://wicg.github.io/aom/demos/#22
References: https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet#matching_the_custom_state_of_a_custom_checkbox_element https://w3c.github.io/webcomponents-cg/2022.html#initial-api-summary-quick-api-proposal-6
Not a trustful reference but still a reference (google):
A followup would be better integration of CustomStateSet
up until now we used something like
@Prop({reflect: true})
active: boolean;
and then you style the component like :host([active]) { }
but basically what you want to do is to use a CustomStateSet and style it with :state()
@Prop({state: true})
active: boolean;
:host(:state(active)) {
}
or maybe better
@CustomState()
active: boolean;
or
@State({custom: true})
active: boolean;
Gives more flexibility so it doesn't have to be defined from the outside although {state: true} is a handy shortcut because it's commonly used like that.
Some custom state examples for a custom component: clickable, disabled, readonly, active, selectable, sortable, dense, required, recommended, variant? ....
But in both cases we probably need a proxy around it, also as soon as a single CustomSate is defined to have attachInternals initialized.
If that makes sense to you, I would maybe try to contribute the state Prop syntax, should not be hard guided by the reflect:true ?
@pfteter thank you for providing more context on this manner. Your references clearly show examples of using element internals outside of any form association. I think it makes sense to open up this feature for that as well. I commented on your PR. Let's continue convo there.
@christian-bromann Thank you, I will have some time next week to implement the comments
@christian-bromann Closing this one