@material/web 2.4.2-nightly.2fe7e22.0 → 2.4.2-nightly.3758f46.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 (198) hide show
  1. package/button/internal/button.d.ts +0 -4
  2. package/button/internal/button.js.map +1 -1
  3. package/checkbox/internal/checkbox.d.ts +2 -2
  4. package/checkbox/internal/checkbox.js.map +1 -1
  5. package/chips/internal/chip.d.ts +2 -0
  6. package/icon/internal/icon.d.ts +1 -1
  7. package/icon/internal/icon.js +1 -1
  8. package/icon/internal/icon.js.map +1 -1
  9. package/iconbutton/internal/icon-button.d.ts +0 -4
  10. package/iconbutton/internal/icon-button.js.map +1 -1
  11. package/internal/aria/aria.d.ts +1 -1
  12. package/internal/events/dispatch-hooks.js +31 -35
  13. package/internal/events/dispatch-hooks.js.map +1 -1
  14. package/labs/behaviors/form-associated.d.ts +0 -22
  15. package/labs/behaviors/form-associated.js +0 -11
  16. package/labs/behaviors/form-associated.js.map +1 -1
  17. package/labs/gb/components/button/_button-tokens.scss +30 -30
  18. package/labs/gb/components/button/button.css +1 -1
  19. package/labs/gb/components/button/button.css.map +1 -1
  20. package/labs/gb/components/button/button.cssresult.js +1 -1
  21. package/labs/gb/components/button/button.cssresult.js.map +1 -1
  22. package/labs/gb/components/button/button.d.ts +1 -16
  23. package/labs/gb/components/button/button.js +10 -33
  24. package/labs/gb/components/button/button.js.map +1 -1
  25. package/labs/gb/components/button/button.scss +25 -25
  26. package/labs/gb/components/button/md-button.d.ts +1 -1
  27. package/labs/gb/components/button/md-button.js +9 -9
  28. package/labs/gb/components/button/md-button.js.map +1 -1
  29. package/labs/gb/components/card/card.d.ts +1 -11
  30. package/labs/gb/components/card/card.js +6 -13
  31. package/labs/gb/components/card/card.js.map +1 -1
  32. package/labs/gb/components/card/md-card.js +6 -6
  33. package/labs/gb/components/card/md-card.js.map +1 -1
  34. package/labs/gb/components/checkbox/checkbox.css +1 -1
  35. package/labs/gb/components/checkbox/checkbox.css.map +1 -1
  36. package/labs/gb/components/checkbox/checkbox.cssresult.js +1 -1
  37. package/labs/gb/components/checkbox/checkbox.cssresult.js.map +1 -1
  38. package/labs/gb/components/checkbox/checkbox.d.ts +1 -16
  39. package/labs/gb/components/checkbox/checkbox.js +8 -31
  40. package/labs/gb/components/checkbox/checkbox.js.map +1 -1
  41. package/labs/gb/components/checkbox/checkbox.scss +13 -13
  42. package/labs/gb/components/checkbox/md-checkbox.d.ts +4 -4
  43. package/labs/gb/components/checkbox/md-checkbox.js +10 -10
  44. package/labs/gb/components/checkbox/md-checkbox.js.map +1 -1
  45. package/labs/gb/components/divider/divider.d.ts +1 -11
  46. package/labs/gb/components/divider/divider.js +4 -11
  47. package/labs/gb/components/divider/divider.js.map +1 -1
  48. package/labs/gb/components/fab/fab.d.ts +1 -16
  49. package/labs/gb/components/fab/fab.js +8 -31
  50. package/labs/gb/components/fab/fab.js.map +1 -1
  51. package/labs/gb/components/fab/md-fab.js +4 -4
  52. package/labs/gb/components/fab/md-fab.js.map +1 -1
  53. package/labs/gb/components/focus/focus-ring.js +1 -1
  54. package/labs/gb/components/focus/focus-ring.js.map +1 -1
  55. package/labs/gb/components/iconbutton/_icon-button-tokens.scss +202 -0
  56. package/labs/gb/components/iconbutton/icon-button.css +4 -0
  57. package/labs/gb/components/iconbutton/icon-button.css.map +1 -0
  58. package/labs/gb/components/iconbutton/icon-button.cssresult.d.ts +3 -0
  59. package/labs/gb/components/iconbutton/icon-button.cssresult.js +14 -0
  60. package/labs/gb/components/iconbutton/icon-button.cssresult.js.map +1 -0
  61. package/labs/gb/components/iconbutton/icon-button.d.ts +97 -0
  62. package/labs/gb/components/iconbutton/icon-button.js +122 -0
  63. package/labs/gb/components/iconbutton/icon-button.js.map +1 -0
  64. package/labs/gb/components/iconbutton/icon-button.scss +153 -0
  65. package/labs/gb/components/iconbutton/md-icon-button.d.ts +73 -0
  66. package/labs/gb/components/iconbutton/md-icon-button.js +176 -0
  67. package/labs/gb/components/iconbutton/md-icon-button.js.map +1 -0
  68. package/labs/gb/components/list/_list-tokens.scss +102 -0
  69. package/labs/gb/components/list/list.css +4 -0
  70. package/labs/gb/components/list/list.css.map +1 -0
  71. package/labs/gb/components/list/list.cssresult.d.ts +3 -0
  72. package/labs/gb/components/list/list.cssresult.js +14 -0
  73. package/labs/gb/components/list/list.cssresult.js.map +1 -0
  74. package/labs/gb/components/list/list.d.ts +103 -0
  75. package/labs/gb/components/list/list.js +109 -0
  76. package/labs/gb/components/list/list.js.map +1 -0
  77. package/labs/gb/components/list/list.scss +212 -0
  78. package/labs/gb/components/list/md-list-item.d.ts +44 -0
  79. package/labs/gb/components/list/md-list-item.js +122 -0
  80. package/labs/gb/components/list/md-list-item.js.map +1 -0
  81. package/labs/gb/components/list/md-list.d.ts +26 -0
  82. package/labs/gb/components/list/md-list.js +51 -0
  83. package/labs/gb/components/list/md-list.js.map +1 -0
  84. package/labs/gb/components/menu/_menu-tokens.scss +128 -0
  85. package/labs/gb/components/menu/md-menu-group.d.ts +26 -0
  86. package/labs/gb/components/menu/md-menu-group.js +65 -0
  87. package/labs/gb/components/menu/md-menu-group.js.map +1 -0
  88. package/labs/gb/components/menu/md-menu-item.d.ts +30 -0
  89. package/labs/gb/components/menu/md-menu-item.js +165 -0
  90. package/labs/gb/components/menu/md-menu-item.js.map +1 -0
  91. package/labs/gb/components/menu/md-menu.d.ts +28 -0
  92. package/labs/gb/components/menu/md-menu.js +141 -0
  93. package/labs/gb/components/menu/md-menu.js.map +1 -0
  94. package/labs/gb/components/menu/menu.css +4 -0
  95. package/labs/gb/components/menu/menu.css.map +1 -0
  96. package/labs/gb/components/menu/menu.cssresult.d.ts +3 -0
  97. package/labs/gb/components/menu/menu.cssresult.js +14 -0
  98. package/labs/gb/components/menu/menu.cssresult.js.map +1 -0
  99. package/labs/gb/components/menu/menu.d.ts +117 -0
  100. package/labs/gb/components/menu/menu.js +107 -0
  101. package/labs/gb/components/menu/menu.js.map +1 -0
  102. package/labs/gb/components/menu/menu.scss +171 -0
  103. package/labs/gb/components/radio/md-radio.d.ts +4 -4
  104. package/labs/gb/components/radio/md-radio.js +11 -11
  105. package/labs/gb/components/radio/md-radio.js.map +1 -1
  106. package/labs/gb/components/radio/radio.css +1 -1
  107. package/labs/gb/components/radio/radio.css.map +1 -1
  108. package/labs/gb/components/radio/radio.cssresult.js +1 -1
  109. package/labs/gb/components/radio/radio.cssresult.js.map +1 -1
  110. package/labs/gb/components/radio/radio.d.ts +1 -14
  111. package/labs/gb/components/radio/radio.js +8 -23
  112. package/labs/gb/components/radio/radio.js.map +1 -1
  113. package/labs/gb/components/radio/radio.scss +4 -5
  114. package/labs/gb/components/ripple/ripple.d.ts +1 -10
  115. package/labs/gb/components/ripple/ripple.js +28 -32
  116. package/labs/gb/components/ripple/ripple.js.map +1 -1
  117. package/labs/gb/components/shared/directives.d.ts +93 -0
  118. package/labs/gb/components/shared/directives.js +111 -0
  119. package/labs/gb/components/shared/directives.js.map +1 -0
  120. package/labs/gb/components/shared/has-slotted.d.ts +10 -0
  121. package/labs/gb/components/shared/has-slotted.js +19 -0
  122. package/labs/gb/components/shared/has-slotted.js.map +1 -0
  123. package/labs/gb/components/shared/pseudo-classes.d.ts +7 -0
  124. package/labs/gb/components/shared/pseudo-classes.js +9 -0
  125. package/labs/gb/components/shared/pseudo-classes.js.map +1 -1
  126. package/labs/gb/components/splitbutton/_split-button-tokens.scss +135 -0
  127. package/labs/gb/components/splitbutton/md-split-button.d.ts +26 -0
  128. package/labs/gb/components/splitbutton/md-split-button.js +119 -0
  129. package/labs/gb/components/splitbutton/md-split-button.js.map +1 -0
  130. package/labs/gb/components/splitbutton/split-button.css +4 -0
  131. package/labs/gb/components/splitbutton/split-button.css.map +1 -0
  132. package/labs/gb/components/splitbutton/split-button.cssresult.d.ts +3 -0
  133. package/labs/gb/components/splitbutton/split-button.cssresult.js +14 -0
  134. package/labs/gb/components/splitbutton/split-button.cssresult.js.map +1 -0
  135. package/labs/gb/components/splitbutton/split-button.d.ts +47 -0
  136. package/labs/gb/components/splitbutton/split-button.js +46 -0
  137. package/labs/gb/components/splitbutton/split-button.js.map +1 -0
  138. package/labs/gb/components/splitbutton/split-button.scss +164 -0
  139. package/labs/gb/components/switch/_switch-tokens.scss +56 -0
  140. package/labs/gb/components/switch/md-switch.d.ts +66 -0
  141. package/labs/gb/components/switch/md-switch.js +162 -0
  142. package/labs/gb/components/switch/md-switch.js.map +1 -0
  143. package/labs/gb/components/switch/switch.css +4 -0
  144. package/labs/gb/components/switch/switch.css.map +1 -0
  145. package/labs/gb/components/switch/switch.cssresult.d.ts +3 -0
  146. package/labs/gb/components/switch/switch.cssresult.js +14 -0
  147. package/labs/gb/components/switch/switch.cssresult.js.map +1 -0
  148. package/labs/gb/components/switch/switch.d.ts +54 -0
  149. package/labs/gb/components/switch/switch.js +85 -0
  150. package/labs/gb/components/switch/switch.js.map +1 -0
  151. package/labs/gb/components/switch/switch.scss +109 -0
  152. package/labs/gb/styles/icon/md-icon.css +1 -1
  153. package/labs/gb/styles/icon/md-icon.css.map +1 -1
  154. package/labs/gb/styles/icon/md-icon.cssresult.js +1 -1
  155. package/labs/gb/styles/icon/md-icon.cssresult.js.map +1 -1
  156. package/labs/gb/styles/icon/md-icon.d.ts +20 -0
  157. package/labs/gb/styles/icon/md-icon.js +24 -0
  158. package/labs/gb/styles/icon/md-icon.js.map +1 -0
  159. package/labs/gb/styles/icon/md-icon.scss +2 -1
  160. package/labs/gb/styles/m3.css +5 -2
  161. package/labs/gb/styles/m3.css.map +1 -1
  162. package/labs/gb/styles/m3.cssresult.js +5 -2
  163. package/labs/gb/styles/m3.cssresult.js.map +1 -1
  164. package/labs/gb/styles/m3.scss +1 -0
  165. package/labs/gb/styles/space/md-space-tokens.css +4 -0
  166. package/labs/gb/styles/space/md-space-tokens.css.map +1 -0
  167. package/labs/gb/styles/space/md-space-tokens.cssresult.d.ts +3 -0
  168. package/labs/gb/styles/space/md-space-tokens.cssresult.js +14 -0
  169. package/labs/gb/styles/space/md-space-tokens.cssresult.js.map +1 -0
  170. package/labs/gb/styles/space/md-space-tokens.scss +28 -0
  171. package/labs/gb/styles/tailwind.css +4 -0
  172. package/labs/gb/styles/tailwind.css.map +1 -0
  173. package/labs/gb/styles/tailwind.cssresult.d.ts +3 -0
  174. package/labs/gb/styles/tailwind.cssresult.js +14 -0
  175. package/labs/gb/styles/tailwind.cssresult.js.map +1 -0
  176. package/labs/gb/styles/tailwind.scss +250 -0
  177. package/labs/gb/styles/typography/internal/_typography-tokens.scss +85 -16
  178. package/labs/gb/styles/typography/md-typography-tokens.css +1 -1
  179. package/labs/gb/styles/typography/md-typography-tokens.css.map +1 -1
  180. package/labs/gb/styles/typography/md-typography-tokens.cssresult.js +1 -1
  181. package/labs/gb/styles/typography/md-typography-tokens.cssresult.js.map +1 -1
  182. package/list/internal/listitem/list-item.d.ts +2 -0
  183. package/menu/internal/menuitem/menu-item.d.ts +2 -0
  184. package/package.json +7 -3
  185. package/radio/internal/radio.d.ts +0 -2
  186. package/radio/internal/radio.js.map +1 -1
  187. package/select/internal/select.d.ts +2 -2
  188. package/select/internal/select.js.map +1 -1
  189. package/select/internal/selectoption/select-option.d.ts +2 -0
  190. package/slider/internal/slider.d.ts +0 -2
  191. package/slider/internal/slider.js.map +1 -1
  192. package/switch/internal/_switch.scss +1 -0
  193. package/switch/internal/switch-styles.css +1 -1
  194. package/switch/internal/switch-styles.css.map +1 -1
  195. package/switch/internal/switch-styles.cssresult.js +1 -1
  196. package/switch/internal/switch-styles.cssresult.js.map +1 -1
  197. package/switch/internal/switch.d.ts +0 -2
  198. package/switch/internal/switch.js.map +1 -1
