@expressivecss/expressive 0.7.0 → 0.8.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 (105) hide show
  1. package/CHANGELOG.md +1266 -1
  2. package/README.md +14 -11
  3. package/dist/css/expressive.css +4215 -1668
  4. package/dist/css/expressive.css.map +1 -1
  5. package/dist/css/expressive.min.css +1 -1
  6. package/dist/css/expressive.min.css.map +1 -1
  7. package/dist/js/expressive.cjs +1231 -1253
  8. package/dist/js/expressive.cjs.map +4 -4
  9. package/dist/js/expressive.js +1231 -1253
  10. package/dist/js/expressive.js.map +4 -4
  11. package/dist/js/expressive.min.js +12 -12
  12. package/dist/js/expressive.min.js.map +4 -4
  13. package/dist/js/expressive.mjs +1231 -1253
  14. package/dist/js/expressive.mjs.map +4 -4
  15. package/dist/types/behaviors/bottomSheets.d.ts +19 -11
  16. package/dist/types/behaviors/sheetDrag.d.ts +40 -0
  17. package/dist/types/behaviors/sideSheets.d.ts +2 -9
  18. package/dist/types/components/autocomplete.d.ts +15 -3
  19. package/dist/types/components/buttons.d.ts +5 -1
  20. package/dist/types/components/carousel.d.ts +87 -53
  21. package/dist/types/components/chips.d.ts +21 -1
  22. package/dist/types/components/expandingCard.d.ts +31 -0
  23. package/dist/types/components/index.d.ts +21 -20
  24. package/dist/types/components/lightbox.d.ts +1 -0
  25. package/dist/types/components/menu.d.ts +7 -1
  26. package/dist/types/components/{sidenav.d.ts → navigationDrawer.d.ts} +16 -16
  27. package/dist/types/components/registry.d.ts +8 -8
  28. package/dist/types/components/slider.d.ts +26 -85
  29. package/dist/types/components/snackbar.d.ts +20 -5
  30. package/dist/types/components/tabs.d.ts +12 -0
  31. package/dist/types/components/timepicker.d.ts +12 -9
  32. package/dist/types/core/utils.d.ts +64 -53
  33. package/dist/types/index.d.ts +8 -9
  34. package/package.json +15 -1
  35. package/src/sass/README.md +61 -11
  36. package/src/sass/abstracts/_breakpoints.scss +17 -19
  37. package/src/sass/abstracts/_mixins.scss +103 -21
  38. package/src/sass/abstracts/_variables.scss +50 -5
  39. package/src/sass/base/_global.scss +6 -24
  40. package/src/sass/base/_grid.scss +15 -12
  41. package/src/sass/base/_normalize.scss +34 -38
  42. package/src/sass/base/_typography.scss +4 -18
  43. package/src/sass/components/_badges.scss +2 -3
  44. package/src/sass/components/_banners.scss +298 -0
  45. package/src/sass/components/_bottom-app-bar.scss +180 -0
  46. package/src/sass/components/_bottom-sheet.scss +12 -4
  47. package/src/sass/components/_button-groups.scss +186 -0
  48. package/src/sass/components/_buttons.scss +245 -92
  49. package/src/sass/components/_cards.scss +494 -73
  50. package/src/sass/components/_carousel.scss +562 -68
  51. package/src/sass/components/_chips.scss +64 -5
  52. package/src/sass/components/_datepicker.scss +24 -24
  53. package/src/sass/components/_dialog.scss +17 -11
  54. package/src/sass/components/_drag-handle.scss +130 -0
  55. package/src/sass/components/_expanding-card.scss +260 -0
  56. package/src/sass/components/_fab-menu.scss +232 -0
  57. package/src/sass/components/_floating-sheet.scss +86 -0
  58. package/src/sass/components/_icon-buttons.scss +194 -0
  59. package/src/sass/components/_icons-material-design.scss +16 -4
  60. package/src/sass/components/_index.scss +22 -6
  61. package/src/sass/components/_list.scss +16 -13
  62. package/src/sass/components/_loading-indicator.scss +106 -0
  63. package/src/sass/components/_menu.scss +335 -61
  64. package/src/sass/components/_navbar.scss +71 -24
  65. package/src/sass/components/_navigation-bar.scss +13 -10
  66. package/src/sass/components/{_sidenav.scss → _navigation-drawer.scss} +123 -33
  67. package/src/sass/components/_navigation-rail.scss +22 -22
  68. package/src/sass/components/_page-footer.scss +19 -16
  69. package/src/sass/components/_pagination.scss +24 -6
  70. package/src/sass/components/_panes.scss +52 -11
  71. package/src/sass/components/{_preloader.scss → _progress.scss} +11 -3
  72. package/src/sass/components/_scrim.scss +37 -0
  73. package/src/sass/components/_search.scss +259 -0
  74. package/src/sass/components/_segmented-buttons.scss +188 -0
  75. package/src/sass/components/_side-sheet.scss +2 -2
  76. package/src/sass/components/_snackbar.scss +20 -15
  77. package/src/sass/components/_split-button.scss +196 -0
  78. package/src/sass/components/_tabs.scss +7 -8
  79. package/src/sass/components/_timepicker.scss +67 -58
  80. package/src/sass/components/_toolbar.scss +206 -80
  81. package/src/sass/components/forms/_checkboxes.scss +49 -12
  82. package/src/sass/components/forms/_fieldset.scss +4 -4
  83. package/src/sass/components/forms/_file-input.scss +8 -1
  84. package/src/sass/components/forms/_index.scss +1 -1
  85. package/src/sass/components/forms/_input-fields.scss +50 -44
  86. package/src/sass/components/forms/_radio-buttons.scss +42 -10
  87. package/src/sass/components/forms/_select.scss +0 -1
  88. package/src/sass/components/forms/{_range.scss → _slider.scss} +8 -9
  89. package/src/sass/components/forms/_switches.scss +6 -7
  90. package/src/sass/tokens/_index.scss +4 -1
  91. package/src/sass/tokens/_reference.scss +70 -61
  92. package/src/sass/tokens/_state.scss +24 -0
  93. package/src/sass/tokens/_theme.scss +6 -3
  94. package/src/sass/tokens/_vibrant.scss +76 -0
  95. package/src/sass/utilities/_colors.scss +14 -1
  96. package/src/sass/utilities/_helpers.scss +5 -5
  97. package/src/sass/utilities/_visibility.scss +48 -26
  98. package/dist/types/behaviors/waves.d.ts +0 -15
  99. package/dist/types/components/parallax.d.ts +0 -16
  100. package/dist/types/components/range.d.ts +0 -43
  101. package/dist/types/core/bounding.d.ts +0 -6
  102. package/dist/types/core/edges.d.ts +0 -6
  103. package/src/sass/components/_parallax.scss +0 -104
  104. package/src/sass/components/_pulse.scss +0 -37
  105. package/src/sass/components/_slider.scss +0 -129
