@material/web 2.4.2-nightly.2fe7e22.0 → 2.4.2-nightly.5088d91.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 (210) hide show
  1. package/button/internal/_touch-target.scss +1 -1
  2. package/button/internal/button.d.ts +0 -4
  3. package/button/internal/button.js.map +1 -1
  4. package/button/internal/shared-styles.css +1 -1
  5. package/button/internal/shared-styles.css.map +1 -1
  6. package/button/internal/shared-styles.cssresult.js +1 -1
  7. package/button/internal/shared-styles.cssresult.js.map +1 -1
  8. package/checkbox/internal/checkbox.d.ts +2 -2
  9. package/checkbox/internal/checkbox.js.map +1 -1
  10. package/chips/internal/chip.d.ts +2 -0
  11. package/custom-elements.json +41872 -0
  12. package/icon/internal/icon.d.ts +1 -1
  13. package/icon/internal/icon.js +1 -1
  14. package/icon/internal/icon.js.map +1 -1
  15. package/iconbutton/internal/icon-button.d.ts +0 -4
  16. package/iconbutton/internal/icon-button.js.map +1 -1
  17. package/internal/aria/aria.d.ts +1 -1
  18. package/internal/events/dispatch-hooks.js +31 -35
  19. package/internal/events/dispatch-hooks.js.map +1 -1
  20. package/labs/behaviors/form-associated.d.ts +0 -22
  21. package/labs/behaviors/form-associated.js +0 -11
  22. package/labs/behaviors/form-associated.js.map +1 -1
  23. package/labs/gb/components/button/_button-tokens.scss +30 -30
  24. package/labs/gb/components/button/button.css +1 -1
  25. package/labs/gb/components/button/button.css.map +1 -1
  26. package/labs/gb/components/button/button.cssresult.js +1 -1
  27. package/labs/gb/components/button/button.cssresult.js.map +1 -1
  28. package/labs/gb/components/button/button.d.ts +1 -16
  29. package/labs/gb/components/button/button.js +10 -33
  30. package/labs/gb/components/button/button.js.map +1 -1
  31. package/labs/gb/components/button/button.scss +25 -25
  32. package/labs/gb/components/button/md-button.d.ts +10 -2
  33. package/labs/gb/components/button/md-button.js +92 -11
  34. package/labs/gb/components/button/md-button.js.map +1 -1
  35. package/labs/gb/components/card/card.d.ts +1 -11
  36. package/labs/gb/components/card/card.js +6 -13
  37. package/labs/gb/components/card/card.js.map +1 -1
  38. package/labs/gb/components/card/md-card.d.ts +9 -1
  39. package/labs/gb/components/card/md-card.js +85 -8
  40. package/labs/gb/components/card/md-card.js.map +1 -1
  41. package/labs/gb/components/checkbox/checkbox.css +1 -1
  42. package/labs/gb/components/checkbox/checkbox.css.map +1 -1
  43. package/labs/gb/components/checkbox/checkbox.cssresult.js +1 -1
  44. package/labs/gb/components/checkbox/checkbox.cssresult.js.map +1 -1
  45. package/labs/gb/components/checkbox/checkbox.d.ts +1 -16
  46. package/labs/gb/components/checkbox/checkbox.js +8 -31
  47. package/labs/gb/components/checkbox/checkbox.js.map +1 -1
  48. package/labs/gb/components/checkbox/checkbox.scss +13 -13
  49. package/labs/gb/components/checkbox/md-checkbox.d.ts +4 -4
  50. package/labs/gb/components/checkbox/md-checkbox.js +10 -10
  51. package/labs/gb/components/checkbox/md-checkbox.js.map +1 -1
  52. package/labs/gb/components/divider/divider.d.ts +1 -11
  53. package/labs/gb/components/divider/divider.js +4 -11
  54. package/labs/gb/components/divider/divider.js.map +1 -1
  55. package/labs/gb/components/fab/fab.d.ts +1 -16
  56. package/labs/gb/components/fab/fab.js +8 -31
  57. package/labs/gb/components/fab/fab.js.map +1 -1
  58. package/labs/gb/components/fab/md-fab.js +4 -4
  59. package/labs/gb/components/fab/md-fab.js.map +1 -1
  60. package/labs/gb/components/focus/focus-ring.js +1 -1
  61. package/labs/gb/components/focus/focus-ring.js.map +1 -1
  62. package/labs/gb/components/iconbutton/_icon-button-tokens.scss +202 -0
  63. package/labs/gb/components/iconbutton/icon-button.css +4 -0
  64. package/labs/gb/components/iconbutton/icon-button.css.map +1 -0
  65. package/labs/gb/components/iconbutton/icon-button.cssresult.d.ts +3 -0
  66. package/labs/gb/components/iconbutton/icon-button.cssresult.js +14 -0
  67. package/labs/gb/components/iconbutton/icon-button.cssresult.js.map +1 -0
  68. package/labs/gb/components/iconbutton/icon-button.d.ts +97 -0
  69. package/labs/gb/components/iconbutton/icon-button.js +122 -0
  70. package/labs/gb/components/iconbutton/icon-button.js.map +1 -0
  71. package/labs/gb/components/iconbutton/icon-button.scss +153 -0
  72. package/labs/gb/components/iconbutton/md-icon-button.d.ts +73 -0
  73. package/labs/gb/components/iconbutton/md-icon-button.js +176 -0
  74. package/labs/gb/components/iconbutton/md-icon-button.js.map +1 -0
  75. package/labs/gb/components/list/_list-tokens.scss +102 -0
  76. package/labs/gb/components/list/list.css +4 -0
  77. package/labs/gb/components/list/list.css.map +1 -0
  78. package/labs/gb/components/list/list.cssresult.d.ts +3 -0
  79. package/labs/gb/components/list/list.cssresult.js +14 -0
  80. package/labs/gb/components/list/list.cssresult.js.map +1 -0
  81. package/labs/gb/components/list/list.d.ts +103 -0
  82. package/labs/gb/components/list/list.js +109 -0
  83. package/labs/gb/components/list/list.js.map +1 -0
  84. package/labs/gb/components/list/list.scss +212 -0
  85. package/labs/gb/components/list/md-list-item.d.ts +44 -0
  86. package/labs/gb/components/list/md-list-item.js +122 -0
  87. package/labs/gb/components/list/md-list-item.js.map +1 -0
  88. package/labs/gb/components/list/md-list.d.ts +26 -0
  89. package/labs/gb/components/list/md-list.js +51 -0
  90. package/labs/gb/components/list/md-list.js.map +1 -0
  91. package/labs/gb/components/menu/_menu-tokens.scss +128 -0
  92. package/labs/gb/components/menu/md-menu-group.d.ts +26 -0
  93. package/labs/gb/components/menu/md-menu-group.js +65 -0
  94. package/labs/gb/components/menu/md-menu-group.js.map +1 -0
  95. package/labs/gb/components/menu/md-menu-item.d.ts +30 -0
  96. package/labs/gb/components/menu/md-menu-item.js +165 -0
  97. package/labs/gb/components/menu/md-menu-item.js.map +1 -0
  98. package/labs/gb/components/menu/md-menu.d.ts +28 -0
  99. package/labs/gb/components/menu/md-menu.js +141 -0
  100. package/labs/gb/components/menu/md-menu.js.map +1 -0
  101. package/labs/gb/components/menu/menu.css +4 -0
  102. package/labs/gb/components/menu/menu.css.map +1 -0
  103. package/labs/gb/components/menu/menu.cssresult.d.ts +3 -0
  104. package/labs/gb/components/menu/menu.cssresult.js +14 -0
  105. package/labs/gb/components/menu/menu.cssresult.js.map +1 -0
  106. package/labs/gb/components/menu/menu.d.ts +117 -0
  107. package/labs/gb/components/menu/menu.js +107 -0
  108. package/labs/gb/components/menu/menu.js.map +1 -0
  109. package/labs/gb/components/menu/menu.scss +171 -0
  110. package/labs/gb/components/radio/md-radio.d.ts +4 -4
  111. package/labs/gb/components/radio/md-radio.js +11 -11
  112. package/labs/gb/components/radio/md-radio.js.map +1 -1
  113. package/labs/gb/components/radio/radio.css +1 -1
  114. package/labs/gb/components/radio/radio.css.map +1 -1
  115. package/labs/gb/components/radio/radio.cssresult.js +1 -1
  116. package/labs/gb/components/radio/radio.cssresult.js.map +1 -1
  117. package/labs/gb/components/radio/radio.d.ts +1 -14
  118. package/labs/gb/components/radio/radio.js +8 -23
  119. package/labs/gb/components/radio/radio.js.map +1 -1
  120. package/labs/gb/components/radio/radio.scss +4 -5
  121. package/labs/gb/components/ripple/ripple.d.ts +1 -10
  122. package/labs/gb/components/ripple/ripple.js +28 -32
  123. package/labs/gb/components/ripple/ripple.js.map +1 -1
  124. package/labs/gb/components/shared/directives.d.ts +93 -0
  125. package/labs/gb/components/shared/directives.js +111 -0
  126. package/labs/gb/components/shared/directives.js.map +1 -0
  127. package/labs/gb/components/shared/has-slotted.d.ts +10 -0
  128. package/labs/gb/components/shared/has-slotted.js +19 -0
  129. package/labs/gb/components/shared/has-slotted.js.map +1 -0
  130. package/labs/gb/components/shared/pseudo-classes.d.ts +7 -0
  131. package/labs/gb/components/shared/pseudo-classes.js +9 -0
  132. package/labs/gb/components/shared/pseudo-classes.js.map +1 -1
  133. package/labs/gb/components/splitbutton/_split-button-tokens.scss +135 -0
  134. package/labs/gb/components/splitbutton/md-split-button.d.ts +26 -0
  135. package/labs/gb/components/splitbutton/md-split-button.js +119 -0
  136. package/labs/gb/components/splitbutton/md-split-button.js.map +1 -0
  137. package/labs/gb/components/splitbutton/split-button.css +4 -0
  138. package/labs/gb/components/splitbutton/split-button.css.map +1 -0
  139. package/labs/gb/components/splitbutton/split-button.cssresult.d.ts +3 -0
  140. package/labs/gb/components/splitbutton/split-button.cssresult.js +14 -0
  141. package/labs/gb/components/splitbutton/split-button.cssresult.js.map +1 -0
  142. package/labs/gb/components/splitbutton/split-button.d.ts +47 -0
  143. package/labs/gb/components/splitbutton/split-button.js +46 -0
  144. package/labs/gb/components/splitbutton/split-button.js.map +1 -0
  145. package/labs/gb/components/splitbutton/split-button.scss +164 -0
  146. package/labs/gb/components/switch/_switch-tokens.scss +56 -0
  147. package/labs/gb/components/switch/md-switch.d.ts +66 -0
  148. package/labs/gb/components/switch/md-switch.js +162 -0
  149. package/labs/gb/components/switch/md-switch.js.map +1 -0
  150. package/labs/gb/components/switch/switch.css +4 -0
  151. package/labs/gb/components/switch/switch.css.map +1 -0
  152. package/labs/gb/components/switch/switch.cssresult.d.ts +3 -0
  153. package/labs/gb/components/switch/switch.cssresult.js +14 -0
  154. package/labs/gb/components/switch/switch.cssresult.js.map +1 -0
  155. package/labs/gb/components/switch/switch.d.ts +54 -0
  156. package/labs/gb/components/switch/switch.js +85 -0
  157. package/labs/gb/components/switch/switch.js.map +1 -0
  158. package/labs/gb/components/switch/switch.scss +109 -0
  159. package/labs/gb/styles/icon/md-icon.css +1 -1
  160. package/labs/gb/styles/icon/md-icon.css.map +1 -1
  161. package/labs/gb/styles/icon/md-icon.cssresult.js +1 -1
  162. package/labs/gb/styles/icon/md-icon.cssresult.js.map +1 -1
  163. package/labs/gb/styles/icon/md-icon.d.ts +20 -0
  164. package/labs/gb/styles/icon/md-icon.js +24 -0
  165. package/labs/gb/styles/icon/md-icon.js.map +1 -0
  166. package/labs/gb/styles/icon/md-icon.scss +2 -1
  167. package/labs/gb/styles/m3.css +5 -2
  168. package/labs/gb/styles/m3.css.map +1 -1
  169. package/labs/gb/styles/m3.cssresult.js +5 -2
  170. package/labs/gb/styles/m3.cssresult.js.map +1 -1
  171. package/labs/gb/styles/m3.scss +1 -0
  172. package/labs/gb/styles/space/md-space-tokens.css +4 -0
  173. package/labs/gb/styles/space/md-space-tokens.css.map +1 -0
  174. package/labs/gb/styles/space/md-space-tokens.cssresult.d.ts +3 -0
  175. package/labs/gb/styles/space/md-space-tokens.cssresult.js +14 -0
  176. package/labs/gb/styles/space/md-space-tokens.cssresult.js.map +1 -0
  177. package/labs/gb/styles/space/md-space-tokens.scss +28 -0
  178. package/labs/gb/styles/tailwind.css +4 -0
  179. package/labs/gb/styles/tailwind.css.map +1 -0
  180. package/labs/gb/styles/tailwind.cssresult.d.ts +3 -0
  181. package/labs/gb/styles/tailwind.cssresult.js +14 -0
  182. package/labs/gb/styles/tailwind.cssresult.js.map +1 -0
  183. package/labs/gb/styles/tailwind.scss +349 -0
  184. package/labs/gb/styles/typography/internal/_typography-tokens.scss +85 -16
  185. package/labs/gb/styles/typography/md-typography-tokens.css +1 -1
  186. package/labs/gb/styles/typography/md-typography-tokens.css.map +1 -1
  187. package/labs/gb/styles/typography/md-typography-tokens.cssresult.js +1 -1
  188. package/labs/gb/styles/typography/md-typography-tokens.cssresult.js.map +1 -1
  189. package/list/internal/listitem/list-item.d.ts +6 -1
  190. package/list/internal/listitem/list-item.js +4 -1
  191. package/list/internal/listitem/list-item.js.map +1 -1
  192. package/menu/internal/menuitem/menu-item.d.ts +2 -0
  193. package/menu/internal/submenu/sub-menu.d.ts +5 -1
  194. package/menu/internal/submenu/sub-menu.js +5 -1
  195. package/menu/internal/submenu/sub-menu.js.map +1 -1
  196. package/package.json +26 -4
  197. package/radio/internal/radio.d.ts +0 -2
  198. package/radio/internal/radio.js.map +1 -1
  199. package/select/internal/select.d.ts +2 -2
  200. package/select/internal/select.js.map +1 -1
  201. package/select/internal/selectoption/select-option.d.ts +2 -0
  202. package/slider/internal/slider.d.ts +0 -2
  203. package/slider/internal/slider.js.map +1 -1
  204. package/switch/internal/_switch.scss +1 -0
  205. package/switch/internal/switch-styles.css +1 -1
  206. package/switch/internal/switch-styles.css.map +1 -1
  207. package/switch/internal/switch-styles.cssresult.js +1 -1
  208. package/switch/internal/switch-styles.cssresult.js.map +1 -1
  209. package/switch/internal/switch.d.ts +0 -2
  210. package/switch/internal/switch.js.map +1 -1