@@ -0,0 +1,111 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { noChange } from 'lit';
7
+ import { AsyncDirective, directive, } from 'lit/async-directive.js';
8
+ import { classMap } from 'lit/directives/class-map.js';
9
+ /**
10
+ * Creates a Lit directive that behaves like `classMap()`, but also provides
11
+ * element setup and cleanup logic.
12
+ *
13
+ * These directives bind to `class="${componentDirectiveName()}"`.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const toggleButton = createClassMapDirective({
18
+ * getClasses: (state: ToggleButtonState) => ({
19
+ * 'toggle-button': true,
20
+ * 'toggle-button-selected': state.selected,
21
+ * }),
22
+ * setupElement: (element, opts) => {
23
+ * element.addEventListener('click', () => {
24
+ * state.selected = !state.selected;
25
+ * }, opts);
26
+ * },
27
+ * });
28
+ *
29
+ * html`
30
+ * <button class="${toggleButton()}">Unselected</button>
31
+ * <button class="${toggleButton({selected: true})}">Selected</button>
32
+ * <button class="${toggleButton({classes: {'visible': isVisible}})}">
33
+ * With additional classes
34
+ * </button>
35
+ * `;
36
+ * ```
37
+ *
38
+ * @param options Options for creating the class map directive.
39
+ * @return A Lit `directive()` that binds to the class attribute.
40
+ */
41
+ export function createClassMapDirective(options) {
42
+ return directive(class ComponentClassMapDirective extends SetupElementDirective {
43
+ constructor() {
44
+ super(...arguments);
45
+ this.setupElement = options.setupElement;
46
+ }
47
+ render(params) {
48
+ return classMap({
49
+ ...(params?.classes || {}),
50
+ ...options.getClasses(params),
51
+ });
52
+ }
53
+ });
54
+ }
55
+ /**
56
+ * Creates a Lit directive that can be used to add setup and cleanup logic to
57
+ * an element.
58
+ *
59
+ * These directives bind as element parts.
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * const logClick = createElementDirective((element, opts) => {
64
+ * element.addEventListener('click', (event) => {
65
+ * console.log('click', event);
66
+ * }, opts);
67
+ * });
68
+ *
69
+ * html`<button ${logClick()}>Click me</button>`;
70
+ * ```
71
+ *
72
+ * @param setupElement The function to set up logic for the directive's element.
73
+ * @return A Lit `directive()` that binds as an element part.
74
+ */
75
+ export function createElementDirective(setupElement) {
76
+ return directive(class ElementDirective extends SetupElementDirective {
77
+ constructor() {
78
+ super(...arguments);
79
+ this.setupElement = setupElement;
80
+ }
81
+ render() {
82
+ return noChange;
83
+ }
84
+ });
85
+ }
86
+ /**
87
+ * A base class for Lit element and attribute directives that provides a setup
88
+ * method for initializing logic when a directive's element is connected.
89
+ */
90
+ class SetupElementDirective extends AsyncDirective {
91
+ update({ element }, params) {
92
+ if (element !== this.element) {
93
+ this.element = element;
94
+ this.disconnected();
95
+ if (this.isConnected) {
96
+ this.reconnected();
97
+ }
98
+ }
99
+ return this.render(...params);
100
+ }
101
+ disconnected() {
102
+ this.cleanup?.abort();
103
+ }
104
+ reconnected() {
105
+ if (this.element && this.setupElement) {
106
+ this.cleanup = new AbortController();
107
+ this.setupElement(this.element, { signal: this.cleanup.signal });
108
+ }
109
+ }
110
+ }
111
+ //# sourceMappingURL=directives.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directives.js","sourceRoot":"","sources":["directives.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,QAAQ,EAAC,MAAM,KAAK,CAAC;AAC7B,OAAO,EACL,cAAc,EAEd,SAAS,GAGV,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAC,QAAQ,EAAiB,MAAM,6BAA6B,CAAC;AAsCrE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,uBAAuB,CACrC,OAAwC;IAExC,OAAO,SAAS,CACd,MAAM,0BAA2B,SAAQ,qBAAqB;QAA9D;;YAQqB,iBAAY,GAAG,OAAO,CAAC,YAAY,CAAC;QACzD,CAAC;QARC,MAAM,CAAC,MAAkC;YACvC,OAAO,QAAQ,CAAC;gBACd,GAAG,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE,CAAC;gBAC1B,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC;aAC9B,CAAC,CAAC;QACL,CAAC;KAGF,CACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,sBAAsB,CACpC,YAAkC;IAElC,OAAO,SAAS,CACd,MAAM,gBAAiB,SAAQ,qBAAqB;QAApD;;YAKqB,iBAAY,GAAG,YAAY,CAAC;QACjD,CAAC;QALC,MAAM;YACJ,OAAO,QAAQ,CAAC;QAClB,CAAC;KAGF,CACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAe,qBAAsB,SAAQ,cAAc;IAmBhD,MAAM,CAAC,EAAC,OAAO,EAA8B,EAAE,MAAiB;QACvE,IAAI,OAAO,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,OAAO,GAAG,OAAsB,CAAC;YACtC,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACrB,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;IAChC,CAAC;IAEkB,YAAY;QAC7B,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;IACxB,CAAC;IAEkB,WAAW;QAC5B,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtC,IAAI,CAAC,OAAO,GAAG,IAAI,eAAe,EAAE,CAAC;YACrC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,EAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAC,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;CACF","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {noChange} from 'lit';\nimport {\n AsyncDirective,\n AttributePart,\n directive,\n DirectiveResult,\n ElementPart,\n} from 'lit/async-directive.js';\nimport {classMap, type ClassInfo} from 'lit/directives/class-map.js';\n\n/**\n * A function that sets up logic for a directive's element.\n *\n * @param element The element attached to the directive.\n * @param opts Options for setting up the element, including an AbortSignal for\n * cleanup.\n */\nexport type SetupElementFunction = (\n element: HTMLElement,\n opts: {signal: AbortSignal},\n) => void;\n\n/**\n * All class map directives include AdditionalClasses to allow adding dynamic\n * classes to the element using `classMap()`.\n */\nexport interface AdditionalClasses {\n /**\n * Additional classes to apply to the element.\n */\n classes?: ClassInfo;\n}\n\n/**\n * Options for creating a class map directive.\n *\n * @param getClasses A function that returns the class names and truthy values\n * if they apply.\n * @param setupElement An optional function to set up logic for the directive's\n * element.\n */\nexport interface ClassMapDirectiveOptions<State> {\n getClasses: (state?: State) => ClassInfo;\n setupElement?: SetupElementFunction;\n}\n\n/**\n * Creates a Lit directive that behaves like `classMap()`, but also provides\n * element setup and cleanup logic.\n *\n * These directives bind to `class=\"${componentDirectiveName()}\"`.\n *\n * @example\n * ```ts\n * const toggleButton = createClassMapDirective({\n * getClasses: (state: ToggleButtonState) => ({\n * 'toggle-button': true,\n * 'toggle-button-selected': state.selected,\n * }),\n * setupElement: (element, opts) => {\n * element.addEventListener('click', () => {\n * state.selected = !state.selected;\n * }, opts);\n * },\n * });\n *\n * html`\n * <button class=\"${toggleButton()}\">Unselected</button>\n * <button class=\"${toggleButton({selected: true})}\">Selected</button>\n * <button class=\"${toggleButton({classes: {'visible': isVisible}})}\">\n * With additional classes\n * </button>\n * `;\n * ```\n *\n * @param options Options for creating the class map directive.\n * @return A Lit `directive()` that binds to the class attribute.\n */\nexport function createClassMapDirective<State = {}>(\n options: ClassMapDirectiveOptions<State>,\n): (state?: State & AdditionalClasses) => DirectiveResult {\n return directive(\n class ComponentClassMapDirective extends SetupElementDirective {\n render(params?: State & AdditionalClasses) {\n return classMap({\n ...(params?.classes || {}),\n ...options.getClasses(params),\n });\n }\n\n protected override setupElement = options.setupElement;\n },\n );\n}\n\n/**\n * Creates a Lit directive that can be used to add setup and cleanup logic to\n * an element.\n *\n * These directives bind as element parts.\n *\n * @example\n * ```ts\n * const logClick = createElementDirective((element, opts) => {\n * element.addEventListener('click', (event) => {\n * console.log('click', event);\n * }, opts);\n * });\n *\n * html`<button ${logClick()}>Click me</button>`;\n * ```\n *\n * @param setupElement The function to set up logic for the directive's element.\n * @return A Lit `directive()` that binds as an element part.\n */\nexport function createElementDirective(\n setupElement: SetupElementFunction,\n): () => DirectiveResult {\n return directive(\n class ElementDirective extends SetupElementDirective {\n render() {\n return noChange;\n }\n\n protected override setupElement = setupElement;\n },\n );\n}\n\n/**\n * A base class for Lit element and attribute directives that provides a setup\n * method for initializing logic when a directive's element is connected.\n */\nabstract class SetupElementDirective extends AsyncDirective {\n /**\n * Called when the directive's element changes. Use this method to add\n * event listeners or perform other setup logic.\n *\n * The `signal` option is used to clean up setup logic when the element is\n * disconnected.\n *\n * @param element The element attached to the directive.\n * @param signal An AbortSignal to clean up event listeners and other logic.\n */\n protected setupElement?: (\n element: HTMLElement,\n opts: {signal: AbortSignal},\n ) => void;\n\n private element?: HTMLElement;\n private cleanup?: AbortController;\n\n override update({element}: ElementPart | AttributePart, params: unknown[]) {\n if (element !== this.element) {\n this.element = element as HTMLElement;\n this.disconnected();\n if (this.isConnected) {\n this.reconnected();\n }\n }\n\n return this.render(...params);\n }\n\n protected override disconnected() {\n this.cleanup?.abort();\n }\n\n protected override reconnected() {\n if (this.element && this.setupElement) {\n this.cleanup = new AbortController();\n this.setupElement(this.element, {signal: this.cleanup.signal});\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
+ * Emulates the `:has-slotted` CSS pseudo class by adding a `.has-slotted` class
8
+ * to `<slot>` elements when they have assigned nodes.
9
+ */
10
+ export declare const hasSlotted: () => import("lit-html/directive.js").DirectiveResult;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { createElementDirective } from './directives.js';
7
+ /**
8
+ * Emulates the `:has-slotted` CSS pseudo class by adding a `.has-slotted` class
9
+ * to `<slot>` elements when they have assigned nodes.
10
+ */
11
+ export const hasSlotted = createElementDirective((element, opts) => {
12
+ if (!element.matches('slot')) {
13
+ throw new Error('hasSlotted() must be used on a <slot> element.');
14
+ }
15
+ element.addEventListener('slotchange', (event) => {
16
+ element.classList.toggle('has-slotted', element.assignedNodes().length > 0);
17
+ }, opts);
18
+ });
19
+ //# sourceMappingURL=has-slotted.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"has-slotted.js","sourceRoot":"","sources":["has-slotted.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,sBAAsB,EAAC,MAAM,iBAAiB,CAAC;AAEvD;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,sBAAsB,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;IACjE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,CAAC,gBAAgB,CACtB,YAAY,EACZ,CAAC,KAAK,EAAE,EAAE;QACR,OAAO,CAAC,SAAS,CAAC,MAAM,CACtB,aAAa,EACZ,OAA2B,CAAC,aAAa,EAAE,CAAC,MAAM,GAAG,CAAC,CACxD,CAAC;IACJ,CAAC,EACD,IAAI,CACL,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {createElementDirective} from './directives.js';\n\n/**\n * Emulates the `:has-slotted` CSS pseudo class by adding a `.has-slotted` class\n * to `<slot>` elements when they have assigned nodes.\n */\nexport const hasSlotted = createElementDirective((element, opts) => {\n if (!element.matches('slot')) {\n throw new Error('hasSlotted() must be used on a <slot> element.');\n }\n\n element.addEventListener(\n 'slotchange',\n (event) => {\n element.classList.toggle(\n 'has-slotted',\n (element as HTMLSlotElement).assignedNodes().length > 0,\n );\n },\n opts,\n );\n});\n"]}
@@ -24,3 +24,10 @@ export declare const PSEUDO_CLASSES: {
24
24
  indeterminate: string;
25
25
  invalid: string;
26
26
  };
