@material/web 2.5.1-nightly.56a486b.0 → 2.5.1-nightly.703aed2.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 (189) hide show
  1. package/custom-elements.json +29543 -23432
  2. package/labs/aria/buttons/keyboard_click_handler.d.ts +25 -0
  3. package/labs/aria/buttons/keyboard_click_handler.js +74 -0
  4. package/labs/aria/buttons/keyboard_click_handler.js.map +1 -0
  5. package/labs/aria/buttons/md-aria-toggle.d.ts +29 -0
  6. package/labs/aria/buttons/md-aria-toggle.js +67 -0
  7. package/labs/aria/buttons/md-aria-toggle.js.map +1 -0
  8. package/labs/aria/buttons/toggle.d.ts +40 -0
  9. package/labs/aria/buttons/toggle.js +100 -0
  10. package/labs/aria/buttons/toggle.js.map +1 -0
  11. package/labs/aria/menu/fieldset.d.ts +36 -0
  12. package/labs/aria/menu/fieldset.js +103 -0
  13. package/labs/aria/menu/fieldset.js.map +1 -0
  14. package/labs/aria/menu/internal.d.ts +15 -0
  15. package/labs/aria/menu/internal.js +16 -0
  16. package/labs/aria/menu/internal.js.map +1 -0
  17. package/labs/aria/menu/md-aria-fieldset.d.ts +11 -0
  18. package/labs/aria/menu/md-aria-fieldset.js +8 -0
  19. package/labs/aria/menu/md-aria-fieldset.js.map +1 -0
  20. package/labs/aria/menu/md-aria-menubar.d.ts +11 -0
  21. package/labs/aria/menu/md-aria-menubar.js +8 -0
  22. package/labs/aria/menu/md-aria-menubar.js.map +1 -0
  23. package/labs/aria/menu/menubar.d.ts +15 -0
  24. package/labs/aria/menu/menubar.js +45 -0
  25. package/labs/aria/menu/menubar.js.map +1 -0
  26. package/labs/aria/menu/menuitem.d.ts +37 -4
  27. package/labs/aria/menu/menuitem.js +172 -21
  28. package/labs/aria/menu/menuitem.js.map +1 -1
  29. package/labs/aria/menu/menulist.d.ts +2 -6
  30. package/labs/aria/menu/menulist.js +12 -46
  31. package/labs/aria/menu/menulist.js.map +1 -1
  32. package/labs/aria/menu/shared-slotted-content.d.ts +10 -0
  33. package/labs/aria/menu/shared-slotted-content.js +51 -0
  34. package/labs/aria/menu/shared-slotted-content.js.map +1 -0
  35. package/labs/aria/pseudo-classes.d.ts +19 -0
  36. package/labs/aria/pseudo-classes.js +22 -0
  37. package/labs/aria/pseudo-classes.js.map +1 -0
  38. package/labs/aria/tabs/tab.js +5 -0
  39. package/labs/aria/tabs/tab.js.map +1 -1
  40. package/labs/gb/components/appbar/app-bar.css +1 -1
  41. package/labs/gb/components/appbar/app-bar.css.map +1 -1
  42. package/labs/gb/components/appbar/app-bar.cssresult.js +1 -1
  43. package/labs/gb/components/appbar/app-bar.cssresult.js.map +1 -1
  44. package/labs/gb/components/appbar/app-bar.scss +1 -0
  45. package/labs/gb/components/badge/badge.css +1 -1
  46. package/labs/gb/components/badge/badge.css.map +1 -1
  47. package/labs/gb/components/badge/badge.cssresult.js +1 -1
  48. package/labs/gb/components/badge/badge.cssresult.js.map +1 -1
  49. package/labs/gb/components/badge/badge.scss +1 -0
  50. package/labs/gb/components/button/button-element.d.ts +2 -0
  51. package/labs/gb/components/button/button-element.js +15 -2
  52. package/labs/gb/components/button/button-element.js.map +1 -1
  53. package/labs/gb/components/button/button.css +1 -1
  54. package/labs/gb/components/button/button.css.map +1 -1
  55. package/labs/gb/components/button/button.cssresult.js +1 -1
  56. package/labs/gb/components/button/button.cssresult.js.map +1 -1
  57. package/labs/gb/components/button/button.scss +1 -0
  58. package/labs/gb/components/buttongroup/_button-group-tokens.scss +123 -0
  59. package/labs/gb/components/buttongroup/button-group-element.d.ts +65 -0
  60. package/labs/gb/components/buttongroup/button-group-element.js +277 -0
  61. package/labs/gb/components/buttongroup/button-group-element.js.map +1 -0
  62. package/labs/gb/components/buttongroup/button-group.css +5 -0
  63. package/labs/gb/components/buttongroup/button-group.css.map +1 -0
  64. package/labs/gb/components/buttongroup/button-group.cssresult.d.ts +3 -0
  65. package/labs/gb/components/buttongroup/button-group.cssresult.js +15 -0
  66. package/labs/gb/components/buttongroup/button-group.cssresult.js.map +1 -0
  67. package/labs/gb/components/buttongroup/button-group.d.ts +96 -0
  68. package/labs/gb/components/buttongroup/button-group.js +105 -0
  69. package/labs/gb/components/buttongroup/button-group.js.map +1 -0
  70. package/labs/gb/components/buttongroup/button-group.scss +282 -0
  71. package/labs/gb/components/buttongroup/md-gb-button-group.d.ts +12 -0
  72. package/labs/gb/components/buttongroup/md-gb-button-group.js +8 -0
  73. package/labs/gb/components/buttongroup/md-gb-button-group.js.map +1 -0
  74. package/labs/gb/components/chip/chip.css +1 -1
  75. package/labs/gb/components/chip/chip.css.map +1 -1
  76. package/labs/gb/components/chip/chip.cssresult.js +1 -1
  77. package/labs/gb/components/chip/chip.cssresult.js.map +1 -1
  78. package/labs/gb/components/chip/chip.scss +1 -0
  79. package/labs/gb/components/fab/fab.css +1 -1
  80. package/labs/gb/components/fab/fab.css.map +1 -1
  81. package/labs/gb/components/fab/fab.cssresult.js +1 -1
  82. package/labs/gb/components/fab/fab.cssresult.js.map +1 -1
  83. package/labs/gb/components/fab/fab.scss +1 -0
  84. package/labs/gb/components/iconbutton/icon-button-element.d.ts +2 -0
  85. package/labs/gb/components/iconbutton/icon-button-element.js +15 -2
  86. package/labs/gb/components/iconbutton/icon-button-element.js.map +1 -1
  87. package/labs/gb/components/iconbutton/icon-button.css +1 -1
  88. package/labs/gb/components/iconbutton/icon-button.css.map +1 -1
  89. package/labs/gb/components/iconbutton/icon-button.cssresult.js +1 -1
  90. package/labs/gb/components/iconbutton/icon-button.cssresult.js.map +1 -1
  91. package/labs/gb/components/iconbutton/icon-button.scss +1 -0
  92. package/labs/gb/components/list/list.css +1 -1
  93. package/labs/gb/components/list/list.css.map +1 -1
  94. package/labs/gb/components/list/list.cssresult.js +1 -1
  95. package/labs/gb/components/list/list.cssresult.js.map +1 -1
  96. package/labs/gb/components/list/list.scss +1 -0
  97. package/labs/gb/components/menu/menu.css +1 -1
  98. package/labs/gb/components/menu/menu.css.map +1 -1
  99. package/labs/gb/components/menu/menu.cssresult.js +1 -1
  100. package/labs/gb/components/menu/menu.cssresult.js.map +1 -1
  101. package/labs/gb/components/menu/menu.scss +1 -0
  102. package/labs/gb/components/navbar/_nav-bar-tokens.scss +53 -0
  103. package/labs/gb/components/navbar/md-gb-nav-bar-item.d.ts +12 -0
  104. package/labs/gb/components/navbar/md-gb-nav-bar-item.js +10 -0
  105. package/labs/gb/components/navbar/md-gb-nav-bar-item.js.map +1 -0
  106. package/labs/gb/components/navbar/md-gb-nav-bar.d.ts +12 -0
  107. package/labs/gb/components/navbar/md-gb-nav-bar.js +10 -0
  108. package/labs/gb/components/navbar/md-gb-nav-bar.js.map +1 -0
  109. package/labs/gb/components/navbar/nav-bar-element.d.ts +58 -0
  110. package/labs/gb/components/navbar/nav-bar-element.js +116 -0
  111. package/labs/gb/components/navbar/nav-bar-element.js.map +1 -0
  112. package/labs/gb/components/navbar/nav-bar-item-element.d.ts +41 -0
  113. package/labs/gb/components/navbar/nav-bar-item-element.js +146 -0
  114. package/labs/gb/components/navbar/nav-bar-item-element.js.map +1 -0
  115. package/labs/gb/components/navbar/nav-bar.css +4 -0
  116. package/labs/gb/components/navbar/nav-bar.css.map +1 -0
  117. package/labs/gb/components/navbar/nav-bar.cssresult.d.ts +3 -0
  118. package/labs/gb/components/navbar/nav-bar.cssresult.js +14 -0
  119. package/labs/gb/components/navbar/nav-bar.cssresult.js.map +1 -0
  120. package/labs/gb/components/navbar/nav-bar.d.ts +86 -0
  121. package/labs/gb/components/navbar/nav-bar.js +92 -0
  122. package/labs/gb/components/navbar/nav-bar.js.map +1 -0
  123. package/labs/gb/components/navbar/nav-bar.scss +295 -0
  124. package/labs/gb/components/shared/pseudo-classes.d.ts +1 -7
  125. package/labs/gb/components/shared/pseudo-classes.js +1 -9
  126. package/labs/gb/components/shared/pseudo-classes.js.map +1 -1
  127. package/labs/gb/components/shared/update-class-list.d.ts +22 -0
  128. package/labs/gb/components/shared/update-class-list.js +26 -0
  129. package/labs/gb/components/shared/update-class-list.js.map +1 -0
  130. package/labs/gb/components/slider/_slider-tokens.scss +82 -0
  131. package/labs/gb/components/slider/md-gb-slider.d.ts +12 -0
  132. package/labs/gb/components/slider/md-gb-slider.js +8 -0
  133. package/labs/gb/components/slider/md-gb-slider.js.map +1 -0
  134. package/labs/gb/components/slider/slider-element.d.ts +145 -0
  135. package/labs/gb/components/slider/slider-element.js +934 -0
  136. package/labs/gb/components/slider/slider-element.js.map +1 -0
  137. package/labs/gb/components/slider/slider.css +1 -0
  138. package/labs/gb/components/slider/slider.css.map +1 -0
  139. package/labs/gb/components/slider/slider.cssresult.d.ts +3 -0
  140. package/labs/gb/components/slider/slider.cssresult.js +11 -0
  141. package/labs/gb/components/slider/slider.cssresult.js.map +1 -0
  142. package/labs/gb/components/slider/slider.d.ts +169 -0
  143. package/labs/gb/components/slider/slider.js +452 -0
  144. package/labs/gb/components/slider/slider.js.map +1 -0
  145. package/labs/gb/components/slider/slider.scss +661 -0
  146. package/labs/gb/components/tabs/_tabs-tokens.scss +177 -0
  147. package/labs/gb/components/tabs/md-gb-tab.d.ts +12 -0
  148. package/labs/gb/components/tabs/md-gb-tab.js +8 -0
  149. package/labs/gb/components/tabs/md-gb-tab.js.map +1 -0
  150. package/labs/gb/components/tabs/md-gb-tabs.d.ts +12 -0
  151. package/labs/gb/components/tabs/md-gb-tabs.js +8 -0
  152. package/labs/gb/components/tabs/md-gb-tabs.js.map +1 -0
  153. package/labs/gb/components/tabs/tab-element.d.ts +42 -0
  154. package/labs/gb/components/tabs/tab-element.js +75 -0
  155. package/labs/gb/components/tabs/tab-element.js.map +1 -0
  156. package/labs/gb/components/tabs/tabs-element.d.ts +37 -0
  157. package/labs/gb/components/tabs/tabs-element.js +67 -0
  158. package/labs/gb/components/tabs/tabs-element.js.map +1 -0
  159. package/labs/gb/components/tabs/tabs.css +4 -0
  160. package/labs/gb/components/tabs/tabs.css.map +1 -0
  161. package/labs/gb/components/tabs/tabs.cssresult.d.ts +3 -0
  162. package/labs/gb/components/tabs/tabs.cssresult.js +14 -0
  163. package/labs/gb/components/tabs/tabs.cssresult.js.map +1 -0
  164. package/labs/gb/components/tabs/tabs.d.ts +98 -0
  165. package/labs/gb/components/tabs/tabs.js +112 -0
  166. package/labs/gb/components/tabs/tabs.js.map +1 -0
  167. package/labs/gb/components/tabs/tabs.scss +301 -0
  168. package/labs/gb/components/toolbar/_toolbar-tokens.scss +70 -0
  169. package/labs/gb/components/toolbar/md-gb-toolbar.d.ts +12 -0
  170. package/labs/gb/components/toolbar/md-gb-toolbar.js +8 -0
  171. package/labs/gb/components/toolbar/md-gb-toolbar.js.map +1 -0
  172. package/labs/gb/components/toolbar/toolbar-element.d.ts +56 -0
  173. package/labs/gb/components/toolbar/toolbar-element.js +120 -0
  174. package/labs/gb/components/toolbar/toolbar-element.js.map +1 -0
  175. package/labs/gb/components/toolbar/toolbar.css +4 -0
  176. package/labs/gb/components/toolbar/toolbar.css.map +1 -0
  177. package/labs/gb/components/toolbar/toolbar.cssresult.d.ts +3 -0
  178. package/labs/gb/components/toolbar/toolbar.cssresult.js +14 -0
  179. package/labs/gb/components/toolbar/toolbar.cssresult.js.map +1 -0
  180. package/labs/gb/components/toolbar/toolbar.d.ts +56 -0
  181. package/labs/gb/components/toolbar/toolbar.js +60 -0
  182. package/labs/gb/components/toolbar/toolbar.js.map +1 -0
  183. package/labs/gb/components/toolbar/toolbar.scss +240 -0
  184. package/labs/gb/styles/tailwind.css +1 -1
  185. package/labs/gb/styles/tailwind.css.map +1 -1
  186. package/labs/gb/styles/tailwind.cssresult.js +1 -1
  187. package/labs/gb/styles/tailwind.cssresult.js.map +1 -1
  188. package/labs/gb/styles/tailwind.scss +2 -0
  189. package/package.json +1 -1
