material-inspired-component-library 5.0.0 → 6.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 (204) hide show
  1. package/README.md +15 -1
  2. package/components/alert/index.scss +4 -4
  3. package/components/appbar/index.scss +3 -2
  4. package/components/badge/index.scss +2 -2
  5. package/components/bottomsheet/index.scss +6 -5
  6. package/components/button/README.md +9 -1
  7. package/components/button/index.scss +20 -20
  8. package/components/button/index.ts +21 -37
  9. package/components/card/index.scss +10 -9
  10. package/components/checkbox/index.scss +11 -11
  11. package/components/datepicker/README.md +146 -0
  12. package/components/datepicker/index.scss +436 -0
  13. package/components/datepicker/index.ts +701 -0
  14. package/components/dialog/README.md +6 -6
  15. package/components/dialog/index.scss +23 -17
  16. package/components/divider/index.scss +2 -0
  17. package/components/iconbutton/README.md +10 -1
  18. package/components/iconbutton/index.scss +18 -17
  19. package/components/iconbutton/index.ts +21 -37
  20. package/components/list/index.scss +10 -10
  21. package/components/menu/index.scss +2 -1
  22. package/components/navigationrail/index.scss +10 -9
  23. package/components/radio/README.md +0 -1
  24. package/components/radio/index.scss +11 -11
  25. package/components/select/index.scss +2 -1
  26. package/components/sidesheet/index.scss +3 -1
  27. package/components/slider/index.scss +7 -7
  28. package/components/stepper/index.scss +5 -4
  29. package/components/switch/README.md +0 -1
  30. package/components/switch/index.scss +21 -21
  31. package/components/textfield/index.scss +6 -5
  32. package/components/textfield/index.ts +63 -6
  33. package/components/timepicker/README.md +8 -9
  34. package/components/timepicker/index.scss +9 -8
  35. package/components/timepicker/index.ts +17 -17
  36. package/dist/alert.css +1 -1
  37. package/dist/appbar.css +1 -1
  38. package/dist/badge.css +1 -1
  39. package/dist/bottomsheet.css +1 -1
  40. package/dist/button.css +1 -1
  41. package/dist/card.css +1 -1
  42. package/dist/checkbox.css +1 -1
  43. package/dist/components/button/index.d.ts +2 -1
  44. package/dist/components/datepicker/index.d.ts +6 -0
  45. package/dist/components/iconbutton/index.d.ts +2 -1
  46. package/dist/datepicker.css +1 -0
  47. package/dist/datepicker.js +1 -0
  48. package/dist/dialog.css +1 -1
  49. package/dist/divider.css +1 -1
  50. package/dist/foundations.css +1 -0
  51. package/dist/foundations.js +1 -0
  52. package/dist/iconbutton.css +1 -1
  53. package/dist/layout.css +1 -1
  54. package/dist/list.css +1 -1
  55. package/dist/menu.css +1 -1
  56. package/dist/micl.css +1 -1
  57. package/dist/micl.js +1 -1
  58. package/dist/navigationrail.css +1 -1
  59. package/dist/radio.css +1 -1
  60. package/dist/scrollbar.css +1 -0
  61. package/dist/scrollbar.js +1 -0
  62. package/dist/select.css +1 -1
  63. package/dist/sidesheet.css +1 -1
  64. package/dist/slider.css +1 -1
  65. package/dist/stepper.css +1 -1
  66. package/dist/switch.css +1 -1
  67. package/dist/textfield.css +1 -1
  68. package/dist/timepicker.css +1 -1
  69. package/docs/accordion.html +3 -1
  70. package/docs/alert.html +3 -1
  71. package/docs/bottomsheet.html +6 -4
  72. package/docs/button.html +19 -17
  73. package/docs/card.html +3 -1
  74. package/docs/checkbox.html +3 -1
  75. package/docs/datepicker.html +275 -0
  76. package/docs/dialog.html +24 -10
  77. package/docs/divider.html +3 -1
  78. package/docs/docs.js +65 -1
  79. package/docs/iconbutton.html +9 -9
  80. package/docs/index.html +6 -3
  81. package/docs/list.html +3 -1
  82. package/docs/menu.html +3 -1
  83. package/docs/micl.css +1 -1
  84. package/docs/micl.js +1 -1
  85. package/docs/navigationrail.html +5 -3
  86. package/docs/radio.html +3 -1
  87. package/docs/select.html +3 -1
  88. package/docs/sidesheet.html +6 -4
  89. package/docs/slider.html +1 -1
  90. package/docs/stepper.html +3 -1
  91. package/docs/switch.html +3 -1
  92. package/docs/textfield.html +3 -1
  93. package/docs/themes/gray/dark-hc.css +51 -0
  94. package/docs/themes/gray/dark-mc.css +51 -0
  95. package/docs/themes/gray/dark.css +51 -0
  96. package/docs/themes/gray/light-hc.css +51 -0
  97. package/docs/themes/gray/light-mc.css +51 -0
  98. package/docs/themes/gray/light.css +51 -0
  99. package/docs/themes/gray/theme.css +306 -0
  100. package/docs/themes/greenery/dark-hc.css +51 -0
  101. package/docs/themes/greenery/dark-mc.css +51 -0
  102. package/docs/themes/greenery/dark.css +51 -0
  103. package/docs/themes/greenery/light-hc.css +51 -0
  104. package/docs/themes/greenery/light-mc.css +51 -0
  105. package/docs/themes/greenery/light.css +51 -0
  106. package/docs/themes/greenery/theme.css +306 -0
  107. package/docs/themes/hermana/dark-hc.css +51 -0
  108. package/docs/themes/hermana/dark-mc.css +51 -0
  109. package/docs/themes/hermana/dark.css +51 -0
  110. package/docs/themes/hermana/light-hc.css +51 -0
  111. package/docs/themes/hermana/light-mc.css +51 -0
  112. package/docs/themes/hermana/light.css +51 -0
  113. package/docs/themes/hermana/theme.css +306 -0
  114. package/docs/themes/illuminating/dark-hc.css +51 -0
  115. package/docs/themes/illuminating/dark-mc.css +51 -0
  116. package/docs/themes/illuminating/dark.css +51 -0
  117. package/docs/themes/illuminating/light-hc.css +51 -0
  118. package/docs/themes/illuminating/light-mc.css +51 -0
  119. package/docs/themes/illuminating/light.css +51 -0
  120. package/docs/themes/illuminating/theme.css +306 -0
  121. package/docs/themes/magenta/dark-hc.css +51 -0
  122. package/docs/themes/magenta/dark-mc.css +51 -0
  123. package/docs/themes/magenta/dark.css +51 -0
  124. package/docs/themes/magenta/light-hc.css +51 -0
  125. package/docs/themes/magenta/light-mc.css +51 -0
  126. package/docs/themes/magenta/light.css +51 -0
  127. package/docs/themes/magenta/theme.css +306 -0
  128. package/docs/themes/mocha/dark-hc.css +51 -0
  129. package/docs/themes/mocha/dark-mc.css +51 -0
  130. package/docs/themes/mocha/dark.css +51 -0
  131. package/docs/themes/mocha/light-hc.css +51 -0
  132. package/docs/themes/mocha/light-mc.css +51 -0
  133. package/docs/themes/mocha/light.css +51 -0
  134. package/docs/themes/mocha/theme.css +306 -0
  135. package/docs/themes/peri/dark-hc.css +51 -0
  136. package/docs/themes/peri/dark-mc.css +51 -0
  137. package/docs/themes/peri/dark.css +51 -0
  138. package/docs/themes/peri/light-hc.css +51 -0
  139. package/docs/themes/peri/light-mc.css +51 -0
  140. package/docs/themes/peri/light.css +51 -0
  141. package/docs/themes/peri/theme.css +306 -0
  142. package/docs/timepicker.html +5 -3
  143. package/foundations/index.scss +102 -0
  144. package/foundations/layout/index.scss +0 -52
  145. package/foundations/scrollbar/index.scss +46 -0
  146. package/intl.d.ts +9 -0
  147. package/micl.ts +18 -8
  148. package/package.json +2 -1
  149. package/styles/README.md +17 -8
  150. package/styles/motion.scss +3 -0
  151. package/styles/shapes.scss +23 -18
  152. package/styles/statelayer.scss +4 -0
  153. package/styles/typography.scss +2 -2
  154. package/styles.scss +3 -26
  155. package/themes/gray/dark-hc.css +51 -0
  156. package/themes/gray/dark-mc.css +51 -0
  157. package/themes/gray/dark.css +51 -0
  158. package/themes/gray/light-hc.css +51 -0
  159. package/themes/gray/light-mc.css +51 -0
  160. package/themes/gray/light.css +51 -0
  161. package/themes/gray/theme.css +306 -0
  162. package/themes/greenery/dark-hc.css +51 -0
  163. package/themes/greenery/dark-mc.css +51 -0
  164. package/themes/greenery/dark.css +51 -0
  165. package/themes/greenery/light-hc.css +51 -0
  166. package/themes/greenery/light-mc.css +51 -0
  167. package/themes/greenery/light.css +51 -0
  168. package/themes/greenery/theme.css +306 -0
  169. package/themes/hermana/dark-hc.css +51 -0
  170. package/themes/hermana/dark-mc.css +51 -0
  171. package/themes/hermana/dark.css +51 -0
  172. package/themes/hermana/light-hc.css +51 -0
  173. package/themes/hermana/light-mc.css +51 -0
  174. package/themes/hermana/light.css +51 -0
  175. package/themes/hermana/theme.css +306 -0
  176. package/themes/illuminating/dark-hc.css +51 -0
  177. package/themes/illuminating/dark-mc.css +51 -0
  178. package/themes/illuminating/dark.css +51 -0
  179. package/themes/illuminating/light-hc.css +51 -0
  180. package/themes/illuminating/light-mc.css +51 -0
  181. package/themes/illuminating/light.css +51 -0
  182. package/themes/illuminating/theme.css +306 -0
  183. package/themes/magenta/dark-hc.css +51 -0
  184. package/themes/magenta/dark-mc.css +51 -0
  185. package/themes/magenta/dark.css +51 -0
  186. package/themes/magenta/light-hc.css +51 -0
  187. package/themes/magenta/light-mc.css +51 -0
  188. package/themes/magenta/light.css +51 -0
  189. package/themes/magenta/theme.css +306 -0
  190. package/themes/mocha/dark-hc.css +51 -0
  191. package/themes/mocha/dark-mc.css +51 -0
  192. package/themes/mocha/dark.css +51 -0
  193. package/themes/mocha/light-hc.css +51 -0
  194. package/themes/mocha/light-mc.css +51 -0
  195. package/themes/mocha/light.css +51 -0
  196. package/themes/mocha/theme.css +306 -0
  197. package/themes/peri/dark-hc.css +51 -0
  198. package/themes/peri/dark-mc.css +51 -0
  199. package/themes/peri/dark.css +51 -0
  200. package/themes/peri/light-hc.css +51 -0
  201. package/themes/peri/light-mc.css +51 -0
  202. package/themes/peri/light.css +51 -0
  203. package/themes/peri/theme.css +306 -0
  204. package/tsconfig.json +2 -2
