@antadesign/anta 0.3.33 → 0.3.35
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/LICENSE.md +14 -1
- package/README.md +9 -0
- package/dist/anta_helpers.d.ts +46 -30
- package/dist/anta_helpers.js +66 -25
- package/dist/bundle.css +1 -1
- package/dist/bundle.js +2 -1353
- package/dist/components/Banner.d.ts +25 -40
- package/dist/components/Banner.js +15 -17
- package/dist/components/Breadcrumbs.d.ts +0 -1
- package/dist/components/Breadcrumbs.js +0 -1
- package/dist/components/Button.d.ts +2 -3
- package/dist/components/Button.js +1 -0
- package/dist/components/ButtonCopy.js +3 -2
- package/dist/components/Calendar.js +13 -13
- package/dist/components/Card.d.ts +9 -17
- package/dist/components/Card.js +50 -46
- package/dist/components/Dialog.d.ts +1 -0
- package/dist/components/Dialog.js +16 -10
- package/dist/components/Expander.d.ts +6 -21
- package/dist/components/Expander.js +24 -23
- package/dist/components/Icon.d.ts +8 -14
- package/dist/components/Input.d.ts +77 -96
- package/dist/components/Input.js +23 -27
- package/dist/components/InputAutocomplete.d.ts +29 -10
- package/dist/components/InputAutocomplete.js +25 -8
- package/dist/components/InputDate.d.ts +0 -1
- package/dist/components/InputDate.js +2 -3
- package/dist/components/InputTime.d.ts +10 -4
- package/dist/components/InputTime.js +20 -16
- package/dist/components/Loader.d.ts +2 -2
- package/dist/components/Menu.d.ts +5 -4
- package/dist/components/Menu.js +13 -8
- package/dist/components/MenuItem.js +1 -14
- package/dist/components/MenuItemCopy.js +2 -2
- package/dist/components/Panel.d.ts +3 -1
- package/dist/components/Panel.js +17 -11
- package/dist/components/Progress.d.ts +21 -23
- package/dist/components/Progress.js +13 -9
- package/dist/components/RadioGroup.js +6 -8
- package/dist/components/{select-parts.css → Select.css} +1 -1
- package/dist/components/Select.d.ts +53 -36
- package/dist/components/Select.js +53 -98
- package/dist/components/SelectFaceted.d.ts +7 -4
- package/dist/components/SelectFaceted.js +21 -10
- package/dist/components/Slider.d.ts +28 -11
- package/dist/components/Slider.js +20 -20
- package/dist/components/Steps.css +1 -1
- package/dist/components/Steps.d.ts +0 -1
- package/dist/components/Steps.js +1 -12
- package/dist/components/Tabs.d.ts +17 -20
- package/dist/components/Tabs.js +7 -9
- package/dist/components/Text.d.ts +55 -36
- package/dist/components/Text.js +35 -22
- package/dist/components/Title.d.ts +19 -27
- package/dist/components/Title.js +2 -1
- package/dist/components/Toaster.js +9 -2
- package/dist/components/Tooltip.d.ts +10 -15
- package/dist/components/copy-props.d.ts +14 -3
- package/dist/components/copy-props.js +14 -3
- package/dist/components/select-tree.d.ts +24 -0
- package/dist/components/select-tree.js +35 -0
- package/dist/element-base.d.ts +10 -0
- package/dist/element-base.js +15 -0
- package/dist/elements/a-avatar.css +1 -1
- package/dist/elements/a-avatar.js +2 -28
- package/dist/elements/a-banner.css +1 -1
- package/dist/elements/a-banner.d.ts +4 -1
- package/dist/elements/a-banner.js +22 -112
- package/dist/elements/a-breadcrumbs.d.ts +1 -0
- package/dist/elements/a-breadcrumbs.js +1 -0
- package/dist/elements/a-button.css +1 -1
- package/dist/elements/a-button.d.ts +10 -7
- package/dist/elements/a-button.js +18 -1
- package/dist/elements/a-calendar.d.ts +14 -13
- package/dist/elements/a-calendar.js +29 -24
- package/dist/elements/a-card.css +1 -1
- package/dist/elements/a-card.d.ts +0 -9
- package/dist/elements/a-card.js +0 -184
- package/dist/elements/a-checkbox.css +1 -1
- package/dist/elements/a-copy.css +1 -1
- package/dist/elements/a-copy.d.ts +1 -5
- package/dist/elements/a-copy.js +129 -108
- package/dist/elements/a-dialog.css +1 -1
- package/dist/elements/a-dialog.d.ts +1 -1
- package/dist/elements/a-dialog.js +68 -194
- package/dist/elements/a-expander.css +1 -1
- package/dist/elements/a-expander.d.ts +4 -30
- package/dist/elements/a-expander.js +85 -344
- package/dist/elements/a-icon.d.ts +5 -23
- package/dist/elements/a-icon.js +1 -2
- package/dist/elements/a-input-date.d.ts +1 -0
- package/dist/elements/a-input-date.js +1 -0
- package/dist/elements/a-input-time.css +1 -1
- package/dist/elements/a-input-time.d.ts +2 -1
- package/dist/elements/a-input-time.js +101 -168
- package/dist/elements/a-input.css +1 -1
- package/dist/elements/a-input.d.ts +10 -8
- package/dist/elements/a-input.js +155 -230
- package/dist/elements/a-loader.d.ts +5 -8
- package/dist/elements/a-loader.js +1 -2
- package/dist/elements/a-menu-item.css +1 -1
- package/dist/elements/a-menu-item.d.ts +5 -3
- package/dist/elements/a-menu-item.js +5 -1
- package/dist/elements/a-menu.css +1 -1
- package/dist/elements/a-menu.d.ts +5 -7
- package/dist/elements/a-menu.js +383 -299
- package/dist/elements/a-panel.css +1 -1
- package/dist/elements/a-panel.js +19 -37
- package/dist/elements/a-progress.css +1 -1
- package/dist/elements/a-progress.d.ts +0 -22
- package/dist/elements/a-progress.js +0 -100
- package/dist/elements/a-radio-group.d.ts +1 -1
- package/dist/elements/a-radio-group.js +6 -4
- package/dist/elements/a-select-faceted.d.ts +1 -0
- package/dist/elements/a-select-faceted.js +1 -0
- package/dist/elements/a-select.d.ts +1 -0
- package/dist/elements/a-select.js +1 -0
- package/dist/elements/a-slider.css +1 -1
- package/dist/elements/a-slider.d.ts +11 -3
- package/dist/elements/a-slider.js +244 -242
- package/dist/elements/a-steps.d.ts +1 -0
- package/dist/elements/a-steps.js +1 -0
- package/dist/elements/a-switch.css +1 -1
- package/dist/elements/a-tab.css +1 -1
- package/dist/elements/a-tabpanel.d.ts +2 -2
- package/dist/elements/a-tabpanel.js +13 -3
- package/dist/elements/a-tabs.css +1 -1
- package/dist/elements/a-tabs.d.ts +1 -1
- package/dist/elements/a-tabs.js +6 -4
- package/dist/elements/a-tag.css +1 -1
- package/dist/elements/a-tag.d.ts +1 -0
- package/dist/elements/a-tag.js +1 -0
- package/dist/elements/a-text.css +1 -1
- package/dist/elements/a-text.d.ts +6 -43
- package/dist/elements/a-text.js +110 -193
- package/dist/elements/a-title.css +1 -1
- package/dist/elements/a-title.d.ts +1 -0
- package/dist/elements/a-title.js +1 -0
- package/dist/elements/a-toast.css +1 -1
- package/dist/elements/a-toast.d.ts +10 -45
- package/dist/elements/a-toast.js +80 -66
- package/dist/elements/a-toaster.css +1 -1
- package/dist/elements/a-toaster.js +9 -44
- package/dist/elements/a-tooltip.css +1 -1
- package/dist/elements/a-tooltip.d.ts +1 -1
- package/dist/elements/a-tooltip.js +142 -136
- package/dist/elements/copy-behavior.d.ts +1 -1
- package/dist/elements/copy-behavior.js +21 -21
- package/dist/elements/index.d.ts +9 -3
- package/dist/elements/index.js +6 -6
- package/dist/elements/input-focus-modality.d.ts +15 -0
- package/dist/elements/input-focus-modality.js +44 -0
- package/dist/elements/input-trailing-actions.d.ts +5 -0
- package/dist/elements/input-trailing-actions.js +38 -0
- package/dist/elements/shadow-aria.d.ts +2 -0
- package/dist/elements/shadow-aria.js +2 -1
- package/dist/elements/value-input.d.ts +3 -0
- package/dist/elements/value-input.js +12 -0
- package/dist/general_types.d.ts +103 -96
- package/dist/index.d.ts +1 -1
- package/dist/input-events.d.ts +4 -0
- package/dist/input-events.js +15 -0
- package/dist/jsx-runtime.d.ts +70 -23
- package/dist/jsx-runtime.js +26 -19
- package/dist/native-event-props.d.ts +2 -0
- package/dist/native-event-props.js +10 -0
- package/dist/reset.css +1 -1
- package/dist/theme-antithesis.css +10 -1
- package/dist/theme-antune.css +1 -1
- package/docs/accessibility.md +17 -3
- package/docs/changelog.md +384 -2
- package/docs/comparison.md +2 -2
- package/docs/components/avatar.md +5 -0
- package/docs/components/banner.md +117 -187
- package/docs/components/breadcrumbs.md +9 -6
- package/docs/components/button.md +22 -0
- package/docs/components/card.md +74 -28
- package/docs/components/checkbox.md +9 -10
- package/docs/components/dialog.md +83 -32
- package/docs/components/expander.md +198 -435
- package/docs/components/icon.md +11 -17
- package/docs/components/input-autocomplete.md +152 -52
- package/docs/components/input-date.md +175 -148
- package/docs/components/input-time.md +81 -38
- package/docs/components/input.md +343 -349
- package/docs/components/loader.md +2 -1
- package/docs/components/menu.md +35 -6
- package/docs/components/panel.md +18 -0
- package/docs/components/progress.md +83 -49
- package/docs/components/radio.md +39 -43
- package/docs/components/select-faceted.md +54 -7
- package/docs/components/select.md +390 -386
- package/docs/components/slider.md +136 -19
- package/docs/components/steps.md +6 -3
- package/docs/components/switch.md +8 -9
- package/docs/components/tabs.md +110 -104
- package/docs/components/text.md +110 -86
- package/docs/components/title.md +47 -33
- package/docs/components/toaster.md +242 -84
- package/docs/components/tooltip.md +204 -113
- package/docs/install-config.md +461 -96
- package/docs/packages/plot.md +228 -143
- package/docs/theming.md +29 -13
- package/package.json +43 -4
- package/theme-antithesis-license.md +66 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { finiteNumber, HTMLElementBase, isModifiedNavigationKey } from "../anta_helpers";
|
|
2
2
|
import "./a-slider.css";
|
|
3
|
+
import { referencedElements } from "./shadow-aria";
|
|
4
|
+
import { upgradeValueProperties } from "./value-input";
|
|
3
5
|
const precisionOf = (value) => {
|
|
4
6
|
const exponent = value.toString().match(/(?:\.(\d+))?(?:e([+-]?\d+))?$/i);
|
|
5
7
|
return Math.max(0, (exponent?.[1]?.length ?? 0) - Number(exponent?.[2] ?? 0));
|
|
@@ -30,7 +32,9 @@ class ASliderElement extends HTMLElementBase {
|
|
|
30
32
|
"inverted",
|
|
31
33
|
"name",
|
|
32
34
|
"aria-label",
|
|
33
|
-
"aria-labelledby"
|
|
35
|
+
"aria-labelledby",
|
|
36
|
+
"aria-describedby",
|
|
37
|
+
"aria-description"
|
|
34
38
|
];
|
|
35
39
|
internals;
|
|
36
40
|
#control;
|
|
@@ -61,186 +65,45 @@ class ASliderElement extends HTMLElementBase {
|
|
|
61
65
|
#lastActiveThumb = 0;
|
|
62
66
|
#seeded = false;
|
|
63
67
|
#dirty = false;
|
|
68
|
+
// Match an accepted range request to the physical thumb that produced it.
|
|
69
|
+
#pendingRequest;
|
|
70
|
+
#endpointLabels = [];
|
|
71
|
+
#accessibilityDirty = true;
|
|
72
|
+
#accessibilityState;
|
|
73
|
+
#accessibilityReferences = [];
|
|
74
|
+
#accessibilityUnresolved = false;
|
|
64
75
|
#drag;
|
|
76
|
+
#onPointerDown = (event) => {
|
|
77
|
+
if (event.composedPath().includes(this.#control)) this.#beginDrag(event);
|
|
78
|
+
};
|
|
79
|
+
#onPointerMove = (event) => this.#moveDrag(event);
|
|
80
|
+
#onPointerEnd = (event) => this.#finishDrag(event);
|
|
81
|
+
#onKeyDown = (event) => this.#handleKeydown(event);
|
|
82
|
+
// Run the default action after consumer listeners on this host, including
|
|
83
|
+
// listeners added after connection. Ancestors may stop propagation.
|
|
84
|
+
#orderDefaultAction = (event) => {
|
|
85
|
+
const handler = event.type === "keydown" ? this.#onKeyDown : event.type === "pointerdown" ? this.#onPointerDown : this.#onPointerMove;
|
|
86
|
+
this.removeEventListener(event.type, handler);
|
|
87
|
+
this.addEventListener(event.type, handler);
|
|
88
|
+
};
|
|
65
89
|
get value() {
|
|
66
90
|
return Array.isArray(this.#value) ? [...this.#value] : this.#value;
|
|
67
91
|
}
|
|
68
92
|
set value(value) {
|
|
69
|
-
|
|
93
|
+
if (value == null || value === "") this.removeAttribute("value");
|
|
94
|
+
else this.setAttribute("value", serializeSliderValue(value));
|
|
70
95
|
}
|
|
71
96
|
get defaultValue() {
|
|
72
97
|
return parseSliderValue(this.getAttribute("defaultvalue"), this.#fallbackValue());
|
|
73
98
|
}
|
|
74
99
|
set defaultValue(value) {
|
|
75
|
-
|
|
100
|
+
if (value == null) this.removeAttribute("defaultvalue");
|
|
101
|
+
else this.setAttribute("defaultvalue", serializeSliderValue(value));
|
|
76
102
|
}
|
|
77
103
|
constructor() {
|
|
78
104
|
super();
|
|
79
105
|
this.internals = this.attachInternals?.();
|
|
80
106
|
const shadow = this.attachShadow({ mode: "open" });
|
|
81
|
-
const style = document.createElement("style");
|
|
82
|
-
style.textContent = `
|
|
83
|
-
:host {
|
|
84
|
-
display: grid;
|
|
85
|
-
grid-template-columns: minmax(0, 1fr);
|
|
86
|
-
gap: 1px;
|
|
87
|
-
outline: none;
|
|
88
|
-
}
|
|
89
|
-
[hidden] { display: none !important; }
|
|
90
|
-
.header {
|
|
91
|
-
display: flex;
|
|
92
|
-
align-items: baseline;
|
|
93
|
-
gap: 1px;
|
|
94
|
-
min-width: 0;
|
|
95
|
-
}
|
|
96
|
-
slot[name="label"] {
|
|
97
|
-
display: block;
|
|
98
|
-
min-width: 0;
|
|
99
|
-
color: var(--slider-label);
|
|
100
|
-
font-family: var(--sans-serif);
|
|
101
|
-
font-size: var(--slider-label-size);
|
|
102
|
-
font-weight: 500;
|
|
103
|
-
line-height: var(--slider-label-line-height);
|
|
104
|
-
}
|
|
105
|
-
.inline-value,
|
|
106
|
-
.end-value {
|
|
107
|
-
color: var(--slider-value);
|
|
108
|
-
font-family: var(--sans-serif);
|
|
109
|
-
font-size: var(--slider-value-size);
|
|
110
|
-
font-variant-numeric: tabular-nums;
|
|
111
|
-
line-height: var(--slider-value-line-height);
|
|
112
|
-
}
|
|
113
|
-
.value-affix { color: var(--slider-value-affix); }
|
|
114
|
-
.inline-separator,
|
|
115
|
-
.inline-value { display: none; }
|
|
116
|
-
.inline-value { margin-inline-start: 0.5ch; }
|
|
117
|
-
.end-value {
|
|
118
|
-
display: block;
|
|
119
|
-
flex: 0 0 auto;
|
|
120
|
-
margin-inline-start: auto;
|
|
121
|
-
padding-inline-start: 1ch;
|
|
122
|
-
}
|
|
123
|
-
:host([value-display="inline"]) .inline-separator,
|
|
124
|
-
:host([value-display="inline"]) .inline-value { display: block; }
|
|
125
|
-
:host([value-display="inline"]) .end-value,
|
|
126
|
-
:host([value-display="thumb"]) .end-value,
|
|
127
|
-
:host([value-display="none"]) .end-value { display: none; }
|
|
128
|
-
.control {
|
|
129
|
-
position: relative;
|
|
130
|
-
block-size: var(--anta-slider-control-size);
|
|
131
|
-
border-radius: 4px;
|
|
132
|
-
cursor: grab;
|
|
133
|
-
touch-action: none;
|
|
134
|
-
user-select: none;
|
|
135
|
-
}
|
|
136
|
-
:host([track-click="jump"]) .control { cursor: pointer; }
|
|
137
|
-
.control[data-dragging] { cursor: grabbing; }
|
|
138
|
-
.control[data-dragging] .thumb[data-active] { background: var(--slider-thumb-active); }
|
|
139
|
-
:host(:focus-visible) .control:not([data-pointer-focus]) {
|
|
140
|
-
outline: 1px solid var(--focus-ring);
|
|
141
|
-
outline-offset: 0;
|
|
142
|
-
}
|
|
143
|
-
.rail-area {
|
|
144
|
-
position: absolute;
|
|
145
|
-
inset-block-start: 50%;
|
|
146
|
-
inset-inline: calc(var(--anta-slider-thumb-size) / 2);
|
|
147
|
-
block-size: var(--anta-slider-track-size);
|
|
148
|
-
transform: translateY(-50%);
|
|
149
|
-
}
|
|
150
|
-
.rail,
|
|
151
|
-
.fill {
|
|
152
|
-
position: absolute;
|
|
153
|
-
inset: 0;
|
|
154
|
-
border-radius: var(--slider-track-radius);
|
|
155
|
-
transition: background-color 75ms ease-out;
|
|
156
|
-
}
|
|
157
|
-
.rail {
|
|
158
|
-
inset-inline: calc(var(--slider-track-inset) - var(--anta-slider-thumb-size) / 2);
|
|
159
|
-
background: var(--slider-track);
|
|
160
|
-
}
|
|
161
|
-
.fill {
|
|
162
|
-
inset-inline-start: calc(var(--_fill-start, 0%) + var(--_fill-start-edge, 0px));
|
|
163
|
-
inset-inline-end: auto;
|
|
164
|
-
inline-size: calc(var(--_fill-end, 0%) - var(--_fill-start, 0%) + var(--_fill-end-edge, 0px) - var(--_fill-start-edge, 0px));
|
|
165
|
-
background: var(--slider-fill);
|
|
166
|
-
}
|
|
167
|
-
.thumb {
|
|
168
|
-
position: absolute;
|
|
169
|
-
inset-block-start: 50%;
|
|
170
|
-
inset-inline-start: var(--_percent, 0%);
|
|
171
|
-
box-sizing: border-box;
|
|
172
|
-
inline-size: var(--anta-slider-thumb-size);
|
|
173
|
-
block-size: var(--anta-slider-thumb-size);
|
|
174
|
-
border: var(--anta-slider-thumb-border-width) solid var(--slider-thumb-border);
|
|
175
|
-
border-radius: var(--slider-thumb-radius);
|
|
176
|
-
background: var(--slider-thumb);
|
|
177
|
-
transition: background-color 75ms ease-out, border-color 75ms ease-out;
|
|
178
|
-
transform: translate(-50%, -50%);
|
|
179
|
-
}
|
|
180
|
-
.thumb[data-last-active] { z-index: 1; }
|
|
181
|
-
.thumb:focus-visible {
|
|
182
|
-
outline: 1px solid var(--focus-ring);
|
|
183
|
-
outline-offset: 2px;
|
|
184
|
-
z-index: 2;
|
|
185
|
-
}
|
|
186
|
-
.thumb-value {
|
|
187
|
-
display: none;
|
|
188
|
-
position: absolute;
|
|
189
|
-
inset-inline-start: var(--_percent, 0%);
|
|
190
|
-
inset-block-start: 50%;
|
|
191
|
-
min-inline-size: max-content;
|
|
192
|
-
color: var(--slider-value);
|
|
193
|
-
font-family: var(--sans-serif);
|
|
194
|
-
font-size: var(--slider-value-size);
|
|
195
|
-
font-variant-numeric: tabular-nums;
|
|
196
|
-
line-height: var(--slider-value-line-height);
|
|
197
|
-
padding-inline: 6px;
|
|
198
|
-
background: var(--bg-2);
|
|
199
|
-
border: 1px solid var(--border-3);
|
|
200
|
-
border-radius: 4px;
|
|
201
|
-
text-align: center;
|
|
202
|
-
transform: translate(-50%, calc(
|
|
203
|
-
-50% - var(--anta-slider-control-size) / 2 - 1px - var(--slider-value-line-height) / 2
|
|
204
|
-
));
|
|
205
|
-
}
|
|
206
|
-
:host([value-display="thumb"]) .thumb-value { display: block; }
|
|
207
|
-
:host([value-display="thumb"]) .thumb-value[hidden] { display: none !important; }
|
|
208
|
-
slot[name="markers"] {
|
|
209
|
-
display: block;
|
|
210
|
-
position: relative;
|
|
211
|
-
min-block-size: var(--slider-marker-line-height);
|
|
212
|
-
}
|
|
213
|
-
slot[name="markers"]::slotted(*) {
|
|
214
|
-
position: absolute;
|
|
215
|
-
inset-inline-start: var(--slider-marker-position);
|
|
216
|
-
max-inline-size: min(12rem, 50vw);
|
|
217
|
-
color: var(--slider-marker);
|
|
218
|
-
font-family: var(--sans-serif);
|
|
219
|
-
font-size: var(--slider-marker-size);
|
|
220
|
-
font-variant-numeric: tabular-nums;
|
|
221
|
-
line-height: var(--slider-marker-line-height);
|
|
222
|
-
text-align: center;
|
|
223
|
-
transform: translateX(-50%);
|
|
224
|
-
white-space: nowrap;
|
|
225
|
-
}
|
|
226
|
-
slot[name="markers"]::slotted([data-slider-marker-start]) { text-align: start; transform: translateX(0); }
|
|
227
|
-
slot[name="markers"]::slotted([data-slider-marker-end]) { text-align: end; transform: translateX(-100%); }
|
|
228
|
-
slot:not([name]) { display: block; }
|
|
229
|
-
:host([disabled]) .control,
|
|
230
|
-
:host(:disabled) .control { cursor: not-allowed; }
|
|
231
|
-
@media (forced-colors: active) {
|
|
232
|
-
.rail { background: Canvas; border: 1px solid CanvasText; }
|
|
233
|
-
.fill { background: Highlight; }
|
|
234
|
-
.thumb { background: Canvas; border-color: CanvasText; }
|
|
235
|
-
:host(:focus-visible) .control { outline: 2px solid Highlight; }
|
|
236
|
-
.thumb:focus-visible { outline: 2px solid Highlight; }
|
|
237
|
-
}
|
|
238
|
-
@media (prefers-reduced-motion: reduce) {
|
|
239
|
-
.rail,
|
|
240
|
-
.fill,
|
|
241
|
-
.thumb { transition: none; }
|
|
242
|
-
}
|
|
243
|
-
`;
|
|
244
107
|
this.#header = document.createElement("div");
|
|
245
108
|
this.#header.className = "header";
|
|
246
109
|
this.#header.part.add("header");
|
|
@@ -249,22 +112,27 @@ class ASliderElement extends HTMLElementBase {
|
|
|
249
112
|
this.#label.part.add("label");
|
|
250
113
|
const separator = document.createElement("span");
|
|
251
114
|
separator.className = "inline-separator";
|
|
115
|
+
separator.part.add("value-separator");
|
|
252
116
|
separator.textContent = ":";
|
|
253
117
|
this.#inlineValue = document.createElement("span");
|
|
254
118
|
this.#inlineValue.className = "inline-value";
|
|
255
|
-
this.#inlineValue.part.add("value");
|
|
119
|
+
this.#inlineValue.part.add("value", "inline-value");
|
|
256
120
|
this.#inlineValuePrefix = document.createElement("span");
|
|
257
121
|
this.#inlineValuePrefix.className = "value-affix";
|
|
122
|
+
this.#inlineValuePrefix.part.add("value-affix");
|
|
258
123
|
this.#inlineValueSuffix = document.createElement("span");
|
|
259
124
|
this.#inlineValueSuffix.className = "value-affix";
|
|
125
|
+
this.#inlineValueSuffix.part.add("value-affix");
|
|
260
126
|
this.#inlineValue.append(this.#inlineValuePrefix, this.#inlineValueSuffix);
|
|
261
127
|
this.#endValue = document.createElement("span");
|
|
262
128
|
this.#endValue.className = "end-value";
|
|
263
|
-
this.#endValue.part.add("value");
|
|
129
|
+
this.#endValue.part.add("value", "end-value");
|
|
264
130
|
this.#endValuePrefix = document.createElement("span");
|
|
265
131
|
this.#endValuePrefix.className = "value-affix";
|
|
132
|
+
this.#endValuePrefix.part.add("value-affix");
|
|
266
133
|
this.#endValueSuffix = document.createElement("span");
|
|
267
134
|
this.#endValueSuffix.className = "value-affix";
|
|
135
|
+
this.#endValueSuffix.part.add("value-affix");
|
|
268
136
|
this.#endValue.append(this.#endValuePrefix, this.#endValueSuffix);
|
|
269
137
|
this.#header.append(this.#label, separator, this.#inlineValue, this.#endValue);
|
|
270
138
|
this.#control = document.createElement("div");
|
|
@@ -272,12 +140,13 @@ class ASliderElement extends HTMLElementBase {
|
|
|
272
140
|
this.#control.part.add("control");
|
|
273
141
|
this.#railArea = document.createElement("div");
|
|
274
142
|
this.#railArea.className = "rail-area";
|
|
143
|
+
this.#railArea.part.add("rail-area");
|
|
275
144
|
const rail = document.createElement("div");
|
|
276
145
|
rail.className = "rail";
|
|
277
146
|
rail.part.add("track");
|
|
278
147
|
this.#fill = document.createElement("div");
|
|
279
148
|
this.#fill.className = "fill";
|
|
280
|
-
this.#fill.part.add("fill");
|
|
149
|
+
this.#fill.part.add("fill", "fill-start");
|
|
281
150
|
this.#fillEnd = document.createElement("div");
|
|
282
151
|
this.#fillEnd.className = "fill";
|
|
283
152
|
this.#fillEnd.part.add("fill", "fill-end");
|
|
@@ -289,19 +158,23 @@ class ASliderElement extends HTMLElementBase {
|
|
|
289
158
|
this.#thumbEnd.part.add("thumb", "thumb-2");
|
|
290
159
|
this.#thumbValue = document.createElement("span");
|
|
291
160
|
this.#thumbValue.className = "thumb-value";
|
|
292
|
-
this.#thumbValue.part.add("thumb-value");
|
|
161
|
+
this.#thumbValue.part.add("thumb-value", "thumb-value-1");
|
|
293
162
|
this.#thumbValuePrefix = document.createElement("span");
|
|
294
163
|
this.#thumbValuePrefix.className = "value-affix";
|
|
164
|
+
this.#thumbValuePrefix.part.add("value-affix");
|
|
295
165
|
this.#thumbValueSuffix = document.createElement("span");
|
|
296
166
|
this.#thumbValueSuffix.className = "value-affix";
|
|
167
|
+
this.#thumbValueSuffix.part.add("value-affix");
|
|
297
168
|
this.#thumbValue.append(this.#thumbValuePrefix, this.#thumbValueSuffix);
|
|
298
169
|
this.#thumbValueEnd = document.createElement("span");
|
|
299
170
|
this.#thumbValueEnd.className = "thumb-value";
|
|
300
171
|
this.#thumbValueEnd.part.add("thumb-value", "thumb-value-2");
|
|
301
172
|
this.#thumbValueEndPrefix = document.createElement("span");
|
|
302
173
|
this.#thumbValueEndPrefix.className = "value-affix";
|
|
174
|
+
this.#thumbValueEndPrefix.part.add("value-affix");
|
|
303
175
|
this.#thumbValueEndSuffix = document.createElement("span");
|
|
304
176
|
this.#thumbValueEndSuffix.className = "value-affix";
|
|
177
|
+
this.#thumbValueEndSuffix.part.add("value-affix");
|
|
305
178
|
this.#thumbValueEnd.append(this.#thumbValueEndPrefix, this.#thumbValueEndSuffix);
|
|
306
179
|
this.#railArea.append(rail, this.#fill, this.#fillEnd, this.#thumb, this.#thumbEnd, this.#thumbValue, this.#thumbValueEnd);
|
|
307
180
|
this.#control.append(this.#railArea);
|
|
@@ -313,7 +186,10 @@ class ASliderElement extends HTMLElementBase {
|
|
|
313
186
|
for (const slot of [this.#label, this.#markers, this.#extras]) {
|
|
314
187
|
slot.addEventListener("slotchange", () => {
|
|
315
188
|
this.#syncSlotVisibility();
|
|
316
|
-
if (slot === this.#label)
|
|
189
|
+
if (slot === this.#label) {
|
|
190
|
+
this.#accessibilityDirty = true;
|
|
191
|
+
this.#paintAccessibility();
|
|
192
|
+
}
|
|
317
193
|
});
|
|
318
194
|
}
|
|
319
195
|
for (const [index, thumb] of [this.#thumb, this.#thumbEnd].entries()) {
|
|
@@ -323,16 +199,25 @@ class ASliderElement extends HTMLElementBase {
|
|
|
323
199
|
this.#paint();
|
|
324
200
|
});
|
|
325
201
|
}
|
|
326
|
-
this.#control.addEventListener("
|
|
327
|
-
this.#control.addEventListener("
|
|
328
|
-
this.#control.addEventListener("
|
|
329
|
-
this
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
202
|
+
this.#control.addEventListener("pointerup", this.#onPointerEnd);
|
|
203
|
+
this.#control.addEventListener("pointercancel", this.#onPointerEnd);
|
|
204
|
+
this.#control.addEventListener("lostpointercapture", this.#onPointerEnd);
|
|
205
|
+
this.addEventListener("blur", () => {
|
|
206
|
+
delete this.#control.dataset.pointerFocus;
|
|
207
|
+
this.#paintStates();
|
|
208
|
+
});
|
|
209
|
+
for (const thumb of [this.#thumb, this.#thumbEnd]) {
|
|
210
|
+
const endpoint = document.createElement("span");
|
|
211
|
+
endpoint.hidden = true;
|
|
212
|
+
thumb.append(endpoint);
|
|
213
|
+
this.#endpointLabels.push(endpoint);
|
|
214
|
+
}
|
|
215
|
+
shadow.append(this.#header, this.#control, this.#markers, this.#extras);
|
|
216
|
+
upgradeValueProperties(this);
|
|
334
217
|
}
|
|
335
218
|
connectedCallback() {
|
|
219
|
+
this.#accessibilityDirty = true;
|
|
220
|
+
for (const type of ["pointerdown", "keydown", "pointermove"]) this.addEventListener(type, this.#orderDefaultAction, true);
|
|
336
221
|
if (!this.#seeded) {
|
|
337
222
|
this.#applyValue(this.#initialValue());
|
|
338
223
|
this.#seeded = true;
|
|
@@ -340,24 +225,54 @@ class ASliderElement extends HTMLElementBase {
|
|
|
340
225
|
this.#paint();
|
|
341
226
|
this.#syncSlotVisibility();
|
|
342
227
|
}
|
|
343
|
-
|
|
228
|
+
disconnectedCallback() {
|
|
229
|
+
this.#endDrag(false);
|
|
230
|
+
for (const type of ["pointerdown", "keydown", "pointermove"]) this.removeEventListener(type, this.#orderDefaultAction, true);
|
|
231
|
+
this.removeEventListener("pointerdown", this.#onPointerDown);
|
|
232
|
+
this.removeEventListener("keydown", this.#onKeyDown);
|
|
233
|
+
this.removeEventListener("pointermove", this.#onPointerMove);
|
|
234
|
+
this.#pendingRequest = void 0;
|
|
235
|
+
delete this.#control.dataset.pointerFocus;
|
|
236
|
+
this.#paintStates();
|
|
237
|
+
}
|
|
238
|
+
adoptedCallback() {
|
|
239
|
+
this.disconnectedCallback();
|
|
240
|
+
}
|
|
241
|
+
attributeChangedCallback(name, previous, next) {
|
|
344
242
|
if (!this.#seeded) return;
|
|
243
|
+
if (name.startsWith("aria-")) this.#accessibilityDirty = true;
|
|
345
244
|
if (name === "value") {
|
|
346
|
-
if (
|
|
347
|
-
this.#
|
|
348
|
-
this.#
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
this.#applyValue(this.#initialValue());
|
|
245
|
+
if (next === null && previous !== null) {
|
|
246
|
+
this.#dirty = true;
|
|
247
|
+
this.#pendingRequest = void 0;
|
|
248
|
+
this.#rebaseDrag();
|
|
249
|
+
} else this.#syncInput();
|
|
250
|
+
} else if (name === "defaultvalue") {
|
|
251
|
+
if (!this.#controlled && !this.#dirty) this.#syncInput();
|
|
354
252
|
} else if (name === "min" || name === "max" || name === "step") {
|
|
355
|
-
this.#
|
|
253
|
+
if (this.#controlled) this.#syncInput();
|
|
254
|
+
else {
|
|
255
|
+
this.#applyValue(this.#value);
|
|
256
|
+
this.#rebaseDrag();
|
|
257
|
+
}
|
|
356
258
|
}
|
|
259
|
+
if (this.#isDisabled) this.#endDrag(true);
|
|
357
260
|
this.#paint();
|
|
358
261
|
if (name === "value-display") this.#syncSlotVisibility();
|
|
359
262
|
}
|
|
263
|
+
#syncInput() {
|
|
264
|
+
const next = this.#normalizeValue(this.#initialValue());
|
|
265
|
+
const pending = this.#pendingRequest;
|
|
266
|
+
if (pending && sameSliderValue(pending.value, next)) this.#orderReversed = pending.reversed;
|
|
267
|
+
else this.#rebaseDrag(next);
|
|
268
|
+
this.#pendingRequest = void 0;
|
|
269
|
+
this.#applyValue(next);
|
|
270
|
+
this.#paint();
|
|
271
|
+
}
|
|
360
272
|
formResetCallback() {
|
|
273
|
+
this.#endDrag(false);
|
|
274
|
+
this.#pendingRequest = void 0;
|
|
275
|
+
if (this.#controlled) return;
|
|
361
276
|
const previous = this.#value;
|
|
362
277
|
this.#applyValue(this.defaultValue);
|
|
363
278
|
this.#dirty = false;
|
|
@@ -366,11 +281,15 @@ class ASliderElement extends HTMLElementBase {
|
|
|
366
281
|
}
|
|
367
282
|
formStateRestoreCallback(state) {
|
|
368
283
|
if (typeof state !== "string") return;
|
|
284
|
+
if (this.#controlled) return;
|
|
285
|
+
this.#endDrag(false);
|
|
286
|
+
this.#pendingRequest = void 0;
|
|
369
287
|
this.#applyValue(parseSliderValue(state, this.#fallbackValue()));
|
|
370
288
|
this.#dirty = true;
|
|
371
289
|
this.#paint();
|
|
372
290
|
}
|
|
373
291
|
formDisabledCallback() {
|
|
292
|
+
if (this.#isDisabled) this.#endDrag(true);
|
|
374
293
|
this.#paint();
|
|
375
294
|
}
|
|
376
295
|
get #min() {
|
|
@@ -386,21 +305,25 @@ class ASliderElement extends HTMLElementBase {
|
|
|
386
305
|
get #isDisabled() {
|
|
387
306
|
return this.hasAttribute("disabled") || this.matches(":disabled");
|
|
388
307
|
}
|
|
308
|
+
get #controlled() {
|
|
309
|
+
return this.hasAttribute("value");
|
|
310
|
+
}
|
|
389
311
|
#fallbackValue() {
|
|
390
312
|
const range = Array.isArray(this.#value) || Array.isArray(parseSliderValue(this.getAttribute("value"), this.#min));
|
|
391
313
|
return range ? [this.#min, this.#max] : this.#min;
|
|
392
314
|
}
|
|
393
315
|
#initialValue() {
|
|
394
|
-
|
|
395
|
-
return
|
|
316
|
+
if (this.#controlled) return parseSliderValue(this.getAttribute("value"), this.#fallbackValue());
|
|
317
|
+
return this.defaultValue;
|
|
396
318
|
}
|
|
397
319
|
#normalize(value) {
|
|
398
320
|
const min = this.#min;
|
|
399
321
|
const max = this.#max;
|
|
400
322
|
const step = this.#step;
|
|
401
323
|
const stepped = min + Math.round((Math.min(max, Math.max(min, value)) - min) / step) * step;
|
|
402
|
-
const precision = Math.
|
|
403
|
-
|
|
324
|
+
const precision = Math.max(precisionOf(min), precisionOf(max), precisionOf(step));
|
|
325
|
+
const rounded = precision <= 100 ? Number(stepped.toFixed(precision)) : Number(stepped.toPrecision(15));
|
|
326
|
+
return Math.min(max, Math.max(min, rounded));
|
|
404
327
|
}
|
|
405
328
|
#normalizeValue(value) {
|
|
406
329
|
if (!Array.isArray(value)) return this.#normalize(value);
|
|
@@ -464,6 +387,7 @@ class ASliderElement extends HTMLElementBase {
|
|
|
464
387
|
this.#renderValue(this.#endValue, this.#endValuePrefix, this.#endValueSuffix, range ? low : high, range ? high : void 0);
|
|
465
388
|
this.#renderValue(this.#thumbValue, this.#thumbValuePrefix, this.#thumbValueSuffix, first);
|
|
466
389
|
if (range) this.#renderValue(this.#thumbValueEnd, this.#thumbValueEndPrefix, this.#thumbValueEndSuffix, second);
|
|
390
|
+
this.#paintStates();
|
|
467
391
|
this.#paintAccessibility();
|
|
468
392
|
this.#paintFormValue();
|
|
469
393
|
}
|
|
@@ -485,43 +409,82 @@ class ASliderElement extends HTMLElementBase {
|
|
|
485
409
|
const suffix = this.getAttribute("value-suffix") ?? "";
|
|
486
410
|
return `${prefix}${value}${suffix}`;
|
|
487
411
|
}
|
|
412
|
+
#paintStates() {
|
|
413
|
+
const states = this.internals?.states;
|
|
414
|
+
if (!states) return;
|
|
415
|
+
const set = (name, enabled) => enabled ? states.add(name) : states.delete(name);
|
|
416
|
+
set("dragging", !!this.#drag);
|
|
417
|
+
set("pointer-focus", this.#control.hasAttribute("data-pointer-focus"));
|
|
418
|
+
set("thumb-1-active", this.#lastActiveThumb === 0);
|
|
419
|
+
set("thumb-2-active", this.#lastActiveThumb === 1);
|
|
420
|
+
for (const [name, element] of [
|
|
421
|
+
["has-header", this.#header],
|
|
422
|
+
["has-markers", this.#markers],
|
|
423
|
+
["has-extras", this.#extras],
|
|
424
|
+
["has-fill", this.#fill],
|
|
425
|
+
["has-fill-end", this.#fillEnd],
|
|
426
|
+
["has-thumb-value", this.#thumbValue],
|
|
427
|
+
["has-thumb-value-end", this.#thumbValueEnd]
|
|
428
|
+
]) set(name, !element.hidden);
|
|
429
|
+
set("range", Array.isArray(this.#value));
|
|
430
|
+
}
|
|
488
431
|
#paintAccessibility() {
|
|
489
432
|
const range = Array.isArray(this.#value);
|
|
490
|
-
const
|
|
433
|
+
const disabled = this.#isDisabled;
|
|
434
|
+
const previous = this.#accessibilityState;
|
|
491
435
|
const root = this.getRootNode();
|
|
492
|
-
const
|
|
493
|
-
|
|
436
|
+
const referencesChanged = this.#accessibilityReferences.some(({ id, element }) => element.id !== id || element.getRootNode() !== root);
|
|
437
|
+
if (this.#accessibilityDirty || this.#accessibilityUnresolved || referencesChanged || !previous || previous.range !== range || previous.disabled !== disabled || range && previous.reversed !== this.#orderReversed) {
|
|
438
|
+
this.#syncAccessibility(range, disabled);
|
|
439
|
+
this.#accessibilityDirty = false;
|
|
440
|
+
this.#accessibilityState = { range, reversed: this.#orderReversed, disabled };
|
|
441
|
+
}
|
|
494
442
|
const internals = this.internals;
|
|
495
443
|
if (internals) {
|
|
496
|
-
internals.role = range ? "group" : "slider";
|
|
497
|
-
internals.ariaLabel = !this.hasAttribute("aria-label") && !this.hasAttribute("aria-labelledby") ? slottedLabel || null : null;
|
|
498
444
|
internals.ariaValueMin = range ? null : String(this.#min);
|
|
499
445
|
internals.ariaValueMax = range ? null : String(this.#max);
|
|
500
446
|
internals.ariaValueNow = range ? null : String(this.#value);
|
|
501
447
|
internals.ariaValueText = range ? null : this.#formatValue(this.#value);
|
|
502
448
|
}
|
|
449
|
+
if (!range) return;
|
|
450
|
+
for (const [index, thumb] of [this.#thumb, this.#thumbEnd].entries()) {
|
|
451
|
+
thumb.ariaValueMin = String(this.#min);
|
|
452
|
+
thumb.ariaValueMax = String(this.#max);
|
|
453
|
+
thumb.ariaValueNow = String(this.#physicalValues[index]);
|
|
454
|
+
thumb.ariaValueText = this.#formatValue(this.#physicalValues[index]);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
#syncAccessibility(range, disabled) {
|
|
458
|
+
const referenced = referencedElements(this, this.getAttribute("aria-labelledby") ?? "");
|
|
459
|
+
const labels = referenced.length ? referenced : this.#label.assignedElements({ flatten: true });
|
|
460
|
+
const explicit = referenced.length ? null : this.getAttribute("aria-label");
|
|
461
|
+
const descriptions = range ? referencedElements(this, this.getAttribute("aria-describedby") ?? "") : [];
|
|
462
|
+
this.#accessibilityReferences = [...referenced, ...descriptions].map((element) => ({ id: element.id, element }));
|
|
463
|
+
const ids = [this.getAttribute("aria-labelledby"), range ? this.getAttribute("aria-describedby") : null].flatMap((value) => value?.match(/\S+/g) ?? []);
|
|
464
|
+
this.#accessibilityUnresolved = ids.length !== this.#accessibilityReferences.length;
|
|
465
|
+
const internals = this.internals;
|
|
466
|
+
if (internals) {
|
|
467
|
+
internals.role = range ? "group" : "slider";
|
|
468
|
+
internals.ariaLabelledByElements = explicit == null && !this.hasAttribute("aria-labelledby") ? labels : [];
|
|
469
|
+
internals.ariaDisabled = disabled ? "true" : null;
|
|
470
|
+
}
|
|
503
471
|
for (const [index, thumb] of [this.#thumb, this.#thumbEnd].entries()) {
|
|
504
472
|
if (!range) {
|
|
505
|
-
|
|
473
|
+
for (const name of ["role", "aria-label", "aria-valuemin", "aria-valuemax", "aria-valuenow", "aria-valuetext", "aria-disabled", "aria-description"]) thumb.removeAttribute(name);
|
|
474
|
+
thumb.ariaLabelledByElements = [];
|
|
475
|
+
thumb.ariaDescribedByElements = [];
|
|
506
476
|
thumb.tabIndex = -1;
|
|
507
|
-
thumb.removeAttribute("aria-label");
|
|
508
|
-
thumb.removeAttribute("aria-valuemin");
|
|
509
|
-
thumb.removeAttribute("aria-valuemax");
|
|
510
|
-
thumb.removeAttribute("aria-valuenow");
|
|
511
|
-
thumb.removeAttribute("aria-valuetext");
|
|
512
|
-
thumb.removeAttribute("aria-disabled");
|
|
513
477
|
continue;
|
|
514
478
|
}
|
|
515
479
|
const endpoint = index === 0 !== this.#orderReversed ? "minimum" : "maximum";
|
|
516
|
-
const
|
|
480
|
+
const endpointLabel = this.#endpointLabels[index];
|
|
481
|
+
endpointLabel.textContent = explicit != null ? `${explicit} ${endpoint}` : labels.length ? endpoint : `${endpoint[0].toUpperCase()}${endpoint.slice(1)} value`;
|
|
517
482
|
thumb.role = "slider";
|
|
518
|
-
thumb.tabIndex =
|
|
519
|
-
thumb.
|
|
520
|
-
thumb.
|
|
521
|
-
thumb.
|
|
522
|
-
thumb.
|
|
523
|
-
thumb.ariaValueText = this.#formatValue(value);
|
|
524
|
-
thumb.ariaDisabled = this.#isDisabled ? "true" : null;
|
|
483
|
+
thumb.tabIndex = disabled ? -1 : 0;
|
|
484
|
+
thumb.ariaLabelledByElements = explicit != null ? [endpointLabel] : [...labels, endpointLabel];
|
|
485
|
+
thumb.ariaDescribedByElements = descriptions;
|
|
486
|
+
thumb.ariaDescription = this.getAttribute("aria-description");
|
|
487
|
+
thumb.ariaDisabled = disabled ? "true" : null;
|
|
525
488
|
}
|
|
526
489
|
}
|
|
527
490
|
#paintFormValue() {
|
|
@@ -547,37 +510,48 @@ class ASliderElement extends HTMLElementBase {
|
|
|
547
510
|
this.#header.hidden = !assigned(this.#label) && this.getAttribute("value-display") === "none";
|
|
548
511
|
this.#markers.hidden = !assigned(this.#markers);
|
|
549
512
|
this.#extras.hidden = !assigned(this.#extras);
|
|
513
|
+
this.#paintStates();
|
|
514
|
+
}
|
|
515
|
+
#snapshot(value) {
|
|
516
|
+
return { value: Array.isArray(value) ? [...value] : value, min: this.#min, max: this.#max, step: this.#step, name: this.getAttribute("name") ?? void 0 };
|
|
517
|
+
}
|
|
518
|
+
#notify(type, value = this.#value) {
|
|
519
|
+
this.dispatchEvent(new CustomEvent(type, { bubbles: true, composed: true, detail: this.#snapshot(value) }));
|
|
550
520
|
}
|
|
551
521
|
#setValue(value, thumb = 0) {
|
|
552
522
|
const next = this.#normalize(value);
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
this.#
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
if (next === this.#value) return false;
|
|
565
|
-
this.#value = next;
|
|
566
|
-
this.#physicalValues = [next, next];
|
|
523
|
+
const physical = [...this.#physicalValues];
|
|
524
|
+
physical[thumb] = next;
|
|
525
|
+
const reversed = physical[0] === physical[1] ? this.#orderReversed : physical[0] > physical[1];
|
|
526
|
+
const requested = Array.isArray(this.#value) ? reversed ? [physical[1], physical[0]] : physical : next;
|
|
527
|
+
if (sameSliderValue(this.#drag?.lastInput ?? this.#value, requested)) return false;
|
|
528
|
+
if (this.#drag) this.#drag.requested = this.#drag.lastInput = requested;
|
|
529
|
+
this.#pendingRequest = this.#controlled ? { value: requested, reversed } : void 0;
|
|
530
|
+
if (!this.#controlled) {
|
|
531
|
+
this.#orderReversed = reversed;
|
|
532
|
+
this.#applyValue(requested);
|
|
533
|
+
this.#dirty = true;
|
|
567
534
|
this.#paint();
|
|
568
535
|
}
|
|
569
|
-
this.#
|
|
570
|
-
|
|
571
|
-
return true;
|
|
536
|
+
this.#notify("input", requested);
|
|
537
|
+
return requested;
|
|
572
538
|
}
|
|
573
539
|
#emitInputAndChange() {
|
|
574
|
-
this
|
|
575
|
-
this
|
|
540
|
+
this.#notify("input");
|
|
541
|
+
this.#notify("change");
|
|
542
|
+
}
|
|
543
|
+
#rebaseDrag(value = this.#value) {
|
|
544
|
+
const drag = this.#drag;
|
|
545
|
+
if (!drag) return;
|
|
546
|
+
drag.startX = drag.clientX;
|
|
547
|
+
drag.startValue = Array.isArray(value) ? value[this.#orderReversed ? 1 - drag.thumb : drag.thumb] : value;
|
|
548
|
+
drag.lastInput = void 0;
|
|
576
549
|
}
|
|
577
550
|
#valueAt(clientX) {
|
|
578
551
|
const rect = this.#railArea.getBoundingClientRect();
|
|
579
552
|
if (rect.width <= 0) return Array.isArray(this.#value) ? this.#physicalValues[this.#lastActiveThumb] : this.#value;
|
|
580
|
-
|
|
553
|
+
const ratio = this.#rtl() ? (rect.right - clientX) / rect.width : (clientX - rect.left) / rect.width;
|
|
554
|
+
return this.#min + ratio * (this.#max - this.#min);
|
|
581
555
|
}
|
|
582
556
|
#thumbAt(clientX) {
|
|
583
557
|
if (!Array.isArray(this.#value)) return 0;
|
|
@@ -586,14 +560,22 @@ class ASliderElement extends HTMLElementBase {
|
|
|
586
560
|
const secondDistance = Math.abs(candidate - this.#physicalValues[1]);
|
|
587
561
|
return firstDistance === secondDistance ? this.#lastActiveThumb : firstDistance < secondDistance ? 0 : 1;
|
|
588
562
|
}
|
|
563
|
+
#rtl() {
|
|
564
|
+
return this.ownerDocument.defaultView?.getComputedStyle(this).direction === "rtl";
|
|
565
|
+
}
|
|
589
566
|
#beginDrag(event) {
|
|
590
|
-
if (this.#isDisabled || event.button !== 0) return;
|
|
567
|
+
if (event.defaultPrevented || this.#drag || this.#isDisabled || event.button !== 0) return;
|
|
591
568
|
const rect = this.#railArea.getBoundingClientRect();
|
|
592
569
|
if (rect.width <= 0) return;
|
|
593
570
|
const thumb = event.composedPath()[0] === this.#thumb ? 0 : event.composedPath()[0] === this.#thumbEnd ? 1 : this.#thumbAt(event.clientX);
|
|
594
571
|
const startValue = Array.isArray(this.#value) ? this.#physicalValues[thumb] : this.#value;
|
|
595
|
-
this.#drag = { pointerId: event.pointerId, startX: event.clientX, startValue, startPublicValue: this.value, thumb };
|
|
596
|
-
|
|
572
|
+
this.#drag = { pointerId: event.pointerId, startX: event.clientX, clientX: event.clientX, startValue, startPublicValue: this.value, thumb };
|
|
573
|
+
try {
|
|
574
|
+
this.#control.setPointerCapture(event.pointerId);
|
|
575
|
+
} catch {
|
|
576
|
+
this.#drag = void 0;
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
597
579
|
this.#control.dataset.dragging = "";
|
|
598
580
|
this.#control.dataset.pointerFocus = "";
|
|
599
581
|
this.#lastActiveThumb = thumb;
|
|
@@ -603,43 +585,62 @@ class ASliderElement extends HTMLElementBase {
|
|
|
603
585
|
focusTarget.focus({ preventScroll: true });
|
|
604
586
|
[this.#thumb, this.#thumbEnd][thumb].dataset.active = "";
|
|
605
587
|
if (this.getAttribute("track-click") === "jump") this.#setValue(this.#valueAt(event.clientX), thumb);
|
|
588
|
+
this.#paintStates();
|
|
606
589
|
event.preventDefault();
|
|
607
590
|
}
|
|
608
591
|
#moveDrag(event) {
|
|
609
592
|
const drag = this.#drag;
|
|
610
593
|
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
594
|
+
if (this.#isDisabled) {
|
|
595
|
+
this.#endDrag(true);
|
|
596
|
+
return;
|
|
597
|
+
}
|
|
598
|
+
if (event.defaultPrevented) return;
|
|
599
|
+
drag.clientX = event.clientX;
|
|
600
|
+
const width = this.#railArea.getBoundingClientRect().width;
|
|
601
|
+
if (width <= 0) return;
|
|
611
602
|
if (!(event.buttons & 1)) {
|
|
612
603
|
this.#finishDrag(event);
|
|
613
604
|
return;
|
|
614
605
|
}
|
|
615
|
-
const next = this.getAttribute("track-click") === "jump" ? this.#valueAt(event.clientX) : drag.startValue + (event.clientX - drag.startX)
|
|
606
|
+
const next = this.getAttribute("track-click") === "jump" ? this.#valueAt(event.clientX) : drag.startValue + (event.clientX - drag.startX) * (this.#rtl() ? -1 : 1) / width * (this.#max - this.#min);
|
|
616
607
|
this.#setValue(next, drag.thumb);
|
|
617
608
|
event.preventDefault();
|
|
618
609
|
}
|
|
619
610
|
#finishDrag(event) {
|
|
611
|
+
if (this.#drag?.pointerId === event.pointerId) this.#endDrag(true);
|
|
612
|
+
}
|
|
613
|
+
#endDrag(commit) {
|
|
620
614
|
const drag = this.#drag;
|
|
621
|
-
if (!drag
|
|
615
|
+
if (!drag) return;
|
|
622
616
|
this.#drag = void 0;
|
|
623
617
|
delete this.#control.dataset.dragging;
|
|
624
618
|
delete [this.#thumb, this.#thumbEnd][drag.thumb].dataset.active;
|
|
625
|
-
if (this.#control.hasPointerCapture(
|
|
626
|
-
|
|
619
|
+
if (this.#control.hasPointerCapture(drag.pointerId)) this.#control.releasePointerCapture(drag.pointerId);
|
|
620
|
+
this.#paintStates();
|
|
621
|
+
const value = drag.requested;
|
|
622
|
+
if (commit && value !== void 0 && !sameSliderValue(value, drag.startPublicValue)) this.#notify("change", value);
|
|
627
623
|
}
|
|
628
624
|
#handleKeydown(event) {
|
|
629
625
|
const source = event.composedPath()[0];
|
|
630
626
|
const range = Array.isArray(this.#value);
|
|
631
627
|
const thumb = source === this.#thumb ? 0 : source === this.#thumbEnd ? 1 : void 0;
|
|
632
|
-
if ((range ? thumb === void 0 : source !== this) || this.#isDisabled || isModifiedNavigationKey(event)) return;
|
|
628
|
+
if (event.defaultPrevented || !event.composedPath().includes(this) || (range ? thumb === void 0 : source !== this) || this.#isDisabled || isModifiedNavigationKey(event)) return;
|
|
633
629
|
delete this.#control.dataset.pointerFocus;
|
|
630
|
+
this.#paintStates();
|
|
634
631
|
const page = Math.max(this.#step, (this.#max - this.#min) / 10);
|
|
635
632
|
const current = range ? this.#physicalValues[thumb ?? 0] : this.#value;
|
|
636
633
|
let next;
|
|
637
634
|
switch (event.key) {
|
|
638
635
|
case "ArrowRight":
|
|
636
|
+
next = current + (this.#rtl() ? -this.#step : this.#step);
|
|
637
|
+
break;
|
|
639
638
|
case "ArrowUp":
|
|
640
639
|
next = current + this.#step;
|
|
641
640
|
break;
|
|
642
641
|
case "ArrowLeft":
|
|
642
|
+
next = current + (this.#rtl() ? this.#step : -this.#step);
|
|
643
|
+
break;
|
|
643
644
|
case "ArrowDown":
|
|
644
645
|
next = current - this.#step;
|
|
645
646
|
break;
|
|
@@ -659,7 +660,8 @@ class ASliderElement extends HTMLElementBase {
|
|
|
659
660
|
return;
|
|
660
661
|
}
|
|
661
662
|
event.preventDefault();
|
|
662
|
-
|
|
663
|
+
const requested = this.#setValue(next, range ? thumb ?? 0 : 0);
|
|
664
|
+
if (requested !== false) this.#notify("change", requested);
|
|
663
665
|
}
|
|
664
666
|
}
|
|
665
667
|
function register_a_slider() {
|