27
+ /**
28
+ * Returns whether the element is disabled.
29
+ *
30
+ * @param element The element to check.
31
+ * @return true if the element is disabled.
32
+ */
33
+ export declare function isDisabled(element: Element): boolean;
@@ -24,4 +24,13 @@ export const PSEUDO_CLASSES = {
24
24
  indeterminate: 'indeterminate',
25
25
  invalid: 'invalid',
26
26
  };
27
+ /**
28
+ * Returns whether the element is disabled.
29
+ *
30
+ * @param element The element to check.
31
+ * @return true if the element is disabled.
32
+ */
33
+ export function isDisabled(element) {
34
+ return element.matches('.disabled,:disabled,[disabled],[aria-disabled=true]');
35
+ }
27
36
  //# sourceMappingURL=pseudo-classes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pseudo-classes.js","sourceRoot":"","sources":["pseudo-classes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;IACd,YAAY,EAAE,eAAe;IAC7B,KAAK,EAAE,OAAO;IACd,aAAa,EAAE,eAAe;IAC9B,OAAO,EAAE,SAAS;CACnB,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * Cross-component classes for emulating pseudo-classes.\n *\n * All components that style with psuedo-classes for their DOM structure also\n * support emulating these states.\n *\n * @example\n * ```html\n * <button class=\"ripple active\">Pressed ripple</button>\n * ```\n */\nexport const PSEUDO_CLASSES = {\n active: 'active',\n checked: 'checked',\n disabled: 'disabled',\n focus: 'focus',\n focusVisible: 'focus-visible',\n hover: 'hover',\n indeterminate: 'indeterminate',\n invalid: 'invalid',\n};\n"]}
