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 new and update existing popover api docs #26413

Merged
merged 20 commits into from
May 3, 2023

Conversation

chrisdavidmills
Copy link
Contributor

@chrisdavidmills chrisdavidmills commented Apr 25, 2023

Description

The Popover API is going to be available in Chrome 114. I've had this confirmed by the relevant engineers, and it is also reflected by the platform status entry: https://chromestatus.com/feature/5463833265045504.

See my research document for further details of what has been added in this PR.

Notes for followup:

  • In the main landing page, I have made mention of the current state of animation for popovers. AFAIK, this work is still underway at the CSSWG/Chrome, so we'll need to update this information once a resolution is available.
  • I created an example to demonstrate using nested popovers, but I'm not happy with it, and think there must be a cleaner, easier way to do this. Advice much appreciated!

@keithamus already did a bunch of fabulous work towards getting this documented. I've updated a few of your pages mate, to tweak wording and add some examples, but what was there was already pretty good. Nice job.

Motivation

Additional details

Related issues and pull requests

Related PRs:

@chrisdavidmills chrisdavidmills requested review from a team as code owners April 25, 2023 14:01
@chrisdavidmills chrisdavidmills requested review from wbamberg, schalkneethling, estelle and bsmth and removed request for a team April 25, 2023 14:01
@github-actions github-actions bot added Content:CSS Cascading Style Sheets docs Content:Glossary Glossary entries Content:HTML Hypertext Markup Language docs Content:WebAPI Web API docs labels Apr 25, 2023
@github-actions
Copy link
Contributor

github-actions bot commented Apr 25, 2023

Preview URLs (29 pages)
Flaws (81)

Note! 16 documents with no flaws that don't need to be listed. 🎉

URL: /en-US/docs/Web/CSS/:popover-open
Title: :popover-open
Flaw count: 1

  • bad_bcd_queries:
    • No BCD data for query: css.selectors.popover-open

URL: /en-US/docs/Web/API/HTMLButtonElement
Title: HTMLButtonElement
Flaw count: 16

  • macros:
    • /en-US/docs/Web/API/HTMLButtonElement/accessKey does not exist
    • /en-US/docs/Web/API/HTMLButtonElement/autofocus does not exist
    • /en-US/docs/Web/API/HTMLButtonElement/form does not exist
    • /en-US/docs/Web/API/HTMLButtonElement/formAction does not exist
    • /en-US/docs/Web/API/HTMLButtonElement/formEnctype does not exist
    • and 11 more flaws omitted

URL: /en-US/docs/Web/API/HTMLButtonElement/popoverTargetAction
Title: HTMLButtonElement: popoverTargetAction property
Flaw count: 1

  • bad_bcd_queries:
    • No BCD data for query: api.HTMLButtonElement.popoverTargetAction

URL: /en-US/docs/Web/API/HTMLButtonElement/popoverTargetElement
Title: HTMLButtonElement: popoverTargetElement property
Flaw count: 1

  • bad_bcd_queries:
    • No BCD data for query: api.HTMLButtonElement.popoverTargetElement

URL: /en-US/docs/Web/API/HTMLInputElement
Title: HTMLInputElement
Flaw count: 45

  • macros:
    • /en-US/docs/Web/API/HTMLInputElement/align does not exist
    • /en-US/docs/Web/API/HTMLInputElement/autocapitalize does not exist
    • /en-US/docs/Web/API/HTMLInputElement/defaultValue does not exist
    • /en-US/docs/Web/API/HTMLInputElement/dirName does not exist
    • /en-US/docs/Web/API/HTMLInputElement/inputmode does not exist
    • and 40 more flaws omitted

URL: /en-US/docs/Web/API/HTMLInputElement/popoverTargetAction
Title: HTMLInputElement: popoverTargetAction property
Flaw count: 1

  • bad_bcd_queries:
    • No BCD data for query: api.HTMLInputElement.popoverTargetAction

URL: /en-US/docs/Web/API/HTMLInputElement/popoverTargetElement
Title: HTMLInputElement: popoverTargetElement property
Flaw count: 1

  • bad_bcd_queries:
    • No BCD data for query: api.HTMLInputElement.popoverTargetElement

