material-inspired-component-library 8.1.0 → 9.0.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 (284) hide show
  1. package/README.md +106 -18
  2. package/components/README.md +1 -1
  3. package/components/accordion/README.md +6 -6
  4. package/components/alert/README.md +10 -10
  5. package/components/alert/index.scss +27 -52
  6. package/components/appbar/README.md +19 -6
  7. package/components/appbar/index.scss +40 -44
  8. package/components/badge/README.md +12 -10
  9. package/components/badge/index.scss +21 -25
  10. package/components/bottomsheet/README.md +26 -1
  11. package/components/bottomsheet/index.scss +58 -44
  12. package/components/button/README.md +70 -10
  13. package/components/button/_shared.scss +210 -0
  14. package/components/button/index.scss +75 -389
  15. package/components/card/README.md +97 -85
  16. package/components/card/index.scss +46 -65
  17. package/components/checkbox/README.md +25 -14
  18. package/{tools/shapes/check.mjs → components/checkbox/_label.scss} +37 -42
  19. package/components/checkbox/index.scss +66 -66
  20. package/components/chip/README.md +186 -0
  21. package/components/chip/index.scss +285 -0
  22. package/components/datepicker/README.md +79 -0
  23. package/components/datepicker/index.scss +346 -315
  24. package/components/dialog/README.md +20 -10
  25. package/components/dialog/index.scss +55 -66
  26. package/components/divider/README.md +16 -15
  27. package/components/divider/index.scss +9 -25
  28. package/components/iconbutton/README.md +63 -12
  29. package/components/iconbutton/index.scss +142 -303
  30. package/components/list/README.md +89 -156
  31. package/components/list/index.scss +34 -36
  32. package/components/menu/README.md +81 -155
  33. package/components/menu/index.scss +52 -58
  34. package/components/navigationbar/README.md +108 -0
  35. package/components/navigationbar/index.scss +185 -0
  36. package/components/navigationrail/README.md +62 -37
  37. package/components/navigationrail/_navitem.scss +96 -0
  38. package/components/navigationrail/index.scss +78 -132
  39. package/components/progressindicator/README.md +83 -47
  40. package/components/progressindicator/index.scss +622 -172
  41. package/components/radio/README.md +11 -9
  42. package/components/radio/index.scss +36 -33
  43. package/components/select/README.md +12 -7
  44. package/components/select/index.scss +26 -34
  45. package/components/shapes/README.md +3 -3
  46. package/components/shapes/index.scss +0 -1
  47. package/components/sidesheet/README.md +21 -9
  48. package/components/sidesheet/index.scss +38 -46
  49. package/components/slider/README.md +21 -0
  50. package/components/slider/index.scss +108 -139
  51. package/components/snackbar/README.md +32 -35
  52. package/components/snackbar/index.scss +10 -22
  53. package/components/stepper/README.md +14 -7
  54. package/components/stepper/index.scss +58 -39
  55. package/components/switch/README.md +22 -15
  56. package/components/switch/index.scss +68 -60
  57. package/components/textfield/README.md +48 -5
  58. package/components/textfield/index.scss +192 -248
  59. package/components/timepicker/README.md +53 -23
  60. package/components/timepicker/index.scss +110 -128
  61. package/dist/alert.css +1 -1
  62. package/dist/alert.js +1 -1
  63. package/dist/appbar.css +1 -1
  64. package/dist/appbar.js +1 -1
  65. package/dist/badge.css +1 -1
  66. package/dist/badge.js +1 -1
  67. package/dist/base.css +1 -0
  68. package/dist/base.js +1 -0
  69. package/dist/bottomsheet.css +1 -1
  70. package/dist/bottomsheet.js +1 -1
  71. package/dist/button.css +1 -1
  72. package/dist/button.js +1 -1
  73. package/dist/card.css +1 -1
  74. package/dist/card.js +1 -1
  75. package/dist/checkbox.css +1 -1
  76. package/dist/checkbox.js +1 -1
  77. package/dist/chip.css +1 -0
  78. package/dist/chip.js +1 -0
  79. package/dist/components/button/index.d.ts +1 -1
  80. package/dist/components/iconbutton/index.d.ts +2 -7
  81. package/dist/components/slider/index.d.ts +1 -1
  82. package/dist/components/textfield/index.d.ts +2 -2
  83. package/dist/datepicker.css +1 -1
  84. package/dist/datepicker.js +1 -1
  85. package/dist/dialog.css +1 -1
  86. package/dist/dialog.js +1 -1
  87. package/dist/divider.css +1 -1
  88. package/dist/divider.js +1 -1
  89. package/dist/field.css +1 -0
  90. package/dist/field.js +1 -0
  91. package/dist/foundations/form/index.js +1 -1
  92. package/dist/foundations/runtime.d.ts +15 -0
  93. package/dist/foundations/runtime.js +1 -0
  94. package/dist/iconbutton.css +1 -1
  95. package/dist/iconbutton.js +1 -1
  96. package/dist/layout.css +1 -1
  97. package/dist/layout.js +1 -1
  98. package/dist/list.css +1 -1
  99. package/dist/list.js +1 -1
  100. package/dist/menu.css +1 -1
  101. package/dist/menu.js +1 -1
  102. package/dist/micl.css +1 -1
  103. package/dist/micl.d.ts +14 -5
  104. package/dist/micl.js +1 -1
  105. package/dist/navigationbar.css +1 -0
  106. package/dist/navigationbar.js +1 -0
  107. package/dist/navigationrail.css +1 -1
  108. package/dist/navigationrail.js +1 -1
  109. package/dist/progressindicator.css +1 -1
  110. package/dist/progressindicator.js +1 -1
  111. package/dist/radio.css +1 -1
  112. package/dist/radio.js +1 -1
  113. package/dist/scrollbar.js +1 -1
  114. package/dist/select.css +1 -1
  115. package/dist/select.js +1 -1
  116. package/dist/shapes.css +1 -1
  117. package/dist/shapes.js +1 -1
  118. package/dist/sidesheet.css +1 -1
  119. package/dist/sidesheet.js +1 -1
  120. package/dist/slider.css +1 -1
  121. package/dist/slider.js +1 -1
  122. package/dist/snackbar.css +1 -1
  123. package/dist/snackbar.js +1 -1
  124. package/dist/stepper.css +1 -1
  125. package/dist/stepper.js +1 -1
  126. package/dist/switch.css +1 -1
  127. package/dist/switch.js +1 -1
  128. package/dist/textfield.css +1 -1
  129. package/dist/textfield.js +1 -1
  130. package/dist/timepicker.css +1 -1
  131. package/dist/timepicker.js +1 -1
  132. package/foundations/_index.scss +35 -0
  133. package/foundations/{index.scss → base/index.scss} +21 -56
  134. package/foundations/field/index.scss +37 -0
  135. package/foundations/layout/index.scss +64 -65
  136. package/package.json +23 -9
  137. package/styles/statelayer.scss +20 -5
  138. package/styles.scss +5 -2
  139. package/.claude/settings.local.json +0 -14
  140. package/.editorconfig +0 -12
  141. package/.gitattributes +0 -9
  142. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -35
  143. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  144. package/CLAUDE.md +0 -53
  145. package/CODE_OF_CONDUCT.md +0 -128
  146. package/components/bottomsheet/index.ts +0 -153
  147. package/components/button/index.ts +0 -79
  148. package/components/checkbox/index.ts +0 -148
  149. package/components/datepicker/index.ts +0 -693
  150. package/components/iconbutton/index.ts +0 -77
  151. package/components/list/index.ts +0 -138
  152. package/components/menu/index.ts +0 -145
  153. package/components/navigationrail/index.ts +0 -87
  154. package/components/progressindicator/index.ts +0 -77
  155. package/components/slider/index.ts +0 -149
  156. package/components/snackbar/index.ts +0 -118
  157. package/components/stepper/index.ts +0 -248
  158. package/components/textfield/index.ts +0 -188
  159. package/components/timepicker/index.ts +0 -413
  160. package/dist/components/progressindicator/index.d.ts +0 -6
  161. package/dist/foundations.css +0 -1
  162. package/dist/foundations.js +0 -1
  163. package/docs/accordion.html +0 -344
  164. package/docs/alert.html +0 -177
  165. package/docs/bottomsheet.html +0 -240
  166. package/docs/button.html +0 -290
  167. package/docs/card-awards.webp +0 -0
  168. package/docs/card-cabinet.webp +0 -0
  169. package/docs/card-city.webp +0 -0
  170. package/docs/card-fingerprint.webp +0 -0
  171. package/docs/card-holiday.webp +0 -0
  172. package/docs/card-names.webp +0 -0
  173. package/docs/card.html +0 -159
  174. package/docs/checkbox.html +0 -147
  175. package/docs/datepicker.html +0 -274
  176. package/docs/dialog.html +0 -195
  177. package/docs/divider.html +0 -139
  178. package/docs/docs.css +0 -26
  179. package/docs/docs.js +0 -139
  180. package/docs/iconbutton.html +0 -329
  181. package/docs/index.html +0 -431
  182. package/docs/list.html +0 -310
  183. package/docs/menu.html +0 -574
  184. package/docs/micl.css +0 -1
  185. package/docs/micl.js +0 -1
  186. package/docs/navigationrail.html +0 -138
  187. package/docs/progressindicator.html +0 -288
  188. package/docs/radio.html +0 -123
  189. package/docs/select.html +0 -337
  190. package/docs/shapes.css +0 -1
  191. package/docs/shapes.html +0 -159
  192. package/docs/shapes.js +0 -1
  193. package/docs/sidesheet.html +0 -149
  194. package/docs/slider.html +0 -141
  195. package/docs/snackbar.html +0 -102
  196. package/docs/stepper.html +0 -319
  197. package/docs/switch.html +0 -196
  198. package/docs/textfield.html +0 -208
  199. package/docs/themes/airblue/dark-hc.css +0 -51
  200. package/docs/themes/airblue/dark-mc.css +0 -51
  201. package/docs/themes/airblue/dark.css +0 -51
  202. package/docs/themes/airblue/light-hc.css +0 -51
  203. package/docs/themes/airblue/light-mc.css +0 -51
  204. package/docs/themes/airblue/light.css +0 -51
  205. package/docs/themes/airblue/theme.css +0 -306
  206. package/docs/themes/barnred/dark-hc.css +0 -51
  207. package/docs/themes/barnred/dark-mc.css +0 -51
  208. package/docs/themes/barnred/dark.css +0 -51
  209. package/docs/themes/barnred/light-hc.css +0 -51
  210. package/docs/themes/barnred/light-mc.css +0 -51
  211. package/docs/themes/barnred/light.css +0 -51
  212. package/docs/themes/barnred/theme.css +0 -306
  213. package/docs/themes/citrine/dark-hc.css +0 -51
  214. package/docs/themes/citrine/dark-mc.css +0 -51
  215. package/docs/themes/citrine/dark.css +0 -51
  216. package/docs/themes/citrine/light-hc.css +0 -51
  217. package/docs/themes/citrine/light-mc.css +0 -51
  218. package/docs/themes/citrine/light.css +0 -51
  219. package/docs/themes/citrine/theme.css +0 -306
  220. package/docs/themes/gray/dark-hc.css +0 -51
  221. package/docs/themes/gray/dark-mc.css +0 -51
  222. package/docs/themes/gray/dark.css +0 -51
  223. package/docs/themes/gray/light-hc.css +0 -51
  224. package/docs/themes/gray/light-mc.css +0 -51
  225. package/docs/themes/gray/light.css +0 -51
  226. package/docs/themes/gray/theme.css +0 -306
  227. package/docs/themes/greenery/dark-hc.css +0 -51
  228. package/docs/themes/greenery/dark-mc.css +0 -51
  229. package/docs/themes/greenery/dark.css +0 -51
  230. package/docs/themes/greenery/light-hc.css +0 -51
  231. package/docs/themes/greenery/light-mc.css +0 -51
  232. package/docs/themes/greenery/light.css +0 -51
  233. package/docs/themes/greenery/theme.css +0 -306
  234. package/docs/themes/hermana/dark-hc.css +0 -51
  235. package/docs/themes/hermana/dark-mc.css +0 -51
  236. package/docs/themes/hermana/dark.css +0 -51
  237. package/docs/themes/hermana/light-hc.css +0 -51
  238. package/docs/themes/hermana/light-mc.css +0 -51
  239. package/docs/themes/hermana/light.css +0 -51
  240. package/docs/themes/hermana/theme.css +0 -306
  241. package/docs/themes/illuminating/dark-hc.css +0 -51
  242. package/docs/themes/illuminating/dark-mc.css +0 -51
  243. package/docs/themes/illuminating/dark.css +0 -51
  244. package/docs/themes/illuminating/light-hc.css +0 -51
  245. package/docs/themes/illuminating/light-mc.css +0 -51
  246. package/docs/themes/illuminating/light.css +0 -51
  247. package/docs/themes/illuminating/theme.css +0 -306
  248. package/docs/themes/magenta/dark-hc.css +0 -51
  249. package/docs/themes/magenta/dark-mc.css +0 -51
  250. package/docs/themes/magenta/dark.css +0 -51
  251. package/docs/themes/magenta/light-hc.css +0 -51
  252. package/docs/themes/magenta/light-mc.css +0 -51
  253. package/docs/themes/magenta/light.css +0 -51
  254. package/docs/themes/magenta/theme.css +0 -306
  255. package/docs/themes/mocha/dark-hc.css +0 -51
  256. package/docs/themes/mocha/dark-mc.css +0 -51
  257. package/docs/themes/mocha/dark.css +0 -51
  258. package/docs/themes/mocha/light-hc.css +0 -51
  259. package/docs/themes/mocha/light-mc.css +0 -51
  260. package/docs/themes/mocha/light.css +0 -51
  261. package/docs/themes/mocha/theme.css +0 -306
  262. package/docs/themes/olivegreen/dark-hc.css +0 -51
  263. package/docs/themes/olivegreen/dark-mc.css +0 -51
  264. package/docs/themes/olivegreen/dark.css +0 -51
  265. package/docs/themes/olivegreen/light-hc.css +0 -51
  266. package/docs/themes/olivegreen/light-mc.css +0 -51
  267. package/docs/themes/olivegreen/light.css +0 -51
  268. package/docs/themes/olivegreen/theme.css +0 -306
  269. package/docs/themes/peri/dark-hc.css +0 -51
  270. package/docs/themes/peri/dark-mc.css +0 -51
  271. package/docs/themes/peri/dark.css +0 -51
  272. package/docs/themes/peri/light-hc.css +0 -51
  273. package/docs/themes/peri/light-mc.css +0 -51
  274. package/docs/themes/peri/light.css +0 -51
  275. package/docs/themes/peri/theme.css +0 -306
  276. package/docs/timepicker.html +0 -160
  277. package/foundations/form/index.ts +0 -174
  278. package/foundations/layout/README.md +0 -127
  279. package/intl.d.ts +0 -9
  280. package/micl.ts +0 -221
  281. package/styles/README.md +0 -196
  282. package/tools/shapes/generate.mjs +0 -828
  283. package/tsconfig.json +0 -116
  284. package/webpack.config.js +0 -104