@@ -19,7 +19,7 @@
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/layout';
22
+ @use '../../foundations';
23
23
  @use '../../styles/motion';
24
24
  @use '../../styles/shapes';
25
25
  @use '../../styles/statelayer';
@@ -41,7 +41,7 @@
41
41
  @mixin slider-track-disabled() {
42
42
  background-image: linear-gradient(
43
43
  var(--md-sys-slider-track-direction),
44
- color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent) calc(100% * (var(--md-sys-slider-value) - var(--md-sys-slider-min)) / (var(--md-sys-slider-max) - var(--md-sys-slider-min))),
44
+ color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-disabled-state-layer-opacity, 38%), transparent) calc(100% * (var(--md-sys-slider-value) - var(--md-sys-slider-min)) / (var(--md-sys-slider-max) - var(--md-sys-slider-min))),
45
45
  transparent calc(100% * (var(--md-sys-slider-value) - var(--md-sys-slider-min)) / (var(--md-sys-slider-max) - var(--md-sys-slider-min))),
46
46
  color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent) calc(100% * (var(--md-sys-slider-value) - var(--md-sys-slider-min)) / (var(--md-sys-slider-max) - var(--md-sys-slider-min))),
47
47
  color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent) 100%,
@@ -79,8 +79,8 @@
79
79
  var(--md-sys-slider-track-direction),
