@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,171 @@
1
+ 'use client';
2
+ import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
3
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
+ import React, { useRef, useId } from 'react';
5
+ import { createPortal } from 'react-dom';
6
+ import { X } from 'lucide-react';
7
+ import { cn } from '../../utils/cn.js';
8
+ import { setRefs } from '../../utils/position.js';
9
+ import { useFocusTrap } from '../../hooks/useFocusTrap.js';
10
+ import { useScrollLock } from '../../hooks/useScrollLock.js';
11
+
12
+ var _excluded = ["isOpen", "onClose", "title", "description", "children", "placement", "size", "dismissible", "showCloseButton", "footer", "initialFocusRef", "className"],
13
+ _excluded2 = ["className"],
14
+ _excluded3 = ["className"],
15
+ _excluded4 = ["className"];
16
+ var PLACEMENT_CLASSES = {
17
+ right: "inset-y-0 right-0 h-full w-full border-l",
18
+ left: "inset-y-0 left-0 h-full w-full border-r",
19
+ top: "inset-x-0 top-0 w-full border-b",
20
+ bottom: "inset-x-0 bottom-0 w-full border-t"
21
+ };
22
+ var SIDE_SIZES = {
23
+ sm: "max-w-xs",
24
+ md: "max-w-md",
25
+ lg: "max-w-2xl",
26
+ xl: "max-w-4xl",
27
+ full: "max-w-full"
28
+ };
29
+ var EDGE_SIZES = {
30
+ sm: "max-h-[30vh]",
31
+ md: "max-h-[50vh]",
32
+ lg: "max-h-[75vh]",
33
+ xl: "max-h-[90vh]",
34
+ full: "h-full"
35
+ };
36
+ var CloseButton = function CloseButton(_ref) {
37
+ var onClose = _ref.onClose,
38
+ className = _ref.className;
39
+ return jsx("button", {
40
+ type: "button",
41
+ onClick: onClose,
42
+ "aria-label": "Close drawer",
43
+ className: cn("rounded-md p-1 text-gray-500 hover:bg-gray-100 hover:text-gray-700 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2", "dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-gray-200 dark:focus:ring-offset-gray-900", className),
44
+ children: jsx(X, {
45
+ className: "h-5 w-5",
46
+ "aria-hidden": "true"
47
+ })
48
+ });
49
+ };
50
+ var Drawer = /*#__PURE__*/React.forwardRef(function (_ref2, _ref3) {
51
+ var isOpen = _ref2.isOpen,
52
+ onClose = _ref2.onClose,
53
+ title = _ref2.title,
54
+ description = _ref2.description,
55
+ children = _ref2.children,
56
+ _ref2$placement = _ref2.placement,
57
+ placement = _ref2$placement === void 0 ? "right" : _ref2$placement,
58
+ _ref2$size = _ref2.size,
59
+ size = _ref2$size === void 0 ? "md" : _ref2$size,
60
+ _ref2$dismissible = _ref2.dismissible,
61
+ dismissible = _ref2$dismissible === void 0 ? true : _ref2$dismissible,
62
+ _ref2$showCloseButton = _ref2.showCloseButton,
63
+ showCloseButton = _ref2$showCloseButton === void 0 ? true : _ref2$showCloseButton,
64
+ footer = _ref2.footer,
65
+ initialFocusRef = _ref2.initialFocusRef,
66
+ className = _ref2.className,
67
+ props = _objectWithoutProperties(_ref2, _excluded);
68
+ var panelRef = useRef(null);
69
+ var titleId = "drawer-title-".concat(useId());
70
+ var descriptionId = "drawer-description-".concat(useId());
71
+ var side = PLACEMENT_CLASSES[placement] ? placement : "right";
72
+ var isEdge = side === "top" || side === "bottom";
73
+ // Without title/description/footer the children are the panel content, so
74
+ // Drawer.Header / Drawer.Body / Drawer.Footer compose without double padding.
75
+ var composed = !title && !description && !footer;
76
+ useScrollLock(isOpen);
77
+ useFocusTrap(panelRef, {
78
+ active: isOpen,
79
+ initialFocusRef: initialFocusRef,
80
+ onEscape: function onEscape() {
81
+ if (dismissible) onClose === null || onClose === void 0 || onClose();
82
+ }
83
+ });
84
+ if (!isOpen || typeof document === "undefined") return null;
85
+ return /*#__PURE__*/createPortal(jsxs("div", {
86
+ className: "fixed inset-0 z-50",
87
+ children: [jsx("div", {
88
+ "aria-hidden": "true",
89
+ "data-testid": "drawer-backdrop",
90
+ className: "absolute inset-0 bg-black/50 animate-fade-in motion-reduce:animate-none",
91
+ onClick: function onClick() {
92
+ return dismissible && (onClose === null || onClose === void 0 ? void 0 : onClose());
93
+ }
94
+ }), jsx("div", _objectSpread2(_objectSpread2({
95
+ ref: function ref(node) {
96
+ return setRefs(node, panelRef, _ref3);
97
+ },
98
+ role: "dialog",
99
+ "aria-modal": "true",
100
+ "aria-labelledby": title ? titleId : undefined,
101
+ "aria-describedby": description ? descriptionId : undefined,
102
+ tabIndex: -1,
103
+ "data-placement": side,
104
+ className: cn("absolute flex flex-col border-gray-200 bg-white text-gray-900 shadow-xl focus:outline-none", "dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100", "animate-fade-in motion-reduce:animate-none", PLACEMENT_CLASSES[side], (isEdge ? EDGE_SIZES : SIDE_SIZES)[size] || (isEdge ? EDGE_SIZES.md : SIDE_SIZES.md), className)
105
+ }, props), {}, {
106
+ children: composed ? jsxs(Fragment, {
107
+ children: [showCloseButton && jsx(CloseButton, {
108
+ onClose: onClose,
109
+ className: "absolute right-3 top-3"
110
+ }), children]
111
+ }) : jsxs(Fragment, {
112
+ children: [jsxs("div", {
113
+ className: "flex items-start justify-between gap-4 border-b border-gray-200 px-6 py-4 dark:border-gray-700",
114
+ children: [jsxs("div", {
115
+ className: "min-w-0",
116
+ children: [title && jsx("h2", {
117
+ id: titleId,
118
+ className: "text-lg font-semibold",
119
+ children: title
120
+ }), description && jsx("p", {
121
+ id: descriptionId,
122
+ className: "mt-1 text-sm text-gray-500 dark:text-gray-400",
123
+ children: description
124
+ })]
125
+ }), showCloseButton && jsx(CloseButton, {
126
+ onClose: onClose
127
+ })]
128
+ }), jsx("div", {
129
+ className: "min-h-0 flex-1 overflow-y-auto px-6 py-4",
130
+ children: children
131
+ }), footer && jsx("div", {
132
+ className: "flex items-center justify-end gap-3 border-t border-gray-200 px-6 py-4 dark:border-gray-700",
133
+ children: footer
134
+ })]
135
+ })
136
+ }))]
137
+ }), document.body);
138
+ });
139
+ Drawer.displayName = "Drawer";
140
+ var DrawerHeader = /*#__PURE__*/React.forwardRef(function (_ref4, ref) {
141
+ var className = _ref4.className,
142
+ props = _objectWithoutProperties(_ref4, _excluded2);
143
+ return jsx("div", _objectSpread2({
144
+ ref: ref,
145
+ className: cn("border-b border-gray-200 px-6 py-4 dark:border-gray-700", className)
146
+ }, props));
147
+ });
148
+ var DrawerBody = /*#__PURE__*/React.forwardRef(function (_ref5, ref) {
149
+ var className = _ref5.className,
150
+ props = _objectWithoutProperties(_ref5, _excluded3);
151
+ return jsx("div", _objectSpread2({
152
+ ref: ref,
153
+ className: cn("min-h-0 flex-1 overflow-y-auto px-6 py-4", className)
154
+ }, props));
155
+ });
156
+ var DrawerFooter = /*#__PURE__*/React.forwardRef(function (_ref6, ref) {
157
+ var className = _ref6.className,
158
+ props = _objectWithoutProperties(_ref6, _excluded4);
159
+ return jsx("div", _objectSpread2({
160
+ ref: ref,
161
+ className: cn("flex items-center justify-end gap-3 border-t border-gray-200 px-6 py-4 dark:border-gray-700", className)
162
+ }, props));
163
+ });
164
+ DrawerHeader.displayName = "Drawer.Header";
165
+ DrawerBody.displayName = "Drawer.Body";
166
+ DrawerFooter.displayName = "Drawer.Footer";
167
+ Drawer.Header = DrawerHeader;
168
+ Drawer.Body = DrawerBody;
169
+ Drawer.Footer = DrawerFooter;
170
+
171
+ export { Drawer as default };
@@ -0,0 +1,362 @@
1
+ 'use client';
2
+ import { objectWithoutProperties as _objectWithoutProperties, slicedToArray as _slicedToArray, objectSpread2 as _objectSpread2, toConsumableArray as _toConsumableArray, typeof as _typeof } from '../../_virtual/_rollupPluginBabelHelpers.js';
3
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
+ import { forwardRef, useState, useRef, useCallback, useEffect, useContext, createContext, useMemo } from 'react';
5
+ import { createPortal } from 'react-dom';
6
+ import { cn } from '../../utils/cn.js';
7
+ import { Bell, Info, AlertTriangle, XCircle, CheckCircle2, X } from 'lucide-react';
8
+
9
+ var _excluded = ["id", "title", "message", "description", "type", "duration", "onClose", "position", "statusIcon", "actions", "color", "footerNote", "showFooterNote", "portal", "className"];
10
+ var STATUS_CONFIG = {
11
+ success: {
12
+ icon: CheckCircle2,
13
+ iconClass: 'text-emerald-500 dark:text-emerald-400',
14
+ progressClass: 'bg-emerald-500 dark:bg-emerald-400'
15
+ },
16
+ error: {
17
+ icon: XCircle,
18
+ iconClass: 'text-rose-500 dark:text-rose-400',
19
+ progressClass: 'bg-rose-500 dark:bg-rose-400'
20
+ },
21
+ warning: {
22
+ icon: AlertTriangle,
23
+ iconClass: 'text-amber-500 dark:text-amber-400',
24
+ progressClass: 'bg-amber-500 dark:bg-amber-400'
25
+ },
26
+ info: {
27
+ icon: Info,
28
+ iconClass: 'text-sky-500 dark:text-sky-400',
29
+ progressClass: 'bg-sky-500 dark:bg-sky-400'
30
+ },
31
+ "default": {
32
+ icon: Bell,
33
+ iconClass: 'text-primary-500 dark:text-primary-400',
34
+ progressClass: 'bg-primary-500 dark:bg-primary-400'
35
+ }
36
+ };
37
+ var POSITION_CLASSES = {
38
+ 'top-right': 'top-4 right-4 items-end',
39
+ 'top-left': 'top-4 left-4 items-start',
40
+ 'bottom-right': 'bottom-4 right-4 items-end',
41
+ 'bottom-left': 'bottom-4 left-4 items-start',
42
+ 'top-center': 'top-4 left-1/2 transform -translate-x-1/2 items-center',
43
+ 'bottom-center': 'bottom-4 left-1/2 transform -translate-x-1/2 items-center'
44
+ };
45
+ var STANDALONE_POSITION_CLASSES = {
46
+ 'top-right': 'top-4 right-4',
47
+ 'top-left': 'top-4 left-4',
48
+ 'bottom-right': 'bottom-4 right-4',
49
+ 'bottom-left': 'bottom-4 left-4',
50
+ 'top-center': 'top-4 left-1/2 transform -translate-x-1/2',
51
+ 'bottom-center': 'bottom-4 left-1/2 transform -translate-x-1/2'
52
+ };
53
+ var Toast = /*#__PURE__*/forwardRef(function (_ref, ref) {
54
+ var id = _ref.id,
55
+ title = _ref.title,
56
+ message = _ref.message,
57
+ description = _ref.description,
58
+ _ref$type = _ref.type,
59
+ type = _ref$type === void 0 ? 'info' : _ref$type,
60
+ _ref$duration = _ref.duration,
61
+ duration = _ref$duration === void 0 ? 5000 : _ref$duration,
62
+ onClose = _ref.onClose,
63
+ _ref$position = _ref.position,
64
+ position = _ref$position === void 0 ? 'top-right' : _ref$position,
65
+ statusIcon = _ref.statusIcon,
66
+ _ref$actions = _ref.actions,
67
+ actions = _ref$actions === void 0 ? [] : _ref$actions,
68
+ color = _ref.color,
69
+ footerNote = _ref.footerNote,
70
+ _ref$showFooterNote = _ref.showFooterNote,
71
+ showFooterNote = _ref$showFooterNote === void 0 ? false : _ref$showFooterNote,
72
+ _ref$portal = _ref.portal,
73
+ portal = _ref$portal === void 0 ? true : _ref$portal,
74
+ _ref$className = _ref.className,
75
+ className = _ref$className === void 0 ? '' : _ref$className,
76
+ props = _objectWithoutProperties(_ref, _excluded);
77
+ var _useState = useState(true),
78
+ _useState2 = _slicedToArray(_useState, 2),
79
+ isVisible = _useState2[0],
80
+ setIsVisible = _useState2[1];
81
+ var _useState3 = useState(false),
82
+ _useState4 = _slicedToArray(_useState3, 2),
83
+ isLeaving = _useState4[0],
84
+ setIsLeaving = _useState4[1];
85
+ var _useState5 = useState(false),
86
+ _useState6 = _slicedToArray(_useState5, 2),
87
+ isPaused = _useState6[0],
88
+ setIsPaused = _useState6[1];
89
+ var progressBarRef = useRef(null);
90
+ var timerTextRef = useRef(null);
91
+ var startTimeRef = useRef(null);
92
+ var remainingRef = useRef(duration);
93
+ var timerRef = useRef(null);
94
+ var animFrameRef = useRef(null);
95
+ var handleClose = useCallback(function () {
96
+ if (isLeaving) return;
97
+ setIsLeaving(true);
98
+ setTimeout(function () {
99
+ setIsVisible(false);
100
+ onClose === null || onClose === void 0 || onClose(id);
101
+ }, 300);
102
+ }, [id, onClose, isLeaving]);
103
+ var handleStopTimer = useCallback(function (e) {
104
+ e === null || e === void 0 || e.stopPropagation();
105
+ setIsPaused(true);
106
+ if (timerRef.current) clearTimeout(timerRef.current);
107
+ if (animFrameRef.current) cancelAnimationFrame(animFrameRef.current);
108
+ }, []);
109
+ // Direct DOM-based progress updates to prevent 60 FPS React re-renders and glitches
110
+ useEffect(function () {
111
+ if (duration <= 0) return;
112
+ if (isPaused) {
113
+ if (timerRef.current) clearTimeout(timerRef.current);
114
+ if (animFrameRef.current) cancelAnimationFrame(animFrameRef.current);
115
+ return;
116
+ }
117
+ startTimeRef.current = Date.now();
118
+ timerRef.current = setTimeout(function () {
119
+ handleClose();
120
+ }, remainingRef.current);
121
+ var _updateProgress = function updateProgress() {
122
+ var elapsed = startTimeRef.current ? Date.now() - startTimeRef.current : 0;
123
+ var currentRemaining = Math.max(0, remainingRef.current - elapsed);
124
+ var pct = currentRemaining / duration * 100;
125
+ if (progressBarRef.current) {
126
+ progressBarRef.current.style.width = "".concat(pct, "%");
127
+ }
128
+ if (timerTextRef.current) {
129
+ var secs = Math.ceil(currentRemaining / 1000);
130
+ timerTextRef.current.textContent = "This message will close in ".concat(secs, " seconds. ");
131
+ }
132
+ if (currentRemaining > 0 && !isPaused) {
133
+ animFrameRef.current = requestAnimationFrame(_updateProgress);
134
+ }
135
+ };
136
+ animFrameRef.current = requestAnimationFrame(_updateProgress);
137
+ return function () {
138
+ if (timerRef.current) clearTimeout(timerRef.current);
139
+ if (animFrameRef.current) cancelAnimationFrame(animFrameRef.current);
140
+ if (!isPaused && startTimeRef.current) {
141
+ var elapsed = Date.now() - startTimeRef.current;
142
+ remainingRef.current = Math.max(0, remainingRef.current - elapsed);
143
+ }
144
+ };
145
+ }, [duration, isPaused, handleClose]);
146
+ if (!isVisible) return null;
147
+ var statusStyle = STATUS_CONFIG[type] || STATUS_CONFIG.info || STATUS_CONFIG["default"];
148
+ var StatusIconComponent = statusStyle.icon;
149
+ var bodyText = description || message;
150
+ var toastContent = jsxs("div", _objectSpread2(_objectSpread2({
151
+ ref: ref,
152
+ onMouseEnter: function onMouseEnter() {
153
+ return setIsPaused(true);
154
+ },
155
+ onMouseLeave: function onMouseLeave() {
156
+ return setIsPaused(false);
157
+ },
158
+ className: cn('relative overflow-hidden rounded-xl border border-slate-200/90 bg-white/95 shadow-xl backdrop-blur-md transition-all duration-300', 'dark:border-slate-800/80 dark:bg-[#18181b] dark:text-slate-100 dark:shadow-2xl', 'max-w-md w-full', isLeaving ? 'opacity-0 scale-95 translate-y-1' : 'animate-slide-up opacity-100 scale-100', portal ? ['fixed z-50', STANDALONE_POSITION_CLASSES[position] || STANDALONE_POSITION_CLASSES['top-right']] : '', className)
159
+ }, props), {}, {
160
+ children: [jsx("div", {
161
+ className: "p-4",
162
+ children: jsxs("div", {
163
+ className: "flex items-start gap-3 justify-between",
164
+ children: [jsx("span", {
165
+ className: "flex-shrink-0 mt-0.5",
166
+ children: statusIcon ? statusIcon : jsx(StatusIconComponent, {
167
+ className: cn('h-5 w-5', statusStyle.iconClass)
168
+ })
169
+ }), jsxs("div", {
170
+ className: "flex-1 min-w-0 pr-2",
171
+ children: [title && jsx("h4", {
172
+ className: "text-sm font-semibold text-slate-900 dark:text-slate-100 leading-snug",
173
+ children: title
174
+ }), bodyText && jsx("p", {
175
+ className: "mt-1 text-xs text-slate-600 dark:text-slate-400 leading-relaxed whitespace-pre-line",
176
+ children: bodyText
177
+ }), actions && actions.length > 0 && jsx("div", {
178
+ className: "mt-3 flex items-center gap-2 flex-wrap",
179
+ children: actions.map(function (actItem, idx) {
180
+ return jsx("button", {
181
+ type: "button",
182
+ onClick: function onClick(e) {
183
+ var _actItem$onClick;
184
+ (_actItem$onClick = actItem.onClick) === null || _actItem$onClick === void 0 || _actItem$onClick.call(actItem, e);
185
+ if (actItem.dismiss !== false) {
186
+ handleClose();
187
+ }
188
+ },
189
+ className: cn('px-3 py-1.5 text-xs font-medium rounded-lg transition-colors border shadow-xs', actItem.variant === 'primary' ? 'bg-primary-600 hover:bg-primary-700 text-white border-primary-600' : 'bg-slate-100 dark:bg-zinc-800/80 text-slate-700 dark:text-zinc-200 border-slate-200 dark:border-zinc-700 hover:bg-slate-200 dark:hover:bg-zinc-700', actItem.className),
190
+ children: actItem.label
191
+ }, actItem.id || actItem.label || "act-".concat(idx));
192
+ })
193
+ })]
194
+ }), jsx("button", {
195
+ type: "button",
196
+ "aria-label": "Close notification",
197
+ className: "flex-shrink-0 rounded-lg p-1 text-slate-400 hover:text-slate-600 dark:hover:text-slate-200 hover:bg-slate-100 dark:hover:bg-zinc-800/70 transition-colors outline-none focus:ring-2 focus:ring-primary-500",
198
+ onClick: handleClose,
199
+ children: jsx(X, {
200
+ className: "h-4 w-4"
201
+ })
202
+ })]
203
+ })
204
+ }), (showFooterNote || footerNote) && duration > 0 && jsx("div", {
205
+ className: "px-4 py-2 bg-slate-50 dark:bg-zinc-950/40 border-t border-slate-100 dark:border-zinc-800/50 text-[11px] text-slate-500 dark:text-zinc-400 flex items-center justify-between",
206
+ children: jsx("span", {
207
+ children: footerNote ? footerNote : jsxs(Fragment, {
208
+ children: [jsxs("span", {
209
+ ref: timerTextRef,
210
+ children: ["This message will close in ", Math.ceil(duration / 1000), " seconds.", ' ']
211
+ }), jsx("button", {
212
+ type: "button",
213
+ onClick: handleStopTimer,
214
+ className: "font-medium text-slate-700 dark:text-zinc-200 hover:underline inline",
215
+ children: "Click to stop."
216
+ })]
217
+ })
218
+ })
219
+ }), duration > 0 && jsx("div", {
220
+ className: "absolute bottom-0 left-0 right-0 h-0.5 bg-slate-100 dark:bg-zinc-800/80 overflow-hidden rounded-b-xl",
221
+ children: jsx("div", {
222
+ ref: progressBarRef,
223
+ className: cn('h-full transition-all ease-linear', color ? '' : statusStyle.progressClass),
224
+ style: {
225
+ width: '100%',
226
+ backgroundColor: color || undefined
227
+ }
228
+ })
229
+ })]
230
+ }));
231
+ if (portal) {
232
+ return /*#__PURE__*/createPortal(toastContent, document.body);
233
+ }
234
+ return toastContent;
235
+ });
236
+ Toast.displayName = 'Toast';
237
+ // Shared queue for <ToastProvider>. `null` outside a provider, where useToast
238
+ // falls back to its own component-local queue (the pre-provider behavior).
239
+ var ToastContext = /*#__PURE__*/createContext(null);
240
+ var ToastStack = function ToastStack(_ref2) {
241
+ var _ref2$toasts = _ref2.toasts,
242
+ toasts = _ref2$toasts === void 0 ? [] : _ref2$toasts,
243
+ _ref2$position = _ref2.position,
244
+ position = _ref2$position === void 0 ? 'top-right' : _ref2$position,
245
+ onRemove = _ref2.onRemove,
246
+ _ref2$className = _ref2.className,
247
+ className = _ref2$className === void 0 ? '' : _ref2$className;
248
+ if (!toasts || toasts.length === 0) {
249
+ return null;
250
+ }
251
+ var posClass = POSITION_CLASSES[position] || POSITION_CLASSES['top-right'];
252
+ return /*#__PURE__*/createPortal(jsx("div", {
253
+ className: cn('fixed z-50 flex flex-col gap-3 max-h-[calc(100vh-2rem)] overflow-y-auto overflow-x-hidden p-2 pointer-events-none', '[scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden', posClass, className),
254
+ children: toasts.map(function (t) {
255
+ return jsx("div", {
256
+ className: "pointer-events-auto w-full max-w-md",
257
+ children: jsx(Toast, _objectSpread2(_objectSpread2({}, t), {}, {
258
+ portal: false,
259
+ position: position,
260
+ onClose: onRemove
261
+ }))
262
+ }, t.id);
263
+ })
264
+ }), document.body);
265
+ };
266
+ // Toast Container Component for vertical stacking & scrollable overflow without visible scrollbars
267
+ var ToastContainer = function ToastContainer(props) {
268
+ var shared = useContext(ToastContext);
269
+ // Under a <ToastProvider> the provider already renders the shared queue, so a
270
+ // legacy `<ToastContainer toasts={useToast().toasts} />` would render every
271
+ // toast twice. Skip it when it is handed the provider's own queue.
272
+ if (shared && props.toasts === shared.toasts) return null;
273
+ return jsx(ToastStack, _objectSpread2({}, props));
274
+ };
275
+ var useToastQueue = function useToastQueue() {
276
+ var _useState7 = useState([]),
277
+ _useState8 = _slicedToArray(_useState7, 2),
278
+ toasts = _useState8[0],
279
+ setToasts = _useState8[1];
280
+ var addToast = useCallback(function (toastOptions) {
281
+ var id = toastOptions.id || "".concat(Date.now(), "-").concat(Math.random().toString(36).slice(2, 7));
282
+ var newToast = _objectSpread2(_objectSpread2({}, toastOptions), {}, {
283
+ id: id
284
+ });
285
+ setToasts(function (prev) {
286
+ return [].concat(_toConsumableArray(prev), [newToast]);
287
+ });
288
+ return id;
289
+ }, []);
290
+ var removeToast = useCallback(function (id) {
291
+ setToasts(function (prev) {
292
+ return prev.filter(function (t) {
293
+ return t.id !== id;
294
+ });
295
+ });
296
+ }, []);
297
+ var clearToasts = useCallback(function () {
298
+ setToasts([]);
299
+ }, []);
300
+ // Build the callable `toast` together with its typed shorthands in one
301
+ // memo, so the stable function is never mutated after creation.
302
+ var toast = useMemo(function () {
303
+ var withType = function withType(type) {
304
+ return function (title, message, options) {
305
+ return addToast(_objectSpread2({
306
+ title: title,
307
+ message: message,
308
+ type: type
309
+ }, _typeof(options) === 'object' ? options : {}));
310
+ };
311
+ };
312
+ return Object.assign(function (options) {
313
+ return addToast(typeof options === 'string' ? {
314
+ message: options
315
+ } : options);
316
+ }, {
317
+ success: withType('success'),
318
+ error: withType('error'),
319
+ warning: withType('warning'),
320
+ info: withType('info'),
321
+ "default": withType('default')
322
+ });
323
+ }, [addToast]);
324
+ return useMemo(function () {
325
+ return {
326
+ toast: toast,
327
+ toasts: toasts,
328
+ removeToast: removeToast,
329
+ clearToasts: clearToasts,
330
+ addToast: addToast
331
+ };
332
+ }, [toast, toasts, removeToast, clearToasts, addToast]);
333
+ };
334
+ // App-level provider: every useToast() below it shares ONE queue, rendered by
335
+ // the provider's own container — no per-screen <ToastContainer> needed.
336
+ var ToastProvider = function ToastProvider(_ref3) {
337
+ var children = _ref3.children,
338
+ _ref3$position = _ref3.position,
339
+ position = _ref3$position === void 0 ? 'top-right' : _ref3$position,
340
+ _ref3$className = _ref3.className,
341
+ className = _ref3$className === void 0 ? '' : _ref3$className;
342
+ var queue = useToastQueue();
343
+ return jsxs(ToastContext.Provider, {
344
+ value: queue,
345
+ children: [children, jsx(ToastStack, {
346
+ toasts: queue.toasts,
347
+ position: position,
348
+ onRemove: queue.removeToast,
349
+ className: className
350
+ })]
351
+ });
352
+ };
353
+ ToastProvider.displayName = 'ToastProvider';
354
+ // Toast Hook. Inside a <ToastProvider> it returns the shared queue; outside one
355
+ // it keeps a component-local queue (render it with <ToastContainer>).
356
+ var useToast = function useToast() {
357
+ var shared = useContext(ToastContext);
358
+ var local = useToastQueue();
359
+ return shared !== null && shared !== void 0 ? shared : local;
360
+ };
361
+
362
+ export { Toast, ToastContainer, ToastProvider, Toast as default, useToast };