@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.
Files changed (144) hide show
  1. package/custom-elements.json +20910 -18104
  2. package/labs/aria/command.d.ts +18 -0
  3. package/labs/aria/command.js +204 -0
  4. package/labs/aria/command.js.map +1 -0
  5. package/labs/aria/menu/md-aria-menuitem.d.ts +11 -0
  6. package/labs/aria/menu/md-aria-menuitem.js +8 -0
  7. package/labs/aria/menu/md-aria-menuitem.js.map +1 -0
  8. package/labs/aria/menu/md-aria-menulist.d.ts +11 -0
  9. package/labs/aria/menu/md-aria-menulist.js +8 -0
  10. package/labs/aria/menu/md-aria-menulist.js.map +1 -0
  11. package/labs/aria/menu/menuitem.d.ts +26 -0
  12. package/labs/aria/menu/menuitem.js +86 -0
  13. package/labs/aria/menu/menuitem.js.map +1 -0
  14. package/labs/aria/menu/menulist.d.ts +25 -0
  15. package/labs/aria/menu/menulist.js +138 -0
  16. package/labs/aria/menu/menulist.js.map +1 -0
  17. package/labs/aria/query-associated.d.ts +23 -0
  18. package/labs/aria/query-associated.js +36 -0
  19. package/labs/aria/query-associated.js.map +1 -0
  20. package/labs/aria/tabs/md-aria-tab.d.ts +11 -0
  21. package/labs/aria/tabs/md-aria-tab.js +8 -0
  22. package/labs/aria/tabs/md-aria-tab.js.map +1 -0
  23. package/labs/aria/tabs/md-aria-tablist.d.ts +11 -0
  24. package/labs/aria/tabs/md-aria-tablist.js +8 -0
  25. package/labs/aria/tabs/md-aria-tablist.js.map +1 -0
  26. package/labs/aria/tabs/md-aria-tabpanel.d.ts +11 -0
  27. package/labs/aria/tabs/md-aria-tabpanel.js +8 -0
  28. package/labs/aria/tabs/md-aria-tabpanel.js.map +1 -0
  29. package/labs/aria/tabs/tab.d.ts +33 -0
  30. package/labs/aria/tabs/tab.js +88 -0
  31. package/labs/aria/tabs/tab.js.map +1 -0
  32. package/labs/aria/tabs/tablist.d.ts +67 -0
  33. package/labs/aria/tabs/tablist.js +271 -0
  34. package/labs/aria/tabs/tablist.js.map +1 -0
  35. package/labs/aria/tabs/tabpanel.d.ts +26 -0
  36. package/labs/aria/tabs/tabpanel.js +53 -0
  37. package/labs/aria/tabs/tabpanel.js.map +1 -0
  38. package/labs/gb/components/appbar/_app-bar-tokens.scss +136 -0
  39. package/labs/gb/components/appbar/app-bar-element.d.ts +54 -0
  40. package/labs/gb/components/appbar/app-bar-element.js +145 -0
  41. package/labs/gb/components/appbar/app-bar-element.js.map +1 -0
  42. package/labs/gb/components/appbar/app-bar.css +4 -0
  43. package/labs/gb/components/appbar/app-bar.css.map +1 -0
  44. package/labs/gb/components/appbar/app-bar.cssresult.d.ts +3 -0
  45. package/labs/gb/components/appbar/app-bar.cssresult.js +14 -0
  46. package/labs/gb/components/appbar/app-bar.cssresult.js.map +1 -0
  47. package/labs/gb/components/appbar/app-bar.d.ts +71 -0
  48. package/labs/gb/components/appbar/app-bar.js +96 -0
  49. package/labs/gb/components/appbar/app-bar.js.map +1 -0
  50. package/labs/gb/components/appbar/app-bar.scss +167 -0
  51. package/labs/gb/components/appbar/md-gb-app-bar.d.ts +12 -0
  52. package/labs/gb/components/appbar/md-gb-app-bar.js +8 -0
  53. package/labs/gb/components/appbar/md-gb-app-bar.js.map +1 -0
  54. package/labs/gb/components/badge/badge-element.d.ts +1 -0
  55. package/labs/gb/components/badge/badge-element.js +1 -0
  56. package/labs/gb/components/badge/badge-element.js.map +1 -1
  57. package/labs/gb/components/button/_button-tokens.scss +5 -1
  58. package/labs/gb/components/button/button-element.d.ts +2 -0
  59. package/labs/gb/components/button/button-element.js +2 -0
  60. package/labs/gb/components/button/button-element.js.map +1 -1
  61. package/labs/gb/components/button/button.css +1 -1
  62. package/labs/gb/components/button/button.css.map +1 -1
  63. package/labs/gb/components/button/button.cssresult.js +1 -1
  64. package/labs/gb/components/button/button.cssresult.js.map +1 -1
  65. package/labs/gb/components/button/button.scss +1 -0
  66. package/labs/gb/components/card/card-element.d.ts +1 -0
  67. package/labs/gb/components/card/card-element.js +1 -0
  68. package/labs/gb/components/card/card-element.js.map +1 -1
  69. package/labs/gb/components/checkbox/checkbox-element.d.ts +1 -0
  70. package/labs/gb/components/checkbox/checkbox-element.js +1 -0
  71. package/labs/gb/components/checkbox/checkbox-element.js.map +1 -1
  72. package/labs/gb/components/chip/_chip-tokens.scss +167 -0
  73. package/labs/gb/components/chip/chip-element.d.ts +74 -0
  74. package/labs/gb/components/chip/chip-element.js +234 -0
  75. package/labs/gb/components/chip/chip-element.js.map +1 -0
  76. package/labs/gb/components/chip/chip.css +4 -0
  77. package/labs/gb/components/chip/chip.css.map +1 -0
  78. package/labs/gb/components/chip/chip.cssresult.d.ts +3 -0
  79. package/labs/gb/components/chip/chip.cssresult.js +14 -0
  80. package/labs/gb/components/chip/chip.cssresult.js.map +1 -0
  81. package/labs/gb/components/chip/chip.d.ts +77 -0
  82. package/labs/gb/components/chip/chip.js +99 -0
  83. package/labs/gb/components/chip/chip.js.map +1 -0
  84. package/labs/gb/components/chip/chip.scss +99 -0
  85. package/labs/gb/components/chip/md-gb-chip.d.ts +13 -0
  86. package/labs/gb/components/chip/md-gb-chip.js +9 -0
  87. package/labs/gb/components/chip/md-gb-chip.js.map +1 -0
  88. package/labs/gb/components/divider/divider-element.d.ts +1 -0
  89. package/labs/gb/components/divider/divider-element.js +1 -0
  90. package/labs/gb/components/divider/divider-element.js.map +1 -1
  91. package/labs/gb/components/fab/_fab-tokens.scss +4 -1
  92. package/labs/gb/components/fab/fab-element.d.ts +2 -0
  93. package/labs/gb/components/fab/fab-element.js +2 -0
  94. package/labs/gb/components/fab/fab-element.js.map +1 -1
  95. package/labs/gb/components/fab/fab.css +1 -1
  96. package/labs/gb/components/fab/fab.css.map +1 -1
  97. package/labs/gb/components/fab/fab.cssresult.js +1 -1
  98. package/labs/gb/components/fab/fab.cssresult.js.map +1 -1
  99. package/labs/gb/components/fab/fab.scss +1 -0
  100. package/labs/gb/components/iconbutton/icon-button-element.d.ts +1 -0
  101. package/labs/gb/components/iconbutton/icon-button-element.js +1 -0
  102. package/labs/gb/components/iconbutton/icon-button-element.js.map +1 -1
  103. package/labs/gb/components/list/_list-tokens.scss +11 -14
  104. package/labs/gb/components/list/list-element.d.ts +1 -0
  105. package/labs/gb/components/list/list-element.js +1 -0
  106. package/labs/gb/components/list/list-element.js.map +1 -1
  107. package/labs/gb/components/list/list-item-element.d.ts +5 -0
  108. package/labs/gb/components/list/list-item-element.js +5 -0
  109. package/labs/gb/components/list/list-item-element.js.map +1 -1
  110. package/labs/gb/components/list/list.css +1 -1
  111. package/labs/gb/components/list/list.css.map +1 -1
  112. package/labs/gb/components/list/list.cssresult.js +1 -1
  113. package/labs/gb/components/list/list.cssresult.js.map +1 -1
  114. package/labs/gb/components/list/list.scss +5 -0
  115. package/labs/gb/components/menu/_menu-tokens.scss +45 -16
  116. package/labs/gb/components/menu/menu-element.d.ts +1 -0
  117. package/labs/gb/components/menu/menu-element.js +1 -0
  118. package/labs/gb/components/menu/menu-element.js.map +1 -1
  119. package/labs/gb/components/menu/menu-group-element.d.ts +1 -0
  120. package/labs/gb/components/menu/menu-group-element.js +1 -0
  121. package/labs/gb/components/menu/menu-group-element.js.map +1 -1
  122. package/labs/gb/components/menu/menu-item-element.d.ts +5 -1
  123. package/labs/gb/components/menu/menu-item-element.js +5 -1
  124. package/labs/gb/components/menu/menu-item-element.js.map +1 -1
  125. package/labs/gb/components/menu/menu.css +1 -1
  126. package/labs/gb/components/menu/menu.css.map +1 -1
  127. package/labs/gb/components/menu/menu.cssresult.js +1 -1
  128. package/labs/gb/components/menu/menu.cssresult.js.map +1 -1
  129. package/labs/gb/components/menu/menu.scss +3 -0
  130. package/labs/gb/components/radio/radio-element.d.ts +1 -0
  131. package/labs/gb/components/radio/radio-element.js +1 -0
  132. package/labs/gb/components/radio/radio-element.js.map +1 -1
  133. package/labs/gb/components/splitbutton/split-button-element.d.ts +1 -0
  134. package/labs/gb/components/splitbutton/split-button-element.js +1 -0
  135. package/labs/gb/components/splitbutton/split-button-element.js.map +1 -1
  136. package/labs/gb/components/switch/switch-element.d.ts +1 -0
  137. package/labs/gb/components/switch/switch-element.js +1 -0
  138. package/labs/gb/components/switch/switch-element.js.map +1 -1
  139. package/labs/gb/styles/icon/icon-element.d.ts +1 -0
  140. package/labs/gb/styles/icon/icon-element.js +1 -0
  141. package/labs/gb/styles/icon/icon-element.js.map +1 -1
  142. package/package.json +1 -1
  143. package/types/command-event.d.ts +22 -0
  144. 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,11 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { AriaMenuitemElement } from './menuitem.js';
7
+ declare global {
8
+ interface HTMLElementTagNameMap {
9
+ 'md-aria-menuitem': AriaMenuitemElement;
10
+ }
11
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { AriaMenuitemElement } from './menuitem.js';
7
+ customElements.define('md-aria-menuitem', AriaMenuitemElement);
8
+ //# sourceMappingURL=md-aria-menuitem.js.map
@@ -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,11 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { AriaMenulistElement } from './menulist.js';
7
+ declare global {
8
+ interface HTMLElementTagNameMap {
9
+ 'md-aria-menulist': AriaMenulistElement;
10
+ }
11
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { AriaMenulistElement } from './menulist.js';
7
+ customElements.define('md-aria-menulist', AriaMenulistElement);
8
+ //# sourceMappingURL=md-aria-menulist.js.map
@@ -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[];