80
80
  transparent 0px,
81
81
  transparent var(--md-sys-slider-thumb-space),
82
- color-mix(in srgb, var(--md-sys-color-on-surface) 38%, var(--md-sys-color-surface)) var(--md-sys-slider-thumb-space),
83
- color-mix(in srgb, var(--md-sys-color-on-surface) 38%, var(--md-sys-color-surface)) 10px,
82
+ color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-disabled-state-layer-opacity, 38%), var(--md-sys-color-surface)) var(--md-sys-slider-thumb-space),
83
+ color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-disabled-state-layer-opacity, 38%), var(--md-sys-color-surface)) 10px,
84
84
  transparent 10px,
85
85
  transparent 16px
86
86
  );
@@ -223,10 +223,10 @@ input[type=range].micl-slider-xl {
223
223
  }
224
224
  &:focus-visible {
225
225
  &::-webkit-slider-thumb {
226
- outline: var(--md-sys-state-focus-indicator-thickness) solid var(--md-sys-color-secondary);
226
+ outline: var(--md-sys-state-focus-indicator-thickness, 3px) solid var(--md-sys-color-secondary);
227
227
  }
228
228
  &::-moz-range-thumb {
229
- outline: var(--md-sys-state-focus-indicator-thickness) solid var(--md-sys-color-secondary);
229
+ outline: var(--md-sys-state-focus-indicator-thickness, 3px) solid var(--md-sys-color-secondary);
230
230
  }
231
231
  }