URL: /en-US/docs/Web/API/HTMLElement
Title: HTMLElement
Flaw count: 9

  • macros:
    • /en-US/docs/Web/API/HTMLElement/attributeStyleMap does not exist
    • /en-US/docs/Web/API/HTMLElement/draggable does not exist
    • /en-US/docs/Web/API/HTMLElement/noModule does not exist
    • /en-US/docs/Web/API/HTMLElement/properties does not exist
    • /en-US/docs/Web/API/HTMLPropertiesCollection does not exist
    • and 4 more flaws omitted

URL: /en-US/docs/Web/API/ToggleEvent
Title: ToggleEvent
Flaw count: 1

  • bad_bcd_queries:
    • No BCD data for query: api.ToggleEvent

URL: /en-US/docs/Web/API/ToggleEvent/oldState
Title: ToggleEvent: oldState property
Flaw count: 1

  • bad_bcd_queries:
    • No BCD data for query: api.ToggleEvent.oldState

URL: /en-US/docs/Web/API/ToggleEvent/newState
Title: ToggleEvent: newState property
Flaw count: 1

  • bad_bcd_queries:
    • No BCD data for query: api.ToggleEvent.newState

URL: /en-US/docs/Web/API/ToggleEvent/ToggleEvent
Title: ToggleEvent: ToggleEvent() constructor
Flaw count: 1

  • bad_bcd_queries:
    • No BCD data for query: api.ToggleEvent.ToggleEvent

URL: /en-US/docs/Web/HTML/Element/input
Title: <input>: The Input (Form Input) element
Flaw count: 2

  • macros:
    • /en-US/docs/Web/API/ValidityState/valid does not exist
    • /en-US/docs/Web/API/ValidityState/customError does not exist
External URLs (11)

URL: /en-US/docs/Web/API/Popover_API
Title: Popover API


URL: /en-US/docs/Web/API/Popover_API/Using
Title: Using the Popover API


URL: /en-US/docs/Web/HTML/Global_attributes/popover
Title: popover

(comment last updated: 2023-05-02 09:12:41)

@wbamberg
Copy link
Collaborator

Looking at this today.

Copy link
Collaborator

@wbamberg wbamberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for the Popover API overview page.

files/en-us/web/api/popover_api/index.md Outdated Show resolved Hide resolved
files/en-us/web/api/popover_api/index.md Outdated Show resolved Hide resolved

The **Popover API** provides developers with a standard, consistent, flexible mechanism for displaying popover content on top of other page content. Popover content can be controlled either declaratively using HTML attributes, or via JavaScript.

## Concepts and usage
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really nice guide, but I think it would be better to put 90% of it in a separate page "Using the Popover API", and keep this section much shorter. I think these overview pages need to function well as a quick way to get an overview of the pieces of the API, and with a long guide section at the start it's much harder to get that sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, agreed. In the next commit I've broken it out into a separate page.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks so good like this!

<div id="mypopover" popover>Popover content</div>
```

You can see how the previous code snippet renders in our [Basic declarative popover example](https://mdn.github.io/dom-examples/popover-api/basic-declarative/).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can see how the previous code snippet renders in our [Basic declarative popover example](https://mdn.github.io/dom-examples/popover-api/basic-declarative/).
You can see how the previous code snippet renders in our [Basic declarative popover example](https://mdn.github.io/dom-examples/popover-api/basic-declarative/) ([source](https://github.com/mdn/dom-examples/tree/main/popover-api/basic-declarative)).

(and the same for all the other very helpful examples in this guide)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really good call Will, thanks! I've added source links for all of them, in my next commit.

files/en-us/web/api/popover_api/index.md Outdated Show resolved Hide resolved
});
```