@@ -0,0 +1,45 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { LitElement, css, html } from 'lit';
7
+ import { internals, mixinElementInternals, } from '../../behaviors/element-internals.js';
8
+ import { sharedSlottedContentStyles } from './shared-slotted-content.js';
9
+ const baseClass = mixinElementInternals(LitElement);
10
+ /** An element implementing the proposed `<menubar>` built-in element. */
11
+ export class AriaMenubarElement extends baseClass {
12
+ constructor() {
13
+ super();
14
+ this[internals].role = 'menubar';
15
+ this[internals].ariaOrientation = 'horizontal';
16
+ }
17
+ updated(changedProperties) {
18
+ super.updated(changedProperties);
19
+ if (!this.hasAttribute('focusgroup')) {
20
+ this.setAttribute('focusgroup', 'menubar');
21
+ }
22
+ }
23
+ render() {
24
+ return html `<slot></slot>`;
25
+ }
26
+ }
27
+ AriaMenubarElement.styles = [
28
+ css `
29
+ :host {
30
+ display: inline-flex;
31
+ flex-direction: row;
32
+ width: max-content;
33
+ background-color: transparent;
34
+ gap: 0.5em;
35
+ border-width: 1px;
36
+ border-style: solid;
37
+ border-color: currentcolor;
38
+ border-image: none;
39
+ border-radius: 0.25em;
40
+ padding: 0.25em;
41
+ }
42
+ `,
43
+ sharedSlottedContentStyles,
44
+ ];
45
+ //# sourceMappingURL=menubar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menubar.js","sourceRoot":"","sources":["menubar.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAoB,UAAU,EAAkB,GAAG,EAAE,IAAI,EAAC,MAAM,KAAK,CAAC;AAC7E,OAAO,EACL,SAAS,EACT,qBAAqB,GACtB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAC,0BAA0B,EAAC,MAAM,6BAA6B,CAAC;AAEvE,MAAM,SAAS,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;AAEpD,yEAAyE;AACzE,MAAM,OAAO,kBAAmB,SAAQ,SAAS;IAoB/C;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,GAAG,SAAS,CAAC;QACjC,IAAI,CAAC,SAAS,CAAC,CAAC,eAAe,GAAG,YAAY,CAAC;IACjD,CAAC;IAEkB,OAAO,CAAC,iBAAuC;QAChE,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAEjC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAEQ,MAAM;QACb,OAAO,IAAI,CAAA,eAAe,CAAC;IAC7B,CAAC;;AAnCe,yBAAM,GAAwB;IAC5C,GAAG,CAAA;;;;;;;;;;;;;;KAcF;IACD,0BAA0B;CAC3B,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {CSSResultOrNative, LitElement, PropertyValues, css, html} from 'lit';\nimport {\n internals,\n mixinElementInternals,\n} from '../../behaviors/element-internals.js';\nimport {sharedSlottedContentStyles} from './shared-slotted-content.js';\n\nconst baseClass = mixinElementInternals(LitElement);\n\n/** An element implementing the proposed `<menubar>` built-in element. */\nexport class AriaMenubarElement extends baseClass {\n static override styles: CSSResultOrNative[] = [\n css`\n :host {\n display: inline-flex;\n flex-direction: row;\n width: max-content;\n background-color: transparent;\n gap: 0.5em;\n border-width: 1px;\n border-style: solid;\n border-color: currentcolor;\n border-image: none;\n border-radius: 0.25em;\n padding: 0.25em;\n }\n `,\n sharedSlottedContentStyles,\n ];\n\n constructor() {\n super();\n this[internals].role = 'menubar';\n this[internals].ariaOrientation = 'horizontal';\n }\n\n protected override updated(changedProperties: PropertyValues<this>) {\n super.updated(changedProperties);\n\n if (!this.hasAttribute('focusgroup')) {\n this.setAttribute('focusgroup', 'menubar');\n }\n }\n\n override render() {\n return html`<slot></slot>`;\n }\n}\n"]}
@@ -4,23 +4,56 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
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;
7
+ import { setCheckedness, updateUsedValues } from './internal.js';
10
8
  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