232
232
  &:active {
@@ -273,7 +273,7 @@ input[type=range].micl-slider-xl {
273
273
  grid-area: slider-icon;
274
274
  inset: 0;
275
275
  margin: 6px;
276
- font-size: var(--md-sys-layout-icon-size, 24px);
276
+ font-size: var(--md-sys-icon-size, 24px);
277
277
  color: var(--md-sys-color-on-primary);
278
278
  z-index: 1;
279
279
  }
@@ -19,8 +19,9 @@
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/layout';
22
+ @use '../../foundations';
23
23
  @use '../../styles/motion';
24
+ @use '../../styles/statelayer';
24
25
 
25
26
  :root {
26
27
  --md-sys-stepper-counter-style: decimal;
@@ -38,7 +39,7 @@ body {
38
39
  box-sizing: border-box;
39
40
  display: flex;
40
41
  flex-direction: column;
41
- row-gap: var(--md-sys-layout-padding-xl, 24px);
42
+ row-gap: var(--md-sys-padding-xl, 24px);
42
43
  margin: 0;
43
44
  background-color: inherit;
44
45
 
@@ -119,7 +120,7 @@ body {
119
120
  &>:last-child {
120
121
  display: flex;
121
122
  flex: 1 1 0;
122
- column-gap: var(--md-sys-layout-padding-xs, 8px)
123
+ column-gap: var(--md-sys-padding-xs, 8px)
123
124
  }
124
125
  &>:last-child {
125
126
  justify-content: flex-end;
@@ -139,7 +140,7 @@ body {
139
140
  text-align: center;
140
141
  background-color: var(--md-sys-color-on-surface);
141
142
  color: var(--md-sys-color-surface);
142
- opacity: 38%;
143
+ opacity: var(--md-sys-state-disabled-state-layer-opacity, 38%);
143
144
  counter-increment: dotnumber 1;
144
145
  }
145
146
  .micl-stepper__progress--done.micl-stepper__progress-dot,
@@ -59,7 +59,6 @@ You can customize the appearance of the Switch component by overriding its globa
59
59
  | --md-sys-switch-handle-selected-size | 24px | The diameter of the handle when the switch is "on" |
60
60
  | --md-sys-switch-handle-pressed-size | 28px | The diameter of the handle when the switch is pressed |
61
61
  | --md-sys-switch-outline-width | 2px | The width of the border |
62
- | --md-sys-switch-state-layer-size | 40px | Sets the size of the area that indicates the component's current state (e.g., hover, focus, press) |
63
62
  | --md-sys-switch-target-height | 32px | The height of the track |
64
63
  | --md-sys-switch-target-width | 52px | The width of the track |
65
64
 
@@ -19,6 +19,7 @@
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';
22
23
  @use '../../styles/motion';
23
24
  @use '../../styles/shapes';
24
25
  @use '../../styles/statelayer';
@@ -29,7 +30,6 @@
29
30
  --md-sys-switch-handle-selected-size: 24px;
30
31
  --md-sys-switch-handle-pressed-size: 28px;
31
32
  --md-sys-switch-outline-width: 2px;
32
- --md-sys-switch-state-layer-size: 40px;
33
33
  --md-sys-switch-target-height: 32px;
34
34
  --md-sys-switch-target-width: 52px;
35
35
  }
@@ -56,7 +56,7 @@ input[type=checkbox].micl-switch {
56
56
  display: block;
57
57
  inline-size: var(--md-sys-switch-target-width);
58
58
  block-size: var(--md-sys-switch-target-height);
59
- margin-block: calc((var(--md-sys-target-size) - var(--md-sys-switch-target-height)) / 2);
59
+ margin-block: calc((var(--md-sys-target-size, 48px) - var(--md-sys-switch-target-height)) / 2);
60
60
  border: var(--md-sys-switch-outline-width) solid var(--md-sys-color-outline);
61
61
  border-radius: inherit;
62
62
  background-color: var(--md-sys-color-surface-container-highest);
@@ -66,17 +66,17 @@ input[type=checkbox].micl-switch {
66
66
  content: var(--md-sys-switch-unselected-icon);
67
67
  box-sizing: border-box;
68
68
  position: absolute;
69
- inline-size: var(--md-sys-switch-state-layer-size);
70
- block-size: var(--md-sys-switch-state-layer-size);
69
+ inline-size: var(--md-sys-state-layer-size, 40px);
70
+ block-size: var(--md-sys-state-layer-size, 40px);
71
71
  inset: 0;
72
- inset-inline-start: calc((var(--md-sys-target-size) - var(--md-sys-switch-state-layer-size) - 16px) / 2);
72
+ inset-inline-start: calc((var(--md-sys-target-size, 48px) - var(--md-sys-state-layer-size, 40px) - 16px) / 2);
73
73
  margin: auto 0;
74
74
  font: 300 16px / 1rem var(--md-ref-typeface-plain);
75
75
  color: var(--md-sys-color-surface-container-highest);
76
76
  text-align: center;
77
77
  background-color: var(--md-sys-color-outline);
78
78
  background-clip: content-box;
79
- border: calc((var(--md-sys-switch-state-layer-size) - var(--md-sys-switch-handle-size)) / 2) solid transparent;
79
+ border: calc((var(--md-sys-state-layer-size, 40px) - var(--md-sys-switch-handle-size)) / 2) solid transparent;
80
80
  border-radius: var(--md-sys-shape-corner-full);
81
81
  transform: rotate(135deg);
82
82
  transition:
@@ -93,11 +93,11 @@ input[type=checkbox].micl-switch {
93
93
  }
94
94
  &::after {
95
95
  content: var(--md-sys-switch-selected-icon);
96
- inset-inline-start: calc(var(--md-sys-switch-target-width) - ((var(--md-sys-switch-state-layer-size) + var(--md-sys-target-size) - 16px) / 2));
96
+ inset-inline-start: calc(var(--md-sys-switch-target-width) - ((var(--md-sys-state-layer-size, 40px) + var(--md-sys-target-size, 48px) - 16px) / 2));
97
97
  font-size: 1.6rem;
98
98
  line-height: 1.3rem;
99
99
  letter-spacing: 0.1rem;
100
- border: calc((var(--md-sys-switch-state-layer-size) - var(--md-sys-switch-handle-selected-size)) / 2) solid transparent;
100
+ border: calc((var(--md-sys-state-layer-size, 40px) - var(--md-sys-switch-handle-selected-size)) / 2) solid transparent;
101
101
  color: var(--md-sys-color-on-primary-container);
102
102
  background-color: var(--md-sys-color-on-primary);
103
103
  }
@@ -107,24 +107,24 @@ input[type=checkbox].micl-switch {
107
107
 
108
108
  &:hover {
109
109
  &::after {
110
- border-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), transparent);
110
+ border-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity, 8%), transparent);
111
111
  background-color: var(--md-sys-color-on-surface-variant);
112
112
  }
113
113
  &:checked::after {
114
- border-color: color-mix(in srgb, var(--md-sys-color-primary) var(--md-sys-state-hover-state-layer-opacity), transparent);
114
+ border-color: color-mix(in srgb, var(--md-sys-color-primary) var(--md-sys-state-hover-state-layer-opacity, 8%), transparent);
115
115
  background-color: var(--md-sys-color-primary-container);
116
116
  }
117
117
  }
118
118
  &:focus-visible {
119
119
  &::after {
120
- border-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-focus-state-layer-opacity), transparent);
120
+ border-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-focus-state-layer-opacity, 10%), transparent);
121
121
  }
