@salt-ds/lab 1.0.0-alpha.62 → 1.0.0-alpha.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/css/salt-lab.css +462 -347
- package/dist-cjs/date-picker/DatePicker.js +4 -3
- package/dist-cjs/date-picker/DatePicker.js.map +1 -1
- package/dist-cjs/date-picker/DatePickerActions.js +1 -1
- package/dist-cjs/date-picker/DatePickerActions.js.map +1 -1
- package/dist-cjs/date-picker/DatePickerContext.js.map +1 -1
- package/dist-cjs/date-picker/DatePickerOverlay.js +0 -4
- package/dist-cjs/date-picker/DatePickerOverlay.js.map +1 -1
- package/dist-cjs/date-picker/DatePickerOverlayProvider.js +65 -43
- package/dist-cjs/date-picker/DatePickerOverlayProvider.js.map +1 -1
- package/dist-cjs/date-picker/DatePickerRangeInput.js +9 -26
- package/dist-cjs/date-picker/DatePickerRangeInput.js.map +1 -1
- package/dist-cjs/date-picker/DatePickerSingleInput.js +7 -14
- package/dist-cjs/date-picker/DatePickerSingleInput.js.map +1 -1
- package/dist-cjs/date-picker/useDatePicker.js +10 -7
- package/dist-cjs/date-picker/useDatePicker.js.map +1 -1
- package/dist-cjs/date-picker/useKeyboard.js +23 -0
- package/dist-cjs/date-picker/useKeyboard.js.map +1 -0
- package/dist-cjs/index.js +13 -8
- package/dist-cjs/index.js.map +1 -1
- package/dist-cjs/number-input/NumberInput.css.js +6 -0
- package/dist-cjs/number-input/NumberInput.css.js.map +1 -0
- package/dist-cjs/{stepper-input/StepperInput.js → number-input/NumberInput.js} +15 -15
- package/dist-cjs/number-input/NumberInput.js.map +1 -0
- package/dist-cjs/number-input/internal/useActivateWhileMouseDown.js.map +1 -0
- package/dist-cjs/number-input/internal/useInterval.js.map +1 -0
- package/dist-cjs/number-input/internal/utils.js.map +1 -0
- package/dist-cjs/{stepper-input/useStepperInput.js → number-input/useNumberInput.js} +3 -3
- package/dist-cjs/number-input/useNumberInput.js.map +1 -0
- package/dist-cjs/slider/RangeSlider.js +161 -0
- package/dist-cjs/slider/RangeSlider.js.map +1 -0
- package/dist-cjs/slider/Slider.js +104 -70
- package/dist-cjs/slider/Slider.js.map +1 -1
- package/dist-cjs/slider/internal/SliderThumb.css.js +6 -0
- package/dist-cjs/slider/internal/SliderThumb.css.js.map +1 -0
- package/dist-cjs/slider/internal/SliderThumb.js +136 -70
- package/dist-cjs/slider/internal/SliderThumb.js.map +1 -1
- package/dist-cjs/slider/internal/SliderTooltip.css.js +6 -0
- package/dist-cjs/slider/internal/SliderTooltip.css.js.map +1 -0
- package/dist-cjs/slider/internal/SliderTooltip.js +43 -0
- package/dist-cjs/slider/internal/SliderTooltip.js.map +1 -0
- package/dist-cjs/slider/internal/SliderTrack.css.js +6 -0
- package/dist-cjs/slider/internal/SliderTrack.css.js.map +1 -0
- package/dist-cjs/slider/internal/SliderTrack.js +160 -80
- package/dist-cjs/slider/internal/SliderTrack.js.map +1 -1
- package/dist-cjs/slider/internal/useRangeSliderThumb.js +194 -0
- package/dist-cjs/slider/internal/useRangeSliderThumb.js.map +1 -0
- package/dist-cjs/slider/internal/useSliderThumb.js +123 -0
- package/dist-cjs/slider/internal/useSliderThumb.js.map +1 -0
- package/dist-cjs/slider/internal/utils.js +97 -72
- package/dist-cjs/slider/internal/utils.js.map +1 -1
- package/dist-cjs/tabs-next/TabOverflowList.css.js +1 -1
- package/dist-cjs/tabs-next/TabOverflowList.js +2 -1
- package/dist-cjs/tabs-next/TabOverflowList.js.map +1 -1
- package/dist-es/date-picker/DatePicker.js +4 -3
- package/dist-es/date-picker/DatePicker.js.map +1 -1
- package/dist-es/date-picker/DatePickerActions.js +1 -1
- package/dist-es/date-picker/DatePickerActions.js.map +1 -1
- package/dist-es/date-picker/DatePickerContext.js.map +1 -1
- package/dist-es/date-picker/DatePickerOverlay.js +0 -4
- package/dist-es/date-picker/DatePickerOverlay.js.map +1 -1
- package/dist-es/date-picker/DatePickerOverlayProvider.js +67 -45
- package/dist-es/date-picker/DatePickerOverlayProvider.js.map +1 -1
- package/dist-es/date-picker/DatePickerRangeInput.js +9 -26
- package/dist-es/date-picker/DatePickerRangeInput.js.map +1 -1
- package/dist-es/date-picker/DatePickerSingleInput.js +7 -14
- package/dist-es/date-picker/DatePickerSingleInput.js.map +1 -1
- package/dist-es/date-picker/useDatePicker.js +10 -7
- package/dist-es/date-picker/useDatePicker.js.map +1 -1
- package/dist-es/date-picker/useKeyboard.js +21 -0
- package/dist-es/date-picker/useKeyboard.js.map +1 -0
- package/dist-es/index.js +6 -4
- package/dist-es/index.js.map +1 -1
- package/dist-es/number-input/NumberInput.css.js +4 -0
- package/dist-es/number-input/NumberInput.css.js.map +1 -0
- package/dist-es/{stepper-input/StepperInput.js → number-input/NumberInput.js} +14 -14
- package/dist-es/number-input/NumberInput.js.map +1 -0
- package/dist-es/number-input/internal/useActivateWhileMouseDown.js.map +1 -0
- package/dist-es/number-input/internal/useInterval.js.map +1 -0
- package/dist-es/number-input/internal/utils.js.map +1 -0
- package/dist-es/{stepper-input/useStepperInput.js → number-input/useNumberInput.js} +3 -3
- package/dist-es/number-input/useNumberInput.js.map +1 -0
- package/dist-es/slider/RangeSlider.js +159 -0
- package/dist-es/slider/RangeSlider.js.map +1 -0
- package/dist-es/slider/Slider.js +107 -73
- package/dist-es/slider/Slider.js.map +1 -1
- package/dist-es/slider/internal/SliderThumb.css.js +4 -0
- package/dist-es/slider/internal/SliderThumb.css.js.map +1 -0
- package/dist-es/slider/internal/SliderThumb.js +138 -72
- package/dist-es/slider/internal/SliderThumb.js.map +1 -1
- package/dist-es/slider/internal/SliderTooltip.css.js +4 -0
- package/dist-es/slider/internal/SliderTooltip.css.js.map +1 -0
- package/dist-es/slider/internal/SliderTooltip.js +41 -0
- package/dist-es/slider/internal/SliderTooltip.js.map +1 -0
- package/dist-es/slider/internal/SliderTrack.css.js +4 -0
- package/dist-es/slider/internal/SliderTrack.css.js.map +1 -0
- package/dist-es/slider/internal/SliderTrack.js +164 -84
- package/dist-es/slider/internal/SliderTrack.js.map +1 -1
- package/dist-es/slider/internal/useRangeSliderThumb.js +192 -0
- package/dist-es/slider/internal/useRangeSliderThumb.js.map +1 -0
- package/dist-es/slider/internal/useSliderThumb.js +121 -0
- package/dist-es/slider/internal/useSliderThumb.js.map +1 -0
- package/dist-es/slider/internal/utils.js +91 -63
- package/dist-es/slider/internal/utils.js.map +1 -1
- package/dist-es/tabs-next/TabOverflowList.css.js +1 -1
- package/dist-es/tabs-next/TabOverflowList.js +3 -2
- package/dist-es/tabs-next/TabOverflowList.js.map +1 -1
- package/dist-types/date-picker/DatePicker.d.ts +6 -1
- package/dist-types/date-picker/DatePickerContext.d.ts +2 -1
- package/dist-types/date-picker/DatePickerOverlayProvider.d.ts +18 -4
- package/dist-types/date-picker/DatePickerRangeInput.d.ts +1 -1
- package/dist-types/date-picker/index.d.ts +1 -0
- package/dist-types/date-picker/useKeyboard.d.ts +14 -0
- package/dist-types/index.d.ts +4 -4
- package/dist-types/{stepper-input/StepperInput.d.ts → number-input/NumberInput.d.ts} +7 -7
- package/dist-types/number-input/index.d.ts +2 -0
- package/dist-types/{stepper-input/useStepperInput.d.ts → number-input/useNumberInput.d.ts} +2 -2
- package/dist-types/slider/RangeSlider.d.ts +91 -0
- package/dist-types/slider/Slider.d.ts +74 -15
- package/dist-types/slider/index.d.ts +1 -1
- package/dist-types/slider/internal/SliderThumb.d.ts +20 -7
- package/dist-types/slider/internal/SliderTooltip.d.ts +6 -0
- package/dist-types/slider/internal/SliderTrack.d.ts +23 -3
- package/dist-types/slider/internal/useRangeSliderThumb.d.ts +26 -0
- package/dist-types/slider/internal/useSliderThumb.d.ts +24 -0
- package/dist-types/slider/internal/utils.d.ts +17 -15
- package/package.json +1 -1
- package/dist-cjs/slider/Slider.css.js +0 -6
- package/dist-cjs/slider/Slider.css.js.map +0 -1
- package/dist-cjs/slider/internal/SliderContext.js +0 -19
- package/dist-cjs/slider/internal/SliderContext.js.map +0 -1
- package/dist-cjs/slider/internal/SliderMarks.js +0 -29
- package/dist-cjs/slider/internal/SliderMarks.js.map +0 -1
- package/dist-cjs/slider/internal/SliderSelection.js +0 -33
- package/dist-cjs/slider/internal/SliderSelection.js.map +0 -1
- package/dist-cjs/slider/internal/useKeyDownThumb.js +0 -50
- package/dist-cjs/slider/internal/useKeyDownThumb.js.map +0 -1
- package/dist-cjs/stepper-input/StepperInput.css.js +0 -6
- package/dist-cjs/stepper-input/StepperInput.css.js.map +0 -1
- package/dist-cjs/stepper-input/StepperInput.js.map +0 -1
- package/dist-cjs/stepper-input/internal/useActivateWhileMouseDown.js.map +0 -1
- package/dist-cjs/stepper-input/internal/useInterval.js.map +0 -1
- package/dist-cjs/stepper-input/internal/utils.js.map +0 -1
- package/dist-cjs/stepper-input/useStepperInput.js.map +0 -1
- package/dist-es/slider/Slider.css.js +0 -4
- package/dist-es/slider/Slider.css.js.map +0 -1
- package/dist-es/slider/internal/SliderContext.js +0 -16
- package/dist-es/slider/internal/SliderContext.js.map +0 -1
- package/dist-es/slider/internal/SliderMarks.js +0 -27
- package/dist-es/slider/internal/SliderMarks.js.map +0 -1
- package/dist-es/slider/internal/SliderSelection.js +0 -31
- package/dist-es/slider/internal/SliderSelection.js.map +0 -1
- package/dist-es/slider/internal/useKeyDownThumb.js +0 -48
- package/dist-es/slider/internal/useKeyDownThumb.js.map +0 -1
- package/dist-es/stepper-input/StepperInput.css.js +0 -4
- package/dist-es/stepper-input/StepperInput.css.js.map +0 -1
- package/dist-es/stepper-input/StepperInput.js.map +0 -1
- package/dist-es/stepper-input/internal/useActivateWhileMouseDown.js.map +0 -1
- package/dist-es/stepper-input/internal/useInterval.js.map +0 -1
- package/dist-es/stepper-input/internal/utils.js.map +0 -1
- package/dist-es/stepper-input/useStepperInput.js.map +0 -1
- package/dist-types/slider/internal/SliderContext.d.ts +0 -11
- package/dist-types/slider/internal/SliderMarks.d.ts +0 -7
- package/dist-types/slider/internal/SliderSelection.d.ts +0 -4
- package/dist-types/slider/internal/index.d.ts +0 -3
- package/dist-types/slider/internal/useKeyDownThumb.d.ts +0 -2
- package/dist-types/slider/types.d.ts +0 -4
- package/dist-types/stepper-input/index.d.ts +0 -2
- /package/dist-cjs/{stepper-input → number-input}/internal/useActivateWhileMouseDown.js +0 -0
- /package/dist-cjs/{stepper-input → number-input}/internal/useInterval.js +0 -0
- /package/dist-cjs/{stepper-input → number-input}/internal/utils.js +0 -0
- /package/dist-es/{stepper-input → number-input}/internal/useActivateWhileMouseDown.js +0 -0
- /package/dist-es/{stepper-input → number-input}/internal/useInterval.js +0 -0
- /package/dist-es/{stepper-input → number-input}/internal/utils.js +0 -0
- /package/dist-types/{stepper-input → number-input}/internal/useActivateWhileMouseDown.d.ts +0 -0
- /package/dist-types/{stepper-input → number-input}/internal/useInterval.d.ts +0 -0
- /package/dist-types/{stepper-input → number-input}/internal/utils.d.ts +0 -0
|
@@ -1,75 +1,103 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const roundedToStep = roundToStep(normaliseBetweenValues, step);
|
|
6
|
-
const decimals = countDecimalPlaces(step);
|
|
7
|
-
const rounded = Number(roundedToStep.toFixed(decimals));
|
|
8
|
-
const value = clampValue(rounded, [min, max]);
|
|
9
|
-
return value;
|
|
10
|
-
};
|
|
11
|
-
const setValue = (value, newValue, index, onChange) => {
|
|
12
|
-
if (value.length === 2) {
|
|
13
|
-
const newValueArray = [...value];
|
|
14
|
-
newValueArray.splice(index, 1, newValue);
|
|
15
|
-
onChange(newValueArray);
|
|
16
|
-
return;
|
|
1
|
+
const toFloat = (value) => typeof value === "string" ? Number.parseFloat(value) : value;
|
|
2
|
+
const calculateMarkPosition = (value, max, min) => {
|
|
3
|
+
if (min === max) {
|
|
4
|
+
return 0;
|
|
17
5
|
}
|
|
18
|
-
|
|
6
|
+
const clampedValue = Number.isNaN(toFloat(value)) ? min : Math.min(Math.max(toFloat(value), min), max);
|
|
7
|
+
const markPosition = (clampedValue - min) / (max - min) * 100;
|
|
8
|
+
return Math.round(markPosition * 100) / 100;
|
|
19
9
|
};
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
if (value
|
|
23
|
-
return max;
|
|
24
|
-
}
|
|
25
|
-
if (value < min) {
|
|
10
|
+
const calculatePercentage = (value, max, min) => (value - min) / (max - min) * 100;
|
|
11
|
+
const clamp = (value, max, min, step, decimalPlaces, marks, restrictToMarks) => {
|
|
12
|
+
if (Number.isNaN(value)) {
|
|
26
13
|
return min;
|
|
27
14
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
15
|
+
const clampedValue = Math.min(Math.max(value, min), max);
|
|
16
|
+
if (restrictToMarks && marks) {
|
|
17
|
+
let closestMark = marks[0].value;
|
|
18
|
+
let smallestDifference = Math.abs(clampedValue - closestMark);
|
|
19
|
+
for (let i = 1; i < marks.length; i++) {
|
|
20
|
+
const currentDifference = Math.abs(clampedValue - marks[i].value);
|
|
21
|
+
if (currentDifference < smallestDifference) {
|
|
22
|
+
smallestDifference = currentDifference;
|
|
23
|
+
closestMark = marks[i].value;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return closestMark;
|
|
27
|
+
}
|
|
28
|
+
let roundedValue = Math.round(clampedValue / step) * step;
|
|
29
|
+
if (roundedValue > max) {
|
|
30
|
+
roundedValue = max;
|
|
31
|
+
}
|
|
32
|
+
return Number.parseFloat(roundedValue.toFixed(decimalPlaces));
|
|
37
33
|
};
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
34
|
+
const clampRange = (range, max, min, step, decimalPlaces, marks, restrictToMarks) => {
|
|
35
|
+
let [start, end] = range;
|
|
36
|
+
if (Number.isNaN(start)) {
|
|
37
|
+
start = min;
|
|
38
|
+
}
|
|
39
|
+
if (Number.isNaN(end)) {
|
|
40
|
+
end = max;
|
|
41
|
+
}
|
|
42
|
+
if (start > end) {
|
|
43
|
+
[start, end] = [end, start];
|
|
44
44
|
}
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
start = clamp(start, max, min, step, decimalPlaces, marks, restrictToMarks);
|
|
46
|
+
end = clamp(end, max, min, step, decimalPlaces, marks, restrictToMarks);
|
|
47
|
+
return [start, end];
|
|
48
|
+
};
|
|
49
|
+
const getClickedPosition = (sliderRef, clientX, max, min, step, decimalPlaces, marks, restrictToMarks) => {
|
|
50
|
+
if (!sliderRef.current) return;
|
|
51
|
+
const sliderRect = sliderRef.current.getBoundingClientRect();
|
|
52
|
+
const rawValue = (clientX - sliderRect.left) / sliderRect.width * (max - min) + min;
|
|
53
|
+
const steppedValue = Math.round(rawValue / step) * step;
|
|
54
|
+
return clamp(
|
|
55
|
+
steppedValue,
|
|
56
|
+
max,
|
|
57
|
+
min,
|
|
58
|
+
step,
|
|
59
|
+
decimalPlaces,
|
|
60
|
+
marks,
|
|
61
|
+
restrictToMarks
|
|
47
62
|
);
|
|
48
|
-
return marks.map((mark) => ({
|
|
49
|
-
...mark,
|
|
50
|
-
label: mark.value.toFixed(decimals)
|
|
51
|
-
}));
|
|
52
63
|
};
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
if (
|
|
56
|
-
|
|
57
|
-
|
|
64
|
+
const getKeyboardValue = (event, value, step, stepMultiplier, max, min, restrictToMarks, marks) => {
|
|
65
|
+
let newValue = value;
|
|
66
|
+
if (restrictToMarks && marks && marks.length >= 1) {
|
|
67
|
+
const currentIndex = marks.findIndex((mark) => mark.value === value);
|
|
68
|
+
switch (event.key) {
|
|
69
|
+
case "ArrowUp":
|
|
70
|
+
case "ArrowRight":
|
|
71
|
+
case "PageUp":
|
|
72
|
+
if (currentIndex < marks.length - 1) {
|
|
73
|
+
newValue = marks[currentIndex + 1].value;
|
|
74
|
+
}
|
|
75
|
+
break;
|
|
76
|
+
case "ArrowDown":
|
|
77
|
+
case "ArrowLeft":
|
|
78
|
+
case "PageDown":
|
|
79
|
+
if (currentIndex > 0) {
|
|
80
|
+
newValue = marks[currentIndex - 1].value;
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
default:
|
|
84
|
+
return newValue;
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
switch (event.key) {
|
|
88
|
+
case "PageUp":
|
|
89
|
+
newValue = Math.min(value + step * stepMultiplier, max);
|
|
90
|
+
break;
|
|
91
|
+
case "PageDown":
|
|
92
|
+
newValue = Math.max(value - step * stepMultiplier, min);
|
|
93
|
+
break;
|
|
94
|
+
default:
|
|
95
|
+
return newValue;
|
|
96
|
+
}
|
|
58
97
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const nearestIndex = distances.indexOf(minDistance);
|
|
62
|
-
return nearestIndex;
|
|
63
|
-
};
|
|
64
|
-
const preventOverlappingValues = (value, newValue, index) => value.length === 2 ? index === 0 ? Math.min(newValue, value[1]) : Math.max(newValue, value[0]) : newValue;
|
|
65
|
-
const parseValueProp = (value, min, max) => {
|
|
66
|
-
if (typeof value === "undefined" || value.length < 1) return;
|
|
67
|
-
const a = clampValue(value[0], [min, max]);
|
|
68
|
-
if (value.length === 1) return [a];
|
|
69
|
-
const b = clampValue(value[1], [min, max]);
|
|
70
|
-
if (a > b) return [a, a];
|
|
71
|
-
return [a, b];
|
|
98
|
+
event.preventDefault();
|
|
99
|
+
return newValue;
|
|
72
100
|
};
|
|
73
101
|
|
|
74
|
-
export {
|
|
102
|
+
export { calculateMarkPosition, calculatePercentage, clamp, clampRange, getClickedPosition, getKeyboardValue, toFloat };
|
|
75
103
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sources":["../src/slider/internal/utils.ts"],"sourcesContent":["import type { RefObject } from \"react\";\
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["../src/slider/internal/utils.ts"],"sourcesContent":["import type { RefObject } from \"react\";\n\nexport const toFloat = (value: number | string) =>\n typeof value === \"string\" ? Number.parseFloat(value) : value;\n\nexport const calculateMarkPosition = (\n value: number | string,\n max: number,\n min: number,\n) => {\n if (min === max) {\n return 0;\n }\n const clampedValue = Number.isNaN(toFloat(value))\n ? min\n : Math.min(Math.max(toFloat(value), min), max);\n const markPosition = ((clampedValue - min) / (max - min)) * 100;\n return Math.round(markPosition * 100) / 100;\n};\n\nexport const calculatePercentage = (value: number, max: number, min: number) =>\n ((value - min) / (max - min)) * 100;\n\nexport const clamp = (\n value: number,\n max: number,\n min: number,\n step: number,\n decimalPlaces: number,\n marks?: { value: number; label: string }[],\n restrictToMarks?: boolean,\n) => {\n if (Number.isNaN(value)) {\n return min;\n }\n // Clamp the value between min and max\n const clampedValue = Math.min(Math.max(value, min), max);\n if (restrictToMarks && marks) {\n // Find the closest mark value\n let closestMark = marks[0].value;\n let smallestDifference = Math.abs(clampedValue - closestMark);\n for (let i = 1; i < marks.length; i++) {\n const currentDifference = Math.abs(clampedValue - marks[i].value);\n if (currentDifference < smallestDifference) {\n smallestDifference = currentDifference;\n closestMark = marks[i].value;\n }\n }\n return closestMark;\n }\n // Round to the nearest multiple of the step\n let roundedValue = Math.round(clampedValue / step) * step;\n // Ensure the rounded value does not exceed max\n if (roundedValue > max) {\n roundedValue = max;\n }\n return Number.parseFloat(roundedValue.toFixed(decimalPlaces));\n};\n\nexport const clampRange = (\n range: [number, number],\n max: number,\n min: number,\n step: number,\n decimalPlaces: number,\n marks?: { value: number; label: string }[],\n restrictToMarks?: boolean,\n) => {\n let [start, end] = range;\n\n if (Number.isNaN(start)) {\n start = min;\n }\n if (Number.isNaN(end)) {\n end = max;\n }\n if (start > end) {\n [start, end] = [end, start];\n }\n start = clamp(start, max, min, step, decimalPlaces, marks, restrictToMarks);\n end = clamp(end, max, min, step, decimalPlaces, marks, restrictToMarks);\n return [start, end] as [number, number];\n};\n\nexport const getClickedPosition = (\n sliderRef: RefObject<HTMLDivElement>,\n clientX: number,\n max: number,\n min: number,\n step: number,\n decimalPlaces: number,\n marks?: { label: string; value: number }[],\n restrictToMarks?: boolean,\n) => {\n if (!sliderRef.current) return;\n\n const sliderRect = sliderRef.current.getBoundingClientRect();\n const rawValue =\n ((clientX - sliderRect.left) / sliderRect.width) * (max - min) + min;\n const steppedValue = Math.round(rawValue / step) * step;\n return clamp(\n steppedValue,\n max,\n min,\n step,\n decimalPlaces,\n marks,\n restrictToMarks,\n );\n};\n\nexport const getKeyboardValue = (\n event: React.KeyboardEvent,\n value: number,\n step: number,\n stepMultiplier: number,\n max: number,\n min: number,\n restrictToMarks?: boolean,\n marks?: { label: string; value: number }[],\n) => {\n let newValue = value;\n\n if (restrictToMarks && marks && marks.length >= 1) {\n const currentIndex = marks.findIndex((mark) => mark.value === value);\n\n switch (event.key) {\n case \"ArrowUp\":\n case \"ArrowRight\":\n case \"PageUp\":\n if (currentIndex < marks.length - 1) {\n newValue = marks[currentIndex + 1].value;\n }\n break;\n case \"ArrowDown\":\n case \"ArrowLeft\":\n case \"PageDown\":\n if (currentIndex > 0) {\n newValue = marks[currentIndex - 1].value;\n }\n break;\n default:\n return newValue;\n }\n } else {\n switch (event.key) {\n case \"PageUp\":\n newValue = Math.min(value + step * stepMultiplier, max);\n break;\n case \"PageDown\":\n newValue = Math.max(value - step * stepMultiplier, min);\n break;\n default:\n return newValue;\n }\n }\n\n event.preventDefault();\n return newValue;\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var css_248z = ".saltTabOverflow {\n position: relative;\n}\n\n.saltTabOverflow-list {\n background: var(--salt-container-primary-background);\n border: var(--salt-size-border) var(--salt-selectable-borderStyle-selected) var(--salt-selectable-borderColor-selected);\n overflow: hidden;\n overflow-y: auto;\n position: absolute;\n z-index: var(--salt-zIndex-flyover);\n box-shadow: var(--salt-overlayable-shadow-popout);\n box-sizing: border-box;\n border-radius: var(--salt-palette-corner, 0);\n}\n\n.saltTabOverflow-listContainer {\n display: flex;\n flex-direction: column;\n gap: var(--salt-size-border);\n max-height: inherit;\n min-height: inherit;\n}\n\n.saltTabOverflow-list[data-hidden=\"true\"] {\n opacity: 0;\n pointer-events: none;\n}\n\n.saltTabOverflow-list .saltTabNext {\n color: var(--salt-content-primary-foreground);\n background: var(--salt-selectable-background);\n font-size: var(--salt-text-fontSize);\n font-weight: var(--salt-text-fontWeight);\n min-height: calc(var(--salt-size-base) + var(--salt-spacing-100));\n padding-left: var(--salt-spacing-100);\n padding-right: var(--salt-spacing-100);\n display: flex;\n gap: var(--salt-spacing-100);\n position: relative;\n align-items: center;\n cursor: var(--salt-selectable-cursor-hover);\n box-sizing: border-box;\n flex-shrink: 0;\n justify-content: flex-start;\n}\n\n.saltTabOverflow-list .saltTabNext .saltTabNextTrigger {\n justify-content: start;\n}\n\n.saltTabOverflow-list .saltTabNext::after {\n display: none;\n}\n\n.saltTabOverflow-list .saltTabNext[aria-disabled=\"true\"] {\n color: var(--salt-content-primary-foreground-disabled);\n cursor: var(--salt-selectable-cursor-disabled);\n}\n\n.saltTabOverflow-list .saltTabNext-focusVisible {\n outline: var(--salt-focused-outline);\n outline-offset: calc(var(--salt-size-border) * -2);\n}\n\n.saltTabOverflow-list .saltTabNext:hover {\n background: var(--salt-selectable-background-hover);\n}\n\n.saltTabOverflow-list .saltTabNext:active {\n background: var(--salt-selectable-background-selected);\n box-shadow: 0 calc(var(--salt-size-border) * -1) 0 0 var(--salt-selectable-borderColor-selected), 0 var(--salt-size-border) 0 0 var(--salt-selectable-borderColor-selected);\n}\n";
|
|
1
|
+
var css_248z = ".saltTabOverflow {\n position: relative;\n}\n\n.saltTabOverflow-list {\n background: var(--salt-container-primary-background);\n border: var(--salt-size-border) var(--salt-selectable-borderStyle-selected) var(--salt-selectable-borderColor-selected);\n overflow: hidden;\n overflow-y: auto;\n position: absolute;\n z-index: var(--salt-zIndex-flyover);\n box-shadow: var(--salt-overlayable-shadow-popout);\n box-sizing: border-box;\n border-radius: var(--salt-palette-corner, 0);\n}\n\n.saltTabOverflow-listContainer {\n display: flex;\n flex-direction: column;\n gap: var(--salt-size-border);\n max-height: inherit;\n min-height: inherit;\n}\n\n.saltTabOverflow-list[data-hidden=\"true\"] {\n opacity: 0;\n pointer-events: none;\n /* Avoid causing page to overflow with the hidden elements */\n width: 1px;\n height: 1px;\n}\n\n.saltTabOverflow-list .saltTabNext {\n color: var(--salt-content-primary-foreground);\n background: var(--salt-selectable-background);\n font-size: var(--salt-text-fontSize);\n font-weight: var(--salt-text-fontWeight);\n min-height: calc(var(--salt-size-base) + var(--salt-spacing-100));\n padding-left: var(--salt-spacing-100);\n padding-right: var(--salt-spacing-100);\n display: flex;\n gap: var(--salt-spacing-100);\n position: relative;\n align-items: center;\n cursor: var(--salt-selectable-cursor-hover);\n box-sizing: border-box;\n flex-shrink: 0;\n justify-content: flex-start;\n}\n\n.saltTabOverflow-list .saltTabNext .saltTabNextTrigger {\n justify-content: start;\n}\n\n.saltTabOverflow-list .saltTabNext::after {\n display: none;\n}\n\n.saltTabOverflow-list .saltTabNext[aria-disabled=\"true\"] {\n color: var(--salt-content-primary-foreground-disabled);\n cursor: var(--salt-selectable-cursor-disabled);\n}\n\n.saltTabOverflow-list .saltTabNext-focusVisible {\n outline: var(--salt-focused-outline);\n outline-offset: calc(var(--salt-size-border) * -2);\n}\n\n.saltTabOverflow-list .saltTabNext:hover {\n background: var(--salt-selectable-background-hover);\n}\n\n.saltTabOverflow-list .saltTabNext:active {\n background: var(--salt-selectable-background-selected);\n box-shadow: 0 calc(var(--salt-size-border) * -1) 0 0 var(--salt-selectable-borderColor-selected), 0 var(--salt-size-border) 0 0 var(--salt-selectable-borderColor-selected);\n}\n";
|
|
2
2
|
|
|
3
3
|
export { css_248z as default };
|
|
4
4
|
//# sourceMappingURL=TabOverflowList.css.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { offset, size, useInteractions, useDismiss, FloatingTree } from '@floating-ui/react';
|
|
2
|
+
import { offset, size, flip, useInteractions, useDismiss, FloatingTree } from '@floating-ui/react';
|
|
3
3
|
import { makePrefixer, useIcon, useFloatingUI, useForkRef, useId, Button } from '@salt-ds/core';
|
|
4
4
|
import { useComponentCssInjection } from '@salt-ds/styles';
|
|
5
5
|
import { useWindow } from '@salt-ds/window';
|
|
@@ -52,7 +52,8 @@ const TabOverflowList = forwardRef(
|
|
|
52
52
|
maxHeight: `max(calc((var(--salt-size-base) + var(--salt-spacing-100)) * 5), calc(${availableHeight}px - var(--salt-spacing-100)))`
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
|
-
})
|
|
55
|
+
}),
|
|
56
|
+
flip()
|
|
56
57
|
]
|
|
57
58
|
});
|
|
58
59
|
const { getFloatingProps } = useInteractions([useDismiss(context)]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabOverflowList.js","sources":["../src/tabs-next/TabOverflowList.tsx"],"sourcesContent":["import {\n FloatingTree,\n offset,\n size,\n useDismiss,\n useInteractions,\n} from \"@floating-ui/react\";\nimport {\n Button,\n makePrefixer,\n useFloatingUI,\n useForkRef,\n useIcon,\n useId,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport {\n Children,\n type ComponentPropsWithoutRef,\n type Dispatch,\n type ReactNode,\n type Ref,\n type RefObject,\n type SetStateAction,\n forwardRef,\n useCallback,\n useRef,\n} from \"react\";\nimport tabOverflowListCss from \"./TabOverflowList.css\";\nimport { useFocusOutside } from \"./hooks/useFocusOutside\";\n\ninterface TabOverflowListProps extends ComponentPropsWithoutRef<\"button\"> {\n buttonRef?: Ref<HTMLButtonElement>;\n tabstripRef: RefObject<HTMLDivElement>;\n children?: ReactNode;\n isMeasuring?: boolean;\n open: boolean;\n setOpen: Dispatch<SetStateAction<boolean>>;\n}\n\nconst withBaseName = makePrefixer(\"saltTabOverflow\");\n\nexport const TabOverflowList = forwardRef<HTMLDivElement, TabOverflowListProps>(\n function TabOverflowList(props, ref) {\n const {\n buttonRef,\n tabstripRef,\n children,\n isMeasuring,\n open,\n setOpen,\n ...rest\n } = props;\n\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-tabs-next-overflow-list\",\n css: tabOverflowListCss,\n window: targetWindow,\n });\n\n const { OverflowIcon } = useIcon();\n\n const { refs, x, y, strategy, context } = useFloatingUI({\n open: open,\n onOpenChange(open, _, reason) {\n if (reason === \"escape-key\") {\n queueMicrotask(() => {\n const allTabs =\n tabstripRef.current?.querySelectorAll<HTMLElement>(\n '[role=\"tab\"]:not([aria-hidden])',\n ) ?? [];\n const numberOfTabsInOverflow =\n listRef.current?.querySelectorAll<HTMLElement>('[role=\"tab\"]')\n .length ?? 0;\n\n allTabs[allTabs.length - numberOfTabsInOverflow - 1]?.focus({\n preventScroll: true,\n });\n });\n }\n\n setOpen(open);\n },\n placement: \"bottom-start\",\n middleware: [\n offset(1),\n size({\n apply({ elements, availableHeight }) {\n Object.assign(elements.floating.style, {\n maxHeight: `max(calc((var(--salt-size-base) + var(--salt-spacing-100)) * 5), calc(${availableHeight}px - var(--salt-spacing-100)))`,\n });\n },\n }),\n ],\n });\n\n const { getFloatingProps } = useInteractions([useDismiss(context)]);\n\n const rootRef = useRef<HTMLDivElement>(null);\n const handleRootRef = useForkRef(rootRef, ref);\n const listRef = useRef<HTMLDivElement>(null);\n const handleListRef = useForkRef<HTMLDivElement>(listRef, refs.setFloating);\n\n const handleFocusOutside = useCallback(() => {\n setOpen(false);\n }, [setOpen]);\n\n useFocusOutside(\n rootRef,\n handleFocusOutside,\n open,\n \"[data-floating-ui-portal]\",\n );\n\n const handleClick = () => {\n if (!open) {\n listRef.current\n ?.querySelectorAll<HTMLElement>('[role=\"tab\"]')[0]\n ?.focus({ preventScroll: true });\n } else {\n setOpen(false);\n }\n };\n\n const handleFocus = () => {\n setOpen(true);\n };\n\n const handleButtonRef = useForkRef<HTMLButtonElement>(\n buttonRef,\n refs.setReference,\n );\n\n const listId = useId();\n\n const childCount = Children.count(children);\n if (childCount === 0 && !isMeasuring) return null;\n\n return (\n <div className={withBaseName()} ref={handleRootRef} data-overflow>\n <Button\n data-overflowbutton\n tabIndex={-1}\n appearance=\"transparent\"\n sentiment=\"neutral\"\n onClick={handleClick}\n ref={handleButtonRef}\n aria-label={`Overflow menu. ${childCount} tabs hidden`}\n aria-expanded={open}\n aria-controls={listId}\n aria-hidden=\"true\"\n role=\"tab\"\n aria-haspopup\n {...rest}\n >\n <OverflowIcon aria-hidden />\n </Button>\n <FloatingTree>\n <div\n ref={handleListRef}\n {...getFloatingProps({\n onFocus: handleFocus,\n role: \"presentation\",\n })}\n className={withBaseName(\"list\")}\n data-hidden={!open}\n style={\n open\n ? { left: x ?? 0, top: y ?? 0, position: strategy }\n : undefined\n }\n id={listId}\n >\n <div className={withBaseName(\"listContainer\")}>{children}</div>\n </div>\n </FloatingTree>\n </div>\n );\n },\n);\n"],"names":["TabOverflowList","tabOverflowListCss","open"],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"TabOverflowList.js","sources":["../src/tabs-next/TabOverflowList.tsx"],"sourcesContent":["import {\n FloatingTree,\n flip,\n offset,\n size,\n useDismiss,\n useInteractions,\n} from \"@floating-ui/react\";\nimport {\n Button,\n makePrefixer,\n useFloatingUI,\n useForkRef,\n useIcon,\n useId,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport {\n Children,\n type ComponentPropsWithoutRef,\n type Dispatch,\n type ReactNode,\n type Ref,\n type RefObject,\n type SetStateAction,\n forwardRef,\n useCallback,\n useRef,\n} from \"react\";\nimport tabOverflowListCss from \"./TabOverflowList.css\";\nimport { useFocusOutside } from \"./hooks/useFocusOutside\";\n\ninterface TabOverflowListProps extends ComponentPropsWithoutRef<\"button\"> {\n buttonRef?: Ref<HTMLButtonElement>;\n tabstripRef: RefObject<HTMLDivElement>;\n children?: ReactNode;\n isMeasuring?: boolean;\n open: boolean;\n setOpen: Dispatch<SetStateAction<boolean>>;\n}\n\nconst withBaseName = makePrefixer(\"saltTabOverflow\");\n\nexport const TabOverflowList = forwardRef<HTMLDivElement, TabOverflowListProps>(\n function TabOverflowList(props, ref) {\n const {\n buttonRef,\n tabstripRef,\n children,\n isMeasuring,\n open,\n setOpen,\n ...rest\n } = props;\n\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-tabs-next-overflow-list\",\n css: tabOverflowListCss,\n window: targetWindow,\n });\n\n const { OverflowIcon } = useIcon();\n\n const { refs, x, y, strategy, context } = useFloatingUI({\n open: open,\n onOpenChange(open, _, reason) {\n if (reason === \"escape-key\") {\n queueMicrotask(() => {\n const allTabs =\n tabstripRef.current?.querySelectorAll<HTMLElement>(\n '[role=\"tab\"]:not([aria-hidden])',\n ) ?? [];\n const numberOfTabsInOverflow =\n listRef.current?.querySelectorAll<HTMLElement>('[role=\"tab\"]')\n .length ?? 0;\n\n allTabs[allTabs.length - numberOfTabsInOverflow - 1]?.focus({\n preventScroll: true,\n });\n });\n }\n\n setOpen(open);\n },\n placement: \"bottom-start\",\n middleware: [\n offset(1),\n size({\n apply({ elements, availableHeight }) {\n Object.assign(elements.floating.style, {\n maxHeight: `max(calc((var(--salt-size-base) + var(--salt-spacing-100)) * 5), calc(${availableHeight}px - var(--salt-spacing-100)))`,\n });\n },\n }),\n flip(),\n ],\n });\n\n const { getFloatingProps } = useInteractions([useDismiss(context)]);\n\n const rootRef = useRef<HTMLDivElement>(null);\n const handleRootRef = useForkRef(rootRef, ref);\n const listRef = useRef<HTMLDivElement>(null);\n const handleListRef = useForkRef<HTMLDivElement>(listRef, refs.setFloating);\n\n const handleFocusOutside = useCallback(() => {\n setOpen(false);\n }, [setOpen]);\n\n useFocusOutside(\n rootRef,\n handleFocusOutside,\n open,\n \"[data-floating-ui-portal]\",\n );\n\n const handleClick = () => {\n if (!open) {\n listRef.current\n ?.querySelectorAll<HTMLElement>('[role=\"tab\"]')[0]\n ?.focus({ preventScroll: true });\n } else {\n setOpen(false);\n }\n };\n\n const handleFocus = () => {\n setOpen(true);\n };\n\n const handleButtonRef = useForkRef<HTMLButtonElement>(\n buttonRef,\n refs.setReference,\n );\n\n const listId = useId();\n\n const childCount = Children.count(children);\n if (childCount === 0 && !isMeasuring) return null;\n\n return (\n <div className={withBaseName()} ref={handleRootRef} data-overflow>\n <Button\n data-overflowbutton\n tabIndex={-1}\n appearance=\"transparent\"\n sentiment=\"neutral\"\n onClick={handleClick}\n ref={handleButtonRef}\n aria-label={`Overflow menu. ${childCount} tabs hidden`}\n aria-expanded={open}\n aria-controls={listId}\n aria-hidden=\"true\"\n role=\"tab\"\n aria-haspopup\n {...rest}\n >\n <OverflowIcon aria-hidden />\n </Button>\n <FloatingTree>\n <div\n ref={handleListRef}\n {...getFloatingProps({\n onFocus: handleFocus,\n role: \"presentation\",\n })}\n className={withBaseName(\"list\")}\n data-hidden={!open}\n style={\n open\n ? { left: x ?? 0, top: y ?? 0, position: strategy }\n : undefined\n }\n id={listId}\n >\n <div className={withBaseName(\"listContainer\")}>{children}</div>\n </div>\n </FloatingTree>\n </div>\n );\n },\n);\n"],"names":["TabOverflowList","tabOverflowListCss","open"],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { DateFrameworkType } from "@salt-ds/date-adapters";
|
|
2
2
|
import { type ReactNode } from "react";
|
|
3
|
+
import { type DatePickerOpenChangeReason } from "./DatePickerOverlayProvider";
|
|
3
4
|
import { type UseDatePickerRangeProps, type UseDatePickerSingleProps } from "./useDatePicker";
|
|
4
5
|
/**
|
|
5
6
|
* Base props for DatePicker.
|
|
@@ -9,11 +10,15 @@ export interface DatePickerBaseProps {
|
|
|
9
10
|
children?: ReactNode;
|
|
10
11
|
/** the open/close state of the overlay. The open/close state will be controlled when this prop is provided. */
|
|
11
12
|
open?: boolean;
|
|
13
|
+
/** When `open` is uncontrolled, set this to `true` to open on click */
|
|
14
|
+
openOnClick?: boolean;
|
|
12
15
|
/**
|
|
13
16
|
* Handler for when open state changes
|
|
14
17
|
* @param newOpen - true when opened
|
|
18
|
+
* @param event - event that triggered the state change
|
|
19
|
+
* @param reason - reason for the the state change
|
|
15
20
|
*/
|
|
16
|
-
|
|
21
|
+
onOpenChange?: (newOpen: boolean, event?: Event, reason?: DatePickerOpenChangeReason) => void;
|
|
17
22
|
/**
|
|
18
23
|
* the initial open/close state of the overlay, when the open/close state is un-controlled.
|
|
19
24
|
*/
|
|
@@ -45,8 +45,9 @@ interface DatePickerBaseState<TDate extends DateFrameworkType> {
|
|
|
45
45
|
helpers: {
|
|
46
46
|
/**
|
|
47
47
|
* Cancels the DatePicker action.
|
|
48
|
+
* @param event - event that triggered the state change
|
|
48
49
|
*/
|
|
49
|
-
cancel: () => void;
|
|
50
|
+
cancel: (event?: Event) => void;
|
|
50
51
|
/**
|
|
51
52
|
* Sets the enableApply state.
|
|
52
53
|
* @param newEnableApply - The new value for enableApply.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { useInteractions } from "@floating-ui/react";
|
|
1
|
+
import { type ElementProps, type FloatingContext, type OpenChangeReason as FloatingUIOpenChangeReason, useInteractions } from "@floating-ui/react";
|
|
2
2
|
import { useFloatingUI } from "@salt-ds/core";
|
|
3
3
|
import { type ReactNode } from "react";
|
|
4
|
+
/** Reason for overlay state change, can be a custom reason */
|
|
5
|
+
export declare type DatePickerOpenChangeReason = FloatingUIOpenChangeReason | "apply" | "cancel" | string;
|
|
4
6
|
/**
|
|
5
7
|
* Interface representing the state for a DatePicker overlay.
|
|
6
8
|
*/
|
|
@@ -29,13 +31,15 @@ interface DatePickerOverlayHelpers {
|
|
|
29
31
|
/**
|
|
30
32
|
* Sets the open state of the overlay.
|
|
31
33
|
* @param newOpen - The new value for the open state.
|
|
34
|
+
* @param event - event that triggered the state change
|
|
35
|
+
* @param reason - reason for the the state change
|
|
32
36
|
*/
|
|
33
|
-
setOpen: (newOpen: boolean) => void;
|
|
37
|
+
setOpen: (newOpen: boolean, event?: Event, reason?: DatePickerOpenChangeReason) => void;
|
|
34
38
|
/**~
|
|
35
39
|
* Register a callback for when onDismiss is called
|
|
36
40
|
* @param onDismissCallback
|
|
37
41
|
*/
|
|
38
|
-
setOnDismiss: (onDismissCallback: () => void) => void;
|
|
42
|
+
setOnDismiss: (onDismissCallback: (event?: Event) => void) => void;
|
|
39
43
|
}
|
|
40
44
|
/**
|
|
41
45
|
* Interface representing the context type for a DatePicker overlay.
|
|
@@ -58,11 +62,17 @@ interface DatePickerOverlayProviderProps {
|
|
|
58
62
|
* If `true`, the overlay is open.
|
|
59
63
|
*/
|
|
60
64
|
open?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* When `open` is uncontrolled, set this to `true` to open on click
|
|
67
|
+
*/
|
|
68
|
+
openOnClick?: boolean;
|
|
61
69
|
/**
|
|
62
70
|
* Handler for when open state changes
|
|
63
71
|
* @param newOpen - true when opened
|
|
72
|
+
* @param event - event that triggered the state change
|
|
73
|
+
* @param reason - reason for the the state change
|
|
64
74
|
*/
|
|
65
|
-
|
|
75
|
+
onOpenChange?: (newOpen: boolean, event?: Event, reason?: DatePickerOpenChangeReason) => void;
|
|
66
76
|
/**
|
|
67
77
|
* The default open state of the overlay.
|
|
68
78
|
*/
|
|
@@ -71,6 +81,10 @@ interface DatePickerOverlayProviderProps {
|
|
|
71
81
|
* The content to be rendered inside the overlay provider.
|
|
72
82
|
*/
|
|
73
83
|
children: ReactNode;
|
|
84
|
+
/**
|
|
85
|
+
* A factory method to create a set of interaction, if provided overrides the default interactions
|
|
86
|
+
*/
|
|
87
|
+
interactions?: (context: FloatingContext) => Array<ElementProps>;
|
|
74
88
|
/**
|
|
75
89
|
* When true, shouldn't open the overlay.
|
|
76
90
|
*/
|
|
@@ -13,5 +13,5 @@ export interface DatePickerRangeInputProps<TDate extends DateFrameworkType> exte
|
|
|
13
13
|
*/
|
|
14
14
|
validate?: (date: DateRangeSelection<TDate> | null, details: DateInputRangeDetails) => DateInputRangeDetails;
|
|
15
15
|
}
|
|
16
|
-
export declare function defaultRangeValidator<TDate extends DateFrameworkType>(dateAdapter: SaltDateAdapter<TDate>, date: DateRangeSelection<TDate> | null, details: DateInputRangeDetails, minDate
|
|
16
|
+
export declare function defaultRangeValidator<TDate extends DateFrameworkType>(dateAdapter: SaltDateAdapter<TDate>, date: DateRangeSelection<TDate> | null, details: DateInputRangeDetails, minDate?: TDate, maxDate?: TDate): DateInputRangeDetails;
|
|
17
17
|
export declare const DatePickerRangeInput: import("react").ForwardRefExoticComponent<DatePickerRangeInputProps<unknown> & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -2,6 +2,7 @@ export * from "./DatePicker";
|
|
|
2
2
|
export * from "./DatePickerActions";
|
|
3
3
|
export * from "./DatePickerContext";
|
|
4
4
|
export * from "./DatePickerOverlay";
|
|
5
|
+
export * from "./DatePickerOverlayProvider";
|
|
5
6
|
export * from "./DatePickerRangeInput";
|
|
6
7
|
export * from "./DatePickerRangePanel";
|
|
7
8
|
export * from "./DatePickerSingleInput";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ElementProps, FloatingContext } from "@floating-ui/react";
|
|
2
|
+
export interface UseKeyboardProps {
|
|
3
|
+
/**
|
|
4
|
+
* Whether the hook is enabled
|
|
5
|
+
* @default true
|
|
6
|
+
*/
|
|
7
|
+
enabled?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Floating UI Interactions hook, that will open DatePicker on keydown
|
|
11
|
+
* @param context
|
|
12
|
+
* @param props
|
|
13
|
+
*/
|
|
14
|
+
export declare function useKeyboard(context: FloatingContext, props: UseKeyboardProps): ElementProps;
|
package/dist-types/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type { SelectHandler, SelectionChangeHandler, SelectionStrategy, useCollectionItems, } from "./common-hooks";
|
|
2
|
-
export type { ListChangeHandler as ListChangeHandlerDeprecated, ListSelectHandler as ListSelectHandlerDeprecated, } from "./list-deprecated";
|
|
3
2
|
export { ListItemBase as ListItemBaseDeprecated, useListItem as useListItemDeprecated, } from "./list-deprecated";
|
|
3
|
+
export type { ListChangeHandler as ListChangeHandlerDeprecated, ListSelectHandler as ListSelectHandlerDeprecated, } from "./list-deprecated";
|
|
4
4
|
export * from "./app-header";
|
|
5
5
|
export * from "./breadcrumbs";
|
|
6
6
|
export * from "./button-bar";
|
|
@@ -19,11 +19,11 @@ export * from "./deck-layout";
|
|
|
19
19
|
export * from "./dialog";
|
|
20
20
|
export * from "./dropdown";
|
|
21
21
|
export * from "./editable-label";
|
|
22
|
-
export { FormFieldLegacy as FormField, type FormFieldLegacyProps as FormFieldProps, FormLabel, } from "./form-field-legacy";
|
|
23
22
|
export * from "./form-field-context-legacy";
|
|
23
|
+
export { FormFieldLegacy as FormField, FormLabel, type FormFieldLegacyProps as FormFieldProps, } from "./form-field-legacy";
|
|
24
24
|
export * from "./form-group";
|
|
25
25
|
export * from "./formatted-input";
|
|
26
|
-
export { InputLegacy as Input, type InputLegacyProps as InputProps,
|
|
26
|
+
export { InputLegacy as Input, StaticInputAdornment, type InputLegacyProps as InputProps, } from "./input-legacy";
|
|
27
27
|
export * from "./layer-layout";
|
|
28
28
|
export * from "./list";
|
|
29
29
|
export * from "./list-next";
|
|
@@ -31,6 +31,7 @@ export * from "./localization-provider";
|
|
|
31
31
|
export * from "./logo";
|
|
32
32
|
export * from "./menu-button";
|
|
33
33
|
export * from "./metric";
|
|
34
|
+
export * from "./number-input";
|
|
34
35
|
export * from "./overlay";
|
|
35
36
|
export * from "./portal";
|
|
36
37
|
export * from "./query-input";
|
|
@@ -40,7 +41,6 @@ export * from "./slider";
|
|
|
40
41
|
export * from "./splitter";
|
|
41
42
|
export * from "./static-list";
|
|
42
43
|
export * from "./stepped-tracker";
|
|
43
|
-
export * from "./stepper-input";
|
|
44
44
|
export * from "./system-status";
|
|
45
45
|
export * from "./tabs";
|
|
46
46
|
export * from "./tabs-next";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ValidationStatus } from "@salt-ds/core";
|
|
2
2
|
import { type ComponentPropsWithoutRef, type InputHTMLAttributes, type ReactNode, type Ref, type SyntheticEvent } from "react";
|
|
3
|
-
export interface
|
|
3
|
+
export interface NumberInputProps extends Omit<ComponentPropsWithoutRef<"div">, "onChange"> {
|
|
4
4
|
/**
|
|
5
5
|
* A boolean. When `true`, the input will receive a full border.
|
|
6
6
|
*/
|
|
@@ -14,7 +14,7 @@ export interface StepperInputProps extends Omit<ComponentPropsWithoutRef<"div">,
|
|
|
14
14
|
*/
|
|
15
15
|
defaultValue?: number | string;
|
|
16
16
|
/**
|
|
17
|
-
* If `true`, the
|
|
17
|
+
* If `true`, the number input will be disabled.
|
|
18
18
|
*/
|
|
19
19
|
disabled?: boolean;
|
|
20
20
|
/**
|
|
@@ -28,7 +28,7 @@ export interface StepperInputProps extends Omit<ComponentPropsWithoutRef<"div">,
|
|
|
28
28
|
*/
|
|
29
29
|
endAdornment?: ReactNode;
|
|
30
30
|
/**
|
|
31
|
-
* Whether to hide the
|
|
31
|
+
* Whether to hide the number buttons. Defaults to `false`.
|
|
32
32
|
* @default false
|
|
33
33
|
*/
|
|
34
34
|
hideButtons?: boolean;
|
|
@@ -51,7 +51,7 @@ export interface StepperInputProps extends Omit<ComponentPropsWithoutRef<"div">,
|
|
|
51
51
|
*/
|
|
52
52
|
min?: number;
|
|
53
53
|
/**
|
|
54
|
-
* Callback when
|
|
54
|
+
* Callback when number input value is changed.
|
|
55
55
|
* @param event - the event triggers value change, could be undefined during increment / decrement button long press
|
|
56
56
|
*/
|
|
57
57
|
onChange?: (event: SyntheticEvent | undefined, value: number | string) => void;
|
|
@@ -68,7 +68,7 @@ export interface StepperInputProps extends Omit<ComponentPropsWithoutRef<"div">,
|
|
|
68
68
|
*/
|
|
69
69
|
startAdornment?: ReactNode;
|
|
70
70
|
/**
|
|
71
|
-
* The amount to increment or decrement the value by when using the
|
|
71
|
+
* The amount to increment or decrement the value by when using the number buttons or Up Arrow and Down Arrow keys. Default to 1.
|
|
72
72
|
* @default 1
|
|
73
73
|
*/
|
|
74
74
|
step?: number;
|
|
@@ -93,8 +93,8 @@ export interface StepperInputProps extends Omit<ComponentPropsWithoutRef<"div">,
|
|
|
93
93
|
*/
|
|
94
94
|
variant?: "primary" | "secondary";
|
|
95
95
|
/**
|
|
96
|
-
* The value of the
|
|
96
|
+
* The value of the number input. The component will be controlled if this prop is provided.
|
|
97
97
|
*/
|
|
98
98
|
value?: number | string | undefined;
|
|
99
99
|
}
|
|
100
|
-
export declare const
|
|
100
|
+
export declare const NumberInput: import("react").ForwardRefExoticComponent<NumberInputProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { type Dispatch, type MouseEvent, type MutableRefObject, type SetStateAction, type SyntheticEvent } from "react";
|
|
2
|
-
import type {
|
|
2
|
+
import type { NumberInputProps } from "./NumberInput";
|
|
3
3
|
/**
|
|
4
4
|
* Manages increment / decrement logic
|
|
5
5
|
*/
|
|
6
|
-
export declare const
|
|
6
|
+
export declare const useNumberInput: ({ decimalPlaces, disabled, inputRef, max, min, onChange, readOnly, setValue, step, stepBlock, value, }: Pick<NumberInputProps, "value" | "max" | "min" | "onChange" | "disabled" | "readOnly" | "step" | "inputRef" | "decimalPlaces" | "stepBlock"> & {
|
|
7
7
|
setValue: Dispatch<SetStateAction<string | number | undefined>>;
|
|
8
8
|
inputRef: MutableRefObject<HTMLInputElement | null>;
|
|
9
9
|
}) => {
|