1
+ {"version":3,"file":"pseudo-classes.js","sourceRoot":"","sources":["pseudo-classes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;IACd,YAAY,EAAE,eAAe;IAC7B,KAAK,EAAE,OAAO;IACd,aAAa,EAAE,eAAe;IAC9B,OAAO,EAAE,SAAS;CACnB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,OAAgB;IACzC,OAAO,OAAO,CAAC,OAAO,CAAC,qDAAqD,CAAC,CAAC;AAChF,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * Cross-component classes for emulating pseudo-classes.\n *\n * All components that style with psuedo-classes for their DOM structure also\n * support emulating these states.\n *\n * @example\n * ```html\n * <button class=\"ripple active\">Pressed ripple</button>\n * ```\n */\nexport const PSEUDO_CLASSES = {\n active: 'active',\n checked: 'checked',\n disabled: 'disabled',\n focus: 'focus',\n focusVisible: 'focus-visible',\n hover: 'hover',\n indeterminate: 'indeterminate',\n invalid: 'invalid',\n};\n\n/**\n * Returns whether the element is disabled.\n *\n * @param element The element to check.\n * @return true if the element is disabled.\n */\nexport function isDisabled(element: Element): boolean {\n return element.matches('.disabled,:disabled,[disabled],[aria-disabled=true]');\n}\n"]}
@@ -0,0 +1,135 @@
1
+ //
2
+ // Copyright 2026 Google LLC
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ //
5
+
6
+ @mixin root {
7
+ --between-space: 2px;
8
+ }
9
+
10
+ @mixin button {
11
+ --icon-size: 0;
12
+ --inner-corner-size: 0;
13
+ --outer-corner-size: calc(var(--container-height) / 2);
14
+ --leading-space: 0;
15
+ --trailing-space: 0;
16
+ }
17
+
18
+ @mixin button-xs {
19
+ --icon-size: 22px;
20
+ --inner-corner-size: var(--md-sys-shape-corner-xs);
21
+ }
22
+
23
+ @mixin button-xs-leading {
24
+ --leading-space: 12px;
25
+ --trailing-space: 10px;
26
+ }
27
+
28
+ @mixin button-xs-trailing {
29
+ --leading-space: 13px;
30
+ --trailing-space: 13px;
31
+ }
32
+
33
+ @mixin button-xs-hovered {
34
+ --inner-corner-size: var(--md-sys-shape-corner-sm);
35
+ }
36
+
37
+ @mixin button-xs-pressed {
38
+ --inner-corner-size: var(--md-sys-shape-corner-sm);
39
+ }
40
+
41
+ @mixin button-sm {
42
+ --icon-size: 22px;
43
+ --inner-corner-size: var(--md-sys-shape-corner-xs);
44
+ }
45
+
46
+ @mixin button-sm-leading {
47
+ --leading-space: 16px;
48
+ --trailing-space: 12px;
49
+ }
50
+
51
+ @mixin button-sm-trailing {
52
+ --leading-space: 13px;
53
+ --trailing-space: 13px;
54
+ }
55
+
56
+ @mixin button-sm-hovered {
57
+ --inner-corner-size: var(--md-sys-shape-corner-md);
58
+ }
59
+
60
+ @mixin button-sm-pressed {
61
+ --inner-corner-size: var(--md-sys-shape-corner-md);
62
+ }
63
+
64
+ @mixin button-md {
65
+ --icon-size: 26px;
66
+ --inner-corner-size: var(--md-sys-shape-corner-xs);
67
+ }
68
+
69
+ @mixin button-md-leading {
70
+ --leading-space: 24px;
71
+ --trailing-space: 24px;
72
+ }
73
+
74
+ @mixin button-md-trailing {
75
+ --leading-space: 15px;
76
+ --trailing-space: 15px;
77
+ }
78
+
79
+ @mixin button-md-hovered {
80
+ --inner-corner-size: var(--md-sys-shape-corner-md);
81
+ }
82
+
83
+ @mixin button-md-pressed {
84
+ --inner-corner-size: var(--md-sys-shape-corner-md);
85
+ }
86
+
87
+ @mixin button-lg {
88
+ --icon-size: 38px;
89
+ --inner-corner-size: var(--md-sys-shape-corner-sm);
90
+ }
91
+
92
+ @mixin button-lg-leading {
93
+ --leading-space: 48px;
94
+ --trailing-space: 48px;
95
+ }
96
+
97
+ @mixin button-lg-trailing {
98
+ --leading-space: 29px;
99
+ --trailing-space: 29px;
100
+ }
101
+
102
+ @mixin button-lg-hovered {
103
+ --inner-corner-size: var(--md-sys-shape-corner-lg-increased);
104
+ }
105
+
106
+ @mixin button-lg-pressed {
107
+ --inner-corner-size: var(--md-sys-shape-corner-lg-increased);
108
+ }
109
+
110
+ @mixin button-xl {
111
+ --icon-size: 50px;
112
+ --inner-corner-size: var(--md-sys-shape-corner-md);
113
+ }
114
+
115
+ @mixin button-xl-leading {
116
+ --leading-space: 64px;
117
+ --trailing-space: 64px;
118
+ }
119
+
120
+ @mixin button-xl-trailing {
121
+ --leading-space: 43px;
122
+ --trailing-space: 43px;
123
+ }
124
+
125
+ @mixin button-xl-hovered {
126
+ --inner-corner-size: var(--md-sys-shape-corner-lg-increased);
127
+ }
128
+
129
+ @mixin button-xl-pressed {
130
+ --inner-corner-size: var(--md-sys-shape-corner-lg-increased);
131
+ }
132
+
133
+ @mixin button-trailing-selected {
134
+ --inner-corner-size: calc(var(--container-height) / 2);
135
+ }
@@ -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 { type SplitButtonColor, type SplitButtonSize } from './split-button.js';
8
+ declare global {
9
+ interface HTMLElementTagNameMap {
10
+ /** A Material Design split button component. */
11
+ 'md-split-button': SplitButton;
12
+ }
13
+ }
14
+ /**
15
+ * A Material Design split button component.
16
+ */
17
+ export declare class SplitButton extends LitElement {
18
+ static styles: CSSResultOrNative[];
19
+ color: SplitButtonColor;
20
+ size: SplitButtonSize;
21
+ selected: boolean;
22
+ protected render(): import("lit-html").TemplateResult<1>;
23
+ private updateSlotFocusVisible;
24
+ private cleanupToggleListener?;
25
+ private handleTrailingSlotchange;
26
+ }
@@ -0,0 +1,119 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { __decorate } from "tslib";
7
+ import { css, html, LitElement } from 'lit';
8
+ import { customElement, property } from 'lit/decorators.js';
9
+ import { button } from '../button/button.js';
10
+ import focusRingStyles from '../focus/focus-ring.css' with { type: 'css' }; // github-only
11
+ // import focusRingStyles from '../focus/focus-ring.cssresult.js'; // google3-only
12
+ import rippleStyles from '../ripple/ripple.css' with { type: 'css' }; // github-only
13
+ // import rippleStyles from '../ripple/ripple.cssresult.js'; // google3-only
14
+ import buttonStyles from '../button/button.css' with { type: 'css' }; // github-only
15
+ // import buttonStyles from '../button/button.cssresult.js'; // google3-only
16
+ import splitButtonStyles from './split-button.css' with { type: 'css' }; // github-only
17
+ // import {styles as splitButtonStyles} from './split-button.cssresult.js'; // google3-only
18
+ import { splitButton, } from './split-button.js';
19
+ /**
20
+ * A Material Design split button component.
21
+ */
22
+ let SplitButton = class SplitButton extends LitElement {
23
+ constructor() {
24
+ super(...arguments);
25
+ this.color = 'filled';
26
+ this.size = 'sm';
27
+ this.selected = false;
28
+ }
29
+ render() {
30
+ const buttonConfig = {
31
+ color: this.color,
32
+ size: this.size,
33
+ };
34
+ return html `<div part="split-btn" class="${splitButton(this)}">
35
+ <slot
36
+ name="leading"
37
+ part="leading-btn"
38
+ class="${button(buttonConfig)}"
39
+ @focusin=${this.updateSlotFocusVisible}
40
+ @focusout=${this.updateSlotFocusVisible}>
41
+ </slot>
42
+ <slot
43
+ name="trailing"
44
+ part="trailing-btn"
45
+ class="${button(buttonConfig)}"
46
+ @focusin=${this.updateSlotFocusVisible}
47
+ @focusout=${this.updateSlotFocusVisible}
48
+ @slotchange=${this.handleTrailingSlotchange}>
49
+ </slot>
50
+ <slot></slot>
51
+ </div>`;
52
+ }
53
+ updateSlotFocusVisible(event) {
54
+ const slot = event.currentTarget;
55
+ const hasFocusVisible = slot
56
+ .assignedElements()
57
+ .some((el) => el.matches(':focus-visible,:has(:focus-visible)'));
58
+ slot.classList.toggle('focus-visible', hasFocusVisible);
59
+ }
60
+ handleTrailingSlotchange(event) {
61
+ this.cleanupToggleListener?.abort();
62
+ this.cleanupToggleListener = new AbortController();
63
+ const slot = event.target;
64
+ const trailingButton = slot
65
+ .assignedElements()
66
+ .find((el) => el.matches('button'));
67
+ if (!trailingButton?.popoverTargetElement)
68
+ return;
69
+ trailingButton.popoverTargetElement.addEventListener('toggle', (event) => {
70
+ this.selected = event.newState === 'open';
71
+ }, { signal: this.cleanupToggleListener.signal });
72
+ }
73
+ };
74
+ SplitButton.styles = [
75
+ focusRingStyles,
76
+ rippleStyles,
77
+ buttonStyles,
78
+ splitButtonStyles,
79
+ css `
80
+ :host {
81
+ display: inline-flex;
82
+ }
83
+ .split-btn {
84
+ flex: 1;
85
+ }
86
+ [name='leading'] {
87
+ display: contents;
88
+ &::slotted(button) {
89
+ all: inherit;
90
+ display: flex;
91
+ }
92
+ }
93
+ [name='trailing'] {
94
+ position: relative;
95
+ &::slotted(button) {
96
+ position: absolute;
97
+ inset: 0;
98
+ appearance: none;
99
+ background: none;
100
+ border: none;
101
+ outline: none;
102
+ }
103
+ }
104
+ `,
105
+ ];
106
+ __decorate([
107
+ property()
108
+ ], SplitButton.prototype, "color", void 0);
109
+ __decorate([
110
+ property()
111
+ ], SplitButton.prototype, "size", void 0);
112
+ __decorate([
113
+ property({ type: Boolean })
114
+ ], SplitButton.prototype, "selected", void 0);
115
+ SplitButton = __decorate([
116
+ customElement('md-split-button')
117
+ ], SplitButton);
118
+ export { SplitButton };
119
+ //# sourceMappingURL=md-split-button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"md-split-button.js","sourceRoot":"","sources":["md-split-button.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;AAEH,OAAO,EAAC,GAAG,EAAqB,IAAI,EAAE,UAAU,EAAC,MAAM,KAAK,CAAC;AAC7D,OAAO,EAAC,aAAa,EAAE,QAAQ,EAAC,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAC,MAAM,EAAC,MAAM,qBAAqB,CAAC;AAE3C,OAAO,eAAe,MAAM,yBAAyB,CAAC,OAAM,IAAI,EAAE,KAAK,EAAC,CAAC,CAAC,cAAc;AACxF,kFAAkF;AAClF,OAAO,YAAY,MAAM,sBAAsB,CAAC,OAAM,IAAI,EAAE,KAAK,EAAC,CAAC,CAAC,cAAc;AAClF,4EAA4E;AAC5E,OAAO,YAAY,MAAM,sBAAsB,CAAC,OAAM,IAAI,EAAE,KAAK,EAAC,CAAC,CAAC,cAAc;AAClF,4EAA4E;AAC5E,OAAO,iBAAiB,MAAM,oBAAoB,CAAC,OAAM,IAAI,EAAE,KAAK,EAAC,CAAC,CAAC,cAAc;AACrF,2FAA2F;AAE3F,OAAO,EACL,WAAW,GAGZ,MAAM,mBAAmB,CAAC;AAS3B;;GAEG;AAEI,IAAM,WAAW,GAAjB,MAAM,WAAY,SAAQ,UAAU;IAApC;;QAkCO,UAAK,GAAqB,QAAQ,CAAC;QACnC,SAAI,GAAoB,IAAI,CAAC;QACd,aAAQ,GAAG,KAAK,CAAC;IAqD9C,CAAC;IAnDoB,MAAM;QACvB,MAAM,YAAY,GAAG;YACnB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC;QAEF,OAAO,IAAI,CAAA,gCAAgC,WAAW,CAAC,IAAI,CAAC;;;;iBAI/C,MAAM,CAAC,YAAY,CAAC;mBAClB,IAAI,CAAC,sBAAsB;oBAC1B,IAAI,CAAC,sBAAsB;;;;;iBAK9B,MAAM,CAAC,YAAY,CAAC;mBAClB,IAAI,CAAC,sBAAsB;oBAC1B,IAAI,CAAC,sBAAsB;sBACzB,IAAI,CAAC,wBAAwB;;;WAGxC,CAAC;IACV,CAAC;IAEO,sBAAsB,CAAC,KAAY;QACzC,MAAM,IAAI,GAAG,KAAK,CAAC,aAAgC,CAAC;QACpD,MAAM,eAAe,GAAG,IAAI;aACzB,gBAAgB,EAAE;aAClB,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAC,CAAC;QACnE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;IAC1D,CAAC;IAGO,wBAAwB,CAAC,KAAY;QAC3C,IAAI,CAAC,qBAAqB,EAAE,KAAK,EAAE,CAAC;QACpC,IAAI,CAAC,qBAAqB,GAAG,IAAI,eAAe,EAAE,CAAC;QACnD,MAAM,IAAI,GAAG,KAAK,CAAC,MAAyB,CAAC;QAC7C,MAAM,cAAc,GAAG,IAAI;aACxB,gBAAgB,EAAE;aAClB,IAAI,CAAC,CAAC,EAAE,EAA2B,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC/D,IAAI,CAAC,cAAc,EAAE,oBAAoB;YAAE,OAAO;QAClD,cAAc,CAAC,oBAAoB,CAAC,gBAAgB,CAClD,QAAQ,EACR,CAAC,KAAY,EAAE,EAAE;YACf,IAAI,CAAC,QAAQ,GAAI,KAAqB,CAAC,QAAQ,KAAK,MAAM,CAAC;QAC7D,CAAC,EACD,EAAC,MAAM,EAAE,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAC,CAC5C,CAAC;IACJ,CAAC;;AAvFe,kBAAM,GAAwB;IAC5C,eAAe;IACf,YAAY;IACZ,YAAY;IACZ,iBAAiB;IACjB,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;KAyBF;CACF,AA/BqB,CA+BpB;AAEU;IAAX,QAAQ,EAAE;0CAAoC;AACnC;IAAX,QAAQ,EAAE;yCAA8B;AACd;IAA1B,QAAQ,CAAC,EAAC,IAAI,EAAE,OAAO,EAAC,CAAC;6CAAkB;AApCjC,WAAW;IADvB,aAAa,CAAC,iBAAiB,CAAC;GACpB,WAAW,CAyFvB","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {css, CSSResultOrNative, html, LitElement} from 'lit';\nimport {customElement, property} from 'lit/decorators.js';\nimport {button} from '../button/button.js';\n\nimport focusRingStyles from '../focus/focus-ring.css' with {type: 'css'}; // github-only\n// import focusRingStyles from '../focus/focus-ring.cssresult.js'; // google3-only\nimport rippleStyles from '../ripple/ripple.css' with {type: 'css'}; // github-only\n// import rippleStyles from '../ripple/ripple.cssresult.js'; // google3-only\nimport buttonStyles from '../button/button.css' with {type: 'css'}; // github-only\n// import buttonStyles from '../button/button.cssresult.js'; // google3-only\nimport splitButtonStyles from './split-button.css' with {type: 'css'}; // github-only\n// import {styles as splitButtonStyles} from './split-button.cssresult.js'; // google3-only\n\nimport {\n splitButton,\n type SplitButtonColor,\n type SplitButtonSize,\n} from './split-button.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n /** A Material Design split button component. */\n 'md-split-button': SplitButton;\n }\n}\n\n/**\n * A Material Design split button component.\n */\n@customElement('md-split-button')\nexport class SplitButton extends LitElement {\n static override styles: CSSResultOrNative[] = [\n focusRingStyles,\n rippleStyles,\n buttonStyles,\n splitButtonStyles,\n css`\n :host {\n display: inline-flex;\n }\n .split-btn {\n flex: 1;\n }\n [name='leading'] {\n display: contents;\n &::slotted(button) {\n all: inherit;\n display: flex;\n }\n }\n [name='trailing'] {\n position: relative;\n &::slotted(button) {\n position: absolute;\n inset: 0;\n appearance: none;\n background: none;\n border: none;\n outline: none;\n }\n }\n `,\n ];\n\n @property() color: SplitButtonColor = 'filled';\n @property() size: SplitButtonSize = 'sm';\n @property({type: Boolean}) selected = false;\n\n protected override render() {\n const buttonConfig = {\n color: this.color,\n size: this.size,\n };\n\n return html`<div part=\"split-btn\" class=\"${splitButton(this)}\">\n <slot\n name=\"leading\"\n part=\"leading-btn\"\n class=\"${button(buttonConfig)}\"\n @focusin=${this.updateSlotFocusVisible}\n @focusout=${this.updateSlotFocusVisible}>\n </slot>\n <slot\n name=\"trailing\"\n part=\"trailing-btn\"\n class=\"${button(buttonConfig)}\"\n @focusin=${this.updateSlotFocusVisible}\n @focusout=${this.updateSlotFocusVisible}\n @slotchange=${this.handleTrailingSlotchange}>\n </slot>\n <slot></slot>\n </div>`;\n }\n\n private updateSlotFocusVisible(event: Event) {\n const slot = event.currentTarget as HTMLSlotElement;\n const hasFocusVisible = slot\n .assignedElements()\n .some((el) => el.matches(':focus-visible,:has(:focus-visible)'));\n slot.classList.toggle('focus-visible', hasFocusVisible);\n }\n\n private cleanupToggleListener?: AbortController;\n private handleTrailingSlotchange(event: Event) {\n this.cleanupToggleListener?.abort();\n this.cleanupToggleListener = new AbortController();\n const slot = event.target as HTMLSlotElement;\n const trailingButton = slot\n .assignedElements()\n .find((el): el is HTMLButtonElement => el.matches('button'));\n if (!trailingButton?.popoverTargetElement) return;\n trailingButton.popoverTargetElement.addEventListener(\n 'toggle',\n (event: Event) => {\n this.selected = (event as ToggleEvent).newState === 'open';\n },\n {signal: this.cleanupToggleListener.signal},\n );\n }\n}\n"]}
@@ -0,0 +1,4 @@
1
+ /*!
2
+ * Copyright 2026 Google LLC
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */@layer md.sys, md.comp.ripple, md.comp.focus-ring, md.comp.button;@layer md.comp.split-button{.split-btn{--between-space: 2px}.split-btn .btn{--icon-size: 0;--inner-corner-size: 0;--outer-corner-size: calc(var(--container-height) / 2);--leading-space: 0;--trailing-space: 0}.split-btn .btn-xs{--icon-size: 22px;--inner-corner-size: var(--md-sys-shape-corner-xs)}.split-btn .btn-xs:where(:nth-child(1 of .btn)){--leading-space: 12px;--trailing-space: 10px}.split-btn .btn-xs:where(:nth-last-child(1 of .btn)){--leading-space: 13px;--trailing-space: 13px}.split-btn .btn-xs:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-sm)}.split-btn .btn-xs:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-sm)}.split-btn .btn-sm{--icon-size: 22px;--inner-corner-size: var(--md-sys-shape-corner-xs)}.split-btn .btn-sm:where(:nth-child(1 of .btn)){--leading-space: 16px;--trailing-space: 12px}.split-btn .btn-sm:where(:nth-last-child(1 of .btn)){--leading-space: 13px;--trailing-space: 13px}.split-btn .btn-sm:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-sm:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-md{--icon-size: 26px;--inner-corner-size: var(--md-sys-shape-corner-xs)}.split-btn .btn-md:where(:nth-child(1 of .btn)){--leading-space: 24px;--trailing-space: 24px}.split-btn .btn-md:where(:nth-last-child(1 of .btn)){--leading-space: 15px;--trailing-space: 15px}.split-btn .btn-md:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-md:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-lg{--icon-size: 38px;--inner-corner-size: var(--md-sys-shape-corner-sm)}.split-btn .btn-lg:where(:nth-child(1 of .btn)){--leading-space: 48px;--trailing-space: 48px}.split-btn .btn-lg:where(:nth-last-child(1 of .btn)){--leading-space: 29px;--trailing-space: 29px}.split-btn .btn-lg:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn .btn-lg:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn .btn-xl{--icon-size: 50px;--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-xl:where(:nth-child(1 of .btn)){--leading-space: 64px;--trailing-space: 64px}.split-btn .btn-xl:where(:nth-last-child(1 of .btn)){--leading-space: 43px;--trailing-space: 43px}.split-btn .btn-xl:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn .btn-xl:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn:is(.split-btn-selected,:has(:popover-open)) :nth-last-child(1 of .btn){--inner-corner-size: calc(var(--container-height) / 2)}.split-btn{display:inline-flex;align-items:center;gap:var(--between-space)}.split-btn :nth-child(1 of .btn){border-start-start-radius:var(--outer-corner-size);border-end-start-radius:var(--outer-corner-size);border-start-end-radius:var(--inner-corner-size);border-end-end-radius:var(--inner-corner-size)}.split-btn :nth-last-child(1 of .btn){border-start-start-radius:var(--inner-corner-size);border-end-start-radius:var(--inner-corner-size);border-start-end-radius:var(--outer-corner-size);border-end-end-radius:var(--outer-corner-size)}.split-btn :nth-last-child(1 of .btn)::before{content:"arrow_drop_down";font:var(--md-icon-size) var(--md-icon-font);display:flex;align-items:center;aspect-ratio:1;width:var(--md-icon-size);overflow:hidden}.split-btn:is(.split-btn-selected,:has(:popover-open)) :nth-last-child(1 of .btn)::before{transform:rotate(180deg);transition:transform var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard)}}/*# sourceMappingURL=split-button.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sourceRoot":"","sources":["split-button.scss","_split-button-tokens.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA,GASA,kEACA,4BACE,WCLA,qBDQE,gBCJF,eACA,uBACA,uDACA,mBACA,oBDIE,qCCCF,mDDEI,gDCEJ,sBACA,uBDCI,qDCGJ,sBACA,+DAIA,6FAIA,mDDCE,mBCGF,kBACA,mDDDI,gDCKJ,sBACA,uBDFI,qDCMJ,sBACA,uBDHI,wCCOJ,mDDHI,0CCOJ,mDDFE,mBCMF,kBACA,mDDJI,gDCQJ,sBACA,uBDLI,qDCSJ,sBACA,uBDNI,wCCUJ,mDDNI,0CCUJ,mDDLE,mBCSF,kBACA,mDDPI,gDCWJ,sBACA,uBDRI,qDCYJ,sBACA,uBDTI,wCCaJ,6DDTI,0CCaJ,6DDRE,mBCYF,kBACA,mDDVI,gDCcJ,sBACA,uBDXI,qDCeJ,sBACA,uBDZI,wCCgBJ,6DDZI,0CCgBJ,6DDVI,kFCcJ,uDDPE,WACE,oBACA,mBACA,yBAGF,iCACE,mDACA,iDACA,iDACA,+CAGF,sCACE,mDACA,iDACA,iDACA,+CAEA,8CACE,0BACA,6CACA,aACA,mBACA,eACA,0BACA,gBAIJ,0FAEE,yBACA","file":"split-button.css"}
@@ -0,0 +1,3 @@
1
+ export declare const styles: import("lit").CSSResult;
2
+ declare const _default: CSSStyleSheet;
3
+ export default _default;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ // Generated stylesheet for ./labs/gb/components/splitbutton/split-button.css.
7
+ import { css } from 'lit';
8
+ export const styles = css `/*!
9
+ * Copyright 2026 Google LLC
10
+ * SPDX-License-Identifier: Apache-2.0
11
+ */@layer md.sys, md.comp.ripple, md.comp.focus-ring, md.comp.button;@layer md.comp.split-button{.split-btn{--between-space: 2px}.split-btn .btn{--icon-size: 0;--inner-corner-size: 0;--outer-corner-size: calc(var(--container-height) / 2);--leading-space: 0;--trailing-space: 0}.split-btn .btn-xs{--icon-size: 22px;--inner-corner-size: var(--md-sys-shape-corner-xs)}.split-btn .btn-xs:where(:nth-child(1 of .btn)){--leading-space: 12px;--trailing-space: 10px}.split-btn .btn-xs:where(:nth-last-child(1 of .btn)){--leading-space: 13px;--trailing-space: 13px}.split-btn .btn-xs:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-sm)}.split-btn .btn-xs:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-sm)}.split-btn .btn-sm{--icon-size: 22px;--inner-corner-size: var(--md-sys-shape-corner-xs)}.split-btn .btn-sm:where(:nth-child(1 of .btn)){--leading-space: 16px;--trailing-space: 12px}.split-btn .btn-sm:where(:nth-last-child(1 of .btn)){--leading-space: 13px;--trailing-space: 13px}.split-btn .btn-sm:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-sm:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-md{--icon-size: 26px;--inner-corner-size: var(--md-sys-shape-corner-xs)}.split-btn .btn-md:where(:nth-child(1 of .btn)){--leading-space: 24px;--trailing-space: 24px}.split-btn .btn-md:where(:nth-last-child(1 of .btn)){--leading-space: 15px;--trailing-space: 15px}.split-btn .btn-md:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-md:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-lg{--icon-size: 38px;--inner-corner-size: var(--md-sys-shape-corner-sm)}.split-btn .btn-lg:where(:nth-child(1 of .btn)){--leading-space: 48px;--trailing-space: 48px}.split-btn .btn-lg:where(:nth-last-child(1 of .btn)){--leading-space: 29px;--trailing-space: 29px}.split-btn .btn-lg:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn .btn-lg:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn .btn-xl{--icon-size: 50px;--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-xl:where(:nth-child(1 of .btn)){--leading-space: 64px;--trailing-space: 64px}.split-btn .btn-xl:where(:nth-last-child(1 of .btn)){--leading-space: 43px;--trailing-space: 43px}.split-btn .btn-xl:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn .btn-xl:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn:is(.split-btn-selected,:has(:popover-open)) :nth-last-child(1 of .btn){--inner-corner-size: calc(var(--container-height) / 2)}.split-btn{display:inline-flex;align-items:center;gap:var(--between-space)}.split-btn :nth-child(1 of .btn){border-start-start-radius:var(--outer-corner-size);border-end-start-radius:var(--outer-corner-size);border-start-end-radius:var(--inner-corner-size);border-end-end-radius:var(--inner-corner-size)}.split-btn :nth-last-child(1 of .btn){border-start-start-radius:var(--inner-corner-size);border-end-start-radius:var(--inner-corner-size);border-start-end-radius:var(--outer-corner-size);border-end-end-radius:var(--outer-corner-size)}.split-btn :nth-last-child(1 of .btn)::before{content:"arrow_drop_down";font:var(--md-icon-size) var(--md-icon-font);display:flex;align-items:center;aspect-ratio:1;width:var(--md-icon-size);overflow:hidden}.split-btn:is(.split-btn-selected,:has(:popover-open)) :nth-last-child(1 of .btn)::before{transform:rotate(180deg);transition:transform var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard)}}
12
+ `;
13
+ export default styles.styleSheet;
14
+ //# sourceMappingURL=split-button.cssresult.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"split-button.cssresult.js","sourceRoot":"","sources":["split-button.cssresult.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,8EAA8E;AAC9E,OAAO,EAAC,GAAG,EAAC,MAAM,KAAK,CAAC;AACxB,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;;;;CAIxB,CAAC;AACF,eAAe,MAAM,CAAC,UAAW,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n// Generated stylesheet for ./labs/gb/components/splitbutton/split-button.css.\nimport {css} from 'lit';\nexport const styles = css`/*!\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */@layer md.sys, md.comp.ripple, md.comp.focus-ring, md.comp.button;@layer md.comp.split-button{.split-btn{--between-space: 2px}.split-btn .btn{--icon-size: 0;--inner-corner-size: 0;--outer-corner-size: calc(var(--container-height) / 2);--leading-space: 0;--trailing-space: 0}.split-btn .btn-xs{--icon-size: 22px;--inner-corner-size: var(--md-sys-shape-corner-xs)}.split-btn .btn-xs:where(:nth-child(1 of .btn)){--leading-space: 12px;--trailing-space: 10px}.split-btn .btn-xs:where(:nth-last-child(1 of .btn)){--leading-space: 13px;--trailing-space: 13px}.split-btn .btn-xs:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-sm)}.split-btn .btn-xs:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-sm)}.split-btn .btn-sm{--icon-size: 22px;--inner-corner-size: var(--md-sys-shape-corner-xs)}.split-btn .btn-sm:where(:nth-child(1 of .btn)){--leading-space: 16px;--trailing-space: 12px}.split-btn .btn-sm:where(:nth-last-child(1 of .btn)){--leading-space: 13px;--trailing-space: 13px}.split-btn .btn-sm:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-sm:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-md{--icon-size: 26px;--inner-corner-size: var(--md-sys-shape-corner-xs)}.split-btn .btn-md:where(:nth-child(1 of .btn)){--leading-space: 24px;--trailing-space: 24px}.split-btn .btn-md:where(:nth-last-child(1 of .btn)){--leading-space: 15px;--trailing-space: 15px}.split-btn .btn-md:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-md:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-lg{--icon-size: 38px;--inner-corner-size: var(--md-sys-shape-corner-sm)}.split-btn .btn-lg:where(:nth-child(1 of .btn)){--leading-space: 48px;--trailing-space: 48px}.split-btn .btn-lg:where(:nth-last-child(1 of .btn)){--leading-space: 29px;--trailing-space: 29px}.split-btn .btn-lg:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn .btn-lg:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn .btn-xl{--icon-size: 50px;--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-xl:where(:nth-child(1 of .btn)){--leading-space: 64px;--trailing-space: 64px}.split-btn .btn-xl:where(:nth-last-child(1 of .btn)){--leading-space: 43px;--trailing-space: 43px}.split-btn .btn-xl:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn .btn-xl:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn:is(.split-btn-selected,:has(:popover-open)) :nth-last-child(1 of .btn){--inner-corner-size: calc(var(--container-height) / 2)}.split-btn{display:inline-flex;align-items:center;gap:var(--between-space)}.split-btn :nth-child(1 of .btn){border-start-start-radius:var(--outer-corner-size);border-end-start-radius:var(--outer-corner-size);border-start-end-radius:var(--inner-corner-size);border-end-end-radius:var(--inner-corner-size)}.split-btn :nth-last-child(1 of .btn){border-start-start-radius:var(--inner-corner-size);border-end-start-radius:var(--inner-corner-size);border-start-end-radius:var(--outer-corner-size);border-end-end-radius:var(--outer-corner-size)}.split-btn :nth-last-child(1 of .btn)::before{content:\"arrow_drop_down\";font:var(--md-icon-size) var(--md-icon-font);display:flex;align-items:center;aspect-ratio:1;width:var(--md-icon-size);overflow:hidden}.split-btn:is(.split-btn-selected,:has(:popover-open)) :nth-last-child(1 of .btn)::before{transform:rotate(180deg);transition:transform var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard)}}\n`;\nexport default styles.styleSheet!;\n"]}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { type ClassInfo } from 'lit/directives/class-map.js';
7
+ /** Split Button color configuration types. */
8
+ export type SplitButtonColor = 'filled' | 'elevated' | 'tonal' | 'outlined';
9
+ /** Split Button size configuration types. */
10
+ export type SplitButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
11
+ /** Split Button classes. */
12
+ export declare const SPLIT_BUTTON_CLASSES: {
13
+ readonly splitButton: "split-btn";
14
+ readonly splitButtonSelected: "split-btn-selected";
15
+ };
16
+ /** The state provided to the `splitButtonClasses()` function. */
17
+ export interface SplitButtonClassesState {
18
+ /** Whether the split trailing button is selected. */
19
+ selected?: boolean;
20
+ }
21
+ /**
22
+ * Returns the split button classes to apply to an element based on the given
23
+ * state.
24
+ *
25
+ * @param state The state of the split button.
26
+ * @return An object of class names and truthy values if they apply.
27
+ */
28
+ export declare function splitButtonClasses({ selected, }?: SplitButtonClassesState): ClassInfo;
29
+ /**
30
+ * A Lit directive that adds split button styling and functionality to its
31
+ * element.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * html`
36
+ * <div class="${splitButton()}">
37
+ * <button class="${button({color: 'filled'})}">Label</button>
38
+ * <button class="${button({color: 'filled'})}" popovertarget="menu"></button>
39
+ * <md-menu id="menu">
40
+ * <md-menu-item>Option 1</md-menu-item>
41
+ * <md-menu-item>Option 2</md-menu-item>
42
+ * </md-menu>
43
+ * </div>
44
+ * `;
45
+ * ```
46
+ */
47
+ export declare const splitButton: (state?: SplitButtonClassesState & import("@material/web/labs/gb/components/shared/directives.js").AdditionalClasses) => import("lit-html/directive.js").DirectiveResult;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { createClassMapDirective } from '@material/web/labs/gb/components/shared/directives.js';
7
+ /** Split Button classes. */
8
+ export const SPLIT_BUTTON_CLASSES = {
9
+ splitButton: 'split-btn',
10
+ splitButtonSelected: 'split-btn-selected',
11
+ };
12
+ /**
13
+ * Returns the split button classes to apply to an element based on the given
14
+ * state.
15
+ *
16
+ * @param state The state of the split button.
17
+ * @return An object of class names and truthy values if they apply.
18
+ */
19
+ export function splitButtonClasses({ selected = false, } = {}) {
20
+ return {
21
+ [SPLIT_BUTTON_CLASSES.splitButton]: true,
22
+ [SPLIT_BUTTON_CLASSES.splitButtonSelected]: selected,
23
+ };
24
+ }
25
+ /**
26
+ * A Lit directive that adds split button styling and functionality to its
27
+ * element.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * html`
32
+ * <div class="${splitButton()}">
33
+ * <button class="${button({color: 'filled'})}">Label</button>
34
+ * <button class="${button({color: 'filled'})}" popovertarget="menu"></button>
35
+ * <md-menu id="menu">
36
+ * <md-menu-item>Option 1</md-menu-item>
37
+ * <md-menu-item>Option 2</md-menu-item>
38
+ * </md-menu>
39
+ * </div>
40
+ * `;
41
+ * ```
42
+ */
43
+ export const splitButton = createClassMapDirective({
44
+ getClasses: splitButtonClasses,
45
+ });
46
+ //# sourceMappingURL=split-button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"split-button.js","sourceRoot":"","sources":["split-button.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,uBAAuB,EAAC,MAAM,uDAAuD,CAAC;AAS9F,4BAA4B;AAC5B,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,WAAW,EAAE,WAAW;IACxB,mBAAmB,EAAE,oBAAoB;CACjC,CAAC;AAQX;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,EACjC,QAAQ,GAAG,KAAK,MACW,EAAE;IAC7B,OAAO;QACL,CAAC,oBAAoB,CAAC,WAAW,CAAC,EAAE,IAAI;QACxC,CAAC,oBAAoB,CAAC,mBAAmB,CAAC,EAAE,QAAQ;KACrD,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,uBAAuB,CAAC;IACjD,UAAU,EAAE,kBAAkB;CAC/B,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {createClassMapDirective} from '@material/web/labs/gb/components/shared/directives.js';\nimport {type ClassInfo} from 'lit/directives/class-map.js';\n\n/** Split Button color configuration types. */\nexport type SplitButtonColor = 'filled' | 'elevated' | 'tonal' | 'outlined';\n\n/** Split Button size configuration types. */\nexport type SplitButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\n/** Split Button classes. */\nexport const SPLIT_BUTTON_CLASSES = {\n splitButton: 'split-btn',\n splitButtonSelected: 'split-btn-selected',\n} as const;\n\n/** The state provided to the `splitButtonClasses()` function. */\nexport interface SplitButtonClassesState {\n /** Whether the split trailing button is selected. */\n selected?: boolean;\n}\n\n/**\n * Returns the split button classes to apply to an element based on the given\n * state.\n *\n * @param state The state of the split button.\n * @return An object of class names and truthy values if they apply.\n */\nexport function splitButtonClasses({\n selected = false,\n}: SplitButtonClassesState = {}): ClassInfo {\n return {\n [SPLIT_BUTTON_CLASSES.splitButton]: true,\n [SPLIT_BUTTON_CLASSES.splitButtonSelected]: selected,\n };\n}\n\n/**\n * A Lit directive that adds split button styling and functionality to its\n * element.\n *\n * @example\n * ```ts\n * html`\n * <div class=\"${splitButton()}\">\n * <button class=\"${button({color: 'filled'})}\">Label</button>\n * <button class=\"${button({color: 'filled'})}\" popovertarget=\"menu\"></button>\n * <md-menu id=\"menu\">\n * <md-menu-item>Option 1</md-menu-item>\n * <md-menu-item>Option 2</md-menu-item>\n * </md-menu>\n * </div>\n * `;\n * ```\n */\nexport const splitButton = createClassMapDirective({\n getClasses: splitButtonClasses,\n});\n"]}