122
122
  &::before {
123
- outline: var(--md-sys-state-focus-indicator-thickness) solid var(--md-sys-color-secondary);
123
+ outline: var(--md-sys-state-focus-indicator-thickness, 3px) solid var(--md-sys-color-secondary);
124
124
  outline-offset: 2px;
125
125
  }
126
126
  &:checked::after {
127
- border-color: color-mix(in srgb, var(--md-sys-color-primary) var(--md-sys-state-focus-state-layer-opacity), transparent);
127
+ border-color: color-mix(in srgb, var(--md-sys-color-primary) var(--md-sys-state-focus-state-layer-opacity, 10%), transparent);
128
128
  background-color: var(--md-sys-color-primary-container);
129
129
  }
130
130
  &:not(:checked)::after {
@@ -134,18 +134,18 @@ input[type=checkbox].micl-switch {
134
134
  &:active {
135
135
  &::after {
136
136
  line-height: 1.7rem;
137
- border: calc((var(--md-sys-switch-state-layer-size) - var(--md-sys-switch-handle-pressed-size)) / 2) solid transparent;
137
+ border: calc((var(--md-sys-state-layer-size, 40px) - var(--md-sys-switch-handle-pressed-size)) / 2) solid transparent;
138
138
  background-color: var(--md-sys-color-on-surface-variant);
139
139
  }
140
140
  &:checked::after {
141
141
  line-height: 1.6rem;
142
- border-width: calc((var(--md-sys-switch-state-layer-size) - var(--md-sys-switch-handle-pressed-size)) / 2);
143
- border-color: color-mix(in srgb, var(--md-sys-color-primary) var(--md-sys-state-pressed-state-layer-opacity), transparent);
142
+ border-width: calc((var(--md-sys-state-layer-size, 40px) - var(--md-sys-switch-handle-pressed-size)) / 2);
143
+ border-color: color-mix(in srgb, var(--md-sys-color-primary) var(--md-sys-state-pressed-state-layer-opacity, 10%), transparent);
144
144
  background-color: var(--md-sys-color-primary-container);
145
145
  }
146
146
  &:not(:checked)::after {
147
- inset-inline-start: calc((var(--md-sys-target-size) - var(--md-sys-switch-state-layer-size) - 16px) / 2);
148
- border-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-pressed-state-layer-opacity), transparent);
147
+ inset-inline-start: calc((var(--md-sys-target-size, 48px) - var(--md-sys-state-layer-size, 40px) - 16px) / 2);
148
+ border-color: color-mix(in srgb, var(--md-sys-color-on-surface) var(--md-sys-state-pressed-state-layer-opacity, 10%), transparent);
149
149
  }
150
150
  }
151
151
  }
@@ -159,12 +159,12 @@ input[type=checkbox].micl-switch {
159
159
  background-color: var(--md-sys-color-on-surface);
160
160
  }
161
161
  &::after {
162
- color: rgb(from var(--md-sys-color-surface-container-highest) r g b / 38%);
162
+ color: rgb(from var(--md-sys-color-surface-container-highest) r g b / var(--md-sys-state-disabled-state-layer-opacity, 38%));
163
163
  background-color: var(--md-sys-color-on-surface);
164
- opacity: 38%;
164
+ opacity: var(--md-sys-state-disabled-state-layer-opacity, 38%);
165
165
  }
166
166
  &:checked::after {
167
- color: rgb(from var(--md-sys-color-on-surface) r g b / 38%);
167
+ color: rgb(from var(--md-sys-color-on-surface) r g b / var(--md-sys-state-disabled-state-layer-opacity, 38%));
168
168
  background-color: var(--md-sys-color-surface);
169
169
  opacity: 100%;
170
170
  }
@@ -19,6 +19,7 @@
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';
22
23
  @use '../../styles/motion';
23
24
  @use '../../styles/shapes';
24
25
  @use '../../styles/statelayer';
@@ -80,8 +81,8 @@
80
81
  caret-color: var(--md-sys-color-primary);
81
82
 
