Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an API for the internal CustomStateSet #18

Open
vrugtehagel opened this issue Sep 5, 2024 · 4 comments
Open

Add an API for the internal CustomStateSet #18

vrugtehagel opened this issue Sep 5, 2024 · 4 comments
Labels
enhancement New feature or request

Comments

@vrugtehagel
Copy link
Owner

It's be cool if authors could use e.g.

<meta state="is-checked" as="isChecked">

then component users can use :state(is-checked) and .isChecked for component state. This essentially just creates the isChecked property (a boolean), and is linked to whether or not the CustomStateSet includes the string is-checked. Probably also the readonly attribute should be supported, because authors might not always want to allow component users to modify internal state. Potentially also as should be optional, though it's a tad unclear to me as of now what the expected behavior would be; would the property be omitted altogether or would the created property name match the camelCased state name?

See CustomStateSet on MDN. This is relatively widely supported, only Safari is lagging behind even with ElementInternals.

@vrugtehagel vrugtehagel added the enhancement New feature or request label Sep 5, 2024
@vrugtehagel
Copy link
Owner Author

vrugtehagel commented Sep 6, 2024

For what it's worth, this can be recreated by doing

<meta property="isChecked">

<script>
effect(() => {
  if($.isChecked) internals.states.add('is-checked')
  else internals.states.delete('is-checked')
}, update => update())
</script>

but this is a little more verbose than I'd like (especially for something that should be simple), and it is not self-documenting like e.g. <meta attribute> even though it is a user-facing aspect of the custom element.

@vrugtehagel
Copy link
Owner Author

Potential issue; it is not currently possible to sync the items in internals.states and the individual properties. That is, manually adding or deleting a state through internals.states.add() or internals.states.delete() would completely bypass the live variables and cause them to be out-of-sync; the property would return the wrong thing.

@vrugtehagel
Copy link
Owner Author

Also, another issue; states are not always boolean. Sometimes you'll want e.g. .visibility = 'visible' | 'hidden' or .color = 'red' | 'green' | 'blue', where only one of the options is in the states set at any given time. This is not appropriately expressed by <meta state="name">.

@vrugtehagel
Copy link
Owner Author

Could also be an option to define different sets of states that are then mutually exclusive, like

<meta state="visible, hidden" as="visibility">
<meta state="red, green, blue" as="color">

But this is rather hard to parse (i.e. takes a considerable amount of code and is relatively non-generic) and still does not cater for more complex situations. For example, having enabled, disabled and visible, hidden, and have hidden and disabled to be mutually exlusive but not any other combinations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant