@expressivecss/expressive 0.9.0 → 0.10.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 (188) hide show
  1. package/CHANGELOG.md +174 -1
  2. package/README.md +178 -25
  3. package/dist/css/expressive.css +365 -1222
  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/fonts/material-symbols-outlined.woff2 +0 -0
  8. package/dist/fonts/material-symbols-rounded.woff2 +0 -0
  9. package/dist/fonts/material-symbols-sharp.woff2 +0 -0
  10. package/dist/js/chunks/chunk-7MM4VJJO.mjs +509 -0
  11. package/dist/js/chunks/chunk-7MM4VJJO.mjs.map +7 -0
  12. package/dist/js/chunks/chunk-7UXHSYIA.mjs +183 -0
  13. package/dist/js/chunks/chunk-7UXHSYIA.mjs.map +7 -0
  14. package/dist/js/chunks/chunk-A3BJA7V4.mjs +28 -0
  15. package/dist/js/chunks/chunk-A3BJA7V4.mjs.map +7 -0
  16. package/dist/js/chunks/chunk-AOGFNMXS.mjs +691 -0
  17. package/dist/js/chunks/chunk-AOGFNMXS.mjs.map +7 -0
  18. package/dist/js/chunks/chunk-D4UZ4HFN.mjs +560 -0
  19. package/dist/js/chunks/chunk-D4UZ4HFN.mjs.map +7 -0
  20. package/dist/js/chunks/chunk-EP3CVKB5.mjs +88 -0
  21. package/dist/js/chunks/chunk-EP3CVKB5.mjs.map +7 -0
  22. package/dist/js/chunks/chunk-G576EP5O.mjs +459 -0
  23. package/dist/js/chunks/chunk-G576EP5O.mjs.map +7 -0
  24. package/dist/js/chunks/chunk-GY2Z5CJ2.mjs +320 -0
  25. package/dist/js/chunks/chunk-GY2Z5CJ2.mjs.map +7 -0
  26. package/dist/js/chunks/chunk-JKNPQQWY.mjs +191 -0
  27. package/dist/js/chunks/chunk-JKNPQQWY.mjs.map +7 -0
  28. package/dist/js/chunks/chunk-JNPIWFJT.mjs +365 -0
  29. package/dist/js/chunks/chunk-JNPIWFJT.mjs.map +7 -0
  30. package/dist/js/chunks/chunk-JODJAGFS.mjs +267 -0
  31. package/dist/js/chunks/chunk-JODJAGFS.mjs.map +7 -0
  32. package/dist/js/chunks/chunk-JR24UB4X.mjs +100 -0
  33. package/dist/js/chunks/chunk-JR24UB4X.mjs.map +7 -0
  34. package/dist/js/chunks/chunk-KR44BSYQ.mjs +55 -0
  35. package/dist/js/chunks/chunk-KR44BSYQ.mjs.map +7 -0
  36. package/dist/js/chunks/chunk-LZVBJ33S.mjs +102 -0
  37. package/dist/js/chunks/chunk-LZVBJ33S.mjs.map +7 -0
  38. package/dist/js/chunks/chunk-MISGHDUU.mjs +326 -0
  39. package/dist/js/chunks/chunk-MISGHDUU.mjs.map +7 -0
  40. package/dist/js/chunks/chunk-N3UHGN3N.mjs +175 -0
  41. package/dist/js/chunks/chunk-N3UHGN3N.mjs.map +7 -0
  42. package/dist/js/chunks/chunk-PB5L3EXF.mjs +7 -0
  43. package/dist/js/chunks/chunk-PB5L3EXF.mjs.map +7 -0
  44. package/dist/js/chunks/chunk-PIIAEYAJ.mjs +85 -0
  45. package/dist/js/chunks/chunk-PIIAEYAJ.mjs.map +7 -0
  46. package/dist/js/chunks/chunk-QSQ24FYT.mjs +59 -0
  47. package/dist/js/chunks/chunk-QSQ24FYT.mjs.map +7 -0
  48. package/dist/js/chunks/chunk-QYCYP443.mjs +1111 -0
  49. package/dist/js/chunks/chunk-QYCYP443.mjs.map +7 -0
  50. package/dist/js/chunks/chunk-SLFNPY5M.mjs +78 -0
  51. package/dist/js/chunks/chunk-SLFNPY5M.mjs.map +7 -0
  52. package/dist/js/chunks/chunk-TK6PX2GC.mjs +663 -0
  53. package/dist/js/chunks/chunk-TK6PX2GC.mjs.map +7 -0
  54. package/dist/js/chunks/chunk-TYM6U5DY.mjs +76 -0
  55. package/dist/js/chunks/chunk-TYM6U5DY.mjs.map +7 -0
  56. package/dist/js/chunks/chunk-TZZ24ZQS.mjs +154 -0
  57. package/dist/js/chunks/chunk-TZZ24ZQS.mjs.map +7 -0
  58. package/dist/js/chunks/chunk-VAS6JQ6P.mjs +94 -0
  59. package/dist/js/chunks/chunk-VAS6JQ6P.mjs.map +7 -0
  60. package/dist/js/chunks/chunk-WWPAPHMA.mjs +1 -0
  61. package/dist/js/chunks/chunk-WWPAPHMA.mjs.map +7 -0
  62. package/dist/js/chunks/chunk-XDB3G6RL.mjs +114 -0
  63. package/dist/js/chunks/chunk-XDB3G6RL.mjs.map +7 -0
  64. package/dist/js/chunks/chunk-XO5WX3TK.mjs +226 -0
  65. package/dist/js/chunks/chunk-XO5WX3TK.mjs.map +7 -0
  66. package/dist/js/chunks/chunk-YFXEJ7GR.mjs +286 -0
  67. package/dist/js/chunks/chunk-YFXEJ7GR.mjs.map +7 -0
  68. package/dist/js/chunks/chunk-ZIZVUWRL.mjs +120 -0
  69. package/dist/js/chunks/chunk-ZIZVUWRL.mjs.map +7 -0
  70. package/dist/js/chunks/chunk-ZZBZI2XN.mjs +338 -0
  71. package/dist/js/chunks/chunk-ZZBZI2XN.mjs.map +7 -0
  72. package/dist/js/expressive.cjs +801 -761
  73. package/dist/js/expressive.cjs.map +4 -4
  74. package/dist/js/expressive.js +801 -761
  75. package/dist/js/expressive.js.map +4 -4
  76. package/dist/js/expressive.min.js +11 -15
  77. package/dist/js/expressive.min.js.map +4 -4
  78. package/dist/js/expressive.mjs +83 -7443
  79. package/dist/js/expressive.mjs.map +4 -4
  80. package/dist/js/internal/behaviors/bottomSheets.mjs +9 -0
  81. package/dist/js/internal/behaviors/bottomSheets.mjs.map +7 -0
  82. package/dist/js/internal/behaviors/dialogs.mjs +8 -0
  83. package/dist/js/internal/behaviors/dialogs.mjs.map +7 -0
  84. package/dist/js/internal/behaviors/forms.mjs +8 -0
  85. package/dist/js/internal/behaviors/forms.mjs.map +7 -0
  86. package/dist/js/internal/behaviors/sheetDrag.mjs +8 -0
  87. package/dist/js/internal/behaviors/sheetDrag.mjs.map +7 -0
  88. package/dist/js/internal/behaviors/sideSheets.mjs +9 -0
  89. package/dist/js/internal/behaviors/sideSheets.mjs.map +7 -0
  90. package/dist/js/internal/components/appBar.mjs +8 -0
  91. package/dist/js/internal/components/appBar.mjs.map +7 -0
  92. package/dist/js/internal/components/autocomplete.mjs +10 -0
  93. package/dist/js/internal/components/autocomplete.mjs.map +7 -0
  94. package/dist/js/internal/components/buttonGroup.mjs +8 -0
  95. package/dist/js/internal/components/buttonGroup.mjs.map +7 -0
  96. package/dist/js/internal/components/buttons.mjs +9 -0
  97. package/dist/js/internal/components/buttons.mjs.map +7 -0
  98. package/dist/js/internal/components/cards.mjs +13 -0
  99. package/dist/js/internal/components/cards.mjs.map +7 -0
  100. package/dist/js/internal/components/carousel.mjs +9 -0
  101. package/dist/js/internal/components/carousel.mjs.map +7 -0
  102. package/dist/js/internal/components/characterCounter.mjs +8 -0
  103. package/dist/js/internal/components/characterCounter.mjs.map +7 -0
  104. package/dist/js/internal/components/chips.mjs +11 -0
  105. package/dist/js/internal/components/chips.mjs.map +7 -0
  106. package/dist/js/internal/components/datepicker.mjs +12 -0
  107. package/dist/js/internal/components/datepicker.mjs.map +7 -0
  108. package/dist/js/internal/components/expandingCard.mjs +11 -0
  109. package/dist/js/internal/components/expandingCard.mjs.map +7 -0
  110. package/dist/js/internal/components/index.mjs +88 -0
  111. package/dist/js/internal/components/index.mjs.map +7 -0
  112. package/dist/js/internal/components/lightbox.mjs +9 -0
  113. package/dist/js/internal/components/lightbox.mjs.map +7 -0
  114. package/dist/js/internal/components/menu.mjs +9 -0
  115. package/dist/js/internal/components/menu.mjs.map +7 -0
  116. package/dist/js/internal/components/navigationRail.mjs +8 -0
  117. package/dist/js/internal/components/navigationRail.mjs.map +7 -0
  118. package/dist/js/internal/components/registry.mjs +33 -0
  119. package/dist/js/internal/components/registry.mjs.map +7 -0
  120. package/dist/js/internal/components/scrollspy.mjs +8 -0
  121. package/dist/js/internal/components/scrollspy.mjs.map +7 -0
  122. package/dist/js/internal/components/select.mjs +10 -0
  123. package/dist/js/internal/components/select.mjs.map +7 -0
  124. package/dist/js/internal/components/slider.mjs +9 -0
  125. package/dist/js/internal/components/slider.mjs.map +7 -0
  126. package/dist/js/internal/components/snackbar.mjs +8 -0
  127. package/dist/js/internal/components/snackbar.mjs.map +7 -0
  128. package/dist/js/internal/components/tabs.mjs +10 -0
  129. package/dist/js/internal/components/tabs.mjs.map +7 -0
  130. package/dist/js/internal/components/timepicker.mjs +10 -0
  131. package/dist/js/internal/components/timepicker.mjs.map +7 -0
  132. package/dist/js/internal/components/tooltip.mjs +9 -0
  133. package/dist/js/internal/components/tooltip.mjs.map +7 -0
  134. package/dist/js/internal/core/component.mjs +7 -0
  135. package/dist/js/internal/core/component.mjs.map +7 -0
  136. package/dist/js/internal/core/utils.mjs +7 -0
  137. package/dist/js/internal/core/utils.mjs.map +7 -0
  138. package/dist/js/internal/plugins/dockedDisplayPlugin.mjs +8 -0
  139. package/dist/js/internal/plugins/dockedDisplayPlugin.mjs.map +7 -0
  140. package/dist/js/modular.mjs +113 -0
  141. package/dist/js/modular.mjs.map +7 -0
  142. package/dist/types/behaviors/sheetDrag.d.ts +1 -1
  143. package/dist/types/components/appBar.d.ts +1 -1
  144. package/dist/types/components/autocomplete.d.ts +9 -0
  145. package/dist/types/components/buttons.d.ts +4 -39
  146. package/dist/types/components/carousel.d.ts +10 -1
  147. package/dist/types/components/chips.d.ts +1 -0
  148. package/dist/types/components/datepicker.d.ts +11 -0
  149. package/dist/types/components/index.d.ts +0 -2
  150. package/dist/types/components/lightbox.d.ts +12 -0
  151. package/dist/types/components/menu.d.ts +3 -0
  152. package/dist/types/components/registry.d.ts +0 -4
  153. package/dist/types/components/select.d.ts +4 -0
  154. package/dist/types/components/slider.d.ts +2 -1
  155. package/dist/types/components/snackbar.d.ts +4 -2
  156. package/dist/types/components/tabs.d.ts +2 -1
  157. package/dist/types/components/timepicker.d.ts +5 -3
  158. package/dist/types/components/tooltip.d.ts +5 -3
  159. package/dist/types/index.d.ts +1 -8
  160. package/dist/types/modular.d.ts +28 -0
  161. package/package.json +16 -4
  162. package/src/sass/README.md +8 -0
  163. package/src/sass/components/_badges.scss +1 -6
  164. package/src/sass/components/_button-groups.scss +5 -1
  165. package/src/sass/components/_buttons.scss +8 -287
  166. package/src/sass/components/_chips.scss +17 -2
  167. package/src/sass/components/_dialog.scss +9 -4
  168. package/src/sass/components/_fab-menu.scss +11 -9
  169. package/src/sass/components/_icon-buttons.scss +0 -5
  170. package/src/sass/components/_index.scss +0 -5
  171. package/src/sass/components/_menu.scss +2 -2
  172. package/src/sass/components/_navigation-rail.scss +1 -1
  173. package/src/sass/components/_panes.scss +50 -78
  174. package/src/sass/components/_progress.scss +73 -13
  175. package/src/sass/components/_scrim.scss +4 -4
  176. package/src/sass/components/_side-sheet.scss +22 -12
  177. package/src/sass/components/_toolbar.scss +1 -4
  178. package/src/sass/components/_tooltip.scss +20 -2
  179. package/src/sass/components/forms/_input-fields.scss +5 -1
  180. package/src/sass/components/forms/_select.scss +1 -0
  181. package/src/sass/components/forms/_slider.scss +81 -25
  182. package/src/sass/custom.scss +38 -0
  183. package/dist/types/components/navigationDrawer.d.ts +0 -110
  184. package/src/sass/components/_banners.scss +0 -298
  185. package/src/sass/components/_bottom-app-bar.scss +0 -180
  186. package/src/sass/components/_floating-sheet.scss +0 -86
  187. package/src/sass/components/_navigation-drawer.scss +0 -476
  188. package/src/sass/components/_segmented-buttons.scss +0 -188
