@dreamtree-org/twreact-ui 1.3.0 → 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 (184) hide show
  1. package/README.md +179 -10
  2. package/ai-skills/dreamtree-ui.md +71 -12
  3. package/dist/ai-schema.json +452 -17
  4. package/dist/components/core/Accordion.d.ts.map +1 -1
  5. package/dist/components/core/Button.d.ts.map +1 -1
  6. package/dist/components/core/Checkbox.d.ts.map +1 -1
  7. package/dist/components/core/ColorPicker.d.ts.map +1 -1
  8. package/dist/components/core/DatePicker.d.ts.map +1 -1
  9. package/dist/components/core/DateRangePicker.d.ts.map +1 -1
  10. package/dist/components/core/Form.d.ts.map +1 -1
  11. package/dist/components/core/Input.d.ts.map +1 -1
  12. package/dist/components/core/LocationPicker.d.ts.map +1 -1
  13. package/dist/components/core/Popover.d.ts +4 -0
  14. package/dist/components/core/Popover.d.ts.map +1 -0
  15. package/dist/components/core/PriceRangePicker.d.ts.map +1 -1
  16. package/dist/components/core/ProgressBar.d.ts.map +1 -1
  17. package/dist/components/core/Radio.d.ts.map +1 -1
  18. package/dist/components/core/Rate.d.ts.map +1 -1
  19. package/dist/components/core/Select.d.ts.map +1 -1
  20. package/dist/components/core/Skeleton.d.ts.map +1 -1
  21. package/dist/components/core/Slider.d.ts +4 -0
  22. package/dist/components/core/Slider.d.ts.map +1 -0
  23. package/dist/components/core/SpeechToText.d.ts.map +1 -1
  24. package/dist/components/core/Switch.d.ts.map +1 -1
  25. package/dist/components/core/Table/ActionMenu.d.ts.map +1 -1
  26. package/dist/components/core/Table/ColumnMenu.d.ts +2 -1
  27. package/dist/components/core/Table/ColumnMenu.d.ts.map +1 -1
  28. package/dist/components/core/Table/MobileCard.d.ts +2 -2
  29. package/dist/components/core/Table/MobileCard.d.ts.map +1 -1
  30. package/dist/components/core/Table/Table.d.ts.map +1 -1
  31. package/dist/components/core/Table/TableRow.d.ts +4 -2
  32. package/dist/components/core/Table/TableRow.d.ts.map +1 -1
  33. package/dist/components/core/Tabs.d.ts.map +1 -1
  34. package/dist/components/core/Textarea.d.ts +4 -0
  35. package/dist/components/core/Textarea.d.ts.map +1 -0
  36. package/dist/components/core/ThreeDotPopover.d.ts.map +1 -1
  37. package/dist/components/core/Tooltip.d.ts.map +1 -1
  38. package/dist/components/feedback/Dialog.d.ts.map +1 -1
  39. package/dist/components/feedback/Drawer.d.ts +4 -0
  40. package/dist/components/feedback/Drawer.d.ts.map +1 -0
  41. package/dist/components/feedback/Toast.d.ts +14 -5
  42. package/dist/components/feedback/Toast.d.ts.map +1 -1
  43. package/dist/components/feedback/Tour.d.ts +4 -0
  44. package/dist/components/feedback/Tour.d.ts.map +1 -0
  45. package/dist/components/feedback/TourSpotlight.d.ts +9 -0
  46. package/dist/components/feedback/TourSpotlight.d.ts.map +1 -0
  47. package/dist/components/navigation/Breadcrumbs.d.ts.map +1 -1
  48. package/dist/components/navigation/FootNav.d.ts.map +1 -1
  49. package/dist/components/navigation/Navbar.d.ts.map +1 -1
  50. package/dist/components/navigation/Sidebar.d.ts +8 -2
  51. package/dist/components/navigation/Sidebar.d.ts.map +1 -1
  52. package/dist/components/utility/Badge.d.ts.map +1 -1
  53. package/dist/components/utility/FileUpload.d.ts.map +1 -1
  54. package/dist/components/utility/Sortable.d.ts +4 -0
  55. package/dist/components/utility/Sortable.d.ts.map +1 -0
  56. package/dist/esm/_vendor/object-assign/index.js +99 -0
  57. package/dist/esm/_vendor/prop-types/_vendor/react-is/cjs/react-is.development.js +190 -0
  58. package/dist/esm/_vendor/prop-types/_vendor/react-is/cjs/react-is.production.min.js +26 -0
  59. package/dist/esm/_vendor/prop-types/_vendor/react-is/index.js +19 -0
  60. package/dist/esm/_vendor/prop-types/checkPropTypes.js +115 -0
  61. package/dist/esm/_vendor/prop-types/factoryWithThrowingShims.js +74 -0
  62. package/dist/esm/_vendor/prop-types/factoryWithTypeCheckers.js +625 -0
  63. package/dist/esm/_vendor/prop-types/index.js +30 -0
  64. package/dist/esm/_vendor/prop-types/lib/ReactPropTypesSecret.js +21 -0
  65. package/dist/esm/_vendor/prop-types/lib/has.js +11 -0
  66. package/dist/esm/_virtual/_commonjsHelpers.js +5 -0
  67. package/dist/esm/_virtual/_rollupPluginBabelHelpers.js +329 -0
  68. package/dist/esm/_virtual/index.js +3 -0
  69. package/dist/esm/_virtual/index2.js +3 -0
  70. package/dist/esm/_virtual/react-is.development.js +3 -0
  71. package/dist/esm/_virtual/react-is.production.min.js +3 -0
  72. package/dist/esm/components/blocks/AppShell.js +205 -0
  73. package/dist/esm/components/blocks/ConfirmDialog.js +57 -0
  74. package/dist/esm/components/blocks/EmptyState.js +44 -0
  75. package/dist/esm/components/blocks/ErrorState.js +53 -0
  76. package/dist/esm/components/blocks/LoadingState.js +134 -0
  77. package/dist/esm/components/blocks/PageHeader.js +51 -0
  78. package/dist/esm/components/blocks/StatCard.js +79 -0
  79. package/dist/esm/components/blocks/StatusPill.js +55 -0
  80. package/dist/esm/components/core/Accordion.js +260 -0
  81. package/dist/esm/components/core/Button.js +59 -0
  82. package/dist/esm/components/core/Checkbox.js +188 -0
  83. package/dist/esm/components/core/ColorPicker.js +348 -0
  84. package/dist/esm/components/core/DatePicker.js +436 -0
  85. package/dist/esm/components/core/DateRangePicker.js +494 -0
  86. package/dist/esm/components/core/Form.js +522 -0
  87. package/dist/esm/components/core/Input.js +179 -0
  88. package/dist/esm/components/core/Loader.js +141 -0
  89. package/dist/esm/components/core/LocationPicker.js +161 -0
  90. package/dist/esm/components/core/Popover.js +171 -0
  91. package/dist/esm/components/core/PriceRangePicker.js +376 -0
  92. package/dist/esm/components/core/ProgressBar.js +152 -0
  93. package/dist/esm/components/core/Radio.js +156 -0
  94. package/dist/esm/components/core/Rate.js +197 -0
  95. package/dist/esm/components/core/RoundedTag.js +118 -0
  96. package/dist/esm/components/core/Select.js +857 -0
  97. package/dist/esm/components/core/Skeleton.js +100 -0
  98. package/dist/esm/components/core/Slider.js +134 -0
  99. package/dist/esm/components/core/SpeechToText.js +226 -0
  100. package/dist/esm/components/core/Switch.js +207 -0
  101. package/dist/esm/components/core/Table/ActionMenu.js +251 -0
  102. package/dist/esm/components/core/Table/ColumnMenu.js +55 -0
  103. package/dist/esm/components/core/Table/FieldInput.js +157 -0
  104. package/dist/esm/components/core/Table/MobileCard.js +187 -0
  105. package/dist/esm/components/core/Table/MobileFilters.js +72 -0
  106. package/dist/esm/components/core/Table/Pagination.js +157 -0
  107. package/dist/esm/components/core/Table/Table.js +1533 -0
  108. package/dist/esm/components/core/Table/TableRow.js +254 -0
  109. package/dist/esm/components/core/Table/constants.js +35 -0
  110. package/dist/esm/components/core/Table/helpers.js +124 -0
  111. package/dist/esm/components/core/Table/useClickOutside.js +26 -0
  112. package/dist/esm/components/core/Tabs.js +289 -0
  113. package/dist/esm/components/core/TextToSpeech.js +52 -0
  114. package/dist/esm/components/core/Textarea.js +125 -0
  115. package/dist/esm/components/core/ThreeDotPopover.js +160 -0
  116. package/dist/esm/components/core/Tooltip.js +372 -0
  117. package/dist/esm/components/feedback/Alert.js +96 -0
  118. package/dist/esm/components/feedback/Dialog.js +200 -0
  119. package/dist/esm/components/feedback/Drawer.js +171 -0
  120. package/dist/esm/components/feedback/Toast.js +362 -0
  121. package/dist/esm/components/feedback/Tour.js +214 -0
  122. package/dist/esm/components/feedback/TourSpotlight.js +71 -0
  123. package/dist/esm/components/navigation/Breadcrumbs.js +75 -0
  124. package/dist/esm/components/navigation/Dropdown.js +53 -0
  125. package/dist/esm/components/navigation/FootNav.js +51 -0
  126. package/dist/esm/components/navigation/Navbar.js +437 -0
  127. package/dist/esm/components/navigation/Sidebar.js +567 -0
  128. package/dist/esm/components/utility/Avatar.js +89 -0
  129. package/dist/esm/components/utility/Badge.js +47 -0
  130. package/dist/esm/components/utility/Card.js +85 -0
  131. package/dist/esm/components/utility/Carousel.js +97 -0
  132. package/dist/esm/components/utility/Condition.js +9 -0
  133. package/dist/esm/components/utility/FileUpload.js +177 -0
  134. package/dist/esm/components/utility/Pagination.js +111 -0
  135. package/dist/esm/components/utility/Sortable.js +190 -0
  136. package/dist/esm/components/utility/Stepper.js +101 -0
  137. package/dist/esm/hooks/useApi.js +169 -0
  138. package/dist/esm/hooks/useControllableState.js +32 -0
  139. package/dist/esm/hooks/useFocusTrap.js +85 -0
  140. package/dist/esm/hooks/useLatestRef.js +20 -0
  141. package/dist/esm/hooks/useMixins.js +100 -0
  142. package/dist/esm/hooks/useScrollLock.js +26 -0
  143. package/dist/esm/hooks/useSliderValues.js +135 -0
  144. package/dist/esm/hooks/useSortable.js +188 -0
  145. package/dist/esm/hooks/useTheme.js +53 -0
  146. package/dist/esm/hooks/useTourTarget.js +92 -0
  147. package/dist/esm/index.js +65 -0
  148. package/dist/esm/store/index.js +26 -0
  149. package/dist/esm/store/store.js +107 -0
  150. package/dist/esm/store/storeSlice.js +45 -0
  151. package/dist/esm/utils/cn.js +11 -0
  152. package/dist/esm/utils/emitter.js +169 -0
  153. package/dist/esm/utils/helpers.js +161 -0
  154. package/dist/esm/utils/position.js +134 -0
  155. package/dist/hooks/useApi.d.ts +2 -1
  156. package/dist/hooks/useApi.d.ts.map +1 -1
  157. package/dist/hooks/useControllableState.d.ts +11 -0
  158. package/dist/hooks/useControllableState.d.ts.map +1 -0
  159. package/dist/hooks/useFocusTrap.d.ts +15 -0
  160. package/dist/hooks/useFocusTrap.d.ts.map +1 -0
  161. package/dist/hooks/useLatestRef.d.ts +8 -0
  162. package/dist/hooks/useLatestRef.d.ts.map +1 -0
  163. package/dist/hooks/useMixins.d.ts.map +1 -1
  164. package/dist/hooks/useScrollLock.d.ts +2 -0
  165. package/dist/hooks/useScrollLock.d.ts.map +1 -0
  166. package/dist/hooks/useSliderValues.d.ts +43 -0
  167. package/dist/hooks/useSliderValues.d.ts.map +1 -0
  168. package/dist/hooks/useSortable.d.ts +32 -0
  169. package/dist/hooks/useSortable.d.ts.map +1 -0
  170. package/dist/hooks/useTheme.d.ts.map +1 -1
  171. package/dist/hooks/useTourTarget.d.ts +15 -0
  172. package/dist/hooks/useTourTarget.d.ts.map +1 -0
  173. package/dist/index.css +1 -1
  174. package/dist/index.d.ts +8 -2
  175. package/dist/index.esm.css +1 -1
  176. package/dist/index.esm.js +4800 -2212
  177. package/dist/index.js +4805 -2210
  178. package/dist/types/index.d.ts +193 -5
  179. package/dist/types/index.d.ts.map +1 -1
  180. package/dist/utils/position.d.ts +30 -0
  181. package/dist/utils/position.d.ts.map +1 -0
  182. package/doc/README.md +7 -1
  183. package/mcp/catalog.snapshot.json +911 -212
  184. package/package.json +14 -2