@@ -0,0 +1,196 @@
1
+ @use "sass:map";
2
+ @use "../abstracts" as *;
3
+
4
+ // Split buttons.
5
+ //
6
+ // Anatomy is the HTML. A <div class="split-button"> holding two buttons: a
7
+ // leading one that performs the action, and a trailing `.menu-trigger` that
8
+ // opens a <menu> of related ones. They sit 2dp apart, the outside of the pair
9
+ // is round, and the seam between them is square-ish until something happens
10
+ // to it.
11
+ //
12
+ // Both halves are ordinary buttons, so every style class works on them and
13
+ // nothing here restates a colour. What this partial owns is the pair: the
14
+ // seam, the two insets that differ from a lone button's, and the larger
15
+ // trailing icon.
16
+ //
17
+ // No composite role is declared. The two halves are two Tab stops doing two
18
+ // different things - `toolbar` and its nine siblings promise an arrow-key
19
+ // model this is not (SEMANTICS rule 2). The menu the trailing half opens has
20
+ // its own keyboard contract, which Menu implements and owns.
21
+ //
22
+ // `aria-expanded` on the trailing half is Menu's to write, not the author's
23
+ // (SEMANTICS rule 1) - which is exactly why the expanded shape can be drawn
24
+ // from a selector with no script of this component's own.
25
+ //
26
+ // Tokens are md.comp.split-button.{xsmall … xlarge} (DSP 34.0.21). Five
27
+ // families collapse to one here the way the button's own ladder does: the
28
+ // size class rewrites the tokens and the two halves map them onto the button
29
+ // tokens once, below.
30
+ //
31
+ // size height lead-start lead-end trail-space trail-icon inner swollen
32
+ // xsmall 32 12 10 13 22 4 8
33
+ // small 40 16 12 13 22 4 12
34
+ // medium 56 24 24 15 26 4 12
35
+ // large 96 48 48 29 38 8 20
36
+ // xlarge 136 64 64 43 50 12 20
37
+ //
38
+ // `lead-start` is the button ladder's own `space` at every size, so it is not
39
+ // restated - `button-size()` sets it and the leading half keeps it. Only the
40
+ // inset facing the seam is the split button's, and only at the two smallest
41
+ // sizes does it actually differ. `between-space` is 2dp in all five families,
42
+ // so it is written once for the same reason.
43
+
44
+ // The two halves. The trailing one *is* the menu trigger: `.menu-trigger`
45
+ // with a target is the JS contract Menu claims, and a split button whose
46
+ // trailing half opened nothing would be a lone button with a decoration
47
+ // glued to it. semantics.json enforces that.
48
+ //
49
+ // `:where()`, not `:is()`: `:is()` takes the specificity of its heaviest
50
+ // argument, so `a.button` would make `> $_half:hover` a class heavier than
51
+ // `> $_trail[aria-expanded]` - and hovering an open split button would
52
+ // collapse the seam Material says stays round for as long as the menu is up.
53
+ //
54
+ // `.icon-button` is deliberately not a half. It is its own component with its
55
+ // own size ladder, insets, colours and icon sizing, all set on the element by
56
+ // its own rule - so the container could not size it by handing it tokens, and
57
+ // the seam here would fight the shape it already draws. Button groups refuse
58
+ // it for the same reason. The trailing half is a `.button.menu-trigger`.
59
+ $_lead: ":where(button:not(.icon-button), a.button):not(.menu-trigger)";
60
+ $_trail: ".menu-trigger:not(.icon-button)";
61
+ $_half: ":where(button:not(.icon-button), a.button)";
62
+
63
+ // md.comp.split-button.<size>.{leading-button.trailing-space,
64
+ // trailing-button.leading-space, trailing.icon-size, inner-corner,
65
+ // inner-pressed-corner}. The hovered and pressed inner corners are the same
66
+ // value in all five families, so one token carries both states.
67
+ $_sizes: (
68
+ "xsmall": (lead-end: 10px, trail-space: 13px, trail-icon: 22px, inner: 4px, swollen: 8px),
69
+ "small": (lead-end: 12px, trail-space: 13px, trail-icon: 22px, inner: 4px, swollen: 12px),
70
+ "medium": (lead-end: 24px, trail-space: 15px, trail-icon: 26px, inner: 4px, swollen: 12px),
71
+ "large": (lead-end: 48px, trail-space: 29px, trail-icon: 38px, inner: 8px, swollen: 20px),
72
+ "xlarge": (lead-end: 64px, trail-space: 43px, trail-icon: 50px, inner: 12px, swollen: 20px),
73
+ );
74
+
75
+ // The two ladders are keyed alike and read together, so a size added to one
76
+ // and not the other would emit `--token: ;` - a dropped declaration with no
77
+ // error and no visible cause. Fail the build instead.
78
+ @if map.keys($_sizes) != map.keys($button-sizes) {
79
+ @error "$_sizes and $button-sizes must name the same five sizes; got " +
80
+ map.keys($_sizes) + " against " + map.keys($button-sizes) + ".";
81
+ }
82
+
83
+ @mixin _split-size($name) {
84
+ $s: map.get($_sizes, $name);
85
+
86
+ --md-comp-split-button-leading-button-trailing-space: #{map.get($s, lead-end)};
87
+ --md-comp-split-button-trailing-button-space: #{map.get($s, trail-space)};
88
+ --md-comp-split-button-trailing-icon-size: #{map.get($s, trail-icon)};
89
+ --md-comp-split-button-inner-corner-corner-size: #{map.get($s, inner)};
90
+ --md-comp-split-button-inner-pressed-corner-corner-size: #{map.get($s, swollen)};
91
+ }
92
+
93
+ .split-button {
94
+ --md-comp-split-button-between-space: 2px;
95
+ --md-comp-split-button-container-shape: 9999px;
96
+
97
+ @include button-size("small");
98
+ @include _split-size("small");
99
+
100
+ display: inline-flex;
101
+ align-items: center;
102
+ gap: var(--md-comp-split-button-between-space);
103
+
104
+ // The size axis. Height, icon size, the leading inset and the outline width
105
+ // are the button ladder's, so `button-size()` sets them on the container and
106
+ // both halves inherit; the five values that are the split button's own are
107
+ // beside it. The type role cannot travel that way - `btn` states a font-size
108
+ // of its own - so it is set on the halves.
109
+ @each $name, $s in $button-sizes {
110
+ &.#{$name} {
111
+ @include button-size($name);
112
+ @include _split-size($name);
113
+
114
+ > #{$_half} {
115
+ @include typescale(map.get($s, label));
116
+ }
117
+ }
118
+ }
119
+
120
+ // The seam goes through a variable so that hovering, pressing or opening
121
+ // changes one value rather than restating `border-radius`. A shorthand under
122
+ // `:hover` would take the round outer corners with it, which is the bug
123
+ // `_button-groups.scss` records.
124
+ > #{$_half} {
125
+ --_inner: var(--md-comp-split-button-inner-corner-corner-size);
126
+
127
+ // `btn` transitions background-color and box-shadow; restating the
128
+ // property list replaces it wholesale, so both have to be named again or
129
+ // an `.elevated` split button snaps its shadow where every other elevated
130
+ // button eases it.
131
+ transition: border-radius .2s ease-out, background-color .2s ease-out,
132
+ box-shadow .2s ease-out;
133
+
134
+ // M3 gives hovered and pressed the same swollen corner.
135
+ &:hover,
136
+ &:active {
137
+ --_inner: var(--md-comp-split-button-inner-pressed-corner-corner-size);
138
+ }
139
+ }
140
+
141
+ // Logical, so the outside of the pair is the outside of the pair in RTL too:
142
+ // the flex row reverses and start follows it.
143
+ > #{$_lead} {
144
+ --md-comp-filled-button-trailing-space: var(--md-comp-split-button-leading-button-trailing-space);
145
+
146
+ border-start-start-radius: var(--md-comp-split-button-container-shape);
147
+ border-end-start-radius: var(--md-comp-split-button-container-shape);
148
+ border-start-end-radius: var(--_inner);
149
+ border-end-end-radius: var(--_inner);
150
+ }
151
+
152
+ > #{$_trail} {
153
+ // Symmetric, and narrower than a lone button's - the trailing half is a
154
+ // glyph in a box, not a label. The width falls out of the two insets and
155
+ // the icon: 48dp at the two smallest sizes, square at the three largest.
156
+ --md-comp-filled-button-leading-space: var(--md-comp-split-button-trailing-button-space);
157
+ --md-comp-filled-button-trailing-space: var(--md-comp-split-button-trailing-button-space);
158
+ // `_buttons.scss` sizes a button's icon from this token, so rewriting it
159
+ // here is the whole of the override. M3 draws the trailing glyph larger
160
+ // than the button ladder's icon at every size (22 against 20, up to 50
161
+ // against 40).
162
+ --md-comp-filled-button-icon-size: var(--md-comp-split-button-trailing-icon-size);
163
+
164
+ border-start-end-radius: var(--md-comp-split-button-container-shape);
165
+ border-end-end-radius: var(--md-comp-split-button-container-shape);
166
+ border-start-start-radius: var(--_inner);
167
+ border-end-start-radius: var(--_inner);
168
+
169
+ // Activation. md.comp.split-button.<size>.trailing.inner-selected-corner
170
+ // is 50%, and Compose resolves a percentage corner against the shape's
171
+ // *smaller* dimension - 20dp on the 48x40 half at `small`, which is what
172
+ // `9999px` clamps to. The two agree at every size, and the outer corners
173
+ // are the same 50% written the same way. So the pair reads as two
174
+ // separated round buttons for as long as the menu is open. Menu writes the
175
+ // attribute; nothing here is scripted.
176
+ &[aria-expanded="true"] {
177
+ --_inner: var(--md-comp-split-button-container-shape);
178
+ }
179
+
180
+ > #{$icon} {
181
+ transition: transform .2s ease-out;
182
+ }
183
+
184
+ &[aria-expanded="true"] > #{$icon} {
185
+ transform: rotate(180deg);
186
+ }
187
+ }
188
+ }
189
+
190
+ // The corner morph and the spin are the only motion this component has.
191
+ @media (prefers-reduced-motion: reduce) {
192
+ .split-button > #{$_half},
193
+ .split-button > #{$_trail} > #{$icon} {
194
+ transition: none;
195
+ }
196
+ }
@@ -83,10 +83,9 @@ $_tab: "> a, > .tab > a";
83
83
  cursor: pointer;
