stencil icon indicating copy to clipboard operation
stencil copied to clipboard

bug: attachInternals should be usable without formAssociated

Open pfteter opened this issue 8 months ago • 5 comments

Prerequisites

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 avatar Jun 10 '25 12:06 pfteter

@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?

christian-bromann avatar Jun 10 '25 18:06 christian-bromann

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): Image

pfteter avatar Jun 11 '25 05:06 pfteter

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 avatar Jun 11 '25 06:06 pfteter

@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 avatar Jun 11 '25 17:06 christian-bromann

@christian-bromann Thank you, I will have some time next week to implement the comments

pfteter avatar Jun 16 '25 07:06 pfteter

@christian-bromann Closing this one

pfteter avatar Jun 25 '25 18:06 pfteter