@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.
Files changed (234) hide show
  1. package/DESIGN.md +2 -2
  2. package/README.md +258 -10
  3. package/ai-skills/dreamtree-ui.md +111 -15
  4. package/charts/package.json +5 -0
  5. package/dist/_shared/cn-DPPQUJu1.js +138 -0
  6. package/dist/ai-schema.json +1252 -179
  7. package/dist/charts/index.d.ts +9 -0
  8. package/dist/charts/index.d.ts.map +1 -0
  9. package/dist/charts/index.js +769 -0
  10. package/dist/components/charts/AreaChart.d.ts +4 -0
  11. package/dist/components/charts/AreaChart.d.ts.map +1 -0
  12. package/dist/components/charts/BarChart.d.ts +4 -0
  13. package/dist/components/charts/BarChart.d.ts.map +1 -0
  14. package/dist/components/charts/CartesianChart.d.ts +5 -0
  15. package/dist/components/charts/CartesianChart.d.ts.map +1 -0
  16. package/dist/components/charts/ChartFrame.d.ts +18 -0
  17. package/dist/components/charts/ChartFrame.d.ts.map +1 -0
  18. package/dist/components/charts/DonutChart.d.ts +4 -0
  19. package/dist/components/charts/DonutChart.d.ts.map +1 -0
  20. package/dist/components/charts/LineChart.d.ts +4 -0
  21. package/dist/components/charts/LineChart.d.ts.map +1 -0
  22. package/dist/components/charts/Sparkline.d.ts +5 -0
  23. package/dist/components/charts/Sparkline.d.ts.map +1 -0
  24. package/dist/components/charts/chartTheme.d.ts +26 -0
  25. package/dist/components/charts/chartTheme.d.ts.map +1 -0
  26. package/dist/components/core/Accordion.d.ts.map +1 -1
  27. package/dist/components/core/Button.d.ts.map +1 -1
  28. package/dist/components/core/Checkbox.d.ts.map +1 -1
  29. package/dist/components/core/ColorPicker.d.ts.map +1 -1
  30. package/dist/components/core/DatePicker.d.ts.map +1 -1
  31. package/dist/components/core/DateRangePicker.d.ts.map +1 -1
  32. package/dist/components/core/Form.d.ts.map +1 -1
  33. package/dist/components/core/Input.d.ts.map +1 -1
  34. package/dist/components/core/LocationPicker.d.ts.map +1 -1
  35. package/dist/components/core/Popover.d.ts +4 -0
  36. package/dist/components/core/Popover.d.ts.map +1 -0
  37. package/dist/components/core/PriceRangePicker.d.ts.map +1 -1
  38. package/dist/components/core/ProgressBar.d.ts.map +1 -1
  39. package/dist/components/core/Radio.d.ts.map +1 -1
  40. package/dist/components/core/Rate.d.ts.map +1 -1
  41. package/dist/components/core/Select.d.ts.map +1 -1
  42. package/dist/components/core/Skeleton.d.ts.map +1 -1
  43. package/dist/components/core/Slider.d.ts +4 -0
  44. package/dist/components/core/Slider.d.ts.map +1 -0
  45. package/dist/components/core/SpeechToText.d.ts.map +1 -1
  46. package/dist/components/core/Switch.d.ts.map +1 -1
  47. package/dist/components/core/Table/ActionMenu.d.ts.map +1 -1
  48. package/dist/components/core/Table/ColumnMenu.d.ts +2 -1
  49. package/dist/components/core/Table/ColumnMenu.d.ts.map +1 -1
  50. package/dist/components/core/Table/MobileCard.d.ts +2 -2
  51. package/dist/components/core/Table/MobileCard.d.ts.map +1 -1
  52. package/dist/components/core/Table/Table.d.ts.map +1 -1
  53. package/dist/components/core/Table/TableRow.d.ts +4 -2
  54. package/dist/components/core/Table/TableRow.d.ts.map +1 -1
  55. package/dist/components/core/Tabs.d.ts.map +1 -1
  56. package/dist/components/core/Textarea.d.ts +4 -0
  57. package/dist/components/core/Textarea.d.ts.map +1 -0
  58. package/dist/components/core/ThreeDotPopover.d.ts.map +1 -1
  59. package/dist/components/core/Tooltip.d.ts.map +1 -1
  60. package/dist/components/feedback/Dialog.d.ts.map +1 -1
  61. package/dist/components/feedback/Drawer.d.ts +4 -0
  62. package/dist/components/feedback/Drawer.d.ts.map +1 -0
  63. package/dist/components/feedback/Toast.d.ts +14 -5
  64. package/dist/components/feedback/Toast.d.ts.map +1 -1
  65. package/dist/components/feedback/Tour.d.ts +4 -0
  66. package/dist/components/feedback/Tour.d.ts.map +1 -0
  67. package/dist/components/feedback/TourSpotlight.d.ts +9 -0
  68. package/dist/components/feedback/TourSpotlight.d.ts.map +1 -0
  69. package/dist/components/navigation/Breadcrumbs.d.ts.map +1 -1
  70. package/dist/components/navigation/FootNav.d.ts.map +1 -1
  71. package/dist/components/navigation/Navbar.d.ts.map +1 -1
  72. package/dist/components/navigation/Sidebar.d.ts +8 -2
  73. package/dist/components/navigation/Sidebar.d.ts.map +1 -1
  74. package/dist/components/rich-text/RichTextEditor.d.ts +4 -0
  75. package/dist/components/rich-text/RichTextEditor.d.ts.map +1 -0
  76. package/dist/components/rich-text/RichTextToolbar.d.ts +219 -0
  77. package/dist/components/rich-text/RichTextToolbar.d.ts.map +1 -0
  78. package/dist/components/utility/Badge.d.ts.map +1 -1
  79. package/dist/components/utility/FileUpload.d.ts.map +1 -1
  80. package/dist/components/utility/Sortable.d.ts +4 -0
  81. package/dist/components/utility/Sortable.d.ts.map +1 -0
  82. package/dist/esm/_vendor/object-assign/index.js +99 -0
  83. package/dist/esm/_vendor/prop-types/_vendor/react-is/cjs/react-is.development.js +190 -0
  84. package/dist/esm/_vendor/prop-types/_vendor/react-is/cjs/react-is.production.min.js +26 -0
  85. package/dist/esm/_vendor/prop-types/_vendor/react-is/index.js +19 -0
  86. package/dist/esm/_vendor/prop-types/checkPropTypes.js +115 -0
  87. package/dist/esm/_vendor/prop-types/factoryWithThrowingShims.js +74 -0
  88. package/dist/esm/_vendor/prop-types/factoryWithTypeCheckers.js +625 -0
  89. package/dist/esm/_vendor/prop-types/index.js +30 -0
  90. package/dist/esm/_vendor/prop-types/lib/ReactPropTypesSecret.js +21 -0
  91. package/dist/esm/_vendor/prop-types/lib/has.js +11 -0
  92. package/dist/esm/_virtual/_commonjsHelpers.js +5 -0
  93. package/dist/esm/_virtual/_rollupPluginBabelHelpers.js +329 -0
  94. package/dist/esm/_virtual/index.js +3 -0
  95. package/dist/esm/_virtual/index2.js +3 -0
  96. package/dist/esm/_virtual/react-is.development.js +3 -0
  97. package/dist/esm/_virtual/react-is.production.min.js +3 -0
  98. package/dist/esm/charts/index.js +5 -0
  99. package/dist/esm/components/blocks/AppShell.js +205 -0
  100. package/dist/esm/components/blocks/ConfirmDialog.js +57 -0
  101. package/dist/esm/components/blocks/EmptyState.js +44 -0
  102. package/dist/esm/components/blocks/ErrorState.js +53 -0
  103. package/dist/esm/components/blocks/LoadingState.js +134 -0
  104. package/dist/esm/components/blocks/PageHeader.js +51 -0
  105. package/dist/esm/components/blocks/StatCard.js +79 -0
  106. package/dist/esm/components/blocks/StatusPill.js +55 -0
  107. package/dist/esm/components/charts/AreaChart.js +16 -0
  108. package/dist/esm/components/charts/BarChart.js +16 -0
  109. package/dist/esm/components/charts/CartesianChart.js +250 -0
  110. package/dist/esm/components/charts/ChartFrame.js +170 -0
  111. package/dist/esm/components/charts/DonutChart.js +119 -0
  112. package/dist/esm/components/charts/LineChart.js +16 -0
  113. package/dist/esm/components/charts/Sparkline.js +110 -0
  114. package/dist/esm/components/charts/chartTheme.js +109 -0
  115. package/dist/esm/components/core/Accordion.js +260 -0
  116. package/dist/esm/components/core/Button.js +59 -0
  117. package/dist/esm/components/core/Checkbox.js +188 -0
  118. package/dist/esm/components/core/ColorPicker.js +348 -0
  119. package/dist/esm/components/core/DatePicker.js +436 -0
  120. package/dist/esm/components/core/DateRangePicker.js +494 -0
  121. package/dist/esm/components/core/Form.js +522 -0
  122. package/dist/esm/components/core/Input.js +179 -0
  123. package/dist/esm/components/core/Loader.js +141 -0
  124. package/dist/esm/components/core/LocationPicker.js +161 -0
  125. package/dist/esm/components/core/Popover.js +171 -0
  126. package/dist/esm/components/core/PriceRangePicker.js +376 -0
  127. package/dist/esm/components/core/ProgressBar.js +152 -0
  128. package/dist/esm/components/core/Radio.js +156 -0
  129. package/dist/esm/components/core/Rate.js +197 -0
  130. package/dist/esm/components/core/RoundedTag.js +118 -0
  131. package/dist/esm/components/core/Select.js +857 -0
  132. package/dist/esm/components/core/Skeleton.js +100 -0
  133. package/dist/esm/components/core/Slider.js +134 -0
  134. package/dist/esm/components/core/SpeechToText.js +226 -0
  135. package/dist/esm/components/core/Switch.js +207 -0
  136. package/dist/esm/components/core/Table/ActionMenu.js +251 -0
  137. package/dist/esm/components/core/Table/ColumnMenu.js +55 -0
  138. package/dist/esm/components/core/Table/FieldInput.js +157 -0
  139. package/dist/esm/components/core/Table/MobileCard.js +187 -0
  140. package/dist/esm/components/core/Table/MobileFilters.js +72 -0
  141. package/dist/esm/components/core/Table/Pagination.js +157 -0
  142. package/dist/esm/components/core/Table/Table.js +1533 -0
  143. package/dist/esm/components/core/Table/TableRow.js +254 -0
  144. package/dist/esm/components/core/Table/constants.js +35 -0
  145. package/dist/esm/components/core/Table/helpers.js +124 -0
  146. package/dist/esm/components/core/Table/useClickOutside.js +26 -0
  147. package/dist/esm/components/core/Tabs.js +289 -0
  148. package/dist/esm/components/core/TextToSpeech.js +52 -0
  149. package/dist/esm/components/core/Textarea.js +125 -0
  150. package/dist/esm/components/core/ThreeDotPopover.js +160 -0
  151. package/dist/esm/components/core/Tooltip.js +372 -0
  152. package/dist/esm/components/feedback/Alert.js +96 -0
  153. package/dist/esm/components/feedback/Dialog.js +200 -0
  154. package/dist/esm/components/feedback/Drawer.js +171 -0
  155. package/dist/esm/components/feedback/Toast.js +362 -0
  156. package/dist/esm/components/feedback/Tour.js +214 -0
  157. package/dist/esm/components/feedback/TourSpotlight.js +71 -0
  158. package/dist/esm/components/navigation/Breadcrumbs.js +75 -0
  159. package/dist/esm/components/navigation/Dropdown.js +53 -0
  160. package/dist/esm/components/navigation/FootNav.js +51 -0
  161. package/dist/esm/components/navigation/Navbar.js +437 -0
  162. package/dist/esm/components/navigation/Sidebar.js +567 -0
  163. package/dist/esm/components/rich-text/RichTextEditor.js +244 -0
  164. package/dist/esm/components/rich-text/RichTextToolbar.js +397 -0
  165. package/dist/esm/components/utility/Avatar.js +89 -0
  166. package/dist/esm/components/utility/Badge.js +47 -0
  167. package/dist/esm/components/utility/Card.js +85 -0
  168. package/dist/esm/components/utility/Carousel.js +97 -0
  169. package/dist/esm/components/utility/Condition.js +9 -0
  170. package/dist/esm/components/utility/FileUpload.js +177 -0
  171. package/dist/esm/components/utility/Pagination.js +111 -0
  172. package/dist/esm/components/utility/Sortable.js +190 -0
  173. package/dist/esm/components/utility/Stepper.js +101 -0
  174. package/dist/esm/hooks/useApi.js +169 -0
  175. package/dist/esm/hooks/useControllableState.js +32 -0
  176. package/dist/esm/hooks/useFocusTrap.js +85 -0
  177. package/dist/esm/hooks/useLatestRef.js +20 -0
  178. package/dist/esm/hooks/useMixins.js +100 -0
  179. package/dist/esm/hooks/useScrollLock.js +26 -0
  180. package/dist/esm/hooks/useSliderValues.js +135 -0
  181. package/dist/esm/hooks/useSortable.js +188 -0
  182. package/dist/esm/hooks/useTheme.js +53 -0
  183. package/dist/esm/hooks/useTourTarget.js +92 -0
  184. package/dist/esm/index.js +65 -0
  185. package/dist/esm/rich-text/index.js +1 -0
  186. package/dist/esm/store/index.js +26 -0
  187. package/dist/esm/store/store.js +107 -0
  188. package/dist/esm/store/storeSlice.js +45 -0
  189. package/dist/esm/utils/cn.js +11 -0
  190. package/dist/esm/utils/emitter.js +169 -0
  191. package/dist/esm/utils/helpers.js +161 -0
  192. package/dist/esm/utils/position.js +134 -0
  193. package/dist/hooks/useApi.d.ts +2 -1
  194. package/dist/hooks/useApi.d.ts.map +1 -1
  195. package/dist/hooks/useControllableState.d.ts +11 -0
  196. package/dist/hooks/useControllableState.d.ts.map +1 -0
  197. package/dist/hooks/useFocusTrap.d.ts +15 -0
  198. package/dist/hooks/useFocusTrap.d.ts.map +1 -0
  199. package/dist/hooks/useLatestRef.d.ts +8 -0
  200. package/dist/hooks/useLatestRef.d.ts.map +1 -0
  201. package/dist/hooks/useMixins.d.ts.map +1 -1
  202. package/dist/hooks/useScrollLock.d.ts +2 -0
  203. package/dist/hooks/useScrollLock.d.ts.map +1 -0
  204. package/dist/hooks/useSliderValues.d.ts +43 -0
  205. package/dist/hooks/useSliderValues.d.ts.map +1 -0
  206. package/dist/hooks/useSortable.d.ts +32 -0
  207. package/dist/hooks/useSortable.d.ts.map +1 -0
  208. package/dist/hooks/useTheme.d.ts.map +1 -1
  209. package/dist/hooks/useTourTarget.d.ts +15 -0
  210. package/dist/hooks/useTourTarget.d.ts.map +1 -0
  211. package/dist/index.css +1 -1
  212. package/dist/index.d.ts +8 -2
  213. package/dist/index.esm.css +1 -1
  214. package/dist/index.esm.js +4817 -2216
  215. package/dist/index.js +4822 -2214
  216. package/dist/rich-text/index.d.ts +5 -0
  217. package/dist/rich-text/index.d.ts.map +1 -0
  218. package/dist/rich-text/index.js +654 -0
  219. package/dist/tokens/brands/studio.css +14 -0
  220. package/dist/tokens/brands/studio.json +20 -0
  221. package/dist/types/charts.d.ts +97 -0
  222. package/dist/types/charts.d.ts.map +1 -0
  223. package/dist/types/index.d.ts +193 -5
  224. package/dist/types/index.d.ts.map +1 -1
  225. package/dist/types/rich-text.d.ts +50 -0
  226. package/dist/types/rich-text.d.ts.map +1 -0
  227. package/dist/utils/position.d.ts +30 -0
  228. package/dist/utils/position.d.ts.map +1 -0
  229. package/doc/README.md +20 -1
  230. package/mcp/catalog.snapshot.json +2505 -800
  231. package/mcp/server-core.mjs +30 -1
  232. package/package.json +51 -3
  233. package/rich-text/package.json +5 -0
  234. package/tokens/brands/studio.json +20 -0