@@ -0,0 +1,179 @@
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 } from 'react';
5
+ import { Search, EyeOff, Eye, X } from 'lucide-react';
6
+ import { cn } from '../../utils/cn.js';
7
+
8
+ var _excluded = ["id", "className", "type", "label", "placeholder", "error", "success", "helperText", "disabled", "required", "clearable", "icon", "iconPosition", "onClear", "showCount", "maxLength", "readOnly", "onChange", "value", "defaultValue"];
9
+ var Input = /*#__PURE__*/forwardRef(function (props, forwardedRef) {
10
+ var id = props.id,
11
+ className = props.className,
12
+ _props$type = props.type,
13
+ type = _props$type === void 0 ? "text" : _props$type,
14
+ label = props.label,
15
+ placeholder = props.placeholder,
16
+ error = props.error,
17
+ success = props.success,
18
+ helperText = props.helperText,
19
+ _props$disabled = props.disabled,
20
+ disabled = _props$disabled === void 0 ? false : _props$disabled,
21
+ _props$required = props.required,
22
+ required = _props$required === void 0 ? false : _props$required,
23
+ _props$clearable = props.clearable,
24
+ clearable = _props$clearable === void 0 ? false : _props$clearable,
25
+ icon = props.icon,
26
+ _props$iconPosition = props.iconPosition,
27
+ iconPosition = _props$iconPosition === void 0 ? "left" : _props$iconPosition,
28
+ onClear = props.onClear,
29
+ _props$showCount = props.showCount,
30
+ showCount = _props$showCount === void 0 ? false : _props$showCount,
31
+ maxLength = props.maxLength,
32
+ _props$readOnly = props.readOnly,
33
+ readOnly = _props$readOnly === void 0 ? false : _props$readOnly,
34
+ onChange = props.onChange,
35
+ value = props.value,
36
+ defaultValue = props.defaultValue,
37
+ rest = _objectWithoutProperties(props, _excluded);
38
+ var internalId = useId();
39
+ var inputId = id || "input-".concat(internalId);
40
+ var isSearch = type === "search";
41
+ var isPassword = type === "password";
42
+ var localRef = useRef(null);
43
+ // Keep our own ref for imperative work (clear/focus) and forward the node
44
+ // to the consumer's ref, whether it is an object ref or a callback ref.
45
+ var setRefs = useCallback(function (node) {
46
+ localRef.current = node;
47
+ if (typeof forwardedRef === "function") forwardedRef(node);else if (forwardedRef) forwardedRef.current = node;
48
+ }, [forwardedRef]);
49
+ // track visibility (password)
50
+ var _useState = useState(false),
51
+ _useState2 = _slicedToArray(_useState, 2),
52
+ showPassword = _useState2[0],
53
+ setShowPassword = _useState2[1];
54
+ // value length (controlled: derived from `value`; uncontrolled: tracked on change)
55
+ var isControlled = typeof value !== "undefined";
56
+ var _useState3 = useState(function () {
57
+ return typeof defaultValue !== "undefined" ? String(defaultValue !== null && defaultValue !== void 0 ? defaultValue : "").length : 0;
58
+ }),
59
+ _useState4 = _slicedToArray(_useState3, 2),
60
+ uncontrolledLength = _useState4[0],
61
+ setUncontrolledLength = _useState4[1];
62
+ var currentLength = isControlled ? String(value !== null && value !== void 0 ? value : "").length : uncontrolledLength;
63
+ var handleChange = function handleChange(e) {
64
+ var _e$target$value;
65
+ var val = (_e$target$value = e.target.value) !== null && _e$target$value !== void 0 ? _e$target$value : "";
66
+ if (!isControlled) setUncontrolledLength(val.length);
67
+ onChange === null || onChange === void 0 || onChange(e);
68
+ };
69
+ var handleClear = function handleClear(e) {
70
+ var _localRef$current, _localRef$current$foc;
71
+ e === null || e === void 0 || e.preventDefault();
72
+ if (isControlled) {
73
+ // controlled — notify parent
74
+ onChange === null || onChange === void 0 || onChange({
75
+ target: {
76
+ value: ""
77
+ }
78
+ });
79
+ } else if (localRef.current) {
80
+ localRef.current.value = "";
81
+ // update local state
82
+ setUncontrolledLength(0);
83
+ }
84
+ (_localRef$current = localRef.current) === null || _localRef$current === void 0 || (_localRef$current$foc = _localRef$current.focus) === null || _localRef$current$foc === void 0 || _localRef$current$foc.call(_localRef$current);
85
+ onClear === null || onClear === void 0 || onClear();
86
+ };
87
+ // padding logic: left and right padding depend on icons/buttons visible
88
+ var leftHasIcon = Boolean(icon && iconPosition === "left") || isSearch;
89
+ var rightHasIcon = Boolean(icon && iconPosition === "right") || isPassword || clearable && currentLength > 0;
90
+ var paddingClass = cn(leftHasIcon ? "pl-10" : "pl-3", rightHasIcon ? "pr-12" : "pr-3");
91
+ var baseClasses = cn("w-full rounded-md border bg-white text-sm placeholder-gray-400 disabled:opacity-50", "h-10 leading-10",
92
+ // consistent height
93
+ paddingClass, error ? "border-red-500 focus:ring-red-500" : "border-gray-300", success ? "border-green-500 focus:ring-green-500" : "", className);
94
+ var inputType = isPassword && showPassword ? "text" : type;
95
+ return jsxs("div", {
96
+ className: "w-full",
97
+ children: [label && jsxs("label", {
98
+ htmlFor: inputId,
99
+ className: "block text-sm font-medium mb-1",
100
+ children: [label, required && jsx("span", {
101
+ className: "text-error-500 ml-1",
102
+ children: "*"
103
+ })]
104
+ }), jsxs("div", {
105
+ className: "relative",
106
+ children: [leftHasIcon && jsx("div", {
107
+ className: "absolute left-3 top-1/2 transform -translate-y-1/2 pointer-events-none",
108
+ children: isSearch ? jsx(Search, {
109
+ className: "h-4 w-4 text-primary-400"
110
+ }) : jsx("span", {
111
+ className: "text-primary-400",
112
+ children: icon
113
+ })
114
+ }), jsx("input", _objectSpread2({
115
+ id: inputId,
116
+ ref: setRefs,
117
+ type: inputType,
118
+ className: baseClasses,
119
+ placeholder: placeholder,
120
+ disabled: disabled,
121
+ readOnly: readOnly,
122
+ "aria-invalid": !!error,
123
+ "aria-describedby": error ? "".concat(inputId, "-error") : success ? "".concat(inputId, "-success") : helperText ? "".concat(inputId, "-helper") : undefined,
124
+ maxLength: maxLength,
125
+ onChange: handleChange,
126
+ value: value,
127
+ defaultValue: defaultValue
128
+ }, rest)), icon && iconPosition === "right" && !isPassword && !(clearable && currentLength > 0) && jsx("div", {
129
+ className: "absolute right-3 top-1/2 transform -translate-y-1/2 pointer-events-none text-primary-400",
130
+ children: icon
131
+ }), isPassword && jsx("button", {
132
+ type: "button",
133
+ className: "absolute right-3 top-1/2 transform -translate-y-1/2 text-primary-500",
134
+ onClick: function onClick() {
135
+ return setShowPassword(function (s) {
136
+ return !s;
137
+ });
138
+ },
139
+ "aria-label": showPassword ? "Hide password" : "Show password",
140
+ disabled: disabled,
141
+ children: showPassword ? jsx(EyeOff, {
142
+ className: "h-4 w-4"
143
+ }) : jsx(Eye, {
144
+ className: "h-4 w-4"
145
+ })
146
+ }), clearable && currentLength > 0 && !isPassword && jsx("button", {
147
+ type: "button",
148
+ className: "absolute right-3 top-1/2 transform -translate-y-1/2 text-primary-500",
149
+ onClick: handleClear,
150
+ "aria-label": "Clear input",
151
+ disabled: disabled,
152
+ children: jsx(X, {
153
+ className: "h-4 w-4"
154
+ })
155
+ })]
156
+ }), error && jsx("p", {
157
+ id: "".concat(inputId, "-error"),
158
+ className: "mt-1 text-sm text-error-600",
159
+ "aria-live": "polite",
160
+ children: error
161
+ }), !error && success && jsx("p", {
162
+ id: "".concat(inputId, "-success"),
163
+ className: "mt-1 text-sm text-success-600",
164
+ "aria-live": "polite",
165
+ children: success
166
+ }), !error && !success && helperText && jsx("p", {
167
+ id: "".concat(inputId, "-helper"),
168
+ className: "mt-1 text-sm text-muted",
169
+ children: helperText
170
+ }), showCount && maxLength && jsxs("div", {
171
+ className: "mt-1 text-right text-xs text-primary-500",
172
+ "aria-hidden": true,
173
+ children: [currentLength, "/", maxLength]
174
+ })]
175
+ });
176
+ });
177
+ Input.displayName = "Input";
178
+
179
+ export { Input as default };
@@ -0,0 +1,141 @@
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 } from 'react';
5
+ import { cn } from '../../utils/cn.js';
6
+
7
+ var _excluded = ["size", "speed", "thickness", "color", "secondaryColor", "variant", "className", "inline", "ariaLabel", "text", "reverse", "style"];
8
+ var sizeToPx = function sizeToPx(size) {
9
+ if (!size) return 24;
10
+ if (typeof size === "number") return size;
11
+ switch (size) {
12
+ case "sm":
13
+ return 14;
14
+ case "md":
15
+ return 20;
16
+ case "lg":
17
+ return 36;
18
+ default:
19
+ return 24;
20
+ }
21
+ };
22
+ var Loader = /*#__PURE__*/forwardRef(function Loader(_ref, ref) {
23
+ var _ref$size = _ref.size,
24
+ size = _ref$size === void 0 ? "md" : _ref$size,
25
+ _ref$speed = _ref.speed,
26
+ speed = _ref$speed === void 0 ? 0.9 : _ref$speed,
27
+ _ref$thickness = _ref.thickness,
28
+ thickness = _ref$thickness === void 0 ? 2.5 : _ref$thickness,
29
+ _ref$color = _ref.color,
30
+ color = _ref$color === void 0 ? "currentColor" : _ref$color,
31
+ _ref$secondaryColor = _ref.secondaryColor,
32
+ secondaryColor = _ref$secondaryColor === void 0 ? "rgba(0,0,0,0.08)" : _ref$secondaryColor,
33
+ _ref$variant = _ref.variant,
34
+ variant = _ref$variant === void 0 ? "spinner" : _ref$variant,
35
+ _ref$className = _ref.className,
36
+ className = _ref$className === void 0 ? "" : _ref$className,
37
+ _ref$inline = _ref.inline,
38
+ inline = _ref$inline === void 0 ? false : _ref$inline,
39
+ _ref$ariaLabel = _ref.ariaLabel,
40
+ ariaLabel = _ref$ariaLabel === void 0 ? "Loading" : _ref$ariaLabel,
41
+ text = _ref.text,
42
+ _ref$reverse = _ref.reverse,
43
+ reverse = _ref$reverse === void 0 ? false : _ref$reverse,
44
+ style = _ref.style,
45
+ rest = _objectWithoutProperties(_ref, _excluded);
46
+ var px = sizeToPx(size);
47
+ var wrapperClass = cn(inline ? "inline-flex" : "flex", "items-center gap-2", className);
48
+ // animation attributes for SVG rotate
49
+ var animDur = "".concat(speed, "s");
50
+ var rotateFrom = reverse ? "360 12 12" : "0 12 12";
51
+ var rotateTo = reverse ? "0 12 12" : "360 12 12";
52
+ return jsxs("div", _objectSpread2(_objectSpread2({
53
+ ref: ref,
54
+ role: "progressbar",
55
+ "aria-label": ariaLabel,
56
+ className: wrapperClass,
57
+ style: style
58
+ }, rest), {}, {
59
+ children: [jsx("style", {
60
+ children: "\n @keyframes loader-bounce {\n 0%, 80%, 100% { transform: translateY(0); opacity: 0.9 }\n 40% { transform: translateY(-6px); opacity: 1 }\n }\n @keyframes loader-bar {\n 0% { transform: translateX(-35%); }\n 100% { transform: translateX(135%); }\n }\n "
61
+ }), variant === "spinner" && jsxs("svg", {
62
+ width: px,
63
+ height: px,
64
+ viewBox: "0 0 24 24",
65
+ fill: "none",
66
+ style: {
67
+ display: "block"
68
+ },
69
+ xmlns: "http://www.w3.org/2000/svg",
70
+ children: [jsx("circle", {
71
+ cx: "12",
72
+ cy: "12",
73
+ r: 10 - thickness,
74
+ stroke: secondaryColor,
75
+ strokeWidth: thickness
76
+ }), jsx("path", {
77
+ d: "M22 12a10 10 0 0 0-10-10",
78
+ stroke: color,
79
+ strokeWidth: thickness,
80
+ strokeLinecap: "round",
81
+ strokeLinejoin: "round",
82
+ strokeDasharray: "24",
83
+ children: jsx("animateTransform", {
84
+ attributeName: "transform",
85
+ attributeType: "XML",
86
+ type: "rotate",
87
+ from: rotateFrom,
88
+ to: rotateTo,
89
+ dur: animDur,
90
+ repeatCount: "indefinite"
91
+ })
92
+ })]
93
+ }), variant === "dots" && jsx("div", {
94
+ style: {
95
+ display: "inline-flex",
96
+ alignItems: "center",
97
+ gap: Math.max(2, Math.round(px / 8))
98
+ },
99
+ children: [0, 1, 2].map(function (i) {
100
+ return jsx("span", {
101
+ "aria-hidden": true,
102
+ style: {
103
+ width: px / 4,
104
+ height: px / 4,
105
+ borderRadius: "9999px",
106
+ display: "inline-block",
107
+ background: color,
108
+ animation: "loader-bounce ".concat(speed, "s ").concat(i * (speed / 6), "s infinite ease-in-out")
109
+ }
110
+ }, i);
111
+ })
112
+ }), variant === "bar" && jsx("div", {
113
+ "aria-hidden": true,
114
+ style: {
115
+ width: Math.max(72, px * 2.5),
116
+ height: Math.max(6, px / 6),
117
+ background: secondaryColor,
118
+ overflow: "hidden",
119
+ borderRadius: 9999,
120
+ position: "relative"
121
+ },
122
+ children: jsx("div", {
123
+ style: {
124
+ position: "absolute",
125
+ left: 0,
126
+ top: 0,
127
+ bottom: 0,
128
+ width: "35%",
129
+ background: "linear-gradient(90deg, ".concat(color, ", ").concat(secondaryColor, ")"),
130
+ transform: "translateX(-35%)",
131
+ animation: "loader-bar ".concat(speed, "s linear infinite")
132
+ }
133
+ })
134
+ }), text && jsx("span", {
135
+ className: "text-sm text-primary-500",
136
+ children: text
137
+ })]
138
+ }));
139
+ });
140
+
141
+ export { Loader as default };
@@ -0,0 +1,161 @@
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 React, { forwardRef, useState, cloneElement } from 'react';
5
+ import { cn } from '../../utils/cn.js';
6
+
7
+ var _excluded = ["value", "onChange", "inputProps", "icon", "iconProps", "iconPosition", "placeholder", "className"];
8
+ function formatCoords(coords) {
9
+ if (!coords) return "";
10
+ var lat = Number(coords.lat);
11
+ var lng = Number(coords.lng);
12
+ if (!isFinite(lat) || !isFinite(lng)) return "";
13
+ return "".concat(lat.toFixed(6), ", ").concat(lng.toFixed(6));
14
+ }
15
+ function parseCoords(str) {
16
+ if (!str || typeof str !== "string") return null;
17
+ var parts = str.split(",").map(function (p) {
18
+ return p.trim();
19
+ }).filter(Boolean);
20
+ if (parts.length < 2) return null;
21
+ var lat = parseFloat(parts[0]);
22
+ var lng = parseFloat(parts[1]);
23
+ if (!isFinite(lat) || !isFinite(lng)) return null;
24
+ return {
25
+ lat: lat,
26
+ lng: lng
27
+ };
28
+ }
29
+ var LocationPicker = /*#__PURE__*/forwardRef(function LocationPicker(_ref, ref) {
30
+ var _ref$value = _ref.value,
31
+ value = _ref$value === void 0 ? null : _ref$value,
32
+ onChange = _ref.onChange,
33
+ _ref$inputProps = _ref.inputProps,
34
+ inputProps = _ref$inputProps === void 0 ? {} : _ref$inputProps,
35
+ _ref$icon = _ref.icon,
36
+ icon = _ref$icon === void 0 ? null : _ref$icon,
37
+ _ref$iconProps = _ref.iconProps,
38
+ iconProps = _ref$iconProps === void 0 ? {} : _ref$iconProps,
39
+ _ref$iconPosition = _ref.iconPosition,
40
+ iconPosition = _ref$iconPosition === void 0 ? "right" : _ref$iconPosition,
41
+ _ref$placeholder = _ref.placeholder,
42
+ placeholder = _ref$placeholder === void 0 ? "lat, lng" : _ref$placeholder,
43
+ className = _ref.className,
44
+ rest = _objectWithoutProperties(_ref, _excluded);
45
+ var _useState = useState(function () {
46
+ return formatCoords(value);
47
+ }),
48
+ _useState2 = _slicedToArray(_useState, 2),
49
+ text = _useState2[0],
50
+ setText = _useState2[1];
51
+ // Re-sync the text when the external `value` changes (adjust-during-render
52
+ // pattern, avoids a cascading effect render).
53
+ var _useState3 = useState(value),
54
+ _useState4 = _slicedToArray(_useState3, 2),
55
+ prevValue = _useState4[0],
56
+ setPrevValue = _useState4[1];
57
+ if (value !== prevValue) {
58
+ setPrevValue(value);
59
+ setText(formatCoords(value));
60
+ }
61
+ var handleInputChange = function handleInputChange(e) {
62
+ var newText = e.target.value;
63
+ setText(newText);
64
+ if (typeof inputProps.onChange === "function") {
65
+ try {
66
+ inputProps.onChange(e);
67
+ } catch (_unused) {
68
+ // ignore errors thrown by consumer handlers
69
+ }
70
+ }
71
+ var parsed = parseCoords(newText);
72
+ if (parsed && typeof onChange === "function") onChange(parsed);else if (newText.trim() === "" && typeof onChange === "function") onChange(null);
73
+ };
74
+ var handleGeoSuccess = function handleGeoSuccess(position) {
75
+ var coords = {
76
+ lat: Number(position.coords.latitude),
77
+ lng: Number(position.coords.longitude)
78
+ };
79
+ setText(formatCoords(coords));
80
+ if (typeof onChange === "function") onChange(coords);
81
+ };
82
+ var handleGeoError = function handleGeoError(err) {
83
+ console.error("LocationPicker geolocation error:", err);
84
+ };
85
+ var handleIconClick = function handleIconClick(e) {
86
+ var _navigator;
87
+ if (!((_navigator = navigator) !== null && _navigator !== void 0 && _navigator.geolocation)) {
88
+ console.error("LocationPicker: geolocation not supported in this browser");
89
+ if (typeof iconProps.onClick === "function") {
90
+ try {
91
+ iconProps.onClick(e);
92
+ } catch (_unused2) {
93
+ // ignore errors thrown by consumer handlers
94
+ }
95
+ }
96
+ return;
97
+ }
98
+ navigator.geolocation.getCurrentPosition(handleGeoSuccess, handleGeoError, {
99
+ enableHighAccuracy: true,
100
+ timeout: 10000
101
+ });
102
+ if (typeof iconProps.onClick === "function") {
103
+ try {
104
+ iconProps.onClick(e);
105
+ } catch (_unused3) {
106
+ // ignore errors thrown by consumer handlers
107
+ }
108
+ }
109
+ };
110
+ var DefaultIcon = jsxs("svg", {
111
+ className: "w-4 h-4",
112
+ viewBox: "0 0 24 24",
113
+ fill: "none",
114
+ xmlns: "http://www.w3.org/2000/svg",
115
+ "aria-hidden": "true",
116
+ children: [jsx("path", {
117
+ d: "M12 2C8.686 2 6 4.686 6 8c0 5.25 6 12 6 12s6-6.75 6-12c0-3.314-2.686-6-6-6z",
118
+ stroke: "currentColor",
119
+ strokeWidth: "1.2",
120
+ strokeLinecap: "round",
121
+ strokeLinejoin: "round"
122
+ }), jsx("circle", {
123
+ cx: "12",
124
+ cy: "8",
125
+ r: "2.2",
126
+ stroke: "currentColor",
127
+ strokeWidth: "1.2"
128
+ })]
129
+ });
130
+ var iconButton = jsx("button", _objectSpread2(_objectSpread2({
131
+ type: "button",
132
+ onClick: handleIconClick
133
+ }, iconProps), {}, {
134
+ "aria-label": iconProps["aria-label"] || "Use my location",
135
+ className: "inline-flex items-center justify-center p-1 focus:outline-none ".concat(iconProps.className || ""),
136
+ children: icon ? /*#__PURE__*/React.isValidElement(icon) ? /*#__PURE__*/cloneElement(icon) : icon : DefaultIcon
137
+ }));
138
+ var inputPaddingClass = iconPosition === "right" ? "pr-10" : "pl-10";
139
+ return jsx("div", _objectSpread2(_objectSpread2({
140
+ className: cn("inline-flex items-center", className)
141
+ }, rest), {}, {
142
+ children: jsxs("div", {
143
+ className: "relative",
144
+ children: [jsx("input", _objectSpread2(_objectSpread2({
145
+ ref: ref,
146
+ type: "text",
147
+ placeholder: placeholder
148
+ }, inputProps), {}, {
149
+ value: text,
150
+ onChange: handleInputChange,
151
+ className: cn("min-w-[200px] rounded-md border border-gray-300 bg-white py-2 px-3 text-sm placeholder-gray-400 shadow-sm focus:border-primary-500 focus:ring-1 focus:ring-primary-500", inputProps.className, inputPaddingClass)
152
+ })), jsx("div", {
153
+ className: cn("absolute inset-y-0 flex items-center", iconPosition === "right" ? "right-2" : "left-2"),
154
+ children: iconButton
155
+ })]
156
+ })
157
+ }));
158
+ });
159
+ LocationPicker.displayName = "LocationPicker";
160
+
161
+ export { LocationPicker as default };
@@ -0,0 +1,171 @@
1
+ 'use client';
2
+ import { objectWithoutProperties as _objectWithoutProperties, slicedToArray as _slicedToArray, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
3
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
+ import React, { useRef, useId, useCallback, useEffect, useLayoutEffect } from 'react';
5
+ import { createPortal } from 'react-dom';
6
+ import { cn } from '../../utils/cn.js';
7
+ import { setRefs, computePosition } from '../../utils/position.js';
8
+ import { useFocusTrap, getFocusable } from '../../hooks/useFocusTrap.js';
9
+ import { useControllableState } from '../../hooks/useControllableState.js';
10
+
11
+ var _excluded = ["trigger", "children", "open", "defaultOpen", "onOpenChange", "placement", "offset", "title", "initialFocusRef", "disabled", "id", "className"];
12
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
13
+ function usePopoverPosition(open, anchorRef, panelRef, placement, offset) {
14
+ useIsomorphicLayoutEffect(function () {
15
+ if (!open) return undefined;
16
+ var update = function update() {
17
+ var _anchorRef$current;
18
+ var anchor = ((_anchorRef$current = anchorRef.current) === null || _anchorRef$current === void 0 ? void 0 : _anchorRef$current.firstElementChild) || anchorRef.current;
19
+ var panel = panelRef.current;
20
+ if (!anchor || !panel) return;
21
+ var size = {
22
+ width: panel.offsetWidth,
23
+ height: panel.offsetHeight
24
+ };
25
+ var _computePosition = computePosition(anchor.getBoundingClientRect(), size, {
26
+ placement: placement,
27
+ offset: offset
28
+ }),
29
+ top = _computePosition.top,
30
+ left = _computePosition.left,
31
+ side = _computePosition.side;
32
+ panel.style.top = "".concat(top, "px");
33
+ panel.style.left = "".concat(left, "px");
34
+ panel.setAttribute("data-side", side);
35
+ };
36
+ update();
37
+ window.addEventListener("resize", update);
38
+ window.addEventListener("scroll", update, true);
39
+ return function () {
40
+ window.removeEventListener("resize", update);
41
+ window.removeEventListener("scroll", update, true);
42
+ };
43
+ }, [open, placement, offset, anchorRef, panelRef]);
44
+ }
45
+ function useOutsideClose(open, anchorRef, panelRef, close) {
46
+ useEffect(function () {
47
+ if (!open) return undefined;
48
+ var onDown = function onDown(e) {
49
+ var _panelRef$current, _anchorRef$current2;
50
+ if ((_panelRef$current = panelRef.current) !== null && _panelRef$current !== void 0 && _panelRef$current.contains(e.target) || (_anchorRef$current2 = anchorRef.current) !== null && _anchorRef$current2 !== void 0 && _anchorRef$current2.contains(e.target)) return;
51
+ close();
52
+ };
53
+ document.addEventListener("mousedown", onDown);
54
+ document.addEventListener("touchstart", onDown);
55
+ return function () {
56
+ document.removeEventListener("mousedown", onDown);
57
+ document.removeEventListener("touchstart", onDown);
58
+ };
59
+ }, [open, anchorRef, panelRef, close]);
60
+ }
61
+ var Popover = /*#__PURE__*/React.forwardRef(function (_ref, _ref2) {
62
+ var _triggerElement$props;
63
+ var trigger = _ref.trigger,
64
+ children = _ref.children,
65
+ openProp = _ref.open,
66
+ _ref$defaultOpen = _ref.defaultOpen,
67
+ defaultOpen = _ref$defaultOpen === void 0 ? false : _ref$defaultOpen,
68
+ onOpenChange = _ref.onOpenChange,
69
+ _ref$placement = _ref.placement,
70
+ placement = _ref$placement === void 0 ? "bottom-start" : _ref$placement,
71
+ _ref$offset = _ref.offset,
72
+ offset = _ref$offset === void 0 ? 8 : _ref$offset,
73
+ title = _ref.title,
74
+ initialFocusRef = _ref.initialFocusRef,
75
+ _ref$disabled = _ref.disabled,
76
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled,
77
+ idProp = _ref.id,
78
+ className = _ref.className,
79
+ props = _objectWithoutProperties(_ref, _excluded);
80
+ var anchorRef = useRef(null);
81
+ var panelRef = useRef(null);
82
+ var reactId = useId();
83
+ var panelId = idProp || "popover-".concat(reactId);
84
+ var titleId = "".concat(panelId, "-title");
85
+ var _useControllableState = useControllableState({
86
+ value: openProp,
87
+ defaultValue: defaultOpen,
88
+ onChange: onOpenChange
89
+ }),
90
+ _useControllableState2 = _slicedToArray(_useControllableState, 2),
91
+ open = _useControllableState2[0],
92
+ setOpen = _useControllableState2[1];
93
+ var close = useCallback(function () {
94
+ return setOpen(false);
95
+ }, [setOpen]);
96
+ var focusTrigger = function focusTrigger() {
97
+ var _getFocusable$;
98
+ return (_getFocusable$ = getFocusable(anchorRef.current)[0]) === null || _getFocusable$ === void 0 ? void 0 : _getFocusable$.focus();
99
+ };
100
+ usePopoverPosition(open, anchorRef, panelRef, placement, offset);
101
+ useOutsideClose(open, anchorRef, panelRef, close);
102
+ useFocusTrap(panelRef, {
103
+ active: open,
104
+ trap: false,
105
+ initialFocusRef: initialFocusRef,
106
+ onEscape: function onEscape() {
107
+ close();
108
+ focusTrigger();
109
+ }
110
+ });
111
+ // Non-modal: tabbing past either end leaves the popover and closes it, with
112
+ // focus continuing from the trigger as if the panel sat right after it.
113
+ var handlePanelKeyDown = function handlePanelKeyDown(e) {
114
+ if (e.key !== "Tab") return;
115
+ var items = getFocusable(panelRef.current);
116
+ var atStart = !items.length || document.activeElement === items[0] || document.activeElement === panelRef.current;
117
+ var atEnd = !items.length || document.activeElement === items[items.length - 1];
118
+ if (e.shiftKey && atStart) {
119
+ e.preventDefault();
120
+ close();
121
+ focusTrigger();
122
+ } else if (!e.shiftKey && atEnd) {
123
+ close();
124
+ focusTrigger();
125
+ }
126
+ };
127
+ var triggerElement = /*#__PURE__*/React.isValidElement(trigger) ? trigger : jsx("button", {
128
+ type: "button",
129
+ children: trigger
130
+ });
131
+ var triggerNode = /*#__PURE__*/React.cloneElement(triggerElement, {
132
+ "aria-haspopup": "dialog",
133
+ "aria-expanded": open,
134
+ "aria-controls": open ? panelId : undefined,
135
+ disabled: (_triggerElement$props = triggerElement.props.disabled) !== null && _triggerElement$props !== void 0 ? _triggerElement$props : disabled,
136
+ onClick: function onClick(e) {
137
+ var _triggerElement$props2, _triggerElement$props3;
138
+ (_triggerElement$props2 = (_triggerElement$props3 = triggerElement.props).onClick) === null || _triggerElement$props2 === void 0 || _triggerElement$props2.call(_triggerElement$props3, e);
139
+ if (!e.defaultPrevented && !disabled) setOpen(!open);
140
+ }
141
+ });
142
+ var content = typeof children === "function" ? children({
143
+ close: close
144
+ }) : children;
145
+ return jsxs(Fragment, {
146
+ children: [jsx("span", {
147
+ ref: anchorRef,
148
+ className: "inline-flex",
149
+ children: triggerNode
150
+ }), open && typeof document !== "undefined" && /*#__PURE__*/createPortal(jsxs("div", _objectSpread2(_objectSpread2({
151
+ ref: function ref(node) {
152
+ return setRefs(node, panelRef, _ref2);
153
+ },
154
+ id: panelId,
155
+ role: "dialog",
156
+ "aria-labelledby": title ? titleId : undefined,
157
+ tabIndex: -1,
158
+ onKeyDown: handlePanelKeyDown,
159
+ className: cn("fixed left-0 top-0 z-50 min-w-[12rem] max-w-sm rounded-lg border border-gray-200 bg-white p-4 text-sm text-gray-900 shadow-lg focus:outline-none", "dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100", "animate-fade-in motion-reduce:animate-none", className)
160
+ }, props), {}, {
161
+ children: [title && jsx("h2", {
162
+ id: titleId,
163
+ className: "mb-2 text-sm font-semibold",
164
+ children: title
165
+ }), content]
166
+ })), document.body)]
167
+ });
168
+ });
169
+ Popover.displayName = "Popover";
170
+
171
+ export { Popover as default };