@skybin-tech/nebula-ui 0.0.25 → 0.0.27

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 (286) hide show
  1. package/dist/cjs/_virtual/_rolldown/runtime.cjs +24 -0
  2. package/dist/cjs/components/Accordion/Accordion.cjs +20 -10
  3. package/dist/cjs/components/Accordion/Accordion.cjs.map +1 -1
  4. package/dist/cjs/components/Alert/Alert.cjs +19 -9
  5. package/dist/cjs/components/Alert/Alert.cjs.map +1 -1
  6. package/dist/cjs/components/Avatar/Avatar.cjs +19 -9
  7. package/dist/cjs/components/Avatar/Avatar.cjs.map +1 -1
  8. package/dist/cjs/components/Badge/Badge.cjs +8 -7
  9. package/dist/cjs/components/Badge/Badge.cjs.map +1 -1
  10. package/dist/cjs/components/Button/Button.cjs +37 -47
  11. package/dist/cjs/components/Button/Button.cjs.map +1 -1
  12. package/dist/cjs/components/Card/Card.cjs +31 -12
  13. package/dist/cjs/components/Card/Card.cjs.map +1 -1
  14. package/dist/cjs/components/Checkbox/Checkbox.cjs +12 -7
  15. package/dist/cjs/components/Checkbox/Checkbox.cjs.map +1 -1
  16. package/dist/cjs/components/DropdownMenu/DropdownMenu.cjs +55 -21
  17. package/dist/cjs/components/DropdownMenu/DropdownMenu.cjs.map +1 -1
  18. package/dist/cjs/components/Form/Checkbox.cjs +128 -142
  19. package/dist/cjs/components/Form/Checkbox.cjs.map +1 -1
  20. package/dist/cjs/components/Form/Form.cjs +106 -105
  21. package/dist/cjs/components/Form/Form.cjs.map +1 -1
  22. package/dist/cjs/components/Form/FormSwitch.cjs +126 -0
  23. package/dist/cjs/components/Form/FormSwitch.cjs.map +1 -0
  24. package/dist/cjs/components/Form/Radio.cjs +157 -172
  25. package/dist/cjs/components/Form/Radio.cjs.map +1 -1
  26. package/dist/cjs/components/Form/TextArea.cjs +137 -152
  27. package/dist/cjs/components/Form/TextArea.cjs.map +1 -1
  28. package/dist/cjs/components/Form/TextBox.cjs +184 -206
  29. package/dist/cjs/components/Form/TextBox.cjs.map +1 -1
  30. package/dist/cjs/components/Form/context.cjs +109 -122
  31. package/dist/cjs/components/Form/context.cjs.map +1 -1
  32. package/dist/cjs/components/Form/hooks.cjs +34 -24
  33. package/dist/cjs/components/Form/hooks.cjs.map +1 -1
  34. package/dist/cjs/components/Form/variants.cjs +14 -14
  35. package/dist/cjs/components/Form/variants.cjs.map +1 -1
  36. package/dist/cjs/components/Input/Input.cjs +11 -7
  37. package/dist/cjs/components/Input/Input.cjs.map +1 -1
  38. package/dist/cjs/components/Label/Label.cjs +11 -7
  39. package/dist/cjs/components/Label/Label.cjs.map +1 -1
  40. package/dist/cjs/components/Pagination/Pagination.cjs +58 -95
  41. package/dist/cjs/components/Pagination/Pagination.cjs.map +1 -1
  42. package/dist/cjs/components/Separator/Separator.cjs +11 -7
  43. package/dist/cjs/components/Separator/Separator.cjs.map +1 -1
  44. package/dist/cjs/components/Skeleton/Skeleton.cjs +7 -6
  45. package/dist/cjs/components/Skeleton/Skeleton.cjs.map +1 -1
  46. package/dist/cjs/components/Switch/Switch.cjs +14 -0
  47. package/dist/cjs/components/Switch/Switch.cjs.map +1 -0
  48. package/dist/cjs/components/Tabs/Tabs.cjs +23 -10
  49. package/dist/cjs/components/Tabs/Tabs.cjs.map +1 -1
  50. package/dist/cjs/components/Textarea/Textarea.cjs +11 -7
  51. package/dist/cjs/components/Textarea/Textarea.cjs.map +1 -1
  52. package/dist/cjs/components/Tooltip/Tooltip.cjs +14 -10
  53. package/dist/cjs/components/Tooltip/Tooltip.cjs.map +1 -1
  54. package/dist/cjs/hooks/useDebounce.cjs +22 -14
  55. package/dist/cjs/hooks/useDebounce.cjs.map +1 -1
  56. package/dist/cjs/hooks/useToast.cjs +105 -84
  57. package/dist/cjs/hooks/useToast.cjs.map +1 -1
  58. package/dist/cjs/hooks/useToggle.cjs +15 -9
  59. package/dist/cjs/hooks/useToggle.cjs.map +1 -1
  60. package/dist/cjs/index.cjs +170 -170
  61. package/dist/cjs/primitives/accordion.cjs +38 -61
  62. package/dist/cjs/primitives/accordion.cjs.map +1 -1
  63. package/dist/cjs/primitives/alert.cjs +33 -63
  64. package/dist/cjs/primitives/alert.cjs.map +1 -1
  65. package/dist/cjs/primitives/avatar.cjs +29 -58
  66. package/dist/cjs/primitives/avatar.cjs.map +1 -1
  67. package/dist/cjs/primitives/badge.cjs +26 -27
  68. package/dist/cjs/primitives/badge.cjs.map +1 -1
  69. package/dist/cjs/primitives/button.cjs +44 -63
  70. package/dist/cjs/primitives/button.cjs.map +1 -1
  71. package/dist/cjs/primitives/calendar.cjs +41 -44
  72. package/dist/cjs/primitives/calendar.cjs.map +1 -1
  73. package/dist/cjs/primitives/card.cjs +39 -70
  74. package/dist/cjs/primitives/card.cjs.map +1 -1
  75. package/dist/cjs/primitives/checkbox.cjs +22 -45
  76. package/dist/cjs/primitives/checkbox.cjs.map +1 -1
  77. package/dist/cjs/primitives/command.cjs +65 -73
  78. package/dist/cjs/primitives/command.cjs.map +1 -1
  79. package/dist/cjs/primitives/dialog.cjs +55 -84
  80. package/dist/cjs/primitives/dialog.cjs.map +1 -1
  81. package/dist/cjs/primitives/dropdown-menu.cjs +82 -153
  82. package/dist/cjs/primitives/dropdown-menu.cjs.map +1 -1
  83. package/dist/cjs/primitives/input.cjs +17 -39
  84. package/dist/cjs/primitives/input.cjs.map +1 -1
  85. package/dist/cjs/primitives/label.cjs +19 -38
  86. package/dist/cjs/primitives/label.cjs.map +1 -1
  87. package/dist/cjs/primitives/popover.cjs +22 -42
  88. package/dist/cjs/primitives/popover.cjs.map +1 -1
  89. package/dist/cjs/primitives/radio-group.cjs +31 -50
  90. package/dist/cjs/primitives/radio-group.cjs.map +1 -1
  91. package/dist/cjs/primitives/scroll-area.cjs +33 -55
  92. package/dist/cjs/primitives/scroll-area.cjs.map +1 -1
  93. package/dist/cjs/primitives/select.cjs +76 -133
  94. package/dist/cjs/primitives/select.cjs.map +1 -1
  95. package/dist/cjs/primitives/separator.cjs +20 -42
  96. package/dist/cjs/primitives/separator.cjs.map +1 -1
  97. package/dist/cjs/primitives/skeleton.cjs +10 -12
  98. package/dist/cjs/primitives/skeleton.cjs.map +1 -1
  99. package/dist/cjs/primitives/sonner.cjs +16 -20
  100. package/dist/cjs/primitives/sonner.cjs.map +1 -1
  101. package/dist/cjs/primitives/switch.cjs +19 -45
  102. package/dist/cjs/primitives/switch.cjs.map +1 -1
  103. package/dist/cjs/primitives/table.cjs +52 -61
  104. package/dist/cjs/primitives/table.cjs.map +1 -1
  105. package/dist/cjs/primitives/tabs.cjs +30 -62
  106. package/dist/cjs/primitives/tabs.cjs.map +1 -1
  107. package/dist/cjs/primitives/textarea.cjs +15 -35
  108. package/dist/cjs/primitives/textarea.cjs.map +1 -1
  109. package/dist/cjs/primitives/textbox.cjs +17 -39
  110. package/dist/cjs/primitives/textbox.cjs.map +1 -1
  111. package/dist/cjs/primitives/toast.cjs +59 -107
  112. package/dist/cjs/primitives/toast.cjs.map +1 -1
  113. package/dist/cjs/primitives/toggle.cjs +39 -55
  114. package/dist/cjs/primitives/toggle.cjs.map +1 -1
  115. package/dist/cjs/primitives/tooltip.cjs +21 -41
  116. package/dist/cjs/primitives/tooltip.cjs.map +1 -1
  117. package/dist/cjs/utils/cn.cjs +11 -6
  118. package/dist/cjs/utils/cn.cjs.map +1 -1
  119. package/dist/components/Accordion/Accordion.js +20 -13
  120. package/dist/components/Accordion/Accordion.js.map +1 -1
  121. package/dist/components/Alert/Alert.js +19 -11
  122. package/dist/components/Alert/Alert.js.map +1 -1
  123. package/dist/components/Avatar/Avatar.js +19 -11
  124. package/dist/components/Avatar/Avatar.js.map +1 -1
  125. package/dist/components/Badge/Badge.d.ts +1 -1
  126. package/dist/components/Badge/Badge.d.ts.map +1 -1
  127. package/dist/components/Badge/Badge.js +8 -8
  128. package/dist/components/Badge/Badge.js.map +1 -1
  129. package/dist/components/Button/Button.js +37 -48
  130. package/dist/components/Button/Button.js.map +1 -1
  131. package/dist/components/Card/Card.js +31 -17
  132. package/dist/components/Card/Card.js.map +1 -1
  133. package/dist/components/Checkbox/Checkbox.js +12 -7
  134. package/dist/components/Checkbox/Checkbox.js.map +1 -1
  135. package/dist/components/DropdownMenu/DropdownMenu.d.ts +4 -4
  136. package/dist/components/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  137. package/dist/components/DropdownMenu/DropdownMenu.js +55 -35
  138. package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
  139. package/dist/components/Form/Checkbox.js +126 -140
  140. package/dist/components/Form/Checkbox.js.map +1 -1
  141. package/dist/components/Form/Form.d.ts +1 -1
  142. package/dist/components/Form/Form.d.ts.map +1 -1
  143. package/dist/components/Form/Form.js +104 -103
  144. package/dist/components/Form/Form.js.map +1 -1
  145. package/dist/components/Form/{Switch.d.ts → FormSwitch.d.ts} +3 -3
  146. package/dist/components/Form/FormSwitch.d.ts.map +1 -0
  147. package/dist/components/Form/FormSwitch.js +126 -0
  148. package/dist/components/Form/FormSwitch.js.map +1 -0
  149. package/dist/components/Form/Radio.d.ts +1 -1
  150. package/dist/components/Form/Radio.d.ts.map +1 -1
  151. package/dist/components/Form/Radio.js +155 -171
  152. package/dist/components/Form/Radio.js.map +1 -1
  153. package/dist/components/Form/Select.d.ts +1 -1
  154. package/dist/components/Form/Select.d.ts.map +1 -1
  155. package/dist/components/Form/TextArea.js +134 -149
  156. package/dist/components/Form/TextArea.js.map +1 -1
  157. package/dist/components/Form/TextBox.js +179 -201
  158. package/dist/components/Form/TextBox.js.map +1 -1
  159. package/dist/components/Form/context.d.ts +3 -5
  160. package/dist/components/Form/context.d.ts.map +1 -1
  161. package/dist/components/Form/context.js +109 -125
  162. package/dist/components/Form/context.js.map +1 -1
  163. package/dist/components/Form/hooks.js +35 -28
  164. package/dist/components/Form/hooks.js.map +1 -1
  165. package/dist/components/Form/index.d.ts +2 -2
  166. package/dist/components/Form/index.d.ts.map +1 -1
  167. package/dist/components/Form/variants.js +15 -14
  168. package/dist/components/Form/variants.js.map +1 -1
  169. package/dist/components/Input/Input.js +11 -7
  170. package/dist/components/Input/Input.js.map +1 -1
  171. package/dist/components/Label/Label.js +11 -7
  172. package/dist/components/Label/Label.js.map +1 -1
  173. package/dist/components/Pagination/Pagination.d.ts +5 -5
  174. package/dist/components/Pagination/Pagination.js +55 -83
  175. package/dist/components/Pagination/Pagination.js.map +1 -1
  176. package/dist/components/Separator/Separator.js +11 -7
  177. package/dist/components/Separator/Separator.js.map +1 -1
  178. package/dist/components/Skeleton/Skeleton.d.ts +1 -1
  179. package/dist/components/Skeleton/Skeleton.d.ts.map +1 -1
  180. package/dist/components/Skeleton/Skeleton.js +7 -6
  181. package/dist/components/Skeleton/Skeleton.js.map +1 -1
  182. package/dist/components/Switch/Switch.d.ts +4 -1
  183. package/dist/components/Switch/Switch.d.ts.map +1 -1
  184. package/dist/components/Switch/Switch.js +14 -0
  185. package/dist/components/Switch/Switch.js.map +1 -0
  186. package/dist/components/Switch/index.d.ts +1 -0
  187. package/dist/components/Switch/index.d.ts.map +1 -1
  188. package/dist/components/Tabs/Tabs.js +23 -13
  189. package/dist/components/Tabs/Tabs.js.map +1 -1
  190. package/dist/components/Textarea/Textarea.js +11 -7
  191. package/dist/components/Textarea/Textarea.js.map +1 -1
  192. package/dist/components/Tooltip/Tooltip.js +14 -13
  193. package/dist/components/Tooltip/Tooltip.js.map +1 -1
  194. package/dist/hooks/useDebounce.js +23 -15
  195. package/dist/hooks/useDebounce.js.map +1 -1
  196. package/dist/hooks/useToast.js +103 -69
  197. package/dist/hooks/useToast.js.map +1 -1
  198. package/dist/hooks/useToggle.js +16 -10
  199. package/dist/hooks/useToggle.js.map +1 -1
  200. package/dist/index.d.ts +4 -2
  201. package/dist/index.d.ts.map +1 -1
  202. package/dist/index.js +29 -160
  203. package/dist/primitives/accordion.js +32 -43
  204. package/dist/primitives/accordion.js.map +1 -1
  205. package/dist/primitives/alert.js +30 -47
  206. package/dist/primitives/alert.js.map +1 -1
  207. package/dist/primitives/avatar.js +22 -38
  208. package/dist/primitives/avatar.js.map +1 -1
  209. package/dist/primitives/badge.d.ts +1 -1
  210. package/dist/primitives/badge.d.ts.map +1 -1
  211. package/dist/primitives/badge.js +23 -27
  212. package/dist/primitives/badge.js.map +1 -1
  213. package/dist/primitives/button.js +41 -46
  214. package/dist/primitives/button.js.map +1 -1
  215. package/dist/primitives/calendar.d.ts +1 -1
  216. package/dist/primitives/calendar.d.ts.map +1 -1
  217. package/dist/primitives/calendar.js +37 -42
  218. package/dist/primitives/calendar.js.map +1 -1
  219. package/dist/primitives/card.js +37 -58
  220. package/dist/primitives/card.js.map +1 -1
  221. package/dist/primitives/checkbox.js +17 -25
  222. package/dist/primitives/checkbox.js.map +1 -1
  223. package/dist/primitives/command.d.ts +2 -2
  224. package/dist/primitives/command.d.ts.map +1 -1
  225. package/dist/primitives/command.js +70 -71
  226. package/dist/primitives/command.js.map +1 -1
  227. package/dist/primitives/dialog.d.ts +2 -2
  228. package/dist/primitives/dialog.js +47 -70
  229. package/dist/primitives/dialog.js.map +1 -1
  230. package/dist/primitives/dropdown-menu.d.ts +1 -1
  231. package/dist/primitives/dropdown-menu.js +70 -140
  232. package/dist/primitives/dropdown-menu.js.map +1 -1
  233. package/dist/primitives/input.js +15 -22
  234. package/dist/primitives/input.js.map +1 -1
  235. package/dist/primitives/label.js +14 -18
  236. package/dist/primitives/label.js.map +1 -1
  237. package/dist/primitives/popover.js +17 -25
  238. package/dist/primitives/popover.js.map +1 -1
  239. package/dist/primitives/radio-group.js +25 -30
  240. package/dist/primitives/radio-group.js.map +1 -1
  241. package/dist/primitives/scroll-area.js +27 -35
  242. package/dist/primitives/scroll-area.js.map +1 -1
  243. package/dist/primitives/select.js +65 -116
  244. package/dist/primitives/select.js.map +1 -1
  245. package/dist/primitives/separator.js +15 -22
  246. package/dist/primitives/separator.js.map +1 -1
  247. package/dist/primitives/skeleton.d.ts +1 -1
  248. package/dist/primitives/skeleton.d.ts.map +1 -1
  249. package/dist/primitives/skeleton.js +10 -12
  250. package/dist/primitives/skeleton.js.map +1 -1
  251. package/dist/primitives/sonner.d.ts +1 -1
  252. package/dist/primitives/sonner.d.ts.map +1 -1
  253. package/dist/primitives/sonner.js +17 -21
  254. package/dist/primitives/sonner.js.map +1 -1
  255. package/dist/primitives/switch.js +14 -25
  256. package/dist/primitives/switch.js.map +1 -1
  257. package/dist/primitives/table.js +50 -51
  258. package/dist/primitives/table.js.map +1 -1
  259. package/dist/primitives/tabs.js +23 -43
  260. package/dist/primitives/tabs.js.map +1 -1
  261. package/dist/primitives/textarea.js +13 -18
  262. package/dist/primitives/textarea.js.map +1 -1
  263. package/dist/primitives/textbox.js +15 -22
  264. package/dist/primitives/textbox.js.map +1 -1
  265. package/dist/primitives/toast.js +48 -87
  266. package/dist/primitives/toast.js.map +1 -1
  267. package/dist/primitives/toggle.js +34 -36
  268. package/dist/primitives/toggle.js.map +1 -1
  269. package/dist/primitives/tooltip.js +16 -24
  270. package/dist/primitives/tooltip.js.map +1 -1
  271. package/dist/stories/Button.d.ts +1 -1
  272. package/dist/stories/Button.d.ts.map +1 -1
  273. package/dist/stories/Button.stories.d.ts +1 -1
  274. package/dist/stories/Header.d.ts +1 -1
  275. package/dist/stories/Header.d.ts.map +1 -1
  276. package/dist/stories/Header.stories.d.ts +1 -1
  277. package/dist/utils/cn.js +10 -5
  278. package/dist/utils/cn.js.map +1 -1
  279. package/package.json +504 -497
  280. package/dist/cjs/components/Form/Switch.cjs +0 -126
  281. package/dist/cjs/components/Form/Switch.cjs.map +0 -1
  282. package/dist/cjs/index.cjs.map +0 -1
  283. package/dist/components/Form/Switch.d.ts.map +0 -1
  284. package/dist/components/Form/Switch.js +0 -126
  285. package/dist/components/Form/Switch.js.map +0 -1
  286. package/dist/index.js.map +0 -1
