@expressivecss/expressive 0.10.1 → 0.12.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.
- package/CHANGELOG.md +238 -7
- package/README.md +22 -1
- package/dist/css/expressive.css +272 -107
- 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-YFXEJ7GR.mjs → chunk-3VOK6J7U.mjs} +7 -8
- package/dist/js/chunks/chunk-3VOK6J7U.mjs.map +7 -0
- 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-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-SLFNPY5M.mjs → chunk-EC63CHXU.mjs} +2 -2
- package/dist/js/chunks/chunk-G3I5H2U3.mjs +7 -0
- package/dist/js/chunks/{chunk-ZAOYQ6SY.mjs.map → chunk-G3I5H2U3.mjs.map} +1 -1
- 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-QYCYP443.mjs → chunk-H2WA4XHH.mjs} +43 -36
- package/dist/js/chunks/chunk-H2WA4XHH.mjs.map +7 -0
- package/dist/js/chunks/{chunk-G576EP5O.mjs → chunk-HB6IW7QQ.mjs} +78 -16
- package/dist/js/chunks/chunk-HB6IW7QQ.mjs.map +7 -0
- package/dist/js/chunks/{chunk-7MM4VJJO.mjs → chunk-HLDXZ7XB.mjs} +23 -15
- package/dist/js/chunks/chunk-HLDXZ7XB.mjs.map +7 -0
- package/dist/js/chunks/{chunk-ZIZVUWRL.mjs → chunk-HNFSMIBY.mjs} +18 -18
- 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-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-AOGFNMXS.mjs → chunk-LWBQIX5J.mjs} +16 -16
- 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-VAS6JQ6P.mjs → chunk-PIJ2TAR3.mjs} +3 -3
- package/dist/js/chunks/{chunk-JR24UB4X.mjs → chunk-PSSHQWCX.mjs} +2 -2
- package/dist/js/chunks/{chunk-PIIAEYAJ.mjs → chunk-QDAL4IYN.mjs} +2 -2
- package/dist/js/chunks/chunk-QV2JAWIZ.mjs +135 -0
- package/dist/js/chunks/chunk-QV2JAWIZ.mjs.map +7 -0
- package/dist/js/chunks/{chunk-N3UHGN3N.mjs → chunk-QVVEWBOF.mjs} +3 -3
- package/dist/js/chunks/{chunk-ZZBZI2XN.mjs → chunk-RFZZCYVU.mjs} +18 -11
- package/dist/js/chunks/chunk-RFZZCYVU.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-JKNPQQWY.mjs → chunk-WJXDBPXQ.mjs} +28 -12
- package/dist/js/chunks/chunk-WJXDBPXQ.mjs.map +7 -0
- package/dist/js/chunks/{chunk-XO5WX3TK.mjs → chunk-YDCS5S3J.mjs} +2 -2
- package/dist/js/chunks/{chunk-TK6PX2GC.mjs → chunk-YSBCHYXP.mjs} +16 -8
- package/dist/js/chunks/chunk-YSBCHYXP.mjs.map +7 -0
- package/dist/js/expressive.cjs +398 -217
- package/dist/js/expressive.cjs.map +2 -2
- package/dist/js/expressive.js +398 -217
- package/dist/js/expressive.js.map +2 -2
- package/dist/js/expressive.min.js +10 -10
- package/dist/js/expressive.min.js.map +3 -3
- package/dist/js/expressive.mjs +30 -30
- 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/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/datepicker.mjs +6 -6
- package/dist/js/internal/components/expandingCard.mjs +3 -3
- package/dist/js/internal/components/index.mjs +23 -23
- package/dist/js/internal/components/lightbox.mjs +3 -3
- package/dist/js/internal/components/menu.mjs +3 -3
- package/dist/js/internal/components/navigationRail.mjs +2 -2
- package/dist/js/internal/components/registry.mjs +24 -24
- 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 +30 -30
- package/dist/types/components/appBar.d.ts +1 -1
- package/dist/types/components/autocomplete.d.ts +2 -1
- package/dist/types/components/datepicker.d.ts +6 -2
- package/dist/types/components/menu.d.ts +1 -0
- package/dist/types/components/scrollspy.d.ts +5 -4
- package/dist/types/components/select.d.ts +7 -1
- 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 +1 -1
- package/package.json +1 -1
- package/src/sass/abstracts/_mixins.scss +19 -11
- package/src/sass/components/_buttons.scss +45 -0
- package/src/sass/components/_carousel.scss +9 -7
- package/src/sass/components/_chips.scss +5 -9
- package/src/sass/components/_dialog.scss +0 -7
- package/src/sass/components/_navbar.scss +13 -8
- package/src/sass/components/_page-footer.scss +0 -11
- package/src/sass/components/_progress.scss +25 -6
- package/src/sass/components/_snackbar.scss +1 -1
- package/src/sass/components/_timepicker.scss +2 -2
- package/src/sass/components/_toolbar.scss +1 -1
- package/src/sass/components/forms/_checkboxes.scss +2 -2
- package/src/sass/components/forms/_fieldset.scss +20 -1
- package/src/sass/components/forms/_file-input.scss +11 -3
- package/src/sass/components/forms/_input-fields.scss +35 -15
- package/src/sass/components/forms/_radio-buttons.scss +2 -2
- package/src/sass/components/forms/_select.scss +3 -2
- package/src/sass/components/forms/_slider.scss +51 -29
- package/src/sass/components/forms/_switches.scss +3 -3
- package/src/sass/utilities/_helpers.scss +14 -0
- package/src/sass/utilities/_spacing.scss +29 -23
- package/src/sass/utilities/_visibility.scss +7 -1
- package/dist/js/chunks/chunk-7MM4VJJO.mjs.map +0 -7
- package/dist/js/chunks/chunk-AOGFNMXS.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-G576EP5O.mjs.map +0 -7
- package/dist/js/chunks/chunk-GY2Z5CJ2.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-LZVBJ33S.mjs.map +0 -7
- package/dist/js/chunks/chunk-QYCYP443.mjs.map +0 -7
- package/dist/js/chunks/chunk-TK6PX2GC.mjs.map +0 -7
- package/dist/js/chunks/chunk-TZZ24ZQS.mjs +0 -154
- package/dist/js/chunks/chunk-TZZ24ZQS.mjs.map +0 -7
- package/dist/js/chunks/chunk-YFXEJ7GR.mjs.map +0 -7
- package/dist/js/chunks/chunk-ZAOYQ6SY.mjs +0 -7
- package/dist/js/chunks/chunk-ZZBZI2XN.mjs.map +0 -7
- /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-ZIZVUWRL.mjs.map → chunk-HNFSMIBY.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-VAS6JQ6P.mjs.map → chunk-PIJ2TAR3.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-JR24UB4X.mjs.map → chunk-PSSHQWCX.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-PIIAEYAJ.mjs.map → chunk-QDAL4IYN.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
|
@@ -101,7 +101,7 @@ input[type=text]:is(.timepicker-input-minutes, .time-picker-input-minutes) {
|
|
|
101
101
|
:is(.timepicker-container, .time-picker-container) .pm-btn {
|
|
102
102
|
width: 3.6rem;
|
|
103
103
|
height: 50%;
|
|
104
|
-
// --btn-padding is a
|
|
104
|
+
// --btn-padding is a retired variable that no longer exists, so this
|
|
105
105
|
// was invalid at computed-value time and the padding resolved to 0 - not
|
|
106
106
|
// to the base button's inline space, which the invalid declaration still
|
|
107
107
|
// beat in the cascade. Written as the 0 it has always rendered as.
|
|
@@ -278,7 +278,7 @@ input[type=text]:is(.timepicker-input-minutes, .time-picker-input-minutes) {
|
|
|
278
278
|
:is(.timepicker-container, .time-picker-container) .pm-btn {
|
|
279
279
|
flex-grow: 1;
|
|
280
280
|
/*width: auto;*/
|
|
281
|
-
// Same two
|
|
281
|
+
// Same two retired variables as above; both declarations
|
|
282
282
|
// rendered as 0. The corner rules that follow square off the inner
|
|
283
283
|
// edges, so the outer ones are the only radius in play.
|
|
284
284
|
padding-inline: 0;
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
// already, in $_bar.
|
|
58
58
|
$_toolbar: ".toolbar";
|
|
59
59
|
|
|
60
|
-
// The two axes. `.max` is
|
|
60
|
+
// The two axes. `.max` is an alias for docked; `.filled` is the older
|
|
61
61
|
// name for vibrant. Both stay in the :is() lists.
|
|
62
62
|
$_floating: "#{$_toolbar}:is(.floating, :not(.docked, .max))";
|
|
63
63
|
$_docked: "#{$_toolbar}:is(.docked, .max)";
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
//
|
|
5
5
|
// Anatomy is the HTML. A <label> wrapping <input type="checkbox"> is
|
|
6
6
|
// the control. The label text is a sibling of the input — no extra class,
|
|
7
|
-
// no required <span>. input + span still works (legacy /
|
|
7
|
+
// no required <span>. input + span still works (legacy / Select).
|
|
8
8
|
// label.switch is a switch, not a checkbox — leave it alone.
|
|
9
9
|
//
|
|
10
10
|
// Tokens follow https://m3.material.io/components/checkbox/specs
|
|
@@ -206,7 +206,7 @@ label:has(> [type="checkbox"]:disabled):not(.switch),
|
|
|
206
206
|
cursor: default;
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
-
// Legacy /
|
|
209
|
+
// Legacy / Select / Autocomplete: input + span draws the same
|
|
210
210
|
// 18dp anatomy. Exclude .switch — that file paints the track on a span.
|
|
211
211
|
$_cb-span: "*:not(.switch) > [type='checkbox'] + span:not(.lever, .supporting-text, .character-counter, .file-path)";
|
|
212
212
|
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
// Anatomy is the HTML. A <fieldset> is the group. A <legend> is the
|
|
6
6
|
// headline. Direct children are the fields — .field, radios, switches,
|
|
7
7
|
// a .inline row of radios, a trailing <small> as supporting text. No wrapper
|
|
8
|
-
// class. .filled / .border / .rounded are helpers markup cannot
|
|
8
|
+
// class. .filled / .border / .rounded / .plain are helpers markup cannot
|
|
9
|
+
// express.
|
|
9
10
|
//
|
|
10
11
|
// M3 has no fieldset component. Tokens follow the outlined grouping
|
|
11
12
|
// container used around related form content, and the outlined text-field
|
|
@@ -99,6 +100,24 @@ fieldset.rounded {
|
|
|
99
100
|
--md-comp-fieldset-container-shape: 12px;
|
|
100
101
|
}
|
|
101
102
|
|
|
103
|
+
// Plain groups radios or checkboxes inside a surface that already frames them,
|
|
104
|
+
// such as a card, a dialog or a filled section. No outline, fill, padding or
|
|
105
|
+
// sibling margin, and the legend starts where the content starts instead of
|
|
106
|
+
// sitting in a notch 4dp outside it.
|
|
107
|
+
fieldset.plain {
|
|
108
|
+
--md-comp-fieldset-container-color: transparent;
|
|
109
|
+
--md-comp-fieldset-outline-width: 0;
|
|
110
|
+
|
|
111
|
+
margin: 0;
|
|
112
|
+
padding: 0;
|
|
113
|
+
|
|
114
|
+
> legend {
|
|
115
|
+
max-width: 100%;
|
|
116
|
+
margin-inline-start: 0;
|
|
117
|
+
padding-inline: 0;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
102
121
|
fieldset:disabled,
|
|
103
122
|
fieldset[disabled] {
|
|
104
123
|
--md-comp-fieldset-outline-color: color-mix(
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
.file-field {
|
|
4
4
|
display: grid;
|
|
5
|
-
|
|
5
|
+
// Short triggers keep their intrinsic width; long labels leave room for
|
|
6
|
+
// the selected filename instead of consuming the entire field.
|
|
7
|
+
grid-template-columns: fit-content(50%) minmax(0, 1fr);
|
|
6
8
|
gap: 10px;
|
|
7
9
|
//position: relative;
|
|
8
10
|
|
|
@@ -18,10 +20,16 @@
|
|
|
18
20
|
> label.button,
|
|
19
21
|
> button,
|
|
20
22
|
> .btn {
|
|
23
|
+
display: block;
|
|
24
|
+
align-content: center;
|
|
25
|
+
overflow-wrap: break-word;
|
|
21
26
|
position: relative;
|
|
22
27
|
overflow: hidden;
|
|
23
|
-
height
|
|
24
|
-
|
|
28
|
+
// A minimum rather than a height, so a wrapped label grows the trigger.
|
|
29
|
+
// `start` keeps the grid from stretching it to the 56dp text field.
|
|
30
|
+
align-self: start;
|
|
31
|
+
min-height: 3rem;
|
|
32
|
+
min-width: 0;
|
|
25
33
|
}
|
|
26
34
|
|
|
27
35
|
span {
|
|
@@ -310,24 +310,44 @@ textarea {
|
|
|
310
310
|
}
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
313
|
+
// Datepicker paints its formatted date over the native value with ::after.
|
|
314
|
+
// Firefox renders no generated content on an <input>, so hiding the native
|
|
315
|
+
// value there left the field blank. The engines that do render it are the ones
|
|
316
|
+
// that expose ::-webkit-datetime-edit.
|
|
317
|
+
@supports selector(::-webkit-datetime-edit) {
|
|
318
|
+
// The positioned input would paint its filled container over the field's
|
|
319
|
+
// icons, which come before it. Raise them inside the field's own stacking
|
|
320
|
+
// context, so they do not also rise over the docked search view or a
|
|
321
|
+
// sticky header. A docked calendar in the field has to escape it.
|
|
322
|
+
.field:has(> :is(.datepicker-date-input, .date-picker-date-input)) {
|
|
323
|
+
&:not(:has(> .display-docked)) {
|
|
324
|
+
isolation: isolate;
|
|
325
|
+
}
|
|
325
326
|
|
|
326
|
-
|
|
327
|
-
|
|
327
|
+
> :is(i, .prefix, .suffix) {
|
|
328
|
+
z-index: 1;
|
|
329
|
+
}
|
|
328
330
|
}
|
|
329
331
|
|
|
330
|
-
|
|
332
|
+
:is(.datepicker-date-input, .date-picker-date-input) {
|
|
333
|
+
position: relative;
|
|
331
334
|
text-indent: -9999px;
|
|
335
|
+
|
|
336
|
+
&::after {
|
|
337
|
+
display: block;
|
|
338
|
+
position: absolute;
|
|
339
|
+
top: 1.1rem;
|
|
340
|
+
content: attr(data-date);
|
|
341
|
+
color: var(--input-color);
|
|
342
|
+
text-indent: 0;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
&:focus-visible {
|
|
346
|
+
text-indent: 0;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
&:focus-visible:after {
|
|
350
|
+
text-indent: -9999px;
|
|
351
|
+
}
|
|
332
352
|
}
|
|
333
353
|
}
|
|
@@ -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;
|
|
@@ -112,8 +112,9 @@ select.browser-default {
|
|
|
112
112
|
transform: rotate(180deg);
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
// Keep
|
|
116
|
-
//
|
|
115
|
+
// Keep native validation focus available and its geometry at the field.
|
|
116
|
+
// The aria-hidden wrapper excludes it from the accessibility tree; JS
|
|
117
|
+
// forwards native focus to the visible combobox after reporting finishes.
|
|
117
118
|
.hide-select {
|
|
118
119
|
position: absolute;
|
|
119
120
|
inset: 0;
|
|
@@ -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);
|
|
@@ -25,10 +25,21 @@
|
|
|
25
25
|
.flex-1 { flex: 1 1 0; }
|
|
26
26
|
.flex-none { flex: none; }
|
|
27
27
|
|
|
28
|
+
// Allow flex and grid children to shrink around their content.
|
|
29
|
+
.min-w-0 { min-width: 0; }
|
|
30
|
+
.min-h-0 { min-height: 0; }
|
|
31
|
+
|
|
32
|
+
// Scrolling and clipping without changing the element's display or size.
|
|
33
|
+
.overflow-x-auto { overflow-x: auto; }
|
|
34
|
+
.overflow-y-auto { overflow-y: auto; }
|
|
35
|
+
.overflow-hidden { overflow: hidden; }
|
|
36
|
+
|
|
28
37
|
// Text alignment
|
|
29
38
|
.left-align { text-align: left; }
|
|
30
39
|
.right-align { text-align: right }
|
|
31
40
|
.center-align { text-align: center; }
|
|
41
|
+
.start-align { text-align: start; }
|
|
42
|
+
.end-align { text-align: end; }
|
|
32
43
|
|
|
33
44
|
// Dividers
|
|
34
45
|
.divider {
|
|
@@ -45,6 +56,9 @@
|
|
|
45
56
|
// live here: no selector in `components` can outrank this one.
|
|
46
57
|
.circle:not(.extra, .large) { border-radius: 50%; }
|
|
47
58
|
.center-block { display: block; margin-left: auto; margin-right: auto; }
|
|
59
|
+
.break-words { overflow-wrap: anywhere; }
|
|
60
|
+
.text-nowrap { white-space: nowrap; }
|
|
61
|
+
.text-wrap { white-space: normal; }
|
|
48
62
|
.truncate { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
49
63
|
.no-padding { padding: 0 !important; }
|
|
50
64
|
|
|
@@ -1,38 +1,44 @@
|
|
|
1
|
-
// Margin, padding and gap scale: .m-3, .pt-2, .px-4, .
|
|
1
|
+
// Margin, padding and gap scale: .m-3, .pt-2, .px-4, .ms-auto, .gap-2, ...
|
|
2
2
|
//
|
|
3
3
|
// Shortcut x value x direction, all !important so a helper wins over the
|
|
4
4
|
// component it is applied to. Edit the maps here to change the scale.
|
|
5
5
|
|
|
6
6
|
$spacing-shortcuts: ("margin": "m", "padding": "p") !default;
|
|
7
|
-
$spacing-directions: (
|
|
7
|
+
$spacing-directions: (
|
|
8
|
+
"top": "t", "right": "r", "bottom": "b", "left": "l",
|
|
9
|
+
"inline-start": "s", "inline-end": "e"
|
|
10
|
+
) !default;
|
|
8
11
|
$spacing-horizontal: "x" !default;
|
|
9
12
|
$spacing-vertical: "y" !default;
|
|
10
13
|
$spacing-values: ("0": 0, "1": 0.25rem, "2": 0.5rem, "3": 0.75rem, "4": 1rem, "5": 1.5rem, "6": 3rem, "auto": auto) !default;
|
|
11
14
|
|
|
12
15
|
@each $property, $shortcut in $spacing-shortcuts{
|
|
13
16
|
@each $name, $value in $spacing-values{
|
|
14
|
-
//
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@each $direction, $suffix in $spacing-directions{
|
|
20
|
-
.#{$shortcut}#{$suffix}-#{$name}{
|
|
21
|
-
#{$property}-#{$direction}: $value !important
|
|
17
|
+
// CSS accepts auto margins, but not auto padding.
|
|
18
|
+
@if $property != "padding" or $value != auto {
|
|
19
|
+
// All direction spacing
|
|
20
|
+
.#{$shortcut}-#{$name}{
|
|
21
|
+
#{$property}: $value !important;
|
|
22
22
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
23
|
+
// Physical and logical side spacing
|
|
24
|
+
@each $direction, $suffix in $spacing-directions{
|
|
25
|
+
.#{$shortcut}#{$suffix}-#{$name}{
|
|
26
|
+
#{$property}-#{$direction}: $value !important
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// x spacing
|
|
30
|
+
@if $spacing-horizontal != null{
|
|
31
|
+
.#{$shortcut}#{$spacing-horizontal}-#{$name}{
|
|
32
|
+
#{$property}-left: $value !important;
|
|
33
|
+
#{$property}-right: $value !important;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// y spacing
|
|
37
|
+
@if $spacing-vertical != null{
|
|
38
|
+
.#{$shortcut}#{$spacing-vertical}-#{$name}{
|
|
39
|
+
#{$property}-top: $value !important;
|
|
40
|
+
#{$property}-bottom: $value !important;
|
|
41
|
+
}
|
|
36
42
|
}
|
|
37
43
|
}
|
|
38
44
|
}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
@use "../abstracts" as *;
|
|
2
2
|
|
|
3
3
|
// Showing and hiding by the exact M3 window size classes.
|
|
4
|
-
// The
|
|
4
|
+
// The older small/med/xxl names remain aliases for compatibility.
|
|
5
5
|
|
|
6
6
|
.hide { display: none !important; }
|
|
7
7
|
|
|
8
|
+
// Hidden from sight, still announced: a visible label's longer twin, an
|
|
9
|
+
// icon-only control's name, a live region's text. Important for the same
|
|
10
|
+
// reason `.hide` is.
|
|
11
|
+
.visually-hidden,
|
|
12
|
+
.visually-hidden-focusable:not(:focus-within) { @include visually-hidden(true); }
|
|
13
|
+
|
|
8
14
|
.hide-on-compact-only,
|
|
9
15
|
.hide-on-small-only,
|
|
10
16
|
.hide-on-small-and-down {
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/ts/components/autocomplete.ts"],
|
|
4
|
-
"sourcesContent": ["import { Utils } from '../core/utils';\nimport { Menu, MenuOptions } from './menu';\nimport { Component, BaseOptions, InitElements, InitElement } from '../core/component';\n\nexport interface AutocompleteData {\n /**\n * A primitive value that can be converted to string.\n * If \"text\" is not provided, it will also be used as \"option text\" as well\n */\n id: string | number;\n /**\n * This optional attribute is used as \"display value\" for the current entry.\n * When provided, it will also be taken into consideration by the standard search function.\n */\n text?: string;\n /**\n * This optional attribute is used to provide a valid image URL to the current option.\n */\n image?: string;\n /**\n * Optional attributes which describes the option.\n */\n description?: string;\n}\n\nexport interface AutocompleteOptions extends BaseOptions {\n i18n: Partial<{\n loading: string;\n noResults: string;\n results: (count: number) => string;\n selected: (count: number) => string;\n }>;\n /**\n * Data object defining autocomplete options with\n * optional icon strings.\n */\n data: AutocompleteData[];\n /**\n * Flag which can be set if multiple values can be selected. The Result will be an Array.\n * @default false\n */\n isMultiSelect: boolean;\n /**\n * Callback for when autocompleted.\n */\n onAutocomplete: (entries: AutocompleteData[]) => void;\n /**\n * Minimum number of characters before autocomplete starts.\n * @default 1\n */\n minLength: number;\n /**\n * The height of the Menu which can be set via css-property.\n * @default '300px'\n */\n maxMenuHeight: string;\n /**\n * Function is called when the input text is altered and data can also be loaded asynchronously.\n * If the results are collected the items in the list can be updated via the function setMenuItems(collectedItems).\n * @param text Searched text.\n * @param autocomplete Current autocomplete instance.\n */\n onSearch: (text: string, autocomplete: Autocomplete) => void;\n /**\n * If true will render the key from each item directly as HTML.\n * User input MUST be properly sanitized first.\n * @default false\n */\n allowUnsafeHTML: boolean;\n /**\n * Pass options object to select menu initialization.\n * @default {}\n */\n menuOptions: Partial<MenuOptions>;\n /**\n * Predefined selected values\n */\n selected: number[] | string[];\n}\n\nconst _defaults: AutocompleteOptions = {\n i18n: {\n loading: 'Loading results.',\n noResults: 'No results.',\n results: count => `${count} ${count === 1 ? 'result' : 'results'} available.`,\n selected: count => `${count} ${count === 1 ? 'item' : 'items'} selected.`\n },\n data: [], // Autocomplete data set\n onAutocomplete: null, // Callback for when autocompleted\n menuOptions: {\n // Default menu options\n autoFocus: false,\n closeOnClick: false,\n coverTrigger: false\n },\n minLength: 1, // Min characters before autocomplete starts\n isMultiSelect: false,\n onSearch: (text: string, autocomplete: Autocomplete) => {\n const normSearch = text.toLocaleLowerCase();\n const data = autocomplete.options.data;\n autocomplete.setMenuItems(\n data.filter((option) =>\n option.id.toString().toLocaleLowerCase().includes(normSearch)\n || option.text?.toLocaleLowerCase().includes(normSearch)\n\n )\n );\n autocomplete.options.data = data;\n },\n maxMenuHeight: '300px',\n allowUnsafeHTML: false,\n selected: []\n};\n\nexport class Autocomplete extends Component<AutocompleteOptions> {\n declare el: HTMLInputElement;\n /** If the autocomplete is open. */\n isOpen: boolean;\n /** Number of matching autocomplete options. */\n count: number;\n /** Index of the current selected option. */\n activeIndex: number;\n private oldVal: string;\n private $active: HTMLElement | null;\n private _openTimer: ReturnType<typeof setTimeout> | undefined;\n private _statusInfo: HTMLElement;\n private _announcer: HTMLElement;\n\n /**\n * The active entry, for both the eye and the screen reader. The class alone\n * was invisible to assistive technology; aria-activedescendant on the input\n * is what reports the move.\n *\n * Deliberately does not touch aria-selected. Active and selected are two\n * different things - in a multi-select the checkboxes track real choices,\n * and folding the highlight into aria-selected would announce a committed\n * choice as unselected the moment the user arrowed past it.\n */\n private _setActive(item: HTMLElement | null) {\n this.$active?.classList.remove('active');\n this.$active = item;\n if (item) {\n item.classList.add('active');\n this.el.setAttribute('aria-activedescendant', item.id);\n } else {\n this.el.removeAttribute('aria-activedescendant');\n }\n }\n private _pointerDown: boolean;\n container: HTMLElement;\n /** Instance of the menu plugin for this autocomplete. */\n menu: Menu;\n static _keydown: boolean;\n selectedValues: AutocompleteData[];\n menuItems: AutocompleteData[];\n\n constructor(el: HTMLInputElement, options: Partial<AutocompleteOptions>) {\n super(el, options, Autocomplete);\n this.el['Expressive_Autocomplete'] = this;\n\n this.options = {\n ...Autocomplete.defaults,\n ...options,\n i18n: { ...Autocomplete.defaults.i18n, ...options?.i18n }\n };\n\n this.isOpen = false;\n this.count = 0;\n this.activeIndex = -1;\n this.oldVal = '';\n this.selectedValues = this.options.selected.map((id) => this.options.data.find(entry => entry.id === id) ?? { id });\n this.menuItems = this.options.data || [];\n this.$active = null;\n this._pointerDown = false;\n this._setupMenu();\n this._setupEventHandlers();\n }\n\n static get defaults(): AutocompleteOptions {\n return _defaults;\n }\n\n /**\n * Initializes instance of Autocomplete.\n * @param el HTML element.\n * @param options Component options.\n */\n static init(el: HTMLInputElement, options?: Partial<AutocompleteOptions>): Autocomplete;\n /**\n * Initializes instances of Autocomplete.\n * @param els HTML elements.\n * @param options Component options.\n */\n static init(\n els: InitElements<HTMLInputElement | InitElement>,\n options?: Partial<AutocompleteOptions>\n ): Autocomplete[];\n /**\n * Initializes instances of Autocomplete.\n * @param els HTML elements.\n * @param options Component options.\n */\n static init(\n els: HTMLInputElement | InitElements<HTMLInputElement | InitElement>,\n options: Partial<AutocompleteOptions> = {}\n ): Autocomplete | Autocomplete[] {\n return super.init(els, options, Autocomplete);\n }\n\n static getInstance(el: HTMLElement): Autocomplete {\n return el['Expressive_Autocomplete'];\n }\n\n /**\n * The three-dot loading indicator, parsed once and cloned thereafter.\n *\n * It is shown on every input change, and it used to be assigned as an\n * innerHTML string each time - re-running the HTML parser over the same\n * fixed markup on every keystroke.\n */\n private static _loadingTemplate: HTMLElement = null;\n\n private static _loadingIndicator(): HTMLElement {\n if (!Autocomplete._loadingTemplate) {\n const template = document.createElement('template');\n template.innerHTML = `<div style=\"height:100%;width:50px;\"><svg version=\"1.1\" id=\"L4\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\" viewBox=\"0 0 100 100\" enable-background=\"new 0 0 0 0\" xml:space=\"preserve\">\n <circle fill=\"#888c\" stroke=\"none\" cx=\"6\" cy=\"50\" r=\"6\"><animate attributeName=\"opacity\" dur=\"1s\" values=\"0;1;0\" repeatCount=\"indefinite\" begin=\"0.1\"/></circle>\n <circle fill=\"#888c\" stroke=\"none\" cx=\"26\" cy=\"50\" r=\"6\"><animate attributeName=\"opacity\" dur=\"1s\" values=\"0;1;0\" repeatCount=\"indefinite\" begin=\"0.2\"/></circle>\n <circle fill=\"#888c\" stroke=\"none\" cx=\"46\" cy=\"50\" r=\"6\"><animate attributeName=\"opacity\" dur=\"1s\" values=\"0;1;0\" repeatCount=\"indefinite\" begin=\"0.3\"/></circle>\n </svg></div>`;\n Autocomplete._loadingTemplate = template.content.firstElementChild as HTMLElement;\n }\n return Autocomplete._loadingTemplate.cloneNode(true) as HTMLElement;\n }\n\n destroy() {\n // open() defers menu.open() to a timer. Without cancelling it, destroying\n // an autocomplete that was opened in the same tick let the callback run\n // against a menu whose element had already been removed.\n if (this._openTimer !== undefined) {\n clearTimeout(this._openTimer);\n this._openTimer = undefined;\n }\n this._removeEventHandlers();\n this.menu.destroy();\n this._removeMenu();\n this._statusInfo.remove();\n this._announcer.remove();\n this.el['Expressive_Autocomplete'] = undefined;\n }\n\n _setupEventHandlers() {\n this.el.addEventListener('blur', this._handleInputBlur);\n this.el.addEventListener('keyup', this._handleInputKeyup);\n this.el.addEventListener('focus', this._handleInputFocus);\n this.el.addEventListener('keydown', this._handleInputKeydown);\n this.el.addEventListener('click', this._handleInputClick);\n // One pair, not two. These used to be a mouse pair plus a touch pair behind\n // a `window.ontouchstart` feature detect; a pointer event covers both, and\n // the detect covered nothing the browser does not report itself.\n this.container.addEventListener('pointerdown', this._handleContainerPointerDown);\n this.container.addEventListener('pointerup', this._handleContainerPointerUp);\n this.container.addEventListener('pointercancel', this._handleContainerPointerUp);\n }\n\n _removeEventHandlers() {\n this.el.removeEventListener('blur', this._handleInputBlur);\n this.el.removeEventListener('keyup', this._handleInputKeyup);\n this.el.removeEventListener('focus', this._handleInputFocus);\n this.el.removeEventListener('keydown', this._handleInputKeydown);\n this.el.removeEventListener('click', this._handleInputClick);\n this.container.removeEventListener('pointerdown', this._handleContainerPointerDown);\n this.container.removeEventListener('pointerup', this._handleContainerPointerUp);\n this.container.removeEventListener('pointercancel', this._handleContainerPointerUp);\n }\n\n _setupMenu() {\n this.container = document.createElement('menu');\n this.container.style.maxHeight = this.options.maxMenuHeight;\n this.container.id = `autocomplete-options-${Utils.guid()}`;\n this.container.classList.add('autocomplete-content');\n this.container.ariaExpanded = 'true';\n // An autocomplete is the textbook combobox, and this one already\n // implements the keyboard contract the roles promise - Up and Down move\n // the active entry, Enter commits it - so it is allowed to claim them.\n // It had none: the suggestions were an unlabelled list of <li>, and the\n // highlight moved with a class no assistive technology could see.\n this.container.setAttribute('role', 'listbox');\n this.el.setAttribute('role', 'combobox');\n this.el.setAttribute('aria-autocomplete', 'list');\n this.el.setAttribute('aria-controls', this.container.id);\n this.el.setAttribute('data-target', this.container.id);\n\n this.menuItems.forEach((menuItem) => {\n const itemElement = this._createMenuItem(menuItem);\n this.container.append(itemElement);\n });\n\n // ! Issue in Component Menu: _placeMenu moves dom-position\n this.el.parentElement.appendChild(this.container);\n\n // Initialize menu\n const menuOptions = {\n ...Autocomplete.defaults.menuOptions,\n ...this.options.menuOptions\n };\n // The wrapper is installed unconditionally: selecting the clicked entry is\n // how the autocomplete works, not an optional extra. Only the forwarding to\n // a user-supplied handler is conditional, and it hands over exactly what\n // Menu would have (the clicked `li`, called on the Menu instance).\n const userOnItemClick = menuOptions.onItemClick;\n menuOptions.onItemClick = (li) => {\n if (!li) return;\n const entryID = li.getAttribute('data-id');\n this.selectOption(entryID);\n if (typeof userOnItemClick === 'function') userOnItemClick.call(this.menu, li);\n };\n this.menu = Menu.init(this.el, menuOptions);\n this.el.setAttribute('aria-haspopup', 'listbox');\n\n // ! Workaround for Label: move label up again\n // TODO: Just use PopperJS in future!\n const label = this.el.parentElement.querySelector('label');\n if (label) this.el.after(label);\n\n // Sketchy removal of menu click handler\n this.el.removeEventListener('click', this.menu._handleClick);\n if(!this.options.isMultiSelect && !(this.options.selected.length === 0)) {\n const selectedValue = this.menuItems.filter((value) => value.id === this.selectedValues[0].id);\n this.el.value = selectedValue[0].text;\n }\n // Set Value if already set in HTML\n if (this.el.value) this.selectOption(this.el.value);\n // Add StatusInfo\n const div = document.createElement('div');\n div.classList.add('status-info');\n div.setAttribute('aria-hidden', 'true');\n div.setAttribute('style', 'position: absolute;right:0;top:0;');\n this.el.parentElement.appendChild(div);\n this._statusInfo = div;\n this._announcer = document.createElement('div');\n this._announcer.classList.add('autocomplete-status');\n this._announcer.setAttribute('role', 'status');\n this._announcer.setAttribute('aria-live', 'polite');\n this._announcer.setAttribute('aria-atomic', 'true');\n this.el.parentElement.appendChild(this._announcer);\n this._updateSelectedInfo();\n }\n\n _removeMenu() {\n this.container.ariaExpanded = 'false';\n this.container.parentNode.removeChild(this.container);\n }\n\n _handleInputBlur = () => {\n if (!this._pointerDown) {\n this.close();\n this._resetAutocomplete();\n }\n };\n\n _handleInputKeyup = (e: KeyboardEvent) => {\n if (e.type === 'keyup') Autocomplete._keydown = false;\n this.count = 0;\n const actualValue = this.el.value.toLocaleLowerCase();\n // Don't capture enter or arrow key usage.\n if (\n e.key === Utils.keys.ENTER ||\n e.key === Utils.keys.ARROW_UP ||\n e.key === Utils.keys.ARROW_DOWN ||\n e.key === Utils.keys.ESC ||\n e.key === 'Tab'\n )\n return;\n // Check if the input isn't empty, and that focus arrived by keyboard -\n // which is what `:focus-visible` means, and used to be a global flag this\n // bundle maintained from four capture-phase document listeners.\n if (this.oldVal !== actualValue && this.el.matches(':focus-visible')) {\n this.open();\n }\n this._inputChangeDetection(actualValue);\n };\n\n _handleInputFocus = () => {\n this.count = 0;\n const actualValue = this.el.value.toLocaleLowerCase();\n this._inputChangeDetection(actualValue);\n };\n\n _inputChangeDetection = (value: string) => {\n if (!this.options.isMultiSelect && this.selectedValues.length && this.el.value !== (this.selectedValues[0].text || String(this.selectedValues[0].id))) {\n this.selectedValues = [];\n }\n // Value has changed!\n if (this.oldVal !== value) {\n this._setStatusLoading();\n this.options.onSearch(this.el.value, this);\n }\n // Reset Single-Select when Input cleared\n if (!this.options.isMultiSelect && this.el.value.length === 0) {\n this.selectedValues = [];\n this._triggerChanged();\n }\n this.oldVal = value;\n };\n\n _handleInputKeydown = (e: KeyboardEvent) => {\n Autocomplete._keydown = true;\n if (e.key === Utils.keys.ESC || e.key === 'Tab') {\n this.close();\n this._resetCurrentElementPosition();\n return;\n }\n // Arrow keys and enter key usage\n const numItems = this.container.querySelectorAll('li').length;\n // select element on Enter\n if (e.key === Utils.keys.ENTER && this.activeIndex >= 0) {\n const liElement = this.container.querySelectorAll('li')[this.activeIndex];\n if (liElement) {\n this.selectOption(liElement.getAttribute('data-id'));\n e.preventDefault();\n }\n return;\n }\n // Capture up and down key\n if (e.key === Utils.keys.ARROW_UP || e.key === Utils.keys.ARROW_DOWN) {\n e.preventDefault();\n if (e.key === Utils.keys.ARROW_UP && this.activeIndex > 0) this.activeIndex--;\n if (e.key === Utils.keys.ARROW_DOWN && this.activeIndex < numItems - 1)\n this.activeIndex++;\n this._setActive(null);\n if (this.activeIndex >= 0) {\n this._setActive(this.container.querySelectorAll('li')[this.activeIndex]);\n // Focus selected\n this.container.children[this.activeIndex].scrollIntoView({\n behavior: 'smooth',\n block: 'nearest',\n inline: 'nearest'\n });\n }\n }\n };\n\n _handleInputClick = () => {\n this.open();\n };\n\n // The flag says \"a press is in flight inside the option list\", so that a blur\n // caused by that press does not close the list out from under it. Without the\n // cancel half, a cancelled gesture left the flag set and the next blur could\n // not close the list at all.\n _handleContainerPointerDown = (e: PointerEvent) => {\n if (!e.isPrimary) return;\n if (e.pointerType === 'mouse' && e.button !== 0) return;\n this._pointerDown = true;\n };\n\n _handleContainerPointerUp = () => {\n this._pointerDown = false;\n };\n\n _resetCurrentElementPosition() {\n this.activeIndex = -1;\n this._setActive(null);\n }\n\n _resetAutocomplete() {\n this.container.replaceChildren();\n this._resetCurrentElementPosition();\n this.oldVal = null;\n this.isOpen = false;\n this._pointerDown = false;\n }\n\n _highlightPartialText(input: string, label: string) {\n const start = label.toLocaleLowerCase().indexOf('' + input.toLocaleLowerCase() + '');\n const end = start + input.length - 1;\n //custom filters may return results where the string does not match any part\n if (start == -1 || end == -1) {\n return [label, '', ''];\n }\n return [label.slice(0, start), label.slice(start, end + 1), label.slice(end + 1)];\n }\n\n _createMenuItem(entry: AutocompleteData) {\n const item = document.createElement('li');\n item.id = `autocomplete-option-${Utils.guid()}`;\n item.setAttribute('role', 'option');\n // role=option promises a selection state on every entry, not just the\n // chosen one - and it has to be the *real* one. A multi-select entry that\n // is already committed is selected whether or not it is the highlighted\n // row.\n const isSelected = this.selectedValues.some((sel) => sel.id === entry.id);\n item.setAttribute('aria-selected', isSelected ? 'true' : 'false');\n item.setAttribute('data-id', <string>entry.id);\n item.setAttribute(\n 'style',\n 'display:grid; grid-auto-flow: column; user-select: none; align-items: center;'\n );\n item.tabIndex = -1;\n // Checkbox\n if (this.options.isMultiSelect) {\n const selection = document.createElement('div');\n selection.classList.add('item-selection');\n selection.style.textAlign = 'center';\n const checkbox = document.createElement('input');\n checkbox.type = 'checkbox';\n checkbox.tabIndex = -1;\n checkbox.checked = isSelected;\n const spacer = document.createElement('span');\n spacer.style.paddingLeft = '21px';\n selection.append(checkbox, spacer);\n item.appendChild(selection);\n }\n // Image\n if (entry.image) {\n const img = document.createElement('img');\n img.classList.add('circle');\n img.src = entry.image;\n item.appendChild(img);\n }\n\n // Text\n const inputText = this.el.value.toLocaleLowerCase();\n const parts = this._highlightPartialText(inputText, (entry.text || entry.id).toString());\n const div = document.createElement('div');\n div.setAttribute('style', 'line-height:1.2;font-weight:500;');\n if (this.options.allowUnsafeHTML) {\n div.innerHTML = parts[0] + '<span class=\"highlight\">' + parts[1] + '</span>' + parts[2];\n } else {\n div.appendChild(document.createTextNode(parts[0]));\n if (parts[1]) {\n const highlight = document.createElement('span');\n highlight.textContent = parts[1];\n highlight.classList.add('highlight');\n div.appendChild(highlight);\n div.appendChild(document.createTextNode(parts[2]));\n }\n }\n\n const itemText = document.createElement('div');\n itemText.classList.add('item-text');\n itemText.setAttribute('style', 'padding:5px;overflow:hidden;');\n item.appendChild(itemText);\n item.querySelector('.item-text').appendChild(div);\n // Description\n if (\n typeof entry.description === 'string' ||\n (typeof entry.description === 'number' && !isNaN(entry.description))\n ) {\n const description = document.createElement('small');\n description.setAttribute(\n 'style',\n 'line-height:1.3;color:grey;white-space:nowrap;text-overflow:ellipsis;display:block;width:90%;overflow:hidden;'\n );\n description.innerText = entry.description;\n item.querySelector('.item-text').appendChild(description);\n }\n // Set Grid\n const getGridConfig = () => {\n if (this.options.isMultiSelect) {\n if (entry.image) return '40px min-content auto'; // cb-img-txt\n return '40px auto'; // cb-txt\n }\n if (entry.image) return 'min-content auto'; // img-txt\n return 'auto'; // txt\n };\n item.style.gridTemplateColumns = getGridConfig();\n return item;\n }\n\n _renderMenu() {\n this._resetAutocomplete();\n // Check if Data is empty\n if (this.menuItems.length === 0) {\n this.menuItems = this.selectedValues; // Show selected Items\n }\n for (let i = 0; i < this.menuItems.length; i++) {\n const item = this._createMenuItem(this.menuItems[i]);\n this.container.append(item);\n }\n }\n\n _setStatusLoading() {\n const statusElement = this._statusInfo;\n if (statusElement) statusElement.replaceChildren(Autocomplete._loadingIndicator());\n this._announce(this.options.i18n.loading);\n }\n\n private _announce(message: string) {\n if (!this._announcer) return;\n const text = this.el.matches(':focus') && this.el.value.length >= this.options.minLength ? message : '';\n if (this._announcer.textContent !== text) this._announcer.textContent = text;\n }\n\n _updateSelectedInfo() {\n const statusElement = this._statusInfo;\n if (statusElement) {\n if (this.options.isMultiSelect)\n statusElement.textContent = this.selectedValues.length.toString();\n else statusElement.replaceChildren();\n }\n }\n\n _refreshInputText() {\n if (this.selectedValues.length === 1) {\n const entry = this.selectedValues[0];\n this.el.value = entry.text || <string>entry.id; // Write Text to Input\n }\n }\n\n _triggerChanged() {\n this.el.dispatchEvent(new Event('change'));\n // Trigger Autocomplete Event\n if (typeof this.options.onAutocomplete === 'function')\n this.options.onAutocomplete.call(this, this.selectedValues);\n }\n\n /**\n * Show autocomplete.\n */\n open = () => {\n const inputText = this.el.value.toLocaleLowerCase();\n this._resetAutocomplete();\n if (inputText.length >= this.options.minLength) {\n this.isOpen = true;\n this._renderMenu();\n this._announce(this.menuItems.length ? this.options.i18n.results(this.menuItems.length) : this.options.i18n.noResults);\n }\n // Open menu\n if (!this.menu.isOpen) {\n // Cancel first: two open() calls before the callback fires would leave\n // the earlier timer untracked, and destroy() can only cancel the one it\n // knows about.\n if (this._openTimer !== undefined) clearTimeout(this._openTimer);\n this._openTimer = setTimeout(() => {\n this._openTimer = undefined;\n this.menu.open();\n }, 0); // TODO: why?\n } else this.menu.recalculateDimensions(); // Recalculate menu when its already open\n };\n\n /**\n * Hide autocomplete.\n */\n close = () => {\n if (this._announcer) this._announcer.textContent = '';\n if (this._openTimer !== undefined) {\n clearTimeout(this._openTimer);\n this._openTimer = undefined;\n }\n this.isOpen = false;\n this.menu.close();\n };\n\n /**\n * Updates the visible or selectable items shown in the menu.\n * @param menuItems Items to be available.\n * @param selected Selected item ids\n * @param open Option to conditionally open menu\n */\n setMenuItems(menuItems: AutocompleteData[], selected: number[] | string[] = null, open: boolean = true) {\n if (this.el['Expressive_Autocomplete'] !== this) return;\n const resultCount = menuItems.length;\n this.menuItems = menuItems;\n this.options.data = menuItems;\n if (selected) {\n this.selectedValues = this.menuItems.filter(\n (item) => !(selected.indexOf(<never>item.id) === -1)\n );\n }\n if (this.options.isMultiSelect) {\n this._renderMenu();\n } else {\n this._refreshInputText();\n }\n if (open) this.open();\n this._updateSelectedInfo();\n this._announce(open ? resultCount ? this.options.i18n.results(resultCount) : this.options.i18n.noResults : '');\n this._triggerChanged();\n }\n\n /**\n * Select a specific autocomplete option via id-property.\n * @param id The id of a data-entry.\n */\n selectOption(id: number | string) {\n const entry = this.menuItems.find((item) => item.id == id);\n if (!entry) return;\n // Toggle Checkbox\n /* const li = this.container.querySelector('li[data-id=\"' + id + '\"]');\n if (!li) return;*/\n if (this.options.isMultiSelect) {\n /* const checkbox = <HTMLInputElement | null>li.querySelector('input[type=\"checkbox\"]');\n checkbox.checked = !checkbox.checked;*/\n if (!(this.selectedValues.filter(\n (selectedEntry) => selectedEntry.id === entry.id\n ).length >= 1)) this.selectedValues.push(entry);\n else this.selectedValues = this.selectedValues.filter(\n (selectedEntry) => selectedEntry.id !== entry.id\n );\n this._renderMenu();\n this.el.focus();\n } else {\n // Single-Select\n this.selectedValues = [entry];\n this._refreshInputText();\n this._resetAutocomplete();\n this.close();\n }\n this._updateSelectedInfo();\n if (this.options.isMultiSelect) this._announce(this.options.i18n.selected(this.selectedValues.length));\n this._triggerChanged();\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|