@limetech/lime-elements 39.45.3 → 40.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/cjs/lime-elements.cjs.js +1 -1
- package/dist/cjs/limel-action-bar_3.cjs.entry.js +1 -1
- package/dist/cjs/limel-ai-avatar.cjs.entry.js +1 -1
- package/dist/cjs/limel-callout.cjs.entry.js +1 -1
- package/dist/cjs/limel-chart.cjs.entry.js +1 -1
- package/dist/cjs/limel-chip-set.cjs.entry.js +1 -1
- package/dist/cjs/limel-chip_2.cjs.entry.js +1 -1
- package/dist/cjs/limel-code-diff.cjs.entry.js +1 -1
- package/dist/cjs/limel-code-editor.cjs.entry.js +1 -1
- package/dist/cjs/limel-collapsible-section.cjs.entry.js +1 -1
- package/dist/cjs/limel-drag-handle.cjs.entry.js +1 -1
- package/dist/cjs/limel-email-viewer.cjs.entry.js +1 -1
- package/dist/cjs/limel-file-viewer.cjs.entry.js +1 -1
- package/dist/cjs/limel-file.cjs.entry.js +1 -1
- package/dist/cjs/limel-flatpickr-adapter.cjs.entry.js +1 -1
- package/dist/cjs/limel-list-item.cjs.entry.js +1 -1
- package/dist/cjs/limel-picker.cjs.entry.js +1 -1
- package/dist/cjs/limel-profile-picture.cjs.entry.js +1 -1
- package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js +40 -40
- package/dist/cjs/limel-slider.cjs.entry.js +140 -16
- package/dist/cjs/limel-snackbar.cjs.entry.js +1 -1
- package/dist/cjs/limel-table.cjs.entry.js +1 -1
- package/dist/cjs/limel-text-editor-link-menu.cjs.entry.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/{translations-Bnw00bkf.js → translations-Do_D3pxu.js} +39 -2
- package/dist/collection/components/slider/slider.css +95 -0
- package/dist/collection/components/slider/slider.js +174 -21
- package/dist/collection/global/translations.js +15 -2
- package/dist/collection/translations/da.js +3 -0
- package/dist/collection/translations/de.js +3 -0
- package/dist/collection/translations/en.js +3 -0
- package/dist/collection/translations/fi.js +3 -0
- package/dist/collection/translations/fr.js +3 -0
- package/dist/collection/translations/nl.js +3 -0
- package/dist/collection/translations/no.js +3 -0
- package/dist/collection/translations/sv.js +3 -0
- package/dist/esm/lime-elements.js +1 -1
- package/dist/esm/limel-action-bar_3.entry.js +1 -1
- package/dist/esm/limel-ai-avatar.entry.js +1 -1
- package/dist/esm/limel-callout.entry.js +1 -1
- package/dist/esm/limel-chart.entry.js +1 -1
- package/dist/esm/limel-chip-set.entry.js +1 -1
- package/dist/esm/limel-chip_2.entry.js +1 -1
- package/dist/esm/limel-code-diff.entry.js +1 -1
- package/dist/esm/limel-code-editor.entry.js +1 -1
- package/dist/esm/limel-collapsible-section.entry.js +1 -1
- package/dist/esm/limel-drag-handle.entry.js +1 -1
- package/dist/esm/limel-email-viewer.entry.js +1 -1
- package/dist/esm/limel-file-viewer.entry.js +1 -1
- package/dist/esm/limel-file.entry.js +1 -1
- package/dist/esm/limel-flatpickr-adapter.entry.js +1 -1
- package/dist/esm/limel-list-item.entry.js +1 -1
- package/dist/esm/limel-picker.entry.js +1 -1
- package/dist/esm/limel-profile-picture.entry.js +1 -1
- package/dist/esm/limel-prosemirror-adapter.entry.js +40 -40
- package/dist/esm/limel-slider.entry.js +140 -16
- package/dist/esm/limel-snackbar.entry.js +1 -1
- package/dist/esm/limel-table.entry.js +1 -1
- package/dist/esm/limel-text-editor-link-menu.entry.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{translations-Cb9R_zmF.js → translations-DgqE77nk.js} +39 -2
- package/dist/lime-elements/lime-elements.esm.js +1 -1
- package/dist/lime-elements/{p-84526b93.entry.js → p-3e316685.entry.js} +1 -1
- package/dist/lime-elements/{p-c8116a01.entry.js → p-565f688a.entry.js} +1 -1
- package/dist/lime-elements/{p-aa080a8f.entry.js → p-5dde5d72.entry.js} +1 -1
- package/dist/lime-elements/{p-31713caf.entry.js → p-5e432a44.entry.js} +1 -1
- package/dist/lime-elements/{p-4a09fb2e.entry.js → p-62a25deb.entry.js} +1 -1
- package/dist/lime-elements/{p-8aa4a38e.entry.js → p-72a1d432.entry.js} +1 -1
- package/dist/lime-elements/{p-9a04a686.entry.js → p-83bdbaf7.entry.js} +1 -1
- package/dist/lime-elements/{p-ca0b86ee.entry.js → p-8c3798ee.entry.js} +1 -1
- package/dist/lime-elements/{p-8aeeeb53.entry.js → p-8cf79fa1.entry.js} +1 -1
- package/dist/lime-elements/{p-7487d65d.entry.js → p-9ed9d0de.entry.js} +1 -1
- package/dist/lime-elements/p-DgqE77nk.js +1 -0
- package/dist/lime-elements/{p-2284caa7.entry.js → p-a6500046.entry.js} +1 -1
- package/dist/lime-elements/{p-e545c9e8.entry.js → p-b04c6602.entry.js} +1 -1
- package/dist/lime-elements/{p-d97df2cd.entry.js → p-b4b43404.entry.js} +1 -1
- package/dist/lime-elements/p-b6528083.entry.js +1 -0
- package/dist/lime-elements/{p-6722e6e2.entry.js → p-cafebc7d.entry.js} +1 -1
- package/dist/lime-elements/{p-2f223e46.entry.js → p-cdcd9880.entry.js} +1 -1
- package/dist/lime-elements/{p-2e5d5e79.entry.js → p-dd116bb1.entry.js} +1 -1
- package/dist/lime-elements/{p-d7bb4310.entry.js → p-dda63b8b.entry.js} +1 -1
- package/dist/lime-elements/{p-7f7e2180.entry.js → p-e8783848.entry.js} +1 -1
- package/dist/lime-elements/{p-19c81ded.entry.js → p-eeddce38.entry.js} +1 -1
- package/dist/lime-elements/{p-9ae7d11b.entry.js → p-f53d8bda.entry.js} +1 -1
- package/dist/lime-elements/{p-03fd2181.entry.js → p-fa4edcf5.entry.js} +1 -1
- package/dist/types/components/slider/slider.d.ts +67 -4
- package/dist/types/components.d.ts +25 -10
- package/dist/types/translations/da.d.ts +3 -0
- package/dist/types/translations/de.d.ts +3 -0
- package/dist/types/translations/en.d.ts +3 -0
- package/dist/types/translations/fi.d.ts +3 -0
- package/dist/types/translations/fr.d.ts +3 -0
- package/dist/types/translations/nl.d.ts +3 -0
- package/dist/types/translations/no.d.ts +3 -0
- package/dist/types/translations/sv.d.ts +3 -0
- package/package.json +7 -7
- package/dist/lime-elements/p-Cb9R_zmF.js +0 -1
- package/dist/lime-elements/p-ee58f0b4.entry.js +0 -1
|
@@ -241,8 +241,10 @@
|
|
|
241
241
|
border-radius: 1.25rem;
|
|
242
242
|
padding: 0 0.375rem;
|
|
243
243
|
height: 1.25rem;
|
|
244
|
+
min-width: 1.25rem;
|
|
244
245
|
display: flex;
|
|
245
246
|
align-items: center;
|
|
247
|
+
justify-content: center;
|
|
246
248
|
white-space: nowrap;
|
|
247
249
|
color: rgb(var(--color-white));
|
|
248
250
|
font-size: 0.6875rem;
|
|
@@ -383,6 +385,99 @@ input[type=range] {
|
|
|
383
385
|
color: var(--limel-notched-outline-label-color, rgb(var(--contrast-1200)));
|
|
384
386
|
}
|
|
385
387
|
|
|
388
|
+
:host(.has-clear-button) div[slot=content] {
|
|
389
|
+
padding-right: calc(1rem + 0.25rem);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
:host(.is-unset) .track .active {
|
|
393
|
+
width: 0;
|
|
394
|
+
}
|
|
395
|
+
:host(.is-unset) .thumb {
|
|
396
|
+
left: 50%;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
button.clear-button {
|
|
400
|
+
appearance: none;
|
|
401
|
+
background: none;
|
|
402
|
+
border: none;
|
|
403
|
+
padding: 0;
|
|
404
|
+
margin: 0;
|
|
405
|
+
font: inherit;
|
|
406
|
+
color: inherit;
|
|
407
|
+
text-align: inherit;
|
|
408
|
+
}
|
|
409
|
+
button.clear-button:focus {
|
|
410
|
+
outline: none;
|
|
411
|
+
}
|
|
412
|
+
button.clear-button:focus-visible {
|
|
413
|
+
outline: none;
|
|
414
|
+
box-shadow: var(--shadow-depth-8-focused);
|
|
415
|
+
}
|
|
416
|
+
button.clear-button:not([disabled]) {
|
|
417
|
+
transition: color var(--limel-clickable-transition-speed, 0.4s) ease, background-color var(--limel-clickable-transition-speed, 0.4s) ease, box-shadow var(--limel-clickable-transform-speed, 0.4s) ease, transform var(--limel-clickable-transform-speed, 0.4s) var(--limel-clickable-transform-timing-function, ease);
|
|
418
|
+
cursor: pointer;
|
|
419
|
+
color: rgb(var(--contrast-1100));
|
|
420
|
+
background-color: rgba(var(--contrast-700), 0.6);
|
|
421
|
+
}
|
|
422
|
+
button.clear-button:not([disabled]):hover, button.clear-button:not([disabled]):focus, button.clear-button:not([disabled]):focus-visible {
|
|
423
|
+
will-change: color, background-color, box-shadow, transform;
|
|
424
|
+
}
|
|
425
|
+
button.clear-button:not([disabled]):hover, button.clear-button:not([disabled]):focus-visible {
|
|
426
|
+
transform: translate3d(0, 0.01rem, 0);
|
|
427
|
+
color: rgb(var(--contrast-100));
|
|
428
|
+
background-color: rgb(var(--contrast-1000));
|
|
429
|
+
}
|
|
430
|
+
button.clear-button:not([disabled]):hover {
|
|
431
|
+
box-shadow: var(--button-shadow-hovered);
|
|
432
|
+
}
|
|
433
|
+
button.clear-button:not([disabled]):active {
|
|
434
|
+
--limel-clickable-transform-timing-function: cubic-bezier(
|
|
435
|
+
0.83,
|
|
436
|
+
-0.15,
|
|
437
|
+
0.49,
|
|
438
|
+
1.16
|
|
439
|
+
);
|
|
440
|
+
transform: translate3d(0, 0.05rem, 0);
|
|
441
|
+
box-shadow: var(--button-shadow-pressed);
|
|
442
|
+
}
|
|
443
|
+
button.clear-button:not([disabled]):hover, button.clear-button:not([disabled]):active {
|
|
444
|
+
--limel-clickable-transition-speed: 0.2s;
|
|
445
|
+
--limel-clickable-transform-speed: 0.16s;
|
|
446
|
+
}
|
|
447
|
+
button.clear-button:not([disabled]):focus-visible {
|
|
448
|
+
background-color: rgb(var(--contrast-1000));
|
|
449
|
+
}
|
|
450
|
+
button.clear-button {
|
|
451
|
+
position: absolute;
|
|
452
|
+
inset: 0.75rem 0 0 auto;
|
|
453
|
+
display: flex;
|
|
454
|
+
align-items: center;
|
|
455
|
+
justify-content: center;
|
|
456
|
+
height: 1rem;
|
|
457
|
+
width: 1rem;
|
|
458
|
+
border-radius: 50%;
|
|
459
|
+
}
|
|
460
|
+
button.clear-button svg {
|
|
461
|
+
width: calc(1rem - 0.25rem);
|
|
462
|
+
height: calc(1rem - 0.25rem);
|
|
463
|
+
fill: currentColor;
|
|
464
|
+
}
|
|
465
|
+
button.clear-button:before {
|
|
466
|
+
content: "";
|
|
467
|
+
position: absolute;
|
|
468
|
+
inset: 0 auto 0 0;
|
|
469
|
+
margin: auto;
|
|
470
|
+
height: 0.125rem;
|
|
471
|
+
width: 0.25rem;
|
|
472
|
+
background-color: rgba(var(--contrast-700), 0.6);
|
|
473
|
+
transform: translate(-100%, 0);
|
|
474
|
+
}
|
|
475
|
+
button.clear-button[disabled] {
|
|
476
|
+
color: rgb(var(--contrast-1000));
|
|
477
|
+
background-color: rgb(var(--contrast-600));
|
|
478
|
+
cursor: not-allowed;
|
|
479
|
+
}
|
|
480
|
+
|
|
386
481
|
:host(limel-slider:focus),
|
|
387
482
|
:host(limel-slider:focus-visible),
|
|
388
483
|
:host(limel-slider:focus-within) {
|
|
@@ -1,12 +1,25 @@
|
|
|
1
1
|
import { h, Host, } from "@stencil/core";
|
|
2
2
|
import { getPercentageClass } from "./get-percentage-class";
|
|
3
3
|
import { createRandomString } from "../../util/random-string";
|
|
4
|
+
import translate from "../../global/translations";
|
|
4
5
|
const DEFAULT_FACTOR = 1;
|
|
5
6
|
const DEFAULT_MAX_VALUE = 100;
|
|
6
7
|
const DEFAULT_MIN_VALUE = 0;
|
|
7
8
|
const MAX_VISIBLE_STEP_DOTS = 20;
|
|
9
|
+
/**
|
|
10
|
+
* Whether the slider holds a value at all. `Number.isFinite` is typed
|
|
11
|
+
* `(number: unknown) => boolean`, so it tests the right thing but narrows
|
|
12
|
+
* nothing; this does, which lets the unset check double as proof that what
|
|
13
|
+
* remains is a number the arithmetic can use. `null`, `undefined` and `NaN`
|
|
14
|
+
* all mean unset.
|
|
15
|
+
* @param value - the slider's `value` prop, which may not be a number.
|
|
16
|
+
*/
|
|
17
|
+
const isSetValue = (value) => {
|
|
18
|
+
return Number.isFinite(value);
|
|
19
|
+
};
|
|
8
20
|
/**
|
|
9
21
|
* @exampleComponent limel-example-slider-basic
|
|
22
|
+
* @exampleComponent limel-example-slider-unset
|
|
10
23
|
* @exampleComponent limel-example-slider-multiplier
|
|
11
24
|
* @exampleComponent limel-example-slider-multiplier-percentage-colors
|
|
12
25
|
* @exampleComponent limel-example-slider-unit
|
|
@@ -36,6 +49,9 @@ export class Slider {
|
|
|
36
49
|
this.factor = DEFAULT_FACTOR;
|
|
37
50
|
/**
|
|
38
51
|
* Set to `true` to indicate that the slider is required.
|
|
52
|
+
* A required slider does not offer the clear button, since a required
|
|
53
|
+
* value cannot be unset. It can still be initialized unset (with a
|
|
54
|
+
* non-finite `value`) to prompt the user to make a choice.
|
|
39
55
|
*/
|
|
40
56
|
this.required = false;
|
|
41
57
|
/**
|
|
@@ -52,6 +68,10 @@ export class Slider {
|
|
|
52
68
|
* Unit to display next to the value
|
|
53
69
|
*/
|
|
54
70
|
this.unit = '';
|
|
71
|
+
/**
|
|
72
|
+
* Defines the language for translations of the accessible labels.
|
|
73
|
+
*/
|
|
74
|
+
this.language = 'en';
|
|
55
75
|
/**
|
|
56
76
|
* The maximum value allowed
|
|
57
77
|
*/
|
|
@@ -60,6 +80,37 @@ export class Slider {
|
|
|
60
80
|
* The minimum value allowed
|
|
61
81
|
*/
|
|
62
82
|
this.valuemin = DEFAULT_MIN_VALUE;
|
|
83
|
+
/**
|
|
84
|
+
* `true` while the value on display is one the consumer has been told
|
|
85
|
+
* about — either it came from the `value` prop, or it has been emitted on
|
|
86
|
+
* `change`. It is `false` from the moment the slider becomes unset until a
|
|
87
|
+
* value is committed again.
|
|
88
|
+
*
|
|
89
|
+
* The native input always holds a value, so while unset it rests at the
|
|
90
|
+
* midpoint. A press that lands on that midpoint, or a drag that returns to
|
|
91
|
+
* it before releasing, leaves the input's value untouched and fires neither
|
|
92
|
+
* `input` nor `change`. Without this flag such an interaction is swallowed:
|
|
93
|
+
* the slider either stays unset, or shows a number the consumer never
|
|
94
|
+
* received.
|
|
95
|
+
*/
|
|
96
|
+
this.valueIsCommitted = false;
|
|
97
|
+
this.syncStateFromValue = () => {
|
|
98
|
+
const value = this.value;
|
|
99
|
+
if (!isSetValue(value)) {
|
|
100
|
+
this.enterUnsetState();
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
this.isUnset = false;
|
|
104
|
+
this.valueIsCommitted = true;
|
|
105
|
+
this.displayValue = this.multiplyByFactor(value);
|
|
106
|
+
this.setPercentageClass(value);
|
|
107
|
+
};
|
|
108
|
+
this.enterUnsetState = () => {
|
|
109
|
+
this.isUnset = true;
|
|
110
|
+
this.valueIsCommitted = false;
|
|
111
|
+
this.displayValue = this.getRestingDisplayValue();
|
|
112
|
+
this.percentageClass = undefined;
|
|
113
|
+
};
|
|
63
114
|
this.renderStepDots = (min, max) => {
|
|
64
115
|
if (!this.step) {
|
|
65
116
|
return;
|
|
@@ -77,24 +128,87 @@ export class Slider {
|
|
|
77
128
|
}
|
|
78
129
|
return (h("limel-helper-line", { helperText: this.helperText, helperTextId: this.helperTextId, invalid: this.invalid }));
|
|
79
130
|
};
|
|
131
|
+
/**
|
|
132
|
+
* A required slider must hold a value, so it offers no way to clear it,
|
|
133
|
+
* and a readonly one cannot be edited at all. The styling needs the same
|
|
134
|
+
* answer to reserve room for the button, so both read it from here rather
|
|
135
|
+
* than each deriving it — the stylesheet cannot see a parsed prop, only
|
|
136
|
+
* the attribute string, and `required="false"` is a present attribute.
|
|
137
|
+
*/
|
|
138
|
+
this.hasClearButton = () => {
|
|
139
|
+
return !this.readonly && !this.required;
|
|
140
|
+
};
|
|
141
|
+
this.renderClearButton = () => {
|
|
142
|
+
if (!this.hasClearButton()) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const label = this.label
|
|
146
|
+
? translate.get('clear-value-of', this.language, {
|
|
147
|
+
label: this.label,
|
|
148
|
+
})
|
|
149
|
+
: translate.get('clear-value', this.language);
|
|
150
|
+
return (h("button", { type: "button", id: this.clearButtonId, class: "clear-button", "aria-label": label, onClick: this.handleClear, disabled: this.isUnset || this.disabled }, h("svg", { viewBox: "0 0 32 32", "aria-hidden": "true", focusable: "false" }, h("path", { d: "M7.219 5.781L5.78 7.22 14.563 16 5.78 24.781 7.22 26.22 16 17.437l8.781 8.782 1.438-1.438L17.437 16l8.782-8.781L24.78 5.78 16 14.563z" })), h("limel-tooltip", { elementId: this.clearButtonId, label: label })));
|
|
151
|
+
};
|
|
80
152
|
this.handleInput = (event) => {
|
|
81
153
|
event.stopPropagation();
|
|
82
154
|
const input = event.target;
|
|
83
155
|
const value = Number(input.value);
|
|
156
|
+
this.isUnset = false;
|
|
84
157
|
this.displayValue = value;
|
|
85
158
|
this.setPercentageClass(value / this.factor);
|
|
86
159
|
};
|
|
87
160
|
this.handleChange = (event) => {
|
|
88
161
|
event.stopPropagation();
|
|
89
162
|
const input = event.target;
|
|
90
|
-
|
|
163
|
+
this.commitValue(Number(input.value));
|
|
164
|
+
};
|
|
165
|
+
this.handleClick = (event) => {
|
|
166
|
+
if (this.valueIsCommitted) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
// The interaction is over and the value on display still hasn't
|
|
170
|
+
// reached the consumer, so the native input never fired a `change`.
|
|
171
|
+
// Commit what it holds. The click is left to bubble, so consumers
|
|
172
|
+
// listening for clicks still see it.
|
|
173
|
+
const input = event.target;
|
|
174
|
+
this.commitValue(Number(input.value));
|
|
175
|
+
};
|
|
176
|
+
/**
|
|
177
|
+
* Leaves the unset state and emits the value, keeping the rendered state
|
|
178
|
+
* and the emitted value in step so the two cannot diverge.
|
|
179
|
+
* @param displayValue - the value held by the native input, already
|
|
180
|
+
* multiplied by `factor`.
|
|
181
|
+
*/
|
|
182
|
+
this.commitValue = (displayValue) => {
|
|
91
183
|
const step = this.multiplyByFactor(this.step);
|
|
92
|
-
|
|
93
|
-
|
|
184
|
+
const min = this.multiplyByFactor(this.valuemin);
|
|
185
|
+
let value = displayValue;
|
|
186
|
+
// Steps are counted from `valuemin`, not from zero — a range of 1–5 in
|
|
187
|
+
// steps of 2 stops at 1, 3 and 5. Rounding against zero would push
|
|
188
|
+
// every one of those to the next even number, past `valuemax`.
|
|
189
|
+
if (!this.isMultipleOfStep(value - min, step)) {
|
|
190
|
+
value = min + this.roundToStep(value - min, step);
|
|
94
191
|
}
|
|
192
|
+
this.valueIsCommitted = true;
|
|
193
|
+
this.isUnset = false;
|
|
194
|
+
this.displayValue = value;
|
|
195
|
+
this.setPercentageClass(value / this.factor);
|
|
95
196
|
this.change.emit(value / this.factor);
|
|
96
197
|
};
|
|
198
|
+
this.handleClear = (event) => {
|
|
199
|
+
var _a;
|
|
200
|
+
event.stopPropagation();
|
|
201
|
+
this.enterUnsetState();
|
|
202
|
+
this.change.emit(null);
|
|
203
|
+
// Move focus to the slider itself so keyboard users can immediately
|
|
204
|
+
// set a new value, and so assistive tech announces the now-unset state
|
|
205
|
+
// instead of focus falling to the body when the button self-disables.
|
|
206
|
+
(_a = this.inputElement) === null || _a === void 0 ? void 0 : _a.focus();
|
|
207
|
+
};
|
|
97
208
|
this.getContainerClassList = () => {
|
|
209
|
+
return Object.assign({ 'is-unset': this.isUnset, 'has-clear-button': this.hasClearButton() }, this.getPercentageClassList());
|
|
210
|
+
};
|
|
211
|
+
this.getPercentageClassList = () => {
|
|
98
212
|
if (!this.percentageClass) {
|
|
99
213
|
return {};
|
|
100
214
|
}
|
|
@@ -105,12 +219,18 @@ export class Slider {
|
|
|
105
219
|
this.multiplyByFactor = (value) => {
|
|
106
220
|
return Math.round(value * this.factor);
|
|
107
221
|
};
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
222
|
+
/**
|
|
223
|
+
* The display value the thumb rests at while unset: the midpoint of the
|
|
224
|
+
* range, so both arrow-key directions are live (unlike anchoring at the
|
|
225
|
+
* minimum). Aligned to the step — native range inputs default to a step of
|
|
226
|
+
* 1 — so it matches a real input value and the first key press doesn't jump.
|
|
227
|
+
*/
|
|
228
|
+
this.getRestingDisplayValue = () => {
|
|
229
|
+
const min = this.multiplyByFactor(this.valuemin);
|
|
230
|
+
const max = this.multiplyByFactor(this.valuemax);
|
|
231
|
+
const midpoint = (min + max) / 2;
|
|
232
|
+
const step = this.step ? this.multiplyByFactor(this.step) : 1;
|
|
233
|
+
return min + Math.round((midpoint - min) / step) * step;
|
|
114
234
|
};
|
|
115
235
|
this.getFraction = () => {
|
|
116
236
|
const min = this.multiplyByFactor(this.valuemin);
|
|
@@ -134,10 +254,10 @@ export class Slider {
|
|
|
134
254
|
};
|
|
135
255
|
this.labelId = createRandomString();
|
|
136
256
|
this.helperTextId = createRandomString();
|
|
257
|
+
this.clearButtonId = createRandomString();
|
|
137
258
|
}
|
|
138
259
|
componentWillLoad() {
|
|
139
|
-
this.
|
|
140
|
-
this.setPercentageClass(this.getValue());
|
|
260
|
+
this.syncStateFromValue();
|
|
141
261
|
}
|
|
142
262
|
render() {
|
|
143
263
|
const min = this.multiplyByFactor(this.valuemin);
|
|
@@ -150,13 +270,18 @@ export class Slider {
|
|
|
150
270
|
if (this.disabled || this.readonly) {
|
|
151
271
|
inputProps.disabled = true;
|
|
152
272
|
}
|
|
153
|
-
return (h(Host, { key: '
|
|
273
|
+
return (h(Host, { key: 'eecd22982d9180f24f947fd2ab9af9a25e64647e', class: this.getContainerClassList() }, h("limel-notched-outline", { key: '848578a10d64a4af81e296c9f961e9be788484a7', labelId: this.labelId, label: this.label, required: this.required, invalid: this.invalid, disabled: this.disabled, readonly: this.readonly, hasValue: !this.isUnset, hasFloatingLabel: true }, h("div", { key: '7ad977107b79fc9ca416562d5c7905b4a962053c', slot: "content" }, h("div", { key: 'dcb137a44b5244e63a4c8a95341d3918dc65445c', class: "slider", style: { '--slider-fraction': `${fraction}` } }, h("input", Object.assign({ key: '73af46f062991f3c715d13c0f44b0fb9478dc37c', type: "range", min: min, max: max, value: this.displayValue, "aria-labelledby": this.labelId, "aria-describedby": this.helperText
|
|
154
274
|
? this.helperTextId
|
|
155
|
-
: undefined,
|
|
275
|
+
: undefined, "aria-valuetext": this.isUnset
|
|
276
|
+
? translate.get('value-not-set', this.language)
|
|
277
|
+
: undefined, ref: (el) => {
|
|
278
|
+
this.inputElement = el;
|
|
279
|
+
}, onInput: this.handleInput, onChange: this.handleChange, onClick: this.handleClick }, inputProps)), h("div", { key: 'e9fb2af7f43cc040c382930d336c8eb903bc0162', class: "track" }, h("div", { key: '2cec88a4b8c99296473bbd9b064bccd0a6450b8f', class: "active" }), this.renderStepDots(min, max)), h("div", { key: '5a090fb0528478450510ff0240e6b5499a177238', class: "thumb" }, h("div", { key: 'fde6792041312183af0328d9fc75d19d2553bf46', class: "knob" }), h("div", { key: 'de717ffa20723870bb27aa22e99fe9fe5ebdd563', class: "indicator", "aria-hidden": "true" }, this.isUnset
|
|
280
|
+
? '\u2194\uFE0E'
|
|
281
|
+
: this.displayValue))), h("div", { key: 'd0c38d092fecc4bf9690680d8541c8d658056f08', class: "range-labels" }, h("span", { key: '581387615da0cdaf105a568e02212f8bdd22eeb6', class: "min" }, this.multiplyByFactor(this.valuemin), this.unit), h("span", { key: '33c5673d8e56995bffdc35340381f2e87ae0918c', class: "max" }, this.multiplyByFactor(this.valuemax), this.unit)))), this.renderClearButton(), this.renderHelperLine()));
|
|
156
282
|
}
|
|
157
283
|
watchValue() {
|
|
158
|
-
this.
|
|
159
|
-
this.setPercentageClass(this.getValue());
|
|
284
|
+
this.syncStateFromValue();
|
|
160
285
|
}
|
|
161
286
|
static get is() { return "limel-slider"; }
|
|
162
287
|
static get encapsulation() { return "shadow"; }
|
|
@@ -282,7 +407,7 @@ export class Slider {
|
|
|
282
407
|
"optional": false,
|
|
283
408
|
"docs": {
|
|
284
409
|
"tags": [],
|
|
285
|
-
"text": "Set to `true` to indicate that the slider is required."
|
|
410
|
+
"text": "Set to `true` to indicate that the slider is required.\nA required slider does not offer the clear button, since a required\nvalue cannot be unset. It can still be initialized unset (with a\nnon-finite `value`) to prompt the user to make a choice."
|
|
286
411
|
},
|
|
287
412
|
"getter": false,
|
|
288
413
|
"setter": false,
|
|
@@ -350,11 +475,38 @@ export class Slider {
|
|
|
350
475
|
"attribute": "unit",
|
|
351
476
|
"defaultValue": "''"
|
|
352
477
|
},
|
|
478
|
+
"language": {
|
|
479
|
+
"type": "string",
|
|
480
|
+
"mutable": false,
|
|
481
|
+
"complexType": {
|
|
482
|
+
"original": "Languages",
|
|
483
|
+
"resolved": "\"da\" | \"de\" | \"en\" | \"fi\" | \"fr\" | \"nb\" | \"nl\" | \"no\" | \"sv\"",
|
|
484
|
+
"references": {
|
|
485
|
+
"Languages": {
|
|
486
|
+
"location": "import",
|
|
487
|
+
"path": "../date-picker/date.types",
|
|
488
|
+
"id": "src/components/date-picker/date.types.ts::Languages",
|
|
489
|
+
"referenceLocation": "Languages"
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
},
|
|
493
|
+
"required": false,
|
|
494
|
+
"optional": false,
|
|
495
|
+
"docs": {
|
|
496
|
+
"tags": [],
|
|
497
|
+
"text": "Defines the language for translations of the accessible labels."
|
|
498
|
+
},
|
|
499
|
+
"getter": false,
|
|
500
|
+
"setter": false,
|
|
501
|
+
"reflect": true,
|
|
502
|
+
"attribute": "language",
|
|
503
|
+
"defaultValue": "'en'"
|
|
504
|
+
},
|
|
353
505
|
"value": {
|
|
354
506
|
"type": "number",
|
|
355
507
|
"mutable": false,
|
|
356
508
|
"complexType": {
|
|
357
|
-
"original": "number",
|
|
509
|
+
"original": "number | null",
|
|
358
510
|
"resolved": "number",
|
|
359
511
|
"references": {}
|
|
360
512
|
},
|
|
@@ -362,7 +514,7 @@ export class Slider {
|
|
|
362
514
|
"optional": false,
|
|
363
515
|
"docs": {
|
|
364
516
|
"tags": [],
|
|
365
|
-
"text": "The value of the input"
|
|
517
|
+
"text": "The value of the input. Set it to `null` to leave the slider unset,\nwhich is also what the `change` event emits once the value is cleared.\nAny other value that is not a finite number \u2014 `undefined`, or `NaN` \u2014\nunsets the slider too."
|
|
366
518
|
},
|
|
367
519
|
"getter": false,
|
|
368
520
|
"setter": false,
|
|
@@ -433,7 +585,8 @@ export class Slider {
|
|
|
433
585
|
static get states() {
|
|
434
586
|
return {
|
|
435
587
|
"percentageClass": {},
|
|
436
|
-
"displayValue": {}
|
|
588
|
+
"displayValue": {},
|
|
589
|
+
"isUnset": {}
|
|
437
590
|
};
|
|
438
591
|
}
|
|
439
592
|
static get events() {
|
|
@@ -445,10 +598,10 @@ export class Slider {
|
|
|
445
598
|
"composed": true,
|
|
446
599
|
"docs": {
|
|
447
600
|
"tags": [],
|
|
448
|
-
"text": "Emitted when the value has been changed"
|
|
601
|
+
"text": "Emitted when the value has been changed.\nEmits `null` when the value has been cleared and the slider becomes\nunset, so handlers must account for a value that is not a number."
|
|
449
602
|
},
|
|
450
603
|
"complexType": {
|
|
451
|
-
"original": "number",
|
|
604
|
+
"original": "number | null",
|
|
452
605
|
"resolved": "number",
|
|
453
606
|
"references": {}
|
|
454
607
|
}
|
|
@@ -13,18 +13,31 @@ const allTranslations = {
|
|
|
13
13
|
fi: fi,
|
|
14
14
|
fr: fr,
|
|
15
15
|
no: no,
|
|
16
|
+
nb: no, // Norwegian Bokmål shares the Norwegian (`no`) translations
|
|
16
17
|
nl: nl,
|
|
17
18
|
sv: sv,
|
|
18
19
|
};
|
|
19
20
|
const REGEX = /\{\s*(\w+)\s*\}/g;
|
|
20
21
|
export class Translations {
|
|
21
22
|
get(key, language = 'en', params) {
|
|
22
|
-
|
|
23
|
+
var _a, _b;
|
|
24
|
+
// Fall back to English when the requested language has no translations.
|
|
25
|
+
// The `language` props are typed, but a custom element takes whatever
|
|
26
|
+
// string an attribute carries, so an unknown language must never make a
|
|
27
|
+
// component throw.
|
|
28
|
+
const languageTranslations = (_a = allTranslations[language]) !== null && _a !== void 0 ? _a : allTranslations.en;
|
|
29
|
+
// Fall back per key as well: a mapped language whose file is missing
|
|
30
|
+
// this one key would otherwise render the key itself as UI text.
|
|
31
|
+
const translation = (_b = languageTranslations[key]) !== null && _b !== void 0 ? _b : allTranslations.en[key];
|
|
23
32
|
if (!translation) {
|
|
24
33
|
return key;
|
|
25
34
|
}
|
|
26
35
|
return translation.replaceAll(REGEX, (match, mergeCodeKey) => {
|
|
27
|
-
|
|
36
|
+
var _a;
|
|
37
|
+
// Nullish, not falsy: `0` and `false` are values a caller can
|
|
38
|
+
// legitimately merge in, and `||` would leave the merge code
|
|
39
|
+
// itself in the string instead.
|
|
40
|
+
return String((_a = params === null || params === void 0 ? void 0 : params[mergeCodeKey]) !== null && _a !== void 0 ? _a : match);
|
|
28
41
|
});
|
|
29
42
|
}
|
|
30
43
|
}
|