@@ -1,210 +1,188 @@
1
1
  "use client";
2
- "use strict";
3
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
4
- const jsxRuntime = require("react/jsx-runtime");
5
- const React = require("react");
6
- const reactHookForm = require("react-hook-form");
7
- const classVarianceAuthority = require("class-variance-authority");
8
- const cn = require("../../utils/cn.cjs");
9
- const context = require("./context.cjs");
10
- const variants = require("./variants.cjs");
11
- const textbox = require("../../primitives/textbox.cjs");
12
- const label = require("../../primitives/label.cjs");
13
- const lucideReact = require("lucide-react");
14
- const textBoxVariants = classVarianceAuthority.cva(
15
- "",
16
- {
17
- variants: {
18
- size: {
19
- sm: "h-8 text-xs px-2",
20
- md: "h-10 text-sm px-3",
21
- lg: "h-12 text-base px-4"
22
- },
23
- variant: {
24
- default: "border-input focus-visible:ring-ring",
25
- error: "border-destructive focus-visible:ring-destructive",
26
- success: "border-green-500 focus-visible:ring-green-500"
27
- }
28
- },
29
- defaultVariants: {
30
- size: "md",
31
- variant: "default"
32
- }
33
- }
34
- );
35
- function TextBoxInner({
36
- name,
37
- label: label$1,
38
- helperText,
39
- showError = true,
40
- error: customError,
41
- size,
42
- variant,
43
- fullWidth = true,
44
- className,
45
- disabled,
46
- prefix,
47
- suffix,
48
- allowClear,
49
- onClear,
50
- id: providedId,
51
- control: externalControl,
52
- // Validation props
53
- required,
54
- minLength,
55
- maxLength,
56
- minValue,
57
- maxValue,
58
- pattern,
59
- email,
60
- url,
61
- validate,
62
- ...props
63
- }, ref) {
64
- const generatedId = React.useId();
65
- const inputId = providedId ?? generatedId;
66
- const formConfigContext = React.useContext(context.FormConfigContext);
67
- const formConfig = formConfigContext ?? {};
68
- const rhfContext = reactHookForm.useFormContext();
69
- const control = externalControl ?? rhfContext?.control;
70
- const registerFieldValidation = formConfigContext?.registerFieldValidation;
71
- const unregisterFieldValidation = formConfigContext?.unregisterFieldValidation;
72
- React.useEffect(() => {
73
- if (registerFieldValidation) {
74
- const rules = {};
75
- if (required !== void 0) rules.required = required;
76
- if (minLength !== void 0) rules.minLength = minLength;
77
- if (maxLength !== void 0) rules.maxLength = maxLength;
78
- if (minValue !== void 0) rules.min = minValue;
79
- if (maxValue !== void 0) rules.max = maxValue;
80
- if (pattern !== void 0) rules.pattern = pattern;
81
- if (email !== void 0) rules.email = email;
82
- if (url !== void 0) rules.url = url;
83
- if (validate !== void 0) rules.validate = validate;
84
- const inputType = props.type ?? "text";
85
- let fieldType = "string";
86
- if (inputType === "number") {
87
- fieldType = "number";
88
- } else if (inputType === "date") {
89
- fieldType = "date";
90
- } else if (inputType === "email" && rules.email === void 0) {
91
- rules.email = true;
92
- } else if (inputType === "url" && rules.url === void 0) {
93
- rules.url = true;
94
- } else if (inputType === "tel" && rules.pattern === void 0) {
95
- rules.pattern = { value: /^\+?[\d\s\-().]{7,}$/, message: "Invalid phone number" };
96
- }
97
- registerFieldValidation({
98
- name,
99
- type: fieldType,
100
- rules
101
- });
102
- return () => {
103
- unregisterFieldValidation?.(name);
104
- };
105
- }
106
- }, [
107
- registerFieldValidation,
108
- unregisterFieldValidation,
109
- name,
110
- required,
111
- minLength,
112
- maxLength,
113
- minValue,
114
- maxValue,
115
- pattern,
116
- email,
117
- url,
118
- validate,
119
- props.type
120
- ]);
121
- const { field, fieldState } = reactHookForm.useController({
122
- name,
123
- control
124
- });
125
- const fieldError = fieldState.error?.message;
126
- const errorMessage = customError ?? fieldError;
127
- const hasError = !!errorMessage;
128
- const effectiveSize = size ?? formConfig.size ?? "md";
129
- const effectiveDisabled = disabled ?? formConfig.disabled;
130
- const effectiveVariant = hasError ? "error" : variant;
131
- const handleClear = () => {
132
- field.onChange("");
133
- onClear?.();
134
- };
135
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn.cn("space-y-1.5", fullWidth && "w-full"), children: [
136
- label$1 && /* @__PURE__ */ jsxRuntime.jsxs(
137
- label.Label,
138
- {
139
- htmlFor: inputId,
140
- className: variants.labelVariants({ required: !!required }),
141
- children: [
142
- label$1,
143
- formConfig.colon && ":"
144
- ]
145
- }
146
- ),
147
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
148
- prefix && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground", children: prefix }),
149
- /* @__PURE__ */ jsxRuntime.jsx(
150
- textbox.TextBoxPrimitive,
151
- {
152
- ...props,
153
- ...field,
154
- ref: (node) => {
155
- if (typeof ref === "function") {
156
- ref(node);
157
- } else if (ref) {
158
- ref.current = node;
159
- }
160
- field.ref(node);
161
- },
162
- id: inputId,
163
- disabled: effectiveDisabled,
164
- "aria-invalid": hasError,
165
- "aria-describedby": hasError ? `${inputId}-error` : helperText ? `${inputId}-helper` : void 0,
166
- className: cn.cn(
167
- textBoxVariants({ size: effectiveSize, variant: effectiveVariant }),
168
- prefix && "pl-10",
169
- (suffix || allowClear) && "pr-10",
170
- className
171
- )
172
- }
173
- ),
174
- (suffix || allowClear && field.value) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute right-3 top-1/2 -translate-y-1/2 flex items-center gap-1", children: [
175
- allowClear && field.value && /* @__PURE__ */ jsxRuntime.jsx(
176
- "button",
177
- {
178
- type: "button",
179
- onClick: handleClear,
180
- className: "text-muted-foreground hover:text-foreground transition-colors",
181
- tabIndex: -1,
182
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" })
183
- }
184
- ),
185
- suffix && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: suffix })
186
- ] })
187
- ] }),
188
- showError && hasError && /* @__PURE__ */ jsxRuntime.jsx(
189
- "p",
190
- {
191
- id: `${inputId}-error`,
192
- className: "text-sm text-destructive",
193
- role: "alert",
194
- children: errorMessage
195
- }
196
- ),
197
- helperText && !hasError && /* @__PURE__ */ jsxRuntime.jsx(
198
- "p",
199
- {
200
- id: `${inputId}-helper`,
201
- className: "text-sm text-muted-foreground",
202
- children: helperText
203
- }
204
- )
205
- ] });
2
+ "use client";
3
+ const require_cn = require("../../utils/cn.cjs");
4
+ const require_context = require("./context.cjs");
5
+ const require_variants = require("./variants.cjs");
6
+ const require_textbox = require("../../primitives/textbox.cjs");
7
+ const require_label = require("../../primitives/label.cjs");
8
+ let react = require("react");
9
+ let class_variance_authority = require("class-variance-authority");
10
+ let react_jsx_runtime = require("react/jsx-runtime");
11
+ let react_hook_form = require("react-hook-form");
12
+ let lucide_react = require("lucide-react");
13
+ //#region src/components/Form/TextBox.tsx
14
+ var textBoxVariants = (0, class_variance_authority.cva)("", {
15
+ variants: {
16
+ size: {
17
+ sm: "h-8 text-xs px-2",
18
+ md: "h-10 text-sm px-3",
19
+ lg: "h-12 text-base px-4"
20
+ },
21
+ variant: {
22
+ default: "border-input focus-visible:ring-ring",
23
+ error: "border-destructive focus-visible:ring-destructive",
24
+ success: "border-green-500 focus-visible:ring-green-500"
25
+ }
26
+ },
27
+ defaultVariants: {
28
+ size: "md",
29
+ variant: "default"
30
+ }
31
+ });
32
+ /**
33
+ * TextBox component with form integration and automatic validation registration
34
+ *
35
+ * This is a wrapper around the shadcn/ui Input primitive that adds:
36
+ * - Form integration with react-hook-form
37
+ * - Automatic validation registration
38
+ * - Label, helper text, and error message support
39
+ * - Prefix/suffix elements
40
+ * - Clear button functionality
41
+ *
42
+ * @example
43
+ * ```tsx
44
+ * // Inside a Form component - validation is automatically registered
45
+ * <Form onSubmit={handleSubmit} defaultValues={{ username: "", email: "" }}>
46
+ * <TextBox name="username" label="Username" required minLength={3} maxLength={50} />
47
+ * <TextBox name="email" label="Email" type="email" required email />
48
+ * <TextBox name="website" label="Website" url />
49
+ * <Button type="submit">Submit</Button>
50
+ * </Form>
51
+ * ```
52
+ */
53
+ function TextBoxInner({ name, label, helperText, showError = true, error: customError, size, variant, fullWidth = true, className, disabled, prefix, suffix, allowClear, onClear, id: providedId, control: externalControl, required, minLength, maxLength, minValue, maxValue, pattern, email, url, validate, ...props }, ref) {
54
+ const generatedId = (0, react.useId)();
55
+ const inputId = providedId ?? generatedId;
56
+ const formConfigContext = (0, react.useContext)(require_context.FormConfigContext);
57
+ const formConfig = formConfigContext ?? {};
58
+ const rhfContext = (0, react_hook_form.useFormContext)();
59
+ const control = externalControl ?? rhfContext?.control;
60
+ const registerFieldValidation = formConfigContext?.registerFieldValidation;
61
+ const unregisterFieldValidation = formConfigContext?.unregisterFieldValidation;
62
+ (0, react.useEffect)(() => {
63
+ if (registerFieldValidation) {
64
+ const rules = {};
65
+ if (required !== void 0) rules.required = required;
66
+ if (minLength !== void 0) rules.minLength = minLength;
67
+ if (maxLength !== void 0) rules.maxLength = maxLength;
68
+ if (minValue !== void 0) rules.min = minValue;
69
+ if (maxValue !== void 0) rules.max = maxValue;
70
+ if (pattern !== void 0) rules.pattern = pattern;
71
+ if (email !== void 0) rules.email = email;
72
+ if (url !== void 0) rules.url = url;
73
+ if (validate !== void 0) rules.validate = validate;
74
+ const inputType = props.type ?? "text";
75
+ let fieldType = "string";
76
+ if (inputType === "number") fieldType = "number";
77
+ else if (inputType === "date") fieldType = "date";
78
+ else if (inputType === "email" && rules.email === void 0) rules.email = true;
79
+ else if (inputType === "url" && rules.url === void 0) rules.url = true;
80
+ else if (inputType === "tel" && rules.pattern === void 0) rules.pattern = {
81
+ value: /^\+?[\d\s\-().]{7,}$/,
82
+ message: "Invalid phone number"
83
+ };
84
+ registerFieldValidation({
85
+ name,
86
+ type: fieldType,
87
+ rules
88
+ });
89
+ return () => {
90
+ unregisterFieldValidation?.(name);
91
+ };
92
+ }
93
+ }, [
94
+ registerFieldValidation,
95
+ unregisterFieldValidation,
96
+ name,
97
+ required,
98
+ minLength,
99
+ maxLength,
100
+ minValue,
101
+ maxValue,
102
+ pattern,
103
+ email,
104
+ url,
105
+ validate,
106
+ props.type
107
+ ]);
108
+ const { field, fieldState } = (0, react_hook_form.useController)({
109
+ name,
110
+ control
111
+ });
112
+ const fieldError = fieldState.error?.message;
113
+ const errorMessage = customError ?? fieldError;
114
+ const hasError = !!errorMessage;
115
+ const effectiveSize = size ?? formConfig.size ?? "md";
116
+ const effectiveDisabled = disabled ?? formConfig.disabled;
117
+ const effectiveVariant = hasError ? "error" : variant;
118
+ const handleClear = () => {
119
+ field.onChange("");
120
+ onClear?.();
121
+ };
122
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
123
+ className: require_cn.cn("space-y-1.5", fullWidth && "w-full"),
124
+ children: [
125
+ label && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_label.Label, {
126
+ htmlFor: inputId,
127
+ className: require_variants.labelVariants({ required: !!required }),
128
+ children: [label, formConfig.colon && ":"]
129
+ }),
130
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
131
+ className: "relative",
132
+ children: [
133
+ prefix && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
134
+ className: "absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground",
135
+ children: prefix
136
+ }),
137
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_textbox.TextBoxPrimitive, {
138
+ ...props,
139
+ ...field,
140
+ ref: (node) => {
141
+ if (typeof ref === "function") ref(node);
142
+ else if (ref) ref.current = node;
143
+ field.ref(node);
144
+ },
145
+ id: inputId,
146
+ disabled: effectiveDisabled,
147
+ "aria-invalid": hasError,
148
+ "aria-describedby": hasError ? `${inputId}-error` : helperText ? `${inputId}-helper` : void 0,
149
+ className: require_cn.cn(textBoxVariants({
150
+ size: effectiveSize,
151
+ variant: effectiveVariant
152
+ }), prefix && "pl-10", (suffix || allowClear) && "pr-10", className)
153
+ }),
154
+ (suffix || allowClear && field.value) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
155
+ className: "absolute right-3 top-1/2 -translate-y-1/2 flex items-center gap-1",
156
+ children: [allowClear && field.value && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
157
+ type: "button",
158
+ onClick: handleClear,
159
+ className: "text-muted-foreground hover:text-foreground transition-colors",
160
+ tabIndex: -1,
161
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, { className: "h-4 w-4" })
162
+ }), suffix && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
163
+ className: "text-muted-foreground",
164
+ children: suffix
165
+ })]
166
+ })
167
+ ]
168
+ }),
169
+ showError && hasError && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
170
+ id: `${inputId}-error`,
171
+ className: "text-sm text-destructive",
172
+ role: "alert",
173
+ children: errorMessage
174
+ }),
175
+ helperText && !hasError && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
176
+ id: `${inputId}-helper`,
177
+ className: "text-sm text-muted-foreground",
178
+ children: helperText
179
+ })
180
+ ]
181
+ });
206
182
  }
