@dreamtree-org/twreact-ui 1.3.8 → 1.3.10
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/DESIGN.md +11 -3
- package/README.md +9 -1
- package/ai-skills/dreamtree-ui.md +2 -2
- package/dist/ai-schema.json +19 -8
- package/dist/charts/index.js +69 -24
- package/dist/components/blocks/AppShell.d.ts.map +1 -1
- package/dist/components/charts/chartTheme.d.ts +2 -5
- package/dist/components/charts/chartTheme.d.ts.map +1 -1
- package/dist/components/core/Accordion.d.ts.map +1 -1
- package/dist/components/core/ColorPicker.d.ts.map +1 -1
- package/dist/components/core/DatePicker.d.ts.map +1 -1
- package/dist/components/core/Form.d.ts.map +1 -1
- package/dist/components/core/Input.d.ts.map +1 -1
- package/dist/components/core/PriceRangePicker.d.ts +0 -29
- package/dist/components/core/PriceRangePicker.d.ts.map +1 -1
- package/dist/components/core/Radio.d.ts.map +1 -1
- package/dist/components/core/Rate.d.ts.map +1 -1
- package/dist/components/core/RoundedTag.d.ts.map +1 -1
- package/dist/components/core/Table/ColumnMenu.d.ts.map +1 -1
- package/dist/components/core/Table/Pagination.d.ts.map +1 -1
- package/dist/components/core/Table/Table.d.ts.map +1 -1
- package/dist/components/core/Table/TableRow.d.ts.map +1 -1
- package/dist/components/core/Table/helpers.d.ts +2 -0
- package/dist/components/core/Table/helpers.d.ts.map +1 -1
- package/dist/components/core/Table/useClickOutside.d.ts +5 -2
- package/dist/components/core/Table/useClickOutside.d.ts.map +1 -1
- package/dist/components/core/Tabs.d.ts.map +1 -1
- package/dist/components/core/TextToSpeech.d.ts +2 -7
- package/dist/components/core/TextToSpeech.d.ts.map +1 -1
- package/dist/components/core/Tooltip.d.ts.map +1 -1
- package/dist/components/feedback/Alert.d.ts.map +1 -1
- package/dist/components/feedback/Dialog.d.ts.map +1 -1
- package/dist/components/feedback/Toast.d.ts.map +1 -1
- package/dist/components/navigation/Sidebar.d.ts.map +1 -1
- package/dist/components/utility/Avatar.d.ts.map +1 -1
- package/dist/components/utility/Carousel.d.ts.map +1 -1
- package/dist/components/utility/Portal.d.ts +6 -0
- package/dist/components/utility/Portal.d.ts.map +1 -0
- package/dist/esm/components/blocks/AppShell.js +24 -18
- package/dist/esm/components/charts/CartesianChart.js +2 -1
- package/dist/esm/components/charts/DonutChart.js +2 -1
- package/dist/esm/components/charts/Sparkline.js +2 -1
- package/dist/esm/components/charts/chartTheme.js +1 -22
- package/dist/esm/components/core/Accordion.js +40 -9
- package/dist/esm/components/core/Button.js +8 -8
- package/dist/esm/components/core/ColorPicker.js +19 -7
- package/dist/esm/components/core/DatePicker.js +97 -58
- package/dist/esm/components/core/Form.js +35 -8
- package/dist/esm/components/core/Input.js +3 -1
- package/dist/esm/components/core/PriceRangePicker.js +205 -218
- package/dist/esm/components/core/Radio.js +36 -6
- package/dist/esm/components/core/Rate.js +41 -50
- package/dist/esm/components/core/RoundedTag.js +25 -8
- package/dist/esm/components/core/Table/ColumnMenu.js +2 -4
- package/dist/esm/components/core/Table/Pagination.js +15 -18
- package/dist/esm/components/core/Table/Table.js +11 -5
- package/dist/esm/components/core/Table/TableRow.js +2 -2
- package/dist/esm/components/core/Table/helpers.js +33 -1
- package/dist/esm/components/core/Tabs.js +6 -5
- package/dist/esm/components/core/TextToSpeech.js +121 -28
- package/dist/esm/components/core/Tooltip.js +100 -28
- package/dist/esm/components/feedback/Alert.js +21 -11
- package/dist/esm/components/feedback/Dialog.js +44 -100
- package/dist/esm/components/feedback/Toast.js +24 -5
- package/dist/esm/components/navigation/Sidebar.js +13 -61
- package/dist/esm/components/utility/Avatar.js +23 -10
- package/dist/esm/components/utility/Carousel.js +34 -17
- package/dist/esm/components/utility/Pagination.js +2 -2
- package/dist/esm/hooks/useClickOutside.js +51 -0
- package/dist/esm/hooks/useFocusTrap.js +10 -2
- package/dist/esm/hooks/useMediaQuery.js +61 -0
- package/dist/esm/hooks/useReducedMotion.js +17 -0
- package/dist/esm/hooks/useScrollLock.js +76 -9
- package/dist/esm/hooks/useTheme.js +6 -1
- package/dist/esm/utils/position.js +6 -0
- package/dist/hooks/useClickOutside.d.ts +14 -0
- package/dist/hooks/useClickOutside.d.ts.map +1 -0
- package/dist/hooks/useFloatingPosition.d.ts +37 -0
- package/dist/hooks/useFloatingPosition.d.ts.map +1 -0
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useMediaQuery.d.ts +22 -0
- package/dist/hooks/useMediaQuery.d.ts.map +1 -0
- package/dist/hooks/usePresence.d.ts +16 -0
- package/dist/hooks/usePresence.d.ts.map +1 -0
- package/dist/hooks/usePresentation.d.ts +9 -0
- package/dist/hooks/usePresentation.d.ts.map +1 -0
- package/dist/hooks/useReducedMotion.d.ts +10 -0
- package/dist/hooks/useReducedMotion.d.ts.map +1 -0
- package/dist/hooks/useScrollLock.d.ts +11 -1
- package/dist/hooks/useScrollLock.d.ts.map +1 -1
- package/dist/hooks/useTheme.d.ts.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.js +1719 -1201
- package/dist/index.js +1718 -1200
- package/dist/tokens/tailwind3-preset.cjs +101 -8
- package/dist/tokens/theme.css +27 -0
- package/dist/tokens/tokens.json +175 -0
- package/dist/tokens/vars.css +2 -0
- package/dist/types/index.d.ts +8 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/position.d.ts.map +1 -1
- package/dist/utils/touchTarget.d.ts +1 -0
- package/dist/utils/touchTarget.d.ts.map +1 -1
- package/mcp/catalog.snapshot.json +83 -53
- package/package.json +2 -1
- package/tokens/lib.cjs +35 -0
- package/tokens/tokens.json +58 -2
- package/dist/esm/components/core/Table/useClickOutside.js +0 -26
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { objectWithoutProperties as _objectWithoutProperties, typeof as _typeof, slicedToArray as _slicedToArray, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
-
import { jsxs, jsx
|
|
4
|
-
import { forwardRef, useState, useEffect, useMemo } from 'react';
|
|
2
|
+
import { objectWithoutProperties as _objectWithoutProperties, typeof as _typeof, slicedToArray as _slicedToArray, objectSpread2 as _objectSpread2, defineProperty as _defineProperty } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
+
import { forwardRef, useState, useEffect, useRef, useMemo } from 'react';
|
|
5
5
|
import { cn } from '../../utils/cn.js';
|
|
6
|
+
import { toPercent, keyToValue } from '../../hooks/useSliderValues.js';
|
|
7
|
+
import { TOUCH_TARGET } from '../../utils/touchTarget.js';
|
|
6
8
|
|
|
7
9
|
var _excluded = ["min", "max", "step", "minGap", "value", "defaultValue", "onChange", "onFinalChange", "showInputs", "showTooltips", "disabled", "presets", "formatValue", "className", "size", "colorClass", "ariaLabel"];
|
|
8
10
|
/**
|
|
9
|
-
*
|
|
11
|
+
* PriceRangePicker - dual-thumb range picker (Tailwind)
|
|
10
12
|
*
|
|
11
13
|
* Props
|
|
12
14
|
* - min: number (default 0)
|
|
@@ -16,7 +18,7 @@ var _excluded = ["min", "max", "step", "minGap", "value", "defaultValue", "onCha
|
|
|
16
18
|
* - value: { min: number, max: number } | null (controlled)
|
|
17
19
|
* - defaultValue: { min: number, max: number } (uncontrolled initial)
|
|
18
20
|
* - onChange: (value) => void
|
|
19
|
-
* - onFinalChange: (value) => void // called on
|
|
21
|
+
* - onFinalChange: (value) => void // called when a drag ends, on thumb keys, or Enter/blur in inputs
|
|
20
22
|
* - showInputs: boolean (default true)
|
|
21
23
|
* - showTooltips: boolean (default true)
|
|
22
24
|
* - disabled: boolean
|
|
@@ -24,16 +26,29 @@ var _excluded = ["min", "max", "step", "minGap", "value", "defaultValue", "onCha
|
|
|
24
26
|
* - formatValue: (n) => string (formatting callback, default: n => n)
|
|
25
27
|
* - className: string (container custom classes)
|
|
26
28
|
* - size: 'sm' | 'md' | 'lg' (affects thumb size & spacing)
|
|
27
|
-
* - colorClass: Tailwind class for active track
|
|
29
|
+
* - colorClass: Tailwind bg class for the active track and thumbs, default 'bg-primary-600'
|
|
28
30
|
* - ariaLabel: string
|
|
29
31
|
*
|
|
30
|
-
* Usage notes
|
|
31
|
-
* - Controlled mode: pass `value` and handle updates via onChange.
|
|
32
|
-
* - Uncontrolled mode: omit `value` and use `defaultValue`.
|
|
33
|
-
*
|
|
34
32
|
* Accessibility
|
|
35
|
-
* -
|
|
33
|
+
* - Each thumb is a `role="slider"` with arrow / Page / Home / End keys.
|
|
34
|
+
* - Dragging uses pointer capture, so mouse, touch and pen all work and a
|
|
35
|
+
* release outside the track still ends the drag.
|
|
36
36
|
*/
|
|
37
|
+
var THUMB_SIZE = {
|
|
38
|
+
sm: "h-4 w-4",
|
|
39
|
+
md: "h-5 w-5",
|
|
40
|
+
lg: "h-7 w-7"
|
|
41
|
+
};
|
|
42
|
+
var TRACK_HEIGHT = {
|
|
43
|
+
sm: "h-1",
|
|
44
|
+
md: "h-1.5",
|
|
45
|
+
lg: "h-2"
|
|
46
|
+
};
|
|
47
|
+
var INPUT_WIDTH = {
|
|
48
|
+
sm: "w-16",
|
|
49
|
+
md: "w-20",
|
|
50
|
+
lg: "w-24"
|
|
51
|
+
};
|
|
37
52
|
var PriceRangePicker = /*#__PURE__*/forwardRef(function PriceRangePicker(_ref, ref) {
|
|
38
53
|
var _ref$min = _ref.min,
|
|
39
54
|
min = _ref$min === void 0 ? 0 : _ref$min,
|
|
@@ -71,188 +86,169 @@ var PriceRangePicker = /*#__PURE__*/forwardRef(function PriceRangePicker(_ref, r
|
|
|
71
86
|
_ref$size = _ref.size,
|
|
72
87
|
size = _ref$size === void 0 ? "md" : _ref$size,
|
|
73
88
|
_ref$colorClass = _ref.colorClass,
|
|
74
|
-
colorClass = _ref$colorClass === void 0 ? "bg-
|
|
89
|
+
colorClass = _ref$colorClass === void 0 ? "bg-primary-600" : _ref$colorClass,
|
|
75
90
|
_ref$ariaLabel = _ref.ariaLabel,
|
|
76
91
|
ariaLabel = _ref$ariaLabel === void 0 ? "Price range" : _ref$ariaLabel,
|
|
77
92
|
rest = _objectWithoutProperties(_ref, _excluded);
|
|
78
93
|
var isControlled = value && _typeof(value) === "object";
|
|
79
|
-
var _useState = useState(
|
|
94
|
+
var _useState = useState(function () {
|
|
95
|
+
return isControlled ? {
|
|
96
|
+
min: value.min,
|
|
97
|
+
max: value.max
|
|
98
|
+
} : {
|
|
99
|
+
min: defaultValue.min,
|
|
100
|
+
max: defaultValue.max
|
|
101
|
+
};
|
|
102
|
+
}),
|
|
80
103
|
_useState2 = _slicedToArray(_useState, 2),
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
var
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
104
|
+
internal = _useState2[0],
|
|
105
|
+
setInternal = _useState2[1];
|
|
106
|
+
var current = isControlled ? {
|
|
107
|
+
min: value.min,
|
|
108
|
+
max: value.max
|
|
109
|
+
} : internal;
|
|
87
110
|
// Inputs mirror state so editing doesn't immediately break constraints
|
|
88
|
-
var
|
|
111
|
+
var _useState3 = useState(current.min),
|
|
112
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
113
|
+
minInput = _useState4[0],
|
|
114
|
+
setMinInput = _useState4[1];
|
|
115
|
+
var _useState5 = useState(current.max),
|
|
89
116
|
_useState6 = _slicedToArray(_useState5, 2),
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
var _useState7 = useState(internalMax),
|
|
93
|
-
_useState8 = _slicedToArray(_useState7, 2),
|
|
94
|
-
maxInput = _useState8[0],
|
|
95
|
-
setMaxInput = _useState8[1];
|
|
96
|
-
// dragging state
|
|
97
|
-
var _useState9 = useState(false),
|
|
98
|
-
_useState0 = _slicedToArray(_useState9, 2),
|
|
99
|
-
isDragging = _useState0[0],
|
|
100
|
-
setIsDragging = _useState0[1];
|
|
117
|
+
maxInput = _useState6[0],
|
|
118
|
+
setMaxInput = _useState6[1];
|
|
101
119
|
useEffect(function () {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}, [internalMin, internalMax, isControlled]);
|
|
120
|
+
setMinInput(current.min);
|
|
121
|
+
setMaxInput(current.max);
|
|
122
|
+
}, [current.min, current.max]);
|
|
123
|
+
var trackRef = useRef(null);
|
|
124
|
+
var thumbRefs = [useRef(null), useRef(null)];
|
|
125
|
+
// Active drag thumb ("min" | "max" | null) plus the latest value, so the
|
|
126
|
+
// pointer-up handler reports what was actually rendered, not stale state.
|
|
127
|
+
var _useState7 = useState(null),
|
|
128
|
+
_useState8 = _slicedToArray(_useState7, 2),
|
|
129
|
+
dragging = _useState8[0],
|
|
130
|
+
setDragging = _useState8[1];
|
|
131
|
+
var latest = useRef(current);
|
|
132
|
+
latest.current = current;
|
|
116
133
|
var clamp = function clamp(v) {
|
|
117
134
|
return Math.min(max, Math.max(min, v));
|
|
118
135
|
};
|
|
136
|
+
var snap = function snap(v) {
|
|
137
|
+
return clamp(Math.round((v - min) / step) * step + min);
|
|
138
|
+
};
|
|
119
139
|
var setValues = function setValues(next) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
var a = clamp(Math.round(next.min / step) * step);
|
|
123
|
-
var b = clamp(Math.round(next.max / step) * step);
|
|
140
|
+
var a = snap(next.min);
|
|
141
|
+
var b = snap(next.max);
|
|
124
142
|
if (b - a < minGap) {
|
|
125
|
-
// push them apart (prefer keeping
|
|
126
|
-
if (next._active === "min")
|
|
127
|
-
a = clamp(b - minGap);
|
|
128
|
-
} else if (next._active === "max") {
|
|
129
|
-
b = clamp(a + minGap);
|
|
130
|
-
} else {
|
|
131
|
-
// equal distribution
|
|
132
|
-
if (a + minGap <= max) b = a + minGap;else a = b - minGap;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
if (isControlled) {
|
|
136
|
-
onChange({
|
|
137
|
-
min: a,
|
|
138
|
-
max: b
|
|
139
|
-
});
|
|
140
|
-
} else {
|
|
141
|
-
setInternalMin(a);
|
|
142
|
-
setInternalMax(b);
|
|
143
|
-
onChange({
|
|
144
|
-
min: a,
|
|
145
|
-
max: b
|
|
146
|
-
});
|
|
143
|
+
// push them apart (prefer keeping the thumb that moved)
|
|
144
|
+
if (next._active === "min") a = clamp(b - minGap);else if (next._active === "max") b = clamp(a + minGap);else if (a + minGap <= max) b = a + minGap;else a = b - minGap;
|
|
147
145
|
}
|
|
146
|
+
var out = {
|
|
147
|
+
min: a,
|
|
148
|
+
max: b
|
|
149
|
+
};
|
|
150
|
+
latest.current = out;
|
|
151
|
+
if (!isControlled) setInternal(out);
|
|
152
|
+
onChange(out);
|
|
153
|
+
return out;
|
|
148
154
|
};
|
|
149
155
|
var handleFinal = function handleFinal(next) {
|
|
150
|
-
onFinalChange({
|
|
156
|
+
return onFinalChange({
|
|
151
157
|
min: next.min,
|
|
152
158
|
max: next.max
|
|
153
159
|
});
|
|
154
160
|
};
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
min: v,
|
|
161
|
-
max: isControlled ? value.max : internalMax,
|
|
162
|
-
_active: "min"
|
|
163
|
-
});
|
|
161
|
+
var bounds = {
|
|
162
|
+
min: min,
|
|
163
|
+
max: max,
|
|
164
|
+
step: step,
|
|
165
|
+
largeStep: Math.max(step, (max - min) / 10)
|
|
164
166
|
};
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
167
|
+
// Thumb keyboard handling
|
|
168
|
+
var handleThumbKey = function handleThumbKey(which) {
|
|
169
|
+
return function (e) {
|
|
170
|
+
if (disabled) return;
|
|
171
|
+
var next = keyToValue(e.key, current[which], bounds);
|
|
172
|
+
if (next === null) return;
|
|
173
|
+
e.preventDefault();
|
|
174
|
+
handleFinal(setValues(_objectSpread2(_objectSpread2({}, current), {}, _defineProperty(_defineProperty({}, which, next), "_active", which))));
|
|
175
|
+
};
|
|
176
|
+
};
|
|
177
|
+
// Pointer drag on the track: grab the nearest thumb and follow the pointer.
|
|
178
|
+
var toValue = function toValue(clientX) {
|
|
179
|
+
var rect = trackRef.current.getBoundingClientRect();
|
|
180
|
+
var ratio = rect.width ? (clientX - rect.left) / rect.width : 0;
|
|
181
|
+
return min + Math.min(1, Math.max(0, ratio)) * (max - min);
|
|
182
|
+
};
|
|
183
|
+
var onPointerDown = function onPointerDown(e) {
|
|
184
|
+
var _e$currentTarget$setP, _e$currentTarget, _thumbRefs$current;
|
|
185
|
+
if (disabled || e.button > 0) return;
|
|
186
|
+
var raw = toValue(e.clientX);
|
|
187
|
+
var which = Math.abs(raw - current.min) < Math.abs(raw - current.max) || current.min === current.max && raw < current.min ? "min" : "max";
|
|
188
|
+
(_e$currentTarget$setP = (_e$currentTarget = e.currentTarget).setPointerCapture) === null || _e$currentTarget$setP === void 0 || _e$currentTarget$setP.call(_e$currentTarget, e.pointerId);
|
|
189
|
+
setDragging(which);
|
|
190
|
+
setValues(_objectSpread2(_objectSpread2({}, current), {}, _defineProperty(_defineProperty({}, which, raw), "_active", which)));
|
|
191
|
+
(_thumbRefs$current = thumbRefs[which === "min" ? 0 : 1].current) === null || _thumbRefs$current === void 0 || _thumbRefs$current.focus();
|
|
192
|
+
};
|
|
193
|
+
var onPointerMove = function onPointerMove(e) {
|
|
194
|
+
if (!dragging) return;
|
|
195
|
+
setValues(_objectSpread2(_objectSpread2({}, latest.current), {}, _defineProperty(_defineProperty({}, dragging, toValue(e.clientX)), "_active", dragging)));
|
|
173
196
|
};
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
setMinInput(parsed);
|
|
197
|
+
var onPointerUp = function onPointerUp() {
|
|
198
|
+
if (!dragging) return;
|
|
199
|
+
setDragging(null);
|
|
200
|
+
handleFinal(latest.current);
|
|
179
201
|
};
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
setMaxInput(parsed);
|
|
202
|
+
// Number inputs
|
|
203
|
+
var parseInput = function parseInput(raw) {
|
|
204
|
+
return raw === "" ? "" : parseInt(raw, 10);
|
|
184
205
|
};
|
|
185
206
|
var commitMinInput = function commitMinInput() {
|
|
186
|
-
var v = minInput === "" ? min : parseInt(minInput, 10);
|
|
187
|
-
|
|
188
|
-
setValues({
|
|
207
|
+
var v = clamp(minInput === "" ? min : parseInt(minInput, 10));
|
|
208
|
+
handleFinal(setValues({
|
|
189
209
|
min: v,
|
|
190
|
-
max:
|
|
210
|
+
max: current.max,
|
|
191
211
|
_active: "min"
|
|
192
|
-
});
|
|
193
|
-
handleFinal({
|
|
194
|
-
min: v,
|
|
195
|
-
max: isControlled ? value.max : internalMax
|
|
196
|
-
});
|
|
212
|
+
}));
|
|
197
213
|
};
|
|
198
214
|
var commitMaxInput = function commitMaxInput() {
|
|
199
|
-
var v = maxInput === "" ? max : parseInt(maxInput, 10);
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
min: isControlled ? value.min : internalMin,
|
|
215
|
+
var v = clamp(maxInput === "" ? max : parseInt(maxInput, 10));
|
|
216
|
+
handleFinal(setValues({
|
|
217
|
+
min: current.min,
|
|
203
218
|
max: v,
|
|
204
219
|
_active: "max"
|
|
205
|
-
});
|
|
206
|
-
handleFinal({
|
|
207
|
-
min: isControlled ? value.min : internalMin,
|
|
208
|
-
max: v
|
|
209
|
-
});
|
|
210
|
-
};
|
|
211
|
-
// Keyboard handling for inputs
|
|
212
|
-
var handleMinInputKey = function handleMinInputKey(e) {
|
|
213
|
-
if (e.key === "Enter") commitMinInput();
|
|
220
|
+
}));
|
|
214
221
|
};
|
|
215
|
-
var handleMaxInputKey = function handleMaxInputKey(e) {
|
|
216
|
-
if (e.key === "Enter") commitMaxInput();
|
|
217
|
-
};
|
|
218
|
-
// Dragging helpers
|
|
219
|
-
var startDrag = function startDrag() {
|
|
220
|
-
return setIsDragging(true);
|
|
221
|
-
};
|
|
222
|
-
var stopDrag = function stopDrag() {
|
|
223
|
-
setIsDragging(false);
|
|
224
|
-
handleFinal({
|
|
225
|
-
min: isControlled ? value.min : internalMin,
|
|
226
|
-
max: isControlled ? value.max : internalMax
|
|
227
|
-
});
|
|
228
|
-
};
|
|
229
|
-
var minPercent = useMemo(function () {
|
|
230
|
-
return ((isControlled ? value.min : internalMin) - min) / (max - min) * 100;
|
|
231
|
-
}, [value, internalMin, min, max, isControlled]);
|
|
232
|
-
var maxPercent = useMemo(function () {
|
|
233
|
-
return ((isControlled ? value.max : internalMax) - min) / (max - min) * 100;
|
|
234
|
-
}, [value, internalMax, min, max, isControlled]);
|
|
235
|
-
var thumbSize = size === "sm" ? 16 : size === "lg" ? 28 : 22;
|
|
236
|
-
var inputWidth = size === "sm" ? "w-12" : size === "lg" ? "w-20" : "w-14";
|
|
237
|
-
var trackHeight = size === "sm" ? "h-1" : size === "lg" ? "h-2" : "h-1.5";
|
|
238
|
-
// Preset helper
|
|
239
222
|
var applyPreset = function applyPreset(p) {
|
|
240
223
|
if (!p || !p.value) return;
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
min: pmin,
|
|
246
|
-
max: pmax
|
|
247
|
-
});
|
|
248
|
-
handleFinal({
|
|
249
|
-
min: pmin,
|
|
250
|
-
max: pmax
|
|
251
|
-
});
|
|
224
|
+
handleFinal(setValues({
|
|
225
|
+
min: p.value.min,
|
|
226
|
+
max: p.value.max
|
|
227
|
+
}));
|
|
252
228
|
};
|
|
229
|
+
var minPercent = useMemo(function () {
|
|
230
|
+
return toPercent(current.min, min, max);
|
|
231
|
+
}, [current.min, min, max]);
|
|
232
|
+
var maxPercent = useMemo(function () {
|
|
233
|
+
return toPercent(current.max, min, max);
|
|
234
|
+
}, [current.max, min, max]);
|
|
235
|
+
var inputClass = cn(INPUT_WIDTH[size] || INPUT_WIDTH.md, "rounded-control border border-line bg-surface py-2 text-center text-sm text-foreground", "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500", "disabled:opacity-50");
|
|
236
|
+
var thumbs = [{
|
|
237
|
+
which: "min",
|
|
238
|
+
percent: minPercent,
|
|
239
|
+
valueNow: current.min,
|
|
240
|
+
vmin: min,
|
|
241
|
+
vmax: current.max
|
|
242
|
+
}, {
|
|
243
|
+
which: "max",
|
|
244
|
+
percent: maxPercent,
|
|
245
|
+
valueNow: current.max,
|
|
246
|
+
vmin: current.min,
|
|
247
|
+
vmax: max
|
|
248
|
+
}];
|
|
253
249
|
return jsxs("div", _objectSpread2(_objectSpread2({
|
|
254
250
|
ref: ref,
|
|
255
|
-
className: cn("bg-
|
|
251
|
+
className: cn("bg-surface rounded-lg p-4 w-full max-w-lg", className)
|
|
256
252
|
}, rest), {}, {
|
|
257
253
|
children: [jsxs("div", {
|
|
258
254
|
className: "flex items-center justify-between",
|
|
@@ -262,37 +258,48 @@ var PriceRangePicker = /*#__PURE__*/forwardRef(function PriceRangePicker(_ref, r
|
|
|
262
258
|
className: "flex-1",
|
|
263
259
|
children: jsx("input", {
|
|
264
260
|
type: "number",
|
|
261
|
+
inputMode: "decimal",
|
|
265
262
|
"aria-label": "Minimum",
|
|
266
263
|
value: minInput,
|
|
267
|
-
onChange:
|
|
264
|
+
onChange: function onChange(e) {
|
|
265
|
+
return setMinInput(parseInput(e.target.value));
|
|
266
|
+
},
|
|
268
267
|
onBlur: commitMinInput,
|
|
269
|
-
onKeyDown:
|
|
270
|
-
|
|
268
|
+
onKeyDown: function onKeyDown(e) {
|
|
269
|
+
return e.key === "Enter" && commitMinInput();
|
|
270
|
+
},
|
|
271
|
+
className: inputClass,
|
|
271
272
|
min: min,
|
|
272
273
|
max: max,
|
|
273
274
|
disabled: disabled
|
|
274
275
|
})
|
|
275
276
|
}), jsx("div", {
|
|
276
|
-
className: "text-xs text-
|
|
277
|
+
className: "text-xs text-muted",
|
|
278
|
+
"aria-hidden": "true",
|
|
277
279
|
children: "\u2014"
|
|
278
280
|
}), jsx("div", {
|
|
279
281
|
className: "flex-1 flex justify-end",
|
|
280
282
|
children: jsx("input", {
|
|
281
283
|
type: "number",
|
|
284
|
+
inputMode: "decimal",
|
|
282
285
|
"aria-label": "Maximum",
|
|
283
286
|
value: maxInput,
|
|
284
|
-
onChange:
|
|
287
|
+
onChange: function onChange(e) {
|
|
288
|
+
return setMaxInput(parseInput(e.target.value));
|
|
289
|
+
},
|
|
285
290
|
onBlur: commitMaxInput,
|
|
286
|
-
onKeyDown:
|
|
287
|
-
|
|
291
|
+
onKeyDown: function onKeyDown(e) {
|
|
292
|
+
return e.key === "Enter" && commitMaxInput();
|
|
293
|
+
},
|
|
294
|
+
className: inputClass,
|
|
288
295
|
min: min,
|
|
289
296
|
max: max,
|
|
290
297
|
disabled: disabled
|
|
291
298
|
})
|
|
292
299
|
})]
|
|
293
300
|
}) : jsxs("div", {
|
|
294
|
-
className: "text-sm",
|
|
295
|
-
children: [formatValue(
|
|
301
|
+
className: "text-sm text-foreground",
|
|
302
|
+
children: [formatValue(current.min), " - ", formatValue(current.max)]
|
|
296
303
|
}), presets && presets.length > 0 && jsx("div", {
|
|
297
304
|
className: "ml-4 flex gap-2",
|
|
298
305
|
children: presets.map(function (p) {
|
|
@@ -301,73 +308,53 @@ var PriceRangePicker = /*#__PURE__*/forwardRef(function PriceRangePicker(_ref, r
|
|
|
301
308
|
onClick: function onClick() {
|
|
302
309
|
return applyPreset(p);
|
|
303
310
|
},
|
|
304
|
-
className: "text-xs px-2 py-1 border rounded-md hover:bg-
|
|
311
|
+
className: cn("text-xs px-2 py-1 border border-line rounded-md text-foreground hover:bg-background", "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 disabled:opacity-50", TOUCH_TARGET),
|
|
305
312
|
disabled: disabled,
|
|
306
313
|
children: p.label
|
|
307
314
|
}, p.id);
|
|
308
315
|
})
|
|
309
316
|
})]
|
|
310
317
|
}), jsxs("div", {
|
|
311
|
-
|
|
318
|
+
ref: trackRef,
|
|
319
|
+
"data-testid": "price-range-track",
|
|
320
|
+
className: cn("relative mt-6 flex h-6 w-full touch-none select-none items-center", disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer"),
|
|
321
|
+
onPointerDown: onPointerDown,
|
|
322
|
+
onPointerMove: onPointerMove,
|
|
323
|
+
onPointerUp: onPointerUp,
|
|
324
|
+
onPointerCancel: onPointerUp,
|
|
312
325
|
children: [jsx("div", {
|
|
313
|
-
className:
|
|
326
|
+
className: cn("w-full rounded-full bg-gray-200 dark:bg-gray-700", TRACK_HEIGHT[size] || TRACK_HEIGHT.md)
|
|
327
|
+
}), jsx("div", {
|
|
328
|
+
className: cn("absolute rounded-full", TRACK_HEIGHT[size] || TRACK_HEIGHT.md, colorClass),
|
|
314
329
|
style: {
|
|
315
330
|
left: "".concat(minPercent, "%"),
|
|
316
331
|
right: "".concat(100 - maxPercent, "%")
|
|
317
332
|
}
|
|
318
|
-
}),
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
className: "absolute inset-0 w-full appearance-none bg-transparent pointer-events-auto",
|
|
332
|
-
style: {
|
|
333
|
-
zIndex: 20
|
|
334
|
-
}
|
|
335
|
-
}), jsx("input", {
|
|
336
|
-
type: "range",
|
|
337
|
-
min: min,
|
|
338
|
-
max: max,
|
|
339
|
-
step: step,
|
|
340
|
-
value: isControlled ? value.max : internalMax,
|
|
341
|
-
onChange: handleMaxRange,
|
|
342
|
-
onMouseDown: startDrag,
|
|
343
|
-
onMouseUp: stopDrag,
|
|
344
|
-
onTouchStart: startDrag,
|
|
345
|
-
onTouchEnd: stopDrag,
|
|
346
|
-
disabled: disabled,
|
|
347
|
-
"aria-label": "".concat(ariaLabel, " - max"),
|
|
348
|
-
className: "absolute inset-0 w-full appearance-none bg-transparent pointer-events-auto",
|
|
349
|
-
style: {
|
|
350
|
-
zIndex: 10
|
|
351
|
-
}
|
|
352
|
-
}), showTooltips && isDragging && jsxs(Fragment, {
|
|
353
|
-
children: [jsx("div", {
|
|
354
|
-
className: "absolute -top-9 text-xs bg-white px-2 py-1 rounded-md shadow-sm border",
|
|
355
|
-
style: {
|
|
356
|
-
left: "".concat(minPercent, "%"),
|
|
357
|
-
transform: "translateX(-50%)"
|
|
358
|
-
},
|
|
359
|
-
children: formatValue(isControlled ? value.min : internalMin)
|
|
360
|
-
}), jsx("div", {
|
|
361
|
-
className: "absolute -top-9 text-xs bg-white px-2 py-1 rounded-md shadow-sm border",
|
|
333
|
+
}), thumbs.map(function (t, i) {
|
|
334
|
+
return jsx("div", {
|
|
335
|
+
ref: thumbRefs[i],
|
|
336
|
+
role: "slider",
|
|
337
|
+
tabIndex: disabled ? -1 : 0,
|
|
338
|
+
"aria-label": "".concat(ariaLabel, " - ").concat(t.which),
|
|
339
|
+
"aria-valuemin": t.vmin,
|
|
340
|
+
"aria-valuemax": t.vmax,
|
|
341
|
+
"aria-valuenow": t.valueNow,
|
|
342
|
+
"aria-valuetext": formatValue(t.valueNow),
|
|
343
|
+
"aria-orientation": "horizontal",
|
|
344
|
+
"aria-disabled": disabled || undefined,
|
|
345
|
+
onKeyDown: handleThumbKey(t.which),
|
|
362
346
|
style: {
|
|
363
|
-
left: "".concat(
|
|
364
|
-
transform: "translateX(-50%)"
|
|
347
|
+
left: "".concat(t.percent, "%")
|
|
365
348
|
},
|
|
366
|
-
|
|
367
|
-
|
|
349
|
+
className: cn("absolute -translate-x-1/2 rounded-full border-[3px] border-white shadow-md dark:border-gray-900", "transition-shadow motion-reduce:transition-none", "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:ring-offset-2",
|
|
350
|
+
// Grow the hit area to 44px on touch without changing the visual size.
|
|
351
|
+
"before:absolute before:left-1/2 before:top-1/2 before:-translate-x-1/2 before:-translate-y-1/2", "[@media(pointer:coarse)]:before:h-11 [@media(pointer:coarse)]:before:w-11 before:content-['']", THUMB_SIZE[size] || THUMB_SIZE.md, colorClass),
|
|
352
|
+
children: showTooltips && dragging === t.which && jsx("span", {
|
|
353
|
+
className: "pointer-events-none absolute -top-9 left-1/2 -translate-x-1/2 whitespace-nowrap rounded-md border border-line bg-surface px-2 py-1 text-xs text-foreground shadow-sm",
|
|
354
|
+
children: formatValue(t.valueNow)
|
|
355
|
+
})
|
|
356
|
+
}, t.which);
|
|
368
357
|
})]
|
|
369
|
-
}), jsx("style", {
|
|
370
|
-
children: "\n input[type=range] { -webkit-appearance: none; appearance: none; background: transparent; }\n input[type=range]::-webkit-slider-runnable-track { height: 6px; background: transparent; }\n input[type=range]::-moz-range-track { height: 6px; background: transparent; }\n\n input[type=range]::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n height: ".concat(thumbSize, "px;\n width: ").concat(thumbSize, "px;\n border-radius: 9999px;\n border: 3px solid #ffffff;\n background: #ff6b6b;\n box-shadow: 0 2px 8px rgba(0,0,0,0.12);\n cursor: pointer;\n margin-top: -").concat(Math.round(thumbSize / 2 - 6), "px; /* vertical centering tweak */\n position: relative;\n }\n\n input[type=range]::-moz-range-thumb {\n height: ").concat(thumbSize, "px;\n width: ").concat(thumbSize, "px;\n border-radius: 9999px;\n border: 3px solid #ffffff;\n background: #ff6b6b;\n box-shadow: 0 2px 8px rgba(0,0,0,0.12);\n cursor: pointer;\n position: relative;\n }\n\n /* Make the track invisible so our styled track shows through */\n input[type=range]::-webkit-slider-runnable-track { background: transparent; }\n input[type=range]::-moz-range-track { background: transparent; }\n\n ")
|
|
371
358
|
})]
|
|
372
359
|
}));
|
|
373
360
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { objectWithoutProperties as _objectWithoutProperties, slicedToArray as _slicedToArray, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
3
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
-
import { forwardRef, useId, useState } from 'react';
|
|
4
|
+
import { forwardRef, useId, useState, useRef, useCallback, useEffect } from 'react';
|
|
5
5
|
import PropTypes from '../../_vendor/prop-types/index.js';
|
|
6
6
|
|
|
7
7
|
var _excluded = ["id", "name", "value", "checked", "defaultChecked", "onChange", "disabled", "required", "label", "size", "labelPosition", "radioColor", "className", "ariaLabel"];
|
|
@@ -74,6 +74,32 @@ var Radio = /*#__PURE__*/forwardRef(function Radio(_ref, ref) {
|
|
|
74
74
|
if (checked === undefined) setInternalChecked(!!defaultChecked);
|
|
75
75
|
}
|
|
76
76
|
var isChecked = checked !== undefined ? checked : internalChecked;
|
|
77
|
+
// Merge the forwarded ref with our own so we can read the native state.
|
|
78
|
+
var inputRef = useRef(null);
|
|
79
|
+
var setRefs = useCallback(function (node) {
|
|
80
|
+
inputRef.current = node;
|
|
81
|
+
if (typeof ref === "function") ref(node);else if (ref) ref.current = node;
|
|
82
|
+
}, [ref]);
|
|
83
|
+
// DTUI-17: browsers never fire `change` on the radio being *unchecked*
|
|
84
|
+
// when a sibling in the same group is selected. In uncontrolled mode,
|
|
85
|
+
// listen for changes on any same-name radio and re-sync our visual state
|
|
86
|
+
// from the native input, so only one dot shows at a time.
|
|
87
|
+
useEffect(function () {
|
|
88
|
+
if (checked !== undefined || !name) return undefined;
|
|
89
|
+
var doc = inputRef.current && inputRef.current.ownerDocument;
|
|
90
|
+
if (!doc) return undefined;
|
|
91
|
+
var sync = function sync(e) {
|
|
92
|
+
var t = e.target;
|
|
93
|
+
var el = inputRef.current;
|
|
94
|
+
if (!el || t === el || !t || t.type !== "radio" || t.name !== name) return;
|
|
95
|
+
if (t.form !== el.form) return;
|
|
96
|
+
setInternalChecked(el.checked);
|
|
97
|
+
};
|
|
98
|
+
doc.addEventListener("change", sync, true);
|
|
99
|
+
return function () {
|
|
100
|
+
return doc.removeEventListener("change", sync, true);
|
|
101
|
+
};
|
|
102
|
+
}, [checked, name]);
|
|
77
103
|
function handleChange(e) {
|
|
78
104
|
if (checked === undefined) setInternalChecked(e.target.checked);
|
|
79
105
|
if (typeof onChange === "function") onChange(e);
|
|
@@ -91,7 +117,7 @@ var Radio = /*#__PURE__*/forwardRef(function Radio(_ref, ref) {
|
|
|
91
117
|
children: " *"
|
|
92
118
|
}) : null]
|
|
93
119
|
}), jsx("input", _objectSpread2({
|
|
94
|
-
ref:
|
|
120
|
+
ref: setRefs,
|
|
95
121
|
id: inputId,
|
|
96
122
|
type: "radio",
|
|
97
123
|
name: name,
|
|
@@ -102,18 +128,22 @@ var Radio = /*#__PURE__*/forwardRef(function Radio(_ref, ref) {
|
|
|
102
128
|
disabled: disabled,
|
|
103
129
|
required: required,
|
|
104
130
|
"aria-label": ariaLabel,
|
|
105
|
-
className: "absolute inset-0 w-full h-full opacity-0 appearance-none m-0 z-10 cursor-pointer"
|
|
131
|
+
className: "peer absolute inset-0 w-full h-full opacity-0 appearance-none m-0 z-10 cursor-pointer disabled:cursor-not-allowed"
|
|
106
132
|
}, props)), jsx("span", {
|
|
107
133
|
"aria-hidden": true,
|
|
108
|
-
|
|
134
|
+
"data-state": isChecked ? "checked" : "unchecked",
|
|
135
|
+
className: cn("inline-flex items-center justify-center rounded-full transition-all motion-reduce:transition-none",
|
|
136
|
+
// Visible focus indicator: the native input is opacity-0, so the
|
|
137
|
+
// ring is drawn on the visual circle when the input has focus.
|
|
138
|
+
"peer-focus-visible:ring-2 peer-focus-visible:ring-primary-500 peer-focus-visible:ring-offset-2 dark:peer-focus-visible:ring-offset-gray-900"),
|
|
109
139
|
style: {
|
|
110
140
|
"--radio-accent": accentColor
|
|
111
141
|
},
|
|
112
142
|
children: jsx("span", {
|
|
113
|
-
className: cn("flex items-center justify-center rounded-full border transition-colors duration-150 ease-in-out border-slate-300 dark:border-gray-600", sizeClasses.outer, disabled ? "bg-slate-100 dark:bg-gray-800" : "bg-white dark:bg-gray-900", isChecked ? "shadow-inner" : ""),
|
|
143
|
+
className: cn("flex items-center justify-center rounded-full border transition-colors duration-150 ease-in-out motion-reduce:transition-none border-slate-300 dark:border-gray-600", sizeClasses.outer, disabled ? "bg-slate-100 dark:bg-gray-800" : "bg-white dark:bg-gray-900", isChecked ? "shadow-inner" : ""),
|
|
114
144
|
children: jsx("span", {
|
|
115
145
|
"aria-hidden": true,
|
|
116
|
-
className: cn("rounded-full transform transition-all duration-200 ease-out", sizeClasses.dot),
|
|
146
|
+
className: cn("rounded-full transform transition-all duration-200 ease-out motion-reduce:transition-none", sizeClasses.dot),
|
|
117
147
|
style: {
|
|
118
148
|
backgroundColor: isChecked ? accentColor : "transparent",
|
|
119
149
|
opacity: isChecked ? 1 : 0,
|