@@ -0,0 +1,171 @@
1
+ /*!
2
+ * Copyright 2026 Google LLC
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ // go/keep-sorted start by_regex='(.+) prefix_order=sass:
7
+ @use 'menu-tokens';
8
+ // go/keep-sorted end
9
+
10
+ @layer md.sys, md.comp.ripple, md.comp.focus-ring, md.comp.divider;
11
+ @layer md.comp.menu {
12
+ .menu {
13
+ & {
14
+ @include menu-tokens.root;
15
+ }
16
+ &.menu-vibrant {
17
+ @include menu-tokens.vibrant;
18
+ --menu-vibrant: true;
19
+ }
20
+
21
+ & {
22
+ flex-direction: column;
23
+ box-shadow: var(--container-elevation);
24
+ border-radius: var(--container-shape);
25
+ background-color: var(--container-color);
26
+ padding-block: var(--group-padding);
27
+ }
28
+
29
+ &:popover-open,
30
+ &.menu-host {
31
+ display: flex;
32
+ }
33
+
34
+ &:popover-open,
35
+ :host(:popover-open):has(&.menu-host) {
36
+ position-area: end span-end;
37
+ border: none;
38
+ }
39
+
40
+ :host(:popover-open):has(&.menu-host) {
41
+ overflow: visible;
42
+ background: none;
43
+ padding: 0;
44
+ }
45
+
46
+ &.menu-host {
47
+ overflow: auto;
48
+ }
49
+
50
+ .divider,
51
+ ::slotted(.divider) {
52
+ margin: 8px 16px;
53
+ }
54
+ }
55
+
56
+ .menu-item {
57
+ & {
58
+ @include menu-tokens.item;
59
+ }
60
+ &:first-child {
61
+ @include menu-tokens.item-first-child;
62
+ }
63
+ &:last-child {
64
+ @include menu-tokens.item-last-child;
65
+ }
66
+ @container style(--menu-vibrant: true) {
67
+ & {
68
+ @include menu-tokens.item-vibrant;
69
+ }
70
+ &:where(:hover, .hover) {
71
+ @include menu-tokens.item-vibrant-hovered;
72
+ }
73
+ &:where(:focus-within, .focus) {
74
+ @include menu-tokens.item-vibrant-focused;
75
+ }
76
+ &:where(:active, .active) {
77
+ @include menu-tokens.item-vibrant-pressed;
78
+ }
79
+ }
80
+
81
+ &:is(:checked, .checked) {
82
+ @include menu-tokens.item-selected;
83
+ @container style(--menu-vibrant: true) {
84
+ @include menu-tokens.item-selected-vibrant;
85
+ }
86
+ }
87
+
88
+ &:is(:disabled, .disabled) {
89
+ @include menu-tokens.item-disabled;
90
+ @container style(--menu-vibrant: true) {
91
+ @include menu-tokens.item-disabled-vibrant;
92
+ }
93
+ &:where(:checked, .checked) {
94
+ @include menu-tokens.item-disabled-selected;
95
+ }
96
+ }
97
+
98
+ & {
99
+ position: relative;
100
+ isolation: isolate;
101
+ display: flex;
102
+ align-items: center;
103
+ user-select: none;
104
+ box-sizing: border-box;
105
+ gap: var(--between-space);
106
+ min-height: calc(var(--height) + 4px);
107
+ border-radius: var(--shape);
108
+ padding-block: var(--top-space) var(--bottom-space);
109
+ padding-inline: var(--leading-space) var(--trailing-space);
110
+ background-image: none;
111
+ outline: none;
112
+ color: var(--label-text-color);
113
+ font: var(--label-text);
114
+ letter-spacing: var(--label-text-tracking);
115
+ }
116
+
117
+ &::before {
118
+ display: flex;
119
+ content: '';
120
+ position: absolute;
121
+ inset: 2px 4px;
122
+ z-index: -1;
123
+ border-radius: inherit;
124
+ background-color: var(--container-color);
125
+ background-image: var(--ripple);
126
+ animation: var(--ripple-animation), var(--focus-ring-animation);
127
+ transition: var(--ripple-transition);
128
+ outline: var(--focus-ring-outline);
129
+ outline-offset: var(--focus-ring-offset);
130
+ }
131
+
132
+ &:not(:disabled, .disabled) {
133
+ cursor: pointer;
134
+ }
135
+
136
+ .menu-item-content {
137
+ display: flex;
138
+ flex-direction: column;
139
+ flex: 1;
140
+ }
141
+
142
+ .menu-item-supporting-text {
143
+ color: var(--supporting-text-color);
144
+ font: var(--supporting-text);
145
+ letter-spacing: var(--supporting-text-tracking);
146
+ }
147
+
148
+ .menu-item-trailing-text {
149
+ color: var(--trailing-supporting-text-color);
150
+ font: var(--trailing-supporting-text);
151
+ letter-spacing: var(--trailing-supporting-text-tracking);
152
+ }
153
+
154
+ .menu-item-leading,
155
+ .menu-item-trailing {
156
+ display: flex;
157
+ align-items: center;
158
+ gap: 8px;
159
+ }
160
+
161
+ .menu-item-leading {
162
+ --md-icon-color: var(--leading-icon-color);
163
+ --md-icon-size: var(--leading-icon-size);
164
+ }
165
+
166
+ .menu-item-trailing {
167
+ --md-icon-color: var(--trailing-icon-color);
168
+ --md-icon-size: var(--trailing-icon-size);
169
+ }
170
+ }
171
+ }
@@ -3,17 +3,17 @@
3
3
  * Copyright 2026 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { createValidator, getValidityAnchor } from '@material/web/labs/behaviors/constraint-validation.js';
7
- import { getFormState, getFormValue } from '@material/web/labs/behaviors/form-associated.js';
8
- import { RadioValidator } from '@material/web/labs/behaviors/validators/radio-validator.js';
9
6
  import { CSSResultOrNative, LitElement } from 'lit';
7
+ import { createValidator, getValidityAnchor } from '../../../behaviors/constraint-validation.js';
8
+ import { getFormState, getFormValue } from '../../../behaviors/form-associated.js';
9
+ import { RadioValidator } from '../../../behaviors/validators/radio-validator.js';
10
10
  declare global {
11
11
  interface HTMLElementTagNameMap {
12
12
  /** A Material Design radio component. */