9
  /**
12
10
  * An element implementing the proposed `<menuitem>` built-in element.
13
11
  *
12
+ * @fires {Event} checked - Fired when the item is checked or unchecked.
14
13
  * @cssstate enabled - True when the item is enabled.
15
14
  * @cssstate disabled - True when the item is disabled.
15
+ * @cssstate checked - True when the item is checked.
16
16
  */
17
17
  export declare class AriaMenuitemElement extends baseClass {
18
18
  static styles: CSSResultOrNative[];
19
- [ancestorMenulist]?: AriaMenulistElement;
19
+ private internalDisabled;
20
+ private checkedness;
21
+ private dirtyCheckedness;
22
+ private internalDefaultChecked;
23
+ private cachedAncestorMenulist;
24
+ private cachedAncestorFieldset;
25
+ private get usedCheckable();
26
+ private get usedDisabled();
27
+ /**
28
+ * Recomputes this element's used `disabled` and `checkable` values and
29
+ * projects them onto its ARIA attributes and custom states.
30
+ *
31
+ * `<md-aria-fieldset>` calls this on its items when a value they inherit from
32
+ * it changes.
33
+ */
34
+ [updateUsedValues](): void;
35
+ private resetAncestorElementCache;
36
+ /**
37
+ * Sets this element's checkedness directly, without running the rest of the
38
+ * 'check a menuitem element' steps.
39
+ *
40
+ * `<md-aria-fieldset>` calls this to reset the items excluded by a newly
41
+ * checked item.
42
+ *
43
+ * @param value The new checkedness.
44
+ */
45
+ [setCheckedness](value: boolean): void;
46
+ private checkAMenuitemElement;
20
47
  get disabled(): boolean;
21
48
  set disabled(value: boolean);
49
+ get checked(): boolean;
50
+ set checked(value: boolean);
51
+ get defaultChecked(): boolean;
52
+ set defaultChecked(value: boolean);
22
53
  constructor();
23
54
  render(): import("lit-html").TemplateResult<1>;
55
+ connectedCallback(): void;
56
+ disconnectedCallback(): void;
24
57
  click(): void;
25
58
  }