@@ -19,13 +19,13 @@
19
19
  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
20
  // SOFTWARE.
21
21
 
22
- @use '../../foundations';
23
22
  @use '../../foundations/layout';
24
23
  @use '../../styles/elevation';
25
24
  @use '../../styles/motion';
26
25
  @use '../../styles/shape';
27
26
  @use '../../styles/statelayer';
28
27
  @use '../../styles/typography';
28
+ @use 'navitem';
29
29
 
30
30
  @include elevation.level(0);
31
31
  @include elevation.level(2);
@@ -42,7 +42,6 @@
42
42
  @include statelayer.keyframes;
43
43
 
44
44
  @include typography.scale('label-large');
45
- @include typography.scale('label-medium');
46
45
 
47
46
  .micl-navigationrail {
48
47
  --md-comp-nav-rail-spring-buffer: 100px;
@@ -56,9 +55,11 @@
56
55
  --_navigationrail-current-max-width: var(--md-comp-nav-rail-collapsed-container-width, 96px);
57
56
  --_navigationrail-current-min-width: var(--md-comp-nav-rail-collapsed-container-width, 96px);
58
57
  --_navigationrail-item-direction: column;
59
- --_navigationrail-item-width: var(--md-comp-nav-rail-item-short-container-height, 56px);
58
+ --_navigationrail-item-width: var(--md-comp-nav-rail-item-vertical-active-indicator-width, 56px);
60
59
  --_navigationrail-item-target-height: var(--_navigationrail-item-base-height);
61
60
 
61
+ --micl-duration: var(--md-comp-nav-rail-motion-duration-reverse);
62
+
62
63
  --_navigationrail-content-gap: var(--md-comp-nav-rail-item-container-vertical-space, 6px);
63
64
  --_navigationrail-morph-speed: var(--md-comp-nav-rail-morph-duration-reverse);
64
65
  --_navigationrail-container-delay: calc(var(--_navigationrail-morph-speed) / 2);
@@ -70,7 +71,7 @@
70
71
  display: flex;
71
72
  flex-direction: column;
72
73
  align-items: flex-start;
73
- block-size: 100vh;
74
+ block-size: calc(100vh - env(safe-area-inset-top, 0px));
74
75
  min-block-size: 100%;
75
76
  margin-block: 0;
76
77
  margin-inline: calc(-1 * var(--md-sys-layout-window-margin, 0px)) auto;
@@ -80,7 +81,6 @@
80
81
  border: none;
81
82
  border-radius: var(--md-comp-nav-rail-collapsed-container-shape, 0px);
82
83
  box-shadow: var(--md-comp-nav-rail-collapsed-container-elevation, var(--md-sys-elevation-level0));
83
- opacity: 100%;
84
84
  overflow: hidden;
85
85
  z-index: 9;
86
86
  interpolate-size: allow-keywords;
@@ -105,43 +105,19 @@
105
105
  inline-size: 100%;
106
106
  row-gap: var(--_navigationrail-content-gap);
107
107
  padding-block: var(--md-comp-nav-rail-item-header-space-minimum, 40px) 16px;
108
- padding-inline: 20px 0;
108
+ padding-inline: 20px;
109
109
 
110
110
  overflow: hidden auto;
111
111
  transition: row-gap var(--_navigationrail-morph-speed) linear;
112
112
 
113
- &> a.micl-navigationrail__item:focus-visible {
114
- --statelayer-opacity: var(--md-sys-state-focus-state-layer-opacity, 10%);
115
- }
116
-
117
113
  &> a.micl-navigationrail__item {
118
- --micl-ripple: 1;
119
- --statelayer-color: var(--md-sys-color-on-secondary-container);
114
+ @extend %micl-navitem;
115
+
120
116
  --_navigationrail-item-base-height: var(--md-comp-nav-rail-item-short-container-height, 56px);
121
117
  --_navigationrail-item-margin-bottom: 0px;
122
118
  --_navigationrail-item-padding-block: 12px;
123
119
 
124
- box-sizing: border-box;
125
- display: flex;
126
- position: relative;
127
- align-items: center;
128
120
  row-gap: var(--md-comp-nav-rail-collapsed-item-vertical-space, 4px);
129
- outline: none;
130
- text-decoration: none;
131
- cursor: pointer;
132
-
133
- overflow: visible;
134
- background-color: transparent;
135
- background-image:
136
- radial-gradient(
137
- circle at var(--micl-x, center) var(--micl-y, center),
138
- transparent 0%,
139
- rgb(from var(--statelayer-color) r g b / calc(var(--statelayer-opacity) * var(--md-sys-state-ripple-opacity-factor))) 10%,
140
- transparent 10%
141
- ),
142
- linear-gradient(rgb(from var(--statelayer-color) r g b / var(--statelayer-opacity)));
143
- background-repeat: no-repeat;
144
- background-size: 0%, 100%;
145
121
 
146
122
  &:has(.micl-navigationrail__text) {
147
123
  --_navigationrail-item-base-height: var(--md-comp-nav-rail-item-vertical-active-indicator-height, 32px);
@@ -178,7 +154,7 @@
178
154
  padding-block: var(--_navigationrail-item-target-padding, var(--_navigationrail-item-padding-block));
179
155
  flex-direction: var(--_navigationrail-item-direction);
180
156
 
181
- border-radius: calc(var(--_navigationrail-item-target-height, var(--_navigationrail-item-base-height)) / 2);
157
+ border-radius: var(--md-comp-nav-rail-item-container-shape, calc(var(--_navigationrail-item-target-height, var(--_navigationrail-item-base-height)) / 2));
182
158
 
183
159
  transition:
184
160
  inline-size calc(var(--_navigationrail-morph-speed) / 2) var(--_navigationrail-item-delay) linear,
@@ -192,58 +168,47 @@
192
168
  --statelayer-opacity var(--md-comp-nav-rail-motion-duration) linear;
193
169
 
194
170
  .micl-navigationrail__icon {
171
+ @extend %micl-navitem-icon;
195
172
  font-size: var(--md-comp-nav-rail-item-icon-size, var(--md-sys-icon-size));
196
173
  inline-size: var(--md-comp-nav-rail-item-icon-size, var(--md-sys-icon-size));
197
- margin: 0;
198
- padding-block: 4px;
199
- padding-inline: 16px;
200
- color: var(--md-sys-color-on-surface-variant);
201
- font-variation-settings: 'FILL' 0;
174
+ padding-inline: var(--md-comp-nav-rail-item-active-indicator-leading-space, 16px) var(--md-comp-nav-rail-item-active-indicator-trailing-space, 16px);
202
175
  }
203
176
  .micl-navigationrail__text {
204
- @include typography.label-medium;
205
- min-block-size: var(--md-sys-typescale-label-medium-line-height);
206
- margin: 4px 0px 0px 0px;
207
- color: var(--md-sys-color-on-surface-variant);
208
- overflow: hidden;
177
+ @extend %micl-navitem-text;
209
178
  animation: var(--_navigationrail-text-animation);
179
+ // the typography and box switch discretely at the midpoint of the morph,
180
+ // while the animation above fades the text out and back in around it
181
+ transition:
182
+ font 0s calc(var(--_navigationrail-morph-speed) / 2),
183
+ letter-spacing 0s calc(var(--_navigationrail-morph-speed) / 2),
184
+ margin 0s calc(var(--_navigationrail-morph-speed) / 2),
185
+ padding 0s calc(var(--_navigationrail-morph-speed) / 2);
210
186
  }
211
187
 
212
- &:hover {
213
- --statelayer-opacity: var(--md-sys-state-hover-state-layer-opacity, 8%);
214
- }
215
188
  &:active {
216
- --statelayer-opacity: var(--md-sys-state-pressed-state-layer-opacity, 10%);
217
189
  transition-duration: 0ms, 0ms, 0ms, calc(var(--_navigationrail-morph-speed) / 2), 0ms, var(--md-comp-nav-rail-motion-duration);
218
190
  }
219
- &.micl-rippling {
220
- animation: micl-ripple var(--md-sys-state-ripple-duration) motion.$md-sys-motion-easing-standard;
221
- }
222
191
  }
223
192
 
224
193
  &> a.micl-navigationrail__item[aria-current="page"] {
225
- background-color: var(--md-sys-color-secondary-container);
194
+ @extend %micl-navitem-current;
226
195
 
227
196
  .micl-navigationrail__icon {
228
- color: var(--md-sys-color-on-secondary-container);
229
- font-variation-settings: 'FILL' 1;
197
+ @extend %micl-navitem-current-icon;
230
198
  }
231
199
  .micl-navigationrail__text {
232
- color: var(--md-sys-color-secondary);
200
+ @extend %micl-navitem-current-text;
233
201
  }
234
202
  }
235
203
  }
236
204
 
237
205
  &[open] {
206
+ --micl-duration: var(--md-comp-nav-rail-motion-duration);
207
+
238
208
  border-start-end-radius: var(--md-comp-nav-rail-expanded-modal-container-shape, var(--md-sys-shape-corner-large));
239
209
  border-end-end-radius: var(--md-comp-nav-rail-expanded-modal-container-shape, var(--md-sys-shape-corner-large));
240
210
  box-shadow: var(--md-comp-nav-rail-expanded-modal-container-elevation, var(--md-sys-elevation-level2));
241
211
  background-color: var(--md-comp-nav-rail-expanded-modal-container-color, var(--md-sys-color-surface-container));
242
- transition:
243
- opacity var(--md-comp-nav-rail-motion-duration) linear,
244
- margin-inline-start var(--md-comp-nav-rail-motion-duration) var(--md-comp-nav-rail-motion-spatial),
245
- overlay var(--md-comp-nav-rail-motion-duration) linear allow-discrete,
246
- display var(--md-comp-nav-rail-motion-duration) linear allow-discrete;
247
212
 
248
213
  &::backdrop {
249
214
  background-color: rgba(0, 0, 0, var(--md-sys-state-backdrop-opacity, 32%));
@@ -254,14 +219,14 @@
254
219
  &::backdrop {
255
220
  background-color: rgba(0, 0, 0, 0);
256
221
  transition:
257
- background-color var(--md-comp-nav-rail-motion-duration) linear,
258
- overlay var(--md-comp-nav-rail-motion-duration) linear allow-discrete,
259
- display var(--md-comp-nav-rail-motion-duration) linear allow-discrete;
222
+ background-color var(--micl-duration) linear,
223
+ overlay var(--micl-duration) linear allow-discrete,
224
+ display var(--micl-duration) linear allow-discrete;
260
225
  }
261
226
  }
262
227
 
263
228
  dialog.micl-navigationrail,
264
- nav.micl-navigationrail:has(> .micl-navigationrail__headline .micl-button--toggle.micl-button--selected) {
229
+ nav.micl-navigationrail:has(> .micl-navigationrail__headline .micl-button--toggle[aria-pressed="true"]) {
265
230
  --_navigationrail-current-max-width: var(--md-comp-nav-rail-expanded-container-width-maximum, 360px);
266
231
  --_navigationrail-current-min-width: var(--md-comp-nav-rail-expanded-container-width-minimum, 220px);
267
232
  --_navigationrail-item-direction: row;
@@ -283,15 +248,18 @@ nav.micl-navigationrail:has(> .micl-navigationrail__headline .micl-button--toggl
283
248
  background-color: var(--md-comp-nav-rail-expanded-container-color, var(--md-sys-color-surface));
284
249
 
285
250
  & > .micl-navigationrail__content > a.micl-navigationrail__item {
251
+ max-inline-size: 100%;
252
+
286
253
  &::before {
287
254
  content: "";
288
255
  position: absolute;
289
256
  inset: 0px;
290
- inset-inline-end: calc(-1 * (var(--md-comp-nav-rail-expanded-container-width-maximum, 360px) - 16px - 100%));
257
+ inset-inline-end: calc(-1 * (var(--md-comp-nav-rail-expanded-container-width-maximum, 360px) - var(--md-comp-nav-rail-item-horizontal-full-width-trailing-space, 16px) - 100%));
291
258
  background-color: transparent;
292
259
  }
293
260
  .micl-navigationrail__text {
294
261
  @include typography.label-large;
262
+ margin-block-start: 0;
295
263
  margin-inline-start: var(--_navigationrail-expanded-text-margin);
296
264
  padding-inline-end: 16px;
297
265
  }
@@ -303,7 +271,7 @@ nav.micl-navigationrail:has(> .micl-navigationrail__headline .micl-button--toggl
303
271
  }
304
272
  }
305
273
 
306
- nav.micl-navigationrail:has(> .micl-navigationrail__headline .micl-button--toggle.micl-button--toggled:not(.micl-button--selected)) {
274
+ nav.micl-navigationrail:has(> .micl-navigationrail__headline .micl-button--toggle.micl-button--toggled:not([aria-pressed="true"])) {
307
275
  --_navigationrail-morph-speed: var(--md-comp-nav-rail-morph-duration-reverse);
308
276
  --_navigationrail-text-animation: var(--_navigationrail-morph-speed) linear forwards navigationrail-text-to-collapsed;
309
277
  }
@@ -312,9 +280,9 @@ nav.micl-navigationrail {
312
280
  position: sticky;
313
281
  float: inline-start;
314
282
  inset: unset;
315
- inset-block-start: 0;
283
+ inset-block-start: env(safe-area-inset-top, 0px);
316
284
  inset-inline-start: 0;
317
- border-inline-end: var(--md-comp-nav-rail-divider-thickness, 0px) solid var(--md-comp-nav-rail-divider-color, var(--md-sys-divider-color));
285
+ border-inline-end: var(--md-comp-nav-rail-divider-thickness, 0px) solid var(--md-comp-nav-rail-divider-color, var(--md-comp-divider-color));
318
286
  }
319
287
 
320
288
  dialog.micl-navigationrail {
@@ -326,10 +294,10 @@ dialog.micl-navigationrail {
326
294
  opacity: 0%;
327
295
 
328
296
  transition:
329
- opacity var(--md-comp-nav-rail-motion-duration-reverse) linear,
330
- margin-inline-start var(--md-comp-nav-rail-motion-duration-reverse) var(--md-comp-nav-rail-motion-spatial),
331
- overlay var(--md-comp-nav-rail-motion-duration-reverse) linear allow-discrete,
332
- display var(--md-comp-nav-rail-motion-duration-reverse) linear allow-discrete;
297
+ opacity var(--micl-duration) linear,
298
+ margin-inline-start var(--micl-duration) var(--md-comp-nav-rail-motion-spatial),
299
+ overlay var(--micl-duration) linear allow-discrete,
300
+ display var(--micl-duration) linear allow-discrete;
333
301
 
334
302
  &[open] {
335
303
  display: flex;
@@ -343,68 +311,46 @@ dialog.micl-navigationrail {
343
311
  }
344
312
  }
345
313
 
346
- @keyframes navigationrail-text-to-collapsed {
347
- 0% {
348
- @include typography.label-large;
349
- margin-block-start: 0;
350
- margin-inline-start: var(--_navigationrail-expanded-text-margin);
351
- padding-inline-end: 16px;
352
- opacity: 100%
353
- }
354
- 49.9% {
355
- @include typography.label-large;
356
- margin-block-start: 0;
357
- margin-inline-start: var(--_navigationrail-expanded-text-margin);
358
- padding-inline-end: 16px;
359
- opacity: 0%;
360
- }
361
- 50.1% {
362
- @include typography.label-medium;
363
- min-block-size: var(--md-sys-typescale-label-medium-line-height);
364
- margin-block-start: -16px;
365
- margin-inline-start: 0px;
366
- padding-inline-end: 0px;
367
- opacity: 0%;
368
- }
369
- 100% {
370
- @include typography.label-medium;
371
- min-block-size: var(--md-sys-typescale-label-medium-line-height);
372
- margin-block-start: 4px;
373
- margin-inline-start: 0px;
374
- padding-inline-end: 0px;
375
- opacity: 100%;
314
+ // Adaptive rail: acts as a modal navigation rail below the named breakpoint and
315
+ // as a permanently visible standard (expanded) rail at the breakpoint and above.
316
+ $_breakpoints: (
317
+ medium: layout.$md-sys-breakpoint-medium-min,
318
+ expanded: layout.$md-sys-breakpoint-expanded-min,
319
+ large: layout.$md-sys-breakpoint-large-min,
320
+ extralarge: layout.$md-sys-breakpoint-extralarge-min,
321
+ );
322
+
323
+ @each $name, $min in $_breakpoints {
324
+ @media (min-width: $min) {
325
+ dialog.micl-navigationrail--modal-to-#{$name}:not([open]) {
326
+ display: flex;
327
+ position: sticky;
328
+ float: inline-start;
329
+ inset: unset;
330
+ inset-block-start: env(safe-area-inset-top, 0px);
331
+ inset-inline-start: 0;
332
+ min-inline-size: var(--_navigationrail-current-min-width);
333
+ max-inline-size: var(--_navigationrail-current-max-width);
334
+ margin-inline: calc(-1 * var(--md-sys-layout-window-margin, 0px)) auto;
335
+ padding-inline: 0;
336
+ opacity: 100%;
337
+ border-inline-end: var(--md-comp-nav-rail-divider-thickness, 0px) solid var(--md-comp-nav-rail-divider-color, var(--md-comp-divider-color));
338
+ }
376
339
  }
377
340
  }
378
341
 
342
+ // The static rules plus the delayed transitions above carry the typography switch;
343
+ // the keyframes only fade the text and slide it along the block axis.
344
+ @keyframes navigationrail-text-to-collapsed {
345
+ 0% { margin-block-start: 0; opacity: 100%; }
346
+ 45% { margin-block-start: 0; opacity: 0%; }
347
+ 55% { margin-block-start: -16px; opacity: 0%; }
348
+ 100% { margin-block-start: 4px; opacity: 100%; }
349
+ }
350
+
379
351
  @keyframes navigationrail-text-to-expanded {
380
- 0% {
381
- @include typography.label-medium;
382
- min-block-size: var(--md-sys-typescale-label-medium-line-height);
383
- margin-block-start: 4px;
384
- margin-inline-start: 0px;
385
- padding-inline-end: 0px;
386
- opacity: 100%;
387
- }
388
- 49.9% {
389
- @include typography.label-medium;
390
- min-block-size: var(--md-sys-typescale-label-medium-line-height);
391
- margin-block-start: -16px;
392
- margin-inline-start: 0px;
393
- padding-inline-end: 0px;
394
- opacity: 0%;
395
- }
396
- 50.1% {
397
- @include typography.label-large;
398
- margin-block-start: 0px;
399
- margin-inline-start: var(--_navigationrail-expanded-text-margin);
400
- padding-inline-end: 16px;
401
- opacity: 0%;
402
- }
403
- 100% {
404
- @include typography.label-large;
405
- margin-block-start: 0px;
406
- margin-inline-start: var(--_navigationrail-expanded-text-margin);
407
- padding-inline-end: 16px;
408
- opacity: 100%;
409
- }
410
- }
352
+ 0% { margin-block-start: 4px; opacity: 100%; }
353
+ 45% { margin-block-start: -16px; opacity: 0%; }
354
+ 55% { margin-block-start: 0; opacity: 0%; }
355
+ 100% { margin-block-start: 0; opacity: 100%; }
356
+ }
@@ -4,20 +4,40 @@ This component implements the [Material Design 3 Expressive Progress indicators]
4
4
  ## Basic Usage
5
5
 
6
6
  ### HTML
7
- Progress indicators use the native `<progress>` element. Add the `micl-progress-linear` class for the linear (bar) variant or `micl-progress-circular` for the circular (ring) variant.
7
+ The flat linear variant and the circular variant use the native `<progress>` element. A **determinate** indicator has a known value: provide the `value` and (optionally) `max` attributes. An **indeterminate** indicator has an unknown value: omit the `value` attribute entirely.
8
8
 
9
- A **determinate** indicator has a known value. Provide the `value` and (optionally) `max` attributes:
9
+ ```HTML
10
+ <progress class="micl-linear-progress" value="0.6"></progress>
11
+ <progress class="micl-circular-progress" value="60" max="100"></progress>
12
+
13
+ <progress class="micl-linear-progress"></progress>
14
+ <progress class="micl-circular-progress"></progress>
15
+ ```
16
+
17
+ The signature Expressive **wavy** indicators cannot be drawn inside a native `<progress>`, so they use a `progressbar`-role element with a wave child instead. A determinate wavy indicator reads its fraction from the `aria-valuenow` / `aria-valuemax` attributes:
10
18
 
11
19
  ```HTML
12
- <progress class="micl-progress-linear" value="0.6" max="1"></progress>
13
- <progress class="micl-progress-circular" value="60" max="100"></progress>
20
+ <div role="progressbar" class="micl-linear-progress"
21
+ aria-valuemin="0" aria-valuemax="1" aria-valuenow="0.6">
22
+ <div class="micl-linear-progress__wave" aria-hidden="true"></div>
23
+ </div>
24
+
25
+ <div role="progressbar" class="micl-circular-progress"
26
+ aria-valuemin="0" aria-valuemax="1" aria-valuenow="0.6">
27
+ <div class="micl-circular-progress__wave" aria-hidden="true"></div>
28
+ </div>
14
29
  ```
15
30
 
16
- An **indeterminate** indicator has an unknown value. Omit the `value` attribute entirely:
31
+ The indeterminate wavy indicators take a modifier class and, per the ARIA `progressbar` pattern, simply omit `aria-valuenow`:
17
32
 
18
33
  ```HTML
19
- <progress class="micl-progress-linear"></progress>
20
- <progress class="micl-progress-circular"></progress>
34
+ <div role="progressbar" class="micl-linear-progress micl-linear-progress--indeterminate">
35
+ <div class="micl-linear-progress__wave" aria-hidden="true"></div>
36
+ </div>
37
+
38
+ <div role="progressbar" class="micl-circular-progress micl-circular-progress--indeterminate">
39
+ <div class="micl-circular-progress__wave" aria-hidden="true"></div>
40
+ </div>
21
41
  ```
22
42
 
23
43
  ### CSS
@@ -33,11 +53,9 @@ Or import all MICL styles:
33
53
  ```
34
54
 
35
55
  ### JavaScript
36
- No custom JavaScript is required for indeterminate indicators — the looping animation is driven entirely by CSS via the native `:indeterminate` state.
37
-
38
- For determinate indicators, the bundled handler mirrors the `value` and `max` attributes into the CSS custom properties that drive the fill, the active/track gap and the Expressive wave amplitude. It also flattens the wave into a straight line over the final 10% of progress.
56
+ No custom JavaScript is required for the core functionality of this component.
39
57
 
40
- > **Updating progress at runtime:** the handler observes the `value` and `max` *attributes*. When you update progress dynamically, set the attribute (`element.setAttribute('value', 0.7)`) rather than only the IDL property (`element.value = 0.7`), so the indicator stays in sync. Alternatively, you may set the `--md-comp-progress-fraction` custom property (a number between `0` and `1`) directly for pure-CSS control without the handler.
58
+ To update progress at runtime, set the `value` attribute (`<progress>`) or the `aria-valuenow` attribute (wavy) and the indicator animates to the new value. Note that setting only the IDL property (`element.value = 0.7`) does not change the attribute; use `element.setAttribute()`.
41
59
 
42
60
  ### Live Demo
43
61
  A live example of the [Progress Indicator component](https://henkpb.github.io/micl/progressindicator.html) is available to interact with.
@@ -45,44 +63,62 @@ A live example of the [Progress Indicator component](https://henkpb.github.io/mi
45
63
  ## Variants
46
64
  The Progress Indicator component offers the following variants:
47
65
 
48
- | CSS class | Description |
49
- | --------- | ----------- |
50
- | micl-progress-linear | A horizontal linear progress bar |
51
- | micl-progress-circular | A circular progress ring |
52
- | micl-progress-circular--s | Small circular ring (28px) |
53
- | micl-progress-circular--m | Medium circular ring (48px, default) |
54
- | micl-progress-circular--l | Large circular ring (64px) |
55
-
56
- Each variant is **determinate** when a `value` attribute is present and **indeterminate** when it is omitted.
57
-
58
- The signature Expressive *wavy active indicator* is applied to the linear variant as a static shape (rasterised once, so any number of determinate indicators cost nothing per frame). Its amplitude eases to zero as the indicator reaches completion, and setting `--md-comp-progress-wave-amplitude` to `0` produces a flat (pre-Expressive) active indicator. Only the transient loading states animate: the linear indeterminate comet, and the circular indeterminate spinner (a GPU-composited rotation). The circular variant renders a smooth ring.
59
-
60
- The component respects the `dir` global attribute, automatically mirroring the linear sweep direction for right-to-left (RTL) languages when `dir="rtl"` is applied to an ancestor element. It also honours the user's `prefers-reduced-motion` setting by disabling the travelling wave and looping animations.
61
-
62
- ## Customizations
63
- You can customize the appearance of the Progress Indicator component by overriding its global CSS variables. Following the MICL convention, these `--md-comp-progress-*` variables can be set on `:root` or on any appropriate parent element to affect its child progress indicators. The colour roles default to the Material Design system colour tokens per the M3 progress-indicator specification.
64
-
65
- | Variable name | Default Value | Description |
66
- | ------------- | ------------- | ----------- |
67
- | --md-comp-progress-active-color | var(--md-sys-color-primary) | Colour of the active (filled) indicator |
68
- | --md-comp-progress-track-color | var(--md-sys-color-secondary-container) | Colour of the remaining track |
69
- | --md-comp-progress-stop-color | var(--md-sys-color-primary) | Colour of the linear end stop indicator dot |
70
- | --md-comp-progress-thickness | 4px | Thickness of the linear track and circular ring stroke |
71
- | --md-comp-progress-track-gap | 4px | Gap between the active indicator and the remaining track (linear) |
72
- | --md-comp-progress-stop-size | 4px | Diameter of the linear end stop indicator dot |
73
- | --md-comp-progress-linear-width | 100% | Default width of the linear indicator |
74
- | --md-comp-progress-wave-wavelength | 40px | Wavelength of the Expressive active wave |
75
- | --md-comp-progress-wave-amplitude | 3px | Amplitude of the Expressive active wave (set to `0` to disable) |
76
- | --md-comp-progress-indeterminate-duration | var(--md-sys-motion-duration-extra-long4) | Period of the indeterminate loop |
77
- | --md-comp-progress-circular-size | 48px | Diameter of the circular indicator |
78
- | --md-comp-progress-wave-image | (inline SVG) | The sine-ribbon mask used for the wavy active indicator |
79
-
80
- **Example: A thicker linear indicator with a calmer wave**
66
+ | CSS class | Element | Description |
67
+ | --------- | ------- | ----------- |
68
+ | `micl-linear-progress` | `<progress>` | A flat horizontal progress bar |
69
+ | `micl-linear-progress` | `<div role="progressbar">` | The Expressive wavy progress bar |
70
+ | `micl-linear-progress--indeterminate` | `<div role="progressbar">` | Modifier for the indeterminate wavy bar |
71
+ | `micl-circular-progress` | `<progress>` | A flat circular progress ring |
72
+ | `micl-circular-progress` | `<div role="progressbar">` | The Expressive wavy progress ring |
73
+ | `micl-circular-progress--indeterminate` | `<div role="progressbar">` | Modifier for the indeterminate wavy ring |
74
+
75
+ - Right-to-left layouts mirror the sweep direction, the wave travel, the gap and the stop dot automatically — via the inherited direction, no extra classes.
76
+ - Under `prefers-reduced-motion` the decorative wave travel is disabled; the functional progress animations are kept.
77
+
78
+ ## Theming
79
+ Each progress indicator can be themed with CSS custom properties that follow the Material Design 3 component-token naming convention.
80
+
81
+ ### Linear (flat and wavy)
82
+
83
+ | Custom property | Meaning | Default |
84
+ |---|---|---|
85
+ | `--md-comp-linear-progress-active-indicator-color` | Colour of the active indicator | `--md-sys-color-primary` |
86
+ | `--md-comp-linear-progress-track-color` | Colour of the remaining track | `--md-sys-color-secondary-container` |
87
+ | `--md-comp-linear-progress-stop-color` | Colour of the stop indicator dot | `--md-sys-color-primary` |
88
+ | `--md-comp-linear-progress-track-thickness` | Thickness of the track | `4px` |
89
+ | `--md-comp-linear-progress-active-thickness` | Thickness of the active indicator | `4px` |
90
+ | `--md-comp-linear-progress-track-active-space` | Gap between the active indicator and the track | `4px` |
91
+ | `--md-comp-linear-progress-stop-size` | Diameter of the stop indicator dot | `4px` |
92
+ | `--md-comp-linear-progress-stop-trailing-space` | Inset of the stop dot from the trailing edge | `0px` |
93
+
94
+ ### Wavy only
95
+
96
+ | Custom property | Meaning | Default |
97
+ |---|---|---|
98
+ | `--md-comp-linear-progress-active-wave-amplitude` | Maximum wave amplitude; set to `0px` for a flat (pre-Expressive) bar | `3px` |
99
+ | `--md-comp-linear-progress-active-wave-wavelength` | Wavelength of the determinate wave | `40px` |
100
+ | `--md-comp-linear-progress-indeterminate-active-wave-wavelength` | Wavelength of the indeterminate wave | `20px` |
101
+ | `--md-comp-linear-progress-wave-image` | The repeating wave mask tile (advanced) | built-in |
102
+
103
+ ### Circular
104
+
105
+ | Custom property | Meaning | Default |
106
+ |---|---|---|
107
+ | `--md-comp-circular-progress-active-indicator-color` | Colour of the active arc | `--md-sys-color-primary` |
108
+ | `--md-comp-circular-progress-track-color` | Colour of the remaining track ring | `--md-sys-color-secondary-container` |
109
+ | `--md-comp-circular-progress-size` | Diameter of the indicator | `40px` |
110
+ | `--md-comp-circular-progress-active-thickness` | Stroke thickness of **both** the active arc and the track ring | `4px` |
111
+ | `--md-comp-circular-progress-track-active-space` | Arc-length gap between the active arc and the track | `4px` |
112
+ | `--md-comp-circular-progress-wave-image` | The wavy ring mask (advanced, wavy variant) | built-in |
113
+
114
+ **Example: A thicker wavy indicator with a calmer wave**
81
115
 
82
116
  ```HTML
83
- <progress class="micl-progress-linear" value="0.4"
84
- style="--md-comp-progress-thickness:8px;--md-comp-progress-wave-amplitude:2px"></progress>
117
+ <div role="progressbar" class="micl-linear-progress" aria-valuenow="0.4" aria-valuemax="1"
118
+ style="--md-comp-linear-progress-active-thickness:6px;--md-comp-linear-progress-active-wave-amplitude:2px">
119
+ <div class="micl-linear-progress__wave" aria-hidden="true"></div>
120
+ </div>
85
121
  ```
86
122
 
87
123
  ## Compatibility
88
- This component utilizes relative RGB color values, CSS `mask`, `conic-gradient` and registered `@property` custom properties, which may not be fully supported in your browser. Please check [Browser compatibility](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#browser_compatibility) for details.
124
+ Determinate indicators read the `value`/`max` (or `aria-valuenow`/`aria-valuemax`) attributes from CSS using typed [`attr()`](https://developer.mozilla.org/en-US/docs/Web/CSS/attr) (CSS Values Level 5). This is supported in Chromium-based browsers; Firefox has the feature implemented behind the `layout.css.attr.enabled` preference (about:config) and is expected to ship it soon.