@expressivecss/expressive 0.11.0 → 0.13.1
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.
- package/CHANGELOG.md +392 -7
- package/README.md +37 -1
- package/dist/css/expressive.css +5440 -234
- package/dist/css/expressive.css.map +1 -1
- package/dist/css/expressive.min.css +1 -1
- package/dist/css/expressive.min.css.map +1 -1
- package/dist/fonts/material-symbols-outlined.woff2 +0 -0
- package/dist/fonts/material-symbols-rounded.woff2 +0 -0
- package/dist/fonts/material-symbols-sharp.woff2 +0 -0
- package/dist/js/chunks/{chunk-AYYYWUJ4.mjs → chunk-3CLXLPYS.mjs} +17 -11
- package/dist/js/chunks/chunk-3CLXLPYS.mjs.map +7 -0
- package/dist/js/chunks/chunk-3DHK5CZU.mjs +105 -0
- package/dist/js/chunks/chunk-3DHK5CZU.mjs.map +7 -0
- package/dist/js/chunks/{chunk-IMUPRRI6.mjs → chunk-3VOK6J7U.mjs} +3 -3
- package/dist/js/chunks/chunk-4PWAPV6F.mjs +7 -0
- package/dist/js/chunks/chunk-4PWAPV6F.mjs.map +7 -0
- package/dist/js/chunks/{chunk-XFJ452AZ.mjs → chunk-55IA2XUC.mjs} +5 -6
- package/dist/js/chunks/{chunk-XFJ452AZ.mjs.map → chunk-55IA2XUC.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-XDB3G6RL.mjs → chunk-6N2XAEFK.mjs} +15 -4
- package/dist/js/chunks/{chunk-XDB3G6RL.mjs.map → chunk-6N2XAEFK.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-MISGHDUU.mjs → chunk-6OMRGML6.mjs} +9 -7
- package/dist/js/chunks/{chunk-MISGHDUU.mjs.map → chunk-6OMRGML6.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-A3BJA7V4.mjs → chunk-6WLSDZ4O.mjs} +2 -2
- package/dist/js/chunks/chunk-CCWDV5CR.mjs +292 -0
- package/dist/js/chunks/chunk-CCWDV5CR.mjs.map +7 -0
- package/dist/js/chunks/{chunk-JODJAGFS.mjs → chunk-CKQP6P76.mjs} +31 -8
- package/dist/js/chunks/chunk-CKQP6P76.mjs.map +7 -0
- package/dist/js/chunks/{chunk-KR44BSYQ.mjs → chunk-DLWYKFEI.mjs} +3 -3
- package/dist/js/chunks/chunk-DTKR54I6.mjs +270 -0
- package/dist/js/chunks/chunk-DTKR54I6.mjs.map +7 -0
- package/dist/js/chunks/{chunk-SLFNPY5M.mjs → chunk-EC63CHXU.mjs} +2 -2
- package/dist/js/chunks/chunk-GVGT6MIU.mjs +47 -0
- package/dist/js/chunks/chunk-GVGT6MIU.mjs.map +7 -0
- package/dist/js/chunks/{chunk-LZVBJ33S.mjs → chunk-GZWPXXY6.mjs} +15 -8
- package/dist/js/chunks/chunk-GZWPXXY6.mjs.map +7 -0
- package/dist/js/chunks/chunk-HKT2S7VM.mjs +48 -0
- package/dist/js/chunks/chunk-HKT2S7VM.mjs.map +7 -0
- package/dist/js/chunks/{chunk-D4UZ4HFN.mjs → chunk-IFXVDDDH.mjs} +23 -11
- package/dist/js/chunks/chunk-IFXVDDDH.mjs.map +7 -0
- package/dist/js/chunks/chunk-K4CJCRGE.mjs +262 -0
- package/dist/js/chunks/chunk-K4CJCRGE.mjs.map +7 -0
- package/dist/js/chunks/chunk-LNCCYGPC.mjs +163 -0
- package/dist/js/chunks/chunk-LNCCYGPC.mjs.map +7 -0
- package/dist/js/chunks/{chunk-QSQ24FYT.mjs → chunk-LTWPGFBR.mjs} +2 -2
- package/dist/js/chunks/{chunk-QSQ24FYT.mjs.map → chunk-LTWPGFBR.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-I5KR22BY.mjs → chunk-LWBQIX5J.mjs} +15 -15
- package/dist/js/chunks/chunk-LWBQIX5J.mjs.map +7 -0
- package/dist/js/chunks/{chunk-GY2Z5CJ2.mjs → chunk-NNYP33NB.mjs} +67 -32
- package/dist/js/chunks/chunk-NNYP33NB.mjs.map +7 -0
- package/dist/js/chunks/chunk-NQLC3YMW.mjs +1 -0
- package/dist/js/chunks/chunk-O5XPWXIQ.mjs +406 -0
- package/dist/js/chunks/chunk-O5XPWXIQ.mjs.map +7 -0
- package/dist/js/chunks/chunk-P3G3QHII.mjs +166 -0
- package/dist/js/chunks/chunk-P3G3QHII.mjs.map +7 -0
- package/dist/js/chunks/{chunk-VAS6JQ6P.mjs → chunk-PIJ2TAR3.mjs} +3 -3
- package/dist/js/chunks/{chunk-74N6U5JJ.mjs → chunk-PLYXLSH3.mjs} +38 -37
- package/dist/js/chunks/chunk-PLYXLSH3.mjs.map +7 -0
- package/dist/js/chunks/{chunk-PIIAEYAJ.mjs → chunk-QDAL4IYN.mjs} +2 -2
- package/dist/js/chunks/chunk-QKWPQK5N.mjs +179 -0
- package/dist/js/chunks/chunk-QKWPQK5N.mjs.map +7 -0
- package/dist/js/chunks/{chunk-FRB7TOCS.mjs → chunk-QV2JAWIZ.mjs} +2 -2
- package/dist/js/chunks/{chunk-N3UHGN3N.mjs → chunk-QVVEWBOF.mjs} +3 -3
- package/dist/js/chunks/chunk-RHRQKTTX.mjs +139 -0
- package/dist/js/chunks/chunk-RHRQKTTX.mjs.map +7 -0
- package/dist/js/chunks/chunk-SPETGK25.mjs +59 -0
- package/dist/js/chunks/chunk-SPETGK25.mjs.map +7 -0
- package/dist/js/chunks/{chunk-TK6PX2GC.mjs → chunk-U2OTHOTI.mjs} +131 -19
- package/dist/js/chunks/chunk-U2OTHOTI.mjs.map +7 -0
- package/dist/js/chunks/{chunk-TYM6U5DY.mjs → chunk-UAEAQBRC.mjs} +2 -2
- package/dist/js/chunks/{chunk-7UXHSYIA.mjs → chunk-UBLRRJ7N.mjs} +3 -3
- package/dist/js/chunks/{chunk-EP3CVKB5.mjs → chunk-UEZUJQ66.mjs} +8 -5
- package/dist/js/chunks/chunk-UEZUJQ66.mjs.map +7 -0
- package/dist/js/chunks/{chunk-JNPIWFJT.mjs → chunk-UNEMYWEW.mjs} +3 -3
- package/dist/js/chunks/chunk-VTLBW7QS.mjs +124 -0
- package/dist/js/chunks/chunk-VTLBW7QS.mjs.map +7 -0
- package/dist/js/chunks/{chunk-JKNPQQWY.mjs → chunk-WJXDBPXQ.mjs} +28 -12
- package/dist/js/chunks/chunk-WJXDBPXQ.mjs.map +7 -0
- package/dist/js/chunks/{chunk-CDW6WIRT.mjs → chunk-XGHORT7J.mjs} +18 -11
- package/dist/js/chunks/chunk-XGHORT7J.mjs.map +7 -0
- package/dist/js/chunks/{chunk-7GKXUG4B.mjs → chunk-XH6BEEMY.mjs} +78 -25
- package/dist/js/chunks/chunk-XH6BEEMY.mjs.map +7 -0
- package/dist/js/chunks/{chunk-XO5WX3TK.mjs → chunk-YDCS5S3J.mjs} +2 -2
- package/dist/js/expressive.cjs +2540 -233
- package/dist/js/expressive.cjs.map +4 -4
- package/dist/js/expressive.js +2540 -233
- package/dist/js/expressive.js.map +4 -4
- package/dist/js/expressive.min.js +10 -10
- package/dist/js/expressive.min.js.map +4 -4
- package/dist/js/expressive.mjs +86 -38
- package/dist/js/expressive.mjs.map +1 -1
- package/dist/js/internal/behaviors/bottomSheets.mjs +3 -3
- package/dist/js/internal/behaviors/dialogs.mjs +2 -2
- package/dist/js/internal/behaviors/forms.mjs +2 -2
- package/dist/js/internal/behaviors/sheetDrag.mjs +2 -2
- package/dist/js/internal/behaviors/sideSheets.mjs +3 -3
- package/dist/js/internal/components/appBar.mjs +2 -2
- package/dist/js/internal/components/autocomplete.mjs +4 -4
- package/dist/js/internal/components/barChart.mjs +10 -0
- package/dist/js/internal/components/barChart.mjs.map +7 -0
- package/dist/js/internal/components/buttonGroup.mjs +2 -2
- package/dist/js/internal/components/buttons.mjs +3 -3
- package/dist/js/internal/components/cards.mjs +3 -3
- package/dist/js/internal/components/carousel.mjs +3 -3
- package/dist/js/internal/components/characterCounter.mjs +2 -2
- package/dist/js/internal/components/chips.mjs +5 -5
- package/dist/js/internal/components/columnChart.mjs +9 -0
- package/dist/js/internal/components/columnChart.mjs.map +7 -0
- package/dist/js/internal/components/commandPalette.mjs +9 -0
- package/dist/js/internal/components/commandPalette.mjs.map +7 -0
- package/dist/js/internal/components/datepicker.mjs +6 -6
- package/dist/js/internal/components/expandingCard.mjs +3 -3
- package/dist/js/internal/components/heatmapChart.mjs +9 -0
- package/dist/js/internal/components/heatmapChart.mjs.map +7 -0
- package/dist/js/internal/components/index.mjs +79 -31
- package/dist/js/internal/components/lightbox.mjs +3 -3
- package/dist/js/internal/components/lineChart.mjs +12 -0
- package/dist/js/internal/components/lineChart.mjs.map +7 -0
- package/dist/js/internal/components/menu.mjs +3 -3
- package/dist/js/internal/components/messageScroller.mjs +9 -0
- package/dist/js/internal/components/messageScroller.mjs.map +7 -0
- package/dist/js/internal/components/mixedChart.mjs +10 -0
- package/dist/js/internal/components/mixedChart.mjs.map +7 -0
- package/dist/js/internal/components/navigationRail.mjs +2 -2
- package/dist/js/internal/components/pieChart.mjs +9 -0
- package/dist/js/internal/components/pieChart.mjs.map +7 -0
- package/dist/js/internal/components/questionnaire.mjs +9 -0
- package/dist/js/internal/components/questionnaire.mjs.map +7 -0
- package/dist/js/internal/components/radarChart.mjs +9 -0
- package/dist/js/internal/components/radarChart.mjs.map +7 -0
- package/dist/js/internal/components/radialChart.mjs +9 -0
- package/dist/js/internal/components/radialChart.mjs.map +7 -0
- package/dist/js/internal/components/registry.mjs +37 -25
- package/dist/js/internal/components/richTextEditor.mjs +9 -0
- package/dist/js/internal/components/richTextEditor.mjs.map +7 -0
- package/dist/js/internal/components/scrollspy.mjs +2 -2
- package/dist/js/internal/components/select.mjs +4 -4
- package/dist/js/internal/components/slider.mjs +3 -3
- package/dist/js/internal/components/snackbar.mjs +2 -2
- package/dist/js/internal/components/tabs.mjs +4 -4
- package/dist/js/internal/components/timepicker.mjs +4 -4
- package/dist/js/internal/components/tooltip.mjs +3 -3
- package/dist/js/internal/core/component.mjs +1 -1
- package/dist/js/internal/core/utils.mjs +1 -1
- package/dist/js/internal/plugins/dockedDisplayPlugin.mjs +2 -2
- package/dist/js/modular.mjs +86 -38
- package/dist/types/behaviors/forms.d.ts +22 -0
- package/dist/types/components/appBar.d.ts +1 -1
- package/dist/types/components/barChart.d.ts +24 -0
- package/dist/types/components/columnChart.d.ts +21 -0
- package/dist/types/components/commandPalette.d.ts +96 -0
- package/dist/types/components/datepicker.d.ts +5 -2
- package/dist/types/components/heatmapChart.d.ts +49 -0
- package/dist/types/components/index.d.ts +12 -0
- package/dist/types/components/lineChart.d.ts +134 -0
- package/dist/types/components/menu.d.ts +32 -0
- package/dist/types/components/messageScroller.d.ts +111 -0
- package/dist/types/components/mixedChart.d.ts +25 -0
- package/dist/types/components/pieChart.d.ts +40 -0
- package/dist/types/components/questionnaire.d.ts +96 -0
- package/dist/types/components/radarChart.d.ts +39 -0
- package/dist/types/components/radialChart.d.ts +45 -0
- package/dist/types/components/registry.d.ts +44 -0
- package/dist/types/components/richTextEditor.d.ts +71 -0
- package/dist/types/components/slider.d.ts +1 -0
- package/dist/types/components/snackbar.d.ts +6 -0
- package/dist/types/components/timepicker.d.ts +4 -1
- package/dist/types/components/tooltip.d.ts +2 -1
- package/dist/types/modular.d.ts +10 -1
- package/package.json +4 -1
- package/src/sass/README.md +3 -6
- package/src/sass/abstracts/_index.scss +1 -1
- package/src/sass/abstracts/_mixins.scss +226 -0
- package/src/sass/abstracts/_variables.scss +14 -0
- package/src/sass/base/_typography.scss +45 -0
- package/src/sass/components/_accordion.scss +161 -0
- package/src/sass/components/_aura.scss +119 -0
- package/src/sass/components/_avatar.scss +86 -0
- package/src/sass/components/_bar-chart.scss +285 -0
- package/src/sass/components/_bottom-sheet.scss +1 -0
- package/src/sass/components/_button-groups.scss +13 -3
- package/src/sass/components/_cards.scss +16 -13
- package/src/sass/components/_carousel.scss +9 -7
- package/src/sass/components/_column-chart.scss +134 -0
- package/src/sass/components/_command-palette.scss +140 -0
- package/src/sass/components/_countdown.scss +89 -0
- package/src/sass/components/_data-table.scss +188 -0
- package/src/sass/components/_dialog.scss +1 -0
- package/src/sass/components/_empty-state.scss +78 -0
- package/src/sass/components/_expanding-card.scss +3 -0
- package/src/sass/components/_heatmap-chart.scss +156 -0
- package/src/sass/components/_index.scss +27 -0
- package/src/sass/components/_kpi.scss +162 -0
- package/src/sass/components/_line-chart.scss +102 -0
- package/src/sass/components/_marquee.scss +111 -0
- package/src/sass/components/_menu.scss +10 -0
- package/src/sass/components/_message-scroller.scss +66 -0
- package/src/sass/components/_message.scss +202 -0
- package/src/sass/components/_mixed-chart.scss +157 -0
- package/src/sass/components/_navbar.scss +11 -6
- package/src/sass/components/_navigation-bar.scss +1 -0
- package/src/sass/components/_navigation-rail.scss +9 -0
- package/src/sass/components/_page-footer.scss +0 -11
- package/src/sass/components/_pie-chart.scss +203 -0
- package/src/sass/components/_popover.scss +112 -0
- package/src/sass/components/_progress.scss +25 -6
- package/src/sass/components/_questionnaire.scss +144 -0
- package/src/sass/components/_radar-chart.scss +205 -0
- package/src/sass/components/_radial-chart.scss +174 -0
- package/src/sass/components/_rich-text-editor.scss +99 -0
- package/src/sass/components/_search.scss +1 -0
- package/src/sass/components/_side-sheet.scss +1 -0
- package/src/sass/components/_skeleton.scss +81 -0
- package/src/sass/components/_snackbar.scss +2 -1
- package/src/sass/components/_stat.scss +86 -0
- package/src/sass/components/_stepper.scss +190 -0
- package/src/sass/components/_timeline.scss +114 -0
- package/src/sass/components/_timepicker.scss +2 -2
- package/src/sass/components/_toolbar.scss +2 -1
- package/src/sass/components/_tooltip.scss +2 -0
- package/src/sass/components/_tree.scss +139 -0
- package/src/sass/components/forms/_checkboxes.scss +2 -2
- package/src/sass/components/forms/_drop-zone.scss +128 -0
- package/src/sass/components/forms/_index.scss +2 -0
- package/src/sass/components/forms/_input-fields.scss +166 -15
- package/src/sass/components/forms/_radio-buttons.scss +2 -2
- package/src/sass/components/forms/_rating.scss +165 -0
- package/src/sass/components/forms/_slider.scss +51 -29
- package/src/sass/components/forms/_switches.scss +3 -3
- package/src/sass/tokens/_reference.scss +3 -15
- package/src/sass/utilities/_helpers.scss +14 -0
- package/src/sass/utilities/_index.scss +2 -0
- package/src/sass/utilities/_scroll-area.scss +35 -0
- package/src/sass/utilities/_shapes.scss +164 -0
- package/src/sass/utilities/_spacing.scss +29 -23
- package/src/sass/utilities/_visibility.scss +3 -2
- package/dist/js/chunks/chunk-74N6U5JJ.mjs.map +0 -7
- package/dist/js/chunks/chunk-7GKXUG4B.mjs.map +0 -7
- package/dist/js/chunks/chunk-AYYYWUJ4.mjs.map +0 -7
- package/dist/js/chunks/chunk-CDW6WIRT.mjs.map +0 -7
- package/dist/js/chunks/chunk-D4UZ4HFN.mjs.map +0 -7
- package/dist/js/chunks/chunk-EP3CVKB5.mjs.map +0 -7
- package/dist/js/chunks/chunk-GY2Z5CJ2.mjs.map +0 -7
- package/dist/js/chunks/chunk-I5KR22BY.mjs.map +0 -7
- package/dist/js/chunks/chunk-JKNPQQWY.mjs.map +0 -7
- package/dist/js/chunks/chunk-JODJAGFS.mjs.map +0 -7
- package/dist/js/chunks/chunk-JR24UB4X.mjs +0 -100
- package/dist/js/chunks/chunk-JR24UB4X.mjs.map +0 -7
- package/dist/js/chunks/chunk-LZVBJ33S.mjs.map +0 -7
- package/dist/js/chunks/chunk-PMBPAFAS.mjs +0 -7
- package/dist/js/chunks/chunk-PMBPAFAS.mjs.map +0 -7
- package/dist/js/chunks/chunk-TK6PX2GC.mjs.map +0 -7
- package/dist/js/chunks/chunk-WWPAPHMA.mjs +0 -1
- /package/dist/js/chunks/{chunk-IMUPRRI6.mjs.map → chunk-3VOK6J7U.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-A3BJA7V4.mjs.map → chunk-6WLSDZ4O.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-KR44BSYQ.mjs.map → chunk-DLWYKFEI.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-SLFNPY5M.mjs.map → chunk-EC63CHXU.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-WWPAPHMA.mjs.map → chunk-NQLC3YMW.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-VAS6JQ6P.mjs.map → chunk-PIJ2TAR3.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-PIIAEYAJ.mjs.map → chunk-QDAL4IYN.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-FRB7TOCS.mjs.map → chunk-QV2JAWIZ.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-N3UHGN3N.mjs.map → chunk-QVVEWBOF.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-TYM6U5DY.mjs.map → chunk-UAEAQBRC.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-7UXHSYIA.mjs.map → chunk-UBLRRJ7N.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-JNPIWFJT.mjs.map → chunk-UNEMYWEW.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-XO5WX3TK.mjs.map → chunk-YDCS5S3J.mjs.map} +0 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
@use "../../abstracts" as *;
|
|
2
|
+
|
|
3
|
+
// Drop zone. A .drop-zone is a large target for choosing files: a <label>
|
|
4
|
+
// holding an icon, a prompt and a native <input type="file">, with an
|
|
5
|
+
// optional .drop-zone-files list after it.
|
|
6
|
+
//
|
|
7
|
+
// The input is stretched invisibly over the whole label, so the browser
|
|
8
|
+
// takes a click, a keypress or a dropped file exactly as it does on a plain
|
|
9
|
+
// file input. The Forms behavior adds .dragover while files are dragged over
|
|
10
|
+
// it and fills .drop-zone-files with each chosen file's name and size.
|
|
11
|
+
//
|
|
12
|
+
// Tokens:
|
|
13
|
+
// --md-comp-drop-zone-shape 16px
|
|
14
|
+
// --md-comp-drop-zone-outline-color outline
|
|
15
|
+
// --md-comp-drop-zone-dragover-container-color primary-container
|
|
16
|
+
// --md-comp-drop-zone-dragover-color on-primary-container
|
|
17
|
+
|
|
18
|
+
.drop-zone {
|
|
19
|
+
--md-comp-drop-zone-shape: 16px;
|
|
20
|
+
--md-comp-drop-zone-outline-color: var(--md-sys-color-outline);
|
|
21
|
+
--md-comp-drop-zone-dragover-container-color: var(--md-sys-color-primary-container);
|
|
22
|
+
--md-comp-drop-zone-dragover-color: var(--md-sys-color-on-primary-container);
|
|
23
|
+
|
|
24
|
+
margin: $element-top-margin 0 $element-bottom-margin;
|
|
25
|
+
|
|
26
|
+
> label {
|
|
27
|
+
position: relative;
|
|
28
|
+
box-sizing: border-box;
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-direction: column;
|
|
31
|
+
align-items: center;
|
|
32
|
+
gap: 4px;
|
|
33
|
+
padding: 32px 24px;
|
|
34
|
+
border: 1px dashed var(--md-comp-drop-zone-outline-color);
|
|
35
|
+
border-radius: var(--md-comp-drop-zone-shape);
|
|
36
|
+
text-align: center;
|
|
37
|
+
color: var(--md-sys-color-on-surface-variant);
|
|
38
|
+
cursor: pointer;
|
|
39
|
+
transition: background-color 0.2s ease-out, border-color 0.2s ease-out;
|
|
40
|
+
@include typescale("body-large");
|
|
41
|
+
|
|
42
|
+
> #{$icon} {
|
|
43
|
+
margin-block-end: 8px;
|
|
44
|
+
font-size: 32px;
|
|
45
|
+
color: var(--md-sys-color-primary);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
> small {
|
|
49
|
+
@include typescale("body-small");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
> input[type="file"] {
|
|
53
|
+
position: absolute;
|
|
54
|
+
inset: 0;
|
|
55
|
+
width: 100%;
|
|
56
|
+
height: 100%;
|
|
57
|
+
margin: 0;
|
|
58
|
+
padding: 0;
|
|
59
|
+
opacity: 0;
|
|
60
|
+
cursor: pointer;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
&:hover {
|
|
64
|
+
background-color: color-mix(
|
|
65
|
+
in oklab,
|
|
66
|
+
var(--md-sys-color-on-surface) state-opacity("hover"),
|
|
67
|
+
transparent
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
&:has(> input:focus-visible) {
|
|
72
|
+
@include focus-ring;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
&:has(> input:disabled) {
|
|
76
|
+
opacity: 0.38;
|
|
77
|
+
cursor: default;
|
|
78
|
+
pointer-events: none;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
&.dragover > label {
|
|
83
|
+
border-style: solid;
|
|
84
|
+
border-color: var(--md-sys-color-primary);
|
|
85
|
+
background-color: var(--md-comp-drop-zone-dragover-container-color);
|
|
86
|
+
color: var(--md-comp-drop-zone-dragover-color);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
> .drop-zone-files {
|
|
90
|
+
display: flex;
|
|
91
|
+
flex-direction: column;
|
|
92
|
+
gap: 2px;
|
|
93
|
+
margin: 8px 0 0;
|
|
94
|
+
padding: 0;
|
|
95
|
+
list-style: none;
|
|
96
|
+
|
|
97
|
+
> li {
|
|
98
|
+
display: flex;
|
|
99
|
+
justify-content: space-between;
|
|
100
|
+
gap: 16px;
|
|
101
|
+
padding: 8px 16px;
|
|
102
|
+
border-radius: 8px;
|
|
103
|
+
background-color: var(--md-sys-color-surface-container);
|
|
104
|
+
color: var(--md-sys-color-on-surface);
|
|
105
|
+
@include typescale("body-medium");
|
|
106
|
+
|
|
107
|
+
> :first-child {
|
|
108
|
+
min-width: 0;
|
|
109
|
+
overflow-wrap: anywhere;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
> :last-child:not(:first-child) {
|
|
113
|
+
flex: none;
|
|
114
|
+
color: var(--md-sys-color-on-surface-variant);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
&:empty {
|
|
119
|
+
display: none;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
@media (prefers-reduced-motion: reduce) {
|
|
125
|
+
.drop-zone > label {
|
|
126
|
+
transition: none;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -177,7 +177,7 @@ $_not-label: ".supporting-text, .character-counter, .file-path, .caret, .prefix,
|
|
|
177
177
|
// .character-counter, .file-path). So the documented markup names the side
|
|
178
178
|
// explicitly with .prefix / .suffix, and those rules key on nothing else.
|
|
179
179
|
> i:is(.prefix, .suffix, :first-of-type, :last-of-type, :last-child),
|
|
180
|
-
> :is(.prefix, .suffix) {
|
|
180
|
+
> :is(.prefix, .suffix):not(.icon-button) {
|
|
181
181
|
position: absolute;
|
|
182
182
|
top: 16px;
|
|
183
183
|
display: flex;
|
|
@@ -200,7 +200,7 @@ $_not-label: ".supporting-text, .character-counter, .file-path, .caret, .prefix,
|
|
|
200
200
|
> i.suffix,
|
|
201
201
|
> i:last-of-type:not(:first-of-type),
|
|
202
202
|
> i:last-child:not(:first-child):not(.prefix),
|
|
203
|
-
> .suffix {
|
|
203
|
+
> .suffix:not(.icon-button) {
|
|
204
204
|
right: 12px;
|
|
205
205
|
// Both icons inherited this from the floating-label rule until they were
|
|
206
206
|
// excluded from it. .prefix restates it below; .suffix has to as well, or
|
|
@@ -208,6 +208,15 @@ $_not-label: ".supporting-text, .character-counter, .file-path, .caret, .prefix,
|
|
|
208
208
|
pointer-events: none;
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
+
// A trailing icon button is a control, so it keeps its 40dp target and its
|
|
212
|
+
// clicks. It centres on the same point as a 24dp trailing icon.
|
|
213
|
+
> .icon-button.suffix {
|
|
214
|
+
position: absolute;
|
|
215
|
+
top: 8px;
|
|
216
|
+
right: 4px;
|
|
217
|
+
z-index: 1;
|
|
218
|
+
}
|
|
219
|
+
|
|
211
220
|
&:has(> i:first-of-type:not(.suffix):not(:last-child), > i.prefix, > .prefix) {
|
|
212
221
|
> :is(input, textarea) {
|
|
213
222
|
padding-left: 52px;
|
|
@@ -310,24 +319,166 @@ textarea {
|
|
|
310
319
|
}
|
|
311
320
|
}
|
|
312
321
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
322
|
+
// Datepicker paints its formatted date over the native value with ::after.
|
|
323
|
+
// Firefox renders no generated content on an <input>, so hiding the native
|
|
324
|
+
// value there left the field blank. The engines that do render it are the ones
|
|
325
|
+
// that expose ::-webkit-datetime-edit.
|
|
326
|
+
@supports selector(::-webkit-datetime-edit) {
|
|
327
|
+
// The positioned input would paint its filled container over the field's
|
|
328
|
+
// icons, which come before it. Raise them inside the field's own stacking
|
|
329
|
+
// context, so they do not also rise over the docked search view or a
|
|
330
|
+
// sticky header. A docked calendar in the field has to escape it.
|
|
331
|
+
.field:has(> :is(.datepicker-date-input, .date-picker-date-input)) {
|
|
332
|
+
&:not(:has(> .display-docked)) {
|
|
333
|
+
isolation: isolate;
|
|
334
|
+
}
|
|
316
335
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
336
|
+
> :is(i, .prefix, .suffix) {
|
|
337
|
+
z-index: 1;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
:is(.datepicker-date-input, .date-picker-date-input) {
|
|
342
|
+
position: relative;
|
|
343
|
+
text-indent: -9999px;
|
|
344
|
+
|
|
345
|
+
&::after {
|
|
346
|
+
display: block;
|
|
347
|
+
position: absolute;
|
|
348
|
+
top: 1.1rem;
|
|
349
|
+
content: attr(data-date);
|
|
350
|
+
color: var(--input-color);
|
|
351
|
+
text-indent: 0;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
&:focus-visible {
|
|
355
|
+
text-indent: 0;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
&:focus-visible:after {
|
|
359
|
+
text-indent: -9999px;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Password visibility toggle. A trailing .icon-button.password-toggle with
|
|
365
|
+
// aria-pressed holds two icons: the first shows while the password is hidden,
|
|
366
|
+
// the second once it is shown. The Forms behavior flips the input's type.
|
|
367
|
+
.password-toggle {
|
|
368
|
+
> #{$icon}:last-child:not(:first-child) {
|
|
369
|
+
display: none;
|
|
324
370
|
}
|
|
325
371
|
|
|
372
|
+
&[aria-pressed="true"] {
|
|
373
|
+
> #{$icon}:first-child:not(:last-child) {
|
|
374
|
+
display: none;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
> #{$icon}:last-child:not(:first-child) {
|
|
378
|
+
display: inline-block;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// One-time code. A single native input drawn as a row of cells, so paste,
|
|
384
|
+
// autofill from autocomplete="one-time-code", undo and the caret all stay the
|
|
385
|
+
// browser's. A monospace face makes every digit 1ch wide; letter-spacing
|
|
386
|
+
// moves each one to the next cell, and the input is clipped after the last.
|
|
387
|
+
//
|
|
388
|
+
// Tokens:
|
|
389
|
+
// --md-comp-otp-length 6
|
|
390
|
+
// --md-comp-otp-cell-width 48px
|
|
391
|
+
// --md-comp-otp-cell-height 56px
|
|
392
|
+
// --md-comp-otp-gap 8px
|
|
393
|
+
// --md-comp-otp-cell-color surface-container-highest
|
|
394
|
+
// --md-comp-otp-indicator-color on-surface-variant / focus: primary
|
|
395
|
+
//
|
|
396
|
+
// :not(.browser-default) matches the weight of the shared text-input rule
|
|
397
|
+
// above, which would otherwise win on width, height and letter-spacing.
|
|
398
|
+
input.otp:not(.browser-default) {
|
|
399
|
+
--md-comp-otp-length: 6;
|
|
400
|
+
--md-comp-otp-cell-width: 48px;
|
|
401
|
+
--md-comp-otp-cell-height: 56px;
|
|
402
|
+
--md-comp-otp-gap: 8px;
|
|
403
|
+
--md-comp-otp-cell-color: var(--md-sys-color-surface-container-highest);
|
|
404
|
+
--md-comp-otp-indicator-color: var(--md-sys-color-on-surface-variant);
|
|
405
|
+
// Derived, not for overriding: the distance between cell starts, the
|
|
406
|
+
// inset that centres a digit in its cell, and the box past the last cell
|
|
407
|
+
// that the caret needs and the clip hides.
|
|
408
|
+
--md-comp-otp-pitch: calc(var(--md-comp-otp-cell-width) + var(--md-comp-otp-gap));
|
|
409
|
+
--md-comp-otp-inset: calc((var(--md-comp-otp-cell-width) - 1ch) / 2);
|
|
410
|
+
--md-comp-otp-overhang: calc(var(--md-comp-otp-gap) + var(--md-comp-otp-inset) + 2px);
|
|
411
|
+
|
|
412
|
+
box-sizing: border-box;
|
|
413
|
+
display: block;
|
|
414
|
+
// Room for the caret after the last digit, clipped back to the cells; the
|
|
415
|
+
// negative margin gives the overhang back to the layout.
|
|
416
|
+
width: calc(var(--md-comp-otp-length) * var(--md-comp-otp-pitch) + var(--md-comp-otp-inset) + 2px);
|
|
417
|
+
height: var(--md-comp-otp-cell-height);
|
|
418
|
+
margin: 0 calc(var(--md-comp-otp-overhang) * -1) 0 0;
|
|
419
|
+
padding: 0 0 0 var(--md-comp-otp-inset);
|
|
420
|
+
border: 0;
|
|
421
|
+
border-radius: 0;
|
|
422
|
+
outline: 0;
|
|
423
|
+
box-shadow: none;
|
|
424
|
+
clip-path: inset(0 var(--md-comp-otp-overhang) 0 0);
|
|
425
|
+
// Digits read left to right in every script.
|
|
426
|
+
direction: ltr;
|
|
427
|
+
font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace;
|
|
428
|
+
font-size: 24px;
|
|
429
|
+
font-variant-numeric: tabular-nums;
|
|
430
|
+
letter-spacing: calc(var(--md-comp-otp-pitch) - 1ch);
|
|
431
|
+
color: var(--md-sys-color-on-surface);
|
|
432
|
+
caret-color: var(--md-sys-color-primary);
|
|
433
|
+
background-color: transparent;
|
|
434
|
+
background-image:
|
|
435
|
+
linear-gradient(
|
|
436
|
+
to right,
|
|
437
|
+
var(--md-comp-otp-indicator-color) var(--md-comp-otp-cell-width),
|
|
438
|
+
transparent 0
|
|
439
|
+
),
|
|
440
|
+
linear-gradient(
|
|
441
|
+
to right,
|
|
442
|
+
var(--md-comp-otp-cell-color) var(--md-comp-otp-cell-width),
|
|
443
|
+
transparent 0
|
|
444
|
+
);
|
|
445
|
+
background-size:
|
|
446
|
+
var(--md-comp-otp-pitch) 1px,
|
|
447
|
+
var(--md-comp-otp-pitch) 100%;
|
|
448
|
+
background-position: left bottom, left top;
|
|
449
|
+
background-repeat: repeat-x;
|
|
450
|
+
|
|
451
|
+
&::placeholder {
|
|
452
|
+
color: var(--md-sys-color-on-surface-variant);
|
|
453
|
+
opacity: 1;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Every cell's indicator turns primary and thickens while the code has
|
|
457
|
+
// focus; the clip would cut an outline, so this is the focus ring.
|
|
458
|
+
&:focus,
|
|
326
459
|
&:focus-visible {
|
|
327
|
-
|
|
460
|
+
--md-comp-otp-indicator-color: var(--md-sys-color-primary);
|
|
461
|
+
|
|
462
|
+
outline: 0;
|
|
463
|
+
background-size:
|
|
464
|
+
var(--md-comp-otp-pitch) 2px,
|
|
465
|
+
var(--md-comp-otp-pitch) 100%;
|
|
328
466
|
}
|
|
329
467
|
|
|
330
|
-
|
|
331
|
-
|
|
468
|
+
&.invalid,
|
|
469
|
+
&[aria-invalid="true"] {
|
|
470
|
+
--md-comp-otp-indicator-color: var(--md-sys-color-error);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
&:disabled {
|
|
474
|
+
opacity: 0.38;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
@media (forced-colors: active) {
|
|
478
|
+
--md-comp-otp-indicator-color: CanvasText;
|
|
479
|
+
|
|
480
|
+
&:focus {
|
|
481
|
+
--md-comp-otp-indicator-color: Highlight;
|
|
482
|
+
}
|
|
332
483
|
}
|
|
333
484
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
//
|
|
5
5
|
// Anatomy is the HTML. A <label> wrapping <input type="radio"> is the
|
|
6
6
|
// control. The label text is a sibling of the input — no extra class, no
|
|
7
|
-
// required <span>. input + span still works (legacy
|
|
7
|
+
// required <span>. input + span still works (legacy).
|
|
8
8
|
//
|
|
9
9
|
// Tokens follow https://m3.material.io/components/radio-button/specs
|
|
10
10
|
// icon 20dp ring, 2dp stroke, on-surface-variant
|
|
@@ -136,7 +136,7 @@ label:has(> [type="radio"]:disabled),
|
|
|
136
136
|
cursor: default;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
// Legacy
|
|
139
|
+
// Legacy: input + span draws the same 20/10 anatomy.
|
|
140
140
|
[type="radio"] + span {
|
|
141
141
|
position: relative;
|
|
142
142
|
display: inline-flex;
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
@use "../../abstracts" as *;
|
|
2
|
+
|
|
3
|
+
// Rating. Two forms share the star.
|
|
4
|
+
//
|
|
5
|
+
// Input: a <fieldset class="rating"> with a <legend> and one radio per star,
|
|
6
|
+
// each in a <label> whose visually hidden text ("3 stars") comes before the
|
|
7
|
+
// radio: a span after it is the older input + span radio, which hides the
|
|
8
|
+
// input. The radio itself is drawn as the star, so arrow keys, form
|
|
9
|
+
// submission and the group's name stay native. A star fills when it or a
|
|
10
|
+
// later star is checked; hovering previews.
|
|
11
|
+
//
|
|
12
|
+
// Display: <span class="rating" role="img" aria-label="Rated 4.5 out of 5">
|
|
13
|
+
// with --md-comp-rating-value. The stars fill to that value, halves included.
|
|
14
|
+
//
|
|
15
|
+
// Loaded after radio-buttons: the input rules match the radio rules' weight
|
|
16
|
+
// and win on order.
|
|
17
|
+
//
|
|
18
|
+
// Tokens:
|
|
19
|
+
// --md-comp-rating-size 24px (display 20px)
|
|
20
|
+
// --md-comp-rating-color tertiary
|
|
21
|
+
// --md-comp-rating-empty-color outline-variant
|
|
22
|
+
// --md-comp-rating-value 0 (display)
|
|
23
|
+
// --md-comp-rating-max 5 (display)
|
|
24
|
+
|
|
25
|
+
$_rating-star: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m12 17.27 6.18 3.73-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z'/%3E%3C/svg%3E");
|
|
26
|
+
|
|
27
|
+
.rating {
|
|
28
|
+
--md-comp-rating-size: 24px;
|
|
29
|
+
--md-comp-rating-color: var(--md-sys-color-tertiary);
|
|
30
|
+
--md-comp-rating-empty-color: var(--md-sys-color-outline-variant);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
fieldset.rating {
|
|
34
|
+
display: flex;
|
|
35
|
+
flex-wrap: wrap;
|
|
36
|
+
align-items: center;
|
|
37
|
+
margin: 0;
|
|
38
|
+
padding: 0;
|
|
39
|
+
border: 0;
|
|
40
|
+
|
|
41
|
+
> legend {
|
|
42
|
+
margin-block-end: 4px;
|
|
43
|
+
padding: 0;
|
|
44
|
+
color: var(--md-sys-color-on-surface-variant);
|
|
45
|
+
@include typescale("body-medium");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
> label {
|
|
49
|
+
display: inline-flex;
|
|
50
|
+
gap: 0;
|
|
51
|
+
min-height: 0;
|
|
52
|
+
padding: 4px;
|
|
53
|
+
border-radius: 50%;
|
|
54
|
+
cursor: pointer;
|
|
55
|
+
|
|
56
|
+
&:has(> input:focus-visible) {
|
|
57
|
+
@include focus-ring;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
&:has(> input:disabled) {
|
|
61
|
+
opacity: 0.38;
|
|
62
|
+
cursor: default;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
> label > [type="radio"] {
|
|
67
|
+
flex: none;
|
|
68
|
+
width: var(--md-comp-rating-size);
|
|
69
|
+
height: var(--md-comp-rating-size);
|
|
70
|
+
border: 0;
|
|
71
|
+
border-radius: 0;
|
|
72
|
+
background-color: var(--md-comp-rating-empty-color);
|
|
73
|
+
background-image: none;
|
|
74
|
+
box-shadow: none;
|
|
75
|
+
mask: $_rating-star center / 100% no-repeat;
|
|
76
|
+
outline: 0;
|
|
77
|
+
transition: background-color 0.15s ease-out;
|
|
78
|
+
|
|
79
|
+
// The base radio draws its dot in :checked, :hover and the disabled
|
|
80
|
+
// states, some at a higher weight; the star mask would show it.
|
|
81
|
+
&:checked,
|
|
82
|
+
&:hover,
|
|
83
|
+
&:disabled,
|
|
84
|
+
&:disabled:checked {
|
|
85
|
+
border: 0;
|
|
86
|
+
background-image: none;
|
|
87
|
+
box-shadow: none;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Filled: the checked star and every star before it.
|
|
92
|
+
> label:has(> :checked) > [type="radio"],
|
|
93
|
+
> label:has(~ label > :checked) > [type="radio"] {
|
|
94
|
+
background-color: var(--md-comp-rating-color);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Hovering previews the rating under the pointer. Both rules sit under the
|
|
98
|
+
// same :has() so the preview outranks the reset.
|
|
99
|
+
&:has(> label:hover) {
|
|
100
|
+
> label > [type="radio"] {
|
|
101
|
+
background-color: var(--md-comp-rating-empty-color);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
> label:hover > [type="radio"],
|
|
105
|
+
> label:has(~ label:hover) > [type="radio"] {
|
|
106
|
+
background-color: color-mix(in oklab, var(--md-comp-rating-color) 70%, transparent);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@media (prefers-reduced-motion: reduce) {
|
|
111
|
+
> label > [type="radio"] {
|
|
112
|
+
transition: none;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.rating:not(fieldset) {
|
|
118
|
+
--md-comp-rating-size: 20px;
|
|
119
|
+
--md-comp-rating-value: 0;
|
|
120
|
+
--md-comp-rating-max: 5;
|
|
121
|
+
|
|
122
|
+
display: inline-block;
|
|
123
|
+
width: calc(var(--md-comp-rating-size) * var(--md-comp-rating-max));
|
|
124
|
+
height: var(--md-comp-rating-size);
|
|
125
|
+
vertical-align: middle;
|
|
126
|
+
background: linear-gradient(
|
|
127
|
+
to right,
|
|
128
|
+
var(--md-comp-rating-color) calc(var(--md-comp-rating-value) / var(--md-comp-rating-max) * 100%),
|
|
129
|
+
var(--md-comp-rating-empty-color) 0
|
|
130
|
+
);
|
|
131
|
+
mask: $_rating-star left center / var(--md-comp-rating-size) repeat-x;
|
|
132
|
+
|
|
133
|
+
&:dir(rtl) {
|
|
134
|
+
background: linear-gradient(
|
|
135
|
+
to left,
|
|
136
|
+
var(--md-comp-rating-color) calc(var(--md-comp-rating-value) / var(--md-comp-rating-max) * 100%),
|
|
137
|
+
var(--md-comp-rating-empty-color) 0
|
|
138
|
+
);
|
|
139
|
+
mask-position: right center;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@media (forced-colors: active) {
|
|
144
|
+
fieldset.rating > label > [type="radio"],
|
|
145
|
+
.rating:not(fieldset) {
|
|
146
|
+
forced-color-adjust: none;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
fieldset.rating > label > [type="radio"] {
|
|
150
|
+
background-color: GrayText;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
fieldset.rating > label:has(> :checked) > [type="radio"],
|
|
154
|
+
fieldset.rating > label:has(~ label > :checked) > [type="radio"] {
|
|
155
|
+
background-color: Highlight;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.rating:not(fieldset) {
|
|
159
|
+
background: linear-gradient(
|
|
160
|
+
to right,
|
|
161
|
+
Highlight calc(var(--md-comp-rating-value) / var(--md-comp-rating-max) * 100%),
|
|
162
|
+
GrayText 0
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -54,7 +54,6 @@ input[type="range"] {
|
|
|
54
54
|
--md-comp-slider-active-fraction: 0%;
|
|
55
55
|
--md-comp-slider-start-fraction: 0%;
|
|
56
56
|
--md-comp-slider-end-fraction: 100%;
|
|
57
|
-
--md-comp-slider-stop-count: 6;
|
|
58
57
|
}
|
|
59
58
|
|
|
60
59
|
:is(#{$_host}) {
|
|
@@ -582,42 +581,65 @@ input[type="range"]:active:not(:disabled)::-moz-range-thumb {
|
|
|
582
581
|
}
|
|
583
582
|
}
|
|
584
583
|
|
|
585
|
-
// Discrete stops. Dots
|
|
586
|
-
:
|
|
584
|
+
// Discrete stops. Dots on the active track, horizontal only. Stop k sits where
|
|
585
|
+
// the handle centre sits at min + k * step: handle / 2 + k * spacing from the
|
|
586
|
+
// input's start edge. JS writes --md-comp-slider-stop-spacing only for a usable
|
|
587
|
+
// step, and for a single input the handle position and track centre, on the
|
|
588
|
+
// host. Tiles repeat from the start edge with the dot half a handle in, and
|
|
589
|
+
// clip-path keeps the stretch from --_from to --_to, measured from that edge.
|
|
590
|
+
// Without a spacing the tile is 0px wide and nothing paints. A centered slider
|
|
591
|
+
// leaves out the dot on the midpoint; an inset icon hides the dots under it.
|
|
592
|
+
//
|
|
593
|
+
// WebKit rounds a background tile to whole device pixels, so at 1x its dot k
|
|
594
|
+
// drifts by k times that rounding. Every tiled image does this there, and the
|
|
595
|
+
// exact repeating-linear-gradient row has square dots. WebKit is outside the
|
|
596
|
+
// Chrome/Firefox baseline, so the dots stay round.
|
|
597
|
+
:is(#{$_host}).stops:not(.vertical)::after {
|
|
598
|
+
--_position: var(--md-comp-slider-active-position, var(--md-comp-slider-active-fraction));
|
|
599
|
+
--_start: calc(var(--_position) + var(--md-comp-slider-gap) + var(--md-comp-slider-handle-width) / 2);
|
|
600
|
+
--_end: calc(var(--_position) - var(--md-comp-slider-gap) - var(--md-comp-slider-handle-width) / 2);
|
|
601
|
+
--_from: 0px;
|
|
602
|
+
--_to: var(--_end);
|
|
603
|
+
--_icon: 0px;
|
|
604
|
+
--_dot: calc(var(--md-comp-slider-handle-width) / 2);
|
|
605
|
+
|
|
587
606
|
content: "";
|
|
588
607
|
position: absolute;
|
|
589
608
|
z-index: 1;
|
|
590
609
|
left: 0;
|
|
591
|
-
top: 50
|
|
592
|
-
width:
|
|
593
|
-
0px,
|
|
594
|
-
calc(
|
|
595
|
-
var(--md-comp-slider-active-position, var(--md-comp-slider-active-fraction)) - var(--md-comp-slider-gap) -
|
|
596
|
-
var(--md-comp-slider-handle-width) / 2
|
|
597
|
-
)
|
|
598
|
-
);
|
|
610
|
+
top: var(--md-comp-slider-track-center, 50%);
|
|
611
|
+
width: 100%;
|
|
599
612
|
height: var(--md-comp-slider-track-height);
|
|
600
613
|
translate: 0 -50%;
|
|
601
614
|
pointer-events: none;
|
|
602
|
-
background
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
);
|
|
607
|
-
background-size: calc(100% / max(1, var(--md-comp-slider-stop-count) - 1)) 100%;
|
|
608
|
-
background-repeat: repeat-x;
|
|
609
|
-
background-position: center;
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
:is(#{$_host}).stops.centered::after {
|
|
613
|
-
left: min(50%, var(--md-comp-slider-active-position, var(--md-comp-slider-active-fraction)));
|
|
614
|
-
width: max(
|
|
615
|
-
0%,
|
|
616
|
-
calc(
|
|
617
|
-
abs(50% - var(--md-comp-slider-active-position, var(--md-comp-slider-active-fraction))) - var(--md-comp-slider-gap) -
|
|
618
|
-
var(--md-comp-slider-handle-width) / 2
|
|
615
|
+
background: radial-gradient(
|
|
616
|
+
circle var(--md-comp-slider-stop-size) at var(--_dot) 50%,
|
|
617
|
+
var(--md-sys-color-on-primary) 99%,
|
|
618
|
+
transparent
|
|
619
619
|
)
|
|
620
|
-
|
|
620
|
+
0 0 / var(--md-comp-slider-stop-spacing, 0px) 100% repeat-x;
|
|
621
|
+
// The inset icon stays on the left in both directions, so --_icon clips the left.
|
|
622
|
+
clip-path: inset(0 calc(100% - var(--_to)) 0 max(var(--_from), var(--_icon)));
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// The input's direction, not the host's: it decides which end is min.
|
|
626
|
+
:is(#{$_host}).stops:not(.vertical):has([type="range"]:dir(rtl))::after {
|
|
627
|
+
--_dot: calc(100% - var(--md-comp-slider-handle-width) / 2);
|
|
628
|
+
background-position-x: right;
|
|
629
|
+
clip-path: inset(0 var(--_from) 0 max(calc(100% - var(--_to)), var(--_icon)));
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
:is(#{$_host}).stops.centered:not(.vertical)::after {
|
|
633
|
+
--_from: min(50% + var(--md-comp-slider-stop-size), var(--_start));
|
|
634
|
+
--_to: max(50% - var(--md-comp-slider-stop-size), var(--_end));
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
:is(#{$_host}).stops:not(.vertical):has(> #{$icon}:first-child)::after {
|
|
638
|
+
--_icon: calc(var(--md-comp-slider-stop-inset) + var(--md-comp-slider-icon-size));
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
:is(#{$_host}).stops:has(> [type="range"]:disabled)::after {
|
|
642
|
+
opacity: 0.38;
|
|
621
643
|
}
|
|
622
644
|
|
|
623
645
|
// Value label — 40dp, 4dp above the handle. JS inserts this after the input.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// Anatomy is the HTML. A <label class="switch"> wrapping
|
|
6
6
|
// <input type="checkbox"> is the control. The label text is a sibling of
|
|
7
7
|
// the input — no .lever required. input + .lever and input + span still
|
|
8
|
-
// work (legacy
|
|
8
|
+
// work (legacy).
|
|
9
9
|
//
|
|
10
10
|
// Tokens follow https://m3.material.io/components/switch/specs
|
|
11
11
|
// track 52×32dp, 16dp corners
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
cursor: default;
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
// Legacy
|
|
132
|
+
// Legacy: input + .lever or input + span draws the same anatomy.
|
|
133
133
|
.switch [type="checkbox"] + .lever,
|
|
134
134
|
.switch [type="checkbox"] + span {
|
|
135
135
|
position: relative;
|
|
@@ -207,7 +207,7 @@
|
|
|
207
207
|
cursor: default;
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
-
//
|
|
210
|
+
// The span holds the label text as well as the track.
|
|
211
211
|
.switch [type="checkbox"] + span:not(.lever):not(:empty) {
|
|
212
212
|
width: auto;
|
|
213
213
|
min-width: var(--md-comp-switch-track-width);
|
|
@@ -24,21 +24,9 @@
|
|
|
24
24
|
// against #006495, the one source there is ground truth for - $md-source below
|
|
25
25
|
// is a branding choice and is free to change without failing it.
|
|
26
26
|
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
// "appetising" hues (0-60deg) are disqualified outright - they put primary on
|
|
31
|
-
// top of error, dEok 0.07-0.12 against ~0.28 here.
|
|
32
|
-
//
|
|
33
|
-
// Teal wins on *worst case* across both schemes rather than on either one
|
|
34
|
-
// alone, which is the metric that matters: evening service runs dark mode in a
|
|
35
|
-
// dim room, and that is where a confirm/void mix-up actually happens.
|
|
36
|
-
// light primary40 vs error40 dEok 0.278
|
|
37
|
-
// dark primary80 vs error80 dEok 0.212 <- best of the candidates
|
|
38
|
-
// light tertiary40 vs error40 dEok 0.224
|
|
39
|
-
// It also leaves green free for the "settled/paid" role a POS will want and
|
|
40
|
-
// Material does not supply.
|
|
41
|
-
$md-source: #006A79 !default;
|
|
27
|
+
// Mist Iris is the default seed for the generated ramps. Primary, secondary,
|
|
28
|
+
// tertiary and neutral colors derive from it; the error ramp stays fixed.
|
|
29
|
+
$md-source: #c6a0f6 !default;
|
|
42
30
|
|
|
43
31
|
// tone -> OKLCH lightness. Fitted against the reference ramps; see the test.
|
|
44
32
|
$tones: (
|