26
59
  export {};
@@ -3,9 +3,7 @@
3
3
  * Copyright 2026 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- var _a;
7
6
  import { __decorate } from "tslib";
8
- import { consume } from '@lit/context';
9
7
  import { LitElement, css, html } from 'lit';
10
8
  import { property } from 'lit/decorators.js';
11
9
  import { afterDispatch, setupDispatchHooks, } from '../../../internal/events/dispatch-hooks.js';
@@ -13,32 +11,150 @@ import { mixinCustomStateSet, toggleState, } from '../../behaviors/custom-state-
13
11
  import { internals, mixinElementInternals, } from '../../behaviors/element-internals.js';
14
12
  import { mixinFocusable } from '../../behaviors/focusable.js';
15
13
  import { sharedCommandInvokerActivationSteps } from '../command.js';
16
- import { ancestorMenulistContext } from './menulist.js';
17
- /** Private property key for the `ancestorMenulist` context. */
18
- const ancestorMenulist = Symbol('ancestorMenulist');
14
+ import { resetMenuitemCheckedness, setCheckedness, updateUsedValues, } from './internal.js';
19
15
  const baseClass = mixinCustomStateSet(mixinFocusable(mixinElementInternals(LitElement)));
20
16
  /**
21
17
  * An element implementing the proposed `<menuitem>` built-in element.
22
18
  *
19
+ * @fires {Event} checked - Fired when the item is checked or unchecked.
23
20
  * @cssstate enabled - True when the item is enabled.
24
21
  * @cssstate disabled - True when the item is disabled.
22
+ * @cssstate checked - True when the item is checked.
25
23
  */