82
83
  &:disabled {
83
- border-block-end-color: rgb(from var(--md-sys-color-on-surface) r g b / 38%);
84
- color: rgb(from var(--md-sys-color-on-surface) r g b / 38%);
84
+ border-block-end-color: rgb(from var(--md-sys-color-on-surface) r g b / var(--md-sys-state-disabled-state-layer-opacity, 38%));
85
+ color: rgb(from var(--md-sys-color-on-surface) r g b / var(--md-sys-state-disabled-state-layer-opacity, 38%));
85
86
  }
86
87
  &::placeholder {
87
88
  color: var(--md-sys-color-on-surface-variant);
@@ -220,12 +221,12 @@
220
221
  &:has(> select:disabled),
221
222
  &:has(> textarea:disabled) {
222
223
  &> label {
223
- color: rgb(from var(--md-sys-color-on-surface) r g b / 38%);
224
+ color: rgb(from var(--md-sys-color-on-surface) r g b / var(--md-sys-state-disabled-state-layer-opacity, 38%));
224
225
  }
225
226
  &> .micl-textfield__icon-leading,
226
227
  &> .micl-textfield__icon-trailing,
227
228
  &> .micl-textfield__supporting-text {
228
- color: rgb(from var(--md-sys-color-on-surface) r g b / 38%);
229
+ color: rgb(from var(--md-sys-color-on-surface) r g b / var(--md-sys-state-disabled-state-layer-opacity, 38%));
229
230
  }
230
231
  &> .micl-textfield__character-counter {
231
232
  display: none;
@@ -253,7 +254,7 @@
253
254
  &> input:not(:disabled),
254
255
  &> select:not(:disabled),
255
256
  &> textarea:not(:disabled) {
256
- --statelayer-opacity: var(--md-sys-state-hover-state-layer-opacity);
257
+ --statelayer-opacity: var(--md-sys-state-hover-state-layer-opacity, 8%);
257
258
 
258
259
  border-block-end-color: var(--md-sys-color-on-surface);
259
260
  }
@@ -44,6 +44,59 @@ export default (() =>
44
44
  }
45
45
  };
46
46
 
47
+ const formatAsDate = (input: HTMLInputElement, inputType: string): void =>
48
+ {
49
+ const partsRegex = /([DMY]{2,4})([^DMY])?([DMY]{2,4})([^DMY])?([DMY]{2,4})/;
50
+ const match = (input.dataset.micldateformat || '').match(partsRegex);
51
+ if (!match) {
52
+ return;
53
+ }
54
+
55
+ const components = [
56
+ { type: match[1], length: match[1].length, separator: match[2] || '' },
57
+ { type: match[3], length: match[3].length, separator: match[4] || '' },
58
+ { type: match[5], length: match[5].length, separator: '' }
59
+ ];
60
+
61
+ input.maxLength = components.reduce((sum, c) => sum + c.length + (c.separator ? 1 : 0), 0);
62
+
63
+ let value = input.value.replace(/\D/g, ''); // remove all non-digits
64
+ let formattedValue = '';
65
+ let valueIndex = 0;
66
+ let cursorPosition = input.selectionStart || 0;
67
+
68
+ for (let i = 0; i < components.length; i++) {
69
+ const comp = components[i];
70
+ if (value.length < valueIndex) break;
71
+
72
+ const segment = value.substring(valueIndex, valueIndex + comp.length);
73
+ formattedValue += segment;
74
+ valueIndex += segment.length;
75
+
76
+ if (segment.length === comp.length && comp.separator) {
77
+ formattedValue += comp.separator;
78
+ }
79
+ }
80
+
81
+ const prevLength = input.value.length;
82
+ input.value = formattedValue.substring(0, input.maxLength);
83
+ const newLength = input.value.length;
84
+
85
+ if (inputType.startsWith('deleteContent')) {
86
+ if (cursorPosition > 0) {
87
+ input.setSelectionRange(cursorPosition, cursorPosition);
88
+ }
89
+ }
90
+ else {
91
+ if (newLength > prevLength && newLength > cursorPosition) {
92
+ input.setSelectionRange(newLength, newLength);
93
+ }
94
+ else {
95
+ input.setSelectionRange(cursorPosition, cursorPosition);
96
+ }
97
+ }
98
+ };
99
+
47
100
  return {
48
101
  initialize: (input: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement): void =>
49
102
  {
@@ -70,14 +123,15 @@ export default (() =>
70
123
  });
71
124
  }
72
125
 
73
- if (input.matches('input[type=time][data-timepicker]')) {
74
- const timePicker = !input.dataset.timepicker ? null :
75
- document.getElementById(input.dataset.timepicker);
76
- if (timePicker instanceof HTMLDialogElement) {
126
+ if (input.matches('input[type=time][data-timepicker],input[type=date][data-datepicker]')) {
127
+ const picker = !input.dataset.timepicker ? (!input.dataset.datepicker ? null :
128
+ document.getElementById(input.dataset.datepicker)) :
129
+ document.getElementById(input.dataset.timepicker);
130
+ if (picker instanceof HTMLDialogElement) {
77
131
  input.addEventListener('click', (event: Event) =>
78
132
  {
79
133
  event.preventDefault();
80
- timePicker.showModal();
134
+ picker.showModal();
81
135
  });
82
136
  input.addEventListener('keydown', (event: Event) =>
83
137
  {
@@ -88,7 +142,7 @@ export default (() =>
88
142
  case 'Enter':
89
143
  case ' ':
90
144
  event.preventDefault();
91
- timePicker.showModal();
145
+ picker.showModal();
92
146
  break;
93
147
  default:
94
148
  }
@@ -109,6 +163,9 @@ export default (() =>
109
163
  return;
110
164
  }
111
165
 
166
+ if (event.target instanceof HTMLInputElement && event.target.dataset.micldateformat) {
167
+ formatAsDate(event.target, (event as InputEvent).inputType);
168
+ }
112
169
  if (event.target.value) {
113
170
  event.target.dataset.miclvalue = '1';
114
171
  }
@@ -27,7 +27,7 @@ The Time picker component is an extension of the [**Dialog** component](../dialo
27
27
  <button
28
28
  type="button"
29
29
  class="micl-timepicker__inputmode micl-iconbutton-standard-s material-symbols-outlined"
30
- data-alticon="schedule"
30
+ data-miclalt="schedule"
31
31
  aria-label="Switch input mode"
32
32
  >keyboard</button>
33
33
  <div>
@@ -83,7 +83,7 @@ By default, the layout is **vertical**. To switch to a **horizontal** layout (si
83
83
  To allow users to toggle between the text inputs and the analog dial, add a button to the `micl-dialog__actions` container:
84
84
 
85
85
  - Class: `micl-timepicker__inputmode`
86
- - Data Attribute: `data-alticon="schedule"` (defines the icon to show when toggled).
86
+ - Data Attribute: `data-miclalt="schedule"` (defines the icon to show when toggled).
87
87
 
88
88
  ### Integration
89
89
  You can trigger the Time picker component from standard input fields or buttons.
@@ -95,19 +95,18 @@ To replace the browser's native time picker, add the `data-timepicker` attribute
95
95
  <input type="time" data-timepicker="mytimepicker" value="09:41">
96
96
  ```
97
97
 
98
- - **Behavior**: When the input is clicked, the picker opens with the input's current value.
99
- - **Reusability**: Multiple input fields can target the same Time picker component ID.
100
-
101
- You may use the same time picker component for different time-input fields. When the user engages with the input field, the time picker is opened showing the time specified in the `value`-attribute.
98
+ - **Behavior**: Clicking the input opens the picker initialized with the input's current value.
99
+ - **Reusability**: Multiple input fields can target the same Time picker component ID. The picker will automatically update to reflect the time of the specific input field engaged by the user.
102
100
 
103
101
  #### Connecting to a Button
104
- You can use a button to trigger the picker using the standard `popovertarget` attribute.
102
+ You can trigger the picker from a button using the standard `popovertarget` attribute.
105
103
 
106
104
  ```HTML
107
- <button type="button" class="micl-button-text-m" popovertarget="mytimepicker">09:41</button>
105
+ <button type="button" class="micl-button-text-m" popovertarget="mytimepicker" value="09:41">09:41</button>
108
106
  ```
109
107
 
110
- - **Behavior**: The Time picker treats the button's text content as the time value to read from and write to.
108
+ - **Behavior**: The Time picker reads from and writes to the button's value attribute.
109
+ - **Formatting**: The component automatically updates the button's text content with the selected time, formatted according to the user's locale.
111
110
 
112
111
  ## Customizations
113
112
  You can customize the appearance of the Time picker component by overriding its global CSS variables. These variables are declared on the `:root` pseudo-class and can be changed on any appropriate parent element to affect its child time pickers.
@@ -19,6 +19,7 @@
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';
22
23
  @use '../../styles/motion';
23
24
  @use '../../styles/shapes';
24
25
  @use '../../styles/statelayer';
@@ -158,13 +159,13 @@ dialog.micl-dialog.micl-timepicker {
158
159
  border: 2px solid var(--md-sys-color-primary);
159
160
  }
160
161
  &:hover {
161
- --statelayer-opacity: var(--md-sys-state-hover-state-layer-opacity);
162
+ --statelayer-opacity: var(--md-sys-state-hover-state-layer-opacity, 8%);
162
163
  }
163
164
  &:focus-visible {
164
- --statelayer-opacity: var(--md-sys-state-focus-state-layer-opacity);
165
+ --statelayer-opacity: var(--md-sys-state-focus-state-layer-opacity, 10%);
165
166
  }
166
167
  &:active {
167
- --statelayer-opacity: var(--md-sys-state-pressed-state-layer-opacity);
168
+ --statelayer-opacity: var(--md-sys-state-pressed-state-layer-opacity, 10%);
168
169
  }
169
170
  }
170
171
  input[name=hour] {
@@ -258,16 +259,16 @@ dialog.micl-dialog.micl-timepicker {
258
259
  }
259
260
  }
260
261
  &:hover {
261
- --statelayer-opacity: var(--md-sys-state-hover-state-layer-opacity);
262
+ --statelayer-opacity: var(--md-sys-state-hover-state-layer-opacity, 8%);
262
263
  }
263
264
  &:focus-visible {
264
- --statelayer-opacity: var(--md-sys-state-focus-state-layer-opacity);
265
+ --statelayer-opacity: var(--md-sys-state-focus-state-layer-opacity, 10%);
265
266
 
266
- outline: var(--md-sys-state-focus-indicator-thickness) solid var(--md-sys-color-secondary);
267
+ outline: var(--md-sys-state-focus-indicator-thickness, 3px) solid var(--md-sys-color-secondary);
267
268
  outline-offset: -2px;
268
269
  }
269
270
  &:active {
270
- --statelayer-opacity: var(--md-sys-state-pressed-state-layer-opacity);
271
+ --statelayer-opacity: var(--md-sys-state-pressed-state-layer-opacity, 10%);
271
272
  }
272
273
  }
273
274
  .micl-timepicker__am {
@@ -316,7 +317,7 @@ dialog.micl-dialog.micl-timepicker {
316
317
  touch-action: none;
317
318
 
318
319
  data.micl-timepicker__dial-inner {
319
- --micl-hour-radius: calc(var(--micl-dial-radius) - var(--md-sys-target-size) + 12px);
320
+ --micl-hour-radius: calc(var(--micl-dial-radius) - var(--md-sys-target-size, 48px) + 12px);
320
321
 
321
322
  z-index: 2;
322
323
  &::before {
@@ -21,7 +21,7 @@
21
21
 
22
22
  export const timepickerSelector = 'dialog.micl-dialog.micl-timepicker';
23
23
 
24
- type ValueElement = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;
24
+ type ValueElement = HTMLInputElement | HTMLButtonElement;
25
25
 
26
26
  interface TimeLimits {
27
27
  max: number,
@@ -49,11 +49,9 @@ export default (() =>
49
49
  return parent.querySelector(selector) as T | null;
50
50
  };
51
51
 
52
- const isValueElement = (element: Element): element is ValueElement =>
52
+ const isValueElement = (element: Element | null): element is ValueElement =>
53
53
  {
54
- return element instanceof HTMLInputElement ||
55
- element instanceof HTMLTextAreaElement ||
56
- element instanceof HTMLSelectElement;
54
+ return element instanceof HTMLInputElement || element instanceof HTMLButtonElement;
57
55
  };
58
56
 
59
57
  const isVisible = (element: Element | null): boolean =>
@@ -302,8 +300,8 @@ export default (() =>
302
300
  mode?.addEventListener('click', () =>
303
301
  {
304
302
  const icon = mode.textContent;
305
- mode.textContent = mode.dataset.alticon || icon;
306
- mode.dataset.alticon = icon;
303
+ mode.textContent = mode.dataset.miclalt || icon;
304
+ mode.dataset.miclalt = icon;
307
305
  dial?.classList.toggle('micl-hidden');
308
306
  inputs.forEach(input =>
309
307
  {
@@ -353,21 +351,21 @@ export default (() =>
353
351
  return;
354
352
  }
355
353
 
356
- let invoker = document.activeElement as HTMLInputElement | HTMLButtonElement | null;
354
+ let invoker = document.activeElement;
357
355
  if (
358
- !invoker
359
- || (!invoker.dataset.timepicker && !invoker.popoverTargetElement)
356
+ !isValueElement(invoker)
357
+ || (!invoker.dataset.timepicker && !invoker.popoverTargetElement && !(invoker as any).commandForElement)
360
358
  ) {
361
359
  invoker = document.querySelector(
362
- `[data-timepicker="${dialog.id}"],[popovertarget="${dialog.id}"]`
360
+ `[data-timepicker="${dialog.id}"],[popovertarget="${dialog.id}"],[commandfor="${dialog.id}"]`
363
361
  );
364
362
  }
365
- if (!invoker) {
363
+ if (!isValueElement(invoker)) {
366
364
  return;
367
365
  }
368
366
  (dialog as any)._miclInvoker = invoker;
369
367
 
370
- const time = (isValueElement(invoker) ? invoker.value : invoker.textContent).split(':');
368
+ const time = (invoker.value || invoker.textContent).split(':');
371
369
  if (time.length === 2) {
372
370
  setInputValue(dialog, 'hour', time[0], true);
373
371
  setInputValue(dialog, 'minute', time[1], false, false);
@@ -383,10 +381,10 @@ export default (() =>
383
381
  let invoker = (dialog as any)._miclInvoker;
384
382
  if (!invoker) {
385
383
  invoker = document.querySelector(
386
- `[data-timepicker="${dialog.id}"],[popovertarget="${dialog.id}"]`
384
+ `[data-timepicker="${dialog.id}"],[popovertarget="${dialog.id}"],[commandfor="${dialog.id}"]`
387
385
  );
388
386
  }
389
- if (!invoker) {
387
+ if (!isValueElement(invoker)) {
390
388
  return;
391
389
  }
392
390
 
@@ -403,9 +401,11 @@ export default (() =>
403
401
  return;
404
402
  }
405
403
  const time = `${h}`.padStart(2, '0') + ':' + `${m}`.padStart(2, '0');
404
+ invoker.value = time;
406
405
 
407
- if (isValueElement(invoker)) {
408
- invoker.value = time;
406
+ if (invoker instanceof HTMLInputElement) {
407
+ invoker.dispatchEvent(new Event('change', { bubbles: true }));
408
+ invoker.dispatchEvent(new Event('input', { bubbles: true }));
409
409
  }
410
410
  else {
411
411
  invoker.textContent = time;