207
- const TextBox = React.forwardRef(TextBoxInner);
183
+ var TextBox = (0, react.forwardRef)(TextBoxInner);
208
184
  TextBox.displayName = "TextBox";
185
+ //#endregion
209
186
  exports.TextBox = TextBox;
210
- //# sourceMappingURL=TextBox.cjs.map
187
+
188
+ //# sourceMappingURL=TextBox.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"TextBox.cjs","sources":["../../../../src/components/Form/TextBox.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, useId, useContext, useEffect } from \"react\";\nimport type { InputHTMLAttributes, ReactNode } from \"react\";\nimport { useController, useFormContext as useRHFFormContext, type FieldValues, type FieldPath, type Control } from \"react-hook-form\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"../../utils/cn\";\nimport { FormConfigContext, type FormConfig, type FieldValidationRules } from \"../Form/context\";\nimport { labelVariants } from \"./variants\";\nimport { TextBoxPrimitive } from \"../../primitives/textbox\";\nimport { Label } from \"../../primitives/label\";\nimport { X } from \"lucide-react\";\n\nconst textBoxVariants = cva(\n \"\",\n {\n variants: {\n size: {\n sm: \"h-8 text-xs px-2\",\n md: \"h-10 text-sm px-3\",\n lg: \"h-12 text-base px-4\",\n },\n variant: {\n default: \"border-input focus-visible:ring-ring\",\n error: \"border-destructive focus-visible:ring-destructive\",\n success: \"border-green-500 focus-visible:ring-green-500\",\n },\n },\n defaultVariants: {\n size: \"md\",\n variant: \"default\",\n },\n }\n);\n\n/**\n * Validation rule with optional custom message\n */\ntype ValidationRule<T> = T | { value: T; message: string };\n\nexport interface TextBoxProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\n> extends Omit<InputHTMLAttributes<HTMLInputElement>, \"size\" | \"name\" | \"prefix\" | \"pattern\" | \"required\" | \"minLength\" | \"maxLength\">,\n VariantProps<typeof textBoxVariants> {\n /** Field name - required for form integration */\n name: TName;\n /** Label text for the input */\n label?: string;\n /** Helper text displayed below the input */\n helperText?: string;\n /** Whether to show the error message */\n showError?: boolean;\n /** Custom error message (overrides form error) */\n error?: string;\n /** Whether the input should take full width */\n fullWidth?: boolean;\n /** Prefix element */\n prefix?: ReactNode;\n /** Suffix element */\n suffix?: ReactNode;\n /** Allow clear button */\n allowClear?: boolean;\n /** Callback when clear is clicked */\n onClear?: () => void;\n /** External control (for use outside Form) */\n control?: Control<TFieldValues>;\n \n // Validation props\n /** Field is required */\n required?: boolean | string;\n /** Minimum length for strings */\n minLength?: ValidationRule<number>;\n /** Maximum length for strings */\n maxLength?: ValidationRule<number>;\n /** Minimum value for numbers */\n minValue?: ValidationRule<number>;\n /** Maximum value for numbers */\n maxValue?: ValidationRule<number>;\n /** Regex pattern for validation */\n pattern?: ValidationRule<RegExp>;\n /** Email validation */\n email?: boolean | string;\n /** URL validation */\n url?: boolean | string;\n /** Custom validation function */\n validate?: (value: unknown) => boolean | string | Promise<boolean | string>;\n}\n\n/**\n * TextBox component with form integration and automatic validation registration\n * \n * This is a wrapper around the shadcn/ui Input primitive that adds:\n * - Form integration with react-hook-form\n * - Automatic validation registration\n * - Label, helper text, and error message support\n * - Prefix/suffix elements\n * - Clear button functionality\n * \n * @example\n * ```tsx\n * // Inside a Form component - validation is automatically registered\n * <Form onSubmit={handleSubmit} defaultValues={{ username: \"\", email: \"\" }}>\n * <TextBox name=\"username\" label=\"Username\" required minLength={3} maxLength={50} />\n * <TextBox name=\"email\" label=\"Email\" type=\"email\" required email />\n * <TextBox name=\"website\" label=\"Website\" url />\n * <Button type=\"submit\">Submit</Button>\n * </Form>\n * ```\n */\nfunction TextBoxInner<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\n>(\n {\n name,\n label,\n helperText,\n showError = true,\n error: customError,\n size,\n variant,\n fullWidth = true,\n className,\n disabled,\n prefix,\n suffix,\n allowClear,\n onClear,\n id: providedId,\n control: externalControl,\n // Validation props\n required,\n minLength,\n maxLength,\n minValue,\n maxValue,\n pattern,\n email,\n url,\n validate,\n ...props\n }: TextBoxProps<TFieldValues, TName>,\n ref: React.ForwardedRef<HTMLInputElement>\n) {\n const generatedId = useId();\n const inputId = providedId ?? generatedId;\n \n // Try to get form context\n const formConfigContext = useContext(FormConfigContext);\n const formConfig: FormConfig = formConfigContext ?? {};\n\n // Get form context from react-hook-form\n const rhfContext = useRHFFormContext<TFieldValues>();\n const control = externalControl ?? rhfContext?.control;\n\n // Destructure stable function references so the effect doesn't depend on the\n // context object identity (which changes every render due to inline construction).\n const registerFieldValidation = formConfigContext?.registerFieldValidation;\n const unregisterFieldValidation = formConfigContext?.unregisterFieldValidation;\n\n // Register validation rules with the form\n useEffect(() => {\n if (registerFieldValidation) {\n const rules: FieldValidationRules = {};\n\n if (required !== undefined) rules.required = required;\n if (minLength !== undefined) rules.minLength = minLength;\n if (maxLength !== undefined) rules.maxLength = maxLength;\n if (minValue !== undefined) rules.min = minValue;\n if (maxValue !== undefined) rules.max = maxValue;\n if (pattern !== undefined) rules.pattern = pattern;\n if (email !== undefined) rules.email = email;\n if (url !== undefined) rules.url = url;\n if (validate !== undefined) rules.validate = validate;\n\n // Determine field type and auto-infer rules from input type\n const inputType = props.type ?? \"text\";\n let fieldType: \"string\" | \"number\" | \"date\" = \"string\";\n\n if (inputType === \"number\") {\n fieldType = \"number\";\n } else if (inputType === \"date\") {\n fieldType = \"date\";\n } else if (inputType === \"email\" && rules.email === undefined) {\n rules.email = true;\n } else if (inputType === \"url\" && rules.url === undefined) {\n rules.url = true;\n } else if (inputType === \"tel\" && rules.pattern === undefined) {\n rules.pattern = { value: /^\\+?[\\d\\s\\-().]{7,}$/, message: \"Invalid phone number\" };\n }\n\n registerFieldValidation({\n name: name as string,\n type: fieldType,\n rules,\n });\n\n return () => {\n unregisterFieldValidation?.(name as string);\n };\n }\n }, [\n registerFieldValidation,\n unregisterFieldValidation,\n name,\n required,\n minLength,\n maxLength,\n minValue,\n maxValue,\n pattern,\n email,\n url,\n validate,\n props.type,\n ]);\n\n // Use controller for form integration\n const { field, fieldState } = useController<TFieldValues, TName>({\n name,\n control,\n });\n\n const fieldError = fieldState.error?.message;\n const errorMessage = customError ?? fieldError;\n const hasError = !!errorMessage;\n \n // Merge sizes - prop takes precedence over form config\n const effectiveSize = size ?? formConfig.size ?? \"md\";\n const effectiveDisabled = disabled ?? formConfig.disabled;\n \n // Determine variant based on error state\n const effectiveVariant = hasError ? \"error\" : variant;\n\n const handleClear = () => {\n field.onChange(\"\");\n onClear?.();\n };\n\n return (\n <div className={cn(\"space-y-1.5\", fullWidth && \"w-full\")}>\n {label && (\n <Label\n htmlFor={inputId}\n className={labelVariants({ required: !!required })}\n >\n {label}\n {formConfig.colon && \":\"}\n </Label>\n )}\n \n <div className=\"relative\">\n {prefix && (\n <div className=\"absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground\">\n {prefix}\n </div>\n )}\n \n <TextBoxPrimitive\n {...props}\n {...field}\n ref={(node) => {\n // Handle both refs\n if (typeof ref === \"function\") {\n ref(node);\n } else if (ref) {\n ref.current = node;\n }\n field.ref(node);\n }}\n id={inputId}\n disabled={effectiveDisabled}\n aria-invalid={hasError}\n aria-describedby={\n hasError\n ? `${inputId}-error`\n : helperText\n ? `${inputId}-helper`\n : undefined\n }\n className={cn(\n textBoxVariants({ size: effectiveSize, variant: effectiveVariant }),\n prefix && \"pl-10\",\n (suffix || allowClear) && \"pr-10\",\n className\n )}\n />\n\n {(suffix || (allowClear && field.value)) && (\n <div className=\"absolute right-3 top-1/2 -translate-y-1/2 flex items-center gap-1\">\n {allowClear && field.value && (\n <button\n type=\"button\"\n onClick={handleClear}\n className=\"text-muted-foreground hover:text-foreground transition-colors\"\n tabIndex={-1}\n >\n <X className=\"h-4 w-4\" />\n </button>\n )}\n {suffix && (\n <span className=\"text-muted-foreground\">{suffix}</span>\n )}\n </div>\n )}\n </div>\n\n {showError && hasError && (\n <p\n id={`${inputId}-error`}\n className=\"text-sm text-destructive\"\n role=\"alert\"\n >\n {errorMessage}\n </p>\n )}\n \n {helperText && !hasError && (\n <p\n id={`${inputId}-helper`}\n className=\"text-sm text-muted-foreground\"\n >\n {helperText}\n </p>\n )}\n </div>\n );\n}\n\n// Use forwardRef with generic support\nexport const TextBox = forwardRef(TextBoxInner) as <\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\n>(\n props: TextBoxProps<TFieldValues, TName> & { ref?: React.ForwardedRef<HTMLInputElement> }\n) => React.ReactElement;\n\n(TextBox as React.FC).displayName = \"TextBox\";\n"],"names":["cva","label","useId","useContext","FormConfigContext","useRHFFormContext","useEffect","useController","cn","jsxs","Label","labelVariants","jsx","TextBoxPrimitive","X","forwardRef"],"mappings":"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"}
1
+ {"version":3,"file":"TextBox.cjs","names":[],"sources":["../../../../src/components/Form/TextBox.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, useId, useContext, useEffect } from \"react\";\nimport type { InputHTMLAttributes, ReactNode } from \"react\";\nimport { useController, useFormContext as useRHFFormContext, type FieldValues, type FieldPath, type Control } from \"react-hook-form\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"../../utils/cn\";\nimport { FormConfigContext, type FormConfig, type FieldValidationRules } from \"../Form/context\";\nimport { labelVariants } from \"./variants\";\nimport { TextBoxPrimitive } from \"../../primitives/textbox\";\nimport { Label } from \"../../primitives/label\";\nimport { X } from \"lucide-react\";\n\nconst textBoxVariants = cva(\n \"\",\n {\n variants: {\n size: {\n sm: \"h-8 text-xs px-2\",\n md: \"h-10 text-sm px-3\",\n lg: \"h-12 text-base px-4\",\n },\n variant: {\n default: \"border-input focus-visible:ring-ring\",\n error: \"border-destructive focus-visible:ring-destructive\",\n success: \"border-green-500 focus-visible:ring-green-500\",\n },\n },\n defaultVariants: {\n size: \"md\",\n variant: \"default\",\n },\n }\n);\n\n/**\n * Validation rule with optional custom message\n */\ntype ValidationRule<T> = T | { value: T; message: string };\n\nexport interface TextBoxProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\n> extends Omit<InputHTMLAttributes<HTMLInputElement>, \"size\" | \"name\" | \"prefix\" | \"pattern\" | \"required\" | \"minLength\" | \"maxLength\">,\n VariantProps<typeof textBoxVariants> {\n /** Field name - required for form integration */\n name: TName;\n /** Label text for the input */\n label?: string;\n /** Helper text displayed below the input */\n helperText?: string;\n /** Whether to show the error message */\n showError?: boolean;\n /** Custom error message (overrides form error) */\n error?: string;\n /** Whether the input should take full width */\n fullWidth?: boolean;\n /** Prefix element */\n prefix?: ReactNode;\n /** Suffix element */\n suffix?: ReactNode;\n /** Allow clear button */\n allowClear?: boolean;\n /** Callback when clear is clicked */\n onClear?: () => void;\n /** External control (for use outside Form) */\n control?: Control<TFieldValues>;\n \n // Validation props\n /** Field is required */\n required?: boolean | string;\n /** Minimum length for strings */\n minLength?: ValidationRule<number>;\n /** Maximum length for strings */\n maxLength?: ValidationRule<number>;\n /** Minimum value for numbers */\n minValue?: ValidationRule<number>;\n /** Maximum value for numbers */\n maxValue?: ValidationRule<number>;\n /** Regex pattern for validation */\n pattern?: ValidationRule<RegExp>;\n /** Email validation */\n email?: boolean | string;\n /** URL validation */\n url?: boolean | string;\n /** Custom validation function */\n validate?: (value: unknown) => boolean | string | Promise<boolean | string>;\n}\n\n/**\n * TextBox component with form integration and automatic validation registration\n * \n * This is a wrapper around the shadcn/ui Input primitive that adds:\n * - Form integration with react-hook-form\n * - Automatic validation registration\n * - Label, helper text, and error message support\n * - Prefix/suffix elements\n * - Clear button functionality\n * \n * @example\n * ```tsx\n * // Inside a Form component - validation is automatically registered\n * <Form onSubmit={handleSubmit} defaultValues={{ username: \"\", email: \"\" }}>\n * <TextBox name=\"username\" label=\"Username\" required minLength={3} maxLength={50} />\n * <TextBox name=\"email\" label=\"Email\" type=\"email\" required email />\n * <TextBox name=\"website\" label=\"Website\" url />\n * <Button type=\"submit\">Submit</Button>\n * </Form>\n * ```\n */\nfunction TextBoxInner<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\n>(\n {\n name,\n label,\n helperText,\n showError = true,\n error: customError,\n size,\n variant,\n fullWidth = true,\n className,\n disabled,\n prefix,\n suffix,\n allowClear,\n onClear,\n id: providedId,\n control: externalControl,\n // Validation props\n required,\n minLength,\n maxLength,\n minValue,\n maxValue,\n pattern,\n email,\n url,\n validate,\n ...props\n }: TextBoxProps<TFieldValues, TName>,\n ref: React.ForwardedRef<HTMLInputElement>\n) {\n const generatedId = useId();\n const inputId = providedId ?? generatedId;\n \n // Try to get form context\n const formConfigContext = useContext(FormConfigContext);\n const formConfig: FormConfig = formConfigContext ?? {};\n\n // Get form context from react-hook-form\n const rhfContext = useRHFFormContext<TFieldValues>();\n const control = externalControl ?? rhfContext?.control;\n\n // Destructure stable function references so the effect doesn't depend on the\n // context object identity (which changes every render due to inline construction).\n const registerFieldValidation = formConfigContext?.registerFieldValidation;\n const unregisterFieldValidation = formConfigContext?.unregisterFieldValidation;\n\n // Register validation rules with the form\n useEffect(() => {\n if (registerFieldValidation) {\n const rules: FieldValidationRules = {};\n\n if (required !== undefined) rules.required = required;\n if (minLength !== undefined) rules.minLength = minLength;\n if (maxLength !== undefined) rules.maxLength = maxLength;\n if (minValue !== undefined) rules.min = minValue;\n if (maxValue !== undefined) rules.max = maxValue;\n if (pattern !== undefined) rules.pattern = pattern;\n if (email !== undefined) rules.email = email;\n if (url !== undefined) rules.url = url;\n if (validate !== undefined) rules.validate = validate;\n\n // Determine field type and auto-infer rules from input type\n const inputType = props.type ?? \"text\";\n let fieldType: \"string\" | \"number\" | \"date\" = \"string\";\n\n if (inputType === \"number\") {\n fieldType = \"number\";\n } else if (inputType === \"date\") {\n fieldType = \"date\";\n } else if (inputType === \"email\" && rules.email === undefined) {\n rules.email = true;\n } else if (inputType === \"url\" && rules.url === undefined) {\n rules.url = true;\n } else if (inputType === \"tel\" && rules.pattern === undefined) {\n rules.pattern = { value: /^\\+?[\\d\\s\\-().]{7,}$/, message: \"Invalid phone number\" };\n }\n\n registerFieldValidation({\n name: name as string,\n type: fieldType,\n rules,\n });\n\n return () => {\n unregisterFieldValidation?.(name as string);\n };\n }\n }, [\n registerFieldValidation,\n unregisterFieldValidation,\n name,\n required,\n minLength,\n maxLength,\n minValue,\n maxValue,\n pattern,\n email,\n url,\n validate,\n props.type,\n ]);\n\n // Use controller for form integration\n const { field, fieldState } = useController<TFieldValues, TName>({\n name,\n control,\n });\n\n const fieldError = fieldState.error?.message;\n const errorMessage = customError ?? fieldError;\n const hasError = !!errorMessage;\n \n // Merge sizes - prop takes precedence over form config\n const effectiveSize = size ?? formConfig.size ?? \"md\";\n const effectiveDisabled = disabled ?? formConfig.disabled;\n \n // Determine variant based on error state\n const effectiveVariant = hasError ? \"error\" : variant;\n\n const handleClear = () => {\n field.onChange(\"\");\n onClear?.();\n };\n\n return (\n <div className={cn(\"space-y-1.5\", fullWidth && \"w-full\")}>\n {label && (\n <Label\n htmlFor={inputId}\n className={labelVariants({ required: !!required })}\n >\n {label}\n {formConfig.colon && \":\"}\n </Label>\n )}\n \n <div className=\"relative\">\n {prefix && (\n <div className=\"absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground\">\n {prefix}\n </div>\n )}\n \n <TextBoxPrimitive\n {...props}\n {...field}\n ref={(node) => {\n // Handle both refs\n if (typeof ref === \"function\") {\n ref(node);\n } else if (ref) {\n ref.current = node;\n }\n field.ref(node);\n }}\n id={inputId}\n disabled={effectiveDisabled}\n aria-invalid={hasError}\n aria-describedby={\n hasError\n ? `${inputId}-error`\n : helperText\n ? `${inputId}-helper`\n : undefined\n }\n className={cn(\n textBoxVariants({ size: effectiveSize, variant: effectiveVariant }),\n prefix && \"pl-10\",\n (suffix || allowClear) && \"pr-10\",\n className\n )}\n />\n\n {(suffix || (allowClear && field.value)) && (\n <div className=\"absolute right-3 top-1/2 -translate-y-1/2 flex items-center gap-1\">\n {allowClear && field.value && (\n <button\n type=\"button\"\n onClick={handleClear}\n className=\"text-muted-foreground hover:text-foreground transition-colors\"\n tabIndex={-1}\n >\n <X className=\"h-4 w-4\" />\n </button>\n )}\n {suffix && (\n <span className=\"text-muted-foreground\">{suffix}</span>\n )}\n </div>\n )}\n </div>\n\n {showError && hasError && (\n <p\n id={`${inputId}-error`}\n className=\"text-sm text-destructive\"\n role=\"alert\"\n >\n {errorMessage}\n </p>\n )}\n \n {helperText && !hasError && (\n <p\n id={`${inputId}-helper`}\n className=\"text-sm text-muted-foreground\"\n >\n {helperText}\n </p>\n )}\n </div>\n );\n}\n\n// Use forwardRef with generic support\nexport const TextBox = forwardRef(TextBoxInner) as <\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\n>(\n props: TextBoxProps<TFieldValues, TName> & { ref?: React.ForwardedRef<HTMLInputElement> }\n) => React.ReactElement;\n\n(TextBox as React.FC).displayName = \"TextBox\";\n"],"mappings":"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"}