13
13
  'md-radio': Radio;
14
14
  }
15
15
  }
16
- declare const radioBaseClass: import("@material/web/labs/behaviors/mixin.js").MixinReturn<import("@material/web/labs/behaviors/mixin.js").MixinReturn<(abstract new (...args: any[]) => import("@material/web/labs/behaviors/element-internals.js").WithElementInternals) & (abstract new (...args: any[]) => import("@material/web/labs/behaviors/focusable.js").Focusable) & typeof LitElement & import("@material/web/labs/behaviors/form-associated.js").FormAssociatedConstructor, import("@material/web/labs/behaviors/form-associated.js").FormAssociated>, import("@material/web/labs/behaviors/constraint-validation.js").ConstraintValidation>;
16
+ declare const radioBaseClass: import("@material/web/labs/behaviors/mixin.js").MixinReturn<import("@material/web/labs/behaviors/mixin.js").MixinReturn<(abstract new (...args: any[]) => import("../../../behaviors/element-internals.js").WithElementInternals) & (abstract new (...args: any[]) => import("../../../behaviors/focusable.js").Focusable) & typeof LitElement & import("../../../behaviors/form-associated.js").FormAssociatedConstructor, import("../../../behaviors/form-associated.js").FormAssociated>, import("../../../behaviors/constraint-validation.js").ConstraintValidation>;
17
17
  /**
18
18
  * A Material Design radio component.
19
19
  */
@@ -4,19 +4,19 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { __decorate } from "tslib";
7
- import { afterDispatch, setupDispatchHooks, } from '@material/web/internal/events/dispatch-hooks.js';
8
- import { createValidator, getValidityAnchor, mixinConstraintValidation, } from '@material/web/labs/behaviors/constraint-validation.js';
9
- import { internals, mixinElementInternals, } from '@material/web/labs/behaviors/element-internals.js';
10
- import { mixinFocusable } from '@material/web/labs/behaviors/focusable.js';
11
- import { getFormState, getFormValue, mixinFormAssociated, } from '@material/web/labs/behaviors/form-associated.js';
12
- import { RadioValidator } from '@material/web/labs/behaviors/validators/radio-validator.js';
13
- import { SingleSelectionController } from '@material/web/radio/internal/single-selection-controller.js';
14
7
  import { css, html, isServer, LitElement } from 'lit';
15
8
  import { customElement, property, query, state } from 'lit/decorators.js';
16
- import focusRingStyles from '@material/web/labs/gb/components/focus/focus-ring.css' with { type: 'css' }; // github-only
17
- // import focusRingStyles from '@material/web/labs/gb/components/focus/focus-ring.cssresult.js'; // google3-only
18
- import rippleStyles from '@material/web/labs/gb/components/ripple/ripple.css' with { type: 'css' }; // github-only
19
- // import rippleStyles from '@material/web/labs/gb/components/ripple/ripple.cssresult.js'; // google3-only
9
+ import { afterDispatch, setupDispatchHooks, } from '../../../../internal/events/dispatch-hooks.js';
10
+ import { SingleSelectionController } from '../../../../radio/internal/single-selection-controller.js';
11
+ import { createValidator, getValidityAnchor, mixinConstraintValidation, } from '../../../behaviors/constraint-validation.js';
12
+ import { internals, mixinElementInternals, } from '../../../behaviors/element-internals.js';
13
+ import { mixinFocusable } from '../../../behaviors/focusable.js';
14
+ import { getFormState, getFormValue, mixinFormAssociated, } from '../../../behaviors/form-associated.js';
15
+ import { RadioValidator } from '../../../behaviors/validators/radio-validator.js';
16
+ import focusRingStyles from '../focus/focus-ring.css' with { type: 'css' }; // github-only
17
+ // import focusRingStyles from '../focus/focus-ring.cssresult.js'; // google3-only
18
+ import rippleStyles from '../ripple/ripple.css' with { type: 'css' }; // github-only
19
+ // import rippleStyles from '../ripple/ripple.cssresult.js'; // google3-only
20
20
  import radioStyles from './radio.css' with { type: 'css' }; // github-only
21
21
  // import {styles as radioStyles} from './radio.cssresult.js'; // google3-only
22
22
  import { radio } from './radio.js';
