@dreamtree-org/twreact-ui 1.2.1 → 1.3.1

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.
Files changed (215) hide show
  1. package/DESIGN.md +118 -0
  2. package/README.md +231 -44
  3. package/ai-skills/dreamtree-ui.md +98 -12
  4. package/dist/ai-schema.json +452 -17
  5. package/dist/components/blocks/AppShell.d.ts +4 -0
  6. package/dist/components/blocks/AppShell.d.ts.map +1 -0
  7. package/dist/components/blocks/ConfirmDialog.d.ts +4 -0
  8. package/dist/components/blocks/ConfirmDialog.d.ts.map +1 -0
  9. package/dist/components/blocks/EmptyState.d.ts +4 -0
  10. package/dist/components/blocks/EmptyState.d.ts.map +1 -0
  11. package/dist/components/blocks/ErrorState.d.ts +4 -0
  12. package/dist/components/blocks/ErrorState.d.ts.map +1 -0
  13. package/dist/components/blocks/LoadingState.d.ts +9 -0
  14. package/dist/components/blocks/LoadingState.d.ts.map +1 -0
  15. package/dist/components/blocks/PageHeader.d.ts +4 -0
  16. package/dist/components/blocks/PageHeader.d.ts.map +1 -0
  17. package/dist/components/blocks/StatCard.d.ts +4 -0
  18. package/dist/components/blocks/StatCard.d.ts.map +1 -0
  19. package/dist/components/blocks/StatusPill.d.ts +5 -0
  20. package/dist/components/blocks/StatusPill.d.ts.map +1 -0
  21. package/dist/components/core/Accordion.d.ts.map +1 -1
  22. package/dist/components/core/Button.d.ts.map +1 -1
  23. package/dist/components/core/Checkbox.d.ts.map +1 -1
  24. package/dist/components/core/ColorPicker.d.ts.map +1 -1
  25. package/dist/components/core/DatePicker.d.ts.map +1 -1
  26. package/dist/components/core/DateRangePicker.d.ts.map +1 -1
  27. package/dist/components/core/Form.d.ts.map +1 -1
  28. package/dist/components/core/Input.d.ts.map +1 -1
  29. package/dist/components/core/LocationPicker.d.ts.map +1 -1
  30. package/dist/components/core/Popover.d.ts +4 -0
  31. package/dist/components/core/Popover.d.ts.map +1 -0
  32. package/dist/components/core/PriceRangePicker.d.ts.map +1 -1
  33. package/dist/components/core/ProgressBar.d.ts.map +1 -1
  34. package/dist/components/core/Radio.d.ts.map +1 -1
  35. package/dist/components/core/Rate.d.ts.map +1 -1
  36. package/dist/components/core/Select.d.ts.map +1 -1
  37. package/dist/components/core/Skeleton.d.ts.map +1 -1
  38. package/dist/components/core/Slider.d.ts +4 -0
  39. package/dist/components/core/Slider.d.ts.map +1 -0
  40. package/dist/components/core/SpeechToText.d.ts.map +1 -1
  41. package/dist/components/core/Switch.d.ts.map +1 -1
  42. package/dist/components/core/Table/ActionMenu.d.ts.map +1 -1
  43. package/dist/components/core/Table/ColumnMenu.d.ts +2 -1
  44. package/dist/components/core/Table/ColumnMenu.d.ts.map +1 -1
  45. package/dist/components/core/Table/MobileCard.d.ts +2 -2
  46. package/dist/components/core/Table/MobileCard.d.ts.map +1 -1
  47. package/dist/components/core/Table/Table.d.ts.map +1 -1
  48. package/dist/components/core/Table/TableRow.d.ts +4 -2
  49. package/dist/components/core/Table/TableRow.d.ts.map +1 -1
  50. package/dist/components/core/Tabs.d.ts.map +1 -1
  51. package/dist/components/core/Textarea.d.ts +4 -0
  52. package/dist/components/core/Textarea.d.ts.map +1 -0
  53. package/dist/components/core/ThreeDotPopover.d.ts.map +1 -1
  54. package/dist/components/core/Tooltip.d.ts.map +1 -1
  55. package/dist/components/feedback/Dialog.d.ts.map +1 -1
  56. package/dist/components/feedback/Drawer.d.ts +4 -0
  57. package/dist/components/feedback/Drawer.d.ts.map +1 -0
  58. package/dist/components/feedback/Toast.d.ts +14 -5
  59. package/dist/components/feedback/Toast.d.ts.map +1 -1
  60. package/dist/components/feedback/Tour.d.ts +4 -0
  61. package/dist/components/feedback/Tour.d.ts.map +1 -0
  62. package/dist/components/feedback/TourSpotlight.d.ts +9 -0
  63. package/dist/components/feedback/TourSpotlight.d.ts.map +1 -0
  64. package/dist/components/navigation/Breadcrumbs.d.ts.map +1 -1
  65. package/dist/components/navigation/FootNav.d.ts.map +1 -1
  66. package/dist/components/navigation/Navbar.d.ts.map +1 -1
  67. package/dist/components/navigation/Sidebar.d.ts +8 -2
  68. package/dist/components/navigation/Sidebar.d.ts.map +1 -1
  69. package/dist/components/utility/Badge.d.ts.map +1 -1
  70. package/dist/components/utility/FileUpload.d.ts.map +1 -1
  71. package/dist/components/utility/Sortable.d.ts +4 -0
  72. package/dist/components/utility/Sortable.d.ts.map +1 -0
  73. package/dist/esm/_vendor/object-assign/index.js +99 -0
  74. package/dist/esm/_vendor/prop-types/_vendor/react-is/cjs/react-is.development.js +190 -0
  75. package/dist/esm/_vendor/prop-types/_vendor/react-is/cjs/react-is.production.min.js +26 -0
  76. package/dist/esm/_vendor/prop-types/_vendor/react-is/index.js +19 -0
  77. package/dist/esm/_vendor/prop-types/checkPropTypes.js +115 -0
  78. package/dist/esm/_vendor/prop-types/factoryWithThrowingShims.js +74 -0
  79. package/dist/esm/_vendor/prop-types/factoryWithTypeCheckers.js +625 -0
  80. package/dist/esm/_vendor/prop-types/index.js +30 -0
  81. package/dist/esm/_vendor/prop-types/lib/ReactPropTypesSecret.js +21 -0
  82. package/dist/esm/_vendor/prop-types/lib/has.js +11 -0
  83. package/dist/esm/_virtual/_commonjsHelpers.js +5 -0
  84. package/dist/esm/_virtual/_rollupPluginBabelHelpers.js +329 -0
  85. package/dist/esm/_virtual/index.js +3 -0
  86. package/dist/esm/_virtual/index2.js +3 -0
  87. package/dist/esm/_virtual/react-is.development.js +3 -0
  88. package/dist/esm/_virtual/react-is.production.min.js +3 -0
  89. package/dist/esm/components/blocks/AppShell.js +205 -0
  90. package/dist/esm/components/blocks/ConfirmDialog.js +57 -0
  91. package/dist/esm/components/blocks/EmptyState.js +44 -0
  92. package/dist/esm/components/blocks/ErrorState.js +53 -0
  93. package/dist/esm/components/blocks/LoadingState.js +134 -0
  94. package/dist/esm/components/blocks/PageHeader.js +51 -0
  95. package/dist/esm/components/blocks/StatCard.js +79 -0
  96. package/dist/esm/components/blocks/StatusPill.js +55 -0
  97. package/dist/esm/components/core/Accordion.js +260 -0
  98. package/dist/esm/components/core/Button.js +59 -0
  99. package/dist/esm/components/core/Checkbox.js +188 -0
  100. package/dist/esm/components/core/ColorPicker.js +348 -0
  101. package/dist/esm/components/core/DatePicker.js +436 -0
  102. package/dist/esm/components/core/DateRangePicker.js +494 -0
  103. package/dist/esm/components/core/Form.js +522 -0
  104. package/dist/esm/components/core/Input.js +179 -0
  105. package/dist/esm/components/core/Loader.js +141 -0
  106. package/dist/esm/components/core/LocationPicker.js +161 -0
  107. package/dist/esm/components/core/Popover.js +171 -0
  108. package/dist/esm/components/core/PriceRangePicker.js +376 -0
  109. package/dist/esm/components/core/ProgressBar.js +152 -0
  110. package/dist/esm/components/core/Radio.js +156 -0
  111. package/dist/esm/components/core/Rate.js +197 -0
  112. package/dist/esm/components/core/RoundedTag.js +118 -0
  113. package/dist/esm/components/core/Select.js +857 -0
  114. package/dist/esm/components/core/Skeleton.js +100 -0
  115. package/dist/esm/components/core/Slider.js +134 -0
  116. package/dist/esm/components/core/SpeechToText.js +226 -0
  117. package/dist/esm/components/core/Switch.js +207 -0
  118. package/dist/esm/components/core/Table/ActionMenu.js +251 -0
  119. package/dist/esm/components/core/Table/ColumnMenu.js +55 -0
  120. package/dist/esm/components/core/Table/FieldInput.js +157 -0
  121. package/dist/esm/components/core/Table/MobileCard.js +187 -0
  122. package/dist/esm/components/core/Table/MobileFilters.js +72 -0
  123. package/dist/esm/components/core/Table/Pagination.js +157 -0
  124. package/dist/esm/components/core/Table/Table.js +1533 -0
  125. package/dist/esm/components/core/Table/TableRow.js +254 -0
  126. package/dist/esm/components/core/Table/constants.js +35 -0
  127. package/dist/esm/components/core/Table/helpers.js +124 -0
  128. package/dist/esm/components/core/Table/useClickOutside.js +26 -0
  129. package/dist/esm/components/core/Tabs.js +289 -0
  130. package/dist/esm/components/core/TextToSpeech.js +52 -0
  131. package/dist/esm/components/core/Textarea.js +125 -0
  132. package/dist/esm/components/core/ThreeDotPopover.js +160 -0
  133. package/dist/esm/components/core/Tooltip.js +372 -0
  134. package/dist/esm/components/feedback/Alert.js +96 -0
  135. package/dist/esm/components/feedback/Dialog.js +200 -0
  136. package/dist/esm/components/feedback/Drawer.js +171 -0
  137. package/dist/esm/components/feedback/Toast.js +362 -0
  138. package/dist/esm/components/feedback/Tour.js +214 -0
  139. package/dist/esm/components/feedback/TourSpotlight.js +71 -0
  140. package/dist/esm/components/navigation/Breadcrumbs.js +75 -0
  141. package/dist/esm/components/navigation/Dropdown.js +53 -0
  142. package/dist/esm/components/navigation/FootNav.js +51 -0
  143. package/dist/esm/components/navigation/Navbar.js +437 -0
  144. package/dist/esm/components/navigation/Sidebar.js +567 -0
  145. package/dist/esm/components/utility/Avatar.js +89 -0
  146. package/dist/esm/components/utility/Badge.js +47 -0
  147. package/dist/esm/components/utility/Card.js +85 -0
  148. package/dist/esm/components/utility/Carousel.js +97 -0
  149. package/dist/esm/components/utility/Condition.js +9 -0
  150. package/dist/esm/components/utility/FileUpload.js +177 -0
  151. package/dist/esm/components/utility/Pagination.js +111 -0
  152. package/dist/esm/components/utility/Sortable.js +190 -0
  153. package/dist/esm/components/utility/Stepper.js +101 -0
  154. package/dist/esm/hooks/useApi.js +169 -0
  155. package/dist/esm/hooks/useControllableState.js +32 -0
  156. package/dist/esm/hooks/useFocusTrap.js +85 -0
  157. package/dist/esm/hooks/useLatestRef.js +20 -0
  158. package/dist/esm/hooks/useMixins.js +100 -0
  159. package/dist/esm/hooks/useScrollLock.js +26 -0
  160. package/dist/esm/hooks/useSliderValues.js +135 -0
  161. package/dist/esm/hooks/useSortable.js +188 -0
  162. package/dist/esm/hooks/useTheme.js +53 -0
  163. package/dist/esm/hooks/useTourTarget.js +92 -0
  164. package/dist/esm/index.js +65 -0
  165. package/dist/esm/store/index.js +26 -0
  166. package/dist/esm/store/store.js +107 -0
  167. package/dist/esm/store/storeSlice.js +45 -0
  168. package/dist/esm/utils/cn.js +11 -0
  169. package/dist/esm/utils/emitter.js +169 -0
  170. package/dist/esm/utils/helpers.js +161 -0
  171. package/dist/esm/utils/position.js +134 -0
  172. package/dist/hooks/useApi.d.ts +2 -1
  173. package/dist/hooks/useApi.d.ts.map +1 -1
  174. package/dist/hooks/useControllableState.d.ts +11 -0
  175. package/dist/hooks/useControllableState.d.ts.map +1 -0
  176. package/dist/hooks/useFocusTrap.d.ts +15 -0
  177. package/dist/hooks/useFocusTrap.d.ts.map +1 -0
  178. package/dist/hooks/useLatestRef.d.ts +8 -0
  179. package/dist/hooks/useLatestRef.d.ts.map +1 -0
  180. package/dist/hooks/useMixins.d.ts.map +1 -1
  181. package/dist/hooks/useScrollLock.d.ts +2 -0
  182. package/dist/hooks/useScrollLock.d.ts.map +1 -0
  183. package/dist/hooks/useSliderValues.d.ts +43 -0
  184. package/dist/hooks/useSliderValues.d.ts.map +1 -0
  185. package/dist/hooks/useSortable.d.ts +32 -0
  186. package/dist/hooks/useSortable.d.ts.map +1 -0
  187. package/dist/hooks/useTheme.d.ts.map +1 -1
  188. package/dist/hooks/useTourTarget.d.ts +15 -0
  189. package/dist/hooks/useTourTarget.d.ts.map +1 -0
  190. package/dist/index.css +1 -1
  191. package/dist/index.d.ts +55 -39
  192. package/dist/index.esm.css +1 -1
  193. package/dist/index.esm.js +7937 -4659
  194. package/dist/index.js +7950 -4657
  195. package/dist/tokens/brands/default.css +1 -0
  196. package/dist/tokens/brands/default.json +5 -0
  197. package/dist/tokens/brands/practicepro.css +17 -0
  198. package/dist/tokens/brands/practicepro.json +27 -0
  199. package/dist/tokens/tailwind3-preset.cjs +214 -0
  200. package/dist/tokens/theme.css +193 -0
  201. package/dist/tokens/tokens.json +373 -0
  202. package/dist/tokens/vars.css +98 -0
  203. package/dist/types/blocks.d.ts +109 -0
  204. package/dist/types/blocks.d.ts.map +1 -0
  205. package/dist/types/index.d.ts +194 -5
  206. package/dist/types/index.d.ts.map +1 -1
  207. package/dist/utils/position.d.ts +30 -0
  208. package/dist/utils/position.d.ts.map +1 -0
  209. package/doc/README.md +26 -1
  210. package/mcp/catalog.snapshot.json +1643 -549
  211. package/package.json +24 -6
  212. package/tokens/brands/default.json +5 -0
  213. package/tokens/brands/practicepro.json +27 -0
  214. package/tokens/lib.cjs +128 -0
  215. package/tokens/tokens.json +133 -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 };