@@ -0,0 +1,289 @@
1
+ 'use client';
2
+ import { objectWithoutProperties as _objectWithoutProperties, slicedToArray as _slicedToArray, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
3
+ import { jsx, jsxs } from 'react/jsx-runtime';
4
+ import React, { forwardRef, useState, useRef, useId, useEffect, createContext, useContext } from 'react';
5
+ import { cn } from '../../utils/cn.js';
6
+
7
+ var _excluded = ["children", "defaultIndex", "index", "onChange", "orientation", "size", "variant", "animated", "className"];
8
+ /*
9
+ Tabs.jsx
10
+ - Default export: Tabs (provider wrapper)
11
+ - Subcomponents attached: Tabs.List, Tabs.Tab, Tabs.Panels, Tabs.Panel
12
+
13
+ Features:
14
+ - Controlled / uncontrolled usage
15
+ - Keyboard navigation (Arrow keys, Home, End)
16
+ - ARIA attributes for accessibility
17
+ - Variants: "line" | "pills" | "unstyled"
18
+ - Sizes: "sm" | "md" | "lg"
19
+ - Simple fade animation
20
+ - Tailwind CSS only
21
+
22
+ Usage example (see bottom of file comment):
23
+ <Tabs defaultIndex={0} variant="pills" size="md">
24
+ <Tabs.List>
25
+ <Tabs.Tab>Home</Tabs.Tab>
26
+ <Tabs.Tab>Profile</Tabs.Tab>
27
+ <Tabs.Tab>Settings</Tabs.Tab>
28
+ </Tabs.List>
29
+ <Tabs.Panels>
30
+ <Tabs.Panel>Home content</Tabs.Panel>
31
+ <Tabs.Panel>Profile content</Tabs.Panel>
32
+ <Tabs.Panel>Settings content</Tabs.Panel>
33
+ </Tabs.Panels>
34
+ </Tabs>
35
+ */
36
+ var TabsContext = /*#__PURE__*/createContext(null);
37
+ // One useId() per Tabs keeps ids stable across SSR and unique per instance (STUDIO-58).
38
+ var tabId = function tabId(baseId, index) {
39
+ return "".concat(baseId, "-tab-").concat(index);
40
+ };
41
+ var panelId = function panelId(baseId, index) {
42
+ return "".concat(baseId, "-panel-").concat(index);
43
+ };
44
+ function useTabsContext(componentName) {
45
+ var ctx = useContext(TabsContext);
46
+ if (!ctx) throw new Error("".concat(componentName, " must be used inside <Tabs>"));
47
+ return ctx;
48
+ }
49
+ var Tabs = /*#__PURE__*/forwardRef(function Tabs(_ref, ref) {
50
+ var children = _ref.children,
51
+ _ref$defaultIndex = _ref.defaultIndex,
52
+ defaultIndex = _ref$defaultIndex === void 0 ? 0 : _ref$defaultIndex,
53
+ controlledIndex = _ref.index,
54
+ onChange = _ref.onChange,
55
+ _ref$orientation = _ref.orientation,
56
+ orientation = _ref$orientation === void 0 ? "horizontal" : _ref$orientation,
57
+ _ref$size = _ref.size,
58
+ size = _ref$size === void 0 ? "md" : _ref$size,
59
+ _ref$variant = _ref.variant,
60
+ variant = _ref$variant === void 0 ? "line" : _ref$variant,
61
+ _ref$animated = _ref.animated,
62
+ animated = _ref$animated === void 0 ? true : _ref$animated,
63
+ _ref$className = _ref.className,
64
+ className = _ref$className === void 0 ? "" : _ref$className,
65
+ rest = _objectWithoutProperties(_ref, _excluded);
66
+ var isControlled = controlledIndex != null;
67
+ var _useState = useState(defaultIndex),
68
+ _useState2 = _slicedToArray(_useState, 2),
69
+ internalIndex = _useState2[0],
70
+ setActiveIndex = _useState2[1];
71
+ var activeIndex = isControlled ? controlledIndex : internalIndex;
72
+ var tabsRef = useRef([]); // DOM refs for keyboard navigation
73
+ var baseId = useId();
74
+ var changeTab = function changeTab(idx) {
75
+ if (!isControlled) setActiveIndex(idx);
76
+ onChange === null || onChange === void 0 || onChange(idx);
77
+ };
78
+ var registerTab = function registerTab(el, idx) {
79
+ tabsRef.current[idx] = el;
80
+ };
81
+ var value = {
82
+ activeIndex: activeIndex,
83
+ changeTab: changeTab,
84
+ registerTab: registerTab,
85
+ tabsRef: tabsRef,
86
+ baseId: baseId,
87
+ orientation: orientation,
88
+ size: size,
89
+ variant: variant,
90
+ animated: animated
91
+ };
92
+ return jsx(TabsContext.Provider, {
93
+ value: value,
94
+ children: jsx("div", _objectSpread2(_objectSpread2({
95
+ ref: ref,
96
+ className: cn("tabs-root", className)
97
+ }, rest), {}, {
98
+ children: children
99
+ }))
100
+ });
101
+ });
102
+ Tabs.displayName = "Tabs";
103
+ /* ------------------------- TabList ------------------------- */
104
+ function TabList(_ref2) {
105
+ var children = _ref2.children,
106
+ _ref2$className = _ref2.className,
107
+ className = _ref2$className === void 0 ? "" : _ref2$className;
108
+ var _useTabsContext = useTabsContext("Tabs.List"),
109
+ orientation = _useTabsContext.orientation;
110
+ return jsx("div", {
111
+ role: "tablist",
112
+ "aria-orientation": orientation,
113
+ className: "flex ".concat(orientation === "vertical" ? "flex-col" : "flex-row", " gap-1 ").concat(className),
114
+ children: React.Children.map(children, function (child, i) {
115
+ var _child$props$index;
116
+ if (! /*#__PURE__*/React.isValidElement(child)) return child;
117
+ return /*#__PURE__*/React.cloneElement(child, {
118
+ index: (_child$props$index = child.props.index) !== null && _child$props$index !== void 0 ? _child$props$index : i
119
+ });
120
+ })
121
+ });
122
+ }
123
+ /* ------------------------- Tab ------------------------- */
124
+ function Tab(_ref3) {
125
+ var children = _ref3.children,
126
+ index = _ref3.index,
127
+ _ref3$className = _ref3.className,
128
+ className = _ref3$className === void 0 ? "" : _ref3$className,
129
+ iconLeft = _ref3.iconLeft,
130
+ iconRight = _ref3.iconRight,
131
+ _ref3$disabled = _ref3.disabled,
132
+ disabled = _ref3$disabled === void 0 ? false : _ref3$disabled,
133
+ _ref3$tabClassName = _ref3.tabClassName,
134
+ tabClassName = _ref3$tabClassName === void 0 ? "" : _ref3$tabClassName;
135
+ var _useTabsContext2 = useTabsContext("Tab"),
136
+ activeIndex = _useTabsContext2.activeIndex,
137
+ changeTab = _useTabsContext2.changeTab,
138
+ registerTab = _useTabsContext2.registerTab,
139
+ tabsRef = _useTabsContext2.tabsRef,
140
+ baseId = _useTabsContext2.baseId,
141
+ size = _useTabsContext2.size,
142
+ variant = _useTabsContext2.variant;
143
+ var internalRef = useRef(null);
144
+ // If the user didn't provide `index` we derive from DOM position by registering nulls until mount.
145
+ // However it's recommended to always keep Tabs.Tab order consistent with Panels.
146
+ useEffect(function () {
147
+ // find index in tabsRef if index not provided
148
+ var idx = typeof index === "number" ? index : tabsRef.current.findIndex(function (el) {
149
+ return el === internalRef.current;
150
+ });
151
+ if (idx === -1) idx = tabsRef.current.length; // fallback
152
+ registerTab(internalRef.current, idx);
153
+ // ensure the tab has the correct array slot
154
+ }, []); // eslint-disable-line react-hooks/exhaustive-deps
155
+ // TabList always injects `index`; a Tab rendered outside it is never selected.
156
+ var idx = typeof index === "number" ? index : -1;
157
+ var selected = idx === activeIndex;
158
+ var id = tabId(baseId, idx);
159
+ var base = "inline-flex items-center gap-2 outline-none select-none";
160
+ var sizeClasses = {
161
+ sm: "px-2 py-1 text-sm",
162
+ md: "px-3 py-2 text-sm",
163
+ lg: "px-4 py-3 text-base"
164
+ };
165
+ var variantClasses = {
166
+ line: selected ? "border-b-2 border-primary-500" : "border-b-2 border-transparent hover:border-gray-200",
167
+ pills: selected ? "bg-primary-600 text-white rounded-full shadow-sm" : "bg-transparent rounded-full hover:bg-gray-100",
168
+ unstyled: ""
169
+ };
170
+ var computedClass = cn(base, sizeClasses[size] || sizeClasses.md, variantClasses[variant], tabClassName, className);
171
+ var focusNext = function focusNext(dir) {
172
+ if (!tabsRef.current || tabsRef.current.length === 0) return;
173
+ var next = idx + dir;
174
+ var len = tabsRef.current.length;
175
+ if (next < 0) next = len - 1;
176
+ if (next >= len) next = 0;
177
+ var el = tabsRef.current[next];
178
+ el === null || el === void 0 || el.focus();
179
+ changeTab(next);
180
+ };
181
+ var onKeyDown = function onKeyDown(e) {
182
+ if (disabled) return;
183
+ var key = e.key;
184
+ if (key === "Home") {
185
+ var _tabsRef$current$;
186
+ e.preventDefault();
187
+ (_tabsRef$current$ = tabsRef.current[0]) === null || _tabsRef$current$ === void 0 || _tabsRef$current$.focus();
188
+ changeTab(0);
189
+ } else if (key === "End") {
190
+ var _tabsRef$current$last;
191
+ e.preventDefault();
192
+ var last = tabsRef.current.length - 1;
193
+ (_tabsRef$current$last = tabsRef.current[last]) === null || _tabsRef$current$last === void 0 || _tabsRef$current$last.focus();
194
+ changeTab(last);
195
+ } else if (key === "ArrowRight") {
196
+ e.preventDefault();
197
+ focusNext(1);
198
+ } else if (key === "ArrowLeft") {
199
+ e.preventDefault();
200
+ focusNext(-1);
201
+ } else if (key === "ArrowDown") {
202
+ // for vertical lists treat Down like ArrowRight
203
+ e.preventDefault();
204
+ focusNext(1);
205
+ } else if (key === "ArrowUp") {
206
+ e.preventDefault();
207
+ focusNext(-1);
208
+ }
209
+ };
210
+ return jsxs("button", {
211
+ ref: internalRef,
212
+ id: id,
213
+ role: "tab",
214
+ "aria-selected": selected,
215
+ "aria-controls": selected ? panelId(baseId, idx) : undefined,
216
+ tabIndex: selected ? 0 : -1,
217
+ disabled: disabled,
218
+ className: computedClass,
219
+ onClick: function onClick() {
220
+ return !disabled && changeTab(idx);
221
+ },
222
+ onKeyDown: onKeyDown,
223
+ children: [iconLeft && jsx("span", {
224
+ className: "shrink-0",
225
+ children: iconLeft
226
+ }), jsx("span", {
227
+ children: children
228
+ }), iconRight && jsx("span", {
229
+ className: "shrink-0",
230
+ children: iconRight
231
+ })]
232
+ });
233
+ }
234
+ /* ------------------------- Panels & Panel ------------------------- */
235
+ function Panels(_ref4) {
236
+ var children = _ref4.children,
237
+ _ref4$className = _ref4.className,
238
+ className = _ref4$className === void 0 ? "" : _ref4$className;
239
+ var _useTabsContext3 = useTabsContext("Tabs.Panels"),
240
+ animated = _useTabsContext3.animated;
241
+ return jsx("div", {
242
+ className: "relative w-full ".concat(className),
243
+ children: React.Children.map(children, function (child, i) {
244
+ var _child$props$index2;
245
+ // inject index if missing
246
+ if (! /*#__PURE__*/React.isValidElement(child)) return child;
247
+ return /*#__PURE__*/React.cloneElement(child, {
248
+ index: (_child$props$index2 = child.props.index) !== null && _child$props$index2 !== void 0 ? _child$props$index2 : i,
249
+ animated: animated
250
+ });
251
+ })
252
+ });
253
+ }
254
+ function Panel(_ref5) {
255
+ var children = _ref5.children,
256
+ index = _ref5.index,
257
+ _ref5$className = _ref5.className,
258
+ className = _ref5$className === void 0 ? "" : _ref5$className,
259
+ _ref5$animated = _ref5.animated,
260
+ animated = _ref5$animated === void 0 ? true : _ref5$animated;
261
+ var _useTabsContext4 = useTabsContext("Tab.Panel"),
262
+ activeIndex = _useTabsContext4.activeIndex,
263
+ baseId = _useTabsContext4.baseId;
264
+ var isActive = index === activeIndex;
265
+ var _useState3 = useState(isActive),
266
+ _useState4 = _slicedToArray(_useState3, 2),
267
+ wasActive = _useState4[0],
268
+ setWasActive = _useState4[1];
269
+ // Remember that the panel has been shown once (adjust-during-render pattern).
270
+ if (isActive && !wasActive) setWasActive(true);
271
+ if (!wasActive && !isActive) return null;
272
+ var base = "w-full transition-all duration-200 ease-in-out";
273
+ var activeClasses = animated ? "opacity-100 translate-y-0 pointer-events-auto relative" : "opacity-100 pointer-events-auto relative";
274
+ var inactiveClasses = animated ? "opacity-0 -translate-y-2 pointer-events-none absolute inset-0" : "hidden pointer-events-none absolute inset-0";
275
+ return jsx("div", {
276
+ id: panelId(baseId, index),
277
+ role: "tabpanel",
278
+ "aria-labelledby": tabId(baseId, index),
279
+ hidden: !isActive,
280
+ className: "".concat(base, " ").concat(isActive ? activeClasses : inactiveClasses, " ").concat(className),
281
+ children: children
282
+ });
283
+ }
284
+ Tabs.List = TabList;
285
+ Tabs.Tab = Tab;
286
+ Tabs.Panels = Panels;
287
+ Tabs.Panel = Panel;
288
+
289
+ export { Panel, Panels, Tab, TabList, Tabs as default };
@@ -0,0 +1,52 @@
1
+ 'use client';
2
+ import { slicedToArray as _slicedToArray } from '../../_virtual/_rollupPluginBabelHelpers.js';
3
+ import { jsx } from 'react/jsx-runtime';
4
+ import { useState } from 'react';
5
+
6
+ var TextToSpeech = function TextToSpeech(_ref) {
7
+ var _ref$text = _ref.text,
8
+ text = _ref$text === void 0 ? "" : _ref$text,
9
+ _ref$rate = _ref.rate,
10
+ rate = _ref$rate === void 0 ? 1 : _ref$rate,
11
+ _ref$pitch = _ref.pitch,
12
+ pitch = _ref$pitch === void 0 ? 0.5 : _ref$pitch,
13
+ _ref$onSpeak = _ref.onSpeak,
14
+ onSpeak = _ref$onSpeak === void 0 ? function () {} : _ref$onSpeak,
15
+ renderButton = _ref.renderButton;
16
+ var _useState = useState(text),
17
+ _useState2 = _slicedToArray(_useState, 1),
18
+ inputText = _useState2[0];
19
+ var _useState3 = useState(false),
20
+ _useState4 = _slicedToArray(_useState3, 2),
21
+ isSpeaking = _useState4[0],
22
+ setIsSpeaking = _useState4[1];
23
+ var handleSpeak = function handleSpeak() {
24
+ var utterance = new SpeechSynthesisUtterance(inputText);
25
+ utterance.rate = rate;
26
+ utterance.pitch = pitch;
27
+ utterance.onstart = function () {
28
+ onSpeak(inputText);
29
+ setIsSpeaking(true);
30
+ };
31
+ utterance.onend = function () {
32
+ setIsSpeaking(false);
33
+ };
34
+ if (isSpeaking) {
35
+ window.speechSynthesis.cancel();
36
+ setIsSpeaking(false);
37
+ } else {
38
+ window.speechSynthesis.speak(utterance);
39
+ }
40
+ };
41
+ return jsx("div", {
42
+ children: renderButton && typeof renderButton === "function" ? renderButton({
43
+ onClick: handleSpeak,
44
+ isSpeaking: isSpeaking
45
+ }) : jsx("button", {
46
+ onClick: handleSpeak,
47
+ children: isSpeaking ? "Stop" : "Speak"
48
+ })
49
+ });
50
+ };
51
+
52
+ export { TextToSpeech as default };
@@ -0,0 +1,125 @@
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, useId, useRef, useCallback, useState, useLayoutEffect, useEffect } from 'react';
5
+ import { AlertCircle } from 'lucide-react';
6
+ import { cn } from '../../utils/cn.js';
7
+ import { setRefs } from '../../utils/position.js';
8
+
9
+ var _excluded = ["id", "className", "label", "error", "helperText", "required", "disabled", "showCount", "maxLength", "autoResize", "rows", "maxRows", "value", "defaultValue", "onChange"];
10
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
11
+ function fitToContent(el, maxRows) {
12
+ if (!el) return;
13
+ el.style.height = "auto";
14
+ var height = el.scrollHeight;
15
+ if (maxRows) {
16
+ var style = window.getComputedStyle(el);
17
+ var line = parseFloat(style.lineHeight) || 20;
18
+ var chrome = parseFloat(style.paddingTop || 0) + parseFloat(style.paddingBottom || 0) + parseFloat(style.borderTopWidth || 0) + parseFloat(style.borderBottomWidth || 0);
19
+ var cap = line * maxRows + chrome;
20
+ el.style.overflowY = height > cap ? "auto" : "hidden";
21
+ height = Math.min(height, cap);
22
+ } else {
23
+ el.style.overflowY = "hidden";
24
+ }
25
+ el.style.height = "".concat(height, "px");
26
+ }
27
+ var Textarea = /*#__PURE__*/forwardRef(function (_ref, forwardedRef) {
28
+ var id = _ref.id,
29
+ className = _ref.className,
30
+ label = _ref.label,
31
+ error = _ref.error,
32
+ helperText = _ref.helperText,
33
+ _ref$required = _ref.required,
34
+ required = _ref$required === void 0 ? false : _ref$required,
35
+ _ref$disabled = _ref.disabled,
36
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled,
37
+ _ref$showCount = _ref.showCount,
38
+ showCount = _ref$showCount === void 0 ? false : _ref$showCount,
39
+ maxLength = _ref.maxLength,
40
+ _ref$autoResize = _ref.autoResize,
41
+ autoResize = _ref$autoResize === void 0 ? false : _ref$autoResize,
42
+ _ref$rows = _ref.rows,
43
+ rows = _ref$rows === void 0 ? 3 : _ref$rows,
44
+ maxRows = _ref.maxRows,
45
+ value = _ref.value,
46
+ defaultValue = _ref.defaultValue,
47
+ onChange = _ref.onChange,
48
+ rest = _objectWithoutProperties(_ref, _excluded);
49
+ var reactId = useId();
50
+ var textareaId = id || "textarea-".concat(reactId);
51
+ var errorId = "".concat(textareaId, "-error");
52
+ var helperId = "".concat(textareaId, "-helper");
53
+ var localRef = useRef(null);
54
+ var setRef = useCallback(function (node) {
55
+ return setRefs(node, localRef, forwardedRef);
56
+ }, [forwardedRef]);
57
+ var isControlled = value !== undefined;
58
+ var _useState = useState(function () {
59
+ return String(defaultValue !== null && defaultValue !== void 0 ? defaultValue : "").length;
60
+ }),
61
+ _useState2 = _slicedToArray(_useState, 2),
62
+ uncontrolledLength = _useState2[0],
63
+ setUncontrolledLength = _useState2[1];
64
+ var length = isControlled ? String(value !== null && value !== void 0 ? value : "").length : uncontrolledLength;
65
+ useIsomorphicLayoutEffect(function () {
66
+ if (autoResize) fitToContent(localRef.current, maxRows);
67
+ }, [autoResize, maxRows, value]);
68
+ var handleChange = function handleChange(e) {
69
+ if (!isControlled) setUncontrolledLength(e.target.value.length);
70
+ if (autoResize) fitToContent(e.target, maxRows);
71
+ onChange === null || onChange === void 0 || onChange(e);
72
+ };
73
+ var describedBy = [error ? errorId : null, helperText ? helperId : null, rest["aria-describedby"]].filter(Boolean).join(" ") || undefined;
74
+ return jsxs("div", {
75
+ className: "w-full",
76
+ children: [label && jsxs("label", {
77
+ htmlFor: textareaId,
78
+ className: "mb-1 block text-sm font-medium text-gray-700 dark:text-gray-200",
79
+ children: [label, required && jsx("span", {
80
+ className: "ml-1 text-error-500",
81
+ "aria-hidden": "true",
82
+ children: "*"
83
+ })]
84
+ }), jsx("textarea", _objectSpread2(_objectSpread2({}, rest), {}, {
85
+ id: textareaId,
86
+ ref: setRef,
87
+ rows: rows,
88
+ required: required,
89
+ disabled: disabled,
90
+ maxLength: maxLength,
91
+ value: value,
92
+ defaultValue: defaultValue,
93
+ onChange: handleChange,
94
+ "aria-invalid": error ? true : undefined,
95
+ "aria-describedby": describedBy,
96
+ className: cn("block w-full rounded-md border bg-white px-3 py-2 text-sm text-gray-900 placeholder-gray-400", "focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500", "disabled:cursor-not-allowed disabled:opacity-50", "dark:bg-gray-900 dark:text-gray-100 dark:placeholder-gray-500 dark:focus:ring-offset-gray-900", error ? "border-error-500 focus:ring-error-500" : "border-gray-300 dark:border-gray-600", autoResize ? "resize-none" : "resize-y", className)
97
+ })), (error || helperText || showCount && maxLength) && jsxs("div", {
98
+ className: "mt-1 flex items-start justify-between gap-3 text-sm",
99
+ children: [jsxs("div", {
100
+ className: "min-w-0",
101
+ children: [error && jsxs("p", {
102
+ id: errorId,
103
+ className: "flex items-center gap-1 text-error-600 dark:text-error-400",
104
+ "aria-live": "polite",
105
+ children: [jsx(AlertCircle, {
106
+ className: "h-4 w-4 shrink-0",
107
+ "aria-hidden": "true"
108
+ }), error]
109
+ }), helperText && jsx("p", {
110
+ id: helperId,
111
+ className: "text-gray-500 dark:text-gray-400",
112
+ children: helperText
113
+ })]
114
+ }), showCount && maxLength && jsxs("span", {
115
+ className: "shrink-0 text-xs text-gray-500 dark:text-gray-400",
116
+ "aria-hidden": "true",
117
+ "data-testid": "textarea-count",
118
+ children: [length, "/", maxLength]
119
+ })]
120
+ })]
121
+ });
122
+ });
123
+ Textarea.displayName = "Textarea";
124
+
125
+ export { Textarea as default };
@@ -0,0 +1,160 @@
1
+ 'use client';
2
+ import { objectWithoutProperties as _objectWithoutProperties, slicedToArray as _slicedToArray, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
3
+ import { jsx, jsxs } from 'react/jsx-runtime';
4
+ import React, { forwardRef, useRef, useCallback, useState, useEffect } from 'react';
5
+ import { MoreVertical } from 'lucide-react';
6
+ import { cn } from '../../utils/cn.js';
7
+
8
+ var _excluded = ["items", "trigger", "className", "menuClass", "menuItemClass", "closeOnSelect", "ariaLabel", "wrapperClassName"];
9
+ /**
10
+ * ThreeDotPopover (Simple)
11
+ *
12
+ * A minimal three-dot popover for your UI library.
13
+ *
14
+ * Features (simple):
15
+ * - Minimal, single-file React component (no animation libs, no portals).
16
+ * - Click trigger toggles menu (default three-dot icon or custom trigger node).
17
+ * - Close on outside click and Escape key.
18
+ * - Menu items: { key, label, icon?, onClick?, disabled?, destructive? }.
19
+ *
20
+ * Props:
21
+ * - items: Array of menu item objects (see above)
22
+ * - trigger: optional React node to use as trigger (falls back to three-dot button)
23
+ * - className: additional class for trigger wrapper
24
+ * - menuClass: additional class for menu container
25
+ * - menuItemClass: additional class for every menu item
26
+ * - closeOnSelect: boolean (default true)
27
+ *
28
+ * Example:
29
+ * const items = [
30
+ * { key: 'edit', label: 'Edit', icon: Edit2, onClick: () => {} },
31
+ * { key: 'view', label: 'View', icon: Eye, onClick: () => {} },
32
+ * { key: 'delete', label: 'Delete', destructive: true, onClick: () => {} },
33
+ * ];
34
+ * <ThreeDotPopoverSimple items={items} />
35
+ */
36
+ var ThreeDotPopoverSimple = /*#__PURE__*/forwardRef(function ThreeDotPopoverSimple(_ref, ref) {
37
+ var _ref$items = _ref.items,
38
+ items = _ref$items === void 0 ? [] : _ref$items,
39
+ _ref$trigger = _ref.trigger,
40
+ trigger = _ref$trigger === void 0 ? null : _ref$trigger,
41
+ _ref$className = _ref.className,
42
+ className = _ref$className === void 0 ? "" : _ref$className,
43
+ _ref$menuClass = _ref.menuClass,
44
+ menuClass = _ref$menuClass === void 0 ? "" : _ref$menuClass,
45
+ _ref$menuItemClass = _ref.menuItemClass,
46
+ menuItemClass = _ref$menuItemClass === void 0 ? "" : _ref$menuItemClass,
47
+ _ref$closeOnSelect = _ref.closeOnSelect,
48
+ closeOnSelect = _ref$closeOnSelect === void 0 ? true : _ref$closeOnSelect,
49
+ _ref$ariaLabel = _ref.ariaLabel,
50
+ ariaLabel = _ref$ariaLabel === void 0 ? "More options" : _ref$ariaLabel,
51
+ _ref$wrapperClassName = _ref.wrapperClassName,
52
+ wrapperClassName = _ref$wrapperClassName === void 0 ? "" : _ref$wrapperClassName,
53
+ rest = _objectWithoutProperties(_ref, _excluded);
54
+ var triggerRef = useRef(null);
55
+ // Callback ref for a consumer-supplied trigger: handing a function (not the
56
+ // ref object) to cloneElement keeps ref access out of render.
57
+ var setTriggerNode = useCallback(function (node) {
58
+ triggerRef.current = node;
59
+ }, []);
60
+ var menuRef = useRef(null);
61
+ var _useState = useState(false),
62
+ _useState2 = _slicedToArray(_useState, 2),
63
+ open = _useState2[0],
64
+ setOpen = _useState2[1];
65
+ useEffect(function () {
66
+ function onDocClick(e) {
67
+ if (!open) return;
68
+ if (triggerRef.current && triggerRef.current.contains(e.target)) return;
69
+ if (menuRef.current && menuRef.current.contains(e.target)) return;
70
+ setOpen(false);
71
+ }
72
+ function onKey(e) {
73
+ if (!open) return;
74
+ if (e.key === "Escape") setOpen(false);
75
+ }
76
+ document.addEventListener("mousedown", onDocClick);
77
+ document.addEventListener("keydown", onKey);
78
+ return function () {
79
+ document.removeEventListener("mousedown", onDocClick);
80
+ document.removeEventListener("keydown", onKey);
81
+ };
82
+ }, [open]);
83
+ function toggleOpen(e) {
84
+ e && e.stopPropagation();
85
+ setOpen(function (v) {
86
+ return !v;
87
+ });
88
+ }
89
+ function handleItemClick(item) {
90
+ if (item.disabled) return;
91
+ item.onClick && item.onClick(item);
92
+ if (closeOnSelect) setOpen(false);
93
+ // natural focus behavior: return focus to trigger
94
+ triggerRef.current && triggerRef.current.focus();
95
+ }
96
+ var DefaultTrigger = jsx("button", {
97
+ type: "button",
98
+ "aria-label": ariaLabel,
99
+ "aria-expanded": open,
100
+ ref: triggerRef,
101
+ onClick: toggleOpen,
102
+ className: cn("inline-flex items-center justify-center rounded-md focus:outline-none", className),
103
+ children: jsx(MoreVertical, {})
104
+ });
105
+ var triggerNode = trigger ?
106
+ /*#__PURE__*/
107
+ // eslint-disable-next-line react-hooks/refs -- setTriggerNode is a callback ref, run by React at commit
108
+ React.cloneElement(trigger, {
109
+ ref: setTriggerNode,
110
+ onClick: function onClick(e) {
111
+ trigger.props && trigger.props.onClick && trigger.props.onClick(e);
112
+ toggleOpen(e);
113
+ },
114
+ "aria-expanded": open,
115
+ "aria-haspopup": "menu"
116
+ }) : DefaultTrigger;
117
+ return jsxs("div", _objectSpread2(_objectSpread2({
118
+ ref: ref,
119
+ className: cn("inline-block relative", wrapperClassName)
120
+ }, rest), {}, {
121
+ children: [triggerNode, jsx("div", {
122
+ ref: menuRef,
123
+ className: cn("absolute left-0 mt-2 min-w-[160px] rounded-lg bg-white border shadow-sm", menuClass),
124
+ style: {
125
+ display: open ? "block" : "none"
126
+ },
127
+ role: "menu",
128
+ "aria-hidden": !open,
129
+ children: jsx("ul", {
130
+ className: "py-1",
131
+ children: items.map(function (it, i) {
132
+ var _it$key;
133
+ var Icon = it.icon || null;
134
+ return jsx("li", {
135
+ children: jsxs("button", {
136
+ type: "button",
137
+ role: "menuitem",
138
+ onClick: function onClick() {
139
+ return handleItemClick(it);
140
+ },
141
+ disabled: it.disabled,
142
+ className: "w-full text-left px-4 py-3 flex items-center gap-3 text-sm leading-5 ".concat(it.destructive ? "text-error-600" : "text-primary-900", " ").concat(it.disabled ? "opacity-50 cursor-not-allowed" : "hover:bg-gray-50", " ").concat(menuItemClass),
143
+ children: [Icon ? jsx(Icon, {
144
+ className: "w-5 h-5"
145
+ }) : jsx("span", {
146
+ className: "w-5 h-5"
147
+ }), jsx("span", {
148
+ className: "flex-1",
149
+ children: it.label
150
+ })]
151
+ })
152
+ }, (_it$key = it.key) !== null && _it$key !== void 0 ? _it$key : i);
153
+ })
154
+ })
155
+ })]
156
+ }));
157
+ });
158
+ ThreeDotPopoverSimple.displayName = "ThreeDotPopover";
159
+
160
+ export { ThreeDotPopoverSimple as default };