@@ -1 +1 @@
1
- {"version":3,"file":"md-radio.js","sourceRoot":"","sources":["md-radio.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 {\n afterDispatch,\n setupDispatchHooks,\n} from '@material/web/internal/events/dispatch-hooks.js';\nimport {\n createValidator,\n getValidityAnchor,\n mixinConstraintValidation,\n} from '@material/web/labs/behaviors/constraint-validation.js';\nimport {\n internals,\n mixinElementInternals,\n} from '@material/web/labs/behaviors/element-internals.js';\nimport {mixinFocusable} from '@material/web/labs/behaviors/focusable.js';\nimport {\n getFormState,\n getFormValue,\n mixinFormAssociated,\n} from '@material/web/labs/behaviors/form-associated.js';\nimport {RadioValidator} from '@material/web/labs/behaviors/validators/radio-validator.js';\nimport {SingleSelectionController} from '@material/web/radio/internal/single-selection-controller.js';\nimport {css, CSSResultOrNative, html, isServer, LitElement} from 'lit';\nimport {customElement, property, query, state} from 'lit/decorators.js';\n\nimport focusRingStyles from '@material/web/labs/gb/components/focus/focus-ring.css' with {type: 'css'}; // github-only\n// import focusRingStyles from '@material/web/labs/gb/components/focus/focus-ring.cssresult.js'; // google3-only\nimport rippleStyles from '@material/web/labs/gb/components/ripple/ripple.css' with {type: 'css'}; // github-only\n// import rippleStyles from '@material/web/labs/gb/components/ripple/ripple.cssresult.js'; // google3-only\nimport radioStyles from './radio.css' with {type: 'css'}; // github-only\n// import {styles as radioStyles} from './radio.cssresult.js'; // google3-only\n\nimport {radio} from './radio.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n /** A Material Design radio component. */\n 'md-radio': Radio;\n }\n}\n\n// Separate variable needed for closure.\nconst radioBaseClass = mixinConstraintValidation(\n mixinFormAssociated(mixinElementInternals(mixinFocusable(LitElement))),\n);\n\n/**\n * A Material Design radio component.\n */\n@customElement('md-radio')\nexport class Radio extends radioBaseClass {\n static override styles: CSSResultOrNative[] = [\n focusRingStyles,\n rippleStyles,\n radioStyles,\n css`\n :host {\n display: inline-flex;\n outline: none;\n }\n .radio {\n flex: 1;\n }\n `,\n ];\n\n /**\n * Whether or not the radio is selected.\n */\n @property({type: Boolean})\n get checked() {\n return this[internals].ariaChecked === 'true';\n }\n set checked(checked: boolean) {\n const wasChecked = this.checked;\n if (wasChecked === checked) {\n return;\n }\n\n this[internals].ariaChecked = String(checked);\n this.requestUpdate('checked', wasChecked);\n this.selectionController.handleCheckedChange();\n }\n\n /**\n * The default checked state of the radio.\n */\n get defaultChecked(): boolean {\n return this.hasAttribute('checked');\n }\n set defaultChecked(value: boolean) {\n this.toggleAttribute('checked', value || false);\n }\n\n /**\n * Whether or not the radio is required. If any radio is required in a group,\n * all radios are implicitly required.\n */\n @property({type: Boolean}) required = false;\n\n /**\n * The element value to use in form submission when checked.\n */\n @property() value = 'on';\n\n @query('.radio', true) private readonly radio!: HTMLElement;\n private readonly selectionController = new SingleSelectionController(this);\n /**\n * Mimics the behavior of <input> dirty checkedness, where the `checked`\n * attribute only updates the checked state if the radio has not been\n * interacted with.\n *\n * @see https://html.spec.whatwg.org/multipage/input.html#concept-input-checked-dirty-flag\n */\n private dirtyCheckedness = false;\n @state() private isFocused = false;\n\n constructor() {\n super();\n if (isServer) return;\n this[internals].role = 'radio';\n this.addController(this.selectionController);\n setupDispatchHooks(this, 'click', 'keydown');\n this.addEventListener('click', (event) => {\n // Return if disabled, or already checked since clicking on a checked\n // radio does not dispatch events.\n if (this.disabled || this.checked) return;\n afterDispatch(event, () => {\n if (event.defaultPrevented) return;\n // Per spec, clicking on a radio input always selects it.\n this.checked = true;\n this.dirtyCheckedness = true;\n this.dispatchEvent(new Event('change', {bubbles: true}));\n this.dispatchEvent(\n new InputEvent('input', {bubbles: true, composed: true}),\n );\n });\n });\n\n this.addEventListener('keydown', (event) => {\n afterDispatch(event, () => {\n if (event.key !== ' ' || event.defaultPrevented) {\n return;\n }\n\n this.click();\n });\n });\n\n this.addEventListener('focus', () => {\n this.isFocused = true;\n });\n\n this.addEventListener('blur', () => {\n this.isFocused = false;\n });\n }\n\n protected override render() {\n return html`<div\n part=\"radio\"\n class=\"ripple-host focus-ring-host ${radio({\n checked: this.checked,\n disabled: this.disabled,\n focus: this.isFocused,\n })}\"></div>`;\n }\n\n override attributeChangedCallback(\n name: string,\n oldValue: string | null,\n newValue: string | null,\n ) {\n if (name === 'checked' && this.dirtyCheckedness) {\n // The 'checked' attribute does not update radios that have been\n // interacted with.\n return;\n }\n\n super.attributeChangedCallback(name, oldValue, newValue);\n }\n\n override [getFormValue]() {\n return this.checked ? this.value : null;\n }\n\n override [getFormState]() {\n return String(this.checked);\n }\n\n override formResetCallback() {\n this.dirtyCheckedness = false;\n this.checked = this.defaultChecked;\n }\n\n override formStateRestoreCallback(state: string) {\n this.checked = state === 'true';\n }\n\n override [createValidator]() {\n return new RadioValidator(() => {\n if (!this.selectionController) {\n // Validation runs on superclass construction, so selection controller\n // might not actually be ready until this class constructs.\n return [this];\n }\n\n return this.selectionController.controls as [Radio, ...Radio[]];\n });\n }\n\n override [getValidityAnchor]() {\n return this.radio;\n }\n}\n"]}
1
+ {"version":3,"file":"md-radio.js","sourceRoot":"","sources":["md-radio.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 {css, CSSResultOrNative, html, isServer, LitElement} from 'lit';\nimport {customElement, property, query, state} from 'lit/decorators.js';\nimport {\n afterDispatch,\n setupDispatchHooks,\n} from '../../../../internal/events/dispatch-hooks.js';\nimport {SingleSelectionController} from '../../../../radio/internal/single-selection-controller.js';\nimport {\n createValidator,\n getValidityAnchor,\n mixinConstraintValidation,\n} from '../../../behaviors/constraint-validation.js';\nimport {\n internals,\n mixinElementInternals,\n} from '../../../behaviors/element-internals.js';\nimport {mixinFocusable} from '../../../behaviors/focusable.js';\nimport {\n getFormState,\n getFormValue,\n mixinFormAssociated,\n} from '../../../behaviors/form-associated.js';\nimport {RadioValidator} from '../../../behaviors/validators/radio-validator.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 radioStyles from './radio.css' with {type: 'css'}; // github-only\n// import {styles as radioStyles} from './radio.cssresult.js'; // google3-only\n\nimport {radio} from './radio.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n /** A Material Design radio component. */\n 'md-radio': Radio;\n }\n}\n\n// Separate variable needed for closure.\nconst radioBaseClass = mixinConstraintValidation(\n mixinFormAssociated(mixinElementInternals(mixinFocusable(LitElement))),\n);\n\n/**\n * A Material Design radio component.\n */\n@customElement('md-radio')\nexport class Radio extends radioBaseClass {\n static override styles: CSSResultOrNative[] = [\n focusRingStyles,\n rippleStyles,\n radioStyles,\n css`\n :host {\n display: inline-flex;\n outline: none;\n }\n .radio {\n flex: 1;\n }\n `,\n ];\n\n /**\n * Whether or not the radio is selected.\n */\n @property({type: Boolean})\n get checked() {\n return this[internals].ariaChecked === 'true';\n }\n set checked(checked: boolean) {\n const wasChecked = this.checked;\n if (wasChecked === checked) {\n return;\n }\n\n this[internals].ariaChecked = String(checked);\n this.requestUpdate('checked', wasChecked);\n this.selectionController.handleCheckedChange();\n }\n\n /**\n * The default checked state of the radio.\n */\n get defaultChecked(): boolean {\n return this.hasAttribute('checked');\n }\n set defaultChecked(value: boolean) {\n this.toggleAttribute('checked', value || false);\n }\n\n /**\n * Whether or not the radio is required. If any radio is required in a group,\n * all radios are implicitly required.\n */\n @property({type: Boolean}) required = false;\n\n /**\n * The element value to use in form submission when checked.\n */\n @property() value = 'on';\n\n @query('.radio', true) private readonly radio!: HTMLElement;\n private readonly selectionController = new SingleSelectionController(this);\n /**\n * Mimics the behavior of <input> dirty checkedness, where the `checked`\n * attribute only updates the checked state if the radio has not been\n * interacted with.\n *\n * @see https://html.spec.whatwg.org/multipage/input.html#concept-input-checked-dirty-flag\n */\n private dirtyCheckedness = false;\n @state() private isFocused = false;\n\n constructor() {\n super();\n if (isServer) return;\n this[internals].role = 'radio';\n this.addController(this.selectionController);\n setupDispatchHooks(this, 'click', 'keydown');\n this.addEventListener('click', (event) => {\n // Return if disabled, or already checked since clicking on a checked\n // radio does not dispatch events.\n if (this.disabled || this.checked) return;\n afterDispatch(event, () => {\n if (event.defaultPrevented) return;\n // Per spec, clicking on a radio input always selects it.\n this.checked = true;\n this.dirtyCheckedness = true;\n this.dispatchEvent(new Event('change', {bubbles: true}));\n this.dispatchEvent(\n new InputEvent('input', {bubbles: true, composed: true}),\n );\n });\n });\n\n this.addEventListener('keydown', (event) => {\n afterDispatch(event, () => {\n if (event.key !== ' ' || event.defaultPrevented) {\n return;\n }\n\n this.click();\n });\n });\n\n this.addEventListener('focus', () => {\n this.isFocused = true;\n });\n\n this.addEventListener('blur', () => {\n this.isFocused = false;\n });\n }\n\n protected override render() {\n return html`<div\n part=\"radio\"\n class=\"ripple-host focus-ring-host ${radio({\n checked: this.checked,\n disabled: this.disabled,\n focus: this.isFocused,\n })}\"></div>`;\n }\n\n override attributeChangedCallback(\n name: string,\n oldValue: string | null,\n newValue: string | null,\n ) {\n if (name === 'checked' && this.dirtyCheckedness) {\n // The 'checked' attribute does not update radios that have been\n // interacted with.\n return;\n }\n\n super.attributeChangedCallback(name, oldValue, newValue);\n }\n\n override [getFormValue]() {\n return this.checked ? this.value : null;\n }\n\n override [getFormState]() {\n return String(this.checked);\n }\n\n override formResetCallback() {\n this.dirtyCheckedness = false;\n this.checked = this.defaultChecked;\n }\n\n override formStateRestoreCallback(state: string) {\n this.checked = state === 'true';\n }\n\n override [createValidator]() {\n return new RadioValidator(() => {\n if (!this.selectionController) {\n // Validation runs on superclass construction, so selection controller\n // might not actually be ready until this class constructs.\n return [this];\n }\n\n return this.selectionController.controls as [Radio, ...Radio[]];\n });\n }\n\n override [getValidityAnchor]() {\n return this.radio;\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
1
  /*!
2
2
  * Copyright 2026 Google LLC
3
3
  * SPDX-License-Identifier: Apache-2.0
4
- */@layer md.sys, md.comp.ripple, md.comp.focus-ring;@layer md.comp.radio{.radio{--icon-color: var(--md-sys-color-on-surface-variant);--icon-size: 20px;--state-layer-color: var(--md-sys-color-on-surface);--state-layer-shape: 50%;--state-layer-size: 40px}.radio:where(:hover,.hover){--icon-color: var(--md-sys-color-on-surface)}.radio:where(:focus-within,.focus){--icon-color: var(--md-sys-color-on-surface)}.radio:where(:active,.active){--state-layer-color: var(--md-sys-color-primary)}.radio:is(:checked,.checked){--icon-color: var(--md-sys-color-primary);--state-layer-color: var(--md-sys-color-primary)}.radio:is(:checked,.checked):where(:active,.active){--state-layer-color: var(--md-sys-color-on-surface)}.radio:is(:disabled,.disabled){--icon-color: hsl(from var(--md-sys-color-on-surface) h s l / 38%)}.radio{appearance:none;position:relative;display:inline-flex;align-items:center;justify-content:center;width:48px;height:48px;background-image:none;outline:none}.radio::before{content:"radio_button_unchecked";color:var(--icon-color);font-family:var(--md-icon-font);font-size:var(--icon-size);line-height:1;width:var(--icon-size);aspect-ratio:1}.radio:is(:checked,.checked)::before{content:"radio_button_checked"}.radio::after{content:"";position:absolute;aspect-ratio:1;background-image:var(--ripple);color:var(--state-layer-color);width:var(--state-layer-size);border-radius:var(--state-layer-shape);outline:var(--focus-ring-outline);outline-offset:var(--focus-ring-offset);transition:var(--ripple-transition);animation:var(--ripple-animation),var(--focus-ring-animation)}}/*# sourceMappingURL=radio.css.map */
4
+ */@layer md.sys, md.comp.ripple, md.comp.focus-ring;@layer md.comp.radio{.radio{--icon-color: var(--md-sys-color-on-surface-variant);--icon-size: 20px;--state-layer-color: var(--md-sys-color-on-surface);--state-layer-shape: 50%;--state-layer-size: 40px}.radio:where(:hover,.hover){--icon-color: var(--md-sys-color-on-surface)}.radio:where(:focus-within,.focus){--icon-color: var(--md-sys-color-on-surface)}.radio:where(:active,.active){--state-layer-color: var(--md-sys-color-primary)}.radio:is(:checked,.checked){--icon-color: var(--md-sys-color-primary);--state-layer-color: var(--md-sys-color-primary)}.radio:is(:checked,.checked):where(:active,.active){--state-layer-color: var(--md-sys-color-on-surface)}.radio:is(:disabled,.disabled){--icon-color: hsl(from var(--md-sys-color-on-surface) h s l / 38%)}.radio{appearance:none;position:relative;display:inline-flex;align-items:center;justify-content:center;width:48px;height:48px;background-image:none;outline:none;--icon: "radio_button_unchecked"}.radio::before{content:var(--icon);color:var(--icon-color);font:var(--icon-size)/1 var(--md-icon-font);width:var(--icon-size);aspect-ratio:1}.radio:is(:checked,.checked)::before{--icon: "radio_button_checked"}.radio::after{content:"";position:absolute;aspect-ratio:1;background-image:var(--ripple);color:var(--state-layer-color);width:var(--state-layer-size);border-radius:var(--state-layer-shape);outline:var(--focus-ring-outline);outline-offset:var(--focus-ring-offset);transition:var(--ripple-transition);animation:var(--ripple-animation),var(--focus-ring-animation)}}/*# sourceMappingURL=radio.css.map */
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["radio.scss","_radio-tokens.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA,GASA,kDACA,qBAEI,OCNF,qDACA,kBACA,oDACA,yBACA,yBDKI,4BCDJ,6CDII,gFAGA,8BCCJ,iDDGE,6BCCF,0CACA,iDDCI,oDCGJ,oDDCE,+BCGF,mEDCE,OACE,gBACA,kBACA,oBACA,mBACA,uBACA,WACA,YACA,sBACA,aAEA,eACE,iCACA,wBACA,gCACA,2BACA,cACA,uBACA,eAEF,qCACE,+BAEF,cACE,WACA,kBACA,eACA,+BACA,+BACA,8BACA,uCACA,kCACA,wCACA,oCACA","file":"radio.css"}
1
+ {"version":3,"sourceRoot":"","sources":["radio.scss","_radio-tokens.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA,GASA,kDACA,qBAEI,OCNF,qDACA,kBACA,oDACA,yBACA,yBDKI,4BCDJ,6CDII,gFAGA,8BCCJ,iDDGE,6BCCF,0CACA,iDDCI,oDCGJ,oDDCE,+BCGF,mEDCE,OACE,gBACA,kBACA,oBACA,mBACA,uBACA,WACA,YACA,sBACA,aACA,iCAEA,eACE,oBACA,wBACA,4CACA,uBACA,eAEF,qCACE,+BAEF,cACE,WACA,kBACA,eACA,+BACA,+BACA,8BACA,uCACA,kCACA,wCACA,oCACA","file":"radio.css"}
@@ -8,7 +8,7 @@ import { css } from 'lit';
8
8
  export const styles = css `/*!
9
9
  * Copyright 2026 Google LLC
10
10
  * SPDX-License-Identifier: Apache-2.0
11
- */@layer md.sys, md.comp.ripple, md.comp.focus-ring;@layer md.comp.radio{.radio{--icon-color: var(--md-sys-color-on-surface-variant);--icon-size: 20px;--state-layer-color: var(--md-sys-color-on-surface);--state-layer-shape: 50%;--state-layer-size: 40px}.radio:where(:hover,.hover){--icon-color: var(--md-sys-color-on-surface)}.radio:where(:focus-within,.focus){--icon-color: var(--md-sys-color-on-surface)}.radio:where(:active,.active){--state-layer-color: var(--md-sys-color-primary)}.radio:is(:checked,.checked){--icon-color: var(--md-sys-color-primary);--state-layer-color: var(--md-sys-color-primary)}.radio:is(:checked,.checked):where(:active,.active){--state-layer-color: var(--md-sys-color-on-surface)}.radio:is(:disabled,.disabled){--icon-color: hsl(from var(--md-sys-color-on-surface) h s l / 38%)}.radio{appearance:none;position:relative;display:inline-flex;align-items:center;justify-content:center;width:48px;height:48px;background-image:none;outline:none}.radio::before{content:"radio_button_unchecked";color:var(--icon-color);font-family:var(--md-icon-font);font-size:var(--icon-size);line-height:1;width:var(--icon-size);aspect-ratio:1}.radio:is(:checked,.checked)::before{content:"radio_button_checked"}.radio::after{content:"";position:absolute;aspect-ratio:1;background-image:var(--ripple);color:var(--state-layer-color);width:var(--state-layer-size);border-radius:var(--state-layer-shape);outline:var(--focus-ring-outline);outline-offset:var(--focus-ring-offset);transition:var(--ripple-transition);animation:var(--ripple-animation),var(--focus-ring-animation)}}
11
+ */@layer md.sys, md.comp.ripple, md.comp.focus-ring;@layer md.comp.radio{.radio{--icon-color: var(--md-sys-color-on-surface-variant);--icon-size: 20px;--state-layer-color: var(--md-sys-color-on-surface);--state-layer-shape: 50%;--state-layer-size: 40px}.radio:where(:hover,.hover){--icon-color: var(--md-sys-color-on-surface)}.radio:where(:focus-within,.focus){--icon-color: var(--md-sys-color-on-surface)}.radio:where(:active,.active){--state-layer-color: var(--md-sys-color-primary)}.radio:is(:checked,.checked){--icon-color: var(--md-sys-color-primary);--state-layer-color: var(--md-sys-color-primary)}.radio:is(:checked,.checked):where(:active,.active){--state-layer-color: var(--md-sys-color-on-surface)}.radio:is(:disabled,.disabled){--icon-color: hsl(from var(--md-sys-color-on-surface) h s l / 38%)}.radio{appearance:none;position:relative;display:inline-flex;align-items:center;justify-content:center;width:48px;height:48px;background-image:none;outline:none;--icon: "radio_button_unchecked"}.radio::before{content:var(--icon);color:var(--icon-color);font:var(--icon-size)/1 var(--md-icon-font);width:var(--icon-size);aspect-ratio:1}.radio:is(:checked,.checked)::before{--icon: "radio_button_checked"}.radio::after{content:"";position:absolute;aspect-ratio:1;background-image:var(--ripple);color:var(--state-layer-color);width:var(--state-layer-size);border-radius:var(--state-layer-shape);outline:var(--focus-ring-outline);outline-offset:var(--focus-ring-offset);transition:var(--ripple-transition);animation:var(--ripple-animation),var(--focus-ring-animation)}}
12
12
  `;
13
13
  export default styles.styleSheet;
14
14
  //# sourceMappingURL=radio.cssresult.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"radio.cssresult.js","sourceRoot":"","sources":["radio.cssresult.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,iEAAiE;AACjE,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/radio/radio.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;@layer md.comp.radio{.radio{--icon-color: var(--md-sys-color-on-surface-variant);--icon-size: 20px;--state-layer-color: var(--md-sys-color-on-surface);--state-layer-shape: 50%;--state-layer-size: 40px}.radio:where(:hover,.hover){--icon-color: var(--md-sys-color-on-surface)}.radio:where(:focus-within,.focus){--icon-color: var(--md-sys-color-on-surface)}.radio:where(:active,.active){--state-layer-color: var(--md-sys-color-primary)}.radio:is(:checked,.checked){--icon-color: var(--md-sys-color-primary);--state-layer-color: var(--md-sys-color-primary)}.radio:is(:checked,.checked):where(:active,.active){--state-layer-color: var(--md-sys-color-on-surface)}.radio:is(:disabled,.disabled){--icon-color: hsl(from var(--md-sys-color-on-surface) h s l / 38%)}.radio{appearance:none;position:relative;display:inline-flex;align-items:center;justify-content:center;width:48px;height:48px;background-image:none;outline:none}.radio::before{content:\"radio_button_unchecked\";color:var(--icon-color);font-family:var(--md-icon-font);font-size:var(--icon-size);line-height:1;width:var(--icon-size);aspect-ratio:1}.radio:is(:checked,.checked)::before{content:\"radio_button_checked\"}.radio::after{content:\"\";position:absolute;aspect-ratio:1;background-image:var(--ripple);color:var(--state-layer-color);width:var(--state-layer-size);border-radius:var(--state-layer-shape);outline:var(--focus-ring-outline);outline-offset:var(--focus-ring-offset);transition:var(--ripple-transition);animation:var(--ripple-animation),var(--focus-ring-animation)}}\n`;\nexport default styles.styleSheet!;\n"]}
1
+ {"version":3,"file":"radio.cssresult.js","sourceRoot":"","sources":["radio.cssresult.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,iEAAiE;AACjE,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/radio/radio.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;@layer md.comp.radio{.radio{--icon-color: var(--md-sys-color-on-surface-variant);--icon-size: 20px;--state-layer-color: var(--md-sys-color-on-surface);--state-layer-shape: 50%;--state-layer-size: 40px}.radio:where(:hover,.hover){--icon-color: var(--md-sys-color-on-surface)}.radio:where(:focus-within,.focus){--icon-color: var(--md-sys-color-on-surface)}.radio:where(:active,.active){--state-layer-color: var(--md-sys-color-primary)}.radio:is(:checked,.checked){--icon-color: var(--md-sys-color-primary);--state-layer-color: var(--md-sys-color-primary)}.radio:is(:checked,.checked):where(:active,.active){--state-layer-color: var(--md-sys-color-on-surface)}.radio:is(:disabled,.disabled){--icon-color: hsl(from var(--md-sys-color-on-surface) h s l / 38%)}.radio{appearance:none;position:relative;display:inline-flex;align-items:center;justify-content:center;width:48px;height:48px;background-image:none;outline:none;--icon: \"radio_button_unchecked\"}.radio::before{content:var(--icon);color:var(--icon-color);font:var(--icon-size)/1 var(--md-icon-font);width:var(--icon-size);aspect-ratio:1}.radio:is(:checked,.checked)::before{--icon: \"radio_button_checked\"}.radio::after{content:\"\";position:absolute;aspect-ratio:1;background-image:var(--ripple);color:var(--state-layer-color);width:var(--state-layer-size);border-radius:var(--state-layer-shape);outline:var(--focus-ring-outline);outline-offset:var(--focus-ring-offset);transition:var(--ripple-transition);animation:var(--ripple-animation),var(--focus-ring-animation)}}\n`;\nexport default styles.styleSheet!;\n"]}
@@ -3,7 +3,6 @@
3
3
  * Copyright 2026 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { AttributePart, Directive, DirectiveParameters } from 'lit/async-directive.js';
7
6
  import { type ClassInfo } from 'lit/directives/class-map.js';
8
7
  /** Radio classes. */
9
8
  export declare const RADIO_CLASSES: {
@@ -43,17 +42,6 @@ export declare function radioClasses({ hover, focus, active, checked, disabled,
43
42
  export declare function setupRadio(radio: HTMLElement, opts?: {
44
43
  signal?: AbortSignal;
45
44
  }): void;
46
- /** The state provided to the `radio()` directive. */
47
- export interface RadioDirectiveState extends RadioClassesState {
48
- /** Additional classes to apply to the element. */
49
- classes?: ClassInfo;
50
- }
51
- declare class RadioDirective extends Directive {
52
- private element?;
53
- private cleanup?;
54
- render(state?: RadioDirectiveState): import("lit-html/directive.js").DirectiveResult<typeof import("lit-html/directives/class-map.js").ClassMapDirective>;
55
- update({ element }: AttributePart, [state]: DirectiveParameters<this>): import("lit-html/directive.js").DirectiveResult<typeof import("lit-html/directives/class-map.js").ClassMapDirective>;
56
- }
57
45
  /**
58
46
  * A Lit directive that adds radio styling and functionality to its element.
59
47
  *
@@ -66,5 +54,4 @@ declare class RadioDirective extends Directive {
66
54
  * `;
67
55
  * ```
68
56
  */
69
- export declare const radio: (state?: RadioDirectiveState) => import("lit-html/directive.js").DirectiveResult<typeof RadioDirective>;
70
- export {};
57
+ export declare const radio: (state?: RadioClassesState & import("../shared/directives.js").AdditionalClasses) => import("lit-html/directive.js").DirectiveResult;
@@ -3,11 +3,10 @@
3
3
  * Copyright 2026 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { focusRingClasses } from '@material/web/labs/gb/components/focus/focus-ring.js';
7
- import { rippleClasses, setupRipple, } from '@material/web/labs/gb/components/ripple/ripple.js';
8
- import { PSEUDO_CLASSES } from '@material/web/labs/gb/components/shared/pseudo-classes.js';
9
- import { Directive, directive, } from 'lit/async-directive.js';
10
- import { classMap } from 'lit/directives/class-map.js';
6
+ import { focusRingClasses } from '../focus/focus-ring.js';
7
+ import { rippleClasses, setupRipple } from '../ripple/ripple.js';
8
+ import { createClassMapDirective } from '../shared/directives.js';
9
+ import { PSEUDO_CLASSES } from '../shared/pseudo-classes.js';
11
10
  /** Radio classes. */
12
11
  export const RADIO_CLASSES = {
13
12
  radio: 'radio',
@@ -44,23 +43,6 @@ export function radioClasses({ hover = false, focus = false, active = false, che
44
43
  export function setupRadio(radio, opts) {
45
44
  setupRipple(radio, opts);
46
45
  }
47
- class RadioDirective extends Directive {
48
- render(state = {}) {
49
- return classMap({
50
- ...(state.classes || {}),
51
- ...radioClasses(state),
52
- });
53
- }
54
- update({ element }, [state]) {
55
- if (element !== this.element) {
56
- this.element = element;
57
- this.cleanup?.abort();
58
- this.cleanup = new AbortController();
59
- setupRadio(this.element, { signal: this.cleanup.signal });
60
- }
61
- return this.render(state);
62
- }
63
- }
64
46
  /**
65
47
  * A Lit directive that adds radio styling and functionality to its element.
66
48
  *
@@ -73,5 +55,8 @@ class RadioDirective extends Directive {
73
55
  * `;
74
56
  * ```
75
57
  */
76
- export const radio = directive(RadioDirective);
58
+ export const radio = createClassMapDirective({
59
+ getClasses: radioClasses,
60
+ setupElement: setupRadio,
61
+ });
77
62
  //# sourceMappingURL=radio.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"radio.js","sourceRoot":"","sources":["radio.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,gBAAgB,EAAC,MAAM,sDAAsD,CAAC;AACtF,OAAO,EACL,aAAa,EACb,WAAW,GACZ,MAAM,mDAAmD,CAAC;AAC3D,OAAO,EAAC,cAAc,EAAC,MAAM,2DAA2D,CAAC;AACzF,OAAO,EAEL,SAAS,EACT,SAAS,GAEV,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAC,QAAQ,EAAiB,MAAM,6BAA6B,CAAC;AAErE,qBAAqB;AACrB,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,cAAc,CAAC,KAAK;IAC3B,KAAK,EAAE,cAAc,CAAC,KAAK;IAC3B,MAAM,EAAE,cAAc,CAAC,MAAM;IAC7B,OAAO,EAAE,cAAc,CAAC,OAAO;IAC/B,QAAQ,EAAE,cAAc,CAAC,QAAQ;CACzB,CAAC;AAgBX;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,EAC3B,KAAK,GAAG,KAAK,EACb,KAAK,GAAG,KAAK,EACb,MAAM,GAAG,KAAK,EACd,OAAO,GAAG,KAAK,EACf,QAAQ,GAAG,KAAK,MACK,EAAE;IACvB,OAAO;QACL,GAAG,aAAa,EAAE;QAClB,GAAG,gBAAgB,EAAE;QACrB,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,IAAI;QAC3B,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,KAAK;QAC5B,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,KAAK;QAC5B,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM;QAC9B,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,OAAO;QAChC,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,QAAQ;KACnC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CACxB,KAAkB,EAClB,IAA6B;IAE7B,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AAC3B,CAAC;AAQD,MAAM,cAAe,SAAQ,SAAS;IAIpC,MAAM,CAAC,QAA6B,EAAE;QACpC,OAAO,QAAQ,CAAC;YACd,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;YACxB,GAAG,YAAY,CAAC,KAAK,CAAC;SACvB,CAAC,CAAC;IACL,CAAC;IAEQ,MAAM,CACb,EAAC,OAAO,EAAgB,EACxB,CAAC,KAAK,CAA4B;QAElC,IAAI,OAAO,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,OAAO,GAAG,OAAsB,CAAC;YACtC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;YACtB,IAAI,CAAC,OAAO,GAAG,IAAI,eAAe,EAAE,CAAC;YACrC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,EAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAC,CAAC,CAAC;QAC1D,CAAC;QAED,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;CACF;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,SAAS,CAAC,cAAc,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {focusRingClasses} from '@material/web/labs/gb/components/focus/focus-ring.js';\nimport {\n rippleClasses,\n setupRipple,\n} from '@material/web/labs/gb/components/ripple/ripple.js';\nimport {PSEUDO_CLASSES} from '@material/web/labs/gb/components/shared/pseudo-classes.js';\nimport {\n AttributePart,\n Directive,\n directive,\n DirectiveParameters,\n} from 'lit/async-directive.js';\nimport {classMap, type ClassInfo} from 'lit/directives/class-map.js';\n\n/** Radio classes. */\nexport const RADIO_CLASSES = {\n radio: 'radio',\n hover: PSEUDO_CLASSES.hover,\n focus: PSEUDO_CLASSES.focus,\n active: PSEUDO_CLASSES.active,\n checked: PSEUDO_CLASSES.checked,\n disabled: PSEUDO_CLASSES.disabled,\n} as const;\n\n/** The state provided to the `radioClasses()` function. */\nexport interface RadioClassesState {\n /** Emulates `:hover`. */\n hover?: boolean;\n /** Emulates `:focus`. */\n focus?: boolean;\n /** Emulates `:active`. */\n active?: boolean;\n /** Emulates `:checked`. */\n checked?: boolean;\n /** Emulates `:disabled`. */\n disabled?: boolean;\n}\n\n/**\n * Returns the radio classes to apply to an element based on the given state.\n *\n * @param state The state of the radio.\n * @return An object of class names and truthy values if they apply.\n */\nexport function radioClasses({\n hover = false,\n focus = false,\n active = false,\n checked = false,\n disabled = false,\n}: RadioClassesState = {}): ClassInfo {\n return {\n ...rippleClasses(),\n ...focusRingClasses(),\n [RADIO_CLASSES.radio]: true,\n [RADIO_CLASSES.hover]: hover,\n [RADIO_CLASSES.focus]: focus,\n [RADIO_CLASSES.active]: active,\n [RADIO_CLASSES.checked]: checked,\n [RADIO_CLASSES.disabled]: disabled,\n };\n}\n\n/**\n * Sets up radio functionality for the given element.\n *\n * @param radio The element on which to set up radio functionality.\n * @param opts Setup options, supports a cleanup `signal`.\n */\nexport function setupRadio(\n radio: HTMLElement,\n opts?: {signal?: AbortSignal},\n): void {\n setupRipple(radio, opts);\n}\n\n/** The state provided to the `radio()` directive. */\nexport interface RadioDirectiveState extends RadioClassesState {\n /** Additional classes to apply to the element. */\n classes?: ClassInfo;\n}\n\nclass RadioDirective extends Directive {\n private element?: HTMLElement;\n private cleanup?: AbortController;\n\n render(state: RadioDirectiveState = {}) {\n return classMap({\n ...(state.classes || {}),\n ...radioClasses(state),\n });\n }\n\n override update(\n {element}: AttributePart,\n [state]: DirectiveParameters<this>,\n ) {\n if (element !== this.element) {\n this.element = element as HTMLElement;\n this.cleanup?.abort();\n this.cleanup = new AbortController();\n setupRadio(this.element, {signal: this.cleanup.signal});\n }\n\n return this.render(state);\n }\n}\n\n/**\n * A Lit directive that adds radio styling and functionality to its element.\n *\n * @example\n * ```ts\n * html`\n * <input type=\"radio\" class=\"${radio()}\" name=\"radio-group\">\n * <input type=\"radio\" class=\"${radio()}\" name=\"radio-group\">\n * <input type=\"radio\" class=\"${radio()}\" name=\"radio-group\">\n * `;\n * ```\n */\nexport const radio = directive(RadioDirective);\n"]}
1
+ {"version":3,"file":"radio.js","sourceRoot":"","sources":["radio.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAC,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAC,aAAa,EAAE,WAAW,EAAC,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAC,uBAAuB,EAAC,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAC,cAAc,EAAC,MAAM,6BAA6B,CAAC;AAE3D,qBAAqB;AACrB,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,cAAc,CAAC,KAAK;IAC3B,KAAK,EAAE,cAAc,CAAC,KAAK;IAC3B,MAAM,EAAE,cAAc,CAAC,MAAM;IAC7B,OAAO,EAAE,cAAc,CAAC,OAAO;IAC/B,QAAQ,EAAE,cAAc,CAAC,QAAQ;CACzB,CAAC;AAgBX;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,EAC3B,KAAK,GAAG,KAAK,EACb,KAAK,GAAG,KAAK,EACb,MAAM,GAAG,KAAK,EACd,OAAO,GAAG,KAAK,EACf,QAAQ,GAAG,KAAK,MACK,EAAE;IACvB,OAAO;QACL,GAAG,aAAa,EAAE;QAClB,GAAG,gBAAgB,EAAE;QACrB,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,IAAI;QAC3B,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,KAAK;QAC5B,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,KAAK;QAC5B,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM;QAC9B,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,OAAO;QAChC,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,QAAQ;KACnC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CACxB,KAAkB,EAClB,IAA6B;IAE7B,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,uBAAuB,CAAC;IAC3C,UAAU,EAAE,YAAY;IACxB,YAAY,EAAE,UAAU;CACzB,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {type ClassInfo} from 'lit/directives/class-map.js';\nimport {focusRingClasses} from '../focus/focus-ring.js';\nimport {rippleClasses, setupRipple} from '../ripple/ripple.js';\nimport {createClassMapDirective} from '../shared/directives.js';\nimport {PSEUDO_CLASSES} from '../shared/pseudo-classes.js';\n\n/** Radio classes. */\nexport const RADIO_CLASSES = {\n radio: 'radio',\n hover: PSEUDO_CLASSES.hover,\n focus: PSEUDO_CLASSES.focus,\n active: PSEUDO_CLASSES.active,\n checked: PSEUDO_CLASSES.checked,\n disabled: PSEUDO_CLASSES.disabled,\n} as const;\n\n/** The state provided to the `radioClasses()` function. */\nexport interface RadioClassesState {\n /** Emulates `:hover`. */\n hover?: boolean;\n /** Emulates `:focus`. */\n focus?: boolean;\n /** Emulates `:active`. */\n active?: boolean;\n /** Emulates `:checked`. */\n checked?: boolean;\n /** Emulates `:disabled`. */\n disabled?: boolean;\n}\n\n/**\n * Returns the radio classes to apply to an element based on the given state.\n *\n * @param state The state of the radio.\n * @return An object of class names and truthy values if they apply.\n */\nexport function radioClasses({\n hover = false,\n focus = false,\n active = false,\n checked = false,\n disabled = false,\n}: RadioClassesState = {}): ClassInfo {\n return {\n ...rippleClasses(),\n ...focusRingClasses(),\n [RADIO_CLASSES.radio]: true,\n [RADIO_CLASSES.hover]: hover,\n [RADIO_CLASSES.focus]: focus,\n [RADIO_CLASSES.active]: active,\n [RADIO_CLASSES.checked]: checked,\n [RADIO_CLASSES.disabled]: disabled,\n };\n}\n\n/**\n * Sets up radio functionality for the given element.\n *\n * @param radio The element on which to set up radio functionality.\n * @param opts Setup options, supports a cleanup `signal`.\n */\nexport function setupRadio(\n radio: HTMLElement,\n opts?: {signal?: AbortSignal},\n): void {\n setupRipple(radio, opts);\n}\n\n/**\n * A Lit directive that adds radio styling and functionality to its element.\n *\n * @example\n * ```ts\n * html`\n * <input type=\"radio\" class=\"${radio()}\" name=\"radio-group\">\n * <input type=\"radio\" class=\"${radio()}\" name=\"radio-group\">\n * <input type=\"radio\" class=\"${radio()}\" name=\"radio-group\">\n * `;\n * ```\n */\nexport const radio = createClassMapDirective({\n getClasses: radioClasses,\n setupElement: setupRadio,\n});\n"]}
@@ -44,18 +44,17 @@
44
44
  height: 48px;
45
45
  background-image: none;
46
46
  outline: none;
47
+ --icon: 'radio_button_unchecked';
47
48
 
48
49
  &::before {
49
- content: 'radio_button_unchecked';
50
+ content: var(--icon);
50
51
  color: var(--icon-color);
51
- font-family: var(--md-icon-font);
52
- font-size: var(--icon-size);
53
- line-height: 1;
52
+ font: var(--icon-size) / 1 var(--md-icon-font);
54
53
  width: var(--icon-size);
55
54
  aspect-ratio: 1;
56
55
  }
57
56
  &:is(:checked, .checked)::before {
58
- content: 'radio_button_checked';
57
+ --icon: 'radio_button_checked';
59
58
  }
60
59
  &::after {
61
60
  content: '';
@@ -3,7 +3,6 @@
3
3
  * Copyright 2026 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { Directive, ElementPart, PartInfo } from 'lit/directive.js';
7
6
  import { type ClassInfo } from 'lit/directives/class-map.js';
8
7
  /** Ripple classes. */
9
8
  export declare const RIPPLE_CLASSES: {
@@ -39,13 +38,6 @@ export declare function rippleClasses({ hover, active, disabled, }?: RippleClass
39
38
  export declare function setupRipple(ripple: HTMLElement, opts?: {
40
39
  signal?: AbortSignal;
41
40
  }): void;
42
- declare class RippleDirective extends Directive {
43
- private element?;
44
- private cleanup?;
45
- constructor(partInfo: PartInfo);
46
- render(): void;
47
- update({ element }: ElementPart): symbol;
48
- }
49
41
  /**
50
42
  * A Lit directive that adds updates the position of a ripple to match pointer
51
43
  * interactions. Use with the `.ripple` class.
@@ -82,5 +74,4 @@ declare class RippleDirective extends Directive {
82
74
  * `;
83
75
  * ```
84
76
  */
85
- export declare const ripple: () => import("lit-html/directive.js").DirectiveResult<typeof RippleDirective>;
86
- export {};
77
+ export declare const ripple: () => import("lit-html/directive.js").DirectiveResult;
@@ -3,9 +3,8 @@
3
3
  * Copyright 2026 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { PSEUDO_CLASSES } from '@material/web/labs/gb/components/shared/pseudo-classes.js';
7
- import { noChange } from 'lit';
8
- import { Directive, directive, PartType, } from 'lit/directive.js';
6
+ import { createElementDirective } from '../shared/directives.js';
7
+ import { PSEUDO_CLASSES, isDisabled } from '../shared/pseudo-classes.js';
9
8
  /** Ripple classes. */
10
9
  export const RIPPLE_CLASSES = {
11
10
  ripple: 'ripple',
@@ -56,22 +55,16 @@ export function setupRipple(ripple, opts) {
56
55
  });
57
56
  }
58
57
  }
58
+ catch {
59
+ // Ignore errors if the properties are already registered.
60
+ }
59
61
  finally {
60
62
  ripplePropertiesRegistered = true;
61
63
  }
62
64
  }
63
65
  let minimumPressTimeoutId;
64
- ripple.addEventListener('pointerdown', (event) => {
65
- if (ripple.matches(':disabled,.disabled'))
66
- return;
67
- // Set ripple position to the pointer position.
68
- const rect = ripple.getBoundingClientRect();
69
- const x = (event.clientX - rect.x) / rect.width;
70
- const y = (event.clientY - rect.y) / rect.height;
71
- ripple.style.setProperty('--ripple-x', `${x * 100}%`);
72
- ripple.style.setProperty('--ripple-y', `${y * 100}%`);
73
- // If another pointerdown is received while the ripple is active, restart
74
- // the active press animation.
66
+ const activateRipple = () => {
67
+ // If the ripple is already active, restart the current press animation.
75
68
  if (ripple.classList.contains(RIPPLE_CLASSES.active)) {
76
69
  const pressAnimation = ripple
77
70
  .getAnimations()
@@ -87,30 +80,33 @@ export function setupRipple(ripple, opts) {
87
80
  minimumPressTimeoutId = setTimeout(() => {
88
81
  ripple.classList.remove(RIPPLE_CLASSES.active);
89
82
  }, MINIMUM_PRESS_MS);
83
+ };
84
+ // Return true if the ripple is disabled, or if the ripple class has been
85
+ // removed. This allows components to disable and re-enable ripple behavior.
86
+ const isRippleDisabled = () => isDisabled(ripple) || !ripple.matches(`.${RIPPLE_CLASSES.ripple}`);
87
+ ripple.addEventListener('pointerdown', (event) => {
88
+ if (isRippleDisabled())
89
+ return;
90
+ // Set ripple position to the pointer position.
91
+ const rect = ripple.getBoundingClientRect();
92
+ const x = (event.clientX - rect.x) / rect.width;
93
+ const y = (event.clientY - rect.y) / rect.height;
94
+ ripple.style.setProperty('--ripple-x', `${x * 100}%`);
95
+ ripple.style.setProperty('--ripple-y', `${y * 100}%`);
96
+ activateRipple();
90
97
  }, opts);
91
98
  ripple.addEventListener('keydown', (event) => {
92
99
  // Reset ripple pointer position when a key is pressed.
93
100
  ripple.style.removeProperty('--ripple-x');
94
101
  ripple.style.removeProperty('--ripple-y');
95
102
  }, opts);
96
- }
97
- class RippleDirective extends Directive {
98
- constructor(partInfo) {
99
- super(partInfo);
100
- if (partInfo.type !== PartType.ELEMENT) {
101
- throw new Error('The `ripple` directive must be used on an element');
102
- }
103
- }
104
- render() { }
105
- update({ element }) {
106
- if (this.element !== element) {
107
- this.element = element;
108
- this.cleanup?.abort();
109
- this.cleanup = new AbortController();
110
- setupRipple(this.element, { signal: this.cleanup.signal });
103
+ ripple.addEventListener('click', (event) => {
104
+ // A UIEvent.detail click count of 0 indicates the click was not triggered
105
+ // by a pointer. Show the ripple press effect for these clicks as well.
106
+ if (event.detail === 0 && !isRippleDisabled()) {
107
+ activateRipple();
111
108
  }
112
- return noChange;
113
- }
109
+ }, opts);
114
110
  }
115
111
  /**
116
112
  * A Lit directive that adds updates the position of a ripple to match pointer
@@ -148,5 +144,5 @@ class RippleDirective extends Directive {
148
144
  * `;
149
145
  * ```
150
146
  */
151
- export const ripple = directive(RippleDirective);
147
+ export const ripple = createElementDirective(setupRipple);
152
148
  //# sourceMappingURL=ripple.js.map