84
84
  appearance: none;
85
85
  @include typescale("title-small");
86
- font-family: $font-stack;
87
86
  transition: color .2s ease, background-color .2s ease;
88
87
 
89
- > i {
88
+ > #{$icon} {
90
89
  flex: 0 0 auto;
91
90
  font-size: var(--md-comp-primary-tab-icon-size);
92
91
  width: var(--md-comp-primary-tab-icon-size);
@@ -97,13 +96,13 @@ $_tab: "> a, > .tab > a";
97
96
 
98
97
  &:hover {
99
98
  color: var(--md-sys-color-on-surface);
100
- background-color: color-mix(in oklab, var(--md-sys-color-on-surface) 8%, transparent);
99
+ background-color: color-mix(in oklab, var(--md-sys-color-on-surface) state-opacity("hover"), transparent);
101
100
  }
102
101
 
103
102
  &:focus-visible,
104
103
  &:focus {
105
104
  color: var(--md-sys-color-on-surface);
106
- background-color: color-mix(in oklab, var(--md-sys-color-on-surface) 10%, transparent);
105
+ background-color: color-mix(in oklab, var(--md-sys-color-on-surface) state-opacity("focus"), transparent);
107
106
  outline: none;
108
107
  }
109
108
 
@@ -113,12 +112,12 @@ $_tab: "> a, > .tab > a";
113
112
  }
