@dreamtree-org/twreact-ui 1.3.10 → 1.3.11
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/README.md +30 -0
- package/ai-skills/dreamtree-ui.md +12 -7
- package/dist/ai-schema.json +137 -21
- package/dist/charts/index.js +195 -66
- package/dist/components/charts/CartesianChart.d.ts.map +1 -1
- package/dist/components/charts/ChartFrame.d.ts.map +1 -1
- package/dist/components/charts/useChartLayout.d.ts +25 -0
- package/dist/components/charts/useChartLayout.d.ts.map +1 -0
- package/dist/components/core/Button.d.ts.map +1 -1
- package/dist/components/core/Checkbox.d.ts.map +1 -1
- package/dist/components/core/ColorPicker.d.ts.map +1 -1
- package/dist/components/core/Input.d.ts.map +1 -1
- package/dist/components/core/Loader.d.ts.map +1 -1
- package/dist/components/core/LocationPicker.d.ts.map +1 -1
- package/dist/components/core/ProgressBar.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/Skeleton.d.ts.map +1 -1
- package/dist/components/core/Slider.d.ts.map +1 -1
- package/dist/components/core/SpeechToText.d.ts.map +1 -1
- package/dist/components/core/Switch.d.ts.map +1 -1
- package/dist/components/core/Tabs.d.ts +2 -5
- package/dist/components/core/Tabs.d.ts.map +1 -1
- package/dist/components/core/Textarea.d.ts.map +1 -1
- package/dist/components/navigation/Breadcrumbs.d.ts.map +1 -1
- package/dist/components/navigation/FootNav.d.ts.map +1 -1
- package/dist/components/utility/Avatar.d.ts +8 -0
- package/dist/components/utility/Avatar.d.ts.map +1 -1
- package/dist/components/utility/AvatarGroup.d.ts +4 -0
- package/dist/components/utility/AvatarGroup.d.ts.map +1 -0
- package/dist/components/utility/Badge.d.ts.map +1 -1
- package/dist/components/utility/Card.d.ts.map +1 -1
- package/dist/components/utility/Carousel.d.ts.map +1 -1
- package/dist/components/utility/FileUpload.d.ts.map +1 -1
- package/dist/components/utility/Pagination.d.ts.map +1 -1
- package/dist/components/utility/Sortable.d.ts.map +1 -1
- package/dist/components/utility/Stepper.d.ts.map +1 -1
- package/dist/esm/components/blocks/EmptyState.js +1 -1
- package/dist/esm/components/blocks/ErrorState.js +1 -1
- package/dist/esm/components/blocks/LoadingState.js +4 -4
- package/dist/esm/components/blocks/StatCard.js +6 -6
- package/dist/esm/components/blocks/StatusPill.js +5 -8
- package/dist/esm/components/charts/CartesianChart.js +85 -62
- package/dist/esm/components/charts/ChartFrame.js +12 -5
- package/dist/esm/components/charts/useChartLayout.js +105 -0
- package/dist/esm/components/core/Button.js +49 -25
- package/dist/esm/components/core/Checkbox.js +71 -45
- package/dist/esm/components/core/ColorPicker.js +31 -42
- package/dist/esm/components/core/Input.js +89 -22
- package/dist/esm/components/core/Loader.js +30 -44
- package/dist/esm/components/core/LocationPicker.js +82 -16
- package/dist/esm/components/core/ProgressBar.js +8 -12
- package/dist/esm/components/core/Radio.js +10 -12
- package/dist/esm/components/core/Rate.js +72 -4
- package/dist/esm/components/core/RoundedTag.js +5 -5
- package/dist/esm/components/core/Skeleton.js +13 -14
- package/dist/esm/components/core/Slider.js +24 -6
- package/dist/esm/components/core/SpeechToText.js +68 -16
- package/dist/esm/components/core/Switch.js +88 -16
- package/dist/esm/components/core/Tabs.js +180 -33
- package/dist/esm/components/core/Textarea.js +10 -2
- package/dist/esm/components/navigation/Breadcrumbs.js +97 -35
- package/dist/esm/components/navigation/FootNav.js +102 -13
- package/dist/esm/components/utility/Avatar.js +14 -12
- package/dist/esm/components/utility/AvatarGroup.js +56 -0
- package/dist/esm/components/utility/Badge.js +43 -23
- package/dist/esm/components/utility/Card.js +32 -8
- package/dist/esm/components/utility/Carousel.js +139 -29
- package/dist/esm/components/utility/FileUpload.js +106 -31
- package/dist/esm/components/utility/Pagination.js +31 -13
- package/dist/esm/components/utility/Sortable.js +6 -2
- package/dist/esm/components/utility/Stepper.js +110 -47
- package/dist/esm/hooks/useSliderValues.js +8 -2
- package/dist/esm/hooks/useSortable.js +107 -5
- package/dist/esm/index.js +1 -0
- package/dist/esm/utils/touchTarget.js +4 -1
- package/dist/hooks/useSliderValues.d.ts +6 -2
- package/dist/hooks/useSliderValues.d.ts.map +1 -1
- package/dist/hooks/useSortable.d.ts +11 -1
- package/dist/hooks/useSortable.d.ts.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.js +2341 -1191
- package/dist/index.js +2341 -1190
- package/dist/types/charts.d.ts +3 -1
- package/dist/types/charts.d.ts.map +1 -1
- package/dist/types/index.d.ts +56 -7
- package/dist/types/index.d.ts.map +1 -1
- package/doc/README.md +1 -0
- package/mcp/catalog.snapshot.json +279 -80
- package/package.json +1 -1
|
@@ -2,7 +2,8 @@
|
|
|
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
4
|
import { forwardRef, useId, useRef, useState, useEffect, useCallback } from 'react';
|
|
5
|
-
import { Check } from 'lucide-react';
|
|
5
|
+
import { Check, Minus } from 'lucide-react';
|
|
6
|
+
import { cn } from '../../utils/cn.js';
|
|
6
7
|
|
|
7
8
|
var _excluded = ["id", "name", "label", "checked", "defaultChecked", "onChange", "disabled", "required", "className", "size", "labelPosition", "value", "ariaLabel", "variant", "indeterminate", "borderColor", "color", "iconClass", "checkedClass", "wrapperProps"];
|
|
8
9
|
var SIZE_CLASSES = {
|
|
@@ -22,52 +23,71 @@ var SIZE_CLASSES = {
|
|
|
22
23
|
icon: "w-4 h-4"
|
|
23
24
|
}
|
|
24
25
|
};
|
|
26
|
+
// `checked` paints the box from the native :checked state; `fill` is the same
|
|
27
|
+
// paint applied from React state for the indeterminate (mixed) state.
|
|
28
|
+
// blue / indigo / purple are raw-palette presets kept for compatibility
|
|
29
|
+
// (deprecated; removed in 2.0 — use the token names).
|
|
25
30
|
var COLOR_PRESETS = {
|
|
26
31
|
primary: {
|
|
27
|
-
checked: "peer-checked:bg-primary-600 peer-checked:border-primary-600 peer-checked:text-white",
|
|
28
|
-
|
|
32
|
+
checked: "peer-checked:bg-primary-600 peer-checked:border-primary-600 peer-checked:text-white dark:peer-checked:bg-primary-500 dark:peer-checked:border-primary-500",
|
|
33
|
+
fill: "bg-primary-600 border-primary-600 text-white dark:bg-primary-500 dark:border-primary-500",
|
|
34
|
+
ring: "peer-focus-visible:ring-primary-500"
|
|
29
35
|
},
|
|
30
36
|
secondary: {
|
|
31
|
-
checked: "peer-checked:bg-secondary-600 peer-checked:border-secondary-600 peer-checked:text-white",
|
|
32
|
-
|
|
37
|
+
checked: "peer-checked:bg-secondary-600 peer-checked:border-secondary-600 peer-checked:text-white dark:peer-checked:bg-secondary-500 dark:peer-checked:border-secondary-500",
|
|
38
|
+
fill: "bg-secondary-600 border-secondary-600 text-white dark:bg-secondary-500 dark:border-secondary-500",
|
|
39
|
+
ring: "peer-focus-visible:ring-secondary-500"
|
|
33
40
|
},
|
|
34
41
|
success: {
|
|
35
|
-
checked: "peer-checked:bg-success-600 peer-checked:border-success-600 peer-checked:text-white",
|
|
36
|
-
|
|
42
|
+
checked: "peer-checked:bg-success-600 peer-checked:border-success-600 peer-checked:text-white dark:peer-checked:bg-success-500 dark:peer-checked:border-success-500",
|
|
43
|
+
fill: "bg-success-600 border-success-600 text-white dark:bg-success-500 dark:border-success-500",
|
|
44
|
+
ring: "peer-focus-visible:ring-success-500"
|
|
37
45
|
},
|
|
38
46
|
green: {
|
|
39
|
-
checked: "peer-checked:bg-success-600 peer-checked:border-success-600 peer-checked:text-white",
|
|
40
|
-
|
|
47
|
+
checked: "peer-checked:bg-success-600 peer-checked:border-success-600 peer-checked:text-white dark:peer-checked:bg-success-500 dark:peer-checked:border-success-500",
|
|
48
|
+
fill: "bg-success-600 border-success-600 text-white dark:bg-success-500 dark:border-success-500",
|
|
49
|
+
ring: "peer-focus-visible:ring-success-500"
|
|
41
50
|
},
|
|
42
51
|
error: {
|
|
43
|
-
checked: "peer-checked:bg-error-600 peer-checked:border-error-600 peer-checked:text-white",
|
|
44
|
-
|
|
52
|
+
checked: "peer-checked:bg-error-600 peer-checked:border-error-600 peer-checked:text-white dark:peer-checked:bg-error-500 dark:peer-checked:border-error-500",
|
|
53
|
+
fill: "bg-error-600 border-error-600 text-white dark:bg-error-500 dark:border-error-500",
|
|
54
|
+
ring: "peer-focus-visible:ring-error-500"
|
|
45
55
|
},
|
|
46
56
|
danger: {
|
|
47
|
-
checked: "peer-checked:bg-error-600 peer-checked:border-error-600 peer-checked:text-white",
|
|
48
|
-
|
|
57
|
+
checked: "peer-checked:bg-error-600 peer-checked:border-error-600 peer-checked:text-white dark:peer-checked:bg-error-500 dark:peer-checked:border-error-500",
|
|
58
|
+
fill: "bg-error-600 border-error-600 text-white dark:bg-error-500 dark:border-error-500",
|
|
59
|
+
ring: "peer-focus-visible:ring-error-500"
|
|
49
60
|
},
|
|
50
61
|
red: {
|
|
51
|
-
checked: "peer-checked:bg-error-600 peer-checked:border-error-600 peer-checked:text-white",
|
|
52
|
-
|
|
62
|
+
checked: "peer-checked:bg-error-600 peer-checked:border-error-600 peer-checked:text-white dark:peer-checked:bg-error-500 dark:peer-checked:border-error-500",
|
|
63
|
+
fill: "bg-error-600 border-error-600 text-white dark:bg-error-500 dark:border-error-500",
|
|
64
|
+
ring: "peer-focus-visible:ring-error-500"
|
|
53
65
|
},
|
|
54
66
|
warning: {
|
|
55
|
-
checked: "peer-checked:bg-warning-600 peer-checked:border-warning-600 peer-checked:text-white",
|
|
56
|
-
|
|
67
|
+
checked: "peer-checked:bg-warning-600 peer-checked:border-warning-600 peer-checked:text-white dark:peer-checked:bg-warning-500 dark:peer-checked:border-warning-500",
|
|
68
|
+
fill: "bg-warning-600 border-warning-600 text-white dark:bg-warning-500 dark:border-warning-500",
|
|
69
|
+
ring: "peer-focus-visible:ring-warning-500"
|
|
57
70
|
},
|
|
58
71
|
blue: {
|
|
59
|
-
checked: "peer-checked:bg-blue-600 peer-checked:border-blue-600 peer-checked:text-white",
|
|
60
|
-
|
|
72
|
+
checked: "peer-checked:bg-blue-600 peer-checked:border-blue-600 peer-checked:text-white dark:peer-checked:bg-blue-500 dark:peer-checked:border-blue-500",
|
|
73
|
+
fill: "bg-blue-600 border-blue-600 text-white dark:bg-blue-500 dark:border-blue-500",
|
|
74
|
+
ring: "peer-focus-visible:ring-blue-500"
|
|
61
75
|
},
|
|
62
76
|
indigo: {
|
|
63
|
-
checked: "peer-checked:bg-indigo-600 peer-checked:border-indigo-600 peer-checked:text-white",
|
|
64
|
-
|
|
77
|
+
checked: "peer-checked:bg-indigo-600 peer-checked:border-indigo-600 peer-checked:text-white dark:peer-checked:bg-indigo-500 dark:peer-checked:border-indigo-500",
|
|
78
|
+
fill: "bg-indigo-600 border-indigo-600 text-white dark:bg-indigo-500 dark:border-indigo-500",
|
|
79
|
+
ring: "peer-focus-visible:ring-indigo-500"
|
|
65
80
|
},
|
|
66
81
|
purple: {
|
|
67
|
-
checked: "peer-checked:bg-purple-600 peer-checked:border-purple-600 peer-checked:text-white",
|
|
68
|
-
|
|
82
|
+
checked: "peer-checked:bg-purple-600 peer-checked:border-purple-600 peer-checked:text-white dark:peer-checked:bg-purple-500 dark:peer-checked:border-purple-500",
|
|
83
|
+
fill: "bg-purple-600 border-purple-600 text-white dark:bg-purple-500 dark:border-purple-500",
|
|
84
|
+
ring: "peer-focus-visible:ring-purple-500"
|
|
69
85
|
}
|
|
70
86
|
};
|
|
87
|
+
// The invisible native input is the hit area: the box size with a mouse,
|
|
88
|
+
// 44×44 centred on the box on coarse pointers.
|
|
89
|
+
var HIT_AREA = "absolute left-1/2 top-1/2 h-full w-full -translate-x-1/2 -translate-y-1/2 [@media(pointer:coarse)]:h-11 [@media(pointer:coarse)]:w-11";
|
|
90
|
+
var ICON_MOTION = "pointer-events-none absolute transition-[opacity,transform] duration-fast ease-standard motion-reduce:transition-none";
|
|
71
91
|
var Checkbox = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
72
92
|
var id = _ref.id,
|
|
73
93
|
name = _ref.name,
|
|
@@ -121,30 +141,28 @@ var Checkbox = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
121
141
|
if (typeof onChange === "function") onChange(e);
|
|
122
142
|
}, [isControlled, onChange]);
|
|
123
143
|
var sizeClass = SIZE_CLASSES[size] || SIZE_CLASSES.md;
|
|
124
|
-
var wrapperCls = "inline-flex items-center ".concat(className);
|
|
125
|
-
var boxOuterCls = "relative inline-flex items-center justify-center rounded-sm border transition-shadow ".concat(sizeClass.box, " ").concat(disabled ? "opacity-60 cursor-not-allowed" : "cursor-pointer hover:shadow-sm", " ");
|
|
126
|
-
// Icon classes driven by React state (reliable)
|
|
127
|
-
var iconBase = "pointer-events-none transform transition-all duration-150 ease-out";
|
|
128
|
-
var iconShown = "opacity-100 scale-100";
|
|
129
|
-
var iconHidden = "opacity-0 scale-75";
|
|
130
144
|
var isPreset = COLOR_PRESETS[color];
|
|
131
|
-
var
|
|
132
|
-
var
|
|
145
|
+
var isMixed = Boolean(indeterminate);
|
|
146
|
+
var isPainted = Boolean(currentChecked) || isMixed;
|
|
147
|
+
var customColorStyle = isPainted && !isPreset && !checkedClass ? {
|
|
133
148
|
backgroundColor: color,
|
|
134
149
|
borderColor: color,
|
|
135
150
|
color: "#ffffff"
|
|
136
151
|
} : {};
|
|
137
152
|
// The outer box shows its own border unless a checked preset or custom colour paints it.
|
|
138
|
-
var showBoxBorder = !(
|
|
153
|
+
var showBoxBorder = !(isPainted && (isPreset || customColorStyle.borderColor));
|
|
154
|
+
var iconState = function iconState(shown) {
|
|
155
|
+
return shown ? "opacity-100 scale-100" : "opacity-0 scale-50";
|
|
156
|
+
};
|
|
139
157
|
return jsxs("div", _objectSpread2(_objectSpread2({
|
|
140
|
-
className:
|
|
158
|
+
className: cn("inline-flex items-center", className)
|
|
141
159
|
}, wrapperProps !== null && wrapperProps !== void 0 ? wrapperProps : {}), {}, {
|
|
142
160
|
children: [label && labelPosition === "left" && jsx("label", {
|
|
143
161
|
htmlFor: inputId,
|
|
144
|
-
className:
|
|
162
|
+
className: cn(sizeClass.label, "select-none mr-2 text-foreground"),
|
|
145
163
|
children: label
|
|
146
164
|
}), jsxs("div", {
|
|
147
|
-
className: "".
|
|
165
|
+
className: cn("relative inline-flex shrink-0 items-center justify-center rounded-sm border transition-shadow duration-fast motion-reduce:transition-none", sizeClass.box, disabled ? "opacity-60 cursor-not-allowed" : "cursor-pointer hover:shadow-sm", !disabled && showBoxBorder && !borderColor && "border-gray-300 dark:border-gray-600"),
|
|
148
166
|
style: disabled || !showBoxBorder || !borderColor ? {} : {
|
|
149
167
|
borderColor: borderColor
|
|
150
168
|
},
|
|
@@ -154,7 +172,7 @@ var Checkbox = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
154
172
|
ref: inputRef,
|
|
155
173
|
name: name,
|
|
156
174
|
type: "checkbox",
|
|
157
|
-
className: "peer
|
|
175
|
+
className: cn("peer m-0 p-0 opacity-0 z-10", HIT_AREA, disabled ? "cursor-not-allowed" : "cursor-pointer"),
|
|
158
176
|
// ensure we set checked only from the boolean (avoid undefined)
|
|
159
177
|
checked: Boolean(currentChecked),
|
|
160
178
|
onChange: handleChange,
|
|
@@ -162,23 +180,31 @@ var Checkbox = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
162
180
|
required: required,
|
|
163
181
|
value: value,
|
|
164
182
|
"aria-label": ariaLabel,
|
|
165
|
-
"aria-checked": Boolean(currentChecked)
|
|
166
|
-
}, props)),
|
|
167
|
-
className: "pointer-events-none z-0 flex items-center justify-center rounded-sm w-full h-full transition-colors duration-
|
|
168
|
-
|
|
183
|
+
"aria-checked": isMixed ? "mixed" : Boolean(currentChecked)
|
|
184
|
+
}, props)), jsxs("div", {
|
|
185
|
+
className: cn("pointer-events-none relative z-0 flex items-center justify-center rounded-sm w-full h-full", "transition-colors duration-fast ease-standard motion-reduce:transition-none",
|
|
186
|
+
// Keyboard focus ring drawn on the visual box (the input is invisible).
|
|
187
|
+
"peer-focus-visible:ring-2 peer-focus-visible:ring-offset-1 dark:peer-focus-visible:ring-offset-gray-900", isPreset ? isPreset.ring : "peer-focus-visible:ring-primary-500", disabled ? "bg-gray-100 text-primary-400 dark:bg-gray-800" : "bg-surface", isPreset && isPreset.checked, isPreset && isMixed && !checkedClass && isPreset.fill, checkedClass),
|
|
188
|
+
style: isPainted && checkedClass ? {
|
|
169
189
|
backgroundColor: "",
|
|
170
190
|
borderColor: ""
|
|
171
191
|
} : customColorStyle,
|
|
172
192
|
"aria-hidden": "true",
|
|
173
|
-
children: jsx(Check, {
|
|
174
|
-
className:
|
|
193
|
+
children: [jsx(Check, {
|
|
194
|
+
className: cn(sizeClass.icon, ICON_MOTION, iconState(currentChecked && !isMixed), iconClass),
|
|
175
195
|
strokeWidth: 2.2,
|
|
176
|
-
"aria-hidden": "true"
|
|
177
|
-
|
|
196
|
+
"aria-hidden": "true",
|
|
197
|
+
"data-icon": "check"
|
|
198
|
+
}), jsx(Minus, {
|
|
199
|
+
className: cn(sizeClass.icon, ICON_MOTION, iconState(isMixed), iconClass),
|
|
200
|
+
strokeWidth: 2.6,
|
|
201
|
+
"aria-hidden": "true",
|
|
202
|
+
"data-icon": "indeterminate"
|
|
203
|
+
})]
|
|
178
204
|
})]
|
|
179
205
|
}), label && labelPosition === "right" && jsx("label", {
|
|
180
206
|
htmlFor: inputId,
|
|
181
|
-
className:
|
|
207
|
+
className: cn(sizeClass.label, "select-none ml-2 text-foreground"),
|
|
182
208
|
children: label
|
|
183
209
|
})]
|
|
184
210
|
}));
|
|
@@ -3,6 +3,7 @@ import { objectWithoutProperties as _objectWithoutProperties, slicedToArray as _
|
|
|
3
3
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
4
|
import { forwardRef, useId, useMemo, useState } from 'react';
|
|
5
5
|
import { cn } from '../../utils/cn.js';
|
|
6
|
+
import Slider from './Slider.js';
|
|
6
7
|
|
|
7
8
|
var _excluded = ["value", "defaultValue", "onChange", "swatches", "showAlpha", "size", "disabled", "className", "label", "id"];
|
|
8
9
|
/**
|
|
@@ -121,6 +122,14 @@ function parseColor(input) {
|
|
|
121
122
|
}
|
|
122
123
|
return null;
|
|
123
124
|
}
|
|
125
|
+
// Same colour (alpha compared to 3 decimals, like the output string).
|
|
126
|
+
function sameColor(x, y) {
|
|
127
|
+
var _x$a, _y$a;
|
|
128
|
+
if (!x || !y) return false;
|
|
129
|
+
var ax = +((_x$a = x.a) !== null && _x$a !== void 0 ? _x$a : 1).toFixed(3);
|
|
130
|
+
var ay = +((_y$a = y.a) !== null && _y$a !== void 0 ? _y$a : 1).toFixed(3);
|
|
131
|
+
return x.r === y.r && x.g === y.g && x.b === y.b && ax === ay;
|
|
132
|
+
}
|
|
124
133
|
function rgbaToString(_ref2) {
|
|
125
134
|
var r = _ref2.r,
|
|
126
135
|
g = _ref2.g,
|
|
@@ -132,7 +141,7 @@ function rgbaToString(_ref2) {
|
|
|
132
141
|
}
|
|
133
142
|
// ---------- Component ----------
|
|
134
143
|
var ColorPicker = /*#__PURE__*/forwardRef(function ColorPicker(props, ref) {
|
|
135
|
-
var _internal$a
|
|
144
|
+
var _internal$a;
|
|
136
145
|
var value = props.value,
|
|
137
146
|
defaultValue = props.defaultValue,
|
|
138
147
|
onChange = props.onChange,
|
|
@@ -224,8 +233,10 @@ var ColorPicker = /*#__PURE__*/forwardRef(function ColorPicker(props, ref) {
|
|
|
224
233
|
children: label
|
|
225
234
|
}), jsxs("div", {
|
|
226
235
|
className: "flex ".concat(sizeMap.gap, " items-start flex-col"),
|
|
227
|
-
children: [jsx("div", {
|
|
236
|
+
children: [swatches.length > 0 && jsx("div", {
|
|
228
237
|
className: "flex flex-wrap ".concat(sizeMap.gap),
|
|
238
|
+
role: "group",
|
|
239
|
+
"aria-label": "Swatches",
|
|
229
240
|
children: swatches.map(function (s, i) {
|
|
230
241
|
var _parseColor;
|
|
231
242
|
var c = (_parseColor = parseColor(s)) !== null && _parseColor !== void 0 ? _parseColor : {
|
|
@@ -234,38 +245,41 @@ var ColorPicker = /*#__PURE__*/forwardRef(function ColorPicker(props, ref) {
|
|
|
234
245
|
b: 0,
|
|
235
246
|
a: 1
|
|
236
247
|
};
|
|
248
|
+
var selected = sameColor(c, internal);
|
|
237
249
|
return jsx("button", {
|
|
238
250
|
type: "button",
|
|
239
251
|
"aria-label": "Select ".concat(s),
|
|
252
|
+
"aria-pressed": selected,
|
|
240
253
|
disabled: disabled,
|
|
241
254
|
onClick: function onClick() {
|
|
242
255
|
return pushChange(c);
|
|
243
256
|
},
|
|
244
|
-
className: "rounded-md border border-
|
|
257
|
+
className: cn("rounded-md border border-line overflow-hidden transition-shadow duration-fast motion-reduce:transition-none", "focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-primary-500 dark:focus-visible:ring-offset-gray-900", "disabled:cursor-not-allowed disabled:opacity-50", selected && "ring-2 ring-offset-2 ring-primary-500 dark:ring-offset-gray-900", sizeMap.swatch),
|
|
245
258
|
style: {
|
|
246
259
|
background: "rgba(".concat(c.r, ",").concat(c.g, ",").concat(c.b, ",").concat(c.a, ")")
|
|
247
260
|
},
|
|
248
|
-
title: s
|
|
261
|
+
title: s,
|
|
262
|
+
"data-selected": selected || undefined
|
|
249
263
|
}, i);
|
|
250
264
|
})
|
|
251
265
|
}), jsxs("div", {
|
|
252
|
-
className: "flex-1 min-w-[220px]",
|
|
266
|
+
className: "w-full sm:flex-1 sm:min-w-[220px]",
|
|
253
267
|
children: [jsxs("div", {
|
|
254
|
-
className: "flex items-center gap-3",
|
|
268
|
+
className: "flex flex-wrap items-center gap-3",
|
|
255
269
|
children: [jsxs("div", {
|
|
256
270
|
className: "flex items-center gap-2",
|
|
257
271
|
children: [jsx("div", {
|
|
258
|
-
className: "rounded-md border border-
|
|
272
|
+
className: "rounded-md border border-line overflow-hidden w-12 h-12 flex items-center justify-center",
|
|
259
273
|
style: {
|
|
260
274
|
background: "rgba(".concat(internal.r, ", ").concat(internal.g, ", ").concat(internal.b, ", ").concat(internal.a, ")")
|
|
261
275
|
}
|
|
262
276
|
}), jsxs("div", {
|
|
263
277
|
className: "flex flex-col",
|
|
264
278
|
children: [jsx("div", {
|
|
265
|
-
className: "text-xs text-primary-500",
|
|
279
|
+
className: "text-xs text-primary-500 dark:text-primary-300",
|
|
266
280
|
children: "Current"
|
|
267
281
|
}), jsx("div", {
|
|
268
|
-
className: "font-mono text-sm",
|
|
282
|
+
className: "font-mono text-sm text-foreground",
|
|
269
283
|
children: rgbaToHex(internal, showAlpha)
|
|
270
284
|
})]
|
|
271
285
|
})]
|
|
@@ -282,7 +296,7 @@ var ColorPicker = /*#__PURE__*/forwardRef(function ColorPicker(props, ref) {
|
|
|
282
296
|
className: "w-10 h-10 p-0 border-none bg-transparent",
|
|
283
297
|
"aria-label": "Native color input"
|
|
284
298
|
}), jsxs("div", {
|
|
285
|
-
className: "flex-1",
|
|
299
|
+
className: "min-w-[8rem] flex-1",
|
|
286
300
|
children: [jsx("span", {
|
|
287
301
|
id: valueLabelId,
|
|
288
302
|
className: "sr-only",
|
|
@@ -303,17 +317,21 @@ var ColorPicker = /*#__PURE__*/forwardRef(function ColorPicker(props, ref) {
|
|
|
303
317
|
}));
|
|
304
318
|
}
|
|
305
319
|
},
|
|
306
|
-
className: "w-full rounded-md border border-
|
|
320
|
+
className: "w-full rounded-md border border-line bg-surface px-2 py-1 font-mono text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 disabled:opacity-50",
|
|
307
321
|
"aria-labelledby": "".concat(labelId, " ").concat(valueLabelId)
|
|
308
322
|
})]
|
|
309
323
|
})]
|
|
310
324
|
}), jsx("div", {
|
|
311
325
|
className: "mt-3 space-y-2",
|
|
312
326
|
children: showAlpha && jsx(Slider, {
|
|
313
|
-
label: "Alpha
|
|
327
|
+
label: "Alpha",
|
|
328
|
+
showValue: true,
|
|
329
|
+
formatValue: function formatValue(v) {
|
|
330
|
+
return "".concat(v, "%");
|
|
331
|
+
},
|
|
314
332
|
min: 0,
|
|
315
333
|
max: 100,
|
|
316
|
-
value: Math.round(((_internal$
|
|
334
|
+
value: Math.round(((_internal$a = internal.a) !== null && _internal$a !== void 0 ? _internal$a : 1) * 100),
|
|
317
335
|
onChange: function onChange(v) {
|
|
318
336
|
pushChange(_objectSpread2(_objectSpread2({}, internal), {}, {
|
|
319
337
|
a: clamp(v / 100, 0, 1)
|
|
@@ -327,34 +345,5 @@ var ColorPicker = /*#__PURE__*/forwardRef(function ColorPicker(props, ref) {
|
|
|
327
345
|
}));
|
|
328
346
|
});
|
|
329
347
|
ColorPicker.displayName = "ColorPicker";
|
|
330
|
-
function Slider(_ref4) {
|
|
331
|
-
var label = _ref4.label,
|
|
332
|
-
min = _ref4.min,
|
|
333
|
-
max = _ref4.max,
|
|
334
|
-
value = _ref4.value,
|
|
335
|
-
_onChange = _ref4.onChange,
|
|
336
|
-
disabled = _ref4.disabled;
|
|
337
|
-
return jsxs("div", {
|
|
338
|
-
className: "flex items-center gap-3",
|
|
339
|
-
children: [jsx("div", {
|
|
340
|
-
className: "w-36 text-sm text-primary-600",
|
|
341
|
-
children: label
|
|
342
|
-
}), jsx("input", {
|
|
343
|
-
type: "range",
|
|
344
|
-
min: min,
|
|
345
|
-
max: max,
|
|
346
|
-
value: value,
|
|
347
|
-
disabled: disabled,
|
|
348
|
-
onChange: function onChange(e) {
|
|
349
|
-
return _onChange(Number(e.target.value));
|
|
350
|
-
},
|
|
351
|
-
className: "w-full h-2 rounded-lg appearance-none bg-gray-200",
|
|
352
|
-
"aria-label": label
|
|
353
|
-
}), jsx("div", {
|
|
354
|
-
className: "w-14 text-right font-mono text-sm",
|
|
355
|
-
children: value
|
|
356
|
-
})]
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
348
|
|
|
360
349
|
export { ColorPicker as default };
|
|
@@ -1,11 +1,52 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { objectWithoutProperties as _objectWithoutProperties, slicedToArray as _slicedToArray, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
4
4
|
import { forwardRef, useId, useRef, useCallback, useState } from 'react';
|
|
5
5
|
import { Search, EyeOff, Eye, X } from 'lucide-react';
|
|
6
6
|
import { cn } from '../../utils/cn.js';
|
|
7
|
+
import { TOUCH_TARGET } from '../../utils/touchTarget.js';
|
|
7
8
|
|
|
8
|
-
var _excluded = ["id", "className", "type", "label", "placeholder", "error", "success", "helperText", "disabled", "required", "clearable", "icon", "iconPosition", "onClear", "showCount", "maxLength", "readOnly", "onChange", "value", "defaultValue"];
|
|
9
|
+
var _excluded = ["id", "className", "type", "label", "placeholder", "error", "success", "helperText", "disabled", "required", "clearable", "icon", "iconPosition", "onClear", "showCount", "maxLength", "readOnly", "onChange", "value", "defaultValue", "size", "floatingLabel", "otp"];
|
|
10
|
+
// Field heights. `md` keeps its 40px desktop look and grows to the 44px touch
|
|
11
|
+
// target on coarse pointers (same rule as Select); `lg` is 44px everywhere.
|
|
12
|
+
var SIZE_CLASSES = {
|
|
13
|
+
sm: "h-8 text-xs",
|
|
14
|
+
md: "h-10 text-sm leading-10 [@media(pointer:coarse)]:h-11",
|
|
15
|
+
lg: "h-11 text-base"
|
|
16
|
+
};
|
|
17
|
+
// Taller fields for `floatingLabel`, with top padding so the value sits below
|
|
18
|
+
// the floated label.
|
|
19
|
+
var FLOATING_SIZE_CLASSES = {
|
|
20
|
+
sm: "h-10 pt-3 text-sm",
|
|
21
|
+
md: "h-12 pt-4 text-sm",
|
|
22
|
+
lg: "h-14 pt-5 text-base"
|
|
23
|
+
};
|
|
24
|
+
// Mobile keyboard / autofill hints for native types. Applied only when the
|
|
25
|
+
// caller did not pass the attribute themselves.
|
|
26
|
+
var TYPE_HINTS = {
|
|
27
|
+
tel: {
|
|
28
|
+
inputMode: "tel",
|
|
29
|
+
autoComplete: "tel"
|
|
30
|
+
},
|
|
31
|
+
email: {
|
|
32
|
+
inputMode: "email",
|
|
33
|
+
autoComplete: "email"
|
|
34
|
+
},
|
|
35
|
+
url: {
|
|
36
|
+
inputMode: "url",
|
|
37
|
+
autoComplete: "url"
|
|
38
|
+
},
|
|
39
|
+
search: {
|
|
40
|
+
inputMode: "search",
|
|
41
|
+
enterKeyHint: "search"
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
var OTP_HINTS = {
|
|
45
|
+
inputMode: "numeric",
|
|
46
|
+
autoComplete: "one-time-code"
|
|
47
|
+
};
|
|
48
|
+
// Password toggle / clear: real buttons that reach 44×44 on coarse pointers.
|
|
49
|
+
var ADORNMENT_BUTTON = cn("absolute right-1 top-1/2 -translate-y-1/2 inline-flex h-8 w-8 items-center justify-center rounded-md", "text-primary-500 hover:text-primary-700 dark:text-primary-400 dark:hover:text-primary-300", "transition-colors duration-fast ease-standard motion-reduce:transition-none", "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500", "disabled:cursor-not-allowed disabled:opacity-50", TOUCH_TARGET);
|
|
9
50
|
var Input = /*#__PURE__*/forwardRef(function (props, forwardedRef) {
|
|
10
51
|
var id = props.id,
|
|
11
52
|
className = props.className,
|
|
@@ -34,7 +75,25 @@ var Input = /*#__PURE__*/forwardRef(function (props, forwardedRef) {
|
|
|
34
75
|
onChange = props.onChange,
|
|
35
76
|
value = props.value,
|
|
36
77
|
defaultValue = props.defaultValue,
|
|
78
|
+
_props$size = props.size,
|
|
79
|
+
sizeProp = _props$size === void 0 ? "md" : _props$size,
|
|
80
|
+
_props$floatingLabel = props.floatingLabel,
|
|
81
|
+
floatingLabel = _props$floatingLabel === void 0 ? false : _props$floatingLabel,
|
|
82
|
+
_props$otp = props.otp,
|
|
83
|
+
otp = _props$otp === void 0 ? false : _props$otp,
|
|
37
84
|
rest = _objectWithoutProperties(props, _excluded);
|
|
85
|
+
// `size` is the field size (sm|md|lg). A numeric value is the native
|
|
86
|
+
// `<input size>` attribute and is passed through unchanged.
|
|
87
|
+
var size = SIZE_CLASSES[sizeProp] ? sizeProp : "md";
|
|
88
|
+
var nativeSize = SIZE_CLASSES[sizeProp] ? undefined : sizeProp;
|
|
89
|
+
var hints = otp ? OTP_HINTS : TYPE_HINTS[type];
|
|
90
|
+
var hintProps = {};
|
|
91
|
+
if (hints) {
|
|
92
|
+
Object.keys(hints).forEach(function (key) {
|
|
93
|
+
if (!(key in rest)) hintProps[key] = hints[key];
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
var isFloating = Boolean(floatingLabel && label);
|
|
38
97
|
var internalId = useId();
|
|
39
98
|
var inputId = id || "input-".concat(internalId);
|
|
40
99
|
var isSearch = type === "search";
|
|
@@ -88,21 +147,22 @@ var Input = /*#__PURE__*/forwardRef(function (props, forwardedRef) {
|
|
|
88
147
|
var leftHasIcon = Boolean(icon && iconPosition === "left") || isSearch;
|
|
89
148
|
var rightHasIcon = Boolean(icon && iconPosition === "right") || isPassword || clearable && currentLength > 0;
|
|
90
149
|
var paddingClass = cn(leftHasIcon ? "pl-10" : "pl-3", rightHasIcon ? "pr-12" : "pr-3");
|
|
91
|
-
var baseClasses = cn("w-full rounded-md border bg-
|
|
92
|
-
//
|
|
93
|
-
paddingClass, error ? "border-
|
|
94
|
-
|
|
95
|
-
|
|
150
|
+
var baseClasses = cn("w-full rounded-md border bg-surface text-foreground placeholder-gray-400 dark:placeholder-gray-500", "transition-colors duration-fast ease-standard motion-reduce:transition-none", "disabled:cursor-not-allowed disabled:opacity-50", isFloating ? FLOATING_SIZE_CLASSES[size] : SIZE_CLASSES[size],
|
|
151
|
+
// The floated label replaces the placeholder until the field is focused.
|
|
152
|
+
isFloating && "peer placeholder-transparent focus:placeholder-gray-400 dark:focus:placeholder-gray-500", paddingClass, "focus:outline-none focus-visible:ring-2", error ? "border-error-500 focus-visible:ring-error-500 dark:border-error-400" : success ? "border-success-500 focus-visible:ring-success-500 dark:border-success-400" : "border-gray-300 focus-visible:ring-primary-500 dark:border-gray-600", className);
|
|
153
|
+
var labelContent = jsxs(Fragment, {
|
|
154
|
+
children: [label, required && jsx("span", {
|
|
155
|
+
className: "text-error-500 ml-1",
|
|
156
|
+
children: "*"
|
|
157
|
+
})]
|
|
158
|
+
});
|
|
96
159
|
var inputType = isPassword && showPassword ? "text" : type;
|
|
97
160
|
return jsxs("div", {
|
|
98
161
|
className: "w-full",
|
|
99
|
-
children: [label &&
|
|
162
|
+
children: [label && !isFloating && jsx("label", {
|
|
100
163
|
htmlFor: inputId,
|
|
101
|
-
className: "block text-sm font-medium mb-1",
|
|
102
|
-
children:
|
|
103
|
-
className: "text-error-500 ml-1",
|
|
104
|
-
children: "*"
|
|
105
|
-
})]
|
|
164
|
+
className: "block text-sm font-medium mb-1 text-foreground",
|
|
165
|
+
children: labelContent
|
|
106
166
|
}), jsxs("div", {
|
|
107
167
|
className: "relative",
|
|
108
168
|
children: [leftHasIcon && jsx("div", {
|
|
@@ -113,12 +173,13 @@ var Input = /*#__PURE__*/forwardRef(function (props, forwardedRef) {
|
|
|
113
173
|
className: "text-primary-400",
|
|
114
174
|
children: icon
|
|
115
175
|
})
|
|
116
|
-
}), jsx("input", _objectSpread2({
|
|
176
|
+
}), jsx("input", _objectSpread2(_objectSpread2({
|
|
117
177
|
id: inputId,
|
|
118
178
|
ref: setRefs,
|
|
119
179
|
type: inputType,
|
|
120
180
|
className: baseClasses,
|
|
121
|
-
placeholder
|
|
181
|
+
// :placeholder-shown drives the floating label, so it needs a placeholder.
|
|
182
|
+
placeholder: isFloating ? placeholder || " " : placeholder,
|
|
122
183
|
disabled: disabled,
|
|
123
184
|
readOnly: readOnly,
|
|
124
185
|
"aria-invalid": !!error,
|
|
@@ -126,13 +187,19 @@ var Input = /*#__PURE__*/forwardRef(function (props, forwardedRef) {
|
|
|
126
187
|
maxLength: maxLength,
|
|
127
188
|
onChange: handleChange,
|
|
128
189
|
value: value,
|
|
129
|
-
defaultValue: defaultValue
|
|
130
|
-
|
|
190
|
+
defaultValue: defaultValue,
|
|
191
|
+
size: nativeSize
|
|
192
|
+
}, hintProps), rest)), isFloating && jsx("label", {
|
|
193
|
+
htmlFor: inputId,
|
|
194
|
+
"data-floating-label": "",
|
|
195
|
+
className: cn("pointer-events-none absolute top-1 origin-left text-xs font-medium text-muted", leftHasIcon ? "left-10" : "left-3", "transition-[top,transform,font-size,color] duration-fast ease-standard motion-reduce:transition-none", "peer-placeholder-shown:top-1/2 peer-placeholder-shown:-translate-y-1/2 peer-placeholder-shown:text-sm", "peer-focus:top-1 peer-focus:translate-y-0 peer-focus:text-xs peer-focus:text-primary-600 dark:peer-focus:text-primary-400"),
|
|
196
|
+
children: labelContent
|
|
197
|
+
}), icon && iconPosition === "right" && !isPassword && !(clearable && currentLength > 0) && jsx("div", {
|
|
131
198
|
className: "absolute right-3 top-1/2 transform -translate-y-1/2 pointer-events-none text-primary-400",
|
|
132
199
|
children: icon
|
|
133
200
|
}), isPassword && jsx("button", {
|
|
134
201
|
type: "button",
|
|
135
|
-
className:
|
|
202
|
+
className: ADORNMENT_BUTTON,
|
|
136
203
|
onClick: function onClick() {
|
|
137
204
|
return setShowPassword(function (s) {
|
|
138
205
|
return !s;
|
|
@@ -147,7 +214,7 @@ var Input = /*#__PURE__*/forwardRef(function (props, forwardedRef) {
|
|
|
147
214
|
})
|
|
148
215
|
}), clearable && currentLength > 0 && !isPassword && jsx("button", {
|
|
149
216
|
type: "button",
|
|
150
|
-
className:
|
|
217
|
+
className: ADORNMENT_BUTTON,
|
|
151
218
|
onClick: handleClear,
|
|
152
219
|
"aria-label": "Clear input",
|
|
153
220
|
disabled: disabled,
|
|
@@ -157,12 +224,12 @@ var Input = /*#__PURE__*/forwardRef(function (props, forwardedRef) {
|
|
|
157
224
|
})]
|
|
158
225
|
}), error && jsx("p", {
|
|
159
226
|
id: "".concat(inputId, "-error"),
|
|
160
|
-
className: "mt-1 text-sm text-error-600",
|
|
227
|
+
className: "mt-1 text-sm text-error-600 dark:text-error-400",
|
|
161
228
|
"aria-live": "polite",
|
|
162
229
|
children: error
|
|
163
230
|
}), !error && success && jsx("p", {
|
|
164
231
|
id: "".concat(inputId, "-success"),
|
|
165
|
-
className: "mt-1 text-sm text-success-600",
|
|
232
|
+
className: "mt-1 text-sm text-success-600 dark:text-success-400",
|
|
166
233
|
"aria-live": "polite",
|
|
167
234
|
children: success
|
|
168
235
|
}), !error && !success && helperText && jsx("p", {
|
|
@@ -170,7 +237,7 @@ var Input = /*#__PURE__*/forwardRef(function (props, forwardedRef) {
|
|
|
170
237
|
className: "mt-1 text-sm text-muted",
|
|
171
238
|
children: helperText
|
|
172
239
|
}), showCount && maxLength && jsxs("div", {
|
|
173
|
-
className: "mt-1 text-right text-xs text-primary-500",
|
|
240
|
+
className: "mt-1 text-right text-xs text-primary-500 dark:text-primary-400",
|
|
174
241
|
"aria-hidden": true,
|
|
175
242
|
children: [currentLength, "/", maxLength]
|
|
176
243
|
})]
|