See our [Toggle help UI example](https://mdn.github.io/dom-examples/popover-api/toggle-help-ui/) to see the popover JavaScript properties, feature detection, and `togglePopover()` method in action.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I know the code above shows this, but when I opened https://mdn.github.io/dom-examples/popover-api/toggle-help-ui/ I couldn't figure out what the point of the example was - it just looked like a declarative example. It was only when I looked at the source code that I realised pressing "h" also opened the popup!

So maybe include a bit in the page like "Press "h" to get help", so people know what to do. And maybe even omit the button entirely?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I totally agree with adding the help text, but I don't want to omit the button entirely because it is central to demonstrate adding the declarative attributes with JS. I've added the help text in a separate PR, which I'll @-mention you in

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


See our [Toggle help UI example](https://mdn.github.io/dom-examples/popover-api/toggle-help-ui/) to see the popover JavaScript properties, feature detection, and `togglePopover()` method in action.

Anoher common pattern in JavaScript is dismissing popovers automatically after a certain amount of time. You might for example want to create a system of "toast" notifications, where you have multiple actions underway at a time (for example multiple files uploading), and want to show a notification when each one succeeds or fails. For this you'll want to use manual popovers so you can show several at the same time, and use {{domxref("setTimeout")}} to remove them. A function for handling such popovers might look like so:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe consider another H3 for this section? It's a very helpful technique but won't be that easy to find, if people are thinking "I know I saw a technique for auto-hiding popups on a timer" and scanning the page. You'd have to change the previous H3 "Controlling popovers with JavaScript" to be more specific, like "Showing popups from JavaScript" or something.

Just a suggestion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I totally agree. New heading added, and previous heading updated.

files/en-us/web/api/popover_api/index.md Outdated Show resolved Hide resolved
files/en-us/web/api/popover_api/index.md Outdated Show resolved Hide resolved
files/en-us/web/api/popover_api/index.md Outdated Show resolved Hide resolved

- `"auto"`: In [auto state](/en-US/docs/Web/API/Popover_API#auto_state_and_light_dismiss):
- The popover can be "light dismissed" — this means that you can hide the popover by clicking outside it or pressing the <kbd>Esc</kbd> key.
- Only one popover can be shown at a time — showing a second popover when one is already shown will hide the first one.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth adding additional clarification here; if there are nested popover elements, or in certain situations when an invoker is within another popover, then there can be multiple popovers open. An example use case could be nested menus.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call, thanks Keith. I've added this in my next commit.

Copy link

@mfreed7 mfreed7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks awesome! Thanks for putting it all together. I've left a number of comments, but overall this looks good. I'd hit "Approve" if I had the permissions.

- `"show"`
- : The button will show a hidden popover. If you try to show an already showing popover, no action will be taken.
- `"toggle"`
- : The button will toggle a popover between showing and hidden. If the popover is hidden, it will be shown; If the popover is showing, it will be hidden.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the last "If the popover" doesn't need "If" to be capitalized.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks; I've updated this on both the button and input DOM object pages.


{{ APIRef("DOM") }}{{SeeCompatTable}}

The **`popoverTargetAction`** property of the {{domxref("HTMLButtonElement")}} interface gets and sets the action to be performed (`"hide"`, `"show"`, or `"toggle"`) on a popover element being controlled by a control button.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this section say, somewhere, that the default value is "toggle"? And maybe that you therefore don't need the attribute if you just want "toggle" behavior?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really good point; I have made sure that the default action is made clear in the main landing page, property pages, and equivalent HTML attribute sections


When `hidePopover()` is called on an element with the [`popover`](/en-US/docs/Web/HTML/Global_attributes/popover) attribute that is currently open, then a {{domxref("HTMLElement/beforetoggle_event", "beforetoggle")}} non-cancelable event will be fired, followed by the popover closing, and a {{domxref("HTMLElement/toggle_event", "toggle")}} event will be fired. If the element is already closed, then nothing will happen.
When `hidePopover()` is called on an showing element with the [`popover`](/en-US/docs/Web/HTML/Global_attributes/popover) attribute, a {{domxref("HTMLElement/beforetoggle_event", "beforetoggle")}} event will be fired, followed by the popover being hidden, and then the {{domxref("HTMLElement/toggle_event", "toggle")}} event firing. If the element is already hidden, an error is thrown.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: s/on an showing/on a showing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, fixed

popover.hidePopover();
} else {
popover.showPopover();
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe ok as-is, but this example feels like one where you'd rather use popover.togglePopover() and avoid the complexity? Maybe just remove the case containing hidePopover() and make the example only show the popover?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I've updated the examples on the showPopover() and hidePopover() pages to just show / hide, not toggle.


- `"auto"`: In [auto state](/en-US/docs/Web/API/Popover_API#auto_state_and_light_dismiss):
- The popover can be "light dismissed" — this means that you can hide the popover by clicking outside it or pressing the <kbd>Esc</kbd> key.
- Only one popover can be shown at a time — showing a second popover when one is already shown will hide the first one.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

@@ -10,11 +10,15 @@ browser-compat: api.HTMLElement.togglePopover

{{ APIRef("HTML DOM") }}{{SeeCompatTable}}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this page is missing documentation of the force parameter: https://html.spec.whatwg.org/multipage/popover.html#dom-togglepopover

You can do this:

p.togglePopover(true); // Show the popover, or do nothing if already showing
p.togglePopover(false); // Hide the popover, or do nothing if already hidden

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah crap, I missed that one! Thanks for the info; I've added it to the page now.


See our [Popover blur background example](https://mdn.github.io/dom-examples/popover-api/blur-background/) for an idea of how this renders.

Finally, animation needs a special mention, as a lot of people are going to want to animate popovers between hosing and hiding. As it stands, [a few updates to CSS behavior](https://open-ui.org/components/popover.research.explainer/#animation-of-popovers) are required to get popovers to be animatable, most notably enabling animation of elements as they move to and from `display: none`. We'll update this article as soon as animation is available for popovers.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you can "hose" a popover, so maybe "showing"? 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha, everyone loves a comedy typo. Fixed now ;-)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know why, but I laughed out loud for a while with this one. So yeah, thanks. 😄

@@ -7,7 +7,9 @@ browser-compat: api.ToggleEvent

{{APIRef("UI Events")}}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the toggle event is "coalesced" meaning if multiple of them are fired before the event loop has a chance to cycle, only a single toggle event will be fired. (Spec is here.) And in that case, the interpretation of the oldState and newState parameters is... interesting.

I say this for your information. It might be too much information to include on MDN. Then again, a developer encountering this behavior might wish it was here.

The example is:

p.addEventListener('toggle',()=>{});
p.showPopover();
p.hidePopover();
// `toggle` only fires once

(I didn't verify the above example, but it should be true.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is worth including, but I've included it on the pages for the HTMLElement beforetoggle/toggle events, as I think it is more useful there. Added.

- {{HTMLElement("dialog")}} elements that have been shown in the top layer via a {{domxref("HTMLDialogElement.showModal()")}} call.
- {{domxref("Popover API", "Popover", "", "nocode")}} elements that have been shown in the top layer via a {{domxref("HTMLElement.showPopover()")}} call.

When multiple elements have been placed into the top layer, the backdrop is drawn immediately beneath the frontmost such element, and on top of the older elements.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, each element in the top layer has its own ::backdrop pseudo element, and all are rendered.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've modified the wording on this page a bit to try to make this more precise, in the next commit. Let me know if you think it's better now.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally clear now - thanks!


### Nested popovers

There is an exception to the rule about not displaying multiple auto popovers at once — when they are nested inside one another. In such cases, multiple popovers are allowed to both be open at the same time, due to their relationship with each other. This pattern is supported to enable use cases such as nested popover menus.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this could use a bit more detail about how popovers can be nested. There are three ways:

  1. Direct DOM descendants:
<div popover>Parent
  <div popover> Child </div>
</div>
  1. Via invoking elements:
<div popover> Parent
  <button popovertarget=foo>Click me</button>
</div>

<div popover id=foo> Child </div>
  1. Via the anchor attribute:
<div popover id=foo> Parent </div>

<div popover anchor=foo> Child </div>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, good call. I've added this.

@github-actions
Copy link
Contributor

This pull request has merge conflicts that must be resolved before it can be merged.

@github-actions github-actions bot added the merge conflicts 🚧 [PR only] label Apr 29, 2023
Co-authored-by: wbamberg <will@bootbonnet.ca>
chrisdavidmills and others added 8 commits May 1, 2023 15:29
Co-authored-by: wbamberg <will@bootbonnet.ca>
Co-authored-by: wbamberg <will@bootbonnet.ca>
Co-authored-by: wbamberg <will@bootbonnet.ca>
Co-authored-by: wbamberg <will@bootbonnet.ca>
Co-authored-by: wbamberg <will@bootbonnet.ca>
Co-authored-by: wbamberg <will@bootbonnet.ca>
Co-authored-by: wbamberg <will@bootbonnet.ca>
@github-actions github-actions bot removed the merge conflicts 🚧 [PR only] label May 1, 2023
Copy link
Collaborator

@wbamberg wbamberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I've now read the rest of it.

Comment on lines 24 to 25
- [Cascade layers](/en-US/docs/Learn/CSS/Building_blocks/Cascade_layers#creating_layers)
- {{cssxref("@layer")}}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't cascade layers a different thing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hrm, I thought from what I'd read that the top layer was effectively an auto-generated cascade layer, but I'm not so sure now. I've deleted the last two links to be on the safe side.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to confirm: top layer and cascade layers are definitely independent things.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, thanks. I'll do some more reading in that area to make sure I don't get confused again.

@@ -19,6 +19,8 @@ it's now in full screen mode. If permission is denied, the promise is rejected a
element receives a {{domxref("Element/fullscreenerror_event", "fullscreenerror")}} event instead. If the element has been
detached from the original document, then the document receives these events instead.

> **Note:** It is possible to put a {{domxref("Popover_API", "popover", "", "nocode")}} element (for example `<div popover>...</div>`) into fullscreen mode. However, if you try to call `requestFullscreen()` on a popover that is already being shown in the top layer (via {{domxref("HTMLElement.showPopover()")}}), the promise will reject, because the behavior doesn't make sense in that context.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should include this here: it's documented under Exceptions, which is the canonical place it should be documented.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK; removed

{{cssxref('::backdrop')}} pseudo-element. Interaction outside the dialog is blocked and
the content outside it is rendered inert.

> **Note:** It is possible to create a {{htmlelement("dialog")}} element that is also a {{domxref("Popover_API", "popover", "", "nocode")}}, i.e. `<dialog popover>...</dialog>`. However, if you try to call `showModal()` on a popover that is already being shown in the top layer (via {{domxref("HTMLElement.showPopover()")}}), the call with fail, because the behavior doesn't make sense in that context.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again I think it is better just to document this once, in Exceptions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, removed. In both this case and requestFullscreen(), I've linked the word "popover" to the Popover API landing page, so that readers can find out more info if they are confused as to what a popover is.

Comment on lines 19 to 20
- If the popover/`<details>` element is currently hidden/closed, the `event.oldState` property will be set to `closed` and the `event.newState` property will be set to `open`.
- If the popover/`<details>` element is currently showing/open, then `event.oldState` will be `open` and `event.newState` will be `closed`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is technically wrong, though, (isn't it?) because the event is fired after the element has transitioned, so if it is "currently" hidden, then its new state will be closed. Maybe instead something like: "If the element is transitioning from hidden to showing, then ..." would be clearer? Could do something similar for beforetoggle, for consistency.

Copy link
Collaborator

@wbamberg wbamberg May 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I can't comment below but it appears as if, when this event is fired on a <details> element, the object is just an Event, and it is only a ToggleEvent when the element is a popover. See https://codepen.io/willbamberg/pen/oNaGBQZ?editors=1011. I think we'll need to explain that here (and in beforetoggle I assume).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I agree with the wording in the bullets, so I've updated those.

For the difference between toggle on <details> and toggle on all other elements, I've actually made the decision to remove all mention of <details> on this page, and instead just add notes to this, and the HTMLDetailsElement.toggle_event pages, explaining that there are two versions, and what the difference is between them. I thought this made more sense, as they are two separate implementations.

And none of this applies to beforetoggle; that was specified purely for the Popover API and has nothing to do with <details>. You can see that from the definitions at https://html.spec.whatwg.org/multipage/indices.html#event-beforetoggle

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intention for the events fired on <details> is that they’re identical to the new stuff for popover. That hasn’t been implemented in browsers yet though. So I’m not sure how MDN likes to handle that situation. But the eventual goal is to align them, in spec and implementation. I guess it’s best to wait for that to become reality though, before documenting it.

I do like the suggestion on wording. The reason we went with oldState and newState was to clear up ambiguity about timing. Sometimes the event comes before the change and sometimes after, so old/new tells you which way the transition went, whenever it happened.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think it will make sense to wait until that's reality. But we can always make more updates at a later date. When the time comes let Rachel know, so it gets added to my work spreadsheet ;-)

});
```

This example illustrates the use of {{domxref("Element.matches()")}} to programmatically check whether a popover is currently showing ({{cssxref(":popover-open")}} selects only showing popovers). This is currently the only way. Alternatively, you could cut out the need for it altogether by :
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, but wouldn't it be better to use a realistic example for them, rather than one whose purpose is immediately undermined? For instance, you could demo showPopover() and hidePopover() with different keyboard shortcuts for showing and hiding, and togglePopover() with a single shortcut for toggling.

```

### Parameters

None.
- `force`
- : A boolean, which causes `togglePopover()` to behave like {{domxref("HTMLElement.showPopover", "showPopover()")}} or {{domxref("HTMLElement.hidePopover", "hidePopover()")}}:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth emphasising the difference (as I read it) - that this version does not throw if the popover is already in the target state.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call; I've added wording to cover this.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side note: there’s a spec PR up now to change the exceptions for showPopover and hidePopover so they don’t throw if the popover is already in the desired state.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, we can make that change when it is in browsers.

I did have to ask though —that would make the behavior exactly the same as togglePopover() with force set. So what is the purpose of it?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The force parameter was basically added to make it parallel to this API. And the change to showPopover/hidePopover was because people thought exceptions were too much, partly because querying for state (.matches(':popover-open')) was cumbersome. But you're right - these two APIs now overlap a lot.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, fair enough.


## Specifications

{{Specifications}}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why the spec table isn't showing up for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The BCD was only merged last week, and it is likely that I created this PR before it was available on MDN. Some of the data for this API was already there, hence some of it showing up and some not. In this case, I think the data point was already there but I added a spec_url.


The **Popover API** provides developers with a standard, consistent, flexible mechanism for displaying popover content on top of other page content. Popover content can be controlled either declaratively using HTML attributes, or via JavaScript.

## Concepts and usage
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks so good like this!

The **`ToggleEvent`** interface represents an event notifying the user of an element whose state toggles between being open or closed.
The **`ToggleEvent`** interface represents an event notifying the user when a popover element's state toggles between showing and hidden.

It is the event object for the {{domxref("HTMLElement.beforetoggle_event", "beforetoggle")}} and {{domxref("HTMLElement.toggle_event", "toggle")}} events, which fire on popovers when their state changes.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But (I think) only for those events when the target is a popover. So maybe something like:

Suggested change
It is the event object for the {{domxref("HTMLElement.beforetoggle_event", "beforetoggle")}} and {{domxref("HTMLElement.toggle_event", "toggle")}} events, which fire on popovers when their state changes.
It is the event object for the {{domxref("HTMLElement.beforetoggle_event", "beforetoggle")}} and {{domxref("HTMLElement.toggle_event", "toggle")}} events when the event target is a popover.

Copy link
Contributor Author

@chrisdavidmills chrisdavidmills May 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but the <details> version seems to be a different, unrelated implementation. I've updated the text differently, adding a note to explain that ToggleEvent is not related to that version of toggle, and how they differ.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comment above.

Copy link
Collaborator

@wbamberg wbamberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, thanks for all the updates, Chris! Looks great. It seems like there will be some follow-up around the events and the behavior of showPopover/hidePopover but I agree this should wait for implementations.

I'm approving but not merging yet in case any of the other reviewers have more comments, but I'm happy for this to be merged.

@chrisdavidmills
Copy link
Contributor Author

OK, thanks for all the updates, Chris! Looks great. It seems like there will be some follow-up around the events and the behavior of showPopover/hidePopover but I agree this should wait for implementations.

I'm approving but not merging yet in case any of the other reviewers have more comments, but I'm happy for this to be merged.

Thanks @wbamberg ! Can you please merge it as soon as you see this ? I've got thumbs up from the Chrome folks to release.

@wbamberg wbamberg merged commit 559c464 into mdn:main May 3, 2023
@chrisdavidmills chrisdavidmills deleted the popover-api-landing-page-etc branch May 3, 2023 15:01
@chrisdavidmills
Copy link
Contributor Author

@wbamberg hoorah, cheers man!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Content:CSS Cascading Style Sheets docs Content:Glossary Glossary entries Content:HTML Hypertext Markup Language docs Content:WebAPI Web API docs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants