@dreamtree-org/twreact-ui 1.2.1 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/DESIGN.md +118 -0
  2. package/README.md +231 -44
  3. package/ai-skills/dreamtree-ui.md +98 -12
  4. package/dist/ai-schema.json +452 -17
  5. package/dist/components/blocks/AppShell.d.ts +4 -0
  6. package/dist/components/blocks/AppShell.d.ts.map +1 -0
  7. package/dist/components/blocks/ConfirmDialog.d.ts +4 -0
  8. package/dist/components/blocks/ConfirmDialog.d.ts.map +1 -0
  9. package/dist/components/blocks/EmptyState.d.ts +4 -0
  10. package/dist/components/blocks/EmptyState.d.ts.map +1 -0
  11. package/dist/components/blocks/ErrorState.d.ts +4 -0
  12. package/dist/components/blocks/ErrorState.d.ts.map +1 -0
  13. package/dist/components/blocks/LoadingState.d.ts +9 -0
  14. package/dist/components/blocks/LoadingState.d.ts.map +1 -0
  15. package/dist/components/blocks/PageHeader.d.ts +4 -0
  16. package/dist/components/blocks/PageHeader.d.ts.map +1 -0
  17. package/dist/components/blocks/StatCard.d.ts +4 -0
  18. package/dist/components/blocks/StatCard.d.ts.map +1 -0
  19. package/dist/components/blocks/StatusPill.d.ts +5 -0
  20. package/dist/components/blocks/StatusPill.d.ts.map +1 -0
  21. package/dist/components/core/Accordion.d.ts.map +1 -1
  22. package/dist/components/core/Button.d.ts.map +1 -1
  23. package/dist/components/core/Checkbox.d.ts.map +1 -1
  24. package/dist/components/core/ColorPicker.d.ts.map +1 -1
  25. package/dist/components/core/DatePicker.d.ts.map +1 -1
  26. package/dist/components/core/DateRangePicker.d.ts.map +1 -1
  27. package/dist/components/core/Form.d.ts.map +1 -1
  28. package/dist/components/core/Input.d.ts.map +1 -1
  29. package/dist/components/core/LocationPicker.d.ts.map +1 -1
  30. package/dist/components/core/Popover.d.ts +4 -0
  31. package/dist/components/core/Popover.d.ts.map +1 -0
  32. package/dist/components/core/PriceRangePicker.d.ts.map +1 -1
  33. package/dist/components/core/ProgressBar.d.ts.map +1 -1
  34. package/dist/components/core/Radio.d.ts.map +1 -1
  35. package/dist/components/core/Rate.d.ts.map +1 -1
  36. package/dist/components/core/Select.d.ts.map +1 -1
  37. package/dist/components/core/Skeleton.d.ts.map +1 -1
  38. package/dist/components/core/Slider.d.ts +4 -0
  39. package/dist/components/core/Slider.d.ts.map +1 -0
  40. package/dist/components/core/SpeechToText.d.ts.map +1 -1
  41. package/dist/components/core/Switch.d.ts.map +1 -1
  42. package/dist/components/core/Table/ActionMenu.d.ts.map +1 -1
  43. package/dist/components/core/Table/ColumnMenu.d.ts +2 -1
  44. package/dist/components/core/Table/ColumnMenu.d.ts.map +1 -1
  45. package/dist/components/core/Table/MobileCard.d.ts +2 -2
  46. package/dist/components/core/Table/MobileCard.d.ts.map +1 -1
  47. package/dist/components/core/Table/Table.d.ts.map +1 -1
  48. package/dist/components/core/Table/TableRow.d.ts +4 -2
  49. package/dist/components/core/Table/TableRow.d.ts.map +1 -1
  50. package/dist/components/core/Tabs.d.ts.map +1 -1
  51. package/dist/components/core/Textarea.d.ts +4 -0
  52. package/dist/components/core/Textarea.d.ts.map +1 -0
  53. package/dist/components/core/ThreeDotPopover.d.ts.map +1 -1
  54. package/dist/components/core/Tooltip.d.ts.map +1 -1
  55. package/dist/components/feedback/Dialog.d.ts.map +1 -1
  56. package/dist/components/feedback/Drawer.d.ts +4 -0
  57. package/dist/components/feedback/Drawer.d.ts.map +1 -0
  58. package/dist/components/feedback/Toast.d.ts +14 -5
  59. package/dist/components/feedback/Toast.d.ts.map +1 -1
  60. package/dist/components/feedback/Tour.d.ts +4 -0
  61. package/dist/components/feedback/Tour.d.ts.map +1 -0
  62. package/dist/components/feedback/TourSpotlight.d.ts +9 -0
  63. package/dist/components/feedback/TourSpotlight.d.ts.map +1 -0
  64. package/dist/components/navigation/Breadcrumbs.d.ts.map +1 -1
  65. package/dist/components/navigation/FootNav.d.ts.map +1 -1
  66. package/dist/components/navigation/Navbar.d.ts.map +1 -1
  67. package/dist/components/navigation/Sidebar.d.ts +8 -2
  68. package/dist/components/navigation/Sidebar.d.ts.map +1 -1
  69. package/dist/components/utility/Badge.d.ts.map +1 -1
  70. package/dist/components/utility/FileUpload.d.ts.map +1 -1
  71. package/dist/components/utility/Sortable.d.ts +4 -0
  72. package/dist/components/utility/Sortable.d.ts.map +1 -0
  73. package/dist/esm/_vendor/object-assign/index.js +99 -0
  74. package/dist/esm/_vendor/prop-types/_vendor/react-is/cjs/react-is.development.js +190 -0
  75. package/dist/esm/_vendor/prop-types/_vendor/react-is/cjs/react-is.production.min.js +26 -0
  76. package/dist/esm/_vendor/prop-types/_vendor/react-is/index.js +19 -0
  77. package/dist/esm/_vendor/prop-types/checkPropTypes.js +115 -0
  78. package/dist/esm/_vendor/prop-types/factoryWithThrowingShims.js +74 -0
  79. package/dist/esm/_vendor/prop-types/factoryWithTypeCheckers.js +625 -0
  80. package/dist/esm/_vendor/prop-types/index.js +30 -0
  81. package/dist/esm/_vendor/prop-types/lib/ReactPropTypesSecret.js +21 -0
  82. package/dist/esm/_vendor/prop-types/lib/has.js +11 -0
  83. package/dist/esm/_virtual/_commonjsHelpers.js +5 -0
  84. package/dist/esm/_virtual/_rollupPluginBabelHelpers.js +329 -0
  85. package/dist/esm/_virtual/index.js +3 -0
  86. package/dist/esm/_virtual/index2.js +3 -0
  87. package/dist/esm/_virtual/react-is.development.js +3 -0
  88. package/dist/esm/_virtual/react-is.production.min.js +3 -0
  89. package/dist/esm/components/blocks/AppShell.js +205 -0
  90. package/dist/esm/components/blocks/ConfirmDialog.js +57 -0
  91. package/dist/esm/components/blocks/EmptyState.js +44 -0
  92. package/dist/esm/components/blocks/ErrorState.js +53 -0
  93. package/dist/esm/components/blocks/LoadingState.js +134 -0
  94. package/dist/esm/components/blocks/PageHeader.js +51 -0
  95. package/dist/esm/components/blocks/StatCard.js +79 -0
  96. package/dist/esm/components/blocks/StatusPill.js +55 -0
  97. package/dist/esm/components/core/Accordion.js +260 -0
  98. package/dist/esm/components/core/Button.js +59 -0
  99. package/dist/esm/components/core/Checkbox.js +188 -0
  100. package/dist/esm/components/core/ColorPicker.js +348 -0
  101. package/dist/esm/components/core/DatePicker.js +436 -0
  102. package/dist/esm/components/core/DateRangePicker.js +494 -0
  103. package/dist/esm/components/core/Form.js +522 -0
  104. package/dist/esm/components/core/Input.js +179 -0
  105. package/dist/esm/components/core/Loader.js +141 -0
  106. package/dist/esm/components/core/LocationPicker.js +161 -0
  107. package/dist/esm/components/core/Popover.js +171 -0
  108. package/dist/esm/components/core/PriceRangePicker.js +376 -0
  109. package/dist/esm/components/core/ProgressBar.js +152 -0
  110. package/dist/esm/components/core/Radio.js +156 -0
  111. package/dist/esm/components/core/Rate.js +197 -0
  112. package/dist/esm/components/core/RoundedTag.js +118 -0
  113. package/dist/esm/components/core/Select.js +857 -0
  114. package/dist/esm/components/core/Skeleton.js +100 -0
  115. package/dist/esm/components/core/Slider.js +134 -0
  116. package/dist/esm/components/core/SpeechToText.js +226 -0
  117. package/dist/esm/components/core/Switch.js +207 -0
  118. package/dist/esm/components/core/Table/ActionMenu.js +251 -0
  119. package/dist/esm/components/core/Table/ColumnMenu.js +55 -0
  120. package/dist/esm/components/core/Table/FieldInput.js +157 -0
  121. package/dist/esm/components/core/Table/MobileCard.js +187 -0
  122. package/dist/esm/components/core/Table/MobileFilters.js +72 -0
  123. package/dist/esm/components/core/Table/Pagination.js +157 -0
  124. package/dist/esm/components/core/Table/Table.js +1533 -0
  125. package/dist/esm/components/core/Table/TableRow.js +254 -0
  126. package/dist/esm/components/core/Table/constants.js +35 -0
  127. package/dist/esm/components/core/Table/helpers.js +124 -0
  128. package/dist/esm/components/core/Table/useClickOutside.js +26 -0
  129. package/dist/esm/components/core/Tabs.js +289 -0
  130. package/dist/esm/components/core/TextToSpeech.js +52 -0
  131. package/dist/esm/components/core/Textarea.js +125 -0
  132. package/dist/esm/components/core/ThreeDotPopover.js +160 -0
  133. package/dist/esm/components/core/Tooltip.js +372 -0
  134. package/dist/esm/components/feedback/Alert.js +96 -0
  135. package/dist/esm/components/feedback/Dialog.js +200 -0
  136. package/dist/esm/components/feedback/Drawer.js +171 -0
  137. package/dist/esm/components/feedback/Toast.js +362 -0
  138. package/dist/esm/components/feedback/Tour.js +214 -0
  139. package/dist/esm/components/feedback/TourSpotlight.js +71 -0
  140. package/dist/esm/components/navigation/Breadcrumbs.js +75 -0
  141. package/dist/esm/components/navigation/Dropdown.js +53 -0
  142. package/dist/esm/components/navigation/FootNav.js +51 -0
  143. package/dist/esm/components/navigation/Navbar.js +437 -0
  144. package/dist/esm/components/navigation/Sidebar.js +567 -0
  145. package/dist/esm/components/utility/Avatar.js +89 -0
  146. package/dist/esm/components/utility/Badge.js +47 -0
  147. package/dist/esm/components/utility/Card.js +85 -0
  148. package/dist/esm/components/utility/Carousel.js +97 -0
  149. package/dist/esm/components/utility/Condition.js +9 -0
  150. package/dist/esm/components/utility/FileUpload.js +177 -0
  151. package/dist/esm/components/utility/Pagination.js +111 -0
  152. package/dist/esm/components/utility/Sortable.js +190 -0
  153. package/dist/esm/components/utility/Stepper.js +101 -0
  154. package/dist/esm/hooks/useApi.js +169 -0
  155. package/dist/esm/hooks/useControllableState.js +32 -0
  156. package/dist/esm/hooks/useFocusTrap.js +85 -0
  157. package/dist/esm/hooks/useLatestRef.js +20 -0
  158. package/dist/esm/hooks/useMixins.js +100 -0
  159. package/dist/esm/hooks/useScrollLock.js +26 -0
  160. package/dist/esm/hooks/useSliderValues.js +135 -0
  161. package/dist/esm/hooks/useSortable.js +188 -0
  162. package/dist/esm/hooks/useTheme.js +53 -0
  163. package/dist/esm/hooks/useTourTarget.js +92 -0
  164. package/dist/esm/index.js +65 -0
  165. package/dist/esm/store/index.js +26 -0
  166. package/dist/esm/store/store.js +107 -0
  167. package/dist/esm/store/storeSlice.js +45 -0
  168. package/dist/esm/utils/cn.js +11 -0
  169. package/dist/esm/utils/emitter.js +169 -0
  170. package/dist/esm/utils/helpers.js +161 -0
  171. package/dist/esm/utils/position.js +134 -0
  172. package/dist/hooks/useApi.d.ts +2 -1
  173. package/dist/hooks/useApi.d.ts.map +1 -1
  174. package/dist/hooks/useControllableState.d.ts +11 -0
  175. package/dist/hooks/useControllableState.d.ts.map +1 -0
  176. package/dist/hooks/useFocusTrap.d.ts +15 -0
  177. package/dist/hooks/useFocusTrap.d.ts.map +1 -0
  178. package/dist/hooks/useLatestRef.d.ts +8 -0
  179. package/dist/hooks/useLatestRef.d.ts.map +1 -0
  180. package/dist/hooks/useMixins.d.ts.map +1 -1
  181. package/dist/hooks/useScrollLock.d.ts +2 -0
  182. package/dist/hooks/useScrollLock.d.ts.map +1 -0
  183. package/dist/hooks/useSliderValues.d.ts +43 -0
  184. package/dist/hooks/useSliderValues.d.ts.map +1 -0
  185. package/dist/hooks/useSortable.d.ts +32 -0
  186. package/dist/hooks/useSortable.d.ts.map +1 -0
  187. package/dist/hooks/useTheme.d.ts.map +1 -1
  188. package/dist/hooks/useTourTarget.d.ts +15 -0
  189. package/dist/hooks/useTourTarget.d.ts.map +1 -0
  190. package/dist/index.css +1 -1
  191. package/dist/index.d.ts +55 -39
  192. package/dist/index.esm.css +1 -1
  193. package/dist/index.esm.js +7937 -4659
  194. package/dist/index.js +7950 -4657
  195. package/dist/tokens/brands/default.css +1 -0
  196. package/dist/tokens/brands/default.json +5 -0
  197. package/dist/tokens/brands/practicepro.css +17 -0
  198. package/dist/tokens/brands/practicepro.json +27 -0
  199. package/dist/tokens/tailwind3-preset.cjs +214 -0
  200. package/dist/tokens/theme.css +193 -0
  201. package/dist/tokens/tokens.json +373 -0
  202. package/dist/tokens/vars.css +98 -0
  203. package/dist/types/blocks.d.ts +109 -0
  204. package/dist/types/blocks.d.ts.map +1 -0
  205. package/dist/types/index.d.ts +194 -5
  206. package/dist/types/index.d.ts.map +1 -1
  207. package/dist/utils/position.d.ts +30 -0
  208. package/dist/utils/position.d.ts.map +1 -0
  209. package/doc/README.md +26 -1
  210. package/mcp/catalog.snapshot.json +1643 -549
  211. package/package.json +24 -6
  212. package/tokens/brands/default.json +5 -0
  213. package/tokens/brands/practicepro.json +27 -0
  214. package/tokens/lib.cjs +128 -0
  215. package/tokens/tokens.json +133 -0
@@ -0,0 +1,522 @@
1
+ 'use client';
2
+ import { objectWithoutProperties as _objectWithoutProperties, slicedToArray as _slicedToArray, objectSpread2 as _objectSpread2, typeof as _typeof, defineProperty as _defineProperty } from '../../_virtual/_rollupPluginBabelHelpers.js';
3
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
+ import { forwardRef, useCallback, useState, useId } from 'react';
5
+ import { useForm, FormProvider, Controller } from 'react-hook-form';
6
+ import { cn } from '../../utils/cn.js';
7
+ import Input from './Input.js';
8
+ import Select from './Select.js';
9
+ import DatePicker from './DatePicker.js';
10
+ import Button from './Button.js';
11
+ import Switch from './Switch.js';
12
+ import ColorPicker from './ColorPicker.js';
13
+
14
+ var _excluded = ["fields", "onSubmit", "defaultValues", "validationSchema", "className", "submitText", "resetText", "submitButtonClass", "resetButtonClass", "showReset", "submitDisabled"],
15
+ _excluded2 = ["type", "name", "label", "required", "options", "placeholder", "helperText"],
16
+ _excluded3 = ["onChange", "ref", "value"];
17
+ /**
18
+ * Error / helper line rendered under Form-owned field markup (textarea,
19
+ * checkbox, radio, file, switch, color). Mirrors Input / Select / DatePicker:
20
+ * the error replaces the helper text while present, and the rendered line's
21
+ * id is what the control's `aria-describedby` points at.
22
+ */
23
+ var FieldMessage = function FieldMessage(_ref) {
24
+ var fieldId = _ref.fieldId,
25
+ error = _ref.error,
26
+ helperText = _ref.helperText;
27
+ if (error) {
28
+ return jsx("p", {
29
+ id: "".concat(fieldId, "-error"),
30
+ className: "mt-1 text-sm text-error-500",
31
+ children: error
32
+ });
33
+ }
34
+ if (helperText) {
35
+ return jsx("p", {
36
+ id: "".concat(fieldId, "-helper"),
37
+ className: "mt-1 text-sm text-muted",
38
+ children: helperText
39
+ });
40
+ }
41
+ return null;
42
+ };
43
+ var describedByFor = function describedByFor(fieldId, error, helperText) {
44
+ return error ? "".concat(fieldId, "-error") : helperText ? "".concat(fieldId, "-helper") : undefined;
45
+ };
46
+ var Form = /*#__PURE__*/forwardRef(function Form(_ref2, ref) {
47
+ var _ref2$fields = _ref2.fields,
48
+ fields = _ref2$fields === void 0 ? [] : _ref2$fields,
49
+ onSubmit = _ref2.onSubmit,
50
+ _ref2$defaultValues = _ref2.defaultValues,
51
+ defaultValues = _ref2$defaultValues === void 0 ? {} : _ref2$defaultValues,
52
+ validationSchema = _ref2.validationSchema,
53
+ className = _ref2.className,
54
+ _ref2$submitText = _ref2.submitText,
55
+ submitText = _ref2$submitText === void 0 ? "Submit" : _ref2$submitText,
56
+ _ref2$resetText = _ref2.resetText,
57
+ resetText = _ref2$resetText === void 0 ? "Reset" : _ref2$resetText,
58
+ submitButtonClass = _ref2.submitButtonClass,
59
+ resetButtonClass = _ref2.resetButtonClass,
60
+ _ref2$showReset = _ref2.showReset,
61
+ showReset = _ref2$showReset === void 0 ? true : _ref2$showReset,
62
+ _ref2$submitDisabled = _ref2.submitDisabled,
63
+ submitDisabled = _ref2$submitDisabled === void 0 ? false : _ref2$submitDisabled,
64
+ props = _objectWithoutProperties(_ref2, _excluded);
65
+ var methods = useForm({
66
+ defaultValues: defaultValues,
67
+ resolver: validationSchema
68
+ });
69
+ var handleSubmit = methods.handleSubmit,
70
+ reset = methods.reset,
71
+ control = methods.control,
72
+ _methods$formState = methods.formState,
73
+ errors = _methods$formState.errors,
74
+ isSubmitting = _methods$formState.isSubmitting;
75
+ var handleFormSubmit = useCallback(function (data) {
76
+ onSubmit === null || onSubmit === void 0 || onSubmit(data);
77
+ }, [onSubmit]);
78
+ var handleReset = useCallback(function () {
79
+ reset(defaultValues);
80
+ }, [reset, defaultValues]);
81
+ // NEW: File input preview state
82
+ var _useState = useState({}),
83
+ _useState2 = _slicedToArray(_useState, 2),
84
+ filePreviews = _useState2[0],
85
+ setFilePreviews = _useState2[1];
86
+ var formId = useId();
87
+ var renderField = function renderField(field) {
88
+ var _errors$name;
89
+ var type = field.type,
90
+ name = field.name,
91
+ label = field.label,
92
+ required = field.required,
93
+ options = field.options,
94
+ placeholder = field.placeholder,
95
+ helperText = field.helperText,
96
+ fieldProps = _objectWithoutProperties(field, _excluded2);
97
+ var error = (_errors$name = errors[name]) === null || _errors$name === void 0 ? void 0 : _errors$name.message;
98
+ // Stable per-field id for Form-owned markup (label <-> control, helper).
99
+ var fieldId = "".concat(formId, "-").concat(name);
100
+ var describedBy = describedByFor(fieldId, error, helperText);
101
+ // `options` is a choice list (array) for select / radio fields, and only
102
+ // those consume it. A plain-object `options` is the documented escape
103
+ // hatch for extra component props and is still spread. An array must
104
+ // never be spread: it leaked index keys ("0", "1", …) as props/attributes.
105
+ var extraProps = options && _typeof(options) === "object" && !Array.isArray(options) ? options : undefined;
106
+ var commonProps = _objectSpread2(_objectSpread2({
107
+ name: name,
108
+ label: label,
109
+ required: required,
110
+ error: error,
111
+ placeholder: placeholder
112
+ }, fieldProps), extraProps);
113
+ switch (type) {
114
+ case "text":
115
+ case "email":
116
+ case "password":
117
+ case "number":
118
+ case "tel":
119
+ case "url":
120
+ return jsx(Controller, {
121
+ name: name,
122
+ control: control,
123
+ render: function render(_ref3) {
124
+ var _ref3$field = _ref3.field,
125
+ onChange = _ref3$field.onChange,
126
+ value = _ref3$field.value,
127
+ ref = _ref3$field.ref;
128
+ return jsx(Input, _objectSpread2({
129
+ type: type,
130
+ value: value || "",
131
+ onChange: onChange,
132
+ ref: ref,
133
+ helperText: helperText
134
+ }, commonProps));
135
+ }
136
+ }, name);
137
+ case "select":
138
+ return jsx(Controller, {
139
+ name: name,
140
+ control: control,
141
+ render: function render(_ref4) {
142
+ var _ref4$field = _ref4.field,
143
+ onChange = _ref4$field.onChange,
144
+ value = _ref4$field.value,
145
+ ref = _ref4$field.ref;
146
+ return jsx(Select, _objectSpread2({
147
+ value: value,
148
+ onChange: onChange,
149
+ ref: ref,
150
+ options: options,
151
+ helperText: helperText
152
+ }, commonProps));
153
+ }
154
+ }, name);
155
+ case "date":
156
+ return jsx(Controller, {
157
+ name: name,
158
+ control: control,
159
+ render: function render(_ref5) {
160
+ var _ref5$field = _ref5.field,
161
+ onChange = _ref5$field.onChange,
162
+ value = _ref5$field.value,
163
+ ref = _ref5$field.ref;
164
+ return jsx(DatePicker, _objectSpread2({
165
+ value: value,
166
+ onChange: onChange,
167
+ ref: ref,
168
+ helperText: helperText
169
+ }, commonProps));
170
+ }
171
+ }, name);
172
+ case "textarea":
173
+ return jsx(Controller, {
174
+ name: name,
175
+ control: control,
176
+ render: function render(_ref6) {
177
+ var _ref6$field = _ref6.field,
178
+ onChange = _ref6$field.onChange,
179
+ value = _ref6$field.value,
180
+ ref = _ref6$field.ref;
181
+ return jsxs("div", {
182
+ className: "w-full",
183
+ children: [label && jsxs("label", {
184
+ htmlFor: fieldId,
185
+ className: "block text-sm font-medium mb-1",
186
+ children: [label, required && jsx("span", {
187
+ className: "text-error-500 ml-1",
188
+ children: "*"
189
+ })]
190
+ }), jsx("textarea", {
191
+ ref: ref,
192
+ id: fieldId,
193
+ "aria-invalid": error ? true : undefined,
194
+ "aria-describedby": describedBy,
195
+ className: cn("flex w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm placeholder:text-primary-400 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50", {
196
+ "border-error-500 focus:ring-error-500": error
197
+ }),
198
+ placeholder: placeholder,
199
+ required: required,
200
+ rows: fieldProps.rows || 3,
201
+ value: value || "",
202
+ onChange: onChange
203
+ }), jsx(FieldMessage, {
204
+ fieldId: fieldId,
205
+ error: error,
206
+ helperText: helperText
207
+ })]
208
+ });
209
+ }
210
+ }, name);
211
+ case "checkbox":
212
+ return jsx(Controller, {
213
+ name: name,
214
+ control: control,
215
+ render: function render(_ref7) {
216
+ var _ref7$field = _ref7.field,
217
+ _onChange = _ref7$field.onChange,
218
+ value = _ref7$field.value,
219
+ ref = _ref7$field.ref;
220
+ return jsxs("div", {
221
+ className: "w-full",
222
+ children: [jsxs("div", {
223
+ className: "flex items-center",
224
+ children: [jsx("input", {
225
+ ref: ref,
226
+ id: fieldId,
227
+ type: "checkbox",
228
+ checked: !!value,
229
+ onChange: function onChange(e) {
230
+ return _onChange(e.target.checked);
231
+ },
232
+ "aria-invalid": error ? true : undefined,
233
+ "aria-describedby": describedBy,
234
+ className: "rounded border-gray-300 text-primary-600 focus:ring-primary-500"
235
+ }), label && jsxs("label", {
236
+ htmlFor: fieldId,
237
+ className: "ml-2 text-sm",
238
+ children: [label, required && jsx("span", {
239
+ className: "text-error-500 ml-1",
240
+ children: "*"
241
+ })]
242
+ })]
243
+ }), jsx(FieldMessage, {
244
+ fieldId: fieldId,
245
+ error: error,
246
+ helperText: helperText
247
+ })]
248
+ });
249
+ }
250
+ }, name);
251
+ case "radio":
252
+ return jsx(Controller, {
253
+ name: name,
254
+ control: control,
255
+ render: function render(_ref8) {
256
+ var _ref8$field = _ref8.field,
257
+ _onChange2 = _ref8$field.onChange,
258
+ value = _ref8$field.value,
259
+ ref = _ref8$field.ref;
260
+ return jsxs("div", {
261
+ className: "w-full",
262
+ children: [label && jsxs("label", {
263
+ className: "block text-sm font-medium mb-2",
264
+ children: [label, required && jsx("span", {
265
+ className: "text-error-500 ml-1",
266
+ children: "*"
267
+ })]
268
+ }), jsx("div", {
269
+ className: "space-y-2",
270
+ role: "radiogroup",
271
+ "aria-label": typeof label === "string" ? label : undefined,
272
+ "aria-describedby": describedBy,
273
+ children: options === null || options === void 0 ? void 0 : options.map(function (option) {
274
+ return jsxs("div", {
275
+ className: "flex items-center",
276
+ children: [jsx("input", {
277
+ ref: ref,
278
+ type: "radio",
279
+ checked: value === option.value,
280
+ onChange: function onChange() {
281
+ return _onChange2(option.value);
282
+ },
283
+ className: "text-primary-600 focus:ring-primary-500"
284
+ }), jsx("label", {
285
+ className: "ml-2 text-sm",
286
+ children: option.label
287
+ })]
288
+ }, option.value);
289
+ })
290
+ }), jsx(FieldMessage, {
291
+ fieldId: fieldId,
292
+ error: error,
293
+ helperText: helperText
294
+ })]
295
+ });
296
+ }
297
+ }, name);
298
+ // NEW: File input type
299
+ case "file":
300
+ return jsx(Controller, {
301
+ name: name,
302
+ control: control,
303
+ render: function render(_ref9) {
304
+ var _ref9$field = _ref9.field,
305
+ _onChange3 = _ref9$field.onChange,
306
+ ref = _ref9$field.ref,
307
+ value = _ref9$field.value,
308
+ field = _objectWithoutProperties(_ref9$field, _excluded3);
309
+ return jsxs("div", {
310
+ className: "w-full",
311
+ children: [label && jsxs("label", {
312
+ className: "block text-sm font-medium mb-1",
313
+ children: [label, required && jsx("span", {
314
+ className: "text-error-500 ml-1",
315
+ children: "*"
316
+ })]
317
+ }), jsxs("div", {
318
+ className: "mt-1 flex items-center",
319
+ children: [jsxs("label", {
320
+ htmlFor: name,
321
+ className: cn("cursor-pointer inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500", {
322
+ "border-error-500": error
323
+ }),
324
+ children: [jsx("svg", {
325
+ className: "-ml-1 mr-2 h-5 w-5 text-primary-400",
326
+ fill: "none",
327
+ stroke: "currentColor",
328
+ viewBox: "0 0 24 24",
329
+ xmlns: "http://www.w3.org/2000/svg",
330
+ children: jsx("path", {
331
+ strokeLinecap: "round",
332
+ strokeLinejoin: "round",
333
+ strokeWidth: 2,
334
+ d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
335
+ })
336
+ }), "Choose File"]
337
+ }), jsx("input", _objectSpread2(_objectSpread2({}, field), {}, {
338
+ id: name,
339
+ ref: ref,
340
+ type: "file",
341
+ "aria-describedby": describedBy,
342
+ className: "sr-only",
343
+ onChange: function onChange(e) {
344
+ var _e$target$files;
345
+ var file = (_e$target$files = e.target.files) === null || _e$target$files === void 0 ? void 0 : _e$target$files[0];
346
+ _onChange3(file);
347
+ // Create preview for image files
348
+ if (file && file.type.startsWith("image/")) {
349
+ var reader = new FileReader();
350
+ reader.onloadend = function () {
351
+ setFilePreviews(function (prev) {
352
+ return _objectSpread2(_objectSpread2({}, prev), {}, _defineProperty({}, name, reader.result));
353
+ });
354
+ };
355
+ reader.readAsDataURL(file);
356
+ } else {
357
+ setFilePreviews(function (prev) {
358
+ return _objectSpread2(_objectSpread2({}, prev), {}, _defineProperty({}, name, null));
359
+ });
360
+ }
361
+ },
362
+ accept: fieldProps.accept,
363
+ multiple: fieldProps.multiple
364
+ })), jsx("span", {
365
+ className: "ml-3 text-sm text-primary-500",
366
+ children: (value === null || value === void 0 ? void 0 : value.name) || "No file chosen"
367
+ }), value && jsx("button", {
368
+ type: "button",
369
+ onClick: function onClick() {
370
+ _onChange3(null);
371
+ setFilePreviews(function (prev) {
372
+ return _objectSpread2(_objectSpread2({}, prev), {}, _defineProperty({}, name, null));
373
+ });
374
+ },
375
+ className: "ml-3 text-sm text-error-600 hover:text-error-800",
376
+ children: "Remove"
377
+ })]
378
+ }), filePreviews[name] && jsx("div", {
379
+ className: "mt-3",
380
+ children: jsx("img", {
381
+ src: filePreviews[name],
382
+ alt: "Preview",
383
+ className: "h-32 w-32 object-cover rounded"
384
+ })
385
+ }), fieldProps.accept && jsxs("p", {
386
+ className: "mt-1 text-xs text-primary-500",
387
+ children: ["Accepted: ", fieldProps.accept]
388
+ }), jsx(FieldMessage, {
389
+ fieldId: fieldId,
390
+ error: error,
391
+ helperText: helperText
392
+ })]
393
+ });
394
+ }
395
+ }, name);
396
+ case "switch":
397
+ return jsx(Controller, {
398
+ name: name,
399
+ control: control,
400
+ render: function render(_ref0) {
401
+ var _ref0$field = _ref0.field,
402
+ onChange = _ref0$field.onChange,
403
+ value = _ref0$field.value,
404
+ ref = _ref0$field.ref;
405
+ return jsxs("div", {
406
+ className: "w-full",
407
+ children: [jsx(Switch, _objectSpread2({
408
+ checked: !!value,
409
+ onChange: onChange,
410
+ ref: ref,
411
+ label: label,
412
+ disabled: fieldProps.disabled,
413
+ "aria-describedby": describedBy
414
+ }, commonProps)), jsx(FieldMessage, {
415
+ fieldId: fieldId,
416
+ error: error,
417
+ helperText: helperText
418
+ })]
419
+ });
420
+ }
421
+ }, name);
422
+ // Color field: mounts the library ColorPicker. The stored value is the
423
+ // string ColorPicker emits (`rgb(r, g, b)`, or `rgba(r, g, b, a)` when
424
+ // alpha < 1); any hex / rgb(a) string is
425
+ // accepted as a default value.
426
+ case "color":
427
+ return jsx(Controller, {
428
+ name: name,
429
+ control: control,
430
+ render: function render(_ref1) {
431
+ var _ref1$field = _ref1.field,
432
+ onChange = _ref1$field.onChange,
433
+ value = _ref1$field.value,
434
+ ref = _ref1$field.ref;
435
+ return jsxs("div", {
436
+ className: "w-full",
437
+ children: [jsx(ColorPicker, {
438
+ ref: ref,
439
+ id: fieldId,
440
+ role: "group",
441
+ "aria-label": typeof label === "string" ? label : undefined,
442
+ "aria-describedby": describedBy,
443
+ value: value || undefined,
444
+ onChange: onChange,
445
+ label: jsxs(Fragment, {
446
+ children: [label !== null && label !== void 0 ? label : "Pick a color", required && jsx("span", {
447
+ className: "text-error-500 ml-1",
448
+ children: "*"
449
+ })]
450
+ }),
451
+ swatches: fieldProps.swatches,
452
+ showAlpha: fieldProps.showAlpha,
453
+ size: fieldProps.size,
454
+ disabled: fieldProps.disabled
455
+ }), jsx(FieldMessage, {
456
+ fieldId: fieldId,
457
+ error: error,
458
+ helperText: helperText
459
+ })]
460
+ });
461
+ }
462
+ }, name);
463
+ case "custom":
464
+ return fieldProps.render ? jsx(Controller, {
465
+ name: name,
466
+ control: control,
467
+ render: function render(_ref10) {
468
+ var field = _ref10.field;
469
+ return fieldProps.render(field);
470
+ }
471
+ }, name) : null;
472
+ default:
473
+ return null;
474
+ }
475
+ };
476
+ var renderFieldGroup = function renderFieldGroup(group) {
477
+ if (group.type === "group") {
478
+ return jsxs("div", {
479
+ className: "space-y-4",
480
+ children: [group.title && jsx("h3", {
481
+ className: "text-lg font-medium text-primary-900",
482
+ children: group.title
483
+ }), group.description && jsx("p", {
484
+ className: "text-sm text-primary-600",
485
+ children: group.description
486
+ }), jsx("div", {
487
+ className: cn("grid gap-4", group.gridCols ? "grid-cols-".concat(group.gridCols) : "grid-cols-1"),
488
+ children: group.fields.map(renderField)
489
+ })]
490
+ }, group.name);
491
+ }
492
+ return renderField(group);
493
+ };
494
+ return jsx(FormProvider, _objectSpread2(_objectSpread2({}, methods), {}, {
495
+ children: jsxs("form", _objectSpread2(_objectSpread2({
496
+ ref: ref,
497
+ className: cn("space-y-6", className),
498
+ onSubmit: handleSubmit(handleFormSubmit)
499
+ }, props), {}, {
500
+ children: [fields.map(renderFieldGroup), jsxs("div", {
501
+ className: "flex gap-4 pt-4",
502
+ children: [jsx(Button, {
503
+ type: "submit",
504
+ loading: isSubmitting,
505
+ disabled: isSubmitting || submitDisabled,
506
+ className: submitButtonClass,
507
+ children: submitText
508
+ }), showReset && jsx(Button, {
509
+ type: "button",
510
+ variant: "outline",
511
+ onClick: handleReset,
512
+ disabled: isSubmitting,
513
+ className: resetButtonClass,
514
+ children: resetText
515
+ })]
516
+ })]
517
+ }))
518
+ }));
519
+ });
520
+ Form.displayName = "Form";
521
+
522
+ export { Form as default };