html
html copied to clipboard
Define :user-invalid / :user-valid for form-associated custom elements
#9047 omitted defining the pseudos for FACE. Perhaps a new ElementInternals
state is needed here?
See also #8938.
I think we pretty much have to expose a way to set "user interacted". But that also means we need some kind of opt-in for setting that unless we're okay with existing form-associated custom elements never matching :user-valid
and :user-invalid
. Maybe we are?
cc @mfreed7 @smaug---- @emilio
I would propose ElementInternals.setUserInteracted()
along with a getter. Then the selector matching would function like other form controls by checking both the validity and that flag.
Not sure. Could it possibly happen automatically as part of focusing? It feels rather error prone if one needs to remember to explicitly call setUserInteracted() - FACE would always need to have a listener for focus which calls setUserInteracted().
Focus isn't representative of the user interacted flag. I would say the change event is more accurate. Potentially the flag could be set on that event, but not sure the developer would expect it.
I think that's why it needs a separate opt-in. We need to know if you want to participate in this mechanism. I suppose we could also make it a tri-state:
-
internals.userInteracted = "auto" | "true" | "false"
auto
is a good idea in theory, however, I'm concerned it's really a fake "auto" if the behavior can't be updated later on for compat reasons.
If you control a custom element presumably you can update it to use the other values (which would then influence matching)? I suppose your consumers might not expect the change, but that's not really something we can concern ourselves with.
@annevk is there any progress on this i just walked into this issue with implementing FACE I'm seeing it working with :valid and :invalid but not yet with :user-valid and :user-invalid I was already thinking of implementing pseudo-states but since that is also not supported everywere that doesn't help much
one lingering question i have is these combined states are very tailored towards a combination of states (inspired by good old angularjs): dirty/pristine, touched/untouched, and valid/invalid If one would be able to read these one could also determine the state user-valid / user-invalid. Wouldn't that be a more flexible solution in the long run?
I think that's what https://github.com/whatwg/html/issues/9639#issuecomment-1723223481 suggests, no?
WebKit is in principle okay with doing something here, but other browsers haven't weighed in much.
It feels rather error prone if one needs to remember to explicitly call setUserInteracted() - FACE would always need to have a listener for focus which calls setUserInteracted().
I agree, I don't really see the value in supporting :user-valid
/:user-invalid
if you have to do this. At that point, you could create your own css custom state selector for your custom element and use that instead. Maybe :user-valid
/:user-invalid
is better than custom state selectors, but it seems like the same thing.
If there is a good way for the user agent to know if there was any interaction inside the custom element that sounds preferable, but I'm not sure what that would be.
I think the value in supporting :user-valid
/ :user-invalid
is the same as with supporting :disabled
and others. In that the web developers that end up using the form-associated custom elements get a consistent API surface across them and built-in elements.
Good point. I suppose that if we just have to add something to ElementInternals, then it should be pretty easy to implement