@@ -1,476 +0,0 @@
1
- @use "../abstracts" as *;
2
-
3
- // Navigation drawer.
4
- //
5
- // Overlay is a modal <dialog> (JS wraps a <ul class="sidenav"> in
6
- // dialog:is(.sidenav-overlay, .navigation-drawer-overlay), or the author writes <dialog class="sidenav">).
7
- // showModal() puts it on the top layer; ::backdrop is the scrim; Escape
8
- // and a scrim tap close it. Drag writes --md-comp-nav-drawer-shift;
9
- // this file does the slide.
10
- //
11
- // Nested sections are native <details>/<summary>. Same `name` is an
12
- // accordion. The summary is a destination row with an expand_more
13
- // chevron; there is no Collapsible plugin.
14
- //
15
- // :is(.sidenav-fixed, .navigation-drawer-fixed) is a breakpoint, not a JS open(): at `large` the host
16
- // is display: contents so the list is a docked sidebar. Below that it
17
- // is the same overlay drawer as any other sidenav.
18
- //
19
- // Tokens:
20
- // --md-comp-nav-drawer-width 300px
21
- // --md-comp-nav-drawer-item-height 48px
22
- // --md-comp-nav-drawer-duration 250ms
23
- // --md-comp-nav-drawer-easing
24
- // --md-comp-nav-drawer-shift 0px (JS, px from fully open)
25
- // --md-comp-nav-drawer-open 1 (JS, 0–1 scrim opacity)
26
- // --md-comp-nav-drawer-font-size 14px
27
- // --md-comp-nav-drawer-padding 16px
28
- // --md-comp-nav-drawer-line-height item height
29
- // --md-comp-nav-drawer-user-view-shape
30
- // 16px, bottom corners of the header
31
- // --md-comp-nav-drawer-user-view-scrim
32
- // gradient laid over the header image
33
- // --md-comp-nav-drawer-user-view-ink-color
34
- // text colour over that scrim
35
-
36
- :root, :host {
37
- --md-comp-nav-drawer-width: 300px;
38
- }
39
-
40
- // A drawer row is whatever element the list item holds: a destination
41
- // <a>, the <summary> of a nested section, the <button> a command row is
42
- // written with (.navigation-drawer-close), and the plain element a
43
- // .subheader label is. Keyed on `li > a`, the row layout disappeared the
44
- // moment a row stopped being an anchor - the same trap $_icon documents.
45
- // $_row-control is the subset that is operable: it takes the hover and
46
- // focus treatment, a label does not. Both are wrapped in :is() - a bare
47
- // comma list breaks out of its context (see $_bar in _navbar).
48
- $_row: ":is(li > :is(a, button, .subheader), summary)";
49
- $_row-control: ":is(li > :is(a, button):not(.button, .icon-button, .circle, .extra), summary)";
50
-
51
-
52
- dialog:is(.sidenav-overlay, .navigation-drawer-overlay),
53
- dialog:is(.sidenav, .navigation-drawer) {
54
- --md-comp-nav-drawer-item-height: 48px;
55
- --md-comp-nav-drawer-duration: 250ms;
56
- --md-comp-nav-drawer-easing: ease;
57
- --md-comp-nav-drawer-shift: 0px;
58
- --md-comp-nav-drawer-open: 1;
59
- --md-comp-nav-drawer-font-size: 14px;
60
- --md-comp-nav-drawer-padding: 16px;
61
- --md-comp-nav-drawer-line-height: var(--md-comp-nav-drawer-item-height);
62
- --md-comp-nav-drawer-user-view-shape: 16px;
63
- --md-comp-nav-drawer-user-view-ink-color: var(--md-ref-palette-neutral100);
64
- --md-comp-nav-drawer-user-view-scrim: linear-gradient(
65
- to bottom,
66
- color-mix(in oklab, var(--md-sys-color-scrim) 15%, transparent) 0%,
67
- color-mix(in oklab, var(--md-sys-color-scrim) 50%, transparent) 55%,
68
- color-mix(in oklab, var(--md-sys-color-scrim) 80%, transparent) 100%
69
- );
70
-
71
- box-sizing: border-box;
72
- width: var(--md-comp-nav-drawer-width);
73
- min-width: 0;
74
- max-width: none;
75
- max-height: none;
76
- height: 100dvh;
77
- margin: 0;
78
- padding: 0;
79
- border: none;
80
- border-radius: 0;
81
- inset: 0 auto 0 0;
82
- overflow: hidden;
83
- color: var(--md-sys-color-on-surface);
84
- background-color: var(--md-sys-color-surface-container-low);
85
- outline: none;
86
- @include z-depth("1");
87
-
88
- transform: translateX(calc(-100% + var(--md-comp-nav-drawer-shift)));
89
- transition:
90
- transform var(--md-comp-nav-drawer-duration) var(--md-comp-nav-drawer-easing),
91
- display var(--md-comp-nav-drawer-duration) allow-discrete,
92
- overlay var(--md-comp-nav-drawer-duration) allow-discrete;
93
-
94
- &:modal {
95
- display: flex;
96
- flex-direction: column;
97
- transform: translateX(var(--md-comp-nav-drawer-shift));
98
- }
99
-
100
- &.right-aligned {
101
- inset: 0 0 0 auto;
102
- transform: translateX(calc(100% - var(--md-comp-nav-drawer-shift)));
103
-
104
- &:modal {
105
- transform: translateX(calc(-1 * var(--md-comp-nav-drawer-shift)));
106
- }
107
- }
108
-
109
- &.dragging {
110
- transition: none;
111
- }
112
-
113
- &::backdrop {
114
- background-color: var(--md-comp-scrim-color);
115
- opacity: var(--md-comp-nav-drawer-open, 1);
116
- backdrop-filter: none;
117
- transition:
118
- opacity var(--md-comp-nav-drawer-duration) var(--md-comp-nav-drawer-easing),
119
- display var(--md-comp-nav-drawer-duration) allow-discrete,
120
- overlay var(--md-comp-nav-drawer-duration) allow-discrete;
121
- }
122
- }
123
-
124
- @starting-style {
125
- :is(dialog:is(.sidenav-overlay, .navigation-drawer-overlay), dialog:is(.sidenav, .navigation-drawer)):modal {
126
- transform: translateX(-100%);
127
- }
128
-
129
- :is(dialog:is(.sidenav-overlay, .navigation-drawer-overlay), dialog:is(.sidenav, .navigation-drawer)).right-aligned:modal {
130
- transform: translateX(100%);
131
- }
132
-
133
- :is(dialog:is(.sidenav-overlay, .navigation-drawer-overlay), dialog:is(.sidenav, .navigation-drawer)):modal::backdrop {
134
- opacity: 0;
135
- }
136
- }
137
-
138
- @media (prefers-reduced-motion: reduce) {
139
- dialog:is(.sidenav-overlay, .navigation-drawer-overlay),
140
- dialog:is(.sidenav, .navigation-drawer) {
141
- transition: none;
142
-
143
- &::backdrop {
144
- transition: none;
145
- }
146
- }
147
- }
148
-
149
- // Docked sidebar: the host must not be a box, or it would steal the
150
- // list's position:fixed. Closed, so it is not :modal and does not
151
- // lock the page.
152
- @include bp-up("expanded") {
153
- dialog:is(.sidenav-overlay, .navigation-drawer-overlay):has(> :is(.sidenav-fixed, .navigation-drawer-fixed)):not(:modal) {
154
- display: contents;
155
- }
156
- }
157
-
158
- :is(.sidenav, .navigation-drawer) {
159
- --md-comp-nav-drawer-item-height: 48px;
160
- --md-comp-nav-drawer-font-size: 14px;
161
- --md-comp-nav-drawer-padding: 16px;
162
- --md-comp-nav-drawer-line-height: var(--md-comp-nav-drawer-item-height);
163
- --md-comp-nav-drawer-user-view-shape: 16px;
164
- --md-comp-nav-drawer-user-view-ink-color: var(--md-ref-palette-neutral100);
165
- --md-comp-nav-drawer-user-view-scrim: linear-gradient(
166
- to bottom,
167
- color-mix(in oklab, var(--md-sys-color-scrim) 15%, transparent) 0%,
168
- color-mix(in oklab, var(--md-sys-color-scrim) 50%, transparent) 55%,
169
- color-mix(in oklab, var(--md-sys-color-scrim) 80%, transparent) 100%
170
- );
171
-
172
- box-sizing: border-box;
173
- position: fixed;
174
- width: var(--md-comp-nav-drawer-width);
175
- inset: 0 auto 0 0;
176
- margin: 0;
177
- padding: 0;
178
- height: 100dvh;
179
- z-index: 999;
180
- overflow-y: auto;
181
- overscroll-behavior: contain;
182
- user-select: none;
183
- color: var(--md-sys-color-on-surface);
184
- background-color: var(--md-sys-color-surface-container-low);
185
- transform: translateX(-100%);
186
- @include z-depth("1");
187
-
188
- &.right-aligned {
189
- inset: 0 0 0 auto;
190
- transform: translateX(100%);
191
- }
192
-
193
- li {
194
- list-style: none;
195
- display: grid;
196
- align-content: center;
197
- }
198
-
199
- // The selected destination keeps its pill under the pointer: the row's own
200
- // state layer mixes into `transparent`, so letting it reach a selected row
201
- // would erase the fill rather than tint it. Higher specificity than the row
202
- // rule, so order does not matter.
203
- li.active > :is(a, button):not(.button, .icon-button, .circle, .extra) {
204
- background-color: var(--md-sys-color-secondary-container);
205
- color: var(--md-sys-color-on-secondary-container);
206
-
207
- &:hover {
208
- background-color: color-mix(
209
- in oklab,
210
- var(--md-sys-color-on-secondary-container) state-opacity("hover"),
211
- var(--md-sys-color-secondary-container)
212
- );
213
- }
214
-
215
- &:active {
216
- background-color: color-mix(
217
- in oklab,
218
- var(--md-sys-color-on-secondary-container) state-opacity("pressed"),
219
- var(--md-sys-color-secondary-container)
220
- );
221
- }
222
- }
223
-
224
- #{$_row} {
225
- display: flex;
226
- align-items: center;
227
- margin: 0 12px;
228
- padding: 0 var(--md-comp-nav-drawer-padding);
229
- height: var(--md-comp-nav-drawer-item-height);
230
- overflow: hidden;
231
- border-radius: 100px;
232
- font-size: var(--md-comp-nav-drawer-font-size);
233
- font-weight: 500;
234
-
235
- > :is(
236
- .material-symbols,
237
- .material-symbols-outlined,
238
- .material-symbols-rounded,
239
- .material-symbols-sharp,
240
- .material-icons
241
- ) {
242
- display: inline-flex;
243
- flex-shrink: 0;
244
- margin-right: 12px;
245
- }
246
- }
247
-
248
- #{$_row-control} {
249
- color: var(--md-sys-color-on-surface-variant);
250
-
251
- &:hover {
252
- background-color: color-mix(in oklab, var(--md-sys-color-on-surface) state-opacity("hover"), transparent);
253
- }
254
-
255
- &:active {
256
- background-color: color-mix(in oklab, var(--md-sys-color-on-surface) state-opacity("pressed"), transparent);
257
- }
258
-
259
- @include focus-visible;
260
- }
261
-
262
- li > :is(a, button):is(.button, .circle, .extra) {
263
- margin: 10px 15px;
264
- }
265
-
266
- // Every <button> is a styled button ($_btn in _buttons is `button:not(...)`),
267
- // so a command row has to be stripped back to a row the same way <summary>
268
- // is. The chevron below stays summary-only.
269
- :is(summary, li > button:not(.button, .icon-button, .circle, .extra)) {
270
- box-sizing: border-box;
271
- // A <button> centres its own content, so a command row's label sat in the
272
- // middle of the row while every anchor row started at the inset.
273
- justify-content: flex-start;
274
- border: 0;
275
- background: transparent;
276
- font: inherit;
277
- text-align: start;
278
- list-style: none;
279
- cursor: pointer;
280
- appearance: none;
281
- }
282
-
283
- summary {
284
- &::-webkit-details-marker {
285
- display: none;
286
- }
287
-
288
- &::marker {
289
- content: none;
290
- }
291
-
292
- &::after {
293
- content: "expand_more";
294
- flex-shrink: 0;
295
- margin-inline-start: auto;
296
- font-family: var(--md-icon-font);
297
- font-size: 24px;
298
- font-style: normal;
299
- font-variation-settings:
300
- "FILL" var(--md-icon-fill),
301
- "wght" var(--md-icon-weight),
302
- "GRAD" var(--md-icon-grade),
303
- "opsz" var(--md-icon-optical-size);
304
- line-height: 1;
305
- -webkit-font-smoothing: antialiased;
306
- transition: transform var(--md-comp-nav-drawer-duration, 250ms)
307
- var(--md-comp-nav-drawer-easing, ease);
308
- }
309
- }
310
-
311
- details {
312
- margin: 0;
313
- }
314
-
315
- details[open] > summary::after {
316
- transform: rotate(180deg);
317
- }
318
-
319
- details > ul {
320
- margin: 0;
321
- padding: 0;
322
- padding-inline-start: 10px;
323
- list-style: none;
324
- }
325
-
326
- .divider {
327
- margin: calc(var(--md-comp-nav-drawer-padding) * 0.5) 0 0;
328
- }
329
-
330
- .subheader {
331
- cursor: initial;
332
- pointer-events: none;
333
- color: var(--md-sys-color-on-surface-variant);
334
- font-size: var(--md-comp-nav-drawer-font-size);
335
- font-weight: 500;
336
- line-height: var(--md-comp-nav-drawer-line-height);
337
- }
338
-
339
- .user-view {
340
- position: relative;
341
- padding: calc(var(--md-comp-nav-drawer-padding) * 2) calc(var(--md-comp-nav-drawer-padding) * 2) 0;
342
- margin-bottom: calc(var(--md-comp-nav-drawer-padding) * 0.5);
343
-
344
- > a {
345
- height: auto;
346
- padding: 0;
347
-
348
- &:is(:hover, :active) {
349
- background-color: transparent;
350
- }
351
- }
352
-
353
- // The header image is clipped by .background, so the radius goes on the
354
- // clipping box rather than the <img>: the image is a child of an
355
- // overflow: hidden box, and rounding the child alone leaves the box's own
356
- // square corners painting behind it.
357
- .background {
358
- overflow: hidden;
359
- position: absolute;
360
- inset: 0;
361
- z-index: -1;
362
- border-end-start-radius: var(--md-comp-nav-drawer-user-view-shape);
363
- border-end-end-radius: var(--md-comp-nav-drawer-user-view-shape);
364
-
365
- // The name and email sit on whatever photograph the author supplied, so
366
- // the scrim is what makes them legible - bottom-weighted, because that
367
- // is where the text is. It rides inside .background so the rounded
368
- // corners clip it too.
369
- &::after {
370
- content: "";
371
- position: absolute;
372
- inset: 0;
373
- background: var(--md-comp-nav-drawer-user-view-scrim);
374
- }
375
- }
376
-
377
- .circle,
378
- .name,
379
- .email {
380
- display: block;
381
- }
382
-
383
- .circle {
384
- height: 64px;
385
- width: 64px;
386
- }
387
-
388
- .name,
389
- .email {
390
- font-size: var(--md-comp-nav-drawer-font-size);
391
- line-height: calc(var(--md-comp-nav-drawer-line-height) * 0.5);
392
- }
393
-
394
- // Over an image the surface roles mean nothing and the link colour these
395
- // spans inherit is unreadable on a mid-tone photograph. Scoped to
396
- // :has(> .background): with no image the header is on the drawer surface
397
- // and must keep tracking the theme, where fixed light ink would vanish.
398
- &:has(> .background) {
399
- .name,
400
- .email {
401
- color: var(--md-comp-nav-drawer-user-view-ink-color);
402
- }
403
- }
404
-
405
- .name {
406
- margin-top: 16px;
407
- font-weight: 500;
408
- }
409
-
410
- .email {
411
- padding-bottom: 16px;
412
- font-weight: 400;
413
- }
414
- }
415
- }
416
-
417
- // Overlay only: the dialog is the panel, so the list fills it. When the
418
- // host is `display: contents` (a docked :is(.sidenav-fixed, .navigation-drawer-fixed)) this must not
419
- // apply — static positioning would drop the list into the header flow
420
- // and it would read as part of the app bar.
421
- dialog:is(.sidenav-overlay, .navigation-drawer-overlay):modal > :is(.sidenav, .navigation-drawer) {
422
- position: static;
423
- inset: auto;
424
- width: 100%;
425
- height: 100%;
426
- transform: none;
427
- box-shadow: none;
428
- background-color: transparent;
429
- z-index: auto;
430
- }
431
-
432
- :is(.sidenav, .navigation-drawer):is(.sidenav-fixed, .navigation-drawer-fixed) {
433
- transform: none;
434
-
435
- &.right-aligned {
436
- transform: none;
437
- }
438
- }
439
-
440
- @include bp-down("expanded") {
441
- // Uninitialized / no-js: keep a fixed drawer off-canvas. Once JS wraps
442
- // it, the host's display:none hides the closed drawer and this must
443
- // not also hide the list inside an open dialog.
444
- :is(.sidenav, .navigation-drawer):is(.sidenav-fixed, .navigation-drawer-fixed) {
445
- transform: translateX(-100%);
446
-
447
- &.right-aligned {
448
- transform: translateX(100%);
449
- }
450
- }
451
-
452
- :is(.sidenav, .navigation-drawer) .user-view {
453
- padding: var(--md-comp-nav-drawer-padding) var(--md-comp-nav-drawer-padding) 0;
454
- }
455
- }
456
-
457
- .drag-target {
458
- position: fixed;
459
- inset: 0 auto 0 0;
460
- width: var(--md-comp-nav-drawer-drag-width, 10px);
461
- height: 100%;
462
- z-index: 998;
463
- touch-action: pan-y;
464
-
465
- &.right-aligned {
466
- inset: 0 0 0 auto;
467
- }
468
- }
469
-
470
- @include bp-up("expanded") {
471
- .drag-target[data-fixed] {
472
- display: none;
473
- pointer-events: none;
474
- }
475
- }
476
-
@@ -1,188 +0,0 @@
1
- @use "../abstracts" as *;
2
-
3
- // Segmented buttons.
4
- //
5
- // Anatomy is the HTML. A <fieldset class="segmented-button"> is the group and
6
- // its <legend> names it. Each segment is an <input> and the
7
- // <label class="segment"> beside it, tied by id: radios make the group
8
- // single-select, checkboxes make it multi-select, and the input type is the
9
- // whole difference.
10
- //
11
- // The control is the label's *sibling*, not its child, which is the same
12
- // arrangement filter chips use and for the same reason: to
13
- // forms/_radio-buttons and forms/_checkboxes, a <label> wrapping one of those
14
- // inputs *is* a radio or a checkbox. They would paint a 20dp ring on the
15
- // input, stretch the label to a 48dp row and, for a checkbox, mask a
16
- // checkmark onto its ::before - none of which a segment wants, and all of
17
- // which outweigh a segment rule that only names two classes.
18
- //
19
- // Nothing here is scripted, and that is the point. The browser owns the
20
- // checked state and, for radios, the arrow-key model a single-select group
21
- // promises: SEMANTICS rule 2 asks that a composite keyboard contract be
22
- // implemented before the role is claimed, and the native one is implemented
23
- // by the platform. No ARIA role is declared, so none is withheld.
24
- //
25
- // Tokens follow M3, md.comp.outlined-segmented-button.* (DSP 34.0.21):
26
- // container 40dp, corner.full, 1dp outline, dividers between segments
27
- // segment 12dp insets, 18dp icon, 8dp icon-label space, label-large
28
- // unselected on-surface on a transparent container
29
- // selected on-secondary-container on secondary-container
30
- // state layer 8% hover, 10% press (focus is the ring, not a layer)
31
- // disabled label and icon at 38%, outline at 12%
32
- .segmented-button {
33
- --md-comp-outlined-segmented-button-container-height: 40px;
34
- --md-comp-outlined-segmented-button-container-shape: 9999px;
35
- --md-comp-outlined-segmented-button-outline-width: 1px;
36
- --md-comp-outlined-segmented-button-outline-color: var(--md-sys-color-outline);
37
- --md-comp-outlined-segmented-button-leading-space: 12px;
38
- --md-comp-outlined-segmented-button-trailing-space: 12px;
39
- --md-comp-outlined-segmented-button-icon-size: 18px;
40
- --md-comp-outlined-segmented-button-icon-label-space: 8px;
41
- --md-comp-outlined-segmented-button-label-text-color: var(--md-sys-color-on-surface);
42
- --md-comp-outlined-segmented-button-selected-container-color: var(--md-sys-color-secondary-container);
43
- --md-comp-outlined-segmented-button-selected-label-text-color: var(--md-sys-color-on-secondary-container);
44
-
45
- // A <fieldset> arrives with a border, 16dp of padding and a min-width; the
46
- // group's own outline replaces all three.
47
- box-sizing: border-box;
48
- // Equal columns across whatever inline size the group is given, which is
49
- // what M3 specifies - material-web's own set is `grid-auto-columns: 1fr` on
50
- // a full-width grid, not a shrink-wrapped row. Constrain the group with a
51
- // width or a wrapper when it should be narrower than its container.
52
- display: grid;
53
- grid-auto-flow: column;
54
- grid-auto-columns: 1fr;
55
- min-inline-size: 0;
56
- margin: 0;
57
- padding: 0;
58
- background-color: transparent;
59
- border: var(--md-comp-outlined-segmented-button-outline-width) solid
60
- var(--md-comp-outlined-segmented-button-outline-color);
61
- border-radius: var(--md-comp-outlined-segmented-button-container-shape);
62
- // Squares the segments off against the pill, so the end segments' fill and
63
- // their focus ring both stop at the outline.
64
- overflow: hidden;
65
-
66
- & + & {
67
- margin-block-start: 24px;
68
- }
69
-
70
- // M3's anatomy has no visible group label. A set of radios is only a set
71
- // because a <fieldset> says so, and a <fieldset> is only named because of
72
- // its <legend> — so the legend is the accessible name and nothing else.
73
- //
74
- // There is deliberately no modifier that shows it. The root is both the
75
- // fieldset and the grid of segments, so a legend back in flow is another
76
- // column beside them; putting it above the pill would take an inner
77
- // wrapper the markup does not have. A group that needs a visible label
78
- // writes one before the fieldset and leaves the legend as the name.
79
- > legend {
80
- @include visually-hidden();
81
- }
82
-
83
- // The control carries the state and the form value; the label is the
84
- // segment. Clipped rather than `display: none` so it stays focusable — and
85
- // so the arrow keys still move between the radios.
86
- > input {
87
- @include visually-hidden();
88
- border: 0;
89
- appearance: none;
90
- }
91
-
92
- > .segment {
93
- // Read back by the state layer below, so hover and press are one rule
94
- // each rather than one per selected/unselected pair.
95
- --_label-color: var(--md-comp-outlined-segmented-button-label-text-color);
96
- --_container-color: transparent;
97
-
98
- display: inline-flex;
99
- align-items: center;
100
- justify-content: center;
101
- gap: var(--md-comp-outlined-segmented-button-icon-label-space);
102
- margin: 0;
103
- min-block-size: calc(
104
- var(--md-comp-outlined-segmented-button-container-height) - 2 *
105
- var(--md-comp-outlined-segmented-button-outline-width)
106
- );
107
- padding-inline: var(--md-comp-outlined-segmented-button-leading-space)
108
- var(--md-comp-outlined-segmented-button-trailing-space);
109
- white-space: nowrap;
110
- cursor: pointer;
111
- user-select: none;
112
- color: var(--_label-color);
113
- background-color: var(--_container-color);
114
- transition: background-color .2s ease, color .2s ease;
115
- @include typescale("label-large");
116
- }
117
-
118
- // Divider, not a border on every segment: the group's own outline is the
119
- // outer edge, so only the joins are drawn. `:first-of-type` counts labels,
120
- // and every segment is one — the legend and the inputs are other types.
121
- > .segment:not(:first-of-type) {
122
- border-inline-start: var(--md-comp-outlined-segmented-button-outline-width) solid
123
- var(--md-comp-outlined-segmented-button-outline-color);
124
- }
125
-
126
- // Selected is the input's business. The adjacency is what lets the label
127
- // read a state only the control has, with no class for the page to sync.
128
- > input:checked + .segment {
129
- --_label-color: var(--md-comp-outlined-segmented-button-selected-label-text-color);
130
- --_container-color: var(--md-comp-outlined-segmented-button-selected-container-color);
131
- }
132
-
133
- > .segment > #{$icon} {
134
- font-size: var(--md-comp-outlined-segmented-button-icon-size);
135
- width: var(--md-comp-outlined-segmented-button-icon-size);
136
- height: var(--md-comp-outlined-segmented-button-icon-size);
137
- line-height: var(--md-comp-outlined-segmented-button-icon-size);
138
- color: inherit;
139
- }
140
-
141
- > input:not(:disabled) + .segment {
142
- &:hover {
143
- background-color: color-mix(
144
- in oklab,
145
- var(--_label-color) state-opacity("hover"),
146
- var(--_container-color)
147
- );
148
- }
149
-
150
- &:active {
151
- background-color: color-mix(
152
- in oklab,
153
- var(--_label-color) state-opacity("pressed"),
154
- var(--_container-color)
155
- );
156
- }
157
- }
158
-
159
- // The ring is drawn inside the segment: `overflow: hidden` above would clip
160
- // an outline sitting outside it, and the end segments would lose half of it
161
- // to the pill's own corner.
162
- > input:focus-visible + .segment {
163
- @include focus-ring();
164
- outline-offset: -3px;
165
- }
166
-
167
- > input:disabled + .segment {
168
- --_label-color: color-mix(in oklab, var(--md-sys-color-on-surface) 38%, transparent);
169
- cursor: default;
170
- }
171
- }
172
-
173
- .segmented-button:disabled {
174
- --md-comp-outlined-segmented-button-outline-color: color-mix(
175
- in oklab,
176
- var(--md-sys-color-on-surface) 12%,
177
- transparent
178
- );
179
- --md-comp-outlined-segmented-button-label-text-color: color-mix(
180
- in oklab,
181
- var(--md-sys-color-on-surface) 38%,
182
- transparent
183
- );
184
-
185
- > .segment {
186
- cursor: default;
187
- }
188
- }