@material/web 2.5.0 → 2.5.1-nightly.23b638c.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +20910 -18104
- package/labs/aria/command.d.ts +18 -0
- package/labs/aria/command.js +204 -0
- package/labs/aria/command.js.map +1 -0
- package/labs/aria/menu/md-aria-menuitem.d.ts +11 -0
- package/labs/aria/menu/md-aria-menuitem.js +8 -0
- package/labs/aria/menu/md-aria-menuitem.js.map +1 -0
- package/labs/aria/menu/md-aria-menulist.d.ts +11 -0
- package/labs/aria/menu/md-aria-menulist.js +8 -0
- package/labs/aria/menu/md-aria-menulist.js.map +1 -0
- package/labs/aria/menu/menuitem.d.ts +26 -0
- package/labs/aria/menu/menuitem.js +86 -0
- package/labs/aria/menu/menuitem.js.map +1 -0
- package/labs/aria/menu/menulist.d.ts +25 -0
- package/labs/aria/menu/menulist.js +138 -0
- package/labs/aria/menu/menulist.js.map +1 -0
- package/labs/aria/query-associated.d.ts +23 -0
- package/labs/aria/query-associated.js +36 -0
- package/labs/aria/query-associated.js.map +1 -0
- package/labs/aria/tabs/md-aria-tab.d.ts +11 -0
- package/labs/aria/tabs/md-aria-tab.js +8 -0
- package/labs/aria/tabs/md-aria-tab.js.map +1 -0
- package/labs/aria/tabs/md-aria-tablist.d.ts +11 -0
- package/labs/aria/tabs/md-aria-tablist.js +8 -0
- package/labs/aria/tabs/md-aria-tablist.js.map +1 -0
- package/labs/aria/tabs/md-aria-tabpanel.d.ts +11 -0
- package/labs/aria/tabs/md-aria-tabpanel.js +8 -0
- package/labs/aria/tabs/md-aria-tabpanel.js.map +1 -0
- package/labs/aria/tabs/tab.d.ts +33 -0
- package/labs/aria/tabs/tab.js +88 -0
- package/labs/aria/tabs/tab.js.map +1 -0
- package/labs/aria/tabs/tablist.d.ts +67 -0
- package/labs/aria/tabs/tablist.js +271 -0
- package/labs/aria/tabs/tablist.js.map +1 -0
- package/labs/aria/tabs/tabpanel.d.ts +26 -0
- package/labs/aria/tabs/tabpanel.js +53 -0
- package/labs/aria/tabs/tabpanel.js.map +1 -0
- package/labs/gb/components/appbar/_app-bar-tokens.scss +136 -0
- package/labs/gb/components/appbar/app-bar-element.d.ts +54 -0
- package/labs/gb/components/appbar/app-bar-element.js +145 -0
- package/labs/gb/components/appbar/app-bar-element.js.map +1 -0
- package/labs/gb/components/appbar/app-bar.css +4 -0
- package/labs/gb/components/appbar/app-bar.css.map +1 -0
- package/labs/gb/components/appbar/app-bar.cssresult.d.ts +3 -0
- package/labs/gb/components/appbar/app-bar.cssresult.js +14 -0
- package/labs/gb/components/appbar/app-bar.cssresult.js.map +1 -0
- package/labs/gb/components/appbar/app-bar.d.ts +71 -0
- package/labs/gb/components/appbar/app-bar.js +96 -0
- package/labs/gb/components/appbar/app-bar.js.map +1 -0
- package/labs/gb/components/appbar/app-bar.scss +167 -0
- package/labs/gb/components/appbar/md-gb-app-bar.d.ts +12 -0
- package/labs/gb/components/appbar/md-gb-app-bar.js +8 -0
- package/labs/gb/components/appbar/md-gb-app-bar.js.map +1 -0
- package/labs/gb/components/badge/badge-element.d.ts +1 -0
- package/labs/gb/components/badge/badge-element.js +1 -0
- package/labs/gb/components/badge/badge-element.js.map +1 -1
- package/labs/gb/components/button/_button-tokens.scss +5 -1
- package/labs/gb/components/button/button-element.d.ts +2 -0
- package/labs/gb/components/button/button-element.js +2 -0
- package/labs/gb/components/button/button-element.js.map +1 -1
- package/labs/gb/components/button/button.css +1 -1
- package/labs/gb/components/button/button.css.map +1 -1
- package/labs/gb/components/button/button.cssresult.js +1 -1
- package/labs/gb/components/button/button.cssresult.js.map +1 -1
- package/labs/gb/components/button/button.scss +1 -0
- package/labs/gb/components/card/card-element.d.ts +1 -0
- package/labs/gb/components/card/card-element.js +1 -0
- package/labs/gb/components/card/card-element.js.map +1 -1
- package/labs/gb/components/checkbox/checkbox-element.d.ts +1 -0
- package/labs/gb/components/checkbox/checkbox-element.js +1 -0
- package/labs/gb/components/checkbox/checkbox-element.js.map +1 -1
- package/labs/gb/components/chip/_chip-tokens.scss +167 -0
- package/labs/gb/components/chip/chip-element.d.ts +74 -0
- package/labs/gb/components/chip/chip-element.js +234 -0
- package/labs/gb/components/chip/chip-element.js.map +1 -0
- package/labs/gb/components/chip/chip.css +4 -0
- package/labs/gb/components/chip/chip.css.map +1 -0
- package/labs/gb/components/chip/chip.cssresult.d.ts +3 -0
- package/labs/gb/components/chip/chip.cssresult.js +14 -0
- package/labs/gb/components/chip/chip.cssresult.js.map +1 -0
- package/labs/gb/components/chip/chip.d.ts +77 -0
- package/labs/gb/components/chip/chip.js +99 -0
- package/labs/gb/components/chip/chip.js.map +1 -0
- package/labs/gb/components/chip/chip.scss +99 -0
- package/labs/gb/components/chip/md-gb-chip.d.ts +13 -0
- package/labs/gb/components/chip/md-gb-chip.js +9 -0
- package/labs/gb/components/chip/md-gb-chip.js.map +1 -0
- package/labs/gb/components/divider/divider-element.d.ts +1 -0
- package/labs/gb/components/divider/divider-element.js +1 -0
- package/labs/gb/components/divider/divider-element.js.map +1 -1
- package/labs/gb/components/fab/_fab-tokens.scss +4 -1
- package/labs/gb/components/fab/fab-element.d.ts +2 -0
- package/labs/gb/components/fab/fab-element.js +2 -0
- package/labs/gb/components/fab/fab-element.js.map +1 -1
- package/labs/gb/components/fab/fab.css +1 -1
- package/labs/gb/components/fab/fab.css.map +1 -1
- package/labs/gb/components/fab/fab.cssresult.js +1 -1
- package/labs/gb/components/fab/fab.cssresult.js.map +1 -1
- package/labs/gb/components/fab/fab.scss +1 -0
- package/labs/gb/components/iconbutton/icon-button-element.d.ts +1 -0
- package/labs/gb/components/iconbutton/icon-button-element.js +1 -0
- package/labs/gb/components/iconbutton/icon-button-element.js.map +1 -1
- package/labs/gb/components/list/_list-tokens.scss +11 -14
- package/labs/gb/components/list/list-element.d.ts +1 -0
- package/labs/gb/components/list/list-element.js +1 -0
- package/labs/gb/components/list/list-element.js.map +1 -1
- package/labs/gb/components/list/list-item-element.d.ts +5 -0
- package/labs/gb/components/list/list-item-element.js +5 -0
- package/labs/gb/components/list/list-item-element.js.map +1 -1
- package/labs/gb/components/list/list.css +1 -1
- package/labs/gb/components/list/list.css.map +1 -1
- package/labs/gb/components/list/list.cssresult.js +1 -1
- package/labs/gb/components/list/list.cssresult.js.map +1 -1
- package/labs/gb/components/list/list.scss +5 -0
- package/labs/gb/components/menu/_menu-tokens.scss +45 -16
- package/labs/gb/components/menu/menu-element.d.ts +1 -0
- package/labs/gb/components/menu/menu-element.js +1 -0
- package/labs/gb/components/menu/menu-element.js.map +1 -1
- package/labs/gb/components/menu/menu-group-element.d.ts +1 -0
- package/labs/gb/components/menu/menu-group-element.js +1 -0
- package/labs/gb/components/menu/menu-group-element.js.map +1 -1
- package/labs/gb/components/menu/menu-item-element.d.ts +5 -1
- package/labs/gb/components/menu/menu-item-element.js +5 -1
- package/labs/gb/components/menu/menu-item-element.js.map +1 -1
- package/labs/gb/components/menu/menu.css +1 -1
- package/labs/gb/components/menu/menu.css.map +1 -1
- package/labs/gb/components/menu/menu.cssresult.js +1 -1
- package/labs/gb/components/menu/menu.cssresult.js.map +1 -1
- package/labs/gb/components/menu/menu.scss +3 -0
- package/labs/gb/components/radio/radio-element.d.ts +1 -0
- package/labs/gb/components/radio/radio-element.js +1 -0
- package/labs/gb/components/radio/radio-element.js.map +1 -1
- package/labs/gb/components/splitbutton/split-button-element.d.ts +1 -0
- package/labs/gb/components/splitbutton/split-button-element.js +1 -0
- package/labs/gb/components/splitbutton/split-button-element.js.map +1 -1
- package/labs/gb/components/switch/switch-element.d.ts +1 -0
- package/labs/gb/components/switch/switch-element.js +1 -0
- package/labs/gb/components/switch/switch-element.js.map +1 -1
- package/labs/gb/styles/icon/icon-element.d.ts +1 -0
- package/labs/gb/styles/icon/icon-element.js +1 -0
- package/labs/gb/styles/icon/icon-element.js.map +1 -1
- package/package.json +1 -1
- package/types/command-event.d.ts +22 -0
- package/types/popover.d.ts +22 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Performs the 'shared command invoker activation steps' for a button or
|
|
8
|
+
* menuitem, to be called when that element is activated: either runs a command
|
|
9
|
+
* (i.e. the element has `command` and `commandfor` attributes) or changes a
|
|
10
|
+
* popover's state (i.e. the element has the `popovertarget` and possibly
|
|
11
|
+
* `popovertargetaction` attributes).
|
|
12
|
+
*
|
|
13
|
+
* https://whatpr.org/html/12011/popover.html#shared-command-invoker-activation-steps
|
|
14
|
+
*
|
|
15
|
+
* @param element The button or menuitem being activated.
|
|
16
|
+
* @param event The event that activated `element`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function sharedCommandInvokerActivationSteps(element: HTMLElement, event: Event): void;
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/// <reference types="../../types/command-event.d.ts" />
|
|
7
|
+
/// <reference types="../../types/popover.d.ts" />
|
|
8
|
+
import { queryAssociatedById } from './query-associated.js';
|
|
9
|
+
/**
|
|
10
|
+
* Determines an element's `command` attribute state, given the attribute value.
|
|
11
|
+
*/
|
|
12
|
+
function getCommandState(attrValue) {
|
|
13
|
+
switch (attrValue) {
|
|
14
|
+
case 'toggle-popover':
|
|
15
|
+
case 'show-popover':
|
|
16
|
+
case 'hide-popover':
|
|
17
|
+
case 'close':
|
|
18
|
+
case 'request-close':
|
|
19
|
+
case 'show-modal':
|
|
20
|
+
return attrValue;
|
|
21
|
+
default:
|
|
22
|
+
return attrValue?.startsWith('--') ? 'custom' : 'unknown';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/** Determines the popover state of an element. */
|
|
26
|
+
function getPopoverState(element) {
|
|
27
|
+
if (element.localName === 'md-aria-menulist') {
|
|
28
|
+
return 'auto';
|
|
29
|
+
}
|
|
30
|
+
const attrValue = element.getAttribute('popover');
|
|
31
|
+
switch (attrValue) {
|
|
32
|
+
case '':
|
|
33
|
+
return 'auto';
|
|
34
|
+
case 'auto':
|
|
35
|
+
case 'manual':
|
|
36
|
+
case 'hint':
|
|
37
|
+
return attrValue;
|
|
38
|
+
case null:
|
|
39
|
+
default:
|
|
40
|
+
return 'no-popover';
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Determines the popover target action from an element's `popovertargetaction`
|
|
45
|
+
* attribute value.
|
|
46
|
+
*/
|
|
47
|
+
function getPopoverTargetActionState(attrValue) {
|
|
48
|
+
switch (attrValue) {
|
|
49
|
+
case 'toggle':
|
|
50
|
+
case 'show':
|
|
51
|
+
case 'hide':
|
|
52
|
+
return attrValue;
|
|
53
|
+
default:
|
|
54
|
+
return 'toggle';
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Performs the 'shared command invoker activation steps' for a button or
|
|
59
|
+
* menuitem, to be called when that element is activated: either runs a command
|
|
60
|
+
* (i.e. the element has `command` and `commandfor` attributes) or changes a
|
|
61
|
+
* popover's state (i.e. the element has the `popovertarget` and possibly
|
|
62
|
+
* `popovertargetaction` attributes).
|
|
63
|
+
*
|
|
64
|
+
* https://whatpr.org/html/12011/popover.html#shared-command-invoker-activation-steps
|
|
65
|
+
*
|
|
66
|
+
* @param element The button or menuitem being activated.
|
|
67
|
+
* @param event The event that activated `element`.
|
|
68
|
+
*/
|
|
69
|
+
export function sharedCommandInvokerActivationSteps(element, event) {
|
|
70
|
+
const idref = element.getAttribute('commandfor');
|
|
71
|
+
const commandTarget = queryAssociatedById(element, idref ?? '');
|
|
72
|
+
if (!commandTarget) {
|
|
73
|
+
popoverTargetAttributeActivationBehavior(element, event.target);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const command = element.getAttribute('command');
|
|
77
|
+
const commandState = getCommandState(command);
|
|
78
|
+
if (commandState === 'unknown' || command === null) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const isPopover = getPopoverState(commandTarget) !== 'no-popover';
|
|
82
|
+
if (isPopover && commandState !== 'custom') {
|
|
83
|
+
// `<dialog>` is the only element that defines 'is valid command steps'.
|
|
84
|
+
if (commandTarget.localName === 'dialog' &&
|
|
85
|
+
!['close', 'request-close', 'show-modal'].includes(commandState)) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const continueSteps = commandTarget.dispatchEvent(new CommandEvent('command', { source: element, command, cancelable: true }));
|
|
90
|
+
if (!continueSteps ||
|
|
91
|
+
!commandTarget.isConnected ||
|
|
92
|
+
commandState === 'custom') {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
switch (command) {
|
|
96
|
+
case 'hide-popover':
|
|
97
|
+
try {
|
|
98
|
+
// Use `togglePopover` because `hidePopover` doesn't support `source`.
|
|
99
|
+
commandTarget.togglePopover({ force: false, source: element });
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
// Do nothing. No exception should be thrown by these steps if the
|
|
103
|
+
// popover isn't in the expected state.
|
|
104
|
+
}
|
|
105
|
+
break;
|
|
106
|
+
case 'toggle-popover':
|
|
107
|
+
try {
|
|
108
|
+
commandTarget.togglePopover({ source: element });
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
// Do nothing. No exception should be thrown by these steps if the
|
|
112
|
+
// popover isn't in the expected state.
|
|
113
|
+
}
|
|
114
|
+
break;
|
|
115
|
+
case 'show-popover':
|
|
116
|
+
try {
|
|
117
|
+
commandTarget.showPopover({ source: element });
|
|
118
|
+
}
|
|
119
|
+
catch (e) {
|
|
120
|
+
// Do nothing. No exception should be thrown by these steps if the
|
|
121
|
+
// popover isn't in the expected state.
|
|
122
|
+
}
|
|
123
|
+
break;
|
|
124
|
+
default:
|
|
125
|
+
// An element can have 'command steps', which are run if the element's
|
|
126
|
+
// command is not a popover command. Currently, only `<dialog>` defines
|
|
127
|
+
// 'command steps', so they're inlined here.
|
|
128
|
+
//
|
|
129
|
+
// https://whatpr.org/html/12011/popover.html#command-steps
|
|
130
|
+
// https://whatpr.org/html/12011/interactive-elements.html#the-dialog-element:command-steps
|
|
131
|
+
if (commandTarget.localName === 'dialog') {
|
|
132
|
+
const dialog = commandTarget;
|
|
133
|
+
if (dialog.matches(':popover-open')) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
switch (commandState) {
|
|
137
|
+
case 'close':
|
|
138
|
+
if (dialog.hasAttribute('open')) {
|
|
139
|
+
dialog.close(element.getAttribute('value') ?? undefined);
|
|
140
|
+
}
|
|
141
|
+
break;
|
|
142
|
+
case 'request-close':
|
|
143
|
+
if (dialog.hasAttribute('open')) {
|
|
144
|
+
dialog.requestClose(element.getAttribute('value') ?? undefined);
|
|
145
|
+
}
|
|
146
|
+
break;
|
|
147
|
+
case 'show-modal':
|
|
148
|
+
if (!dialog.hasAttribute('open')) {
|
|
149
|
+
dialog.showModal();
|
|
150
|
+
}
|
|
151
|
+
break;
|
|
152
|
+
default:
|
|
153
|
+
// Do nothing.
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Performs the 'popover target attribute activation behavior' for a button or
|
|
161
|
+
* menuitem.
|
|
162
|
+
*
|
|
163
|
+
* These steps are taken when a button or menuitem is activated, but doesn't
|
|
164
|
+
* target an element with a `command` attribute.
|
|
165
|
+
*
|
|
166
|
+
* https://whatpr.org/html/12011/popover.html#popover-target-attribute-activation-behavior
|
|
167
|
+
*
|
|
168
|
+
* @param element The button or menuitem being activated.
|
|
169
|
+
* @param eventTarget The target of the event that activated `element`.
|
|
170
|
+
*/
|
|
171
|
+
function popoverTargetAttributeActivationBehavior(element, eventTarget) {
|
|
172
|
+
const idref = element.getAttribute('popovertarget');
|
|
173
|
+
const popover = queryAssociatedById(element, idref ?? '');
|
|
174
|
+
if (!popover) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
// TODO: The spec describes a case here that's relevant when the popover is
|
|
178
|
+
// nested inside its invoker itself, which would cause clicking anywhere in
|
|
179
|
+
// the popover to close the popover.
|
|
180
|
+
//
|
|
181
|
+
// https://github.com/whatwg/html/pull/10770
|
|
182
|
+
const open = popover.matches(':popover-open');
|
|
183
|
+
const action = getPopoverTargetActionState(element.getAttribute('popovertargetaction') ?? '');
|
|
184
|
+
if (!open && (action === 'show' || action === 'toggle')) {
|
|
185
|
+
try {
|
|
186
|
+
popover.showPopover({ source: element });
|
|
187
|
+
}
|
|
188
|
+
catch (e) {
|
|
189
|
+
// Do nothing. No exception should be thrown by these steps if the
|
|
190
|
+
// popover isn't in the expected state.
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
else if (open && (action === 'hide' || action === 'toggle')) {
|
|
194
|
+
try {
|
|
195
|
+
// Use `togglePopover` because `hidePopover` doesn't support `source`.
|
|
196
|
+
popover.togglePopover({ force: false, source: element });
|
|
197
|
+
}
|
|
198
|
+
catch (e) {
|
|
199
|
+
// Do nothing. No exception should be thrown by these steps if the
|
|
200
|
+
// popover isn't in the expected state.
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["command.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/// <reference types=\"../../types/command-event.d.ts\" />\n/// <reference types=\"../../types/popover.d.ts\" />\n\nimport {queryAssociatedById} from './query-associated.js';\n\n/**\n * An element's `command` attribute state: either one of a fixed set of commands\n * with spec-defined actions, `custom` (if it begins with `--`), or `unknown`.\n *\n * https://whatpr.org/html/12011/popover.html#attr-command\n */\ntype CommandState =\n | 'toggle-popover'\n | 'show-popover'\n | 'hide-popover'\n | 'close'\n | 'request-close'\n | 'show-modal'\n | 'custom'\n | 'unknown';\n\n/**\n * Determines an element's `command` attribute state, given the attribute value.\n */\nfunction getCommandState(attrValue: string | null): CommandState {\n switch (attrValue) {\n case 'toggle-popover':\n case 'show-popover':\n case 'hide-popover':\n case 'close':\n case 'request-close':\n case 'show-modal':\n return attrValue;\n default:\n return attrValue?.startsWith('--') ? 'custom' : 'unknown';\n }\n}\n\n/**\n * An element's popover state, as determined by its type or `popover` attribute.\n *\n * https://whatpr.org/html/12011/popover.html#popover-state\n */\ntype PopoverState = 'auto' | 'manual' | 'hint' | 'no-popover';\n\n/** Determines the popover state of an element. */\nfunction getPopoverState(element: HTMLElement): PopoverState {\n if (element.localName === 'md-aria-menulist') {\n return 'auto';\n }\n\n const attrValue = element.getAttribute('popover');\n switch (attrValue) {\n case '':\n return 'auto';\n case 'auto':\n case 'manual':\n case 'hint':\n return attrValue;\n case null:\n default:\n return 'no-popover';\n }\n}\n\n/**\n * An element's popover target action state: the action taken on the popover\n * referenced by the element's `popovertarget` attribute.\n *\n * https://whatpr.org/html/12011/popover.html#attr-popovertargetaction\n */\ntype PopoverTargetActionState = 'toggle' | 'show' | 'hide';\n\n/**\n * Determines the popover target action from an element's `popovertargetaction`\n * attribute value.\n */\nfunction getPopoverTargetActionState(\n attrValue: string,\n): PopoverTargetActionState {\n switch (attrValue) {\n case 'toggle':\n case 'show':\n case 'hide':\n return attrValue;\n default:\n return 'toggle';\n }\n}\n\n/**\n * Performs the 'shared command invoker activation steps' for a button or\n * menuitem, to be called when that element is activated: either runs a command\n * (i.e. the element has `command` and `commandfor` attributes) or changes a\n * popover's state (i.e. the element has the `popovertarget` and possibly\n * `popovertargetaction` attributes).\n *\n * https://whatpr.org/html/12011/popover.html#shared-command-invoker-activation-steps\n *\n * @param element The button or menuitem being activated.\n * @param event The event that activated `element`.\n */\nexport function sharedCommandInvokerActivationSteps(\n element: HTMLElement,\n event: Event,\n) {\n const idref = element.getAttribute('commandfor');\n const commandTarget = queryAssociatedById(\n element,\n idref ?? '',\n ) as HTMLElement | null;\n if (!commandTarget) {\n popoverTargetAttributeActivationBehavior(element, event.target as Node);\n return;\n }\n\n const command = element.getAttribute('command');\n const commandState = getCommandState(command);\n if (commandState === 'unknown' || command === null) {\n return;\n }\n\n const isPopover = getPopoverState(commandTarget) !== 'no-popover';\n if (isPopover && commandState !== 'custom') {\n // `<dialog>` is the only element that defines 'is valid command steps'.\n if (\n commandTarget.localName === 'dialog' &&\n !['close', 'request-close', 'show-modal'].includes(commandState)\n ) {\n return;\n }\n }\n\n const continueSteps = commandTarget.dispatchEvent(\n new CommandEvent('command', {source: element, command, cancelable: true}),\n );\n\n if (\n !continueSteps ||\n !commandTarget.isConnected ||\n commandState === 'custom'\n ) {\n return;\n }\n\n switch (command) {\n case 'hide-popover':\n try {\n // Use `togglePopover` because `hidePopover` doesn't support `source`.\n commandTarget.togglePopover({force: false, source: element});\n } catch (e) {\n // Do nothing. No exception should be thrown by these steps if the\n // popover isn't in the expected state.\n }\n break;\n case 'toggle-popover':\n try {\n commandTarget.togglePopover({source: element});\n } catch (e) {\n // Do nothing. No exception should be thrown by these steps if the\n // popover isn't in the expected state.\n }\n break;\n case 'show-popover':\n try {\n commandTarget.showPopover({source: element});\n } catch (e) {\n // Do nothing. No exception should be thrown by these steps if the\n // popover isn't in the expected state.\n }\n break;\n default:\n // An element can have 'command steps', which are run if the element's\n // command is not a popover command. Currently, only `<dialog>` defines\n // 'command steps', so they're inlined here.\n //\n // https://whatpr.org/html/12011/popover.html#command-steps\n // https://whatpr.org/html/12011/interactive-elements.html#the-dialog-element:command-steps\n if (commandTarget.localName === 'dialog') {\n const dialog = commandTarget as HTMLDialogElement;\n if (dialog.matches(':popover-open')) {\n return;\n }\n\n switch (commandState) {\n case 'close':\n if (dialog.hasAttribute('open')) {\n dialog.close(element.getAttribute('value') ?? undefined);\n }\n break;\n case 'request-close':\n if (dialog.hasAttribute('open')) {\n dialog.requestClose(element.getAttribute('value') ?? undefined);\n }\n break;\n case 'show-modal':\n if (!dialog.hasAttribute('open')) {\n dialog.showModal();\n }\n break;\n default:\n // Do nothing.\n break;\n }\n }\n }\n}\n\n/**\n * Performs the 'popover target attribute activation behavior' for a button or\n * menuitem.\n *\n * These steps are taken when a button or menuitem is activated, but doesn't\n * target an element with a `command` attribute.\n *\n * https://whatpr.org/html/12011/popover.html#popover-target-attribute-activation-behavior\n *\n * @param element The button or menuitem being activated.\n * @param eventTarget The target of the event that activated `element`.\n */\nfunction popoverTargetAttributeActivationBehavior(\n element: HTMLElement,\n eventTarget: Node,\n) {\n const idref = element.getAttribute('popovertarget');\n const popover = queryAssociatedById(\n element,\n idref ?? '',\n ) as HTMLElement | null;\n if (!popover) {\n return;\n }\n\n // TODO: The spec describes a case here that's relevant when the popover is\n // nested inside its invoker itself, which would cause clicking anywhere in\n // the popover to close the popover.\n //\n // https://github.com/whatwg/html/pull/10770\n\n const open = popover.matches(':popover-open');\n const action = getPopoverTargetActionState(\n element.getAttribute('popovertargetaction') ?? '',\n );\n if (!open && (action === 'show' || action === 'toggle')) {\n try {\n popover.showPopover({source: element});\n } catch (e) {\n // Do nothing. No exception should be thrown by these steps if the\n // popover isn't in the expected state.\n }\n } else if (open && (action === 'hide' || action === 'toggle')) {\n try {\n // Use `togglePopover` because `hidePopover` doesn't support `source`.\n popover.togglePopover({force: false, source: element});\n } catch (e) {\n // Do nothing. No exception should be thrown by these steps if the\n // popover isn't in the expected state.\n }\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"md-aria-menuitem.js","sourceRoot":"","sources":["md-aria-menuitem.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,mBAAmB,EAAC,MAAM,eAAe,CAAC;AAQlD,cAAc,CAAC,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {AriaMenuitemElement} from './menuitem.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'md-aria-menuitem': AriaMenuitemElement;\n }\n}\n\ncustomElements.define('md-aria-menuitem', AriaMenuitemElement);\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"md-aria-menulist.js","sourceRoot":"","sources":["md-aria-menulist.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,mBAAmB,EAAC,MAAM,eAAe,CAAC;AAQlD,cAAc,CAAC,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {AriaMenulistElement} from './menulist.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'md-aria-menulist': AriaMenulistElement;\n }\n}\n\ncustomElements.define('md-aria-menulist', AriaMenulistElement);\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { CSSResultOrNative, LitElement } from 'lit';
|
|
7
|
+
import { AriaMenulistElement } from './menulist.js';
|
|
8
|
+
/** Private property key for the `ancestorMenulist` context. */
|
|
9
|
+
declare const ancestorMenulist: unique symbol;
|
|
10
|
+
declare const baseClass: import("../../behaviors/mixin.js").MixinReturn<import("../../behaviors/mixin.js").MixinReturn<import("../../behaviors/mixin.js").MixinReturn<typeof LitElement, import("../../behaviors/element-internals.js").WithElementInternals>, import("../../behaviors/focusable.js").Focusable>, import("../../behaviors/custom-state-set.js").WithCustomStateSet>;
|
|
11
|
+
/**
|
|
12
|
+
* An element implementing the proposed `<menuitem>` built-in element.
|
|
13
|
+
*
|
|
14
|
+
* @cssstate enabled - True when the item is enabled.
|
|
15
|
+
* @cssstate disabled - True when the item is disabled.
|
|
16
|
+
*/
|
|
17
|
+
export declare class AriaMenuitemElement extends baseClass {
|
|
18
|
+
static styles: CSSResultOrNative[];
|
|
19
|
+
[ancestorMenulist]?: AriaMenulistElement;
|
|
20
|
+
get disabled(): boolean;
|
|
21
|
+
set disabled(value: boolean);
|
|
22
|
+
constructor();
|
|
23
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
24
|
+
click(): void;
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
var _a;
|
|
7
|
+
import { __decorate } from "tslib";
|
|
8
|
+
import { consume } from '@lit/context';
|
|
9
|
+
import { LitElement, css, html } from 'lit';
|
|
10
|
+
import { property } from 'lit/decorators.js';
|
|
11
|
+
import { afterDispatch, setupDispatchHooks, } from '../../../internal/events/dispatch-hooks.js';
|
|
12
|
+
import { mixinCustomStateSet, toggleState, } from '../../behaviors/custom-state-set.js';
|
|
13
|
+
import { internals, mixinElementInternals, } from '../../behaviors/element-internals.js';
|
|
14
|
+
import { mixinFocusable } from '../../behaviors/focusable.js';
|
|
15
|
+
import { sharedCommandInvokerActivationSteps } from '../command.js';
|
|
16
|
+
import { ancestorMenulistContext } from './menulist.js';
|
|
17
|
+
/** Private property key for the `ancestorMenulist` context. */
|
|
18
|
+
const ancestorMenulist = Symbol('ancestorMenulist');
|
|
19
|
+
const baseClass = mixinCustomStateSet(mixinFocusable(mixinElementInternals(LitElement)));
|
|
20
|
+
/**
|
|
21
|
+
* An element implementing the proposed `<menuitem>` built-in element.
|
|
22
|
+
*
|
|
23
|
+
* @cssstate enabled - True when the item is enabled.
|
|
24
|
+
* @cssstate disabled - True when the item is disabled.
|
|
25
|
+
*/
|
|
26
|
+
export class AriaMenuitemElement extends baseClass {
|
|
27
|
+
get disabled() {
|
|
28
|
+
return this[internals].ariaDisabled === 'true';
|
|
29
|
+
}
|
|
30
|
+
set disabled(value) {
|
|
31
|
+
const oldValue = this.disabled;
|
|
32
|
+
value = Boolean(value);
|
|
33
|
+
this[internals].ariaDisabled = String(value);
|
|
34
|
+
this[toggleState]('disabled', value);
|
|
35
|
+
this[toggleState]('enabled', !value);
|
|
36
|
+
this.requestUpdate('disabled', oldValue);
|
|
37
|
+
}
|
|
38
|
+
constructor() {
|
|
39
|
+
super();
|
|
40
|
+
this[internals].role = 'menuitem';
|
|
41
|
+
this.disabled = false;
|
|
42
|
+
setupDispatchHooks(this, 'keydown', 'click');
|
|
43
|
+
this.addEventListener('keydown', (event) => {
|
|
44
|
+
afterDispatch(event, () => {
|
|
45
|
+
if (event.defaultPrevented) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
49
|
+
this.click();
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
this.addEventListener('click', (event) => {
|
|
54
|
+
afterDispatch(event, () => {
|
|
55
|
+
if (event.defaultPrevented || this.disabled) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
this[ancestorMenulist]?.hidePopover();
|
|
59
|
+
sharedCommandInvokerActivationSteps(this, event);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
render() {
|
|
64
|
+
return html `<slot></slot>`;
|
|
65
|
+
}
|
|
66
|
+
click() {
|
|
67
|
+
if (!this.disabled) {
|
|
68
|
+
super.click();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
_a = ancestorMenulist;
|
|
73
|
+
AriaMenuitemElement.styles = [
|
|
74
|
+
css `
|
|
75
|
+
:host {
|
|
76
|
+
display: inline-flex;
|
|
77
|
+
}
|
|
78
|
+
`,
|
|
79
|
+
];
|
|
80
|
+
__decorate([
|
|
81
|
+
consume({ context: ancestorMenulistContext, subscribe: true })
|
|
82
|
+
], AriaMenuitemElement.prototype, _a, void 0);
|
|
83
|
+
__decorate([
|
|
84
|
+
property({ type: Boolean, reflect: true, noAccessor: true })
|
|
85
|
+
], AriaMenuitemElement.prototype, "disabled", null);
|
|
86
|
+
//# sourceMappingURL=menuitem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menuitem.js","sourceRoot":"","sources":["menuitem.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {consume} from '@lit/context';\nimport {CSSResultOrNative, LitElement, css, html} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {\n afterDispatch,\n setupDispatchHooks,\n} from '../../../internal/events/dispatch-hooks.js';\nimport {\n mixinCustomStateSet,\n toggleState,\n} from '../../behaviors/custom-state-set.js';\nimport {\n internals,\n mixinElementInternals,\n} from '../../behaviors/element-internals.js';\nimport {mixinFocusable} from '../../behaviors/focusable.js';\nimport {sharedCommandInvokerActivationSteps} from '../command.js';\nimport {AriaMenulistElement, ancestorMenulistContext} from './menulist.js';\n\n/** Private property key for the `ancestorMenulist` context. */\nconst ancestorMenulist = Symbol('ancestorMenulist');\n\nconst baseClass = mixinCustomStateSet(\n mixinFocusable(mixinElementInternals(LitElement)),\n);\n\n/**\n * An element implementing the proposed `<menuitem>` built-in element.\n *\n * @cssstate enabled - True when the item is enabled.\n * @cssstate disabled - True when the item is disabled.\n */\nexport class AriaMenuitemElement extends baseClass {\n static override styles: CSSResultOrNative[] = [\n css`\n :host {\n display: inline-flex;\n }\n `,\n ];\n\n @consume({context: ancestorMenulistContext, subscribe: true})\n [ancestorMenulist]?: AriaMenulistElement;\n\n @property({type: Boolean, reflect: true, noAccessor: true})\n get disabled() {\n return this[internals].ariaDisabled === 'true';\n }\n set disabled(value: boolean) {\n const oldValue = this.disabled;\n value = Boolean(value);\n this[internals].ariaDisabled = String(value);\n this[toggleState]('disabled', value);\n this[toggleState]('enabled', !value);\n this.requestUpdate('disabled', oldValue);\n }\n\n constructor() {\n super();\n this[internals].role = 'menuitem';\n this.disabled = false;\n\n setupDispatchHooks(this, 'keydown', 'click');\n this.addEventListener('keydown', (event: KeyboardEvent) => {\n afterDispatch(event, () => {\n if (event.defaultPrevented) {\n return;\n }\n\n if (event.key === 'Enter' || event.key === ' ') {\n this.click();\n }\n });\n });\n this.addEventListener('click', (event: Event) => {\n afterDispatch(event, () => {\n if (event.defaultPrevented || this.disabled) {\n return;\n }\n\n this[ancestorMenulist]?.hidePopover();\n sharedCommandInvokerActivationSteps(this, event);\n });\n });\n }\n\n override render() {\n return html`<slot></slot>`;\n }\n\n override click() {\n if (!this.disabled) {\n super.click();\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { CSSResultOrNative, LitElement } from 'lit';
|
|
7
|
+
/** The `<md-aria-menulist>` that should own descendant `<md-aria-menuitem>`s. */
|
|
8
|
+
export declare const ancestorMenulistContext: {
|
|
9
|
+
__context__: AriaMenulistElement;
|
|
10
|
+
};
|
|
11
|
+
declare const baseClass: import("../../behaviors/mixin.js").MixinReturn<typeof LitElement, import("../../behaviors/element-internals.js").WithElementInternals>;
|
|
12
|
+
/**
|
|
13
|
+
* An element implementing the proposed `<menulist>` built-in element.
|
|
14
|
+
*/
|
|
15
|
+
export declare class AriaMenulistElement extends baseClass {
|
|
16
|
+
static styles: CSSResultOrNative[];
|
|
17
|
+
popover: string;
|
|
18
|
+
focusGroup: string;
|
|
19
|
+
constructor();
|
|
20
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
21
|
+
private opener;
|
|
22
|
+
private handleToggle;
|
|
23
|
+
private handleFocusout;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { __decorate } from "tslib";
|
|
7
|
+
/// <reference types="../../../types/popover.d.ts" />
|
|
8
|
+
import { ContextProvider, createContext } from '@lit/context';
|
|
9
|
+
import { LitElement, css, html } from 'lit';
|
|
10
|
+
import { property } from 'lit/decorators.js';
|
|
11
|
+
import { internals, mixinElementInternals, } from '../../behaviors/element-internals.js';
|
|
12
|
+
/** The `<md-aria-menulist>` that should own descendant `<md-aria-menuitem>`s. */
|
|
13
|
+
export const ancestorMenulistContext = createContext(Symbol('ancestorMenulistContext'));
|
|
14
|
+
const baseClass = mixinElementInternals(LitElement);
|
|
15
|
+
/**
|
|
16
|
+
* An element implementing the proposed `<menulist>` built-in element.
|
|
17
|
+
*/
|
|
18
|
+
export class AriaMenulistElement extends baseClass {
|
|
19
|
+
constructor() {
|
|
20
|
+
super();
|
|
21
|
+
this.popover = 'auto';
|
|
22
|
+
this.focusGroup = 'menu';
|
|
23
|
+
this.opener = null;
|
|
24
|
+
const provider = new ContextProvider(this, {
|
|
25
|
+
context: ancestorMenulistContext,
|
|
26
|
+
});
|
|
27
|
+
provider.setValue(this);
|
|
28
|
+
this[internals].role = 'menu';
|
|
29
|
+
this[internals].ariaOrientation = 'vertical';
|
|
30
|
+
this.addEventListener('toggle', this.handleToggle.bind(this));
|
|
31
|
+
this.addEventListener('focusout', this.handleFocusout.bind(this));
|
|
32
|
+
}
|
|
33
|
+
render() {
|
|
34
|
+
return html `<slot></slot>`;
|
|
35
|
+
}
|
|
36
|
+
handleToggle(event) {
|
|
37
|
+
if (event.newState === 'open') {
|
|
38
|
+
this.opener = event.source;
|
|
39
|
+
}
|
|
40
|
+
else if (event.newState === 'closed' && this.matches(':focus-within')) {
|
|
41
|
+
// When closing, restore focus if focus remained in the menulist (e.g.
|
|
42
|
+
// during _keyboard_ light dismiss).
|
|
43
|
+
this.opener?.focus?.();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
handleFocusout() {
|
|
47
|
+
if (!this.matches(':focus-within')) {
|
|
48
|
+
this.hidePopover();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
AriaMenulistElement.styles = [
|
|
53
|
+
css `
|
|
54
|
+
/* Unset UA |[popover]| styles. */
|
|
55
|
+
@layer {
|
|
56
|
+
:host([popover]) {
|
|
57
|
+
position: unset;
|
|
58
|
+
width: unset;
|
|
59
|
+
height: unset;
|
|
60
|
+
color: unset;
|
|
61
|
+
background-color: unset;
|
|
62
|
+
inset: unset;
|
|
63
|
+
margin: unset;
|
|
64
|
+
border: unset;
|
|
65
|
+
border-image: unset;
|
|
66
|
+
padding: unset;
|
|
67
|
+
overflow: unset;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
:host([popover]:popover-open) {
|
|
71
|
+
display: unset;
|
|
72
|
+
overlay: unset;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
:host {
|
|
77
|
+
display: block;
|
|
78
|
+
position: fixed;
|
|
79
|
+
width: max-content;
|
|
80
|
+
max-block-size: stretch;
|
|
81
|
+
color: canvastext;
|
|
82
|
+
background-color: canvas;
|
|
83
|
+
margin: 0px;
|
|
84
|
+
inset: auto;
|
|
85
|
+
overflow: auto;
|
|
86
|
+
border: 1px solid currentColor;
|
|
87
|
+
border-image: none;
|
|
88
|
+
padding: 0.25em;
|
|
89
|
+
|
|
90
|
+
/* This should really only apply when the implicit anchor is a menuitem
|
|
91
|
+
* in a menubar, but applies to buttons too? */
|
|
92
|
+
position-area: block-end span-inline-end;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
:host(:not(:popover-open)) {
|
|
96
|
+
display: none;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
::slotted(md-aria-menuitem) {
|
|
100
|
+
display: flex;
|
|
101
|
+
align-items: center;
|
|
102
|
+
user-select: none;
|
|
103
|
+
min-inline-size: 24px;
|
|
104
|
+
min-block-size: max(24px, 1lh);
|
|
105
|
+
font-weight: inherit;
|
|
106
|
+
gap: 0.5em;
|
|
107
|
+
padding-inline: 0.5em;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
::slotted(md-aria-menuitem:state(enabled):hover) {
|
|
111
|
+
background-color: color-mix(in lab, currentColor 10%, transparent);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
::slotted(md-aria-menuitem:state(disabled)) {
|
|
115
|
+
color: color-mix(in lab, currentColor 50%, transparent);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
::slotted(hr) {
|
|
119
|
+
color: inherit;
|
|
120
|
+
margin-inline: 0px;
|
|
121
|
+
border: none;
|
|
122
|
+
border-block-start: 1px solid currentColor;
|
|
123
|
+
border-image: none;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
::slotted(a:any-link),
|
|
127
|
+
::slotted(img[usemap]) {
|
|
128
|
+
display: none;
|
|
129
|
+
}
|
|
130
|
+
`,
|
|
131
|
+
];
|
|
132
|
+
__decorate([
|
|
133
|
+
property({ reflect: true })
|
|
134
|
+
], AriaMenulistElement.prototype, "popover", void 0);
|
|
135
|
+
__decorate([
|
|
136
|
+
property({ reflect: true })
|
|
137
|
+
], AriaMenulistElement.prototype, "focusGroup", void 0);
|
|
138
|
+
//# sourceMappingURL=menulist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menulist.js","sourceRoot":"","sources":["menulist.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;AAEH,qDAAqD;AAErD,OAAO,EAAC,eAAe,EAAE,aAAa,EAAC,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAoB,UAAU,EAAE,GAAG,EAAE,IAAI,EAAC,MAAM,KAAK,CAAC;AAC7D,OAAO,EAAC,QAAQ,EAAC,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EACL,SAAS,EACT,qBAAqB,GACtB,MAAM,sCAAsC,CAAC;AAE9C,iFAAiF;AACjF,MAAM,CAAC,MAAM,uBAAuB,GAAG,aAAa,CAClD,MAAM,CAAC,yBAAyB,CAAC,CAClC,CAAC;AAOF,MAAM,SAAS,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;AAEpD;;GAEG;AACH,MAAM,OAAO,mBAAoB,SAAQ,SAAS;IAwFhD;QACE,KAAK,EAAE,CAAC;QAND,YAAO,GAAG,MAAM,CAAC;QAG1B,eAAU,GAAG,MAAM,CAAC;QAoBZ,WAAM,GAAiC,IAAI,CAAC;QAflD,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,IAAI,EAAE;YACzC,OAAO,EAAE,uBAAuB;SACjC,CAAC,CAAC;QACH,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAExB,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,GAAG,MAAM,CAAC;QAC9B,IAAI,CAAC,SAAS,CAAC,CAAC,eAAe,GAAG,UAAU,CAAC;QAC7C,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9D,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACpE,CAAC;IAEQ,MAAM;QACb,OAAO,IAAI,CAAA,eAAe,CAAC;IAC7B,CAAC;IAIO,YAAY,CAAC,KAAkB;QACrC,IAAI,KAAK,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;YAC9B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAsC,CAAC;QAC7D,CAAC;aAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;YACxE,sEAAsE;YACtE,oCAAoC;YACpC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACzB,CAAC;IACH,CAAC;IAEO,cAAc;QACpB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;YACnC,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;;AAzHe,0BAAM,GAAwB;IAC5C,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA6EF;CACF,AA/EqB,CA+EpB;AAGO;IADR,QAAQ,CAAC,EAAC,OAAO,EAAE,IAAI,EAAC,CAAC;oDACA;AAG1B;IADC,QAAQ,CAAC,EAAC,OAAO,EAAE,IAAI,EAAC,CAAC;uDACN","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/// <reference types=\"../../../types/popover.d.ts\" />\n\nimport {ContextProvider, createContext} from '@lit/context';\nimport {CSSResultOrNative, LitElement, css, html} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {\n internals,\n mixinElementInternals,\n} from '../../behaviors/element-internals.js';\n\n/** The `<md-aria-menulist>` that should own descendant `<md-aria-menuitem>`s. */\nexport const ancestorMenulistContext = createContext<AriaMenulistElement>(\n Symbol('ancestorMenulistContext'),\n);\n\n// `focus` is defined on `HTMLElement` and `SVGElement` directly, not `Element`.\ninterface MaybeFocusableElement extends Element {\n focus?: HTMLElement['focus'];\n}\n\nconst baseClass = mixinElementInternals(LitElement);\n\n/**\n * An element implementing the proposed `<menulist>` built-in element.\n */\nexport class AriaMenulistElement extends baseClass {\n static override styles: CSSResultOrNative[] = [\n css`\n /* Unset UA |[popover]| styles. */\n @layer {\n :host([popover]) {\n position: unset;\n width: unset;\n height: unset;\n color: unset;\n background-color: unset;\n inset: unset;\n margin: unset;\n border: unset;\n border-image: unset;\n padding: unset;\n overflow: unset;\n }\n\n :host([popover]:popover-open) {\n display: unset;\n overlay: unset;\n }\n }\n\n :host {\n display: block;\n position: fixed;\n width: max-content;\n max-block-size: stretch;\n color: canvastext;\n background-color: canvas;\n margin: 0px;\n inset: auto;\n overflow: auto;\n border: 1px solid currentColor;\n border-image: none;\n padding: 0.25em;\n\n /* This should really only apply when the implicit anchor is a menuitem\n * in a menubar, but applies to buttons too? */\n position-area: block-end span-inline-end;\n }\n\n :host(:not(:popover-open)) {\n display: none;\n }\n\n ::slotted(md-aria-menuitem) {\n display: flex;\n align-items: center;\n user-select: none;\n min-inline-size: 24px;\n min-block-size: max(24px, 1lh);\n font-weight: inherit;\n gap: 0.5em;\n padding-inline: 0.5em;\n }\n\n ::slotted(md-aria-menuitem:state(enabled):hover) {\n background-color: color-mix(in lab, currentColor 10%, transparent);\n }\n\n ::slotted(md-aria-menuitem:state(disabled)) {\n color: color-mix(in lab, currentColor 50%, transparent);\n }\n\n ::slotted(hr) {\n color: inherit;\n margin-inline: 0px;\n border: none;\n border-block-start: 1px solid currentColor;\n border-image: none;\n }\n\n ::slotted(a:any-link),\n ::slotted(img[usemap]) {\n display: none;\n }\n `,\n ];\n\n @property({reflect: true})\n override popover = 'auto';\n\n @property({reflect: true})\n focusGroup = 'menu';\n\n constructor() {\n super();\n\n const provider = new ContextProvider(this, {\n context: ancestorMenulistContext,\n });\n provider.setValue(this);\n\n this[internals].role = 'menu';\n this[internals].ariaOrientation = 'vertical';\n this.addEventListener('toggle', this.handleToggle.bind(this));\n this.addEventListener('focusout', this.handleFocusout.bind(this));\n }\n\n override render() {\n return html`<slot></slot>`;\n }\n\n private opener: MaybeFocusableElement | null = null;\n\n private handleToggle(event: ToggleEvent) {\n if (event.newState === 'open') {\n this.opener = event.source as MaybeFocusableElement | null;\n } else if (event.newState === 'closed' && this.matches(':focus-within')) {\n // When closing, restore focus if focus remained in the menulist (e.g.\n // during _keyboard_ light dismiss).\n this.opener?.focus?.();\n }\n }\n\n private handleFocusout() {\n if (!this.matches(':focus-within')) {\n this.hidePopover();\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Queries for an associated element with the given ID that is in the same root
|
|
8
|
+
* as the given element.
|
|
9
|
+
*
|
|
10
|
+
* @param element The element to query from.
|
|
11
|
+
* @param id The ID of the associated element to query for.
|
|
12
|
+
* @return The associated element with the given ID, or null if not found.
|
|
13
|
+
*/
|
|
14
|
+
export declare function queryAssociatedById(element: Element, id: string): Element | null;
|
|
15
|
+
/**
|
|
16
|
+
* Queries for one or more associated elements that match the given
|
|
17
|
+
* space-separated ID string that are in the same root as the given element.
|
|
18
|
+
*
|
|
19
|
+
* @param element The element to query from.
|
|
20
|
+
* @param ids The space-separated IDs of the associated elements to query for.
|
|
21
|
+
* @return An array of associated elements with the given IDs.
|
|
22
|
+
*/
|
|
23
|
+
export declare function queryAssociatedByIds(element: Element, ids: string): Element[];
|