Skip to content

Commit fec7549

Browse files
authored
review edits: declarative dialog popover control (#806)
* apply updates to guide * wip update demo expectations
1 parent 84df2f4 commit fec7549

3 files changed

Lines changed: 164 additions & 51 deletions

File tree

guides/user-experience/declarative-dialog-popover-control/demo.html

Lines changed: 137 additions & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
- The document contains a button with the `commandfor` attribute targeting the ID of a popover element.
2-
- A button used to toggle a popover has a `command` attribute set to `toggle-popover`.
3-
- A button used to explicitly open a popover has a `command` attribute set to `show-popover`.
4-
- A button used to explicitly close a popover has a `command` attribute set to `hide-popover`.
5-
- The target element for the popover has the `popover` attribute.
6-
- The document contains a button with the `commandfor` attribute targeting the ID of a `<dialog>` element.
7-
- The button targeting the dialog has a `command` attribute set to `show-modal`.
8-
- The target element for the dialog is a `<dialog>` element.
9-
- There is a button, typically inside the `<dialog>` element, with the `commandfor` attribute targeting the dialog's ID.
10-
- The button to close the dialog has a `command` attribute set to `close`.
11-
- The document includes a fallback script that conditionally loads the `invokers-polyfill`.
12-
- The `invokers-polyfill` is only loaded if `'commandForElement' in HTMLButtonElement.prototype` is false.
13-
- The document includes a fallback script that conditionally loads a `popover` polyfill.
14-
- The `popover` polyfill is only loaded if `'popover' in HTMLElement.prototype` is false.
15-
- If the open state of a popover is styled, `:popover-open` is not used by itself, combined with the polyfill class `.\:popover-open` via `:is()` or `:where()`
1+
- The document uses buttons with `commandfor` and `command` attributes to declaratively control UI elements.
2+
- A button used to toggle a popover has `command="toggle-popover"` and an initial `aria-expanded="false"` attribute.
3+
- Buttons for explicit popover control use `command="show-popover"` and `command="hide-popover"`.
4+
- The target element for popover commands has the `popover` attribute.
5+
- A button used to open a modal dialog has `command="show-modal"` and targets a `<dialog>` element.
6+
- A button used to close a dialog has `command="close"`.
7+
- The fallback strategy MUST feature detect support by checking for `commandForElement` in `HTMLButtonElement.prototype` and `popover` in `HTMLElement.prototype`.
8+
- Polyfills MUST be loaded via dynamic `import()` only when native support is missing (or forced for testing).
9+
- The `invokers-polyfill` is dynamically imported from a CDN (e.g., `https://esm.run/invokers-polyfill`).
10+
- The `@oddbird/popover-polyfill` is dynamically imported and its `apply()` method is called.
11+
- CSS styling for the open state of a popover uses `:is()` or `:where()` to combine `:popover-open` with the polyfill class `.\:popover-open`.
12+
- The target element for explicit popover control (show/hide) has the `popover="manual"` attribute.
13+
- A `command` event listener is attached directly to each target element (not delegated via bubbling) when using the polyfill.
14+
- The `command` event listener identifies the command name via `event.command` (native) or `event.detail.command` (polyfill).

guides/user-experience/declarative-dialog-popover-control/guide.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ If you need to control opening and closing with separate buttons, you can use th
4444
Show Popover
4545
</button>
4646

47-
<div id="my-explicit-popover" popover>
47+
<div id="my-explicit-popover" popover="manual">
4848
<p>This popover is explicitly opened and closed by separate buttons.</p>
4949

5050
<!-- MANDATORY: Use 'hide-popover' to explicitly close the targeted popover. -->
@@ -85,9 +85,10 @@ Because Invoker Commands and Popovers are not yet universally supported, you MUS
8585
### Polyfilling Invoker Commands
8686

8787
MANDATORY: Feature detect support by checking for the `commandForElement` property on the `HTMLButtonElement` prototype. Do NOT check the window or document object. You MUST dynamically import the polyfill only when the native feature is missing. DO NOT unconditionally load the polyfill.
88+
Mandatory: Listen for the 'command' event directly on the target element because the native 'command' event does not bubble.
8889

89-
**Option 1: Using a package manager (e.g., npm)**
90-
Install the polyfill in your project (`npm install invokers-polyfill`).
90+
**Option 1: Using a bundler**
91+
Install the polyfill via npm (`npm install invokers-polyfill`). This approach is for projects using a bundler (like Vite or Webpack) or import maps. For all other setups, use the CDN option below.
9192

9293
```javascript
9394
// MANDATORY: Feature detect 'commandForElement' on HTMLButtonElement.prototype.
@@ -97,32 +98,32 @@ if (!('commandForElement' in HTMLButtonElement.prototype)) {
9798
}
9899
```
99100

100-
**Option 2: Manual installation without npm**
101-
If you are not using a package manager, dynamically import the polyfill directly from a CDN (such as unpkg) inside a `<script type="module">`.
101+
**Option 2: Using a CDN**
102+
For projects without a bundler, dynamically import the polyfill directly from a CDN inside a `<script type="module">`.
102103

103104
```html
104105
<script type="module">
105106
// MANDATORY: Feature detect 'commandForElement' on HTMLButtonElement.prototype.
106107
// Conditionally load the invokers-polyfill from a CDN only in browsers lacking native support.
107108
if (!('commandForElement' in HTMLButtonElement.prototype)) {
108-
import('https://unpkg.com/invokers-polyfill@latest/invoker.min.js');
109+
import('https://esm.run/invokers-polyfill');
109110
}
110111
</script>
111112
```
112113

113114
**Invokers Polyfill Limitations**
114-
Unlike the native Invoker Commands API, `invokers-polyfill` does not automatically handle ARIA attributes (such as `aria-expanded`) on the command button.
115+
MANDATORY: This polyfill does not handle the ARIA states (e.g., `aria-expanded`) of the command button the way native browsers do. You are strongly encouraged to handle these states yourself to ensure your site is fully accessible.
115116

116-
MANDATORY: You MUST manually manage these ARIA states to ensure your site remains fully accessible to screen readers in browsers relying on the polyfill.
117+
{{ INCLUDE("../declarative-button-actions/guide.md#fallback-strategies") }}
117118

118119
### Polyfilling the Popover Attribute
119120

120121
To support the `popover` attribute in older browsers, use the `@oddbird/popover-polyfill`.
121122

122123
MANDATORY: Feature detect popover support by checking for the `popover` property on the `HTMLElement` prototype. Conditionally initialize the polyfill only if native support is missing.
123124

124-
**Option 1: Using a package manager**
125-
Install the package (`npm install @oddbird/popover-polyfill`).
125+
**Option 1: Using a bundler**
126+
Install the package via npm (`npm install @oddbird/popover-polyfill`). This method requires a bundler or import maps to resolve the module path.
126127

127128
```javascript
128129
// MANDATORY: Feature detect 'popover' on HTMLElement.prototype.
@@ -133,8 +134,8 @@ if (!('popover' in HTMLElement.prototype)) {
133134
}
134135
```
135136

136-
**Option 2: Manual installation without npm**
137-
If you are not using a package manager, dynamically import the polyfill directly from a CDN (such as unpkg) inside a `<script type="module">`.
137+
**Option 2: Using a CDN**
138+
For projects without a bundler, dynamically import the polyfill directly from a CDN inside a `<script type="module">`.
138139

139140
```html
140141
<script type="module">

0 commit comments

Comments
 (0)