@dreamtree-org/twreact-ui 1.3.0 → 1.3.2
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 +2 -2
- package/README.md +258 -10
- package/ai-skills/dreamtree-ui.md +111 -15
- package/charts/package.json +5 -0
- package/dist/_shared/cn-DPPQUJu1.js +138 -0
- package/dist/ai-schema.json +1252 -179
- package/dist/charts/index.d.ts +9 -0
- package/dist/charts/index.d.ts.map +1 -0
- package/dist/charts/index.js +769 -0
- package/dist/components/charts/AreaChart.d.ts +4 -0
- package/dist/components/charts/AreaChart.d.ts.map +1 -0
- package/dist/components/charts/BarChart.d.ts +4 -0
- package/dist/components/charts/BarChart.d.ts.map +1 -0
- package/dist/components/charts/CartesianChart.d.ts +5 -0
- package/dist/components/charts/CartesianChart.d.ts.map +1 -0
- package/dist/components/charts/ChartFrame.d.ts +18 -0
- package/dist/components/charts/ChartFrame.d.ts.map +1 -0
- package/dist/components/charts/DonutChart.d.ts +4 -0
- package/dist/components/charts/DonutChart.d.ts.map +1 -0
- package/dist/components/charts/LineChart.d.ts +4 -0
- package/dist/components/charts/LineChart.d.ts.map +1 -0
- package/dist/components/charts/Sparkline.d.ts +5 -0
- package/dist/components/charts/Sparkline.d.ts.map +1 -0
- package/dist/components/charts/chartTheme.d.ts +26 -0
- package/dist/components/charts/chartTheme.d.ts.map +1 -0
- package/dist/components/core/Accordion.d.ts.map +1 -1
- 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/DatePicker.d.ts.map +1 -1
- package/dist/components/core/DateRangePicker.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/LocationPicker.d.ts.map +1 -1
- package/dist/components/core/Popover.d.ts +4 -0
- package/dist/components/core/Popover.d.ts.map +1 -0
- package/dist/components/core/PriceRangePicker.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/Select.d.ts.map +1 -1
- package/dist/components/core/Skeleton.d.ts.map +1 -1
- package/dist/components/core/Slider.d.ts +4 -0
- package/dist/components/core/Slider.d.ts.map +1 -0
- package/dist/components/core/SpeechToText.d.ts.map +1 -1
- package/dist/components/core/Switch.d.ts.map +1 -1
- package/dist/components/core/Table/ActionMenu.d.ts.map +1 -1
- package/dist/components/core/Table/ColumnMenu.d.ts +2 -1
- package/dist/components/core/Table/ColumnMenu.d.ts.map +1 -1
- package/dist/components/core/Table/MobileCard.d.ts +2 -2
- package/dist/components/core/Table/MobileCard.d.ts.map +1 -1
- package/dist/components/core/Table/Table.d.ts.map +1 -1
- package/dist/components/core/Table/TableRow.d.ts +4 -2
- package/dist/components/core/Table/TableRow.d.ts.map +1 -1
- package/dist/components/core/Tabs.d.ts.map +1 -1
- package/dist/components/core/Textarea.d.ts +4 -0
- package/dist/components/core/Textarea.d.ts.map +1 -0
- package/dist/components/core/ThreeDotPopover.d.ts.map +1 -1
- package/dist/components/core/Tooltip.d.ts.map +1 -1
- package/dist/components/feedback/Dialog.d.ts.map +1 -1
- package/dist/components/feedback/Drawer.d.ts +4 -0
- package/dist/components/feedback/Drawer.d.ts.map +1 -0
- package/dist/components/feedback/Toast.d.ts +14 -5
- package/dist/components/feedback/Toast.d.ts.map +1 -1
- package/dist/components/feedback/Tour.d.ts +4 -0
- package/dist/components/feedback/Tour.d.ts.map +1 -0
- package/dist/components/feedback/TourSpotlight.d.ts +9 -0
- package/dist/components/feedback/TourSpotlight.d.ts.map +1 -0
- package/dist/components/navigation/Breadcrumbs.d.ts.map +1 -1
- package/dist/components/navigation/FootNav.d.ts.map +1 -1
- package/dist/components/navigation/Navbar.d.ts.map +1 -1
- package/dist/components/navigation/Sidebar.d.ts +8 -2
- package/dist/components/navigation/Sidebar.d.ts.map +1 -1
- package/dist/components/rich-text/RichTextEditor.d.ts +4 -0
- package/dist/components/rich-text/RichTextEditor.d.ts.map +1 -0
- package/dist/components/rich-text/RichTextToolbar.d.ts +219 -0
- package/dist/components/rich-text/RichTextToolbar.d.ts.map +1 -0
- package/dist/components/utility/Badge.d.ts.map +1 -1
- package/dist/components/utility/FileUpload.d.ts.map +1 -1
- package/dist/components/utility/Sortable.d.ts +4 -0
- package/dist/components/utility/Sortable.d.ts.map +1 -0
- package/dist/esm/_vendor/object-assign/index.js +99 -0
- package/dist/esm/_vendor/prop-types/_vendor/react-is/cjs/react-is.development.js +190 -0
- package/dist/esm/_vendor/prop-types/_vendor/react-is/cjs/react-is.production.min.js +26 -0
- package/dist/esm/_vendor/prop-types/_vendor/react-is/index.js +19 -0
- package/dist/esm/_vendor/prop-types/checkPropTypes.js +115 -0
- package/dist/esm/_vendor/prop-types/factoryWithThrowingShims.js +74 -0
- package/dist/esm/_vendor/prop-types/factoryWithTypeCheckers.js +625 -0
- package/dist/esm/_vendor/prop-types/index.js +30 -0
- package/dist/esm/_vendor/prop-types/lib/ReactPropTypesSecret.js +21 -0
- package/dist/esm/_vendor/prop-types/lib/has.js +11 -0
- package/dist/esm/_virtual/_commonjsHelpers.js +5 -0
- package/dist/esm/_virtual/_rollupPluginBabelHelpers.js +329 -0
- package/dist/esm/_virtual/index.js +3 -0
- package/dist/esm/_virtual/index2.js +3 -0
- package/dist/esm/_virtual/react-is.development.js +3 -0
- package/dist/esm/_virtual/react-is.production.min.js +3 -0
- package/dist/esm/charts/index.js +5 -0
- package/dist/esm/components/blocks/AppShell.js +205 -0
- package/dist/esm/components/blocks/ConfirmDialog.js +57 -0
- package/dist/esm/components/blocks/EmptyState.js +44 -0
- package/dist/esm/components/blocks/ErrorState.js +53 -0
- package/dist/esm/components/blocks/LoadingState.js +134 -0
- package/dist/esm/components/blocks/PageHeader.js +51 -0
- package/dist/esm/components/blocks/StatCard.js +79 -0
- package/dist/esm/components/blocks/StatusPill.js +55 -0
- package/dist/esm/components/charts/AreaChart.js +16 -0
- package/dist/esm/components/charts/BarChart.js +16 -0
- package/dist/esm/components/charts/CartesianChart.js +250 -0
- package/dist/esm/components/charts/ChartFrame.js +170 -0
- package/dist/esm/components/charts/DonutChart.js +119 -0
- package/dist/esm/components/charts/LineChart.js +16 -0
- package/dist/esm/components/charts/Sparkline.js +110 -0
- package/dist/esm/components/charts/chartTheme.js +109 -0
- package/dist/esm/components/core/Accordion.js +260 -0
- package/dist/esm/components/core/Button.js +59 -0
- package/dist/esm/components/core/Checkbox.js +188 -0
- package/dist/esm/components/core/ColorPicker.js +348 -0
- package/dist/esm/components/core/DatePicker.js +436 -0
- package/dist/esm/components/core/DateRangePicker.js +494 -0
- package/dist/esm/components/core/Form.js +522 -0
- package/dist/esm/components/core/Input.js +179 -0
- package/dist/esm/components/core/Loader.js +141 -0
- package/dist/esm/components/core/LocationPicker.js +161 -0
- package/dist/esm/components/core/Popover.js +171 -0
- package/dist/esm/components/core/PriceRangePicker.js +376 -0
- package/dist/esm/components/core/ProgressBar.js +152 -0
- package/dist/esm/components/core/Radio.js +156 -0
- package/dist/esm/components/core/Rate.js +197 -0
- package/dist/esm/components/core/RoundedTag.js +118 -0
- package/dist/esm/components/core/Select.js +857 -0
- package/dist/esm/components/core/Skeleton.js +100 -0
- package/dist/esm/components/core/Slider.js +134 -0
- package/dist/esm/components/core/SpeechToText.js +226 -0
- package/dist/esm/components/core/Switch.js +207 -0
- package/dist/esm/components/core/Table/ActionMenu.js +251 -0
- package/dist/esm/components/core/Table/ColumnMenu.js +55 -0
- package/dist/esm/components/core/Table/FieldInput.js +157 -0
- package/dist/esm/components/core/Table/MobileCard.js +187 -0
- package/dist/esm/components/core/Table/MobileFilters.js +72 -0
- package/dist/esm/components/core/Table/Pagination.js +157 -0
- package/dist/esm/components/core/Table/Table.js +1533 -0
- package/dist/esm/components/core/Table/TableRow.js +254 -0
- package/dist/esm/components/core/Table/constants.js +35 -0
- package/dist/esm/components/core/Table/helpers.js +124 -0
- package/dist/esm/components/core/Table/useClickOutside.js +26 -0
- package/dist/esm/components/core/Tabs.js +289 -0
- package/dist/esm/components/core/TextToSpeech.js +52 -0
- package/dist/esm/components/core/Textarea.js +125 -0
- package/dist/esm/components/core/ThreeDotPopover.js +160 -0
- package/dist/esm/components/core/Tooltip.js +372 -0
- package/dist/esm/components/feedback/Alert.js +96 -0
- package/dist/esm/components/feedback/Dialog.js +200 -0
- package/dist/esm/components/feedback/Drawer.js +171 -0
- package/dist/esm/components/feedback/Toast.js +362 -0
- package/dist/esm/components/feedback/Tour.js +214 -0
- package/dist/esm/components/feedback/TourSpotlight.js +71 -0
- package/dist/esm/components/navigation/Breadcrumbs.js +75 -0
- package/dist/esm/components/navigation/Dropdown.js +53 -0
- package/dist/esm/components/navigation/FootNav.js +51 -0
- package/dist/esm/components/navigation/Navbar.js +437 -0
- package/dist/esm/components/navigation/Sidebar.js +567 -0
- package/dist/esm/components/rich-text/RichTextEditor.js +244 -0
- package/dist/esm/components/rich-text/RichTextToolbar.js +397 -0
- package/dist/esm/components/utility/Avatar.js +89 -0
- package/dist/esm/components/utility/Badge.js +47 -0
- package/dist/esm/components/utility/Card.js +85 -0
- package/dist/esm/components/utility/Carousel.js +97 -0
- package/dist/esm/components/utility/Condition.js +9 -0
- package/dist/esm/components/utility/FileUpload.js +177 -0
- package/dist/esm/components/utility/Pagination.js +111 -0
- package/dist/esm/components/utility/Sortable.js +190 -0
- package/dist/esm/components/utility/Stepper.js +101 -0
- package/dist/esm/hooks/useApi.js +169 -0
- package/dist/esm/hooks/useControllableState.js +32 -0
- package/dist/esm/hooks/useFocusTrap.js +85 -0
- package/dist/esm/hooks/useLatestRef.js +20 -0
- package/dist/esm/hooks/useMixins.js +100 -0
- package/dist/esm/hooks/useScrollLock.js +26 -0
- package/dist/esm/hooks/useSliderValues.js +135 -0
- package/dist/esm/hooks/useSortable.js +188 -0
- package/dist/esm/hooks/useTheme.js +53 -0
- package/dist/esm/hooks/useTourTarget.js +92 -0
- package/dist/esm/index.js +65 -0
- package/dist/esm/rich-text/index.js +1 -0
- package/dist/esm/store/index.js +26 -0
- package/dist/esm/store/store.js +107 -0
- package/dist/esm/store/storeSlice.js +45 -0
- package/dist/esm/utils/cn.js +11 -0
- package/dist/esm/utils/emitter.js +169 -0
- package/dist/esm/utils/helpers.js +161 -0
- package/dist/esm/utils/position.js +134 -0
- package/dist/hooks/useApi.d.ts +2 -1
- package/dist/hooks/useApi.d.ts.map +1 -1
- package/dist/hooks/useControllableState.d.ts +11 -0
- package/dist/hooks/useControllableState.d.ts.map +1 -0
- package/dist/hooks/useFocusTrap.d.ts +15 -0
- package/dist/hooks/useFocusTrap.d.ts.map +1 -0
- package/dist/hooks/useLatestRef.d.ts +8 -0
- package/dist/hooks/useLatestRef.d.ts.map +1 -0
- package/dist/hooks/useMixins.d.ts.map +1 -1
- package/dist/hooks/useScrollLock.d.ts +2 -0
- package/dist/hooks/useScrollLock.d.ts.map +1 -0
- package/dist/hooks/useSliderValues.d.ts +43 -0
- package/dist/hooks/useSliderValues.d.ts.map +1 -0
- package/dist/hooks/useSortable.d.ts +32 -0
- package/dist/hooks/useSortable.d.ts.map +1 -0
- package/dist/hooks/useTheme.d.ts.map +1 -1
- package/dist/hooks/useTourTarget.d.ts +15 -0
- package/dist/hooks/useTourTarget.d.ts.map +1 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.js +4817 -2216
- package/dist/index.js +4822 -2214
- package/dist/rich-text/index.d.ts +5 -0
- package/dist/rich-text/index.d.ts.map +1 -0
- package/dist/rich-text/index.js +654 -0
- package/dist/tokens/brands/studio.css +14 -0
- package/dist/tokens/brands/studio.json +20 -0
- package/dist/types/charts.d.ts +97 -0
- package/dist/types/charts.d.ts.map +1 -0
- package/dist/types/index.d.ts +193 -5
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/rich-text.d.ts +50 -0
- package/dist/types/rich-text.d.ts.map +1 -0
- package/dist/utils/position.d.ts +30 -0
- package/dist/utils/position.d.ts.map +1 -0
- package/doc/README.md +20 -1
- package/mcp/catalog.snapshot.json +2505 -800
- package/mcp/server-core.mjs +30 -1
- package/package.json +51 -3
- package/rich-text/package.json +5 -0
- package/tokens/brands/studio.json +20 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
+
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
4
|
+
import { forwardRef } from 'react';
|
|
5
|
+
import { cn } from '../../utils/cn.js';
|
|
6
|
+
|
|
7
|
+
var _excluded = ["count", "circle", "height", "width", "rounded", "animated", "active", "gap", "inline", "className", "children", "style"];
|
|
8
|
+
/**
|
|
9
|
+
* Skeleton Component (React)
|
|
10
|
+
*
|
|
11
|
+
* Props
|
|
12
|
+
* - count (number) - number of skeleton items to render (default: 1)
|
|
13
|
+
* - circle (boolean) - render items as circles (rounded-full)
|
|
14
|
+
* - height (number|string) - override height in px or CSS units (e.g. '2rem')
|
|
15
|
+
* - width (number|string) - override width in px or CSS units
|
|
16
|
+
* - rounded (boolean) - whether elements have rounded corners (if circle is false)
|
|
17
|
+
* - animated (boolean) - whether to show shimmer animation
|
|
18
|
+
* - active (boolean) - if true, show skeletons; if false, render children
|
|
19
|
+
* - gap (string) - spacing between stacked skeleton items (CSS value, default '8px')
|
|
20
|
+
* - inline (boolean) - render items inline (row) instead of stacked (column)
|
|
21
|
+
* - className (string) - extra wrapper classes
|
|
22
|
+
* - children - optional children to render when active === false
|
|
23
|
+
*/
|
|
24
|
+
function toPxOrUnit(value) {
|
|
25
|
+
if (typeof value === "number") return "".concat(value, "px");
|
|
26
|
+
if (typeof value === "string") return value;
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
var Skeleton = /*#__PURE__*/forwardRef(function Skeleton(_ref, ref) {
|
|
30
|
+
var _ref$count = _ref.count,
|
|
31
|
+
count = _ref$count === void 0 ? 1 : _ref$count,
|
|
32
|
+
_ref$circle = _ref.circle,
|
|
33
|
+
circle = _ref$circle === void 0 ? false : _ref$circle,
|
|
34
|
+
_ref$height = _ref.height,
|
|
35
|
+
height = _ref$height === void 0 ? 16 : _ref$height,
|
|
36
|
+
width = _ref.width,
|
|
37
|
+
_ref$rounded = _ref.rounded,
|
|
38
|
+
rounded = _ref$rounded === void 0 ? true : _ref$rounded,
|
|
39
|
+
_ref$animated = _ref.animated,
|
|
40
|
+
animated = _ref$animated === void 0 ? true : _ref$animated,
|
|
41
|
+
_ref$active = _ref.active,
|
|
42
|
+
active = _ref$active === void 0 ? true : _ref$active,
|
|
43
|
+
_ref$gap = _ref.gap,
|
|
44
|
+
gap = _ref$gap === void 0 ? "8px" : _ref$gap,
|
|
45
|
+
_ref$inline = _ref.inline,
|
|
46
|
+
inline = _ref$inline === void 0 ? false : _ref$inline,
|
|
47
|
+
_ref$className = _ref.className,
|
|
48
|
+
className = _ref$className === void 0 ? "" : _ref$className,
|
|
49
|
+
_ref$children = _ref.children,
|
|
50
|
+
children = _ref$children === void 0 ? null : _ref$children,
|
|
51
|
+
_ref$style = _ref.style,
|
|
52
|
+
style = _ref$style === void 0 ? {} : _ref$style,
|
|
53
|
+
rest = _objectWithoutProperties(_ref, _excluded);
|
|
54
|
+
if (!active) return jsx(Fragment, {
|
|
55
|
+
children: children
|
|
56
|
+
});
|
|
57
|
+
var resolvedHeight = toPxOrUnit(height);
|
|
58
|
+
var resolvedWidth = width !== undefined ? toPxOrUnit(width) : circle ? resolvedHeight : inline ? resolvedHeight : "100%";
|
|
59
|
+
var borderRadius = circle ? "9999px" : rounded ? "8px" : "2px";
|
|
60
|
+
var containerDirection = inline ? "row" : "column";
|
|
61
|
+
var items = Array.from({
|
|
62
|
+
length: Math.max(1, Math.floor(count))
|
|
63
|
+
});
|
|
64
|
+
var shimmerOverlay = animated ? "linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.5) 50%, rgba(255,255,255,0) 100%)" : "none";
|
|
65
|
+
return jsxs("div", _objectSpread2(_objectSpread2({
|
|
66
|
+
ref: ref,
|
|
67
|
+
className: cn("skeleton-wrapper", className),
|
|
68
|
+
role: "status",
|
|
69
|
+
"aria-busy": active,
|
|
70
|
+
"aria-live": "polite",
|
|
71
|
+
style: _objectSpread2({
|
|
72
|
+
display: "flex",
|
|
73
|
+
flexDirection: containerDirection,
|
|
74
|
+
gap: gap,
|
|
75
|
+
alignItems: "center"
|
|
76
|
+
}, style)
|
|
77
|
+
}, rest), {}, {
|
|
78
|
+
children: [jsx("style", {
|
|
79
|
+
children: "\n @keyframes skeleton-shimmer {\n 0% { background-position: -150% 0; }\n 100% { background-position: 150% 0; }\n }\n .skeleton-wrapper .skeleton-item {\n display: inline-block;\n position: relative;\n overflow: hidden;\n }\n "
|
|
80
|
+
}), items.map(function (_, i) {
|
|
81
|
+
return jsx("div", {
|
|
82
|
+
// Token classes rather than an inline hex, so brands and dark mode apply (STUDIO-59).
|
|
83
|
+
className: "skeleton-item bg-gray-200 dark:bg-gray-700",
|
|
84
|
+
style: {
|
|
85
|
+
height: resolvedHeight,
|
|
86
|
+
width: resolvedWidth,
|
|
87
|
+
borderRadius: borderRadius,
|
|
88
|
+
backgroundImage: shimmerOverlay,
|
|
89
|
+
backgroundSize: animated ? "200% 100%" : undefined,
|
|
90
|
+
backgroundRepeat: "no-repeat",
|
|
91
|
+
animation: animated ? "skeleton-shimmer 1.2s linear infinite" : undefined,
|
|
92
|
+
willChange: animated ? "background-position" : undefined
|
|
93
|
+
}
|
|
94
|
+
}, i);
|
|
95
|
+
})]
|
|
96
|
+
}));
|
|
97
|
+
});
|
|
98
|
+
Skeleton.displayName = "Skeleton";
|
|
99
|
+
|
|
100
|
+
export { Skeleton as default };
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
+
import { forwardRef, useId, useRef, useMemo } from 'react';
|
|
5
|
+
import { cn } from '../../utils/cn.js';
|
|
6
|
+
import { useSliderValues, useSliderPointer, toPercent, keyToValue } from '../../hooks/useSliderValues.js';
|
|
7
|
+
|
|
8
|
+
var _excluded = ["value", "defaultValue", "onChange", "onChangeEnd", "min", "max", "step", "largeStep", "disabled", "label", "showValue", "formatValue", "thumbLabels", "name", "className", "aria-label"];
|
|
9
|
+
var DEFAULT_THUMB_LABELS = ["Minimum", "Maximum"];
|
|
10
|
+
var Slider = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
11
|
+
var value = _ref.value,
|
|
12
|
+
defaultValue = _ref.defaultValue,
|
|
13
|
+
onChange = _ref.onChange,
|
|
14
|
+
onChangeEnd = _ref.onChangeEnd,
|
|
15
|
+
_ref$min = _ref.min,
|
|
16
|
+
min = _ref$min === void 0 ? 0 : _ref$min,
|
|
17
|
+
_ref$max = _ref.max,
|
|
18
|
+
max = _ref$max === void 0 ? 100 : _ref$max,
|
|
19
|
+
_ref$step = _ref.step,
|
|
20
|
+
step = _ref$step === void 0 ? 1 : _ref$step,
|
|
21
|
+
largeStep = _ref.largeStep,
|
|
22
|
+
_ref$disabled = _ref.disabled,
|
|
23
|
+
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
|
|
24
|
+
label = _ref.label,
|
|
25
|
+
_ref$showValue = _ref.showValue,
|
|
26
|
+
showValue = _ref$showValue === void 0 ? false : _ref$showValue,
|
|
27
|
+
_ref$formatValue = _ref.formatValue,
|
|
28
|
+
formatValue = _ref$formatValue === void 0 ? String : _ref$formatValue,
|
|
29
|
+
_ref$thumbLabels = _ref.thumbLabels,
|
|
30
|
+
thumbLabels = _ref$thumbLabels === void 0 ? DEFAULT_THUMB_LABELS : _ref$thumbLabels,
|
|
31
|
+
name = _ref.name,
|
|
32
|
+
className = _ref.className,
|
|
33
|
+
ariaLabel = _ref["aria-label"],
|
|
34
|
+
rest = _objectWithoutProperties(_ref, _excluded);
|
|
35
|
+
var labelId = "slider-label-".concat(useId());
|
|
36
|
+
var trackRef = useRef(null);
|
|
37
|
+
var bounds = useMemo(function () {
|
|
38
|
+
return {
|
|
39
|
+
min: min,
|
|
40
|
+
max: max,
|
|
41
|
+
step: step > 0 ? step : 1,
|
|
42
|
+
largeStep: largeStep !== null && largeStep !== void 0 ? largeStep : Math.max(step, (max - min) / 10)
|
|
43
|
+
};
|
|
44
|
+
}, [min, max, step, largeStep]);
|
|
45
|
+
var _useSliderValues = useSliderValues({
|
|
46
|
+
value: value,
|
|
47
|
+
defaultValue: defaultValue !== null && defaultValue !== void 0 ? defaultValue : min,
|
|
48
|
+
onChange: onChange,
|
|
49
|
+
onChangeEnd: onChangeEnd,
|
|
50
|
+
bounds: bounds
|
|
51
|
+
}),
|
|
52
|
+
values = _useSliderValues.values,
|
|
53
|
+
isRange = _useSliderValues.isRange,
|
|
54
|
+
setThumb = _useSliderValues.setThumb;
|
|
55
|
+
var pointer = useSliderPointer({
|
|
56
|
+
trackRef: trackRef,
|
|
57
|
+
values: values,
|
|
58
|
+
setThumb: setThumb,
|
|
59
|
+
bounds: bounds,
|
|
60
|
+
disabled: disabled
|
|
61
|
+
});
|
|
62
|
+
var handleKeyDown = function handleKeyDown(index) {
|
|
63
|
+
return function (e) {
|
|
64
|
+
if (disabled) return;
|
|
65
|
+
var next = keyToValue(e.key, values[index], bounds);
|
|
66
|
+
if (next === null) return;
|
|
67
|
+
e.preventDefault();
|
|
68
|
+
setThumb(index, next, true);
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
var low = isRange ? toPercent(values[0], min, max) : 0;
|
|
72
|
+
var high = toPercent(values[values.length - 1], min, max);
|
|
73
|
+
var display = values.map(function (v) {
|
|
74
|
+
return formatValue(v);
|
|
75
|
+
}).join(" – ");
|
|
76
|
+
return jsxs("div", _objectSpread2(_objectSpread2({
|
|
77
|
+
ref: ref,
|
|
78
|
+
className: cn("w-full", disabled && "opacity-50", className)
|
|
79
|
+
}, rest), {}, {
|
|
80
|
+
children: [(label || showValue) && jsxs("div", {
|
|
81
|
+
className: "mb-2 flex items-center justify-between text-sm",
|
|
82
|
+
children: [label && jsx("span", {
|
|
83
|
+
id: labelId,
|
|
84
|
+
className: "font-medium text-gray-700 dark:text-gray-200",
|
|
85
|
+
children: label
|
|
86
|
+
}), showValue && jsx("span", {
|
|
87
|
+
className: "tabular-nums text-gray-500 dark:text-gray-400",
|
|
88
|
+
"aria-hidden": "true",
|
|
89
|
+
children: display
|
|
90
|
+
})]
|
|
91
|
+
}), jsxs("div", _objectSpread2(_objectSpread2({
|
|
92
|
+
ref: trackRef,
|
|
93
|
+
className: cn("relative flex h-5 touch-none select-none items-center", disabled ? "cursor-not-allowed" : "cursor-pointer")
|
|
94
|
+
}, pointer), {}, {
|
|
95
|
+
children: [jsx("div", {
|
|
96
|
+
className: "h-1.5 w-full rounded-full bg-gray-200 dark:bg-gray-700"
|
|
97
|
+
}), jsx("div", {
|
|
98
|
+
className: "absolute h-1.5 rounded-full bg-primary-600 dark:bg-primary-500",
|
|
99
|
+
style: {
|
|
100
|
+
left: "".concat(low, "%"),
|
|
101
|
+
width: "".concat(high - low, "%")
|
|
102
|
+
}
|
|
103
|
+
}), values.map(function (v, i) {
|
|
104
|
+
var thumbLabel = isRange ? thumbLabels[i] : undefined;
|
|
105
|
+
return jsx("div", {
|
|
106
|
+
role: "slider",
|
|
107
|
+
tabIndex: disabled ? -1 : 0,
|
|
108
|
+
"aria-valuemin": isRange && i === 1 ? values[0] : min,
|
|
109
|
+
"aria-valuemax": isRange && i === 0 ? values[1] : max,
|
|
110
|
+
"aria-valuenow": v,
|
|
111
|
+
"aria-valuetext": formatValue(v),
|
|
112
|
+
"aria-orientation": "horizontal",
|
|
113
|
+
"aria-disabled": disabled || undefined,
|
|
114
|
+
"aria-label": thumbLabel !== null && thumbLabel !== void 0 ? thumbLabel : label ? undefined : ariaLabel,
|
|
115
|
+
"aria-labelledby": label && !thumbLabel ? labelId : undefined,
|
|
116
|
+
onKeyDown: handleKeyDown(i),
|
|
117
|
+
style: {
|
|
118
|
+
left: "".concat(toPercent(v, min, max), "%")
|
|
119
|
+
},
|
|
120
|
+
className: cn("absolute h-4 w-4 -translate-x-1/2 rounded-full border-2 border-primary-600 bg-white shadow", "transition-shadow motion-reduce:transition-none", "focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500", "dark:border-primary-500 dark:bg-gray-900 dark:focus:ring-offset-gray-900")
|
|
121
|
+
}, i);
|
|
122
|
+
})]
|
|
123
|
+
})), name && values.map(function (v, i) {
|
|
124
|
+
return jsx("input", {
|
|
125
|
+
type: "hidden",
|
|
126
|
+
name: isRange ? "".concat(name, "[").concat(i, "]") : name,
|
|
127
|
+
value: v
|
|
128
|
+
}, i);
|
|
129
|
+
})]
|
|
130
|
+
}));
|
|
131
|
+
});
|
|
132
|
+
Slider.displayName = "Slider";
|
|
133
|
+
|
|
134
|
+
export { Slider as default };
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { objectWithoutProperties as _objectWithoutProperties, slicedToArray as _slicedToArray, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
+
import { forwardRef, useRef, useState, useEffect, useCallback, useImperativeHandle } from 'react';
|
|
5
|
+
import { MicOff, Mic } from 'lucide-react';
|
|
6
|
+
import { cn } from '../../utils/cn.js';
|
|
7
|
+
|
|
8
|
+
var _excluded = ["lang", "continuous", "interimResults", "onSpeechComplete", "onSpeaking", "onError", "onStart", "onStop", "renderButton", "autoStart", "disabled", "resetOnStart", "className"];
|
|
9
|
+
var isProbablyMobile = function isProbablyMobile() {
|
|
10
|
+
if (typeof navigator === "undefined") return false;
|
|
11
|
+
return /Android|iPhone|iPad|iPod/i.test(navigator.userAgent);
|
|
12
|
+
};
|
|
13
|
+
// Routine, non-fatal recognition events. The browser fires these during normal
|
|
14
|
+
// operation (e.g. a pause in speech, or a programmatic stop) and follows them
|
|
15
|
+
// with `onend`, so surfacing them as errors only creates noise for consumers.
|
|
16
|
+
var NON_FATAL_ERRORS = new Set(["no-speech", "aborted"]);
|
|
17
|
+
var SpeechToText = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
18
|
+
var _ref$lang = _ref.lang,
|
|
19
|
+
lang = _ref$lang === void 0 ? "en-US" : _ref$lang,
|
|
20
|
+
_ref$continuous = _ref.continuous,
|
|
21
|
+
continuous = _ref$continuous === void 0 ? true : _ref$continuous,
|
|
22
|
+
_ref$interimResults = _ref.interimResults,
|
|
23
|
+
interimResults = _ref$interimResults === void 0 ? true : _ref$interimResults,
|
|
24
|
+
_ref$onSpeechComplete = _ref.onSpeechComplete,
|
|
25
|
+
onSpeechComplete = _ref$onSpeechComplete === void 0 ? function () {} : _ref$onSpeechComplete,
|
|
26
|
+
_ref$onSpeaking = _ref.onSpeaking,
|
|
27
|
+
onSpeaking = _ref$onSpeaking === void 0 ? function () {} : _ref$onSpeaking,
|
|
28
|
+
_ref$onError = _ref.onError,
|
|
29
|
+
onError = _ref$onError === void 0 ? function () {} : _ref$onError,
|
|
30
|
+
_ref$onStart = _ref.onStart,
|
|
31
|
+
onStart = _ref$onStart === void 0 ? function () {} : _ref$onStart,
|
|
32
|
+
_ref$onStop = _ref.onStop,
|
|
33
|
+
onStop = _ref$onStop === void 0 ? function () {} : _ref$onStop,
|
|
34
|
+
renderButton = _ref.renderButton,
|
|
35
|
+
_ref$autoStart = _ref.autoStart,
|
|
36
|
+
autoStart = _ref$autoStart === void 0 ? false : _ref$autoStart,
|
|
37
|
+
_ref$disabled = _ref.disabled,
|
|
38
|
+
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
|
|
39
|
+
_ref$resetOnStart = _ref.resetOnStart,
|
|
40
|
+
resetOnStart = _ref$resetOnStart === void 0 ? false : _ref$resetOnStart,
|
|
41
|
+
className = _ref.className,
|
|
42
|
+
rest = _objectWithoutProperties(_ref, _excluded);
|
|
43
|
+
var recognitionRef = useRef(null);
|
|
44
|
+
var isMountedRef = useRef(true);
|
|
45
|
+
var autoStartedRef = useRef(false);
|
|
46
|
+
var finalTranscriptRef = useRef("");
|
|
47
|
+
var _useState = useState(false),
|
|
48
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
49
|
+
_isListening = _useState2[0],
|
|
50
|
+
setIsListening = _useState2[1];
|
|
51
|
+
var _useState3 = useState(true),
|
|
52
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
53
|
+
_isSupported = _useState4[0],
|
|
54
|
+
setIsSupported = _useState4[1];
|
|
55
|
+
var _useState5 = useState(null),
|
|
56
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
57
|
+
error = _useState6[0],
|
|
58
|
+
setError = _useState6[1];
|
|
59
|
+
useEffect(function () {
|
|
60
|
+
var hasSpeechRecognition = typeof window !== "undefined" && ("SpeechRecognition" in window || "webkitSpeechRecognition" in window);
|
|
61
|
+
setIsSupported(hasSpeechRecognition);
|
|
62
|
+
}, []);
|
|
63
|
+
var buildFinalTranscript = useCallback(function () {
|
|
64
|
+
return finalTranscriptRef.current.trim();
|
|
65
|
+
}, []);
|
|
66
|
+
var initializeRecognition = useCallback(function () {
|
|
67
|
+
if (recognitionRef.current) return recognitionRef.current;
|
|
68
|
+
var SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
69
|
+
if (!SpeechRecognition) {
|
|
70
|
+
var err = new Error("SpeechRecognition API not supported");
|
|
71
|
+
setError(err);
|
|
72
|
+
onError(err);
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
var recognition = new SpeechRecognition();
|
|
76
|
+
recognition.continuous = isProbablyMobile() ? false : continuous;
|
|
77
|
+
recognition.interimResults = interimResults;
|
|
78
|
+
recognition.lang = lang;
|
|
79
|
+
recognition.onstart = function () {
|
|
80
|
+
if (!isMountedRef.current) return;
|
|
81
|
+
setIsListening(true);
|
|
82
|
+
setError(null);
|
|
83
|
+
onStart();
|
|
84
|
+
};
|
|
85
|
+
recognition.onresult = function (event) {
|
|
86
|
+
if (!isMountedRef.current) return;
|
|
87
|
+
var interim = "";
|
|
88
|
+
var finalChunk = "";
|
|
89
|
+
for (var i = event.resultIndex; i < event.results.length; i++) {
|
|
90
|
+
var _res$;
|
|
91
|
+
var res = event.results[i];
|
|
92
|
+
var text = ((_res$ = res[0]) === null || _res$ === void 0 ? void 0 : _res$.transcript) || "";
|
|
93
|
+
if (res.isFinal) {
|
|
94
|
+
finalChunk += text + " ";
|
|
95
|
+
finalTranscriptRef.current += text + " ";
|
|
96
|
+
} else {
|
|
97
|
+
interim += text;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (interim) onSpeaking(interim.trim());
|
|
101
|
+
if (finalChunk) onSpeechComplete(finalChunk.trim());
|
|
102
|
+
};
|
|
103
|
+
recognition.onerror = function (event) {
|
|
104
|
+
if (!isMountedRef.current) return;
|
|
105
|
+
// Ignore routine events — `onend` handles the listening-state reset.
|
|
106
|
+
if (NON_FATAL_ERRORS.has(event === null || event === void 0 ? void 0 : event.error)) return;
|
|
107
|
+
var err = new Error((event === null || event === void 0 ? void 0 : event.error) || "Speech recognition error");
|
|
108
|
+
setError(err);
|
|
109
|
+
setIsListening(false);
|
|
110
|
+
onError(err);
|
|
111
|
+
};
|
|
112
|
+
recognition.onend = function () {
|
|
113
|
+
if (!isMountedRef.current) return;
|
|
114
|
+
setIsListening(false);
|
|
115
|
+
onStop();
|
|
116
|
+
};
|
|
117
|
+
recognitionRef.current = recognition;
|
|
118
|
+
return recognition;
|
|
119
|
+
}, [continuous, interimResults, lang, onStart, onSpeaking, onSpeechComplete, onError, onStop]);
|
|
120
|
+
var startListening = useCallback(function () {
|
|
121
|
+
if (!_isSupported || disabled || _isListening) return;
|
|
122
|
+
try {
|
|
123
|
+
var rec = initializeRecognition();
|
|
124
|
+
if (!rec) return;
|
|
125
|
+
if (resetOnStart) {
|
|
126
|
+
finalTranscriptRef.current = "";
|
|
127
|
+
}
|
|
128
|
+
rec.start();
|
|
129
|
+
} catch (err) {
|
|
130
|
+
setError(err);
|
|
131
|
+
onError(err);
|
|
132
|
+
}
|
|
133
|
+
}, [_isSupported, disabled, _isListening, initializeRecognition, resetOnStart, onError]);
|
|
134
|
+
var stopListening = useCallback(function () {
|
|
135
|
+
if (!recognitionRef.current) return;
|
|
136
|
+
try {
|
|
137
|
+
recognitionRef.current.stop();
|
|
138
|
+
} catch (_unused) {
|
|
139
|
+
// already stopped
|
|
140
|
+
}
|
|
141
|
+
}, []);
|
|
142
|
+
var toggleListening = useCallback(function () {
|
|
143
|
+
if (disabled) return;
|
|
144
|
+
_isListening ? stopListening() : startListening();
|
|
145
|
+
}, [_isListening, disabled, startListening, stopListening]);
|
|
146
|
+
// Auto-start once, after support has been resolved. The ref guard keeps a
|
|
147
|
+
// later stop from being immediately undone by a re-running effect.
|
|
148
|
+
useEffect(function () {
|
|
149
|
+
if (autoStart && _isSupported && !disabled && !autoStartedRef.current) {
|
|
150
|
+
autoStartedRef.current = true;
|
|
151
|
+
startListening();
|
|
152
|
+
}
|
|
153
|
+
}, [autoStart, _isSupported, disabled, startListening]);
|
|
154
|
+
// Mark unmounted so async recognition handlers don't touch state after
|
|
155
|
+
// teardown, then stop the engine.
|
|
156
|
+
useEffect(function () {
|
|
157
|
+
isMountedRef.current = true;
|
|
158
|
+
return function () {
|
|
159
|
+
isMountedRef.current = false;
|
|
160
|
+
if (recognitionRef.current) {
|
|
161
|
+
try {
|
|
162
|
+
recognitionRef.current.stop();
|
|
163
|
+
} catch (_unused2) {
|
|
164
|
+
// already stopped
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
}, []);
|
|
169
|
+
useImperativeHandle(ref, function () {
|
|
170
|
+
return {
|
|
171
|
+
start: startListening,
|
|
172
|
+
stop: stopListening,
|
|
173
|
+
toggle: toggleListening,
|
|
174
|
+
isListening: function isListening() {
|
|
175
|
+
return _isListening;
|
|
176
|
+
},
|
|
177
|
+
isSupported: function isSupported() {
|
|
178
|
+
return _isSupported;
|
|
179
|
+
},
|
|
180
|
+
getTranscript: buildFinalTranscript,
|
|
181
|
+
clearTranscript: function clearTranscript() {
|
|
182
|
+
finalTranscriptRef.current = "";
|
|
183
|
+
},
|
|
184
|
+
getError: function getError() {
|
|
185
|
+
return error;
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
}, [_isListening, _isSupported, error, startListening, stopListening, toggleListening, buildFinalTranscript]);
|
|
189
|
+
if (typeof renderButton === "function") {
|
|
190
|
+
// The start/stop/toggle callbacks only touch refs when invoked from
|
|
191
|
+
// event handlers, never while renderButton itself is rendering.
|
|
192
|
+
// eslint-disable-next-line react-hooks/refs
|
|
193
|
+
return renderButton({
|
|
194
|
+
isListening: _isListening,
|
|
195
|
+
isSupported: _isSupported,
|
|
196
|
+
error: error,
|
|
197
|
+
start: startListening,
|
|
198
|
+
stop: stopListening,
|
|
199
|
+
toggle: toggleListening,
|
|
200
|
+
disabled: disabled || !_isSupported
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
var isDisabled = disabled || !_isSupported;
|
|
204
|
+
return jsxs("button", _objectSpread2(_objectSpread2({
|
|
205
|
+
type: "button",
|
|
206
|
+
"aria-pressed": _isListening,
|
|
207
|
+
"aria-label": _isListening ? "Stop listening" : "Start listening",
|
|
208
|
+
onClick: toggleListening,
|
|
209
|
+
disabled: isDisabled,
|
|
210
|
+
className: cn("inline-flex items-center gap-2 rounded-md px-4 h-10 text-sm font-medium", "border border-gray-300 bg-transparent transition-colors", "hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500", "disabled:opacity-50 disabled:pointer-events-none", {
|
|
211
|
+
"text-error-600 border-error-600": _isListening,
|
|
212
|
+
"text-gray-900": !_isListening
|
|
213
|
+
}, className)
|
|
214
|
+
}, rest), {}, {
|
|
215
|
+
children: [_isListening ? jsx(MicOff, {
|
|
216
|
+
className: "h-4 w-4",
|
|
217
|
+
"aria-hidden": "true"
|
|
218
|
+
}) : jsx(Mic, {
|
|
219
|
+
className: "h-4 w-4",
|
|
220
|
+
"aria-hidden": "true"
|
|
221
|
+
}), _isListening ? "Stop" : "Start"]
|
|
222
|
+
}));
|
|
223
|
+
});
|
|
224
|
+
SpeechToText.displayName = "SpeechToText";
|
|
225
|
+
|
|
226
|
+
export { SpeechToText as default };
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { objectWithoutProperties as _objectWithoutProperties, slicedToArray as _slicedToArray, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
+
import { forwardRef, useState, useId, useEffect } from 'react';
|
|
5
|
+
import { cn } from '../../utils/cn.js';
|
|
6
|
+
|
|
7
|
+
var _excluded = ["id", "name", "checked", "defaultChecked", "onChange", "disabled", "size", "color", "trackClass", "thumbClass", "className", "topLabel", "bottomLabel", "rightLabel", "leftLabel", "ariaLabel"];
|
|
8
|
+
/**
|
|
9
|
+
* Switch.jsx
|
|
10
|
+
* - Plain JSX (no TypeScript)
|
|
11
|
+
* - Uses only trackClass and thumbClass (both accept any valid CSS color string or class name)
|
|
12
|
+
* - Controlled or uncontrolled usage
|
|
13
|
+
* - Sizes: 'sm' | 'md' | 'lg'
|
|
14
|
+
* - Accessible (role="switch", keyboard toggle)
|
|
15
|
+
* - Hidden input for form serialization (name prop)
|
|
16
|
+
*
|
|
17
|
+
* New props:
|
|
18
|
+
* - topLabel, bottomLabel, rightLabel, leftLabel (renders label in those positions)
|
|
19
|
+
*/
|
|
20
|
+
var SIZE_MAP = {
|
|
21
|
+
sm: {
|
|
22
|
+
track: "w-9 h-5",
|
|
23
|
+
knob: "w-4 h-4",
|
|
24
|
+
knobTranslate: "translate-x-4"
|
|
25
|
+
},
|
|
26
|
+
md: {
|
|
27
|
+
track: "w-11 h-6",
|
|
28
|
+
knob: "w-5 h-5",
|
|
29
|
+
knobTranslate: "translate-x-5"
|
|
30
|
+
},
|
|
31
|
+
lg: {
|
|
32
|
+
track: "w-14 h-8",
|
|
33
|
+
knob: "w-6 h-6",
|
|
34
|
+
knobTranslate: "translate-x-6"
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
var COLOR_PRESETS = {
|
|
38
|
+
primary: {
|
|
39
|
+
bg: "bg-primary-600",
|
|
40
|
+
ring: "focus-visible:ring-primary-300"
|
|
41
|
+
},
|
|
42
|
+
secondary: {
|
|
43
|
+
bg: "bg-secondary-600",
|
|
44
|
+
ring: "focus-visible:ring-secondary-300"
|
|
45
|
+
},
|
|
46
|
+
success: {
|
|
47
|
+
bg: "bg-success-600",
|
|
48
|
+
ring: "focus-visible:ring-success-300"
|
|
49
|
+
},
|
|
50
|
+
green: {
|
|
51
|
+
bg: "bg-success-600",
|
|
52
|
+
ring: "focus-visible:ring-success-300"
|
|
53
|
+
},
|
|
54
|
+
error: {
|
|
55
|
+
bg: "bg-error-600",
|
|
56
|
+
ring: "focus-visible:ring-error-300"
|
|
57
|
+
},
|
|
58
|
+
danger: {
|
|
59
|
+
bg: "bg-error-600",
|
|
60
|
+
ring: "focus-visible:ring-error-300"
|
|
61
|
+
},
|
|
62
|
+
red: {
|
|
63
|
+
bg: "bg-error-600",
|
|
64
|
+
ring: "focus-visible:ring-error-300"
|
|
65
|
+
},
|
|
66
|
+
warning: {
|
|
67
|
+
bg: "bg-warning-600",
|
|
68
|
+
ring: "focus-visible:ring-warning-300"
|
|
69
|
+
},
|
|
70
|
+
blue: {
|
|
71
|
+
bg: "bg-blue-600",
|
|
72
|
+
ring: "focus-visible:ring-blue-300"
|
|
73
|
+
},
|
|
74
|
+
indigo: {
|
|
75
|
+
bg: "bg-indigo-600",
|
|
76
|
+
ring: "focus-visible:ring-indigo-300"
|
|
77
|
+
},
|
|
78
|
+
purple: {
|
|
79
|
+
bg: "bg-purple-600",
|
|
80
|
+
ring: "focus-visible:ring-purple-300"
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
var Switch = /*#__PURE__*/forwardRef(function Switch(props, ref) {
|
|
84
|
+
var id = props.id,
|
|
85
|
+
name = props.name,
|
|
86
|
+
checked = props.checked,
|
|
87
|
+
_props$defaultChecked = props.defaultChecked,
|
|
88
|
+
defaultChecked = _props$defaultChecked === void 0 ? false : _props$defaultChecked,
|
|
89
|
+
onChange = props.onChange,
|
|
90
|
+
_props$disabled = props.disabled,
|
|
91
|
+
disabled = _props$disabled === void 0 ? false : _props$disabled,
|
|
92
|
+
_props$size = props.size,
|
|
93
|
+
size = _props$size === void 0 ? "md" : _props$size,
|
|
94
|
+
_props$color = props.color,
|
|
95
|
+
color = _props$color === void 0 ? "primary" : _props$color,
|
|
96
|
+
trackClass = props.trackClass,
|
|
97
|
+
thumbClass = props.thumbClass,
|
|
98
|
+
_props$className = props.className,
|
|
99
|
+
className = _props$className === void 0 ? "" : _props$className,
|
|
100
|
+
topLabel = props.topLabel,
|
|
101
|
+
bottomLabel = props.bottomLabel,
|
|
102
|
+
rightLabel = props.rightLabel,
|
|
103
|
+
leftLabel = props.leftLabel,
|
|
104
|
+
ariaLabel = props.ariaLabel,
|
|
105
|
+
rest = _objectWithoutProperties(props, _excluded);
|
|
106
|
+
var isControlled = typeof checked === "boolean";
|
|
107
|
+
var _useState = useState(defaultChecked),
|
|
108
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
109
|
+
internalChecked = _useState2[0],
|
|
110
|
+
setInternalChecked = _useState2[1];
|
|
111
|
+
var isOn = isControlled ? checked : internalChecked;
|
|
112
|
+
var autoId = useId();
|
|
113
|
+
var switchId = id || "switch-".concat(autoId);
|
|
114
|
+
useEffect(function () {
|
|
115
|
+
if (!isControlled) setInternalChecked(defaultChecked);
|
|
116
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
117
|
+
}, [defaultChecked]);
|
|
118
|
+
var toggle = function toggle() {
|
|
119
|
+
if (disabled) return;
|
|
120
|
+
var next = !isOn;
|
|
121
|
+
if (!isControlled) setInternalChecked(next);
|
|
122
|
+
onChange && onChange(next);
|
|
123
|
+
};
|
|
124
|
+
var handleKeyDown = function handleKeyDown(e) {
|
|
125
|
+
if (disabled) return;
|
|
126
|
+
if (e.key === " " || e.key === "Spacebar" || e.key === "Enter") {
|
|
127
|
+
e.preventDefault();
|
|
128
|
+
toggle();
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
var sizeStuff = SIZE_MAP[size] || SIZE_MAP.md;
|
|
132
|
+
var isPreset = COLOR_PRESETS[color];
|
|
133
|
+
// Classes for the track (we use inline style for arbitrary trackClass when ON)
|
|
134
|
+
var trackClasses = cn("relative inline-flex items-center rounded-full transition-colors duration-200 ease-in-out", sizeStuff.track, isOn ? trackClass ? "" : isPreset ? isPreset.bg : "" : "bg-gray-100", disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer", trackClass // Accepting trackClass as a class name
|
|
135
|
+
);
|
|
136
|
+
// Knob classes (thumb)
|
|
137
|
+
var knobBase = cn("inline-block rounded-full bg-white shadow transform ring-0 transition-transform duration-200 ease-in-out", sizeStuff.knob, thumbClass // Accepting thumbClass as a class name
|
|
138
|
+
);
|
|
139
|
+
var knobTransform = isOn ? sizeStuff.knobTranslate : "translate-x-1";
|
|
140
|
+
var ringClass = isPreset ? isPreset.ring : "focus-visible:ring-primary-300";
|
|
141
|
+
var focusClasses = disabled ? "" : "focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 ".concat(ringClass);
|
|
142
|
+
var trackStyle = isOn && !trackClass && !isPreset ? {
|
|
143
|
+
backgroundColor: color
|
|
144
|
+
} : undefined; // Fallback to default trackClass if trackClass is not a class
|
|
145
|
+
var accessibleLabel = ariaLabel || rightLabel || leftLabel || topLabel || bottomLabel || "Toggle";
|
|
146
|
+
var containerIsColumn = Boolean(topLabel || bottomLabel);
|
|
147
|
+
var containerClass = cn(containerIsColumn ? "flex flex-col" : "inline-flex items-center", "gap-2", className);
|
|
148
|
+
var labelOpacityClass = disabled ? "opacity-50" : "";
|
|
149
|
+
return jsxs("div", {
|
|
150
|
+
className: containerClass,
|
|
151
|
+
children: [topLabel ? jsx("label", {
|
|
152
|
+
htmlFor: switchId,
|
|
153
|
+
className: labelOpacityClass,
|
|
154
|
+
children: topLabel
|
|
155
|
+
}) : null, jsxs("div", {
|
|
156
|
+
className: "inline-flex items-center gap-2",
|
|
157
|
+
children: [leftLabel ? jsx("label", {
|
|
158
|
+
htmlFor: switchId,
|
|
159
|
+
className: labelOpacityClass,
|
|
160
|
+
children: leftLabel
|
|
161
|
+
}) : null, jsxs("button", _objectSpread2(_objectSpread2({
|
|
162
|
+
ref: ref,
|
|
163
|
+
id: switchId,
|
|
164
|
+
type: "button",
|
|
165
|
+
role: "switch",
|
|
166
|
+
"aria-checked": isOn,
|
|
167
|
+
"aria-label": accessibleLabel,
|
|
168
|
+
"aria-disabled": disabled || undefined,
|
|
169
|
+
disabled: disabled,
|
|
170
|
+
tabIndex: disabled ? -1 : 0,
|
|
171
|
+
className: cn(trackClasses, focusClasses),
|
|
172
|
+
onClick: toggle,
|
|
173
|
+
onKeyDown: handleKeyDown,
|
|
174
|
+
style: trackStyle
|
|
175
|
+
}, rest), {}, {
|
|
176
|
+
children: [jsx("span", {
|
|
177
|
+
className: "sr-only",
|
|
178
|
+
children: accessibleLabel
|
|
179
|
+
}), jsx("span", {
|
|
180
|
+
"aria-hidden": "true",
|
|
181
|
+
className: cn(knobBase, knobTransform)
|
|
182
|
+
})]
|
|
183
|
+
})), rightLabel ? jsx("label", {
|
|
184
|
+
htmlFor: switchId,
|
|
185
|
+
className: labelOpacityClass,
|
|
186
|
+
children: rightLabel
|
|
187
|
+
}) : null]
|
|
188
|
+
}), bottomLabel ? jsx("label", {
|
|
189
|
+
htmlFor: switchId,
|
|
190
|
+
className: labelOpacityClass,
|
|
191
|
+
children: bottomLabel
|
|
192
|
+
}) : null, name ? jsx("input", {
|
|
193
|
+
type: "checkbox",
|
|
194
|
+
name: name,
|
|
195
|
+
readOnly: true,
|
|
196
|
+
"aria-hidden": true,
|
|
197
|
+
tabIndex: -1,
|
|
198
|
+
value: isOn ? "on" : "off",
|
|
199
|
+
checked: isOn,
|
|
200
|
+
onChange: function onChange() {},
|
|
201
|
+
className: "hidden"
|
|
202
|
+
}) : null]
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
Switch.displayName = "Switch";
|
|
206
|
+
|
|
207
|
+
export { Switch as default };
|