@radix-ng/primitives 0.50.0 → 1.0.0-beta.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/collection/README.md +1 -0
- package/fesm2022/radix-ng-primitives-accordion.mjs +134 -66
- package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-alert-dialog.mjs +224 -132
- package/fesm2022/radix-ng-primitives-alert-dialog.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-arrow.mjs +26 -10
- package/fesm2022/radix-ng-primitives-arrow.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-aspect-ratio.mjs +6 -6
- package/fesm2022/radix-ng-primitives-aspect-ratio.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-avatar.mjs +68 -75
- package/fesm2022/radix-ng-primitives-avatar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-button.mjs +123 -0
- package/fesm2022/radix-ng-primitives-button.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-calendar.mjs +104 -103
- package/fesm2022/radix-ng-primitives-calendar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-checkbox.mjs +414 -80
- package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-collapsible.mjs +193 -92
- package/fesm2022/radix-ng-primitives-collapsible.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-collection.mjs +72 -0
- package/fesm2022/radix-ng-primitives-collection.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-config.mjs +5 -5
- package/fesm2022/radix-ng-primitives-config.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-context-menu.mjs +143 -427
- package/fesm2022/radix-ng-primitives-context-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-core.mjs +757 -757
- package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-cropper.mjs +55 -53
- package/fesm2022/radix-ng-primitives-cropper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-date-field.mjs +93 -86
- package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-dialog.mjs +658 -330
- package/fesm2022/radix-ng-primitives-dialog.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-dismissable-layer.mjs +98 -76
- package/fesm2022/radix-ng-primitives-dismissable-layer.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-drawer.mjs +1059 -0
- package/fesm2022/radix-ng-primitives-drawer.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-editable.mjs +20 -20
- package/fesm2022/radix-ng-primitives-editable.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-field.mjs +363 -0
- package/fesm2022/radix-ng-primitives-field.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-fieldset.mjs +79 -0
- package/fesm2022/radix-ng-primitives-fieldset.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-focus-guards.mjs +3 -3
- package/fesm2022/radix-ng-primitives-focus-guards.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-focus-scope.mjs +29 -14
- package/fesm2022/radix-ng-primitives-focus-scope.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-input.mjs +172 -0
- package/fesm2022/radix-ng-primitives-input.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-label.mjs +11 -11
- package/fesm2022/radix-ng-primitives-label.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menu.mjs +1484 -353
- package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menubar.mjs +290 -162
- package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-meter.mjs +271 -0
- package/fesm2022/radix-ng-primitives-meter.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-navigation-menu.mjs +1060 -1553
- package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-number-field.mjs +1102 -366
- package/fesm2022/radix-ng-primitives-number-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-pagination.mjs +51 -51
- package/fesm2022/radix-ng-primitives-pagination.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-popover.mjs +980 -995
- package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-popper.mjs +137 -82
- package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-portal.mjs +40 -16
- package/fesm2022/radix-ng-primitives-portal.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-presence.mjs +134 -246
- package/fesm2022/radix-ng-primitives-presence.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-preview-card.mjs +997 -0
- package/fesm2022/radix-ng-primitives-preview-card.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-progress.mjs +231 -92
- package/fesm2022/radix-ng-primitives-progress.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-radio.mjs +211 -70
- package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-roving-focus.mjs +127 -77
- package/fesm2022/radix-ng-primitives-roving-focus.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-select.mjs +791 -511
- package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-separator.mjs +16 -45
- package/fesm2022/radix-ng-primitives-separator.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-slider.mjs +976 -720
- package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-stepper.mjs +69 -71
- package/fesm2022/radix-ng-primitives-stepper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-switch.mjs +128 -124
- package/fesm2022/radix-ng-primitives-switch.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-tabs.mjs +388 -115
- package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-time-field.mjs +111 -117
- package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toggle-group.mjs +122 -248
- package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toggle.mjs +99 -62
- package/fesm2022/radix-ng-primitives-toggle.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toolbar.mjs +307 -94
- package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-tooltip.mjs +690 -1079
- package/fesm2022/radix-ng-primitives-tooltip.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-visually-hidden.mjs +46 -87
- package/fesm2022/radix-ng-primitives-visually-hidden.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives.mjs.map +1 -1
- package/meter/README.md +3 -0
- package/navigation-menu/README.md +2 -1
- package/package.json +85 -63
- package/portal/README.md +2 -0
- package/preview-card/README.md +3 -0
- package/schematics/collection.json +1 -0
- package/schematics/ng-add/index.d.ts +3 -2
- package/schematics/ng-add/index.js +62 -31
- package/schematics/ng-add/index.js.map +1 -1
- package/schematics/ng-add/package-config.d.ts +4 -2
- package/schematics/ng-add/package-config.js +10 -2
- package/schematics/ng-add/package-config.js.map +1 -1
- package/schematics/ng-add/schema.d.ts +3 -0
- package/schematics/ng-add/schema.js +3 -0
- package/schematics/ng-add/schema.js.map +1 -0
- package/schematics/ng-add/schema.json +14 -0
- package/select/README.md +2 -0
- package/{accordion/index.d.ts → types/radix-ng-primitives-accordion.d.ts} +102 -67
- package/types/radix-ng-primitives-alert-dialog.d.ts +114 -0
- package/{arrow/index.d.ts → types/radix-ng-primitives-arrow.d.ts} +1 -1
- package/{aspect-ratio/index.d.ts → types/radix-ng-primitives-aspect-ratio.d.ts} +1 -1
- package/{avatar/index.d.ts → types/radix-ng-primitives-avatar.d.ts} +7 -11
- package/types/radix-ng-primitives-button.d.ts +73 -0
- package/{calendar/index.d.ts → types/radix-ng-primitives-calendar.d.ts} +2 -3
- package/types/radix-ng-primitives-checkbox.d.ts +337 -0
- package/types/radix-ng-primitives-collapsible.d.ts +159 -0
- package/types/radix-ng-primitives-collection.d.ts +44 -0
- package/{config/index.d.ts → types/radix-ng-primitives-config.d.ts} +1 -1
- package/types/radix-ng-primitives-context-menu.d.ts +73 -0
- package/{core/index.d.ts → types/radix-ng-primitives-core.d.ts} +311 -236
- package/{cropper/index.d.ts → types/radix-ng-primitives-cropper.d.ts} +6 -5
- package/{date-field/index.d.ts → types/radix-ng-primitives-date-field.d.ts} +42 -27
- package/types/radix-ng-primitives-dialog.d.ts +323 -0
- package/{dismissable-layer/index.d.ts → types/radix-ng-primitives-dismissable-layer.d.ts} +15 -7
- package/types/radix-ng-primitives-drawer.d.ts +448 -0
- package/{editable/index.d.ts → types/radix-ng-primitives-editable.d.ts} +1 -1
- package/types/radix-ng-primitives-field.d.ts +373 -0
- package/types/radix-ng-primitives-fieldset.d.ts +48 -0
- package/{focus-scope/index.d.ts → types/radix-ng-primitives-focus-scope.d.ts} +13 -5
- package/types/radix-ng-primitives-input.d.ts +87 -0
- package/{label/index.d.ts → types/radix-ng-primitives-label.d.ts} +0 -1
- package/types/radix-ng-primitives-menu.d.ts +612 -0
- package/types/radix-ng-primitives-menubar.d.ts +66 -0
- package/types/radix-ng-primitives-meter.d.ts +193 -0
- package/types/radix-ng-primitives-navigation-menu.d.ts +488 -0
- package/types/radix-ng-primitives-number-field.d.ts +464 -0
- package/{pagination/index.d.ts → types/radix-ng-primitives-pagination.d.ts} +2 -2
- package/types/radix-ng-primitives-popover.d.ts +416 -0
- package/{popper/index.d.ts → types/radix-ng-primitives-popper.d.ts} +50 -9
- package/types/radix-ng-primitives-portal.d.ts +30 -0
- package/types/radix-ng-primitives-presence.d.ts +55 -0
- package/types/radix-ng-primitives-preview-card.d.ts +359 -0
- package/types/radix-ng-primitives-progress.d.ts +206 -0
- package/{radio/index.d.ts → types/radix-ng-primitives-radio.d.ts} +56 -26
- package/{roving-focus/index.d.ts → types/radix-ng-primitives-roving-focus.d.ts} +38 -27
- package/types/radix-ng-primitives-select.d.ts +512 -0
- package/types/radix-ng-primitives-separator.d.ts +38 -0
- package/types/radix-ng-primitives-slider.d.ts +377 -0
- package/{stepper/index.d.ts → types/radix-ng-primitives-stepper.d.ts} +21 -22
- package/types/radix-ng-primitives-switch.d.ts +121 -0
- package/types/radix-ng-primitives-tabs.d.ts +247 -0
- package/{time-field/index.d.ts → types/radix-ng-primitives-time-field.d.ts} +46 -31
- package/types/radix-ng-primitives-toggle-group.d.ts +116 -0
- package/types/radix-ng-primitives-toggle.d.ts +65 -0
- package/types/radix-ng-primitives-toolbar.d.ts +180 -0
- package/types/radix-ng-primitives-tooltip.d.ts +395 -0
- package/{visually-hidden/index.d.ts → types/radix-ng-primitives-visually-hidden.d.ts} +19 -19
- package/alert-dialog/index.d.ts +0 -57
- package/checkbox/index.d.ts +0 -164
- package/collapsible/index.d.ts +0 -85
- package/context-menu/index.d.ts +0 -129
- package/dialog/index.d.ts +0 -205
- package/dropdown-menu/README.md +0 -1
- package/dropdown-menu/index.d.ts +0 -171
- package/fesm2022/radix-ng-primitives-dropdown-menu.mjs +0 -583
- package/fesm2022/radix-ng-primitives-dropdown-menu.mjs.map +0 -1
- package/fesm2022/radix-ng-primitives-hover-card.mjs +0 -1246
- package/fesm2022/radix-ng-primitives-hover-card.mjs.map +0 -1
- package/fesm2022/radix-ng-primitives-tooltip2.mjs +0 -740
- package/fesm2022/radix-ng-primitives-tooltip2.mjs.map +0 -1
- package/hover-card/README.md +0 -3
- package/hover-card/index.d.ts +0 -472
- package/menu/index.d.ts +0 -139
- package/menubar/index.d.ts +0 -56
- package/navigation-menu/index.d.ts +0 -405
- package/number-field/index.d.ts +0 -203
- package/popover/index.d.ts +0 -403
- package/portal/index.d.ts +0 -22
- package/presence/index.d.ts +0 -103
- package/progress/index.d.ts +0 -79
- package/select/index.d.ts +0 -214
- package/separator/index.d.ts +0 -63
- package/slider/index.d.ts +0 -263
- package/switch/index.d.ts +0 -105
- package/tabs/index.d.ts +0 -112
- package/toggle/index.d.ts +0 -75
- package/toggle-group/index.d.ts +0 -194
- package/toolbar/index.d.ts +0 -55
- package/tooltip/index.d.ts +0 -433
- package/tooltip2/README.md +0 -3
- package/tooltip2/index.d.ts +0 -325
- /package/{focus-guards/index.d.ts → types/radix-ng-primitives-focus-guards.d.ts} +0 -0
- /package/{index.d.ts → types/radix-ng-primitives.d.ts} +0 -0
|
@@ -1,851 +1,1107 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject,
|
|
3
|
-
import {
|
|
2
|
+
import { inject, ElementRef, DestroyRef, Directive, computed, input, numberAttribute, booleanAttribute, model, output, signal, NgModule } from '@angular/core';
|
|
3
|
+
import { DOCUMENT } from '@angular/common';
|
|
4
|
+
import * as i1 from '@radix-ng/primitives/core';
|
|
5
|
+
import { createContext, clamp, injectControlValueAccessor, injectId, RdxControlValueAccessor } from '@radix-ng/primitives/core';
|
|
6
|
+
export { clamp } from '@radix-ng/primitives/core';
|
|
4
7
|
|
|
5
|
-
// https://github.com/tmcw-up-for-adoption/simple-linear-scale/blob/master/index.js
|
|
6
|
-
function linearScale(input, output) {
|
|
7
|
-
return (value) => {
|
|
8
|
-
if (input[0] === input[1] || output[0] === output[1])
|
|
9
|
-
return output[0];
|
|
10
|
-
const ratio = (output[1] - output[0]) / (input[1] - input[0]);
|
|
11
|
-
return output[0] + ratio * (value - input[0]);
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
8
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
9
|
+
* The Slider context exposes the root directive instance to every child part.
|
|
10
|
+
* The root owns all state, value-change logic and thumb registration; parts read
|
|
11
|
+
* signals and call methods off it.
|
|
17
12
|
*
|
|
18
|
-
* @
|
|
19
|
-
* // returns false
|
|
20
|
-
* hasMinStepsBetweenValues([1,2,3], 2);
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* // returns true
|
|
24
|
-
* hasMinStepsBetweenValues([1,2,3], 1);
|
|
13
|
+
* @see https://base-ui.com/react/components/slider
|
|
25
14
|
*/
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
15
|
+
const [injectSliderRootContext, provideSliderRootContext] = createContext('RdxSliderRootContext');
|
|
16
|
+
|
|
17
|
+
/** Ascending comparator. */
|
|
18
|
+
function asc(a, b) {
|
|
19
|
+
return a - b;
|
|
20
|
+
}
|
|
21
|
+
/** Maps a value within `[min, max]` to a 0–100 percentage. */
|
|
22
|
+
function valueToPercent(value, min, max) {
|
|
23
|
+
return ((value - min) * 100) / (max - min);
|
|
24
|
+
}
|
|
25
|
+
/** Replaces the item at `index` then re-sorts the array ascending. */
|
|
26
|
+
function replaceArrayItemAtIndex(array, index, newValue) {
|
|
27
|
+
const output = array.slice();
|
|
28
|
+
output[index] = newValue;
|
|
29
|
+
return output.sort(asc);
|
|
30
|
+
}
|
|
31
|
+
/** The center point of an element in client coordinates. */
|
|
32
|
+
function getMidpoint(element) {
|
|
33
|
+
const rect = element.getBoundingClientRect();
|
|
34
|
+
return { x: (rect.left + rect.right) / 2, y: (rect.top + rect.bottom) / 2 };
|
|
35
|
+
}
|
|
36
|
+
/** Converts an array of values into clamped 0–100 percentages. */
|
|
37
|
+
function valueArrayToPercentages(values, min, max) {
|
|
38
|
+
return values.map((value) => clamp(valueToPercent(value, min, max), 0, 100));
|
|
39
|
+
}
|
|
40
|
+
/** Number of decimal places in `num`, handling exponential notation for tiny values. */
|
|
41
|
+
function getDecimalPrecision(num) {
|
|
42
|
+
if (num === 0) {
|
|
43
|
+
return 0;
|
|
31
44
|
}
|
|
32
|
-
|
|
45
|
+
if (Math.abs(num) < 1) {
|
|
46
|
+
const parts = num.toExponential().split('e-');
|
|
47
|
+
const mantissaDecimalPart = parts[0].split('.')[1];
|
|
48
|
+
return (mantissaDecimalPart ? mantissaDecimalPart.length : 0) + parseInt(parts[1], 10);
|
|
49
|
+
}
|
|
50
|
+
const decimalPart = num.toString().split('.')[1];
|
|
51
|
+
return decimalPart ? decimalPart.length : 0;
|
|
52
|
+
}
|
|
53
|
+
/** Snaps `value` to the nearest step, using `min` as the origin of the step grid. */
|
|
54
|
+
function roundValueToStep(value, step, min) {
|
|
55
|
+
const nearest = Math.round((value - min) / step) * step + min;
|
|
56
|
+
return Number(nearest.toFixed(Math.max(getDecimalPrecision(step), getDecimalPrecision(min))));
|
|
33
57
|
}
|
|
34
58
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* // returns 1
|
|
40
|
-
* getClosestValueIndex([10, 30], 25);
|
|
59
|
+
* Resolves the value(s) for the keyboard / hidden-input path: clamps to the
|
|
60
|
+
* bounds, and for range sliders also clamps to neighbouring thumbs and re-sorts.
|
|
61
|
+
* Returns a `number` for single sliders and a sorted `number[]` for range sliders.
|
|
41
62
|
*/
|
|
42
|
-
function
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
63
|
+
function getSliderValue(valueInput, index, min, max, range, values) {
|
|
64
|
+
let newValue = clamp(valueInput, min, max);
|
|
65
|
+
if (range) {
|
|
66
|
+
newValue = clamp(newValue, values[index - 1] ?? Number.NEGATIVE_INFINITY, values[index + 1] ?? Number.POSITIVE_INFINITY);
|
|
67
|
+
return replaceArrayItemAtIndex(values, index, newValue);
|
|
68
|
+
}
|
|
69
|
+
return newValue;
|
|
70
|
+
}
|
|
71
|
+
/** Returns `false` if any adjacent pair of values is closer than the minimum distance. */
|
|
72
|
+
function validateMinimumDistance(values, step, minStepsBetweenValues) {
|
|
73
|
+
if (!Array.isArray(values)) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
const distances = values.reduce((acc, val, index, vals) => {
|
|
77
|
+
if (index === vals.length - 1) {
|
|
78
|
+
return acc;
|
|
79
|
+
}
|
|
80
|
+
acc.push(Math.abs(val - vals[index + 1]));
|
|
81
|
+
return acc;
|
|
82
|
+
}, []);
|
|
83
|
+
return Math.min(...distances) >= step * minStepsBetweenValues;
|
|
84
|
+
}
|
|
85
|
+
/** Keyboard step helper: increments/decrements `thumbValue` and clamps to bounds. */
|
|
86
|
+
function getNewValue(thumbValue, increment, direction, min, max) {
|
|
87
|
+
const value = direction === 1 ? thumbValue + increment : thumbValue - increment;
|
|
88
|
+
const roundedValue = Number(value.toFixed(Math.max(getDecimalPrecision(thumbValue), getDecimalPrecision(increment), getDecimalPrecision(min))));
|
|
89
|
+
return clamp(roundedValue, min, max);
|
|
48
90
|
}
|
|
49
91
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* // returns [1, 9]
|
|
54
|
-
* getStepsBetweenValues([10, 11, 20]);
|
|
92
|
+
* The "push" collision algorithm: moves the pressed thumb and pushes its
|
|
93
|
+
* neighbours only as far as needed, letting them spring back toward their
|
|
94
|
+
* initial positions as the pressed thumb retreats.
|
|
55
95
|
*/
|
|
56
|
-
function
|
|
57
|
-
|
|
96
|
+
function getPushedThumbValues(params) {
|
|
97
|
+
const { values, index, nextValue, min, max, step, minStepsBetweenValues, initialValues } = params;
|
|
98
|
+
if (values.length === 0) {
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
const nextValues = values.slice();
|
|
102
|
+
const minValueDifference = step * minStepsBetweenValues;
|
|
103
|
+
const lastIndex = nextValues.length - 1;
|
|
104
|
+
const baseInitialValues = initialValues ?? values;
|
|
105
|
+
const indexMin = min + index * minValueDifference;
|
|
106
|
+
const indexMax = max - (lastIndex - index) * minValueDifference;
|
|
107
|
+
nextValues[index] = clamp(nextValue, indexMin, indexMax);
|
|
108
|
+
// push thumbs to the right
|
|
109
|
+
for (let i = index + 1; i <= lastIndex; i += 1) {
|
|
110
|
+
const minAllowed = nextValues[i - 1] + minValueDifference;
|
|
111
|
+
const maxAllowed = max - (lastIndex - i) * minValueDifference;
|
|
112
|
+
const initialValue = baseInitialValues[i] ?? nextValues[i];
|
|
113
|
+
let candidate = Math.max(nextValues[i], minAllowed);
|
|
114
|
+
if (initialValue < candidate) {
|
|
115
|
+
candidate = Math.max(initialValue, minAllowed);
|
|
116
|
+
}
|
|
117
|
+
nextValues[i] = clamp(candidate, minAllowed, maxAllowed);
|
|
118
|
+
}
|
|
119
|
+
// push thumbs to the left
|
|
120
|
+
for (let i = index - 1; i >= 0; i -= 1) {
|
|
121
|
+
const maxAllowed = nextValues[i + 1] - minValueDifference;
|
|
122
|
+
const minAllowed = min + i * minValueDifference;
|
|
123
|
+
const initialValue = baseInitialValues[i] ?? nextValues[i];
|
|
124
|
+
let candidate = Math.min(nextValues[i], maxAllowed);
|
|
125
|
+
if (initialValue > candidate) {
|
|
126
|
+
candidate = Math.min(initialValue, maxAllowed);
|
|
127
|
+
}
|
|
128
|
+
nextValues[i] = clamp(candidate, minAllowed, maxAllowed);
|
|
129
|
+
}
|
|
130
|
+
for (let i = 0; i <= lastIndex; i += 1) {
|
|
131
|
+
nextValues[i] = Number(nextValues[i].toFixed(12));
|
|
132
|
+
}
|
|
133
|
+
return nextValues;
|
|
134
|
+
}
|
|
135
|
+
/** Dispatches the pressed thumb's new value through the configured collision behavior. */
|
|
136
|
+
function resolveThumbCollision(params) {
|
|
137
|
+
const { behavior, values, currentValues, initialValues, pressedIndex, nextValue, min, max, step, minStepsBetweenValues } = params;
|
|
138
|
+
const activeValues = (currentValues ?? values).slice();
|
|
139
|
+
const baselineValues = initialValues ?? values;
|
|
140
|
+
const range = activeValues.length > 1;
|
|
141
|
+
const minValueDifference = step * minStepsBetweenValues;
|
|
142
|
+
if (!range) {
|
|
143
|
+
return { value: nextValue, thumbIndex: 0, didSwap: false };
|
|
144
|
+
}
|
|
145
|
+
if (behavior === 'push') {
|
|
146
|
+
const value = getPushedThumbValues({
|
|
147
|
+
values: activeValues,
|
|
148
|
+
index: pressedIndex,
|
|
149
|
+
nextValue,
|
|
150
|
+
min,
|
|
151
|
+
max,
|
|
152
|
+
step,
|
|
153
|
+
minStepsBetweenValues
|
|
154
|
+
});
|
|
155
|
+
return { value, thumbIndex: pressedIndex, didSwap: false };
|
|
156
|
+
}
|
|
157
|
+
if (behavior === 'swap') {
|
|
158
|
+
const pressedInitialValue = activeValues[pressedIndex];
|
|
159
|
+
const epsilon = 1e-7;
|
|
160
|
+
const candidateValues = activeValues.slice();
|
|
161
|
+
const previousNeighbor = candidateValues[pressedIndex - 1];
|
|
162
|
+
const nextNeighbor = candidateValues[pressedIndex + 1];
|
|
163
|
+
const lowerBound = previousNeighbor != null ? previousNeighbor + minValueDifference : min;
|
|
164
|
+
const upperBound = nextNeighbor != null ? nextNeighbor - minValueDifference : max;
|
|
165
|
+
const constrainedValue = clamp(nextValue, lowerBound, upperBound);
|
|
166
|
+
const pressedValueAfterClamp = Number(constrainedValue.toFixed(12));
|
|
167
|
+
candidateValues[pressedIndex] = pressedValueAfterClamp;
|
|
168
|
+
const movingForward = nextValue > pressedInitialValue;
|
|
169
|
+
const movingBackward = nextValue < pressedInitialValue;
|
|
170
|
+
const shouldSwapForward = movingForward && nextNeighbor != null && nextValue >= nextNeighbor - epsilon;
|
|
171
|
+
const shouldSwapBackward = movingBackward && previousNeighbor != null && nextValue <= previousNeighbor + epsilon;
|
|
172
|
+
if (!shouldSwapForward && !shouldSwapBackward) {
|
|
173
|
+
return { value: candidateValues, thumbIndex: pressedIndex, didSwap: false };
|
|
174
|
+
}
|
|
175
|
+
const targetIndex = shouldSwapForward ? pressedIndex + 1 : pressedIndex - 1;
|
|
176
|
+
const initialValuesForPush = candidateValues.map((_, idx) => {
|
|
177
|
+
if (idx === pressedIndex) {
|
|
178
|
+
return pressedValueAfterClamp;
|
|
179
|
+
}
|
|
180
|
+
const baseline = baselineValues[idx];
|
|
181
|
+
return baseline != null ? baseline : activeValues[idx];
|
|
182
|
+
});
|
|
183
|
+
const nextValueForTarget = shouldSwapForward
|
|
184
|
+
? Math.max(nextValue, candidateValues[targetIndex])
|
|
185
|
+
: Math.min(nextValue, candidateValues[targetIndex]);
|
|
186
|
+
const adjustedValues = getPushedThumbValues({
|
|
187
|
+
values: candidateValues,
|
|
188
|
+
index: targetIndex,
|
|
189
|
+
nextValue: nextValueForTarget,
|
|
190
|
+
min,
|
|
191
|
+
max,
|
|
192
|
+
step,
|
|
193
|
+
minStepsBetweenValues,
|
|
194
|
+
initialValues: initialValuesForPush
|
|
195
|
+
});
|
|
196
|
+
const neighborIndex = shouldSwapForward ? targetIndex - 1 : targetIndex + 1;
|
|
197
|
+
if (neighborIndex >= 0 && neighborIndex < adjustedValues.length) {
|
|
198
|
+
const previousValue = adjustedValues[neighborIndex - 1];
|
|
199
|
+
const nextValueAfter = adjustedValues[neighborIndex + 1];
|
|
200
|
+
let neighborLowerBound = previousValue != null ? previousValue + minValueDifference : min;
|
|
201
|
+
neighborLowerBound = Math.max(neighborLowerBound, min + neighborIndex * minValueDifference);
|
|
202
|
+
let neighborUpperBound = nextValueAfter != null ? nextValueAfter - minValueDifference : max;
|
|
203
|
+
neighborUpperBound = Math.min(neighborUpperBound, max - (adjustedValues.length - 1 - neighborIndex) * minValueDifference);
|
|
204
|
+
const restoredValue = clamp(pressedValueAfterClamp, neighborLowerBound, neighborUpperBound);
|
|
205
|
+
adjustedValues[neighborIndex] = Number(restoredValue.toFixed(12));
|
|
206
|
+
}
|
|
207
|
+
return { value: adjustedValues, thumbIndex: targetIndex, didSwap: true };
|
|
208
|
+
}
|
|
209
|
+
// behavior === 'none' — clamp the pressed thumb between its neighbours; thumbs never cross.
|
|
210
|
+
const previousNeighbor = activeValues[pressedIndex - 1];
|
|
211
|
+
const nextNeighbor = activeValues[pressedIndex + 1];
|
|
212
|
+
const lowerBound = previousNeighbor != null ? previousNeighbor + minValueDifference : min;
|
|
213
|
+
const upperBound = nextNeighbor != null ? nextNeighbor - minValueDifference : max;
|
|
214
|
+
const constrained = Number(clamp(nextValue, lowerBound, upperBound).toFixed(12));
|
|
215
|
+
const value = activeValues.slice();
|
|
216
|
+
value[pressedIndex] = constrained;
|
|
217
|
+
return { value, thumbIndex: pressedIndex, didSwap: false };
|
|
58
218
|
}
|
|
59
219
|
/**
|
|
60
|
-
*
|
|
61
|
-
*
|
|
220
|
+
* Border + padding on the leading/trailing edge of the control along the active
|
|
221
|
+
* axis. Uses physical longhands (`left`/`right`/`top`/`bottom`) rather than
|
|
222
|
+
* logical ones (`inline-start`/…) because `getComputedStyle` resolves the
|
|
223
|
+
* physical properties in every browser, whereas logical longhands return an
|
|
224
|
+
* empty string in some engines.
|
|
62
225
|
*/
|
|
63
|
-
function
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
226
|
+
function getControlOffset(styles, vertical, rtl) {
|
|
227
|
+
if (!styles) {
|
|
228
|
+
return { start: 0, end: 0 };
|
|
229
|
+
}
|
|
230
|
+
const parseSize = (v) => {
|
|
231
|
+
const p = parseFloat(v);
|
|
232
|
+
return Number.isNaN(p) ? 0 : p;
|
|
233
|
+
};
|
|
234
|
+
const sideOffset = (side) => parseSize(styles.getPropertyValue(`border-${side}-width`)) +
|
|
235
|
+
parseSize(styles.getPropertyValue(`padding-${side}`));
|
|
236
|
+
let startSide;
|
|
237
|
+
let endSide;
|
|
238
|
+
if (vertical) {
|
|
239
|
+
startSide = 'top';
|
|
240
|
+
endSide = 'bottom';
|
|
241
|
+
}
|
|
242
|
+
else if (rtl) {
|
|
243
|
+
startSide = 'right';
|
|
244
|
+
endSide = 'left';
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
startSide = 'left';
|
|
248
|
+
endSide = 'right';
|
|
249
|
+
}
|
|
250
|
+
return { start: sideOffset(startSide), end: sideOffset(endSide) };
|
|
74
251
|
}
|
|
75
|
-
|
|
76
|
-
|
|
252
|
+
const formatterCache = new Map();
|
|
253
|
+
function getFormatter(locale, options) {
|
|
254
|
+
const key = JSON.stringify({ locale: locale ?? null, options: options ?? null });
|
|
255
|
+
let formatter = formatterCache.get(key);
|
|
256
|
+
if (!formatter) {
|
|
257
|
+
formatter = new Intl.NumberFormat(locale, options);
|
|
258
|
+
formatterCache.set(key, formatter);
|
|
259
|
+
}
|
|
260
|
+
return formatter;
|
|
77
261
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
262
|
+
/** Formats a number with a cached `Intl.NumberFormat` instance. */
|
|
263
|
+
function formatNumber(value, locale, options) {
|
|
264
|
+
if (value == null) {
|
|
265
|
+
return '';
|
|
266
|
+
}
|
|
267
|
+
return getFormatter(locale, options).format(value);
|
|
81
268
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
269
|
+
/** Default `aria-valuetext` for a two-thumb range, or a formatted value when `format` is set. */
|
|
270
|
+
function getDefaultAriaValueText(values, index, format, locale) {
|
|
271
|
+
if (index < 0) {
|
|
272
|
+
return undefined;
|
|
273
|
+
}
|
|
274
|
+
if (values.length === 2) {
|
|
275
|
+
return index === 0
|
|
276
|
+
? `${formatNumber(values[index], locale, format)} start range`
|
|
277
|
+
: `${formatNumber(values[index], locale, format)} end range`;
|
|
278
|
+
}
|
|
279
|
+
return format ? formatNumber(values[index], locale, format) : undefined;
|
|
86
280
|
}
|
|
87
|
-
const PAGE_KEYS = ['PageUp', 'PageDown'];
|
|
88
281
|
const ARROW_KEYS = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return Math.min(Math.max(value, min), max);
|
|
282
|
+
const COMPOSITE_KEYS = new Set([...ARROW_KEYS, 'Home', 'End']);
|
|
283
|
+
const ALL_KEYS = new Set([...COMPOSITE_KEYS, 'PageUp', 'PageDown']);
|
|
284
|
+
function areValuesEqual(a, b) {
|
|
285
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
286
|
+
return a.length === b.length && a.every((v, i) => v === b[i]);
|
|
287
|
+
}
|
|
288
|
+
return a === b;
|
|
97
289
|
}
|
|
98
290
|
|
|
99
|
-
|
|
291
|
+
const INTENTIONAL_DRAG_COUNT_THRESHOLD = 2;
|
|
292
|
+
/**
|
|
293
|
+
* The interactive area of the slider. Handles pointer presses and drags on the
|
|
294
|
+
* track, mapping pointer position to a value and moving the closest thumb.
|
|
295
|
+
*
|
|
296
|
+
* @see https://base-ui.com/react/components/slider
|
|
297
|
+
*/
|
|
298
|
+
class RdxSliderControl {
|
|
100
299
|
constructor() {
|
|
101
|
-
this.
|
|
102
|
-
this.
|
|
103
|
-
this.
|
|
104
|
-
this.
|
|
105
|
-
this.
|
|
106
|
-
this.
|
|
107
|
-
this.
|
|
300
|
+
this.root = injectSliderRootContext();
|
|
301
|
+
this.elementRef = inject(ElementRef);
|
|
302
|
+
this.document = inject(DOCUMENT);
|
|
303
|
+
this.styles = null;
|
|
304
|
+
this.moveCount = 0;
|
|
305
|
+
this.currentInteractionValue = null;
|
|
306
|
+
this.onMove = (event) => this.handleMove(event);
|
|
307
|
+
this.onUp = (event) => this.handleUp(event);
|
|
308
|
+
this.onCancel = (event) => this.handleUp(event);
|
|
309
|
+
this.root.controlRef.set(this.elementRef.nativeElement);
|
|
310
|
+
inject(DestroyRef).onDestroy(() => this.stopListening());
|
|
108
311
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
event.preventDefault();
|
|
312
|
+
onPointerDown(event) {
|
|
313
|
+
const control = this.elementRef.nativeElement;
|
|
314
|
+
if (this.root.isDisabled() || event.defaultPrevented || event.button !== 0) {
|
|
315
|
+
return;
|
|
114
316
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
event.preventDefault();
|
|
317
|
+
const target = event.target;
|
|
318
|
+
if (!target) {
|
|
319
|
+
return;
|
|
119
320
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
321
|
+
// Suppress the nested range input's native click-to-set and drag so the
|
|
322
|
+
// control fully owns pointer interaction (otherwise releasing on a thumb
|
|
323
|
+
// fires a native change that snaps the value to the press point inside
|
|
324
|
+
// the thumb-sized input). Focus is restored manually via focusThumb.
|
|
325
|
+
event.preventDefault();
|
|
326
|
+
this.styles = this.document.defaultView?.getComputedStyle(control) ?? null;
|
|
327
|
+
this.startPressing({ x: event.clientX, y: event.clientY });
|
|
328
|
+
const finger = this.getFingerState({ x: event.clientX, y: event.clientY });
|
|
329
|
+
if (finger == null) {
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
this.root.setDragging(true);
|
|
333
|
+
// Pressing directly on a thumb sets a center offset; only a rail press changes value on down.
|
|
334
|
+
if (this.root.pressedThumbCenterOffset == null) {
|
|
335
|
+
this.setValueFromPointer(finger, 'track-press');
|
|
124
336
|
}
|
|
337
|
+
this.root.focusThumb(finger.thumbIndex);
|
|
338
|
+
control.setPointerCapture(event.pointerId);
|
|
339
|
+
this.moveCount = 0;
|
|
340
|
+
this.document.addEventListener('pointermove', this.onMove);
|
|
341
|
+
this.document.addEventListener('pointerup', this.onUp, { once: true });
|
|
342
|
+
this.document.addEventListener('pointercancel', this.onCancel, { once: true });
|
|
125
343
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
if (
|
|
134
|
-
|
|
344
|
+
handleMove(event) {
|
|
345
|
+
this.moveCount += 1;
|
|
346
|
+
if (event.buttons === 0) {
|
|
347
|
+
this.handleUp(event);
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
const finger = this.getFingerState({ x: event.clientX, y: event.clientY });
|
|
351
|
+
if (finger == null) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
if (validateMinimumDistance(finger.value, this.root.step(), this.root.minStepsBetweenValues())) {
|
|
355
|
+
if (!this.root.dragging() && this.moveCount > INTENTIONAL_DRAG_COUNT_THRESHOLD) {
|
|
356
|
+
this.root.setDragging(true);
|
|
357
|
+
}
|
|
358
|
+
const applied = this.setValueFromPointer(finger, 'drag');
|
|
359
|
+
if (applied && finger.didSwap) {
|
|
360
|
+
this.root.focusThumb(finger.thumbIndex);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
handleUp(event) {
|
|
365
|
+
this.root.setActive(-1);
|
|
366
|
+
this.root.setDragging(false);
|
|
367
|
+
this.root.pressedThumbCenterOffset = null;
|
|
368
|
+
this.root.pressedInput = null;
|
|
369
|
+
if (this.currentInteractionValue != null) {
|
|
370
|
+
this.root.commitValue();
|
|
371
|
+
}
|
|
372
|
+
const control = this.elementRef.nativeElement;
|
|
373
|
+
if (control.hasPointerCapture?.(event.pointerId)) {
|
|
374
|
+
control.releasePointerCapture(event.pointerId);
|
|
375
|
+
}
|
|
376
|
+
this.root.resetPressedThumb();
|
|
377
|
+
this.root.pressedValues = null;
|
|
378
|
+
this.currentInteractionValue = null;
|
|
379
|
+
this.stopListening();
|
|
380
|
+
}
|
|
381
|
+
stopListening() {
|
|
382
|
+
this.document.removeEventListener('pointermove', this.onMove);
|
|
383
|
+
this.document.removeEventListener('pointerup', this.onUp);
|
|
384
|
+
this.document.removeEventListener('pointercancel', this.onCancel);
|
|
385
|
+
}
|
|
386
|
+
startPressing(finger) {
|
|
387
|
+
const values = this.root.values();
|
|
388
|
+
const range = this.root.range();
|
|
389
|
+
this.root.pressedValues = range ? values.slice() : null;
|
|
390
|
+
this.currentInteractionValue = null;
|
|
391
|
+
const pressedThumbIndex = this.root.pressedThumbIndex;
|
|
392
|
+
let closestThumbIndex = pressedThumbIndex;
|
|
393
|
+
if (pressedThumbIndex > -1 && pressedThumbIndex < values.length) {
|
|
394
|
+
// Pressed directly on a thumb sitting on max — walk left over stacked max thumbs.
|
|
395
|
+
if (values[pressedThumbIndex] === this.root.max()) {
|
|
396
|
+
let c = pressedThumbIndex;
|
|
397
|
+
while (c > 0 && values[c - 1] === this.root.max()) {
|
|
398
|
+
c -= 1;
|
|
399
|
+
}
|
|
400
|
+
closestThumbIndex = c;
|
|
401
|
+
}
|
|
135
402
|
}
|
|
136
403
|
else {
|
|
137
|
-
|
|
404
|
+
// Pressed on the rail — find the nearest enabled thumb by midpoint distance.
|
|
405
|
+
const axis = this.root.orientation() === 'horizontal' ? 'x' : 'y';
|
|
406
|
+
const thumbs = this.root.thumbList();
|
|
407
|
+
let minDistance;
|
|
408
|
+
closestThumbIndex = -1;
|
|
409
|
+
for (let i = 0; i < thumbs.length; i += 1) {
|
|
410
|
+
const thumb = thumbs[i];
|
|
411
|
+
if (thumb.disabled()) {
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
414
|
+
const midpoint = getMidpoint(thumb.element);
|
|
415
|
+
const distance = Math.abs(finger[axis] - midpoint[axis]);
|
|
416
|
+
if (minDistance === undefined || distance <= minDistance) {
|
|
417
|
+
closestThumbIndex = i;
|
|
418
|
+
minDistance = distance;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
if (closestThumbIndex > -1 && closestThumbIndex !== pressedThumbIndex) {
|
|
423
|
+
this.root.pressedThumbIndex = closestThumbIndex;
|
|
424
|
+
this.root.pressedInput = this.root.thumbList()[closestThumbIndex]?.inputElement ?? null;
|
|
138
425
|
}
|
|
139
426
|
}
|
|
140
|
-
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
427
|
+
setValueFromPointer(finger, reason) {
|
|
428
|
+
const nextValues = Array.isArray(finger.value) ? finger.value : [finger.value];
|
|
429
|
+
const applied = this.root.setValue(nextValues, reason);
|
|
430
|
+
if (applied) {
|
|
431
|
+
this.currentInteractionValue = finger.value;
|
|
432
|
+
if (finger.didSwap) {
|
|
433
|
+
this.root.pressedThumbIndex = finger.thumbIndex;
|
|
434
|
+
this.root.pressedInput = this.root.thumbList()[finger.thumbIndex]?.inputElement ?? null;
|
|
435
|
+
}
|
|
144
436
|
}
|
|
437
|
+
return applied;
|
|
145
438
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
439
|
+
/** Projects a pointer position onto the track and resolves it to a value (+ collision). */
|
|
440
|
+
getFingerState(finger) {
|
|
441
|
+
const control = this.root.controlRef();
|
|
442
|
+
const values = this.root.values();
|
|
443
|
+
const range = this.root.range();
|
|
444
|
+
const thumbIndex = this.root.pressedThumbIndex;
|
|
445
|
+
const vertical = this.root.orientation() === 'vertical';
|
|
446
|
+
const rtl = this.root.dir() === 'rtl';
|
|
447
|
+
const min = this.root.min();
|
|
448
|
+
const max = this.root.max();
|
|
449
|
+
const step = this.root.step();
|
|
450
|
+
if (!control || (!range && (thumbIndex < 0 || thumbIndex >= values.length))) {
|
|
451
|
+
return null;
|
|
452
|
+
}
|
|
453
|
+
const { width, height, bottom, left, right } = control.getBoundingClientRect();
|
|
454
|
+
const controlOffset = getControlOffset(this.styles, vertical, rtl);
|
|
455
|
+
const controlSize = (vertical ? height : width) - controlOffset.start - controlOffset.end;
|
|
456
|
+
// A collapsed/unmeasurable track would divide by zero and yield NaN values.
|
|
457
|
+
if (!(controlSize > 0)) {
|
|
458
|
+
return null;
|
|
459
|
+
}
|
|
460
|
+
const thumbCenterOffset = this.root.pressedThumbCenterOffset ?? 0;
|
|
461
|
+
const fingerX = finger.x - thumbCenterOffset;
|
|
462
|
+
const fingerY = finger.y - thumbCenterOffset;
|
|
463
|
+
const valueSize = vertical
|
|
464
|
+
? bottom - fingerY - controlOffset.end
|
|
465
|
+
: (rtl ? right - fingerX : fingerX - left) - controlOffset.start;
|
|
466
|
+
const valueRescaled = clamp(valueSize / controlSize, 0, 1);
|
|
467
|
+
let newValue = (max - min) * valueRescaled + min;
|
|
468
|
+
newValue = roundValueToStep(newValue, step, min);
|
|
469
|
+
newValue = clamp(newValue, min, max);
|
|
470
|
+
if (!range) {
|
|
471
|
+
return { value: newValue, thumbIndex, didSwap: false };
|
|
151
472
|
}
|
|
473
|
+
if (thumbIndex < 0) {
|
|
474
|
+
return null;
|
|
475
|
+
}
|
|
476
|
+
return resolveThumbCollision({
|
|
477
|
+
behavior: this.root.thumbCollisionBehavior(),
|
|
478
|
+
values,
|
|
479
|
+
currentValues: values,
|
|
480
|
+
initialValues: this.root.pressedValues,
|
|
481
|
+
pressedIndex: thumbIndex,
|
|
482
|
+
nextValue: newValue,
|
|
483
|
+
min,
|
|
484
|
+
max,
|
|
485
|
+
step,
|
|
486
|
+
minStepsBetweenValues: this.root.minStepsBetweenValues()
|
|
487
|
+
});
|
|
152
488
|
}
|
|
153
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
154
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
489
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxSliderControl, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
490
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxSliderControl, isStandalone: true, selector: "div[rdxSliderControl]", host: { listeners: { "pointerdown": "onPointerDown($event)" }, properties: { "attr.data-orientation": "root.orientation()", "attr.data-disabled": "root.isDisabled() ? \"\" : undefined", "attr.data-dragging": "root.dragging() ? \"\" : undefined" } }, exportAs: ["rdxSliderControl"], ngImport: i0 }); }
|
|
155
491
|
}
|
|
156
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
492
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxSliderControl, decorators: [{
|
|
157
493
|
type: Directive,
|
|
158
494
|
args: [{
|
|
159
|
-
selector: '[
|
|
495
|
+
selector: 'div[rdxSliderControl]',
|
|
496
|
+
exportAs: 'rdxSliderControl',
|
|
160
497
|
host: {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
'
|
|
164
|
-
'(pointerdown)': 'onPointerDown($event)'
|
|
165
|
-
'(pointermove)': 'onPointerMove($event)',
|
|
166
|
-
'(pointerup)': 'onPointerUp($event)'
|
|
498
|
+
'[attr.data-orientation]': 'root.orientation()',
|
|
499
|
+
'[attr.data-disabled]': 'root.isDisabled() ? "" : undefined',
|
|
500
|
+
'[attr.data-dragging]': 'root.dragging() ? "" : undefined',
|
|
501
|
+
'(pointerdown)': 'onPointerDown($event)'
|
|
167
502
|
}
|
|
168
503
|
}]
|
|
169
|
-
}] });
|
|
504
|
+
}], ctorParameters: () => [] });
|
|
170
505
|
|
|
171
|
-
|
|
506
|
+
/**
|
|
507
|
+
* Visualises the portion of the track between the slider's minimum (or the first
|
|
508
|
+
* thumb in a range) and the active value.
|
|
509
|
+
*
|
|
510
|
+
* @see https://base-ui.com/react/components/slider
|
|
511
|
+
*/
|
|
512
|
+
class RdxSliderIndicator {
|
|
172
513
|
constructor() {
|
|
173
|
-
this.
|
|
174
|
-
this.
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
const slideDirection = this.rootContext.isSlidingFromLeft() ? 'from-left' : 'from-right';
|
|
202
|
-
const isBackKey = BACK_KEYS[slideDirection].includes(event.key);
|
|
203
|
-
this.stepKeyDown.emit({ event, direction: isBackKey ? -1 : 1 });
|
|
204
|
-
}
|
|
205
|
-
getValueFromPointer(pointerPosition) {
|
|
206
|
-
this.rect.set(this.sliderElement()?.nativeElement.getBoundingClientRect());
|
|
207
|
-
const rect = this.rect();
|
|
208
|
-
if (!rect)
|
|
209
|
-
return 0;
|
|
210
|
-
const input = [0, rect.width];
|
|
211
|
-
const output = this.rootContext.isSlidingFromLeft()
|
|
212
|
-
? [this.min, this.max]
|
|
213
|
-
: [this.max, this.min];
|
|
214
|
-
const value = linearScale(input, output);
|
|
215
|
-
this.rect.set(rect);
|
|
216
|
-
return value(pointerPosition - rect.left);
|
|
217
|
-
}
|
|
218
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxSliderHorizontalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
219
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.3", type: RdxSliderHorizontalComponent, isStandalone: true, selector: "rdx-slider-horizontal", inputs: { dir: { classPropertyName: "dir", publicName: "dir", isSignal: false, isRequired: false, transformFunction: null }, inverted: { classPropertyName: "inverted", publicName: "inverted", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: false, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: false, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { slideStart: "slideStart", slideMove: "slideMove", slideEnd: "slideEnd", stepKeyDown: "stepKeyDown", endKeyDown: "endKeyDown", homeKeyDown: "homeKeyDown" }, viewQueries: [{ propertyName: "sliderElement", first: true, predicate: ["sliderElement"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
220
|
-
<span
|
|
221
|
-
#sliderElement
|
|
222
|
-
[class]="className"
|
|
223
|
-
[attr.data-orientation]="'horizontal'"
|
|
224
|
-
[style]="{ '--rdx-slider-thumb-transform': 'translateX(-50%)' }"
|
|
225
|
-
(slideStart)="onSlideStart($event)"
|
|
226
|
-
(slideMove)="onSlideMove($event)"
|
|
227
|
-
(slideEnd)="onSlideEnd()"
|
|
228
|
-
(stepKeyDown)="onStepKeyDown($event)"
|
|
229
|
-
(endKeyDown)="endKeyDown.emit($event)"
|
|
230
|
-
(homeKeyDown)="homeKeyDown.emit($event)"
|
|
231
|
-
rdxSliderImpl
|
|
232
|
-
>
|
|
233
|
-
<ng-content />
|
|
234
|
-
</span>
|
|
235
|
-
`, isInline: true, dependencies: [{ kind: "directive", type: RdxSliderImplDirective, selector: "[rdxSliderImpl]", outputs: ["slideStart", "slideMove", "slideEnd", "homeKeyDown", "endKeyDown", "stepKeyDown"] }] }); }
|
|
514
|
+
this.root = injectSliderRootContext();
|
|
515
|
+
this.indicatorStyle = computed(() => {
|
|
516
|
+
const vertical = this.root.orientation() === 'vertical';
|
|
517
|
+
const range = this.root.range();
|
|
518
|
+
const values = this.root.values();
|
|
519
|
+
const min = this.root.min();
|
|
520
|
+
const max = this.root.max();
|
|
521
|
+
const startEdge = vertical ? 'bottom' : 'inset-inline-start';
|
|
522
|
+
const mainSide = vertical ? 'height' : 'width';
|
|
523
|
+
const crossSide = vertical ? 'width' : 'height';
|
|
524
|
+
const start = valueToPercent(values[0], min, max);
|
|
525
|
+
const end = valueToPercent(values[values.length - 1], min, max);
|
|
526
|
+
const styles = {
|
|
527
|
+
position: vertical ? 'absolute' : 'relative',
|
|
528
|
+
[crossSide]: 'inherit'
|
|
529
|
+
};
|
|
530
|
+
if (!range) {
|
|
531
|
+
styles[startEdge] = 0;
|
|
532
|
+
styles[mainSide] = `${start}%`;
|
|
533
|
+
return styles;
|
|
534
|
+
}
|
|
535
|
+
styles[startEdge] = `${start}%`;
|
|
536
|
+
styles[mainSide] = `${end - start}%`;
|
|
537
|
+
return styles;
|
|
538
|
+
}, ...(ngDevMode ? [{ debugName: "indicatorStyle" }] : /* istanbul ignore next */ []));
|
|
539
|
+
}
|
|
540
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxSliderIndicator, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
541
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxSliderIndicator, isStandalone: true, selector: "div[rdxSliderIndicator]", host: { properties: { "style": "indicatorStyle()", "attr.data-orientation": "root.orientation()", "attr.data-disabled": "root.isDisabled() ? \"\" : undefined", "attr.data-dragging": "root.dragging() ? \"\" : undefined" } }, exportAs: ["rdxSliderIndicator"], ngImport: i0 }); }
|
|
236
542
|
}
|
|
237
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
238
|
-
type:
|
|
543
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxSliderIndicator, decorators: [{
|
|
544
|
+
type: Directive,
|
|
239
545
|
args: [{
|
|
240
|
-
selector: '
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
(slideStart)="onSlideStart($event)"
|
|
249
|
-
(slideMove)="onSlideMove($event)"
|
|
250
|
-
(slideEnd)="onSlideEnd()"
|
|
251
|
-
(stepKeyDown)="onStepKeyDown($event)"
|
|
252
|
-
(endKeyDown)="endKeyDown.emit($event)"
|
|
253
|
-
(homeKeyDown)="homeKeyDown.emit($event)"
|
|
254
|
-
rdxSliderImpl
|
|
255
|
-
>
|
|
256
|
-
<ng-content />
|
|
257
|
-
</span>
|
|
258
|
-
`
|
|
546
|
+
selector: 'div[rdxSliderIndicator]',
|
|
547
|
+
exportAs: 'rdxSliderIndicator',
|
|
548
|
+
host: {
|
|
549
|
+
'[style]': 'indicatorStyle()',
|
|
550
|
+
'[attr.data-orientation]': 'root.orientation()',
|
|
551
|
+
'[attr.data-disabled]': 'root.isDisabled() ? "" : undefined',
|
|
552
|
+
'[attr.data-dragging]': 'root.dragging() ? "" : undefined'
|
|
553
|
+
}
|
|
259
554
|
}]
|
|
260
|
-
}], propDecorators: { dir: [{
|
|
261
|
-
type: Input
|
|
262
|
-
}], min: [{
|
|
263
|
-
type: Input
|
|
264
|
-
}], max: [{
|
|
265
|
-
type: Input
|
|
266
|
-
}], className: [{
|
|
267
|
-
type: Input
|
|
268
|
-
}] } });
|
|
269
|
-
|
|
270
|
-
class RdxSliderOrientationContextService {
|
|
271
|
-
constructor() {
|
|
272
|
-
this.contextSignal = signal({
|
|
273
|
-
startEdge: 'left',
|
|
274
|
-
endEdge: 'right',
|
|
275
|
-
direction: 1,
|
|
276
|
-
size: 'width'
|
|
277
|
-
}, ...(ngDevMode ? [{ debugName: "contextSignal" }] : []));
|
|
278
|
-
}
|
|
279
|
-
get context() {
|
|
280
|
-
return this.contextSignal();
|
|
281
|
-
}
|
|
282
|
-
updateContext(context) {
|
|
283
|
-
this.contextSignal.update((current) => ({
|
|
284
|
-
...current,
|
|
285
|
-
...context
|
|
286
|
-
}));
|
|
287
|
-
}
|
|
288
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxSliderOrientationContextService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
289
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxSliderOrientationContextService }); }
|
|
290
|
-
}
|
|
291
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxSliderOrientationContextService, decorators: [{
|
|
292
|
-
type: Injectable
|
|
293
555
|
}] });
|
|
294
556
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
this.stepKeyDown = output();
|
|
307
|
-
this.endKeyDown = output();
|
|
308
|
-
this.homeKeyDown = output();
|
|
309
|
-
this.sliderElement = viewChild('sliderElement', ...(ngDevMode ? [{ debugName: "sliderElement" }] : []));
|
|
310
|
-
this.rect = signal(undefined, ...(ngDevMode ? [{ debugName: "rect" }] : []));
|
|
311
|
-
}
|
|
312
|
-
onSlideStart(event) {
|
|
313
|
-
const value = this.getValueFromPointer(event.clientY);
|
|
314
|
-
this.slideStart.emit(value);
|
|
315
|
-
}
|
|
316
|
-
onSlideMove(event) {
|
|
317
|
-
const value = this.getValueFromPointer(event.clientY);
|
|
318
|
-
this.slideMove.emit(value);
|
|
319
|
-
}
|
|
320
|
-
onSlideEnd() {
|
|
321
|
-
this.rect.set(undefined);
|
|
322
|
-
this.slideEnd.emit();
|
|
323
|
-
}
|
|
324
|
-
onStepKeyDown(event) {
|
|
325
|
-
const slideDirection = this.rootContext.isSlidingFromBottom() ? 'from-bottom' : 'from-top';
|
|
326
|
-
const isBackKey = BACK_KEYS[slideDirection].includes(event.key);
|
|
327
|
-
this.stepKeyDown.emit({ event, direction: isBackKey ? -1 : 1 });
|
|
328
|
-
}
|
|
329
|
-
getValueFromPointer(pointerPosition) {
|
|
330
|
-
this.rect.set(this.sliderElement()?.nativeElement.getBoundingClientRect());
|
|
331
|
-
const rect = this.rect();
|
|
332
|
-
if (!rect)
|
|
333
|
-
return 0;
|
|
334
|
-
const input = [0, rect.height];
|
|
335
|
-
const output = this.rootContext.isSlidingFromBottom()
|
|
336
|
-
? [this.max, this.min]
|
|
337
|
-
: [this.min, this.max];
|
|
338
|
-
const value = linearScale(input, output);
|
|
339
|
-
this.rect.set(rect);
|
|
340
|
-
return value(pointerPosition - rect.top);
|
|
341
|
-
}
|
|
342
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxSliderVerticalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
343
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.3", type: RdxSliderVerticalComponent, isStandalone: true, selector: "rdx-slider-vertical", inputs: { dir: { classPropertyName: "dir", publicName: "dir", isSignal: false, isRequired: false, transformFunction: null }, inverted: { classPropertyName: "inverted", publicName: "inverted", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: false, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: false, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { slideStart: "slideStart", slideMove: "slideMove", slideEnd: "slideEnd", stepKeyDown: "stepKeyDown", endKeyDown: "endKeyDown", homeKeyDown: "homeKeyDown" }, viewQueries: [{ propertyName: "sliderElement", first: true, predicate: ["sliderElement"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
344
|
-
<span
|
|
345
|
-
#sliderElement
|
|
346
|
-
[class]="className"
|
|
347
|
-
[attr.data-orientation]="'vertical'"
|
|
348
|
-
[style]="{ '--rdx-slider-thumb-transform': 'translateY(-50%)' }"
|
|
349
|
-
(slideStart)="onSlideStart($event)"
|
|
350
|
-
(slideMove)="onSlideMove($event)"
|
|
351
|
-
(slideEnd)="onSlideEnd()"
|
|
352
|
-
(stepKeyDown)="onStepKeyDown($event)"
|
|
353
|
-
(endKeyDown)="endKeyDown.emit($event)"
|
|
354
|
-
(homeKeyDown)="homeKeyDown.emit($event)"
|
|
355
|
-
rdxSliderImpl
|
|
356
|
-
>
|
|
357
|
-
<ng-content />
|
|
358
|
-
</span>
|
|
359
|
-
`, isInline: true, dependencies: [{ kind: "directive", type: RdxSliderImplDirective, selector: "[rdxSliderImpl]", outputs: ["slideStart", "slideMove", "slideEnd", "homeKeyDown", "endKeyDown", "stepKeyDown"] }] }); }
|
|
557
|
+
function sortByDomOrder(list) {
|
|
558
|
+
return list.slice().sort((a, b) => {
|
|
559
|
+
const position = a.element.compareDocumentPosition(b.element);
|
|
560
|
+
if (position & Node.DOCUMENT_POSITION_FOLLOWING) {
|
|
561
|
+
return -1;
|
|
562
|
+
}
|
|
563
|
+
if (position & Node.DOCUMENT_POSITION_PRECEDING) {
|
|
564
|
+
return 1;
|
|
565
|
+
}
|
|
566
|
+
return 0;
|
|
567
|
+
});
|
|
360
568
|
}
|
|
361
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxSliderVerticalComponent, decorators: [{
|
|
362
|
-
type: Component,
|
|
363
|
-
args: [{
|
|
364
|
-
selector: 'rdx-slider-vertical',
|
|
365
|
-
imports: [RdxSliderImplDirective],
|
|
366
|
-
template: `
|
|
367
|
-
<span
|
|
368
|
-
#sliderElement
|
|
369
|
-
[class]="className"
|
|
370
|
-
[attr.data-orientation]="'vertical'"
|
|
371
|
-
[style]="{ '--rdx-slider-thumb-transform': 'translateY(-50%)' }"
|
|
372
|
-
(slideStart)="onSlideStart($event)"
|
|
373
|
-
(slideMove)="onSlideMove($event)"
|
|
374
|
-
(slideEnd)="onSlideEnd()"
|
|
375
|
-
(stepKeyDown)="onStepKeyDown($event)"
|
|
376
|
-
(endKeyDown)="endKeyDown.emit($event)"
|
|
377
|
-
(homeKeyDown)="homeKeyDown.emit($event)"
|
|
378
|
-
rdxSliderImpl
|
|
379
|
-
>
|
|
380
|
-
<ng-content />
|
|
381
|
-
</span>
|
|
382
|
-
`
|
|
383
|
-
}]
|
|
384
|
-
}], propDecorators: { dir: [{
|
|
385
|
-
type: Input
|
|
386
|
-
}], min: [{
|
|
387
|
-
type: Input
|
|
388
|
-
}], max: [{
|
|
389
|
-
type: Input
|
|
390
|
-
}], className: [{
|
|
391
|
-
type: Input
|
|
392
|
-
}] } });
|
|
393
|
-
|
|
394
569
|
/**
|
|
395
|
-
*
|
|
570
|
+
* Groups all parts of the slider and owns its state, value-change logic and
|
|
571
|
+
* thumb registration. A single directive drives both orientations — there are no
|
|
572
|
+
* separate horizontal/vertical components.
|
|
573
|
+
*
|
|
574
|
+
* @see https://base-ui.com/react/components/slider
|
|
396
575
|
*/
|
|
397
|
-
class
|
|
576
|
+
class RdxSliderRoot {
|
|
398
577
|
constructor() {
|
|
399
578
|
/** @ignore */
|
|
400
|
-
this.
|
|
579
|
+
this.cva = injectControlValueAccessor();
|
|
580
|
+
this.id = input(injectId('rdx-slider-'), ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
401
581
|
/**
|
|
402
|
-
* The minimum value
|
|
403
|
-
*
|
|
404
|
-
* @group Props
|
|
405
|
-
* @defaultValue 0
|
|
582
|
+
* The minimum value of the slider.
|
|
583
|
+
* @default 0
|
|
406
584
|
*/
|
|
407
|
-
this.min = input(0, ...(ngDevMode ?
|
|
585
|
+
this.min = input(0, { ...(ngDevMode ? { debugName: "min" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
408
586
|
/**
|
|
409
|
-
* The maximum value
|
|
410
|
-
*
|
|
411
|
-
* @group Props
|
|
412
|
-
* @defaultValue 100
|
|
587
|
+
* The maximum value of the slider.
|
|
588
|
+
* @default 100
|
|
413
589
|
*/
|
|
414
|
-
this.max = input(100, ...(ngDevMode ?
|
|
590
|
+
this.max = input(100, { ...(ngDevMode ? { debugName: "max" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
415
591
|
/**
|
|
416
|
-
* The
|
|
417
|
-
*
|
|
418
|
-
* @group Props
|
|
419
|
-
* @defaultValue 1
|
|
592
|
+
* The granularity with which the value can change through user interaction.
|
|
593
|
+
* @default 1
|
|
420
594
|
*/
|
|
421
|
-
this.step = input(1, ...(ngDevMode ?
|
|
595
|
+
this.step = input(1, { ...(ngDevMode ? { debugName: "step" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
422
596
|
/**
|
|
423
|
-
* The
|
|
424
|
-
*
|
|
425
|
-
* @group Props
|
|
426
|
-
* @defaultValue 0
|
|
597
|
+
* The granularity with which the value changes on Page Up / Page Down keys and Shift + Arrow keys.
|
|
598
|
+
* @default 10
|
|
427
599
|
*/
|
|
428
|
-
this.
|
|
600
|
+
this.largeStep = input(10, { ...(ngDevMode ? { debugName: "largeStep" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
429
601
|
/**
|
|
430
|
-
* The
|
|
431
|
-
*
|
|
432
|
-
* @group Props
|
|
433
|
-
* @defaultValue 'horizontal'
|
|
602
|
+
* The minimum number of steps that must separate two thumbs in a range slider.
|
|
603
|
+
* @default 0
|
|
434
604
|
*/
|
|
435
|
-
this.
|
|
605
|
+
this.minStepsBetweenValues = input(0, { ...(ngDevMode ? { debugName: "minStepsBetweenValues" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
436
606
|
/**
|
|
437
|
-
*
|
|
438
|
-
*
|
|
439
|
-
* @group Props
|
|
440
|
-
* @defaultValue false
|
|
441
|
-
*/
|
|
442
|
-
this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
443
|
-
/**
|
|
444
|
-
* Whether the slider is visually inverted.
|
|
445
|
-
*
|
|
446
|
-
* @group Props
|
|
447
|
-
* @defaultValue false
|
|
448
|
-
*/
|
|
449
|
-
this.inverted = input(false, ...(ngDevMode ? [{ debugName: "inverted", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
450
|
-
/**
|
|
451
|
-
* The reading direction of the combobox when applicable.
|
|
452
|
-
*
|
|
453
|
-
* @group Props
|
|
454
|
-
* @defaultValue 'ltr'
|
|
455
|
-
*/
|
|
456
|
-
this.dir = input('ltr', ...(ngDevMode ? [{ debugName: "dir" }] : []));
|
|
457
|
-
this.className = '';
|
|
458
|
-
/**
|
|
459
|
-
* Style class of the component.
|
|
460
|
-
*
|
|
461
|
-
* @group Props
|
|
607
|
+
* The orientation of the slider.
|
|
608
|
+
* @default 'horizontal'
|
|
462
609
|
*/
|
|
463
|
-
this.
|
|
610
|
+
this.orientation = input('horizontal', ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
|
|
464
611
|
/**
|
|
465
|
-
* The
|
|
466
|
-
*
|
|
467
|
-
* @group Props
|
|
612
|
+
* The reading direction. Mirrors the horizontal axis when set to `'rtl'`.
|
|
613
|
+
* @default 'ltr'
|
|
468
614
|
*/
|
|
469
|
-
this.
|
|
615
|
+
this.dir = input('ltr', ...(ngDevMode ? [{ debugName: "dir" }] : /* istanbul ignore next */ []));
|
|
470
616
|
/**
|
|
471
|
-
*
|
|
472
|
-
*
|
|
473
|
-
* @group Emits
|
|
617
|
+
* How thumbs behave when they meet in a range slider.
|
|
618
|
+
* @default 'push'
|
|
474
619
|
*/
|
|
475
|
-
this.
|
|
620
|
+
this.thumbCollisionBehavior = input('push', ...(ngDevMode ? [{ debugName: "thumbCollisionBehavior" }] : /* istanbul ignore next */ []));
|
|
621
|
+
/** Options forwarded to `Intl.NumberFormat` when displaying and announcing values. */
|
|
622
|
+
this.format = input(...(ngDevMode ? [undefined, { debugName: "format" }] : /* istanbul ignore next */ []));
|
|
623
|
+
/** Locale used for value formatting. */
|
|
624
|
+
this.locale = input(...(ngDevMode ? [undefined, { debugName: "locale" }] : /* istanbul ignore next */ []));
|
|
625
|
+
/** Name of the hidden inputs rendered by each thumb, for form submission. */
|
|
626
|
+
this.name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : /* istanbul ignore next */ []));
|
|
627
|
+
/** Id of the form the slider belongs to. */
|
|
628
|
+
this.form = input(...(ngDevMode ? [undefined, { debugName: "form" }] : /* istanbul ignore next */ []));
|
|
476
629
|
/**
|
|
477
|
-
*
|
|
478
|
-
*
|
|
479
|
-
* Useful when you only need to capture a final value e.g. to update a backend service.
|
|
480
|
-
*
|
|
481
|
-
* @group Emits
|
|
630
|
+
* When `true`, the user cannot interact with the slider.
|
|
631
|
+
* @default false
|
|
482
632
|
*/
|
|
483
|
-
this.
|
|
633
|
+
this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
634
|
+
/** The uncontrolled value of the slider when it is initially rendered. */
|
|
635
|
+
this.defaultValue = input(...(ngDevMode ? [undefined, { debugName: "defaultValue" }] : /* istanbul ignore next */ []));
|
|
636
|
+
/** The controlled value of the slider. Use with `(onValueChange)` or two-way `[(value)]`. */
|
|
637
|
+
this.value = model(...(ngDevMode ? [undefined, { debugName: "value" }] : /* istanbul ignore next */ []));
|
|
638
|
+
this.ariaLabelledBy = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabelledBy" } : /* istanbul ignore next */ {}), alias: 'aria-labelledby' });
|
|
639
|
+
/** Emitted when the value changes (during interaction). */
|
|
640
|
+
this.onValueChange = output();
|
|
641
|
+
/** Emitted when interaction ends, with the final value — useful for committing to a backend. */
|
|
642
|
+
this.onValueCommitted = output();
|
|
484
643
|
/** @ignore */
|
|
485
|
-
this.
|
|
644
|
+
this.controlRef = signal(null, ...(ngDevMode ? [{ debugName: "controlRef" }] : /* istanbul ignore next */ []));
|
|
645
|
+
/** @ignore Active thumb index (-1 when none). */
|
|
646
|
+
this.active = signal(-1, ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
|
|
647
|
+
/** @ignore Last thumb index that was focused/used, drives z-index stacking. */
|
|
648
|
+
this.lastUsedThumbIndex = signal(-1, ...(ngDevMode ? [{ debugName: "lastUsedThumbIndex" }] : /* istanbul ignore next */ []));
|
|
649
|
+
/** @ignore Whether a pointer drag is in progress. */
|
|
650
|
+
this.dragging = signal(false, ...(ngDevMode ? [{ debugName: "dragging" }] : /* istanbul ignore next */ []));
|
|
651
|
+
/** @ignore Pointer-drag scratch state (not reactive). */
|
|
652
|
+
this.pressedThumbIndex = -1;
|
|
486
653
|
/** @ignore */
|
|
487
|
-
this.
|
|
654
|
+
this.pressedThumbCenterOffset = null;
|
|
488
655
|
/** @ignore */
|
|
489
|
-
this.
|
|
656
|
+
this.pressedInput = null;
|
|
657
|
+
/** @ignore Snapshot of values at drag start, the baseline for push/swap. */
|
|
658
|
+
this.pressedValues = null;
|
|
490
659
|
/** @ignore */
|
|
491
|
-
this.
|
|
660
|
+
this.lastChangeReason = 'none';
|
|
492
661
|
/** @ignore */
|
|
493
|
-
this.
|
|
662
|
+
this.isDisabled = computed(() => !!this.cva.disabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
663
|
+
/** @ignore The current value source (controlled value, else default, else min). */
|
|
664
|
+
this.currentRaw = computed(() => this.cva.value() ?? this.defaultValue() ?? this.min(), ...(ngDevMode ? [{ debugName: "currentRaw" }] : /* istanbul ignore next */ []));
|
|
665
|
+
/** Whether the slider has multiple thumbs (the value is an array). */
|
|
666
|
+
this.range = computed(() => Array.isArray(this.cva.value() ?? this.defaultValue()), ...(ngDevMode ? [{ debugName: "range" }] : /* istanbul ignore next */ []));
|
|
667
|
+
/** The clamped values rendered to the user, sorted ascending for range sliders. */
|
|
668
|
+
this.values = computed(() => {
|
|
669
|
+
const raw = this.currentRaw();
|
|
670
|
+
const min = this.min();
|
|
671
|
+
const max = this.max();
|
|
672
|
+
const arr = (Array.isArray(raw) ? raw.slice() : [raw]).map((v) => clamp(v, min, max));
|
|
673
|
+
return this.range() ? arr.sort(asc) : arr;
|
|
674
|
+
}, ...(ngDevMode ? [{ debugName: "values" }] : /* istanbul ignore next */ []));
|
|
675
|
+
this.thumbs = signal([], ...(ngDevMode ? [{ debugName: "thumbs" }] : /* istanbul ignore next */ []));
|
|
676
|
+
/** Registered thumbs in DOM order. */
|
|
677
|
+
this.thumbList = this.thumbs.asReadonly();
|
|
494
678
|
}
|
|
495
679
|
/** @ignore */
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
if (isHorizontal) {
|
|
499
|
-
this.orientationContext.updateContext({
|
|
500
|
-
direction: this.isSlidingFromLeft() ? 1 : -1,
|
|
501
|
-
size: 'width',
|
|
502
|
-
startEdge: this.isSlidingFromLeft() ? 'left' : 'right',
|
|
503
|
-
endEdge: this.isSlidingFromLeft() ? 'right' : 'left'
|
|
504
|
-
});
|
|
505
|
-
}
|
|
506
|
-
else {
|
|
507
|
-
this.orientationContext.updateContext({
|
|
508
|
-
direction: this.isSlidingFromBottom() ? -1 : 1,
|
|
509
|
-
size: 'height',
|
|
510
|
-
startEdge: this.isSlidingFromBottom() ? 'bottom' : 'top',
|
|
511
|
-
endEdge: this.isSlidingFromBottom() ? 'top' : 'bottom'
|
|
512
|
-
});
|
|
513
|
-
}
|
|
680
|
+
registerThumb(thumb) {
|
|
681
|
+
this.thumbs.update((list) => sortByDomOrder([...list, thumb]));
|
|
514
682
|
}
|
|
515
683
|
/** @ignore */
|
|
516
|
-
|
|
517
|
-
this.
|
|
684
|
+
unregisterThumb(thumb) {
|
|
685
|
+
this.thumbs.update((list) => list.filter((t) => t !== thumb));
|
|
518
686
|
}
|
|
519
687
|
/** @ignore */
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
this.updateValues(value, closestIndex);
|
|
688
|
+
thumbIndexOf(thumb) {
|
|
689
|
+
return this.thumbList().indexOf(thumb);
|
|
523
690
|
}
|
|
524
691
|
/** @ignore */
|
|
525
|
-
|
|
526
|
-
this.
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
handleSlideEnd() {
|
|
530
|
-
const prevValue = this.valuesBeforeSlideStart()[this.valueIndexToChange()];
|
|
531
|
-
const nextValue = this.modelValue()[this.valueIndexToChange()];
|
|
532
|
-
const hasChanged = nextValue !== prevValue;
|
|
533
|
-
if (hasChanged) {
|
|
534
|
-
this.valueCommit.emit([...this.modelValue()]);
|
|
692
|
+
setActive(index) {
|
|
693
|
+
this.active.set(index);
|
|
694
|
+
if (index !== -1) {
|
|
695
|
+
this.lastUsedThumbIndex.set(index);
|
|
535
696
|
}
|
|
536
697
|
}
|
|
537
698
|
/** @ignore */
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
const atIndex = this.valueIndexToChange();
|
|
541
|
-
const currentValue = this.modelValue()[atIndex];
|
|
542
|
-
this.updateValues(currentValue + stepInDirection, atIndex, true);
|
|
699
|
+
focusThumb(index) {
|
|
700
|
+
this.thumbList()[index]?.inputElement?.focus({ preventScroll: true });
|
|
543
701
|
}
|
|
544
702
|
/** @ignore */
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
if (hasChanged) {
|
|
554
|
-
this.modelValue.set(nextValues);
|
|
555
|
-
this.valueChange.emit([...this.modelValue()]);
|
|
556
|
-
this.thumbElements[this.valueIndexToChange()]?.focus();
|
|
557
|
-
if (commit) {
|
|
558
|
-
this.valueCommit.emit([...this.modelValue()]);
|
|
559
|
-
}
|
|
560
|
-
}
|
|
703
|
+
formatValue(value) {
|
|
704
|
+
return formatNumber(value, this.locale(), this.format());
|
|
705
|
+
}
|
|
706
|
+
/** @ignore Output value matching the original value shape (number vs array). */
|
|
707
|
+
outputValue() {
|
|
708
|
+
const raw = this.cva.value();
|
|
709
|
+
if (raw !== undefined) {
|
|
710
|
+
return raw;
|
|
561
711
|
}
|
|
712
|
+
return this.range() ? this.values() : this.values()[0];
|
|
562
713
|
}
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
[attr.aria-disabled]="disabled()"
|
|
575
|
-
[attr.data-disabled]="disabled() ? '' : undefined"
|
|
576
|
-
(pointerdown)="onPointerDown()"
|
|
577
|
-
(slideStart)="handleSlideStart($event)"
|
|
578
|
-
(slideMove)="handleSlideMove($event)"
|
|
579
|
-
(slideEnd)="handleSlideEnd()"
|
|
580
|
-
(homeKeyDown)="updateValues(min(), 0, true)"
|
|
581
|
-
(endKeyDown)="updateValues(max(), modelValue().length - 1, true)"
|
|
582
|
-
(stepKeyDown)="handleStepKeyDown($event)"
|
|
583
|
-
>
|
|
584
|
-
<ng-container *ngTemplateOutlet="transclude" />
|
|
585
|
-
</rdx-slider-horizontal>
|
|
714
|
+
/**
|
|
715
|
+
* @ignore
|
|
716
|
+
* Applies a new full set of values, preserving the single/range value shape.
|
|
717
|
+
* Returns `false` when the value did not change.
|
|
718
|
+
*/
|
|
719
|
+
setValue(nextValues, reason) {
|
|
720
|
+
const next = this.range() ? nextValues : nextValues[0];
|
|
721
|
+
const current = this.outputValue();
|
|
722
|
+
const hasNaN = Array.isArray(next) ? next.some((v) => Number.isNaN(v)) : Number.isNaN(next);
|
|
723
|
+
if (hasNaN || areValuesEqual(next, current)) {
|
|
724
|
+
return false;
|
|
586
725
|
}
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
}
|
|
608
|
-
|
|
726
|
+
this.lastChangeReason = reason;
|
|
727
|
+
this.value.set(next);
|
|
728
|
+
this.cva.setValue(next);
|
|
729
|
+
this.onValueChange.emit(next);
|
|
730
|
+
return true;
|
|
731
|
+
}
|
|
732
|
+
/** @ignore Keyboard / native input path: clamps to neighbours, commits immediately. */
|
|
733
|
+
handleInputChange(valueInput, index, reason = 'keyboard') {
|
|
734
|
+
if (this.isDisabled()) {
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
const result = getSliderValue(valueInput, index, this.min(), this.max(), this.range(), this.values());
|
|
738
|
+
if (!validateMinimumDistance(result, this.step(), this.minStepsBetweenValues())) {
|
|
739
|
+
return;
|
|
740
|
+
}
|
|
741
|
+
const arr = Array.isArray(result) ? result : [result];
|
|
742
|
+
const applied = this.setValue(arr, reason);
|
|
743
|
+
this.cva.markAsTouched();
|
|
744
|
+
if (applied) {
|
|
745
|
+
this.onValueCommitted.emit(this.outputValue());
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
/** @ignore Emits the committed value at the end of a pointer drag. */
|
|
749
|
+
commitValue() {
|
|
750
|
+
this.onValueCommitted.emit(this.outputValue());
|
|
751
|
+
}
|
|
752
|
+
/** @ignore */
|
|
753
|
+
markAsTouched() {
|
|
754
|
+
this.cva.markAsTouched();
|
|
755
|
+
}
|
|
756
|
+
/** @ignore */
|
|
757
|
+
setDragging(dragging) {
|
|
758
|
+
this.dragging.set(dragging);
|
|
759
|
+
}
|
|
760
|
+
/** @ignore */
|
|
761
|
+
resetPressedThumb() {
|
|
762
|
+
this.pressedThumbIndex = -1;
|
|
763
|
+
this.pressedThumbCenterOffset = null;
|
|
764
|
+
this.pressedInput = null;
|
|
765
|
+
}
|
|
766
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxSliderRoot, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
767
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxSliderRoot, isStandalone: true, selector: "div[rdxSliderRoot]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, largeStep: { classPropertyName: "largeStep", publicName: "largeStep", isSignal: true, isRequired: false, transformFunction: null }, minStepsBetweenValues: { classPropertyName: "minStepsBetweenValues", publicName: "minStepsBetweenValues", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, dir: { classPropertyName: "dir", publicName: "dir", isSignal: true, isRequired: false, transformFunction: null }, thumbCollisionBehavior: { classPropertyName: "thumbCollisionBehavior", publicName: "thumbCollisionBehavior", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, defaultValue: { classPropertyName: "defaultValue", publicName: "defaultValue", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledBy: { classPropertyName: "ariaLabelledBy", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", onValueChange: "onValueChange", onValueCommitted: "onValueCommitted" }, host: { attributes: { "role": "group" }, properties: { "id": "id()", "attr.aria-labelledby": "ariaLabelledBy()", "attr.dir": "dir()", "attr.data-orientation": "orientation()", "attr.data-disabled": "isDisabled() ? \"\" : undefined", "attr.data-dragging": "dragging() ? \"\" : undefined" } }, providers: [provideSliderRootContext(() => inject(RdxSliderRoot))], exportAs: ["rdxSliderRoot"], hostDirectives: [{ directive: i1.RdxControlValueAccessor, inputs: ["value", "value", "disabled", "disabled"] }], ngImport: i0 }); }
|
|
609
768
|
}
|
|
610
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
611
|
-
type:
|
|
769
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxSliderRoot, decorators: [{
|
|
770
|
+
type: Directive,
|
|
612
771
|
args: [{
|
|
613
|
-
selector: '
|
|
614
|
-
|
|
615
|
-
providers: [
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
(slideEnd)="handleSlideEnd()"
|
|
632
|
-
(homeKeyDown)="updateValues(min(), 0, true)"
|
|
633
|
-
(endKeyDown)="updateValues(max(), modelValue().length - 1, true)"
|
|
634
|
-
(stepKeyDown)="handleStepKeyDown($event)"
|
|
635
|
-
>
|
|
636
|
-
<ng-container *ngTemplateOutlet="transclude" />
|
|
637
|
-
</rdx-slider-horizontal>
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
@if (orientation() === 'vertical') {
|
|
641
|
-
<rdx-slider-vertical
|
|
642
|
-
[className]="styleClass() || className"
|
|
643
|
-
[min]="min()"
|
|
644
|
-
[max]="max()"
|
|
645
|
-
[dir]="dir()"
|
|
646
|
-
[inverted]="inverted()"
|
|
647
|
-
[attr.aria-disabled]="disabled()"
|
|
648
|
-
[attr.data-disabled]="disabled() ? '' : undefined"
|
|
649
|
-
(pointerdown)="onPointerDown()"
|
|
650
|
-
(slideStart)="handleSlideStart($event)"
|
|
651
|
-
(slideMove)="handleSlideMove($event)"
|
|
652
|
-
(slideEnd)="handleSlideEnd()"
|
|
653
|
-
(homeKeyDown)="updateValues(min(), 0, true)"
|
|
654
|
-
(endKeyDown)="updateValues(max(), modelValue().length - 1, true)"
|
|
655
|
-
(stepKeyDown)="handleStepKeyDown($event)"
|
|
656
|
-
>
|
|
657
|
-
<ng-container *ngTemplateOutlet="transclude" />
|
|
658
|
-
</rdx-slider-vertical>
|
|
659
|
-
}
|
|
660
|
-
`
|
|
772
|
+
selector: 'div[rdxSliderRoot]',
|
|
773
|
+
exportAs: 'rdxSliderRoot',
|
|
774
|
+
providers: [provideSliderRootContext(() => inject(RdxSliderRoot))],
|
|
775
|
+
hostDirectives: [
|
|
776
|
+
{
|
|
777
|
+
directive: RdxControlValueAccessor,
|
|
778
|
+
inputs: ['value: value', 'disabled']
|
|
779
|
+
}
|
|
780
|
+
],
|
|
781
|
+
host: {
|
|
782
|
+
role: 'group',
|
|
783
|
+
'[id]': 'id()',
|
|
784
|
+
'[attr.aria-labelledby]': 'ariaLabelledBy()',
|
|
785
|
+
'[attr.dir]': 'dir()',
|
|
786
|
+
'[attr.data-orientation]': 'orientation()',
|
|
787
|
+
'[attr.data-disabled]': 'isDisabled() ? "" : undefined',
|
|
788
|
+
'[attr.data-dragging]': 'dragging() ? "" : undefined'
|
|
789
|
+
}
|
|
661
790
|
}]
|
|
662
|
-
}], propDecorators: {
|
|
663
|
-
type: Input
|
|
664
|
-
}] } });
|
|
791
|
+
}], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], largeStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "largeStep", required: false }] }], minStepsBetweenValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "minStepsBetweenValues", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], dir: [{ type: i0.Input, args: [{ isSignal: true, alias: "dir", required: false }] }], thumbCollisionBehavior: [{ type: i0.Input, args: [{ isSignal: true, alias: "thumbCollisionBehavior", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], defaultValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValue", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], ariaLabelledBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-labelledby", required: false }] }], onValueChange: [{ type: i0.Output, args: ["onValueChange"] }], onValueCommitted: [{ type: i0.Output, args: ["onValueCommitted"] }] } });
|
|
665
792
|
|
|
666
|
-
|
|
793
|
+
/**
|
|
794
|
+
* A draggable handle. Render one per value; place an `input[rdxSliderThumbInput]`
|
|
795
|
+
* inside it for keyboard, accessibility and form submission.
|
|
796
|
+
*
|
|
797
|
+
* @see https://base-ui.com/react/components/slider
|
|
798
|
+
*/
|
|
799
|
+
class RdxSliderThumb {
|
|
667
800
|
constructor() {
|
|
668
|
-
this.
|
|
669
|
-
this.
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
this.
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
801
|
+
this.root = injectSliderRootContext();
|
|
802
|
+
this.element = inject(ElementRef).nativeElement;
|
|
803
|
+
/** The nested range input, set by `[rdxSliderThumbInput]`. */
|
|
804
|
+
this.inputElement = null;
|
|
805
|
+
/** Explicit index for this thumb (required for SSR range sliders). */
|
|
806
|
+
this.indexInput = input(undefined, { ...(ngDevMode ? { debugName: "indexInput" } : /* istanbul ignore next */ {}), alias: 'index',
|
|
807
|
+
transform: (v) => (v == null ? undefined : numberAttribute(v)) });
|
|
808
|
+
/** Disables this individual thumb. */
|
|
809
|
+
this.thumbDisabled = input(false, { ...(ngDevMode ? { debugName: "thumbDisabled" } : /* istanbul ignore next */ {}), alias: 'disabled', transform: booleanAttribute });
|
|
810
|
+
/** The position of this thumb among its siblings. */
|
|
811
|
+
this.index = computed(() => this.indexInput() ?? this.root.thumbIndexOf(this), ...(ngDevMode ? [{ debugName: "index" }] : /* istanbul ignore next */ []));
|
|
812
|
+
/** Whether this thumb is disabled (own state OR root disabled). */
|
|
813
|
+
this.disabled = computed(() => this.thumbDisabled() || this.root.isDisabled(), ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
814
|
+
/** The value represented by this thumb. */
|
|
815
|
+
this.value = computed(() => this.root.values()[this.index()], ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
816
|
+
this.percent = computed(() => {
|
|
817
|
+
const value = this.value();
|
|
818
|
+
return value === undefined ? NaN : valueToPercent(value, this.root.min(), this.root.max());
|
|
819
|
+
}, ...(ngDevMode ? [{ debugName: "percent" }] : /* istanbul ignore next */ []));
|
|
820
|
+
this.thumbStyle = computed(() => {
|
|
821
|
+
const vertical = this.root.orientation() === 'vertical';
|
|
822
|
+
const rtl = this.root.dir() === 'rtl';
|
|
823
|
+
const startEdge = vertical ? 'bottom' : 'inset-inline-start';
|
|
824
|
+
const crossOffset = vertical ? 'left' : 'top';
|
|
825
|
+
const percent = this.percent();
|
|
826
|
+
if (!Number.isFinite(percent)) {
|
|
827
|
+
return { position: 'absolute', visibility: 'hidden' };
|
|
828
|
+
}
|
|
829
|
+
const index = this.index();
|
|
830
|
+
let zIndex;
|
|
831
|
+
if (this.root.range()) {
|
|
832
|
+
if (this.root.active() === index) {
|
|
833
|
+
zIndex = 2;
|
|
834
|
+
}
|
|
835
|
+
else if (this.root.lastUsedThumbIndex() === index) {
|
|
836
|
+
zIndex = 1;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
else if (this.root.active() === index) {
|
|
840
|
+
zIndex = 1;
|
|
841
|
+
}
|
|
842
|
+
const style = {
|
|
843
|
+
position: 'absolute',
|
|
844
|
+
[startEdge]: `${percent}%`,
|
|
845
|
+
[crossOffset]: '50%',
|
|
846
|
+
translate: `${(vertical || !rtl ? -1 : 1) * 50}% ${(vertical ? 1 : -1) * 50}%`
|
|
679
847
|
};
|
|
680
|
-
|
|
848
|
+
if (zIndex !== undefined) {
|
|
849
|
+
style['z-index'] = zIndex;
|
|
850
|
+
}
|
|
851
|
+
return style;
|
|
852
|
+
}, ...(ngDevMode ? [{ debugName: "thumbStyle" }] : /* istanbul ignore next */ []));
|
|
853
|
+
// Registration is DOM-order sorted on the root and reads no inputs, so the constructor
|
|
854
|
+
// (where the host element already exists) is the right place; cleanup goes via DestroyRef.
|
|
855
|
+
this.root.registerThumb(this);
|
|
856
|
+
inject(DestroyRef).onDestroy(() => this.root.unregisterThumb(this));
|
|
681
857
|
}
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
858
|
+
onPointerDown(event) {
|
|
859
|
+
if (this.disabled()) {
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
862
|
+
const index = this.index();
|
|
863
|
+
this.root.pressedThumbIndex = index;
|
|
864
|
+
const axis = this.root.orientation() === 'horizontal' ? 'x' : 'y';
|
|
865
|
+
const rect = this.element.getBoundingClientRect();
|
|
866
|
+
const midpoint = axis === 'x' ? (rect.left + rect.right) / 2 : (rect.top + rect.bottom) / 2;
|
|
867
|
+
const pointer = axis === 'x' ? event.clientX : event.clientY;
|
|
868
|
+
this.root.pressedThumbCenterOffset = pointer - midpoint;
|
|
869
|
+
if (this.inputElement) {
|
|
870
|
+
this.root.pressedInput = this.inputElement;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxSliderThumb, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
874
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxSliderThumb, isStandalone: true, selector: "div[rdxSliderThumb]", inputs: { indexInput: { classPropertyName: "indexInput", publicName: "index", isSignal: true, isRequired: false, transformFunction: null }, thumbDisabled: { classPropertyName: "thumbDisabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "pointerdown": "onPointerDown($event)" }, properties: { "style": "thumbStyle()", "attr.data-index": "index()", "attr.data-orientation": "root.orientation()", "attr.data-disabled": "disabled() ? \"\" : undefined", "attr.data-dragging": "root.dragging() ? \"\" : undefined" } }, exportAs: ["rdxSliderThumb"], ngImport: i0 }); }
|
|
686
875
|
}
|
|
687
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
688
|
-
type:
|
|
876
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxSliderThumb, decorators: [{
|
|
877
|
+
type: Directive,
|
|
689
878
|
args: [{
|
|
690
|
-
selector: '
|
|
879
|
+
selector: 'div[rdxSliderThumb]',
|
|
880
|
+
exportAs: 'rdxSliderThumb',
|
|
691
881
|
host: {
|
|
692
|
-
'[
|
|
693
|
-
'[attr.data-
|
|
694
|
-
'[
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
882
|
+
'[style]': 'thumbStyle()',
|
|
883
|
+
'[attr.data-index]': 'index()',
|
|
884
|
+
'[attr.data-orientation]': 'root.orientation()',
|
|
885
|
+
'[attr.data-disabled]': 'disabled() ? "" : undefined',
|
|
886
|
+
'[attr.data-dragging]': 'root.dragging() ? "" : undefined',
|
|
887
|
+
'(pointerdown)': 'onPointerDown($event)'
|
|
888
|
+
}
|
|
699
889
|
}]
|
|
700
|
-
}] });
|
|
890
|
+
}], ctorParameters: () => [], propDecorators: { indexInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "index", required: false }] }], thumbDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
|
|
701
891
|
|
|
702
|
-
|
|
892
|
+
/**
|
|
893
|
+
* The native `input[type=range]` nested inside a thumb. It is visually hidden but
|
|
894
|
+
* remains the focusable element that drives keyboard interaction, accessibility
|
|
895
|
+
* and form submission.
|
|
896
|
+
*
|
|
897
|
+
* @see https://base-ui.com/react/components/slider
|
|
898
|
+
*/
|
|
899
|
+
class RdxSliderThumbInput {
|
|
703
900
|
constructor() {
|
|
704
|
-
this.
|
|
705
|
-
this.
|
|
706
|
-
this.
|
|
707
|
-
this.
|
|
708
|
-
this.
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
const percent = this.percent();
|
|
727
|
-
const offset = this.thumbInBoundsOffset();
|
|
728
|
-
return `calc(${percent}% + ${offset}px)`;
|
|
729
|
-
}, ...(ngDevMode ? [{ debugName: "transform" }] : []));
|
|
730
|
-
this.orientationSize = signal(0, ...(ngDevMode ? [{ debugName: "orientationSize" }] : []));
|
|
731
|
-
this.thumbInBoundsOffset = computed(() => {
|
|
732
|
-
const context = this.rootContext.orientationContext.context;
|
|
733
|
-
const size = this.orientationSize();
|
|
734
|
-
const percent = this.percent();
|
|
735
|
-
const direction = context.direction;
|
|
736
|
-
return size ? getThumbInBoundsOffset(size, percent, direction) : 0;
|
|
737
|
-
}, ...(ngDevMode ? [{ debugName: "thumbInBoundsOffset" }] : []));
|
|
738
|
-
this.combinedStyles = computed(() => {
|
|
739
|
-
const context = this.rootContext.orientationContext.context;
|
|
740
|
-
const startEdge = context.startEdge;
|
|
741
|
-
const percent = this.percent();
|
|
742
|
-
const offset = this.thumbInBoundsOffset();
|
|
743
|
-
return {
|
|
744
|
-
position: 'absolute',
|
|
745
|
-
transform: 'var(--rdx-slider-thumb-transform)',
|
|
746
|
-
display: (this.isMounted() && this.value()) === false ? 'none' : undefined,
|
|
747
|
-
[startEdge]: `calc(${percent}% + ${offset}px)`
|
|
748
|
-
};
|
|
749
|
-
}, ...(ngDevMode ? [{ debugName: "combinedStyles" }] : []));
|
|
901
|
+
this.root = injectSliderRootContext();
|
|
902
|
+
this.thumb = inject(RdxSliderThumb);
|
|
903
|
+
this.element = inject(ElementRef).nativeElement;
|
|
904
|
+
this.ariaLabel = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
|
|
905
|
+
this.ariaValueTextInput = input(undefined, { ...(ngDevMode ? { debugName: "ariaValueTextInput" } : /* istanbul ignore next */ {}), alias: 'aria-valuetext' });
|
|
906
|
+
this.writingMode = computed(() => this.root.orientation() === 'vertical' ? (this.root.dir() === 'rtl' ? 'vertical-rl' : 'vertical-lr') : undefined, ...(ngDevMode ? [{ debugName: "writingMode" }] : /* istanbul ignore next */ []));
|
|
907
|
+
this.ariaLabelledBy = computed(() => this.ariaLabel() == null ? this.root.ariaLabelledBy() : undefined, ...(ngDevMode ? [{ debugName: "ariaLabelledBy" }] : /* istanbul ignore next */ []));
|
|
908
|
+
this.valueText = computed(() => this.ariaValueTextInput() ??
|
|
909
|
+
getDefaultAriaValueText(this.root.values(), this.thumb.index(), this.root.format(), this.root.locale()), ...(ngDevMode ? [{ debugName: "valueText" }] : /* istanbul ignore next */ []));
|
|
910
|
+
// Host element exists in the constructor and the registration has no input dependency.
|
|
911
|
+
this.thumb.inputElement = this.element;
|
|
912
|
+
inject(DestroyRef).onDestroy(() => {
|
|
913
|
+
if (this.thumb.inputElement === this.element) {
|
|
914
|
+
this.thumb.inputElement = null;
|
|
915
|
+
}
|
|
916
|
+
});
|
|
917
|
+
}
|
|
918
|
+
onChange(event) {
|
|
919
|
+
const value = event.target.valueAsNumber;
|
|
920
|
+
if (!Number.isNaN(value)) {
|
|
921
|
+
this.root.handleInputChange(value, this.thumb.index(), 'input');
|
|
922
|
+
}
|
|
750
923
|
}
|
|
751
924
|
onFocus() {
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
const
|
|
772
|
-
const index = this.
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
925
|
+
this.root.setActive(this.thumb.index());
|
|
926
|
+
}
|
|
927
|
+
onBlur() {
|
|
928
|
+
this.root.setActive(-1);
|
|
929
|
+
this.root.markAsTouched();
|
|
930
|
+
}
|
|
931
|
+
onKeyDown(event) {
|
|
932
|
+
if (event.defaultPrevented || !ALL_KEYS.has(event.key)) {
|
|
933
|
+
return;
|
|
934
|
+
}
|
|
935
|
+
if (COMPOSITE_KEYS.has(event.key)) {
|
|
936
|
+
event.stopPropagation();
|
|
937
|
+
}
|
|
938
|
+
const min = this.root.min();
|
|
939
|
+
const max = this.root.max();
|
|
940
|
+
const step = this.root.step();
|
|
941
|
+
const largeStep = this.root.largeStep();
|
|
942
|
+
const rtl = this.root.dir() === 'rtl';
|
|
943
|
+
const range = this.root.range();
|
|
944
|
+
const values = this.root.values();
|
|
945
|
+
const index = this.thumb.index();
|
|
946
|
+
const thumbValue = values[index];
|
|
947
|
+
const rounded = roundValueToStep(thumbValue, step, min);
|
|
948
|
+
let newValue = null;
|
|
949
|
+
switch (event.key) {
|
|
950
|
+
case 'ArrowUp':
|
|
951
|
+
newValue = getNewValue(rounded, event.shiftKey ? largeStep : step, 1, min, max);
|
|
952
|
+
break;
|
|
953
|
+
case 'ArrowRight':
|
|
954
|
+
newValue = getNewValue(rounded, event.shiftKey ? largeStep : step, rtl ? -1 : 1, min, max);
|
|
955
|
+
break;
|
|
956
|
+
case 'ArrowDown':
|
|
957
|
+
newValue = getNewValue(rounded, event.shiftKey ? largeStep : step, -1, min, max);
|
|
958
|
+
break;
|
|
959
|
+
case 'ArrowLeft':
|
|
960
|
+
newValue = getNewValue(rounded, event.shiftKey ? largeStep : step, rtl ? 1 : -1, min, max);
|
|
961
|
+
break;
|
|
962
|
+
case 'PageUp':
|
|
963
|
+
newValue = getNewValue(rounded, largeStep, 1, min, max);
|
|
964
|
+
break;
|
|
965
|
+
case 'PageDown':
|
|
966
|
+
newValue = getNewValue(rounded, largeStep, -1, min, max);
|
|
967
|
+
break;
|
|
968
|
+
case 'End':
|
|
969
|
+
newValue =
|
|
970
|
+
range && Number.isFinite(values[index + 1])
|
|
971
|
+
? values[index + 1] - step * this.root.minStepsBetweenValues()
|
|
972
|
+
: max;
|
|
973
|
+
break;
|
|
974
|
+
case 'Home':
|
|
975
|
+
newValue =
|
|
976
|
+
range && Number.isFinite(values[index - 1])
|
|
977
|
+
? values[index - 1] + step * this.root.minStepsBetweenValues()
|
|
978
|
+
: min;
|
|
979
|
+
break;
|
|
980
|
+
default:
|
|
981
|
+
break;
|
|
982
|
+
}
|
|
983
|
+
if (newValue !== null) {
|
|
984
|
+
this.root.handleInputChange(newValue, index, 'keyboard');
|
|
985
|
+
event.preventDefault();
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxSliderThumbInput, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
989
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxSliderThumbInput, isStandalone: true, selector: "input[rdxSliderThumbInput]", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaValueTextInput: { classPropertyName: "ariaValueTextInput", publicName: "aria-valuetext", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "type": "range" }, listeners: { "keydown": "onKeyDown($event)", "change": "onChange($event)", "focus": "onFocus()", "blur": "onBlur()" }, properties: { "style.writing-mode": "writingMode()", "attr.min": "root.min()", "attr.max": "root.max()", "attr.step": "root.step()", "value": "thumb.value() ?? \"\"", "disabled": "thumb.disabled()", "attr.name": "root.name()", "attr.form": "root.form()", "attr.aria-orientation": "root.orientation()", "attr.aria-valuenow": "thumb.value()", "attr.aria-valuetext": "valueText()", "attr.aria-label": "ariaLabel()", "attr.aria-labelledby": "ariaLabelledBy()", "attr.data-index": "thumb.index()" }, styleAttribute: "position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0; opacity: 0; cursor: inherit;" }, exportAs: ["rdxSliderThumbInput"], ngImport: i0 }); }
|
|
782
990
|
}
|
|
783
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
991
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxSliderThumbInput, decorators: [{
|
|
784
992
|
type: Directive,
|
|
785
993
|
args: [{
|
|
786
|
-
selector: '[
|
|
994
|
+
selector: 'input[rdxSliderThumbInput]',
|
|
995
|
+
exportAs: 'rdxSliderThumbInput',
|
|
787
996
|
host: {
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
'[
|
|
791
|
-
'[attr.
|
|
792
|
-
'[attr.
|
|
793
|
-
'[attr.
|
|
794
|
-
'[
|
|
795
|
-
'[
|
|
796
|
-
'[
|
|
797
|
-
'
|
|
997
|
+
type: 'range',
|
|
998
|
+
style: 'position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0; opacity: 0; cursor: inherit;',
|
|
999
|
+
'[style.writing-mode]': 'writingMode()',
|
|
1000
|
+
'[attr.min]': 'root.min()',
|
|
1001
|
+
'[attr.max]': 'root.max()',
|
|
1002
|
+
'[attr.step]': 'root.step()',
|
|
1003
|
+
'[value]': 'thumb.value() ?? ""',
|
|
1004
|
+
'[disabled]': 'thumb.disabled()',
|
|
1005
|
+
'[attr.name]': 'root.name()',
|
|
1006
|
+
'[attr.form]': 'root.form()',
|
|
1007
|
+
'[attr.aria-orientation]': 'root.orientation()',
|
|
1008
|
+
'[attr.aria-valuenow]': 'thumb.value()',
|
|
1009
|
+
'[attr.aria-valuetext]': 'valueText()',
|
|
1010
|
+
'[attr.aria-label]': 'ariaLabel()',
|
|
1011
|
+
'[attr.aria-labelledby]': 'ariaLabelledBy()',
|
|
1012
|
+
'[attr.data-index]': 'thumb.index()',
|
|
1013
|
+
'(keydown)': 'onKeyDown($event)',
|
|
1014
|
+
'(change)': 'onChange($event)',
|
|
1015
|
+
'(focus)': 'onFocus()',
|
|
1016
|
+
'(blur)': 'onBlur()'
|
|
798
1017
|
}
|
|
799
1018
|
}]
|
|
800
|
-
}] });
|
|
1019
|
+
}], ctorParameters: () => [], propDecorators: { ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], ariaValueTextInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-valuetext", required: false }] }] } });
|
|
801
1020
|
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
1021
|
+
/**
|
|
1022
|
+
* The track of the slider — the positioning context for the indicator and thumbs.
|
|
1023
|
+
*
|
|
1024
|
+
* @see https://base-ui.com/react/components/slider
|
|
1025
|
+
*/
|
|
1026
|
+
class RdxSliderTrack {
|
|
1027
|
+
constructor() {
|
|
1028
|
+
this.root = injectSliderRootContext();
|
|
1029
|
+
}
|
|
1030
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxSliderTrack, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1031
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxSliderTrack, isStandalone: true, selector: "div[rdxSliderTrack]", host: { properties: { "attr.data-orientation": "root.orientation()", "attr.data-disabled": "root.isDisabled() ? \"\" : undefined", "attr.data-dragging": "root.dragging() ? \"\" : undefined" }, styleAttribute: "position: relative;" }, exportAs: ["rdxSliderTrack"], ngImport: i0 }); }
|
|
807
1032
|
}
|
|
808
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
809
|
-
type:
|
|
1033
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxSliderTrack, decorators: [{
|
|
1034
|
+
type: Directive,
|
|
810
1035
|
args: [{
|
|
811
|
-
selector: '
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
1036
|
+
selector: 'div[rdxSliderTrack]',
|
|
1037
|
+
exportAs: 'rdxSliderTrack',
|
|
1038
|
+
host: {
|
|
1039
|
+
style: 'position: relative;',
|
|
1040
|
+
'[attr.data-orientation]': 'root.orientation()',
|
|
1041
|
+
'[attr.data-disabled]': 'root.isDisabled() ? "" : undefined',
|
|
1042
|
+
'[attr.data-dragging]': 'root.dragging() ? "" : undefined'
|
|
1043
|
+
}
|
|
816
1044
|
}]
|
|
817
1045
|
}] });
|
|
818
1046
|
|
|
819
|
-
|
|
1047
|
+
/**
|
|
1048
|
+
* Displays the slider's current value(s) as formatted text. Renders into an
|
|
1049
|
+
* `output` element; the displayed value honours the root `format` and `locale`.
|
|
1050
|
+
*
|
|
1051
|
+
* @see https://base-ui.com/react/components/slider
|
|
1052
|
+
*/
|
|
1053
|
+
class RdxSliderValue {
|
|
820
1054
|
constructor() {
|
|
821
|
-
this.
|
|
1055
|
+
this.root = injectSliderRootContext();
|
|
1056
|
+
/** The separator placed between values of a range slider. */
|
|
1057
|
+
this.separator = input(' – ', ...(ngDevMode ? [{ debugName: "separator" }] : /* istanbul ignore next */ []));
|
|
1058
|
+
this.display = computed(() => this.root
|
|
1059
|
+
.values()
|
|
1060
|
+
.map((value) => this.root.formatValue(value) || `${value}`)
|
|
1061
|
+
.join(this.separator()), ...(ngDevMode ? [{ debugName: "display" }] : /* istanbul ignore next */ []));
|
|
822
1062
|
}
|
|
823
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
824
|
-
static { this.ɵ
|
|
825
|
-
<ng-content />
|
|
826
|
-
`, isInline: true }); }
|
|
1063
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxSliderValue, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1064
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxSliderValue, isStandalone: true, selector: "output[rdxSliderValue]", inputs: { separator: { classPropertyName: "separator", publicName: "separator", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "aria-live": "off" }, properties: { "textContent": "display()" } }, exportAs: ["rdxSliderValue"], ngImport: i0 }); }
|
|
827
1065
|
}
|
|
828
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
829
|
-
type:
|
|
1066
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxSliderValue, decorators: [{
|
|
1067
|
+
type: Directive,
|
|
830
1068
|
args: [{
|
|
831
|
-
selector: '
|
|
1069
|
+
selector: 'output[rdxSliderValue]',
|
|
1070
|
+
exportAs: 'rdxSliderValue',
|
|
832
1071
|
host: {
|
|
833
|
-
'
|
|
834
|
-
'[
|
|
835
|
-
}
|
|
836
|
-
template: `
|
|
837
|
-
<ng-content />
|
|
838
|
-
`
|
|
1072
|
+
'aria-live': 'off',
|
|
1073
|
+
'[textContent]': 'display()'
|
|
1074
|
+
}
|
|
839
1075
|
}]
|
|
840
|
-
}] });
|
|
1076
|
+
}], propDecorators: { separator: [{ type: i0.Input, args: [{ isSignal: true, alias: "separator", required: false }] }] } });
|
|
841
1077
|
|
|
842
|
-
const _imports = [
|
|
1078
|
+
const _imports = [
|
|
1079
|
+
RdxSliderRoot,
|
|
1080
|
+
RdxSliderControl,
|
|
1081
|
+
RdxSliderTrack,
|
|
1082
|
+
RdxSliderIndicator,
|
|
1083
|
+
RdxSliderThumb,
|
|
1084
|
+
RdxSliderThumbInput,
|
|
1085
|
+
RdxSliderValue
|
|
1086
|
+
];
|
|
843
1087
|
class RdxSliderModule {
|
|
844
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
845
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
|
|
846
|
-
|
|
1088
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxSliderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1089
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: RdxSliderModule, imports: [RdxSliderRoot,
|
|
1090
|
+
RdxSliderControl,
|
|
1091
|
+
RdxSliderTrack,
|
|
1092
|
+
RdxSliderIndicator,
|
|
1093
|
+
RdxSliderThumb,
|
|
1094
|
+
RdxSliderThumbInput,
|
|
1095
|
+
RdxSliderValue], exports: [RdxSliderRoot,
|
|
1096
|
+
RdxSliderControl,
|
|
1097
|
+
RdxSliderTrack,
|
|
1098
|
+
RdxSliderIndicator,
|
|
1099
|
+
RdxSliderThumb,
|
|
1100
|
+
RdxSliderThumbInput,
|
|
1101
|
+
RdxSliderValue] }); }
|
|
1102
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxSliderModule }); }
|
|
847
1103
|
}
|
|
848
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1104
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxSliderModule, decorators: [{
|
|
849
1105
|
type: NgModule,
|
|
850
1106
|
args: [{
|
|
851
1107
|
imports: [..._imports],
|
|
@@ -857,5 +1113,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImpor
|
|
|
857
1113
|
* Generated bundle index. Do not edit.
|
|
858
1114
|
*/
|
|
859
1115
|
|
|
860
|
-
export {
|
|
1116
|
+
export { ALL_KEYS, ARROW_KEYS, COMPOSITE_KEYS, RdxSliderControl, RdxSliderIndicator, RdxSliderModule, RdxSliderRoot, RdxSliderThumb, RdxSliderThumbInput, RdxSliderTrack, RdxSliderValue, areValuesEqual, asc, formatNumber, getControlOffset, getDecimalPrecision, getDefaultAriaValueText, getMidpoint, getNewValue, getPushedThumbValues, getSliderValue, injectSliderRootContext, provideSliderRootContext, replaceArrayItemAtIndex, resolveThumbCollision, roundValueToStep, validateMinimumDistance, valueArrayToPercentages, valueToPercent };
|
|
861
1117
|
//# sourceMappingURL=radix-ng-primitives-slider.mjs.map
|