114
113
 
115
114
  &.active:hover {
116
- background-color: color-mix(in oklab, var(--md-sys-color-primary) 8%, transparent);
115
+ background-color: color-mix(in oklab, var(--md-sys-color-primary) state-opacity("hover"), transparent);
117
116
  }
118
117
 
119
118
  &.active:focus-visible,
120
119
  &.active:focus {
121
- background-color: color-mix(in oklab, var(--md-sys-color-primary) 10%, transparent);
120
+ background-color: color-mix(in oklab, var(--md-sys-color-primary) state-opacity("focus"), transparent);
122
121
  }
123
122
 
124
123
  // Disabled — on the <a>. The wrapping `.tab.disabled` case is
@@ -135,7 +134,7 @@ $_tab: "> a, > .tab > a";
135
134
  // Stacked icon + label is 64dp (primary).
136
135
  &:not(.horizontal) {
137
136
  #{$_tab} {
138
- &:has(> i) {
137
+ &:has(> #{$icon}) {
139
138
  min-height: var(--md-comp-primary-tab-with-icon-container-height);
140
139
  padding-block: 8px;
141
140
  }
@@ -210,7 +209,7 @@ $_tab: "> a, > .tab > a";
210
209
  }
211
210
  }
212
211
 
213
- @include bp-down("large") {
212
+ @include bp-down("expanded") {
214
213
  .tabs {
215
214
  > :is(a, .tab) {
216
215
  flex: 1 1 0;
@@ -1,6 +1,6 @@
1
1
  @use "../abstracts" as *;
2
2
 
3
- .timepicker-container {
3
+ :is(.timepicker-container, .time-picker-container) {
4
4
  display: flex;
5
5
  flex-direction: column;
6
6
  max-width: 325px;
@@ -13,7 +13,7 @@
13
13
  }
14
14
 
15
15
  /* Clock Digital Display */
16
- .timepicker-digital-display {
16
+ :is(.timepicker-digital-display, .time-picker-digital-display) {
17
17
  width: auto;
18
18
  flex: 1 auto;
19
19
  // background-color: var(--md-sys-color-surface);
@@ -21,7 +21,7 @@
21
21
  font-weight: 300;
22
22
  }
23
23
 
24
- .timepicker-text-container {
24
+ :is(.timepicker-text-container, .time-picker-text-container) {
25
25
  display: flex;
26
26
  font-size: 4rem;
27
27
  text-align: left;
@@ -40,29 +40,29 @@
40
40
  }
41
41
  }
42
42
 
43
- .timepicker-display-column {
43
+ :is(.timepicker-display-column, .time-picker-display-column) {
44
44
  display: inline-flex;
45
45
  }
46
46
 
47
- .timepicker-display-digital-clock {
47
+ :is(.timepicker-display-digital-clock, .time-picker-display-digital-clock) {
48
48
  flex-grow: 1;
49
49
  display: inline-flex;
50
50
  }
51
51
 
52
- .timepicker-input-hours-wrapper,
53
- .timepicker-input-minutes-wrapper {
52
+ :is(.timepicker-input-hours-wrapper, .time-picker-input-hours-wrapper),
53
+ :is(.timepicker-input-minutes-wrapper, .time-picker-input-minutes-wrapper) {
54
54
  width: 6.9rem;
55
55
  height: 5.75rem;
56
56
  }
57
57
 
58
- .timepicker-input-hours,
59
- .timepicker-input-minutes,
60
- .timepicker-span-am-pm div {
58
+ :is(.timepicker-input-hours, .time-picker-input-hours),
59
+ :is(.timepicker-input-minutes, .time-picker-input-minutes),
60
+ :is(.timepicker-span-am-pm, .time-picker-span-am-pm) div {
61
61
  cursor: pointer;
62
62
  }
63
63
 
64
- input[type=text].timepicker-input-hours,
65
- input[type=text].timepicker-input-minutes {
64
+ input[type=text]:is(.timepicker-input-hours, .time-picker-input-hours),
65
+ input[type=text]:is(.timepicker-input-minutes, .time-picker-input-minutes) {
66
66
  height: 100%;
67
67
  padding: 1.33rem .8rem;
68
68
  border: 0;
@@ -75,7 +75,7 @@ input[type=text].timepicker-input-minutes {
75
75
  }
76
76
  }
77
77
 
78
- .timepicker-input-divider-wrapper {
78
+ :is(.timepicker-input-divider-wrapper, .time-picker-input-divider-wrapper) {
79
79
  width: 1.6rem;
80
80
  text-align: center;
81
81
  }
@@ -84,7 +84,7 @@ input[type=text].timepicker-input-minutes {
84
84
  color: var(--md-sys-color-on-background);
85
85
  }*/
86
86
 
87
- .timepicker-display-am-pm {
87
+ :is(.timepicker-display-am-pm, .time-picker-display-am-pm) {
88
88
  font-size: 1.3rem;
89
89
  /*position: absolute;
90
90
  top: 1rem;
@@ -92,17 +92,20 @@ input[type=text].timepicker-input-minutes {
92
92
  font-weight: 400;
93
93
  }
94
94
 
95
- .timepicker-span-am-pm {
95
+ :is(.timepicker-span-am-pm, .time-picker-span-am-pm) {
96
96
  height: 5.75rem;
97
97
  max-width: 3.5rem;
98
98
  }
99
99
 
100
- .timepicker-container .am-btn,
101
- .timepicker-container .pm-btn {
100
+ :is(.timepicker-container, .time-picker-container) .am-btn,
101
+ :is(.timepicker-container, .time-picker-container) .pm-btn {
102
102
  width: 3.6rem;
103
103
  height: 50%;
104
- padding-left: calc(var(--btn-padding) / 1.8);
105
- padding-right: calc(var(--btn-padding) / 1.8);
104
+ // --btn-padding is a Materialize variable that no longer exists, so this
105
+ // was invalid at computed-value time and the padding resolved to 0 - not
106
+ // to the base button's inline space, which the invalid declaration still
107
+ // beat in the cascade. Written as the 0 it has always rendered as.
108
+ padding-inline: 0;
106
109
  line-height: 2rem;
107
110
  vertical-align: middle;
108
111
  text-align: center;
@@ -110,25 +113,25 @@ input[type=text].timepicker-input-minutes {
110
113
  border: 1px solid var(--md-sys-color-outline);
111
114
  }
112
115
 
113
- .timepicker-container .am-btn {
116
+ :is(.timepicker-container, .time-picker-container) .am-btn {
114
117
  border-bottom-right-radius: 0;
115
118
  border-bottom-left-radius: 0;
116
119
  }
117
120
 
118
- .timepicker-container .pm-btn {
121
+ :is(.timepicker-container, .time-picker-container) .pm-btn {
119
122
  border-top: 0;
120
123
  border-top-left-radius: 0;
121
124
  border-top-right-radius: 0;
122
125
  }
123
126
 
124
127
  /* Analog Clock Display */
125
- .timepicker-analog-display {
128
+ :is(.timepicker-analog-display, .time-picker-analog-display) {
126
129
  flex: 2.5 auto;
127
130
  padding: .67rem;
128
131
  // background-color: var(--md-sys-color-surface);
129
132
  }
130
133
 
131
- .timepicker-plate {
134
+ :is(.timepicker-plate, .time-picker-plate) {
132
135
  background-color: var(--md-sys-color-surface-variant);
133
136
  border-radius: 50%;
134
137
  width: 260px;
@@ -137,10 +140,14 @@ input[type=text].timepicker-input-minutes {
137
140
  position: relative;
138
141
  margin: 0 1.6rem 1.6rem 1.6rem;
139
142
  user-select: none;
143
+ // Dragging the clock hand is a two-dimensional gesture, so no axis is left
144
+ // to the page. See the note on the snackbar: under Pointer Events this is
145
+ // what reserves the gesture, not `preventDefault()`.
146
+ touch-action: none;
140
147
  }
141
148
 
142
- .timepicker-canvas,
143
- .timepicker-dial {
149
+ :is(.timepicker-canvas, .time-picker-canvas),
150
+ :is(.timepicker-dial, .time-picker-dial) {
144
151
  position: absolute;
145
152
  left: 0;
146
153
  right: 0;
@@ -148,11 +155,11 @@ input[type=text].timepicker-input-minutes {
148
155
  bottom: 0;
149
156
  }
150
157
 
151
- .timepicker-minutes {
158
+ :is(.timepicker-minutes, .time-picker-minutes) {
152
159
  visibility: hidden;
153
160
  }
154
161
 
155
- .timepicker-tick {
162
+ :is(.timepicker-tick, .time-picker-tick) {
156
163
  border-radius: 50%;
157
164
  color: var(--md-sys-color-on-background);
158
165
  line-height: 40px;
@@ -164,28 +171,28 @@ input[type=text].timepicker-input-minutes {
164
171
  font-size: 15px;
165
172
  }
166
173
 
167
- .timepicker-tick.active,
168
- .timepicker-tick:hover {
174
+ :is(.timepicker-tick, .time-picker-tick).active,
175
+ :is(.timepicker-tick, .time-picker-tick):hover {
169
176
  background-color: color-mix(in oklab, var(--md-sys-color-primary) 6%, transparent);
170
177
  }
171
178
 
172
- .timepicker-dial {
179
+ :is(.timepicker-dial, .time-picker-dial) {
173
180
  transition: transform 350ms, opacity 350ms;
174
181
  }
175
182
 
176
- .timepicker-dial-out {
183
+ :is(.timepicker-dial-out, .time-picker-dial-out) {
177
184
  opacity: 0;
178
185
 
179
- &.timepicker-hours {
186
+ &:is(.timepicker-hours, .time-picker-hours) {
180
187
  transform: scale(1.1, 1.1);
181
188
  }
182
189
 
183
- &.timepicker-minutes {
190
+ &:is(.timepicker-minutes, .time-picker-minutes) {
184
191
  transform: scale(.8, .8);
185
192
  }
186
193
  }
187
194
 
188
- .timepicker-canvas {
195
+ :is(.timepicker-canvas, .time-picker-canvas) {
189
196
  transition: opacity 175ms;
190
197
 
191
198
  line {
@@ -195,100 +202,102 @@ input[type=text].timepicker-input-minutes {
195
202
  }
196
203
  }
197
204
 
198
- .timepicker-canvas-out {
205
+ :is(.timepicker-canvas-out, .time-picker-canvas-out) {
199
206
  opacity: 0.25;
200
207
  }
201
208
 
202
- .timepicker-canvas-bearing {
209
+ :is(.timepicker-canvas-bearing, .time-picker-canvas-bearing) {
203
210
  stroke: none;
204
211
  fill: var(--md-sys-color-primary);
205
212
  }
206
213
 
207
- .timepicker-canvas-bg {
214
+ :is(.timepicker-canvas-bg, .time-picker-canvas-bg) {
208
215
  stroke: none;
209
216
  fill: var(--md-sys-color-primary);
210
217
  }
211
218
 
212
219
 
213
220
  /* Footer */
214
- .timepicker-footer {
221
+ :is(.timepicker-footer, .time-picker-footer) {
215
222
  margin: 0 auto;
216
223
  padding: 5px 1rem;
217
224
  display: flex;
218
225
  justify-content: space-between;
219
226
  }
220
227
 
221
- .timepicker-clear {
228
+ :is(.timepicker-clear, .time-picker-clear) {
222
229
  color: var(--md-sys-color-error);
223
230
  }
224
231
 
225
- .timepicker-close {
232
+ :is(.timepicker-close, .time-picker-close) {
226
233
  color: var(--md-sys-color-primary);
227
234
  }
228
235
 
229
- .timepicker-clear,
230
- .timepicker-close {
236
+ :is(.timepicker-clear, .time-picker-clear),
237
+ :is(.timepicker-close, .time-picker-close) {
231
238
  padding: 0 20px;
232
239
  }
233
240
 
234
241
  /* Media Queries */
235
- @include bp-up("large") {
236
- .timepicker-container {
242
+ @include bp-up("expanded") {
243
+ :is(.timepicker-container, .time-picker-container) {
237
244
  width: auto;
238
245
  max-width: 620px;
239
246
  }
240
247
 
241
- .timepicker-container {
248
+ :is(.timepicker-container, .time-picker-container) {
242
249
  flex-direction: row;
243
250
  }
244
251
 
245
- .timepicker-digital-display {
252
+ :is(.timepicker-digital-display, .time-picker-digital-display) {
246
253
  padding: .67rem;
247
254
  }
248
255
 
249
- .timepicker-text-container {
256
+ :is(.timepicker-text-container, .time-picker-text-container) {
250
257
  /*top: 31%;*/
251
258
  flex-direction: column;
252
259
  margin-top: 4.8rem;
253
260
  text-align: center;
254
261
  }
255
262
 
256
- .timepicker-display-column {
263
+ :is(.timepicker-display-column, .time-picker-display-column) {
257
264
  padding: 0 3%;
258
265
  }
259
266
 
260
- .timepicker-display-am-pm {
267
+ :is(.timepicker-display-am-pm, .time-picker-display-am-pm) {
261
268
  margin-top: 1.1rem;
262
269
  }
263
270
 
264
- .timepicker-span-am-pm {
271
+ :is(.timepicker-span-am-pm, .time-picker-span-am-pm) {
265
272
  display: flex;
266
273
  flex-grow: 1;
267
274
  max-width: unset;
268
275
  }
269
276
 
270
- .timepicker-container .am-btn,
271
- .timepicker-container .pm-btn {
277
+ :is(.timepicker-container, .time-picker-container) .am-btn,
278
+ :is(.timepicker-container, .time-picker-container) .pm-btn {
272
279
  flex-grow: 1;
273
280
  /*width: auto;*/
274
- padding-left: calc(var(--btn-padding) / .565);
275
- padding-right: calc(var(--btn-padding) / .565);
276
- border-radius: var(--btn-border-radius);
281
+ // Same two dead Materialize variables as above; both declarations
282
+ // rendered as 0. The corner rules that follow square off the inner
283
+ // edges, so the outer ones are the only radius in play.
284
+ padding-inline: 0;
285
+ border-radius: 0;
277
286
  border: 1px solid var(--md-sys-color-outline);
278
287
  }
279
288
 
280
- .timepicker-container .am-btn {
289
+ :is(.timepicker-container, .time-picker-container) .am-btn {
281
290
  border-top-right-radius: 0;
282
291
  border-bottom-right-radius: 0;
283
292
  }
284
293
 
285
- .timepicker-container .pm-btn {
294
+ :is(.timepicker-container, .time-picker-container) .pm-btn {
286
295
  border-left: 0;
287
296
  border-bottom-left-radius: 0;
288
297
  border-top-left-radius: 0;
289
298
  }
290
299
 
291
- .timepicker-plate {
300
+ :is(.timepicker-plate, .time-picker-plate) {
292
301
  margin-top: 1.6rem;
293
302
  }
294
303
  }