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 beforeopen, afteropen, beforeclosed, and afterclosed events? #8386

Closed
mfreed7 opened this issue Oct 13, 2022 · 7 comments
Closed

Add beforeopen, afteropen, beforeclosed, and afterclosed events? #8386

mfreed7 opened this issue Oct 13, 2022 · 7 comments
Labels
topic: popover The popover attribute and friends

Comments

@mfreed7
Copy link
Contributor

mfreed7 commented Oct 13, 2022

The CSSWG recently resolved to add :open and :closed pseudo classes. These will apply to anything that can open/close, which includes <dialog>, <details>, and <select>, and also the pop-up API (see DOM and html PRs). For the pop-up API, there is a need for events that fire when these states change. In OpenUI, we recently discussed the naming for these events, and resolved that we'd prefer to make this a more general set of events that should apply to anything that can be "open"/"closed".

For the pop-up API, there is only the need for events that happen before the state changes, and interestingly only the "opening" event is cancelable. However, in the general case, it would seem that we should add four events, two for before/after the state changes to "open" and two for "closed".

Thoughts? Are there precedents, suggestions, or requirements for the naming of these four events?

@domenic domenic transferred this issue from whatwg/dom Oct 14, 2022
@domenic
Copy link
Member

domenic commented Oct 14, 2022

General thoughts:

The main question is how this integrates with the existing events that exist for these controls: toggle on <details>, and cancel + close on <dialog>. Particularly, you'll want to look at the timing of each of those, and how they're named.

I'm also a bit unsure on the use case for such events on <select>.

Finally, it's worth looking at whether you need distinct events for opening and closing, or if a single event plus consulting event.target.something is good enough.

@mfreed7 mfreed7 mentioned this issue Oct 21, 2022
3 tasks
@mfreed7
Copy link
Contributor Author

mfreed7 commented Nov 8, 2022

Strawperson proposal:

  • duringopenclose - fired "when" an element transitions from open to closed or vise versa. This event does not bubble. This event is sometimes cancelable and sometimes not, depending on the element. The exact event timing also depends on the element.
  • afteropenclose - always fired asynchronously (queued on the User Interaction task queue) after an element transitions from open to closed or vise versa. This event does not bubble, and is not cancelable.

This would be intended to be used on anything supporting :open or :closed pseudo classes, including:

  • <details>. This element already fires the toggle event, asynchronously, after the open attribute has changed state. The afteropenclose event would be queued immediately after the toggle event. Because the trigger is the changing of an attribute, the duringopenclose event would be fired asynchronously in this case, and would be queued before the toggle event. All three events would be queued from here. The duringopenclose event would never be cancelable.
  • <dialog>. This element already fires asynchronous cancel and close events, after the open attribute has changed state. The duringopenclose event would be fired from close the dialog and whenever the open attribute is directly changed, and would never be cancelable. The afteropenclose event would be queued after the close event (which is already queued after the cancel event, if fired).
  • <select> and <selectmenu>. (The desire to support these is discussed here and here, respectively.) These elements do not currently fire events when the open/closed state changes. The duringopenclose event would be fired when the element is activated, and would not be cancelable. The afteropenclose event would be queued after the control is activated. For <selectmenu> it is possible that the duringopenclose event could be made cancelable, and could re-use the timing from the Popover API.
  • The Popover API. The explainer for this feature discusses show/hide events (and is waiting for a PR to land to rename these). The events listed there would correspond naturally to the duringopenclose event described here. The afteropenclose event would be queued at the point when the :open pseudo selector begins to match, as discussed in the animation section.

@domenic
Copy link
Member

domenic commented Nov 8, 2022

Am I understanding that the proposal is to add a sync mutation event (duringopenclose) for <details> and <dialog> attribute changes? That seems like a really bad idea, for all the usual reasons sync mutation events are a bad idea...

@mfreed7
Copy link
Contributor Author

mfreed7 commented Nov 8, 2022

Am I understanding that the proposal is to add a sync mutation event (duringopenclose) for <details> and <dialog> attribute changes? That seems like a really bad idea, for all the usual reasons sync mutation events are a bad idea...

No, because those are triggered by attribute changes, they should be async. I said that for <details>, but I guess I left it ambiguous for <dialog>. But async. I think perhaps select and certainly popover can be sync for that event.

@domenic
Copy link
Member

domenic commented Nov 8, 2022

Hmm, OK.

Can you state more about the use cases for these? For example:

  • Why introduce two new events, instead of reusing the cancel (for cancelable) and toggle (for non-cancelable after the fact) events?

  • Why do we need two? Is it just so that the first one can be cancelable?

  • In general, what kind of example code would use each? How would such example code compare to using the existing events?

@mfreed7
Copy link
Contributor Author

mfreed7 commented Nov 8, 2022

  • Why introduce two new events, instead of reusing the cancel (for cancelable) and toggle (for non-cancelable after the fact) events?

This feels uber-confusing when the trigger for the event is that a popover is going to be shown. That event, for popover at least, is a) cancelable, and b) synchronous before the element is shown. Using addEventListener('cancel') for that feels wrong.

  • Why do we need two? Is it just so that the first one can be cancelable?

The intention of two was for one to be "before" and one "after". However, in writing out the behavior for the existing elements, it looks like perhaps the only place where that makes any sense is for Popover, where there even is the concept of "before" and "after" in a clean way.

  • In general, what kind of example code would use each? How would such example code compare to using the existing events?

The concept and examples I can think of are all Popover-related. For example, in the "hidden"->"show" transition, before the transition, use duringopenclose to load up content for the popover. And after the popover is shown, use afteropenclose to capture metrics that the popover has been shown. Candidly there aren't great use cases for afteropenclose even for Popover.

Generally, I'm beginning to get the feeling that we might want to just go back to popovershow and popoverhide, specific to Popover, and not try to add more general events. They feel like they might just add confusion without adding value to the other elements.

@annevk
Copy link
Member

annevk commented Feb 16, 2023

We settled on beforetoggle and toggle in 78551f6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: popover The popover attribute and friends
Development

No branches or pull requests

3 participants