26
24
  export class AriaMenuitemElement extends baseClass {
25
+ get usedCheckable() {
26
+ if (this.cachedAncestorMenulist === null ||
27
+ this.cachedAncestorFieldset === null) {
28
+ return null;
29
+ }
30
+ return this.cachedAncestorFieldset.checkable;
31
+ }
32
+ get usedDisabled() {
33
+ return this.cachedAncestorFieldset?.disabled || this.internalDisabled;
34
+ }
35
+ /**
36
+ * Recomputes this element's used `disabled` and `checkable` values and
37
+ * projects them onto its ARIA attributes and custom states.
38
+ *
39
+ * `<md-aria-fieldset>` calls this on its items when a value they inherit from
40
+ * it changes.
41
+ */
42
+ [updateUsedValues]() {
43
+ const usedDisabled = this.usedDisabled;
44
+ this[internals].ariaDisabled = String(usedDisabled);
45
+ this[toggleState]('disabled', usedDisabled);
46
+ this[toggleState]('enabled', !usedDisabled);
47
+ const usedCheckable = this.usedCheckable;
48
+ switch (usedCheckable) {
49
+ case null:
50
+ this[internals].role = 'menuitem';
51
+ this[toggleState]('_checkable', false);
52
+ break;
53
+ case 'single':
54
+ this[internals].role = 'menuitemradio';
55
+ this[toggleState]('_checkable', true);
56
+ break;
57
+ case 'multiple':
58
+ default:
59
+ this[internals].role = 'menuitemcheckbox';
60
+ this[toggleState]('_checkable', true);
61
+ break;
62
+ }
63
+ const usedChecked = usedCheckable !== null ? this.checkedness : null;
64
+ if (usedChecked === null) {
65
+ this[internals].ariaChecked = null;
66
+ this[toggleState]('checked', false);
67
+ }
68
+ else {
69
+ this[internals].ariaChecked = String(usedChecked);
70
+ this[toggleState]('checked', usedChecked);
71
+ }
72
+ }
73
+ resetAncestorElementCache() {
74
+ this.cachedAncestorMenulist = null;
75
+ this.cachedAncestorFieldset = null;
76
+ for (let node = this.parentNode; node instanceof HTMLElement; node = node.parentNode) {
77
+ if (node.localName === 'md-aria-menulist') {
78
+ this.cachedAncestorMenulist = node;
79
+ break;
80
+ }
81
+ if (node.localName === 'md-aria-fieldset') {
82
+ this.cachedAncestorFieldset = node;
83
+ }
84
+ }
85
+ this[updateUsedValues]();
86
+ }
87
+ /**
88
+ * Sets this element's checkedness directly, without running the rest of the
89
+ * 'check a menuitem element' steps.
90
+ *
91
+ * `<md-aria-fieldset>` calls this to reset the items excluded by a newly
92
+ * checked item.
93
+ *
94
+ * @param value The new checkedness.
95
+ */
96
+ [setCheckedness](value) {
97
+ this.checkedness = value;
98
+ this[updateUsedValues]();
99
+ }
100
+ checkAMenuitemElement(isChecked, fireEvents) {
101
+ if (this.usedCheckable === null) {
102
+ // TODO: Handle the invoked submenu.
103
+ return 'close-menulist';
104
+ }
105
+ this[setCheckedness](isChecked);
106
+ this.dirtyCheckedness = true;
107
+ if (fireEvents) {
108
+ this.dispatchEvent(new Event('checked'));
109
+ }
110
+ if (this.checkedness && this.usedCheckable === 'single') {
111
+ this.cachedAncestorFieldset?.[resetMenuitemCheckedness](this);
112
+ }
113
+ return this.usedCheckable === 'single' ? 'close-menulist' : 'stay-open';
114
+ }
27
115
  get disabled() {
28
- return this[internals].ariaDisabled === 'true';
116
+ return this.internalDisabled;
29
117
  }
30
118
  set disabled(value) {
31
- const oldValue = this.disabled;
32
119
  value = Boolean(value);
33
- this[internals].ariaDisabled = String(value);
34
- this[toggleState]('disabled', value);
35
- this[toggleState]('enabled', !value);
120
+ const oldValue = this.internalDisabled;
121
+ this.internalDisabled = value;
122
+ this[updateUsedValues]();
36
123
  this.requestUpdate('disabled', oldValue);
37
124
  }
125
+ get checked() {
126
+ return this.checkedness;
127
+ }
128
+ set checked(value) {
129
+ this.checkAMenuitemElement(value, false);
130
+ }
131
+ get defaultChecked() {
132
+ return this.internalDefaultChecked;
133
+ }
134
+ set defaultChecked(value) {
135
+ value = Boolean(value);
136
+ const oldValue = this.internalDefaultChecked;
137
+ this.internalDefaultChecked = value;
138
+ if (!this.dirtyCheckedness) {
139
+ // The proposed spec DOES NOT call into the full 'check a menuitem
140
+ // element' steps - it only sets checkedness - but this seems like the
141
+ // only reasonable behavior when the element is part of a single-checkable
142
+ // fieldset. Otherwise, multiple elements with `defaultchecked` could
143
+ // become checked.
144
+ this.checkAMenuitemElement(value, false);
145
+ this.dirtyCheckedness = false;
146
+ }
147
+ this.requestUpdate('defaultChecked', oldValue);
148
+ }
38
149
  constructor() {
39
150
  super();
40
- this[internals].role = 'menuitem';
41
- this.disabled = false;
151
+ this.internalDisabled = false;
152
+ this.checkedness = false;
153
+ this.dirtyCheckedness = false;
154
+ this.internalDefaultChecked = false;
155
+ this.cachedAncestorMenulist = null;
156
+ this.cachedAncestorFieldset = null;
157
+ this[updateUsedValues]();
42
158
  setupDispatchHooks(this, 'keydown', 'click');
43
159
  this.addEventListener('keydown', (event) => {
44
160
  afterDispatch(event, () => {
@@ -52,35 +168,70 @@ export class AriaMenuitemElement extends baseClass {
52
168
  });
53
169
  this.addEventListener('click', (event) => {
54
170
  afterDispatch(event, () => {
55
- if (event.defaultPrevented || this.disabled) {
171
+ if (event.defaultPrevented || this.usedDisabled) {
56
172
  return;
57
173
  }
58
- this[ancestorMenulist]?.hidePopover();
174
+ const newChecked = !this.checkedness;
175
+ const closeBehavior = this.checkAMenuitemElement(newChecked, true);
176
+ // TODO: Handle the invoked submenu.
177
+ if (closeBehavior === 'close-menulist') {
178
+ // TODO: This should be the 'outermost containing menulist', not just
179
+ // the cached ancestor menulist.
180
+ this.cachedAncestorMenulist?.hidePopover();
181
+ }
59
182
  sharedCommandInvokerActivationSteps(this, event);
60
183
  });
61
184
  });
62
185
  }
63
186
  render() {
64
- return html `<slot></slot>`;
187
+ return html `<span part="checkmark"></span><slot></slot>`;
188
+ }
189
+ connectedCallback() {
190
+ super.connectedCallback();
191
+ this.resetAncestorElementCache();
192
+ if (this.internalDefaultChecked && !this.dirtyCheckedness) {
193
+ this.checkAMenuitemElement(true, false);
194
+ this.dirtyCheckedness = false;
195
+ }
196
+ }
197
+ disconnectedCallback() {
198
+ super.disconnectedCallback();
199
+ this.resetAncestorElementCache();
65
200
  }
66
201
  click() {
67
- if (!this.disabled) {
202
+ if (!this.usedDisabled) {
68
203
  super.click();
69
204
  }
70
205
  }
71
206
  }
72
- _a = ancestorMenulist;
73
207
  AriaMenuitemElement.styles = [
74
208
  css `
75
209
  :host {
76
210
  display: inline-flex;
77
211
  }
212
+
213
+ [part='checkmark'] {
214
+ &::before {
215
+ content: '\\2713' / '';
216
+ }
217
+
218
+ :host(:not(:state(_checkable))) & {
219
+ display: none;
220
+ }
221
+
222
+ :host(:not(:state(checked))) & {
223
+ visibility: hidden;
224
+ }
225
+ }
78
226
  `,
79
227
  ];
80
228
  __decorate([
81
- consume({ context: ancestorMenulistContext, subscribe: true })
82
- ], AriaMenuitemElement.prototype, _a, void 0);
83
- __decorate([
84
- property({ type: Boolean, reflect: true, noAccessor: true })
229
+ property({ type: Boolean, reflect: true })
85
230
  ], AriaMenuitemElement.prototype, "disabled", null);
231
+ __decorate([
232
+ property({ type: Boolean, attribute: false })
233
+ ], AriaMenuitemElement.prototype, "checked", null);
234
+ __decorate([
235
+ property({ type: Boolean, reflect: true })
236
+ ], AriaMenuitemElement.prototype, "defaultChecked", null);
86
237
  //# sourceMappingURL=menuitem.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"menuitem.js","sourceRoot":"","sources":["menuitem.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;;AAEH,OAAO,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AACrC,OAAO,EAAoB,UAAU,EAAE,GAAG,EAAE,IAAI,EAAC,MAAM,KAAK,CAAC;AAC7D,OAAO,EAAC,QAAQ,EAAC,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EACL,aAAa,EACb,kBAAkB,GACnB,MAAM,4CAA4C,CAAC;AACpD,OAAO,EACL,mBAAmB,EACnB,WAAW,GACZ,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,SAAS,EACT,qBAAqB,GACtB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAC,cAAc,EAAC,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAC,mCAAmC,EAAC,MAAM,eAAe,CAAC;AAClE,OAAO,EAAsB,uBAAuB,EAAC,MAAM,eAAe,CAAC;AAE3E,+DAA+D;AAC/D,MAAM,gBAAgB,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAEpD,MAAM,SAAS,GAAG,mBAAmB,CACnC,cAAc,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC,CAClD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,OAAO,mBAAoB,SAAQ,SAAS;IAahD,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,YAAY,KAAK,MAAM,CAAC;IACjD,CAAC;IACD,IAAI,QAAQ,CAAC,KAAc;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/B,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QACvB,IAAI,CAAC,SAAS,CAAC,CAAC,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,CAAC,WAAW,CAAC,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QACrC,IAAI,CAAC,WAAW,CAAC,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC3C,CAAC;IAED;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,GAAG,UAAU,CAAC;QAClC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QAEtB,kBAAkB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAC7C,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,KAAoB,EAAE,EAAE;YACxD,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE;gBACxB,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;oBAC3B,OAAO;gBACT,CAAC;gBAED,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;oBAC/C,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE;YAC9C,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE;gBACxB,IAAI,KAAK,CAAC,gBAAgB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAC5C,OAAO;gBACT,CAAC;gBAED,IAAI,CAAC,gBAAgB,CAAC,EAAE,WAAW,EAAE,CAAC;gBACtC,mCAAmC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACnD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAEQ,MAAM;QACb,OAAO,IAAI,CAAA,eAAe,CAAC;IAC7B,CAAC;IAEQ,KAAK;QACZ,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;;KApDA,gBAAgB;AATD,0BAAM,GAAwB;IAC5C,GAAG,CAAA;;;;KAIF;CACF,CAAC;AAGF;IADC,OAAO,CAAC,EAAC,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,IAAI,EAAC,CAAC;6CACpB;AAGzC;IADC,QAAQ,CAAC,EAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAC,CAAC;mDAG1D","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"]}
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 {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 type {AriaFieldsetElement, CheckableState} from './fieldset.js';\nimport {\n resetMenuitemCheckedness,\n setCheckedness,\n updateUsedValues,\n} from './internal.js';\nimport type {AriaMenulistElement} from './menulist.js';\n\nconst baseClass = mixinCustomStateSet(\n mixinFocusable(mixinElementInternals(LitElement)),\n);\n\n/**\n * An element implementing the proposed `<menuitem>` built-in element.\n *\n * @fires {Event} checked - Fired when the item is checked or unchecked.\n * @cssstate enabled - True when the item is enabled.\n * @cssstate disabled - True when the item is disabled.\n * @cssstate checked - True when the item is checked.\n */\nexport class AriaMenuitemElement extends baseClass {\n static override styles: CSSResultOrNative[] = [\n css`\n :host {\n display: inline-flex;\n }\n\n [part='checkmark'] {\n &::before {\n content: '\\\\2713' / '';\n }\n\n :host(:not(:state(_checkable))) & {\n display: none;\n }\n\n :host(:not(:state(checked))) & {\n visibility: hidden;\n }\n }\n `,\n ];\n\n private internalDisabled = false;\n private checkedness = false;\n private dirtyCheckedness = false;\n private internalDefaultChecked = false;\n private cachedAncestorMenulist: AriaMenulistElement | null = null;\n private cachedAncestorFieldset: AriaFieldsetElement | null = null;\n\n private get usedCheckable(): CheckableState {\n if (\n this.cachedAncestorMenulist === null ||\n this.cachedAncestorFieldset === null\n ) {\n return null;\n }\n\n return this.cachedAncestorFieldset.checkable;\n }\n\n private get usedDisabled(): boolean {\n return this.cachedAncestorFieldset?.disabled || this.internalDisabled;\n }\n\n /**\n * Recomputes this element's used `disabled` and `checkable` values and\n * projects them onto its ARIA attributes and custom states.\n *\n * `<md-aria-fieldset>` calls this on its items when a value they inherit from\n * it changes.\n */\n [updateUsedValues]() {\n const usedDisabled = this.usedDisabled;\n this[internals].ariaDisabled = String(usedDisabled);\n this[toggleState]('disabled', usedDisabled);\n this[toggleState]('enabled', !usedDisabled);\n\n const usedCheckable = this.usedCheckable;\n switch (usedCheckable) {\n case null:\n this[internals].role = 'menuitem';\n this[toggleState]('_checkable', false);\n break;\n case 'single':\n this[internals].role = 'menuitemradio';\n this[toggleState]('_checkable', true);\n break;\n case 'multiple':\n default:\n this[internals].role = 'menuitemcheckbox';\n this[toggleState]('_checkable', true);\n break;\n }\n\n const usedChecked: boolean | null =\n usedCheckable !== null ? this.checkedness : null;\n if (usedChecked === null) {\n this[internals].ariaChecked = null;\n this[toggleState]('checked', false);\n } else {\n this[internals].ariaChecked = String(usedChecked);\n this[toggleState]('checked', usedChecked);\n }\n }\n\n private resetAncestorElementCache() {\n this.cachedAncestorMenulist = null;\n this.cachedAncestorFieldset = null;\n\n for (\n let node = this.parentNode;\n node instanceof HTMLElement;\n node = node.parentNode\n ) {\n if (node.localName === 'md-aria-menulist') {\n this.cachedAncestorMenulist = node as AriaMenulistElement;\n break;\n }\n\n if (node.localName === 'md-aria-fieldset') {\n this.cachedAncestorFieldset = node as AriaFieldsetElement;\n }\n }\n\n this[updateUsedValues]();\n }\n\n /**\n * Sets this element's checkedness directly, without running the rest of the\n * 'check a menuitem element' steps.\n *\n * `<md-aria-fieldset>` calls this to reset the items excluded by a newly\n * checked item.\n *\n * @param value The new checkedness.\n */\n [setCheckedness](value: boolean) {\n this.checkedness = value;\n this[updateUsedValues]();\n }\n\n private checkAMenuitemElement(\n isChecked: boolean,\n fireEvents: boolean,\n ): 'close-menulist' | 'stay-open' {\n if (this.usedCheckable === null) {\n // TODO: Handle the invoked submenu.\n return 'close-menulist';\n }\n\n this[setCheckedness](isChecked);\n this.dirtyCheckedness = true;\n\n if (fireEvents) {\n this.dispatchEvent(new Event('checked'));\n }\n\n if (this.checkedness && this.usedCheckable === 'single') {\n this.cachedAncestorFieldset?.[resetMenuitemCheckedness](this);\n }\n\n return this.usedCheckable === 'single' ? 'close-menulist' : 'stay-open';\n }\n\n @property({type: Boolean, reflect: true})\n get disabled() {\n return this.internalDisabled;\n }\n set disabled(value: boolean) {\n value = Boolean(value);\n const oldValue = this.internalDisabled;\n\n this.internalDisabled = value;\n this[updateUsedValues]();\n\n this.requestUpdate('disabled', oldValue);\n }\n\n @property({type: Boolean, attribute: false})\n get checked(): boolean {\n return this.checkedness;\n }\n set checked(value: boolean) {\n this.checkAMenuitemElement(value, false);\n }\n\n @property({type: Boolean, reflect: true})\n get defaultChecked(): boolean {\n return this.internalDefaultChecked;\n }\n set defaultChecked(value: boolean) {\n value = Boolean(value);\n const oldValue = this.internalDefaultChecked;\n\n this.internalDefaultChecked = value;\n\n if (!this.dirtyCheckedness) {\n // The proposed spec DOES NOT call into the full 'check a menuitem\n // element' steps - it only sets checkedness - but this seems like the\n // only reasonable behavior when the element is part of a single-checkable\n // fieldset. Otherwise, multiple elements with `defaultchecked` could\n // become checked.\n this.checkAMenuitemElement(value, false);\n this.dirtyCheckedness = false;\n }\n\n this.requestUpdate('defaultChecked', oldValue);\n }\n\n constructor() {\n super();\n this[updateUsedValues]();\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.usedDisabled) {\n return;\n }\n\n const newChecked = !this.checkedness;\n\n const closeBehavior = this.checkAMenuitemElement(newChecked, true);\n\n // TODO: Handle the invoked submenu.\n\n if (closeBehavior === 'close-menulist') {\n // TODO: This should be the 'outermost containing menulist', not just\n // the cached ancestor menulist.\n this.cachedAncestorMenulist?.hidePopover();\n }\n\n sharedCommandInvokerActivationSteps(this, event);\n });\n });\n }\n\n override render() {\n return html`<span part=\"checkmark\"></span><slot></slot>`;\n }\n\n override connectedCallback() {\n super.connectedCallback();\n this.resetAncestorElementCache();\n\n if (this.internalDefaultChecked && !this.dirtyCheckedness) {\n this.checkAMenuitemElement(true, false);\n this.dirtyCheckedness = false;\n }\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.resetAncestorElementCache();\n }\n\n override click() {\n if (!this.usedDisabled) {\n super.click();\n }\n }\n}\n"]}
@@ -3,11 +3,7 @@
3
3
  * Copyright 2026 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
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
- };
6
+ import { CSSResultOrNative, LitElement, PropertyValues } from 'lit';
11
7
  declare const baseClass: import("../../behaviors/mixin.js").MixinReturn<typeof LitElement, import("../../behaviors/element-internals.js").WithElementInternals>;
12
8
  /**
13
9
  * An element implementing the proposed `<menulist>` built-in element.
@@ -15,8 +11,8 @@ declare const baseClass: import("../../behaviors/mixin.js").MixinReturn<typeof L
15
11
  export declare class AriaMenulistElement extends baseClass {
16
12
  static styles: CSSResultOrNative[];
17
13
  popover: string;
18
- focusGroup: string;
19
14
  constructor();
15
+ protected updated(changedProperties: PropertyValues<this>): void;
20
16
  render(): import("lit-html").TemplateResult<1>;
21
17
  private opener;
22
18
  private handleToggle;
@@ -5,12 +5,10 @@
5
5
  */
6
6
  import { __decorate } from "tslib";
7
7
  /// <reference types="../../../types/popover.d.ts" />
8
- import { ContextProvider, createContext } from '@lit/context';
9
8
  import { LitElement, css, html } from 'lit';
10
9
  import { property } from 'lit/decorators.js';
11
10
  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'));
11
+ import { sharedSlottedContentStyles } from './shared-slotted-content.js';
14
12
  const baseClass = mixinElementInternals(LitElement);
15
13
  /**
16
14
  * An element implementing the proposed `<menulist>` built-in element.
@@ -19,17 +17,18 @@ export class AriaMenulistElement extends baseClass {
19
17
  constructor() {
20
18
  super();
21
19
  this.popover = 'auto';
22
- this.focusGroup = 'menu';
23
20
  this.opener = null;
24
- const provider = new ContextProvider(this, {
25
- context: ancestorMenulistContext,
26
- });
27
- provider.setValue(this);
28
21
  this[internals].role = 'menu';
29
22
  this[internals].ariaOrientation = 'vertical';
30
23
  this.addEventListener('toggle', this.handleToggle.bind(this));
31
24
  this.addEventListener('focusout', this.handleFocusout.bind(this));
32
25
  }
26
+ updated(changedProperties) {
27
+ super.updated(changedProperties);
28
+ if (!this.hasAttribute('focusgroup')) {
29
+ this.setAttribute('focusgroup', 'menu');
30
+ }
31
+ }
33
32
  render() {
34
33
  return html `<slot></slot>`;
35
34
  }
@@ -50,6 +49,7 @@ export class AriaMenulistElement extends baseClass {
50
49
  }
51
50
  }
52
51
  AriaMenulistElement.styles = [
52
+ sharedSlottedContentStyles,
53
53
  css `
54
54
  /* Unset UA |[popover]| styles. */
55
55
  @layer {
@@ -86,53 +86,19 @@ AriaMenulistElement.styles = [
86
86
  border: 1px solid currentColor;
87
87
  border-image: none;
88
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
89
  position-area: block-end span-inline-end;
90
+ position-try-fallbacks:
91
+ flip-block,
92
+ flip-inline,
93
+ flip-block flip-inline;
93
94
  }
94
95
 
95
96
  :host(:not(:popover-open)) {
96
97
  display: none;
97
98
  }
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
99
  `,
131
100
  ];
132
101
  __decorate([
133
102
  property({ reflect: true })
134
103
  ], AriaMenulistElement.prototype, "popover", void 0);
135
- __decorate([
136
- property({ reflect: true })
137
- ], AriaMenulistElement.prototype, "focusGroup", void 0);
138
104
  //# sourceMappingURL=menulist.js.map
@@ -1 +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"]}
1
+ {"version":3,"file":"menulist.js","sourceRoot":"","sources":["menulist.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;AAEH,qDAAqD;AAErD,OAAO,EAAoB,UAAU,EAAkB,GAAG,EAAE,IAAI,EAAC,MAAM,KAAK,CAAC;AAC7E,OAAO,EAAC,QAAQ,EAAC,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EACL,SAAS,EACT,qBAAqB,GACtB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAC,0BAA0B,EAAC,MAAM,6BAA6B,CAAC;AAOvE,MAAM,SAAS,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;AAEpD;;GAEG;AACH,MAAM,OAAO,mBAAoB,SAAQ,SAAS;IAuDhD;QACE,KAAK,EAAE,CAAC;QAHD,YAAO,GAAG,MAAM,CAAC;QAsBlB,WAAM,GAAiC,IAAI,CAAC;QAlBlD,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;IAEkB,OAAO,CAAC,iBAAuC;QAChE,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAEjC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAC1C,CAAC;IACH,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;;AA1Fe,0BAAM,GAAwB;IAC5C,0BAA0B;IAC1B,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA8CF;CACF,AAjDqB,CAiDpB;AAGO;IADR,QAAQ,CAAC,EAAC,OAAO,EAAE,IAAI,EAAC,CAAC;oDACA","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 {CSSResultOrNative, LitElement, PropertyValues, css, html} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {\n internals,\n mixinElementInternals,\n} from '../../behaviors/element-internals.js';\nimport {sharedSlottedContentStyles} from './shared-slotted-content.js';\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 sharedSlottedContentStyles,\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 position-area: block-end span-inline-end;\n position-try-fallbacks:\n flip-block,\n flip-inline,\n flip-block flip-inline;\n }\n\n :host(:not(:popover-open)) {\n display: none;\n }\n `,\n ];\n\n @property({reflect: true})\n override popover = 'auto';\n\n constructor() {\n super();\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 protected override updated(changedProperties: PropertyValues<this>) {\n super.updated(changedProperties);\n\n if (!this.hasAttribute('focusgroup')) {\n this.setAttribute('focusgroup', 'menu');\n }\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,10 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ /**
7
+ * Shared styles used by `<md-aria-menulist>` and `<md-aria-fieldset>`, to
8
+ * simulate the descendant combinator in UA styles for `<menuitem>`.
9
+ */
10
+ export declare const sharedSlottedContentStyles: import("lit").CSSResult;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { css } from 'lit';
7
+ /**
8
+ * Shared styles used by `<md-aria-menulist>` and `<md-aria-fieldset>`, to
9
+ * simulate the descendant combinator in UA styles for `<menuitem>`.
10
+ */
11
+ export const sharedSlottedContentStyles = css `
12
+ ::slotted(md-aria-menuitem) {
13
+ display: flex;
14
+ align-items: center;
15
+ user-select: none;
16
+ min-inline-size: 24px;
17
+ min-block-size: max(24px, 1lh);
18
+ font-weight: inherit;
19
+ gap: 0.5em;
20
+ padding-inline: 0.5em;
21
+ }
22
+
23
+ ::slotted(md-aria-menuitem:state(enabled):hover) {
24
+ background-color: color-mix(in lab, currentColor 10%, transparent);
25
+ }
26
+
27
+ ::slotted(md-aria-menuitem:state(disabled)) {
28
+ color: color-mix(in lab, currentColor 50%, transparent);
29
+ }
30
+
31
+ ::slotted(md-aria-fieldset) {
32
+ margin-inline: 0;
33
+ border: none;
34
+ padding-block: 0;
35
+ padding-inline: 0;
36
+ }
37
+
38
+ ::slotted(hr) {
39
+ color: inherit;
40
+ margin-inline: 0;
41
+ border: none;
42
+ border-block-start: 1px solid currentColor;
43
+ border-image: none;
44
+ }
45
+
46
+ ::slotted(a:any-link),
47
+ ::slotted(img[usemap]) {
48
+ display: none;
49
+ }
50
+ `;
51
+ //# sourceMappingURL=shared-slotted-content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-slotted-content.js","sourceRoot":"","sources":["shared-slotted-content.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,GAAG,EAAC,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuC5C,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {css} from 'lit';\n\n/**\n * Shared styles used by `<md-aria-menulist>` and `<md-aria-fieldset>`, to\n * simulate the descendant combinator in UA styles for `<menuitem>`.\n */\nexport const sharedSlottedContentStyles = css`\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(md-aria-fieldset) {\n margin-inline: 0;\n border: none;\n padding-block: 0;\n padding-inline: 0;\n }\n\n ::slotted(hr) {\n color: inherit;\n margin-inline: 0;\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"]}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ /**
7
+ * Returns whether the element is disabled.
8
+ *
9
+ * Checks if the element matches any of the following:
10
+ * - `.disabled` class
11
+ * - `:disabled` pseudo-class
12
+ * - `:state(disabled)` pseudo-class
13
+ * - `[disabled]` attribute
14
+ * - `[aria-disabled=true]` attribute
15
+ *
16
+ * @param element The element to check.
17
+ * @return true if the element is disabled.
18
+ */
19
+ export declare function isDisabled(element: Element): boolean;