@fuf-stack/uniform 1.4.1 → 1.5.0

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 (187) hide show
  1. package/dist/Checkboxes/index.cjs +16 -0
  2. package/dist/{RadioGroup → Checkboxes}/index.cjs.map +1 -1
  3. package/dist/Checkboxes/index.d.cts +10 -0
  4. package/dist/Checkboxes/index.d.ts +10 -0
  5. package/dist/Checkboxes/index.js +16 -0
  6. package/dist/{CheckboxGroup-B1g42iP0.d.cts → Checkboxes-CR0Uu2g9.d.cts} +9 -9
  7. package/dist/{CheckboxGroup-B1g42iP0.d.ts → Checkboxes-CR0Uu2g9.d.ts} +9 -9
  8. package/dist/FieldArray/index.cjs +5 -5
  9. package/dist/FieldArray/index.d.cts +2 -2
  10. package/dist/FieldArray/index.d.ts +2 -2
  11. package/dist/FieldArray/index.js +4 -4
  12. package/dist/FieldArray-EP4otr2x.d.cts +160 -0
  13. package/dist/FieldArray-EP4otr2x.d.ts +160 -0
  14. package/dist/{FieldValidationError-CU_xw0BL.d.ts → FieldValidationError-DwtLkGMo.d.cts} +2 -2
  15. package/dist/{FieldValidationError-CU_xw0BL.d.cts → FieldValidationError-DwtLkGMo.d.ts} +2 -2
  16. package/dist/Form/index.cjs +6 -4
  17. package/dist/Form/index.cjs.map +1 -1
  18. package/dist/Form/index.js +5 -3
  19. package/dist/Input/index.cjs +5 -5
  20. package/dist/Input/index.d.cts +2 -2
  21. package/dist/Input/index.d.ts +2 -2
  22. package/dist/Input/index.js +4 -4
  23. package/dist/{Input-C6ujfEkn.d.ts → Input-CCIEnvIp.d.ts} +1 -1
  24. package/dist/{Input-BQkZtJx8.d.cts → Input-D7HT_8jf.d.cts} +1 -1
  25. package/dist/RadioBoxes/index.cjs +5 -5
  26. package/dist/RadioBoxes/index.d.cts +3 -2
  27. package/dist/RadioBoxes/index.d.ts +3 -2
  28. package/dist/RadioBoxes/index.js +4 -4
  29. package/dist/{RadioBoxes-CE3mYoFk.d.cts → RadioBoxes-DpkI28l0.d.cts} +3 -2
  30. package/dist/{RadioBoxes-CE3mYoFk.d.ts → RadioBoxes-DpkI28l0.d.ts} +3 -2
  31. package/dist/RadioTabs/index.cjs +5 -5
  32. package/dist/RadioTabs/index.d.cts +2 -2
  33. package/dist/RadioTabs/index.d.ts +2 -2
  34. package/dist/RadioTabs/index.js +4 -4
  35. package/dist/{RadioTabs-BCWW3tru.d.cts → RadioTabs-DTDcAZoH.d.cts} +1 -1
  36. package/dist/{RadioTabs-BCWW3tru.d.ts → RadioTabs-DTDcAZoH.d.ts} +1 -1
  37. package/dist/Radios/index.cjs +16 -0
  38. package/dist/Radios/index.cjs.map +1 -0
  39. package/dist/Radios/index.d.cts +9 -0
  40. package/dist/Radios/index.d.ts +9 -0
  41. package/dist/Radios/index.js +16 -0
  42. package/dist/{RadioGroup-CAOX80Xx.d.cts → Radios-DprlJhoq.d.cts} +9 -9
  43. package/dist/{RadioGroup-CAOX80Xx.d.ts → Radios-DprlJhoq.d.ts} +9 -9
  44. package/dist/Select/index.cjs +5 -5
  45. package/dist/Select/index.d.cts +2 -2
  46. package/dist/Select/index.d.ts +2 -2
  47. package/dist/Select/index.js +4 -4
  48. package/dist/{Select-CTRWinmO.d.cts → Select-CDkZmZp2.d.cts} +1 -1
  49. package/dist/{Select-CTRWinmO.d.ts → Select-CDkZmZp2.d.ts} +1 -1
  50. package/dist/SubmitButton/index.cjs +6 -4
  51. package/dist/SubmitButton/index.cjs.map +1 -1
  52. package/dist/SubmitButton/index.js +5 -3
  53. package/dist/Switch/index.cjs +5 -5
  54. package/dist/Switch/index.js +4 -4
  55. package/dist/TextArea/index.cjs +5 -5
  56. package/dist/TextArea/index.d.cts +4 -2
  57. package/dist/TextArea/index.d.ts +4 -2
  58. package/dist/TextArea/index.js +4 -4
  59. package/dist/TextArea-DhxNWYNg.d.cts +86 -0
  60. package/dist/TextArea-DhxNWYNg.d.ts +86 -0
  61. package/dist/chunk-2DHTL4PW.cjs +117 -0
  62. package/dist/chunk-2DHTL4PW.cjs.map +1 -0
  63. package/dist/{chunk-FOVP54XP.cjs → chunk-3NH4MEMM.cjs} +18 -27
  64. package/dist/chunk-3NH4MEMM.cjs.map +1 -0
  65. package/dist/{chunk-M2DNMSQZ.js → chunk-3Q3IUEGL.js} +52 -49
  66. package/dist/chunk-3Q3IUEGL.js.map +1 -0
  67. package/dist/{chunk-JSQ77E6L.js → chunk-4WRUHOGY.js} +49 -47
  68. package/dist/chunk-4WRUHOGY.js.map +1 -0
  69. package/dist/{chunk-KG4XCEPW.js → chunk-53XSXUNE.js} +42 -40
  70. package/dist/chunk-53XSXUNE.js.map +1 -0
  71. package/dist/{chunk-77C6VN4L.cjs → chunk-5LWD6VRV.cjs} +50 -47
  72. package/dist/chunk-5LWD6VRV.cjs.map +1 -0
  73. package/dist/{chunk-C64RKQEW.cjs → chunk-62AYJT2H.cjs} +3 -3
  74. package/dist/{chunk-C64RKQEW.cjs.map → chunk-62AYJT2H.cjs.map} +1 -1
  75. package/dist/chunk-76KOVUDN.js +138 -0
  76. package/dist/chunk-76KOVUDN.js.map +1 -0
  77. package/dist/{chunk-FHRMVL6B.js → chunk-AYWMAPAX.js} +134 -89
  78. package/dist/chunk-AYWMAPAX.js.map +1 -0
  79. package/dist/chunk-BWPTCHL7.cjs +103 -0
  80. package/dist/chunk-BWPTCHL7.cjs.map +1 -0
  81. package/dist/{chunk-2GYFDVXX.cjs → chunk-C5GIWGQR.cjs} +173 -33
  82. package/dist/chunk-C5GIWGQR.cjs.map +1 -0
  83. package/dist/{chunk-IYDCKENI.js → chunk-CJD3DW4J.js} +166 -26
  84. package/dist/chunk-CJD3DW4J.js.map +1 -0
  85. package/dist/{chunk-N2EEOWEP.cjs → chunk-CW4VK77Z.cjs} +59 -64
  86. package/dist/chunk-CW4VK77Z.cjs.map +1 -0
  87. package/dist/{chunk-LJQ35BUK.js → chunk-D2HI4KE4.js} +2 -2
  88. package/dist/chunk-DYTE5N3B.cjs +684 -0
  89. package/dist/chunk-DYTE5N3B.cjs.map +1 -0
  90. package/dist/chunk-ELYGQTXB.js +47 -0
  91. package/dist/chunk-ELYGQTXB.js.map +1 -0
  92. package/dist/chunk-GST3AQOR.js +684 -0
  93. package/dist/chunk-GST3AQOR.js.map +1 -0
  94. package/dist/{chunk-AYNTZPKL.cjs → chunk-HQNZYWJX.cjs} +132 -87
  95. package/dist/chunk-HQNZYWJX.cjs.map +1 -0
  96. package/dist/chunk-LLQLEDOO.js +103 -0
  97. package/dist/chunk-LLQLEDOO.js.map +1 -0
  98. package/dist/chunk-NHEZXA4H.cjs +47 -0
  99. package/dist/chunk-NHEZXA4H.cjs.map +1 -0
  100. package/dist/{chunk-M7VM7XBE.js → chunk-OCYJFIPV.js} +8 -8
  101. package/dist/chunk-OCYJFIPV.js.map +1 -0
  102. package/dist/{chunk-ORQO6JXK.cjs → chunk-S36CKKDV.cjs} +45 -43
  103. package/dist/chunk-S36CKKDV.cjs.map +1 -0
  104. package/dist/chunk-S7K35LVS.js +117 -0
  105. package/dist/chunk-S7K35LVS.js.map +1 -0
  106. package/dist/{chunk-Y3GELCDP.js → chunk-VLEYEBRE.js} +62 -67
  107. package/dist/chunk-VLEYEBRE.js.map +1 -0
  108. package/dist/{chunk-UGCZORU3.cjs → chunk-YIBISSMT.cjs} +9 -9
  109. package/dist/chunk-YIBISSMT.cjs.map +1 -0
  110. package/dist/chunk-Z353BLWI.cjs +138 -0
  111. package/dist/chunk-Z353BLWI.cjs.map +1 -0
  112. package/dist/{chunk-ULR4573W.cjs → chunk-ZLQCMOVU.cjs} +40 -38
  113. package/dist/chunk-ZLQCMOVU.cjs.map +1 -0
  114. package/dist/{chunk-2B6CDMOZ.js → chunk-ZN3ESUQR.js} +16 -25
  115. package/dist/chunk-ZN3ESUQR.js.map +1 -0
  116. package/dist/helpers/index.cjs +4 -2
  117. package/dist/helpers/index.cjs.map +1 -1
  118. package/dist/helpers/index.d.cts +54 -10
  119. package/dist/helpers/index.d.ts +54 -10
  120. package/dist/helpers/index.js +3 -1
  121. package/dist/hooks/index.cjs +7 -3
  122. package/dist/hooks/index.cjs.map +1 -1
  123. package/dist/hooks/index.d.cts +86 -4
  124. package/dist/hooks/index.d.ts +86 -4
  125. package/dist/hooks/index.js +8 -4
  126. package/dist/index.cjs +20 -16
  127. package/dist/index.cjs.map +1 -1
  128. package/dist/index.d.cts +11 -11
  129. package/dist/index.d.ts +11 -11
  130. package/dist/index.js +30 -26
  131. package/dist/partials/FieldValidationError/index.cjs +2 -2
  132. package/dist/partials/FieldValidationError/index.d.cts +2 -2
  133. package/dist/partials/FieldValidationError/index.d.ts +2 -2
  134. package/dist/partials/FieldValidationError/index.js +1 -1
  135. package/package.json +13 -12
  136. package/dist/CheckboxGroup/index.cjs +0 -16
  137. package/dist/CheckboxGroup/index.cjs.map +0 -1
  138. package/dist/CheckboxGroup/index.d.cts +0 -10
  139. package/dist/CheckboxGroup/index.d.ts +0 -10
  140. package/dist/CheckboxGroup/index.js +0 -16
  141. package/dist/FieldArray-DVQka7Bh.d.cts +0 -130
  142. package/dist/FieldArray-DVQka7Bh.d.ts +0 -130
  143. package/dist/RadioGroup/index.cjs +0 -16
  144. package/dist/RadioGroup/index.d.cts +0 -9
  145. package/dist/RadioGroup/index.d.ts +0 -9
  146. package/dist/RadioGroup/index.js +0 -16
  147. package/dist/TextArea-DnFGyl4a.d.cts +0 -27
  148. package/dist/TextArea-DnFGyl4a.d.ts +0 -27
  149. package/dist/chunk-2B6CDMOZ.js.map +0 -1
  150. package/dist/chunk-2GYFDVXX.cjs.map +0 -1
  151. package/dist/chunk-77C6VN4L.cjs.map +0 -1
  152. package/dist/chunk-AYNTZPKL.cjs.map +0 -1
  153. package/dist/chunk-CQWA2DFV.js +0 -37
  154. package/dist/chunk-CQWA2DFV.js.map +0 -1
  155. package/dist/chunk-EEBHFSBY.cjs +0 -112
  156. package/dist/chunk-EEBHFSBY.cjs.map +0 -1
  157. package/dist/chunk-FHRMVL6B.js.map +0 -1
  158. package/dist/chunk-FOVP54XP.cjs.map +0 -1
  159. package/dist/chunk-IYDCKENI.js.map +0 -1
  160. package/dist/chunk-JSQ77E6L.js.map +0 -1
  161. package/dist/chunk-JZF4HUYO.cjs +0 -409
  162. package/dist/chunk-JZF4HUYO.cjs.map +0 -1
  163. package/dist/chunk-KG4XCEPW.js.map +0 -1
  164. package/dist/chunk-KQN55PEW.js +0 -76
  165. package/dist/chunk-KQN55PEW.js.map +0 -1
  166. package/dist/chunk-M2DNMSQZ.js.map +0 -1
  167. package/dist/chunk-M7VM7XBE.js.map +0 -1
  168. package/dist/chunk-N2EEOWEP.cjs.map +0 -1
  169. package/dist/chunk-NAZIH6HV.js +0 -409
  170. package/dist/chunk-NAZIH6HV.js.map +0 -1
  171. package/dist/chunk-ORQO6JXK.cjs.map +0 -1
  172. package/dist/chunk-RDBCJJI7.cjs +0 -88
  173. package/dist/chunk-RDBCJJI7.cjs.map +0 -1
  174. package/dist/chunk-RF7KNUCI.js +0 -88
  175. package/dist/chunk-RF7KNUCI.js.map +0 -1
  176. package/dist/chunk-UGCZORU3.cjs.map +0 -1
  177. package/dist/chunk-ULR4573W.cjs.map +0 -1
  178. package/dist/chunk-XKMLCM5K.js +0 -112
  179. package/dist/chunk-XKMLCM5K.js.map +0 -1
  180. package/dist/chunk-Y3AB4GV6.cjs +0 -37
  181. package/dist/chunk-Y3AB4GV6.cjs.map +0 -1
  182. package/dist/chunk-Y3GELCDP.js.map +0 -1
  183. package/dist/chunk-YGNY6CKU.cjs +0 -76
  184. package/dist/chunk-YGNY6CKU.cjs.map +0 -1
  185. /package/dist/{CheckboxGroup → Checkboxes}/index.js.map +0 -0
  186. /package/dist/{RadioGroup → Radios}/index.js.map +0 -0
  187. /package/dist/{chunk-LJQ35BUK.js.map → chunk-D2HI4KE4.js.map} +0 -0
@@ -1,409 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
-
3
- var _chunkTTD3KL6Ecjs = require('./chunk-TTD3KL6E.cjs');
4
-
5
-
6
- var _chunkOE5BOGGXcjs = require('./chunk-OE5BOGGX.cjs');
7
-
8
-
9
- var _chunkY3AB4GV6cjs = require('./chunk-Y3AB4GV6.cjs');
10
-
11
-
12
-
13
-
14
- var _chunk2GYFDVXXcjs = require('./chunk-2GYFDVXX.cjs');
15
-
16
-
17
- var _chunkYGNY6CKUcjs = require('./chunk-YGNY6CKU.cjs');
18
-
19
-
20
-
21
-
22
- var _chunk555JRYCScjs = require('./chunk-555JRYCS.cjs');
23
-
24
- // src/FieldArray/FieldArray.tsx
25
- var _pixelutils = require('@fuf-stack/pixel-utils');
26
- var _pixels = require('@fuf-stack/pixels');
27
-
28
- // src/FieldArray/subcomponents/FieldArrayElement.tsx
29
- var _sortable = require('@dnd-kit/sortable');
30
- var _utilities = require('@dnd-kit/utilities');
31
-
32
-
33
- // src/FieldArray/subcomponents/ElementInsertAfterButton.tsx
34
- var _fa6 = require('react-icons/fa6');
35
-
36
-
37
- var _jsxruntime = require('react/jsx-runtime');
38
- var ElementInsertAfterButton = ({
39
- className = void 0,
40
- onClick,
41
- testId = void 0
42
- }) => {
43
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
44
- _pixels.Button,
45
- {
46
- className: _pixelutils.cn.call(void 0, className),
47
- color: "success",
48
- icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _fa6.FaPlus, {}),
49
- onClick,
50
- size: "sm",
51
- testId,
52
- variant: "light"
53
- }
54
- );
55
- };
56
- var ElementInsertAfterButton_default = ElementInsertAfterButton;
57
-
58
- // src/FieldArray/subcomponents/ElementRemoveButton.tsx
59
- var _fa = require('react-icons/fa');
60
-
61
-
62
-
63
- var ElementRemoveButton = ({
64
- className = void 0,
65
- onClick,
66
- testId = void 0
67
- }) => {
68
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
69
- _pixels.Button,
70
- {
71
- ariaLabel: "remove element",
72
- className: _pixelutils.cn.call(void 0, className),
73
- color: "danger",
74
- icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _fa.FaTimes, {}),
75
- onClick,
76
- testId,
77
- variant: "light"
78
- }
79
- );
80
- };
81
- var ElementRemoveButton_default = ElementRemoveButton;
82
-
83
- // src/FieldArray/subcomponents/SortDragHandle.tsx
84
-
85
-
86
-
87
-
88
- var SortDragHandle = ({
89
- className = void 0,
90
- id,
91
- testId = void 0
92
- }) => {
93
- const { attributes, listeners } = _sortable.useSortable.call(void 0, { id });
94
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
95
- "div",
96
- _chunk555JRYCScjs.__spreadProps.call(void 0, _chunk555JRYCScjs.__spreadValues.call(void 0, _chunk555JRYCScjs.__spreadValues.call(void 0, {
97
- className: _pixelutils.cn.call(void 0, className),
98
- "data-testid": testId
99
- }, attributes), listeners), {
100
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _fa.FaGripVertical, {})
101
- })
102
- );
103
- };
104
- var SortDragHandle_default = SortDragHandle;
105
-
106
- // src/FieldArray/subcomponents/FieldArrayElement.tsx
107
-
108
- var FieldArrayElement = ({
109
- arrayFieldName,
110
- children,
111
- className,
112
- fields,
113
- id,
114
- index,
115
- insertAfter = false,
116
- lastNotDeletable = true,
117
- methods,
118
- sortable = false,
119
- testId = void 0
120
- }) => {
121
- var _a;
122
- const { getFieldState } = _chunk2GYFDVXXcjs.useFormContext.call(void 0, );
123
- const { error, invalid } = getFieldState(arrayFieldName, void 0);
124
- const { getHelperWrapperProps, getErrorMessageProps } = _chunk2GYFDVXXcjs.useInput.call(void 0, {
125
- classNames: { helperWrapper: "block" },
126
- errorMessage: JSON.stringify(error),
127
- isInvalid: invalid,
128
- labelPlacement: "inside",
129
- placeholder: " "
130
- });
131
- const { setNodeRef, transform, transition } = _sortable.useSortable.call(void 0, { id });
132
- const sortingStyle = sortable ? {
133
- transform: _utilities.CSS.Translate.toString(transform),
134
- transition
135
- } : void 0;
136
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
137
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
138
- "li",
139
- {
140
- ref: setNodeRef,
141
- className: _pixelutils.cn.call(void 0, className.listItem),
142
- style: sortingStyle,
143
- children: [
144
- sortable ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
145
- SortDragHandle_default,
146
- {
147
- className: className.sortDragHandle,
148
- id,
149
- testId: `${testId}_sort_drag_handle`
150
- }
151
- ) : null,
152
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
153
- "div",
154
- {
155
- className: _pixelutils.cn.call(void 0, className.elementWrapper),
156
- "data-testid": `${testId}_element_wrapper`,
157
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkTTD3KL6Ecjs.Grid_default, { children })
158
- }
159
- ),
160
- lastNotDeletable && fields.length === 1 ? null : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
161
- ElementRemoveButton_default,
162
- {
163
- className: className.removeButton,
164
- testId: `${testId}_remove_button`,
165
- onClick: () => {
166
- methods.remove();
167
- }
168
- }
169
- ),
170
- insertAfter && index !== fields.length - 1 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
171
- ElementInsertAfterButton_default,
172
- {
173
- className: className.insertAfterButton,
174
- testId: `${testId}_insert_after_button`,
175
- onClick: () => {
176
- methods.insert();
177
- }
178
- }
179
- ) : null
180
- ]
181
- }
182
- ),
183
- typeof (error == null ? void 0 : error[index]) !== "undefined" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", _chunk555JRYCScjs.__spreadProps.call(void 0, _chunk555JRYCScjs.__spreadValues.call(void 0, {}, getHelperWrapperProps()), { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", _chunk555JRYCScjs.__spreadProps.call(void 0, _chunk555JRYCScjs.__spreadValues.call(void 0, {}, getErrorMessageProps()), { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
184
- _chunkY3AB4GV6cjs.FieldValidationError_default,
185
- {
186
- error: (_a = error[Number(index)]) == null ? void 0 : _a._errors,
187
- testId
188
- }
189
- ) })) }))
190
- ] });
191
- };
192
- var FieldArrayElement_default = FieldArrayElement;
193
-
194
- // src/FieldArray/subcomponents/SortContext.tsx
195
-
196
-
197
-
198
-
199
-
200
-
201
-
202
- var _core = require('@dnd-kit/core');
203
-
204
-
205
-
206
- var _modifiers = require('@dnd-kit/modifiers');
207
-
208
-
209
-
210
-
211
-
212
- var SortContext = ({
213
- children,
214
- sortable,
215
- fields,
216
- move
217
- }) => {
218
- const sensors = _core.useSensors.call(void 0,
219
- _core.useSensor.call(void 0, _core.PointerSensor),
220
- _core.useSensor.call(void 0, _core.KeyboardSensor)
221
- );
222
- if (!sortable) {
223
- return children;
224
- }
225
- const handleDragEnd = (event) => {
226
- const { active, over } = event;
227
- if (active.id !== (over == null ? void 0 : over.id)) {
228
- const oldIndex = fields.findIndex((field) => {
229
- return field.id === active.id;
230
- });
231
- const newIndex = fields.findIndex((field) => {
232
- return field.id === (over == null ? void 0 : over.id);
233
- });
234
- move(oldIndex, newIndex);
235
- }
236
- };
237
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
238
- _core.DndContext,
239
- {
240
- collisionDetection: _core.closestCenter,
241
- modifiers: [_modifiers.restrictToVerticalAxis, _modifiers.restrictToWindowEdges],
242
- onDragEnd: handleDragEnd,
243
- sensors,
244
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
245
- _sortable.SortableContext,
246
- {
247
- strategy: _sortable.verticalListSortingStrategy,
248
- items: fields.map((field) => {
249
- return field.id;
250
- }),
251
- children
252
- }
253
- )
254
- }
255
- );
256
- };
257
- var SortContext_default = SortContext;
258
-
259
- // src/FieldArray/FieldArray.tsx
260
-
261
- var fieldArrayVariants = _pixelutils.tv.call(void 0, {
262
- slots: {
263
- appendButton: "w-full",
264
- elementWrapper: "grow",
265
- insertAfterButton: "text-xs font-medium",
266
- label: "pointer-events-auto! static! z-0! -mb-1 ml-1 inline-block!",
267
- list: "m-0 w-full list-none",
268
- listItem: "mb-4 flex w-full flex-row",
269
- removeButton: "ml-1",
270
- sortDragHandle: "mr-2 text-base text-xl"
271
- }
272
- });
273
- var FieldArray = ({
274
- appendButtonText = "Add Element",
275
- children,
276
- className: _className = void 0,
277
- duplicate = false,
278
- elementInitialValue: _elementInitialValue = null,
279
- insertAfter = false,
280
- label: _label = void 0,
281
- lastElementNotRemovable = false,
282
- name,
283
- sortable = false,
284
- testId: _testId = void 0
285
- }) => {
286
- var _a;
287
- const variants = fieldArrayVariants();
288
- const className = _pixelutils.variantsToClassNames.call(void 0, variants, _className, "list");
289
- const {
290
- control,
291
- debugMode,
292
- getValues,
293
- getFieldState,
294
- trigger
295
- // watch
296
- } = _chunk2GYFDVXXcjs.useFormContext.call(void 0, );
297
- const { fields, append, remove, insert, move } = _chunk2GYFDVXXcjs.useFieldArray.call(void 0, {
298
- control,
299
- name
300
- });
301
- const { error, testId, invalid, required } = getFieldState(name, _testId);
302
- const { label, getLabelProps, getHelperWrapperProps, getErrorMessageProps } = _chunk2GYFDVXXcjs.useInput.call(void 0, {
303
- isInvalid: invalid,
304
- isRequired: required,
305
- errorMessage: JSON.stringify(error),
306
- label: _label,
307
- labelPlacement: "inside",
308
- placeholder: " ",
309
- classNames: { helperWrapper: "block" }
310
- });
311
- const elementInitialValue = _chunkYGNY6CKUcjs.toNullishString.call(void 0, _elementInitialValue);
312
- if (lastElementNotRemovable && fields.length === 0) {
313
- append(elementInitialValue);
314
- }
315
- const showTestIdCopyButton = debugMode === "debug-testids";
316
- const showLabel = label || showTestIdCopyButton;
317
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SortContext_default, { fields, move, sortable, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
318
- "ul",
319
- {
320
- className: className.list,
321
- "data-testid": testId,
322
- onBlur: () => _chunk555JRYCScjs.__async.call(void 0, null, null, function* () {
323
- return trigger(name);
324
- }),
325
- children: [
326
- showLabel ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
327
- label ? (
328
- // eslint-disable-next-line jsx-a11y/label-has-associated-control
329
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
330
- "label",
331
- _chunk555JRYCScjs.__spreadProps.call(void 0, _chunk555JRYCScjs.__spreadValues.call(void 0, {}, getLabelProps()), {
332
- className: _pixelutils.cn.call(void 0, (_a = getLabelProps()) == null ? void 0 : _a.className, className.label),
333
- children: label
334
- })
335
- )
336
- ) : null,
337
- showTestIdCopyButton ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkOE5BOGGXcjs.FieldCopyTestIdButton_default, { testId }) : null
338
- ] }) : null,
339
- fields.map((field, index) => {
340
- const elementName = `${name}.${index}`;
341
- const elementTestId = `${testId}_${index}`;
342
- const elementMethods = {
343
- append: () => {
344
- append(elementInitialValue);
345
- },
346
- duplicate: () => {
347
- const values = getValues(name);
348
- insert(index + 1, values[index]);
349
- },
350
- insert: () => {
351
- insert(index + 1, elementInitialValue);
352
- },
353
- remove: () => {
354
- remove(index);
355
- }
356
- };
357
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
358
- FieldArrayElement_default,
359
- {
360
- arrayFieldName: name,
361
- className,
362
- duplicate,
363
- fields,
364
- id: field.id,
365
- index,
366
- insertAfter,
367
- lastNotDeletable: lastElementNotRemovable,
368
- methods: elementMethods,
369
- sortable,
370
- testId: elementTestId,
371
- children: children({
372
- index,
373
- length: fields.length,
374
- methods: elementMethods,
375
- name: elementName,
376
- testId: elementTestId
377
- })
378
- },
379
- field.id
380
- );
381
- }),
382
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
383
- _pixels.Button,
384
- {
385
- disableAnimation: true,
386
- className: className.appendButton,
387
- size: "sm",
388
- testId: `${testId}_append_button`,
389
- onClick: () => {
390
- append(elementInitialValue);
391
- },
392
- children: appendButtonText
393
- }
394
- ),
395
- (error == null ? void 0 : error._errors) ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", _chunk555JRYCScjs.__spreadProps.call(void 0, _chunk555JRYCScjs.__spreadValues.call(void 0, {}, getHelperWrapperProps()), { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", _chunk555JRYCScjs.__spreadProps.call(void 0, _chunk555JRYCScjs.__spreadValues.call(void 0, {}, getErrorMessageProps()), { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkY3AB4GV6cjs.FieldValidationError_default, { error: error == null ? void 0 : error._errors, testId }) })) })) : null
396
- ]
397
- }
398
- ) });
399
- };
400
- var FieldArray_default = FieldArray;
401
-
402
- // src/FieldArray/index.ts
403
- var FieldArray_default2 = FieldArray_default;
404
-
405
-
406
-
407
-
408
- exports.FieldArray_default = FieldArray_default; exports.FieldArray_default2 = FieldArray_default2;
409
- //# sourceMappingURL=chunk-JZF4HUYO.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/work/pixels/pixels/packages/uniform/dist/chunk-JZF4HUYO.cjs","../src/FieldArray/FieldArray.tsx","../src/FieldArray/subcomponents/FieldArrayElement.tsx","../src/FieldArray/subcomponents/ElementInsertAfterButton.tsx","../src/FieldArray/subcomponents/ElementRemoveButton.tsx","../src/FieldArray/subcomponents/SortDragHandle.tsx","../src/FieldArray/subcomponents/SortContext.tsx","../src/FieldArray/index.ts"],"names":["jsx","Button","cn","useSortable","Fragment","FieldArray_default"],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACF,wDAA6B;AAC7B;AACA;ACpBA,oDAA6C;AAC7C,2CAAuB;ADsBvB;AACA;AExBA,6CAA4B;AAC5B,+CAAoB;AAEpB;AFyBA;AACA;AG9BA,sCAAuB;AAEvB;AACA;AAoBY,+CAAA;AATZ,IAAM,yBAAA,EAA2B,CAAC;AAAA,EAChC,UAAA,EAAY,KAAA,CAAA;AAAA,EACZ,OAAA;AAAA,EACA,OAAA,EAAS,KAAA;AACX,CAAA,EAAA,GAAqC;AACnC,EAAA,uBACE,6BAAA;AAAA,IAAC,cAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,4BAAA,SAAY,CAAA;AAAA,MACvB,KAAA,EAAM,SAAA;AAAA,MACN,IAAA,kBAAM,6BAAA,WAAC,EAAA,CAAA,CAAO,CAAA;AAAA,MACd,OAAA;AAAA,MACA,IAAA,EAAK,IAAA;AAAA,MACL,MAAA;AAAA,MACA,OAAA,EAAQ;AAAA,IAAA;AAAA,EACV,CAAA;AAEJ,CAAA;AAEA,IAAO,iCAAA,EAAQ,wBAAA;AHsBf;AACA;AIvDA,oCAAwB;AAExB;AACA;AAqBY;AAVZ,IAAM,oBAAA,EAAsB,CAAC;AAAA,EAC3B,UAAA,EAAY,KAAA,CAAA;AAAA,EACZ,OAAA;AAAA,EACA,OAAA,EAAS,KAAA;AACX,CAAA,EAAA,GAAgC;AAC9B,EAAA,uBACEA,6BAAAA;AAAA,IAACC,cAAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,gBAAA;AAAA,MACV,SAAA,EAAWC,4BAAAA,SAAY,CAAA;AAAA,MACvB,KAAA,EAAM,QAAA;AAAA,MACN,IAAA,kBAAMF,6BAAAA,WAAC,EAAA,CAAA,CAAQ,CAAA;AAAA,MACf,OAAA;AAAA,MACA,MAAA;AAAA,MACA,OAAA,EAAQ;AAAA,IAAA;AAAA,EACV,CAAA;AAEJ,CAAA;AAEA,IAAO,4BAAA,EAAQ,mBAAA;AJ+Cf;AACA;AKhFA;AAEA;AAEA;AA8BM;AAfN,IAAM,eAAA,EAAiB,CAAC;AAAA,EACtB,UAAA,EAAY,KAAA,CAAA;AAAA,EACZ,EAAA;AAAA,EACA,OAAA,EAAS,KAAA;AACX,CAAA,EAAA,GAA2B;AAEzB,EAAA,MAAM,EAAE,UAAA,EAAY,UAAU,EAAA,EAAI,mCAAA,EAAc,GAAG,CAAC,CAAA;AAEpD,EAAA,uBACEA,6BAAAA;AAAA,IAAC,KAAA;AAAA,IAAA,6CAAA,8CAAA,8CAAA;AAAA,MACC,SAAA,EAAWE,4BAAAA,SAAY,CAAA;AAAA,MACvB,aAAA,EAAa;AAAA,IAAA,CAAA,EACT,UAAA,CAAA,EACA,SAAA,CAAA,EAJL;AAAA,MAMC,QAAA,kBAAAF,6BAAAA,kBAAC,EAAA,CAAA,CAAe;AAAA,IAAA,CAAA;AAAA,EAClB,CAAA;AAEJ,CAAA;AAEA,IAAO,uBAAA,EAAQ,cAAA;AL+Df;AACA;AENI;AArCJ,IAAM,kBAAA,EAAoB,CAAC;AAAA,EACzB,cAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,EAAA;AAAA,EACA,KAAA;AAAA,EACA,YAAA,EAAc,KAAA;AAAA,EACd,iBAAA,EAAmB,IAAA;AAAA,EACnB,OAAA;AAAA,EACA,SAAA,EAAW,KAAA;AAAA,EACX,OAAA,EAAS,KAAA;AACX,CAAA,EAAA,GAA8B;AA1E9B,EAAA,IAAA,EAAA;AA2EE,EAAA,MAAM,EAAE,cAAc,EAAA,EAAI,8CAAA,CAAe;AACzC,EAAA,MAAM,EAAE,KAAA,EAAO,QAAQ,EAAA,EAAI,aAAA,CAAc,cAAA,EAAgB,KAAA,CAAS,CAAA;AAGlE,EAAA,MAAM,EAAE,qBAAA,EAAuB,qBAAqB,EAAA,EAAI,wCAAA;AAAS,IAC/D,UAAA,EAAY,EAAE,aAAA,EAAe,QAAQ,CAAA;AAAA,IACrC,YAAA,EAAc,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA;AAAA,IAClC,SAAA,EAAW,OAAA;AAAA,IACX,cAAA,EAAgB,QAAA;AAAA,IAChB,WAAA,EAAa;AAAA,EACf,CAAC,CAAA;AAKD,EAAA,MAAM,EAAE,UAAA,EAAY,SAAA,EAAW,WAAW,EAAA,EAAIG,mCAAAA,EAAc,GAAG,CAAC,CAAA;AAChE,EAAA,MAAM,aAAA,EAAe,SAAA,EACjB;AAAA,IACE,SAAA,EAAW,cAAA,CAAI,SAAA,CAAU,QAAA,CAAS,SAAS,CAAA;AAAA,IAC3C;AAAA,EACF,EAAA,EACA,KAAA,CAAA;AAEJ,EAAA,uBACE,8BAAA,oBAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAA,8BAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,UAAA;AAAA,QACL,SAAA,EAAWD,4BAAAA,SAAG,CAAU,QAAQ,CAAA;AAAA,QAChC,KAAA,EAAO,YAAA;AAAA,QAGN,QAAA,EAAA;AAAA,UAAA,SAAA,kBACCF,6BAAAA;AAAA,YAAC,sBAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAW,SAAA,CAAU,cAAA;AAAA,cACrB,EAAA;AAAA,cACA,MAAA,EAAQ,CAAA,EAAA;AAAS,YAAA;AAEjB,UAAA;AAGJ,0BAAA;AAAC,YAAA;AAAA,YAAA;AACC,cAAA;AACA,cAAA;AAGA,cAAA;AAAgB,YAAA;AAClB,UAAA;AAGC,UAAA;AACE,YAAA;AAAA,YAAA;AACC,cAAA;AACQ,cAAA;AACC,cAAA;AACP,gBAAA;AACF,cAAA;AAAA,YAAA;AACF,UAAA;AAID,UAAA;AACE,YAAA;AAAA,YAAA;AACC,cAAA;AACQ,cAAA;AACC,cAAA;AACP,gBAAA;AACF,cAAA;AAAA,YAAA;AAEA,UAAA;AAAA,QAAA;AAAA,MAAA;AACN,IAAA;AAGQ,IAAA;AAGD,MAAA;AAAA,MAAA;AAEQ,QAAA;AACP,QAAA;AAAA,MAAA;AAGN,IAAA;AAEJ,EAAA;AAEJ;AAEO;AF8BgB;AACA;AM7LvB;AACE;AACA;AACA;AACA;AACA;AACA;AACK;AACP;AACE;AACA;AACK;AACP;AACE;AACA;AACK;AAkEDA;AA7Ce;AACnB,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACiC;AAEjB,EAAA;AACJ,IAAA;AACA,IAAA;AACZ,EAAA;AAGe,EAAA;AACN,IAAA;AACT,EAAA;AAMM,EAAA;AACY,IAAA;AAGE,IAAA;AAEC,MAAA;AACF,QAAA;AACd,MAAA;AACgB,MAAA;AACF,QAAA;AACd,MAAA;AAEc,MAAA;AACjB,IAAA;AACF,EAAA;AAGE,EAAA;AAAC,IAAA;AAAA,IAAA;AACC,MAAA;AACY,MAAA;AACD,MAAA;AACX,MAAA;AAEA,MAAA;AAAC,QAAA;AAAA,QAAA;AACW,UAAA;AACH,UAAA;AACE,YAAA;AACR,UAAA;AAEA,UAAA;AAAA,QAAA;AACH,MAAA;AAAA,IAAA;AACF,EAAA;AAEJ;AAEO;ANgKgB;AACA;AC5JbI;AAzFG;AACJ,EAAA;AACS,IAAA;AACE,IAAA;AACG,IAAA;AACZ,IAAA;AACD,IAAA;AACI,IAAA;AACI,IAAA;AACE,IAAA;AAClB,EAAA;AACD;AAKmB;AACC,EAAA;AACnB,EAAA;AACW,EAAA;AACC,EAAA;AACS,EAAA;AACP,EAAA;AACE,EAAA;AAChB,EAAA;AACA,EAAA;AACW,EAAA;AACO,EAAA;AACG;AAzCvB,EAAA;AA2CmB,EAAA;AACC,EAAA;AAEZ,EAAA;AACJ,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AAAA;AAEiB,EAAA;AAEH,EAAA;AACd,IAAA;AACA,IAAA;AACD,EAAA;AAEc,EAAA;AAGA,EAAA;AAEA,IAAA;AACC,IAAA;AACO,IAAA;AACZ,IAAA;AACS,IAAA;AACH,IAAA;AACC,IAAA;AACf,EAAA;AAGG,EAAA;AAIF,EAAA;AACK,IAAA;AACT,EAAA;AAEM,EAAA;AACY,EAAA;AAGhB,EAAA;AACG,IAAA;AAAA,IAAA;AACY,MAAA;AACE,MAAA;AAMO,MAAA;AACH,QAAA;AACjB,MAAA;AAGC,MAAA;AACC,QAAA;AACG,UAAA;AAAA;AAEC,4BAAA;AAAC,cAAA;AAAA,cAAA;AAEC,gBAAA;AAEC,gBAAA;AAAA,cAAA;AACH,YAAA;AACE,UAAA;AACH,UAAA;AAID,QAAA;AAES,QAAA;AACL,UAAA;AACA,UAAA;AAGA,UAAA;AACI,YAAA;AACC,cAAA;AACT,YAAA;AACW,YAAA;AACH,cAAA;AACC,cAAA;AACT,YAAA;AACQ,YAAA;AACC,cAAA;AACT,YAAA;AACQ,YAAA;AACC,cAAA;AACT,YAAA;AACF,UAAA;AAGE,UAAA;AAAC,YAAA;AAAA,YAAA;AAEC,cAAA;AACA,cAAA;AACA,cAAA;AACA,cAAA;AACI,cAAA;AACJ,cAAA;AACA,cAAA;AACA,cAAA;AACS,cAAA;AACT,cAAA;AACQ,cAAA;AAEP,cAAA;AACC,gBAAA;AACA,gBAAA;AACA,gBAAA;AACM,gBAAA;AACN,gBAAA;AACD,cAAA;AAAA,YAAA;AAnBU,YAAA;AAoBb,UAAA;AAEH,QAAA;AAGD,wBAAA;AAACH,UAAAA;AAAA,UAAA;AACC,YAAA;AACW,YAAA;AACN,YAAA;AACM,YAAA;AACF,YAAA;AACA,cAAA;AACT,YAAA;AAEC,YAAA;AAAA,UAAA;AACH,QAAA;AAIC,QAAA;AAOG,MAAA;AAAA,IAAA;AAER,EAAA;AAEJ;AAEO;AD+MgB;AACA;AO3YhBI;AP6YgB;AACA;AACA;AACA;AACA","file":"/home/runner/work/pixels/pixels/packages/uniform/dist/chunk-JZF4HUYO.cjs","sourcesContent":[null,"import type { FieldArrayElementMethods } from './subcomponents/FieldArrayElement';\nimport type { FieldArrayProps } from './types';\n\nimport { cn, tv, variantsToClassNames } from '@fuf-stack/pixel-utils';\nimport { Button } from '@fuf-stack/pixels';\n\nimport { toNullishString } from '../helpers';\nimport { useFieldArray, useFormContext, useInput } from '../hooks';\nimport { FieldCopyTestIdButton } from '../partials/FieldCopyTestIdButton';\nimport { FieldValidationError } from '../partials/FieldValidationError';\nimport FieldArrayElement from './subcomponents/FieldArrayElement';\nimport SortContext from './subcomponents/SortContext';\n\nexport const fieldArrayVariants = tv({\n slots: {\n appendButton: 'w-full',\n elementWrapper: 'grow',\n insertAfterButton: 'text-xs font-medium',\n label: 'pointer-events-auto! static! z-0! -mb-1 ml-1 inline-block!',\n list: 'm-0 w-full list-none',\n listItem: 'mb-4 flex w-full flex-row',\n removeButton: 'ml-1',\n sortDragHandle: 'mr-2 text-base text-xl',\n },\n});\n\n/**\n * FieldArray component based in [RHF useFieldArray](https://react-hook-form.com/docs/usefieldarray)\n */\nconst FieldArray = ({\n appendButtonText = 'Add Element',\n children,\n className: _className = undefined,\n duplicate = false,\n elementInitialValue: _elementInitialValue = null,\n insertAfter = false,\n label: _label = undefined,\n lastElementNotRemovable = false,\n name,\n sortable = false,\n testId: _testId = undefined,\n}: FieldArrayProps) => {\n // className from slots\n const variants = fieldArrayVariants();\n const className = variantsToClassNames(variants, _className, 'list');\n\n const {\n control,\n debugMode,\n getValues,\n getFieldState,\n trigger,\n // watch\n } = useFormContext();\n\n const { fields, append, remove, insert, move } = useFieldArray({\n control,\n name,\n });\n\n const { error, testId, invalid, required } = getFieldState(name, _testId);\n\n // TODO: what about input props?\n const { label, getLabelProps, getHelperWrapperProps, getErrorMessageProps } =\n useInput({\n isInvalid: invalid,\n isRequired: required,\n errorMessage: JSON.stringify(error),\n label: _label,\n labelPlacement: 'inside',\n placeholder: ' ',\n classNames: { helperWrapper: 'block' },\n });\n\n // TODO: add info\n const elementInitialValue = toNullishString(_elementInitialValue);\n\n // When lastElementNotRemovable is set and the field array is empty,\n // add an initial element to ensure there's always at least one visible element\n if (lastElementNotRemovable && fields.length === 0) {\n append(elementInitialValue);\n }\n\n const showTestIdCopyButton = debugMode === 'debug-testids';\n const showLabel = label || showTestIdCopyButton;\n\n return (\n <SortContext fields={fields} move={move} sortable={sortable}>\n <ul\n className={className.list}\n data-testid={testId}\n /**\n * TODO: this trigger causes the field array (not element)\n * are shown immediately, but this will cause additional\n * render cycles, not sure if we should do this...\n */\n onBlur={async () => {\n return trigger(name);\n }}\n >\n {/* field array label */}\n {showLabel ? (\n <>\n {label ? (\n // eslint-disable-next-line jsx-a11y/label-has-associated-control\n <label\n {...getLabelProps()}\n className={cn(getLabelProps()?.className, className.label)}\n >\n {label}\n </label>\n ) : null}\n {showTestIdCopyButton ? (\n <FieldCopyTestIdButton testId={testId} />\n ) : null}\n </>\n ) : null}\n\n {fields.map((field, index) => {\n const elementName = `${name}.${index}`;\n const elementTestId = `${testId}_${index}`;\n\n // create methods for element\n const elementMethods: FieldArrayElementMethods = {\n append: () => {\n append(elementInitialValue);\n },\n duplicate: () => {\n const values = getValues(name);\n insert(index + 1, values[index]);\n },\n insert: () => {\n insert(index + 1, elementInitialValue);\n },\n remove: () => {\n remove(index);\n },\n };\n\n return (\n <FieldArrayElement\n key={field.id}\n arrayFieldName={name}\n className={className}\n duplicate={duplicate}\n fields={fields}\n id={field.id}\n index={index}\n insertAfter={insertAfter}\n lastNotDeletable={lastElementNotRemovable}\n methods={elementMethods}\n sortable={sortable}\n testId={elementTestId}\n >\n {children({\n index,\n length: fields.length,\n methods: elementMethods,\n name: elementName,\n testId: elementTestId,\n })}\n </FieldArrayElement>\n );\n })}\n\n {/* append elements */}\n <Button\n disableAnimation\n className={className.appendButton}\n size=\"sm\"\n testId={`${testId}_append_button`}\n onClick={() => {\n append(elementInitialValue);\n }}\n >\n {appendButtonText}\n </Button>\n\n {/* top level field array errors */}\n {/* @ts-expect-error rhf incompatibility */}\n {error?._errors ? (\n <div {...getHelperWrapperProps()}>\n <div {...getErrorMessageProps()}>\n {/* @ts-expect-error rhf incompatibility */}\n <FieldValidationError error={error?._errors} testId={testId} />\n </div>\n </div>\n ) : null}\n </ul>\n </SortContext>\n );\n};\n\nexport default FieldArray;\n","import type { ClassValue } from '@fuf-stack/pixel-utils';\nimport type { FieldArrayFeatures } from '../types';\n\nimport { useSortable } from '@dnd-kit/sortable';\nimport { CSS } from '@dnd-kit/utilities';\n\nimport { cn } from '@fuf-stack/pixel-utils';\n\nimport { Grid } from '../../Grid';\nimport { useFormContext, useInput } from '../../hooks';\nimport { FieldValidationError } from '../../partials/FieldValidationError';\nimport ElementInsertAfterButton from './ElementInsertAfterButton';\nimport ElementRemoveButton from './ElementRemoveButton';\nimport SortDragHandle from './SortDragHandle';\n\nexport interface FieldArrayElementMethods {\n /** Add new element at end */\n append: () => void;\n /** Clone current element */\n duplicate: () => void;\n /** Add new element after current */\n insert: () => void;\n /** Remove current element */\n remove: () => void;\n}\n\ninterface FieldArrayElementProps extends FieldArrayFeatures {\n /** Base field name for form context */\n arrayFieldName: string;\n /** Form elements to render inside array element */\n children: React.ReactNode;\n /** CSS class names for component parts */\n className: {\n /** Class of wrapper div inside the li that wraps the rendered element fields directly */\n elementWrapper?: ClassValue;\n /** Class for the li */\n listItem?: ClassValue;\n /** Class for the insert button between elements */\n insertAfterButton?: ClassValue;\n /** Class for the remove element button */\n removeButton?: ClassValue;\n /** Class for the drag handle when sorting enabled */\n sortDragHandle?: ClassValue;\n };\n /** All fields in the form array */\n fields: Record<'id', string>[];\n /** Unique identifier for drag/drop */\n id: string | number;\n /** Field index in array */\n index: number;\n /** Prevent deletion of last remaining element */\n lastNotDeletable?: boolean;\n /** Field array operation methods */\n methods: FieldArrayElementMethods;\n /** HTML data-testid of the element */\n testId?: string;\n}\n\n/**\n * Form array element component using react-hook-form with drag-drop sorting\n * and validation capabilities\n */\nconst FieldArrayElement = ({\n arrayFieldName,\n children,\n className,\n fields,\n id,\n index,\n insertAfter = false,\n lastNotDeletable = true,\n methods,\n sortable = false,\n testId = undefined,\n}: FieldArrayElementProps) => {\n const { getFieldState } = useFormContext();\n const { error, invalid } = getFieldState(arrayFieldName, undefined);\n\n // TODO: what about input props? and label props? Do we need a label?\n const { getHelperWrapperProps, getErrorMessageProps } = useInput({\n classNames: { helperWrapper: 'block' },\n errorMessage: JSON.stringify(error),\n isInvalid: invalid,\n labelPlacement: 'inside',\n placeholder: ' ',\n });\n\n // Apply transform styles when sortable is enabled for smooth drag animations\n // transform: handles the item's position during drag\n // transition: controls the animation timing when dropping\n const { setNodeRef, transform, transition } = useSortable({ id });\n const sortingStyle = sortable\n ? {\n transform: CSS.Translate.toString(transform),\n transition,\n }\n : undefined;\n\n return (\n <>\n <li\n ref={setNodeRef}\n className={cn(className.listItem)}\n style={sortingStyle}\n >\n {/** sorting drag handle */}\n {sortable ? (\n <SortDragHandle\n className={className.sortDragHandle}\n id={id}\n testId={`${testId}_sort_drag_handle`}\n />\n ) : null}\n\n {/** render element fields */}\n <div\n className={cn(className.elementWrapper)}\n data-testid={`${testId}_element_wrapper`}\n >\n {/* TODO: this has to be improved */}\n <Grid>{children}</Grid>\n </div>\n\n {/** remove element */}\n {lastNotDeletable && fields.length === 1 ? null : (\n <ElementRemoveButton\n className={className.removeButton}\n testId={`${testId}_remove_button`}\n onClick={() => {\n methods.remove();\n }}\n />\n )}\n\n {/** insertAfter feature when not last element */}\n {insertAfter && index !== fields.length - 1 ? (\n <ElementInsertAfterButton\n className={className.insertAfterButton}\n testId={`${testId}_insert_after_button`}\n onClick={() => {\n methods.insert();\n }}\n />\n ) : null}\n </li>\n\n {/** element error */}\n {typeof error?.[index] !== 'undefined' && (\n <div {...getHelperWrapperProps()}>\n <div {...getErrorMessageProps()}>\n <FieldValidationError\n /* @ts-expect-error rhf incompatibility */\n error={error[Number(index)]?._errors}\n testId={testId as string}\n />\n </div>\n </div>\n )}\n </>\n );\n};\n\nexport default FieldArrayElement;\n","import type { ClassValue } from '@fuf-stack/pixel-utils';\n\nimport { FaPlus } from 'react-icons/fa6';\n\nimport { cn } from '@fuf-stack/pixel-utils';\nimport { Button } from '@fuf-stack/pixels';\n\ninterface ElementInsertAfterButtonProps {\n /** CSS class name */\n className?: ClassValue;\n /** click handler */\n onClick: () => void;\n /** HTML data-testid attribute used in e2e tests */\n testId?: string;\n}\n\nconst ElementInsertAfterButton = ({\n className = undefined,\n onClick,\n testId = undefined,\n}: ElementInsertAfterButtonProps) => {\n return (\n <Button\n className={cn(className)}\n color=\"success\"\n icon={<FaPlus />}\n onClick={onClick}\n size=\"sm\"\n testId={testId}\n variant=\"light\"\n />\n );\n};\n\nexport default ElementInsertAfterButton;\n","import type { ClassValue } from '@fuf-stack/pixel-utils';\n\nimport { FaTimes } from 'react-icons/fa';\n\nimport { cn } from '@fuf-stack/pixel-utils';\nimport { Button } from '@fuf-stack/pixels';\n\ninterface ElementRemoveButtonProps {\n /** CSS class name */\n className?: ClassValue;\n /** click handler */\n onClick: () => void;\n /** HTML data-testid attribute used in e2e tests */\n testId?: string;\n}\n\nconst ElementRemoveButton = ({\n className = undefined,\n onClick,\n testId = undefined,\n}: ElementRemoveButtonProps) => {\n return (\n <Button\n ariaLabel=\"remove element\"\n className={cn(className)}\n color=\"danger\"\n icon={<FaTimes />}\n onClick={onClick}\n testId={testId}\n variant=\"light\"\n />\n );\n};\n\nexport default ElementRemoveButton;\n","import type { ClassValue } from '@fuf-stack/pixel-utils';\n\nimport { FaGripVertical } from 'react-icons/fa';\n\nimport { useSortable } from '@dnd-kit/sortable';\n\nimport { cn } from '@fuf-stack/pixel-utils';\n\ninterface SortDragHandleProps {\n /** Optional CSS class name */\n className?: ClassValue;\n /** Unique identifier for sortable item */\n id: string | number;\n /** HTML data-testid attribute used in e2e tests */\n testId?: string;\n}\n\n/**\n * Drag handle component that integrates with dnd-kit sortable functionality.\n * Renders a vertical grip icon that can be used to reorder items.\n */\nconst SortDragHandle = ({\n className = undefined,\n id,\n testId = undefined,\n}: SortDragHandleProps) => {\n // Get dnd-kit sortable attributes and listeners\n const { attributes, listeners } = useSortable({ id });\n\n return (\n <div\n className={cn(className)}\n data-testid={testId}\n {...attributes}\n {...listeners}\n >\n <FaGripVertical />\n </div>\n );\n};\n\nexport default SortDragHandle;\n","import type { DragEndEvent } from '@dnd-kit/core';\nimport type { ReactNode } from 'react';\nimport type { UseFieldArrayMove } from 'react-hook-form';\n\nimport {\n closestCenter,\n DndContext,\n KeyboardSensor,\n PointerSensor,\n useSensor,\n useSensors,\n} from '@dnd-kit/core';\nimport {\n restrictToVerticalAxis,\n restrictToWindowEdges,\n} from '@dnd-kit/modifiers';\nimport {\n SortableContext,\n verticalListSortingStrategy,\n} from '@dnd-kit/sortable';\n\ninterface SortContextProps {\n /** child components */\n children: ReactNode;\n /** enable/disable sorting functionality */\n sortable: boolean;\n /** Array of objects containing unique IDs for sortable items */\n fields: Record<'id', string>[];\n /** react-hook-form's move function to update field array indices */\n move: UseFieldArrayMove;\n}\n\n/**\n * A wrapper component that provides drag-and-drop sorting functionality for field arrays\n * using dnd-kit and react-hook-form.\n *\n * This component integrates with react-hook-form's field arrays to enable vertical\n * drag-and-drop reordering of form fields. It supports both pointer (mouse/touch)\n * and keyboard interactions for accessibility.\n */\nconst SortContext = ({\n children,\n sortable,\n fields,\n move,\n}: SortContextProps): ReactNode => {\n // Initialize sensors for both pointer (mouse/touch) and keyboard interactions\n const sensors = useSensors(\n useSensor(PointerSensor),\n useSensor(KeyboardSensor),\n );\n\n // Early return if sorting is disabled\n if (!sortable) {\n return children;\n }\n\n /**\n * Handles the end of a drag operation by updating field positions\n * @param event - The drag end event containing active and over elements\n */\n const handleDragEnd = (event: DragEndEvent) => {\n const { active, over } = event;\n\n // Only move if dropping over a different item\n if (active.id !== over?.id) {\n // Find the indices of the dragged item and drop target\n const oldIndex = fields.findIndex((field) => {\n return field.id === active.id;\n });\n const newIndex = fields.findIndex((field) => {\n return field.id === over?.id;\n });\n // Update the field array order using react-hook-form's move function\n move(oldIndex, newIndex);\n }\n };\n\n return (\n <DndContext\n collisionDetection={closestCenter}\n modifiers={[restrictToVerticalAxis, restrictToWindowEdges]}\n onDragEnd={handleDragEnd}\n sensors={sensors}\n >\n <SortableContext\n strategy={verticalListSortingStrategy}\n items={fields.map((field) => {\n return field.id;\n })}\n >\n {children}\n </SortableContext>\n </DndContext>\n );\n};\n\nexport default SortContext;\n","import FieldArray from './FieldArray';\n\nexport type * from './types';\n\nexport { FieldArray };\n\nexport default FieldArray;\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/RadioBoxes/RadioBoxes.tsx","../src/RadioBoxes/RadioBox.tsx","../src/RadioBoxes/index.ts"],"sourcesContent":["import type { TVClassName, TVProps } from '@fuf-stack/pixel-utils';\nimport type { ReactElement, ReactNode } from 'react';\n\nimport { RadioGroup as HeroRadioGroup } from '@heroui/radio';\n\nimport { slugify, tv, variantsToClassNames } from '@fuf-stack/pixel-utils';\n\nimport { useController, useFormContext } from '../hooks';\nimport { FieldCopyTestIdButton } from '../partials/FieldCopyTestIdButton';\nimport { FieldValidationError } from '../partials/FieldValidationError';\nimport { RadioBox } from './RadioBox';\n\nexport const radioBoxesVariants = tv({\n slots: {\n base: 'group', // Needs group for group-data condition\n itemBase: '',\n itemControl: 'bg-focus group-data-[invalid=true]:bg-danger',\n itemDescription: '',\n itemLabel: 'text-sm',\n itemLabelWrapper: '',\n itemWrapper:\n 'group-data-[invalid=true]:!border-danger [&:not(group-data-[invalid=\"true\"]):not(group-data-[selected=\"false\"])]:border-focus', // TODO: get rid of !.\n // see HeroUI styles for group-data condition,\n // e.g.: https://github.com/heroui-inc/heroui/blob/main/packages/core/theme/src/components/select.ts\n label:\n 'text-foreground group-data-[invalid=true]:text-danger text-sm subpixel-antialiased',\n wrapper: '',\n },\n});\n\ntype VariantProps = TVProps<typeof radioBoxesVariants>;\ntype ClassName = TVClassName<typeof radioBoxesVariants>;\n\nexport interface RadioBoxesOption {\n /** Description of the value. Works with variant radioBox. */\n description?: ReactNode;\n /** disables the option */\n disabled?: boolean;\n /** option label */\n label?: ReactNode;\n /** option icon */\n icon?: ReactNode;\n /** HTML data-testid attribute of the option */\n testId?: string;\n /** option value */\n value: string;\n}\n\nexport interface RadioBoxesProps extends VariantProps {\n /** CSS class name */\n className?: ClassName;\n /** Determines if the Buttons are disabled or not. */\n disabled?: boolean;\n /** determines orientation of the Buttons. */\n inline?: boolean;\n /** Label displayed next to the RadioButton. */\n label?: ReactNode;\n /** Name the RadioButtons are registered at in HTML forms (react-hook-form). */\n name: string;\n /** Radio button configuration. */\n options: RadioBoxesOption[];\n /** Id to grab element in internal tests. */\n testId?: string;\n}\n\n/**\n * RadioBoxes component based on [HeroUI RadioGroup](https://www.heroui.com//docs/components/radio-group)\n */\nconst RadioBoxes = ({\n className = undefined,\n disabled = false,\n inline = false,\n label = undefined,\n name,\n options,\n testId: _testId = undefined,\n}: RadioBoxesProps): ReactElement => {\n const { control, debugMode, getFieldState, getValues } = useFormContext();\n\n const { error, invalid, required, testId } = getFieldState(name, _testId);\n\n const { field } = useController({ control, disabled, name });\n const { onChange, disabled: isDisabled, onBlur, ref } = field;\n\n const showTestIdCopyButton = debugMode === 'debug-testids';\n const showLabel = label || showTestIdCopyButton;\n\n const variants = radioBoxesVariants();\n const classNames = variantsToClassNames(variants, className, 'base');\n\n const itemClassNames = {\n base: classNames.itemBase,\n control: classNames.itemControl,\n description: classNames.itemDescription,\n label: classNames.itemLabel,\n labelWrapper: classNames.itemLabelWrapper,\n wrapper: classNames.itemWrapper,\n };\n\n return (\n <HeroRadioGroup\n classNames={classNames}\n // see HeroUI styles for group-data condition (data-invalid),\n // e.g.: https://github.com/heroui-inc/heroui/blob/main/packages/components/select/src/use-select.ts\n ref={ref}\n data-invalid={invalid}\n data-required={required}\n data-testid={testId}\n defaultValue={getValues()[name]}\n isDisabled={isDisabled}\n isInvalid={invalid}\n isRequired={required}\n name={name}\n onBlur={onBlur}\n orientation={inline ? 'horizontal' : 'vertical'}\n errorMessage={\n error && <FieldValidationError error={error} testId={testId} />\n }\n label={\n showLabel && (\n // eslint-disable-next-line jsx-a11y/label-has-associated-control\n <label>\n {label}\n {showTestIdCopyButton && <FieldCopyTestIdButton testId={testId} />}\n </label>\n )\n }\n >\n {options.map((option) => {\n if ('value' in option) {\n const optionTestId = slugify(\n `${testId}_option_${option.testId || option.value}`,\n { replaceDots: true },\n );\n return (\n <RadioBox\n key={option.value}\n classNames={itemClassNames}\n data-testid={optionTestId}\n description={option.description}\n icon={option.icon}\n isDisabled={isDisabled || option.disabled}\n onChange={onChange}\n value={option.value}\n >\n {option.label ? option.label : option.value}\n </RadioBox>\n );\n }\n return null;\n })}\n </HeroRadioGroup>\n );\n};\n\nexport default RadioBoxes;\n","import type { RadioProps as HeroRadioProps } from '@heroui/radio';\nimport type { ReactNode } from 'react';\n\nimport { useRadio } from '@heroui/radio';\nimport { VisuallyHidden } from '@react-aria/visually-hidden';\n\nimport { cn } from '@fuf-stack/pixel-utils';\n\ninterface RadioProps extends HeroRadioProps {\n /** icon for the option */\n icon?: ReactNode;\n}\n\nexport const RadioBox = ({ icon = undefined, ...props }: RadioProps) => {\n const {\n children,\n Component,\n description,\n getBaseProps,\n getControlProps,\n getInputProps,\n getLabelProps,\n getLabelWrapperProps,\n getWrapperProps,\n isDisabled,\n } = useRadio(props);\n\n return (\n <Component\n {...getBaseProps()}\n className={cn(\n 'group border-default hover:bg-content2 data-[selected=true]:border-focus inline-flex flex-auto cursor-pointer items-center justify-between gap-4 rounded-lg border-2 p-4',\n {\n // disabled styles\n 'opacity-disabled pointer-events-none': isDisabled,\n },\n )}\n >\n <VisuallyHidden>\n <input {...getInputProps()} />\n </VisuallyHidden>\n <span {...getWrapperProps()}>\n <span {...getControlProps()} />\n </span>\n {icon}\n <div\n {...getLabelWrapperProps()}\n className={cn(getLabelWrapperProps().className, 'grow')}\n >\n {children ? <span {...getLabelProps()}>{children}</span> : null}\n {description ? (\n <span className=\"text-small text-foreground opacity-70\">\n {description}\n </span>\n ) : null}\n </div>\n </Component>\n );\n};\n\nexport default RadioBox;\n","import RadioBoxes from './RadioBoxes';\n\nexport type { RadioBoxesProps } from './RadioBoxes';\n\nexport { RadioBoxes };\n\nexport default RadioBoxes;\n"],"mappings":"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","names":["jsx","jsxs","RadioBoxes_default"]}
@@ -1,76 +0,0 @@
1
- // src/helpers/nullishFields/nullishFields.ts
2
- var nullString = "__NULL__";
3
- var falseString = "__FALSE__";
4
- var zeroString = "__ZERO__";
5
- var fromNullishString = (value) => {
6
- if (typeof value !== "string") {
7
- return value;
8
- }
9
- switch (value) {
10
- case nullString:
11
- return null;
12
- case falseString:
13
- return false;
14
- case zeroString:
15
- return 0;
16
- default:
17
- return value;
18
- }
19
- };
20
- var toNullishString = (value) => {
21
- if (value === null || value === "") {
22
- return nullString;
23
- }
24
- if (value === false) {
25
- return falseString;
26
- }
27
- if (value === 0) {
28
- return zeroString;
29
- }
30
- return value;
31
- };
32
- var toFormFormat = (fields) => {
33
- const formFormatJson = JSON.stringify(fields, (_, value) => {
34
- if (Array.isArray(value)) {
35
- return value.map(toNullishString);
36
- }
37
- if (value && typeof value === "object") {
38
- return Object.fromEntries(
39
- Object.entries(value).filter(([_key, v]) => {
40
- return v !== "" && v !== null;
41
- })
42
- );
43
- }
44
- return value;
45
- });
46
- return JSON.parse(formFormatJson);
47
- };
48
- var toValidationFormat = (formState) => {
49
- if (formState === void 0 || formState === null) {
50
- return formState;
51
- }
52
- const validationFormatJson = JSON.stringify(formState, (_, value) => {
53
- if (Array.isArray(value)) {
54
- return value.map(fromNullishString);
55
- }
56
- if (value && typeof value === "object") {
57
- return Object.fromEntries(
58
- Object.entries(value).filter(([_key, v]) => {
59
- return fromNullishString(v) !== "" && fromNullishString(v) !== null;
60
- }).map(([k, v]) => {
61
- return [k, fromNullishString(v)];
62
- })
63
- );
64
- }
65
- return value;
66
- });
67
- return JSON.parse(validationFormatJson);
68
- };
69
-
70
- export {
71
- fromNullishString,
72
- toNullishString,
73
- toFormFormat,
74
- toValidationFormat
75
- };
76
- //# sourceMappingURL=chunk-KQN55PEW.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/helpers/nullishFields/nullishFields.ts"],"sourcesContent":["/**\n * String markers used to preserve null, false, and 0 values during JSON processing\n */\nconst nullString = '__NULL__';\nconst falseString = '__FALSE__';\nconst zeroString = '__ZERO__';\n\n/**\n * Converts marker strings back to their original values when processing arrays\n */\nexport const fromNullishString = (value: unknown): unknown => {\n if (typeof value !== 'string') {\n return value;\n }\n\n switch (value) {\n case nullString:\n return null;\n case falseString:\n return false;\n case zeroString:\n return 0;\n default:\n return value;\n }\n};\n\n/**\n * Converts null/falsy values to marker strings for JSON processing\n */\nexport const toNullishString = (value: unknown): unknown => {\n if (value === null || value === '') {\n return nullString;\n }\n if (value === false) {\n return falseString;\n }\n if (value === 0) {\n return zeroString;\n }\n return value;\n};\n\n/**\n * Converts field values to a format suitable for forms by:\n * - Converting array values to their string markers to preserve null/falsy values\n * - Removing empty strings and null values from objects\n *\n * This conversion is required because React Hook Form does not support arrays with\n * flat values (string, number, boolean, null). Array fields must contain objects.\n * We work around this by converting array values to string markers.\n *\n * @example\n * const fields = {\n * name: 'John',\n * scores: [0, null, 75, false],\n * contact: {\n * email: '',\n * phone: null,\n * address: '123 Main St'\n * }\n * };\n *\n * // Result:\n * {\n * name: 'John',\n * scores: ['__ZERO__', '__NULL__', 75, '__FALSE__'],\n * contact: {\n * address: '123 Main St'\n * }\n * }\n */\nexport const toFormFormat = (fields: Record<string, unknown>) => {\n const formFormatJson = JSON.stringify(fields, (_, value) => {\n if (Array.isArray(value)) {\n return value.map(toNullishString);\n }\n\n if (value && typeof value === 'object') {\n return Object.fromEntries(\n Object.entries(value).filter(([_key, v]) => {\n return v !== '' && v !== null;\n }),\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return value;\n });\n\n return JSON.parse(formFormatJson) as Record<string, unknown>;\n};\n\n/**\n * Converts form state to a format suitable for validation by:\n * - Converting array string markers (__NULL__, __FALSE__, __ZERO__) back to their original values\n * - Converting _NULL__ to null\n * - Removing fields that contain empty strings, null, or any string markers representing null/empty values\n *\n * @example\n * const formState = {\n * name: 'John',\n * scores: [75, '__ZERO__', '_NULL__', '__FALSE__'],\n * email: null,\n * phone: '__NULL__',\n * contact: {\n * address: '123 Main St',\n * fax: null\n * }\n * };\n *\n * // Result:\n * {\n * name: 'John',\n * scores: [75, 0, null, false],\n * contact: {\n * address: '123 Main St'\n * }\n * }\n */\nexport const toValidationFormat = (\n formState: Record<string, unknown> | null | undefined,\n): Record<string, unknown> | null | undefined => {\n // Handle null or undefined input\n if (formState === undefined || formState === null) {\n return formState;\n }\n\n const validationFormatJson = JSON.stringify(formState, (_, value) => {\n if (Array.isArray(value)) {\n return value.map(fromNullishString);\n }\n\n if (value && typeof value === 'object') {\n return Object.fromEntries(\n Object.entries(value)\n .filter(([_key, v]) => {\n return fromNullishString(v) !== '' && fromNullishString(v) !== null;\n })\n .map(([k, v]) => {\n return [k, fromNullishString(v)];\n }),\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return value;\n });\n\n return JSON.parse(validationFormatJson) as Record<string, unknown>;\n};\n"],"mappings":";AAGA,IAAM,aAAa;AACnB,IAAM,cAAc;AACpB,IAAM,aAAa;AAKZ,IAAM,oBAAoB,CAAC,UAA4B;AAC5D,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AAEA,UAAQ,OAAO;AAAA,IACb,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAKO,IAAM,kBAAkB,CAAC,UAA4B;AAC1D,MAAI,UAAU,QAAQ,UAAU,IAAI;AAClC,WAAO;AAAA,EACT;AACA,MAAI,UAAU,OAAO;AACnB,WAAO;AAAA,EACT;AACA,MAAI,UAAU,GAAG;AACf,WAAO;AAAA,EACT;AACA,SAAO;AACT;AA+BO,IAAM,eAAe,CAAC,WAAoC;AAC/D,QAAM,iBAAiB,KAAK,UAAU,QAAQ,CAAC,GAAG,UAAU;AAC1D,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,aAAO,MAAM,IAAI,eAAe;AAAA,IAClC;AAEA,QAAI,SAAS,OAAO,UAAU,UAAU;AACtC,aAAO,OAAO;AAAA,QACZ,OAAO,QAAQ,KAAK,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,MAAM;AAC1C,iBAAO,MAAM,MAAM,MAAM;AAAA,QAC3B,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,EACT,CAAC;AAED,SAAO,KAAK,MAAM,cAAc;AAClC;AA6BO,IAAM,qBAAqB,CAChC,cAC+C;AAE/C,MAAI,cAAc,UAAa,cAAc,MAAM;AACjD,WAAO;AAAA,EACT;AAEA,QAAM,uBAAuB,KAAK,UAAU,WAAW,CAAC,GAAG,UAAU;AACnE,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,aAAO,MAAM,IAAI,iBAAiB;AAAA,IACpC;AAEA,QAAI,SAAS,OAAO,UAAU,UAAU;AACtC,aAAO,OAAO;AAAA,QACZ,OAAO,QAAQ,KAAK,EACjB,OAAO,CAAC,CAAC,MAAM,CAAC,MAAM;AACrB,iBAAO,kBAAkB,CAAC,MAAM,MAAM,kBAAkB,CAAC,MAAM;AAAA,QACjE,CAAC,EACA,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM;AACf,iBAAO,CAAC,GAAG,kBAAkB,CAAC,CAAC;AAAA,QACjC,CAAC;AAAA,MACL;AAAA,IACF;AAEA,WAAO;AAAA,EACT,CAAC;AAED,SAAO,KAAK,MAAM,oBAAoB;AACxC;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/Input/Input.tsx","../src/Input/index.ts"],"sourcesContent":["import type { TVClassName, TVProps } from '@fuf-stack/pixel-utils';\nimport type { InputProps as HeroInputProps } from '@heroui/input';\nimport type { ReactNode } from 'react';\nimport type { InputValueTransform } from '../hooks';\n\nimport { Input as HeroInput } from '@heroui/input';\n\nimport { tv, variantsToClassNames } from '@fuf-stack/pixel-utils';\n\nimport { useController, useFormContext, useInputValueDebounce } from '../hooks';\nimport { FieldCopyTestIdButton } from '../partials/FieldCopyTestIdButton';\nimport { FieldValidationError } from '../partials/FieldValidationError';\n\n// input variants\nexport const inputVariants = tv({\n slots: {\n /** wrapper around the whole input */\n base: '',\n /** clear button */\n clearButton: '',\n /** actual input element */\n input: '',\n /** inner wrapper (HeroUI inputWrapper slot) */\n inputWrapper: 'bg-content1 group-data-[focus=true]:border-focus',\n },\n});\n\ntype VariantProps = TVProps<typeof inputVariants>;\ntype ClassName = TVClassName<typeof inputVariants>;\n\nexport interface InputProps extends VariantProps {\n /** CSS class name */\n className?: ClassName;\n /** shows clear button when input has value */\n clearable?: boolean;\n /** debounce delay in milliseconds for form state updates (default: 300ms) */\n debounceDelay?: number;\n /** input field is disabled */\n disabled?: boolean;\n /** added content to the end of the input Field. */\n endContent?: ReactNode;\n /** form field label (set to false to disable label) */\n label?: string | false;\n /** form field name */\n name: string;\n /** callback that is fired when the value is cleared */\n onClear?: () => void;\n /** form field placeholder */\n placeholder?: string;\n /** size of the input */\n size?: 'sm' | 'md' | 'lg';\n /** content added to the start of the input field */\n startContent?: ReactNode;\n /** HTML data-testid attribute used in e2e tests */\n testId?: string;\n /** allows disentangled display and form values for a field */\n transform?: InputValueTransform;\n /** input type */\n type?: 'number' | 'password';\n}\n\n/**\n * Input component based on [HeroUI Input](https://www.heroui.com//docs/components/input)\n */\nconst Input = ({\n className: _className = undefined,\n clearable = false,\n debounceDelay = 300,\n disabled = false,\n endContent = undefined,\n label = undefined,\n name,\n onClear = undefined,\n placeholder = ' ',\n size = undefined,\n startContent = undefined,\n testId: _testId = undefined,\n transform = undefined,\n type = undefined,\n}: InputProps) => {\n const { control, debugMode, getFieldState, resetField } = useFormContext();\n const { error, invalid, required, testId } = getFieldState(name, _testId);\n\n const { field } = useController({\n control,\n disabled,\n name,\n });\n\n const {\n disabled: isDisabled,\n onChange: fieldOnChange,\n onBlur: fieldOnBlur,\n value: fieldValue,\n ref,\n } = field;\n\n // Use hook that provides debounced onChange and enhanced blur handling\n const { onChange, onBlur, value } = useInputValueDebounce({\n debounceDelay,\n onBlur: fieldOnBlur,\n onChange: fieldOnChange,\n transform,\n type,\n value: fieldValue,\n });\n\n // If input is clearable add props for clearing input value\n const clearableProps: Pick<HeroInputProps, 'isClearable' | 'onClear'> =\n clearable\n ? {\n isClearable: true,\n onClear: () => {\n // if field had initial value we do not reset it\n // to that value, but clear it instead\n resetField(name, { defaultValue: null });\n // if onClear cb provided we call it\n if (onClear) {\n onClear();\n }\n },\n }\n : {};\n\n const showTestIdCopyButton = debugMode === 'debug-testids';\n const showLabel = label ?? showTestIdCopyButton;\n\n // classNames from slots\n const variants = inputVariants();\n const classNames = variantsToClassNames(variants, _className, 'base');\n\n return (\n <HeroInput\n ref={ref}\n data-testid={testId}\n endContent={endContent}\n isDisabled={isDisabled}\n isInvalid={invalid}\n isRequired={required}\n labelPlacement=\"outside\"\n name={name}\n onBlur={onBlur}\n onChange={onChange}\n placeholder={placeholder}\n radius=\"sm\"\n size={size}\n startContent={startContent}\n type={type}\n // @ts-expect-error can be number for input type number\n value={value}\n variant=\"bordered\"\n classNames={{\n base: classNames.base,\n clearButton: classNames.clearButton,\n input: classNames.input,\n inputWrapper: classNames.inputWrapper,\n }}\n errorMessage={\n error ? <FieldValidationError error={error} testId={testId} /> : null\n }\n label={\n showLabel ? (\n <>\n {label}\n {showTestIdCopyButton ?? <FieldCopyTestIdButton testId={testId} />}\n </>\n ) : null\n }\n {...clearableProps}\n />\n );\n};\n\nexport default Input;\n","import Input from './Input';\n\nexport type { InputProps } from './Input';\n\nexport { Input };\n\nexport default Input;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAKA,SAAS,SAAS,iBAAiB;AAEnC,SAAS,IAAI,4BAA4B;AAuJzB,SAIN,UAJM,KAIN,YAJM;AAhJT,IAAM,gBAAgB,GAAG;AAAA,EAC9B,OAAO;AAAA;AAAA,IAEL,MAAM;AAAA;AAAA,IAEN,aAAa;AAAA;AAAA,IAEb,OAAO;AAAA;AAAA,IAEP,cAAc;AAAA,EAChB;AACF,CAAC;AAuCD,IAAM,QAAQ,CAAC;AAAA,EACb,WAAW,aAAa;AAAA,EACxB,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,WAAW;AAAA,EACX,aAAa;AAAA,EACb,QAAQ;AAAA,EACR;AAAA,EACA,UAAU;AAAA,EACV,cAAc;AAAA,EACd,OAAO;AAAA,EACP,eAAe;AAAA,EACf,QAAQ,UAAU;AAAA,EAClB,YAAY;AAAA,EACZ,OAAO;AACT,MAAkB;AAChB,QAAM,EAAE,SAAS,WAAW,eAAe,WAAW,IAAI,eAAe;AACzE,QAAM,EAAE,OAAO,SAAS,UAAU,OAAO,IAAI,cAAc,MAAM,OAAO;AAExE,QAAM,EAAE,MAAM,IAAI,cAAc;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM;AAAA,IACJ,UAAU;AAAA,IACV,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,OAAO;AAAA,IACP;AAAA,EACF,IAAI;AAGJ,QAAM,EAAE,UAAU,QAAQ,MAAM,IAAI,sBAAsB;AAAA,IACxD;AAAA,IACA,QAAQ;AAAA,IACR,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,OAAO;AAAA,EACT,CAAC;AAGD,QAAM,iBACJ,YACI;AAAA,IACE,aAAa;AAAA,IACb,SAAS,MAAM;AAGb,iBAAW,MAAM,EAAE,cAAc,KAAK,CAAC;AAEvC,UAAI,SAAS;AACX,gBAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF,IACA,CAAC;AAEP,QAAM,uBAAuB,cAAc;AAC3C,QAAM,YAAY,wBAAS;AAG3B,QAAM,WAAW,cAAc;AAC/B,QAAM,aAAa,qBAAqB,UAAU,YAAY,MAAM;AAEpE,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,eAAa;AAAA,MACb;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,gBAAe;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MAEA;AAAA,MACA,SAAQ;AAAA,MACR,YAAY;AAAA,QACV,MAAM,WAAW;AAAA,QACjB,aAAa,WAAW;AAAA,QACxB,OAAO,WAAW;AAAA,QAClB,cAAc,WAAW;AAAA,MAC3B;AAAA,MACA,cACE,QAAQ,oBAAC,gCAAqB,OAAc,QAAgB,IAAK;AAAA,MAEnE,OACE,YACE,iCACG;AAAA;AAAA,QACA,sDAAwB,oBAAC,iCAAsB,QAAgB;AAAA,SAClE,IACE;AAAA,OAEF;AAAA,EACN;AAEJ;AAEA,IAAO,gBAAQ;;;ACvKf,IAAOA,iBAAQ;","names":["Input_default"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/Switch/Switch.tsx","../src/Switch/index.ts"],"sourcesContent":["import type { TVClassName, TVProps } from '@fuf-stack/pixel-utils';\nimport type { SwitchProps as HeroSwitchProps } from '@heroui/switch';\nimport type { ReactNode } from 'react';\n\nimport { Switch as HeroSwitch } from '@heroui/switch';\n\nimport { tv, variantsToClassNames } from '@fuf-stack/pixel-utils';\n\nimport { useController, useFormContext, useInput } from '../hooks';\nimport { FieldCopyTestIdButton } from '../partials/FieldCopyTestIdButton';\nimport { FieldValidationError } from '../partials/FieldValidationError';\n\nexport const switchVariants = tv({\n slots: {\n base: '',\n endContent: '',\n errorMessage: 'mt-1 ml-1',\n // see HeroUI styles for group-data condition,\n // e.g.: https://github.com/heroui-inc/heroui/blob/main/packages/core/theme/src/components/select.ts\n label:\n 'text-foreground group-data-[invalid=true]:!text-danger group-data-[required=true]:after:text-danger text-sm subpixel-antialiased group-data-[required=true]:after:ml-0.5 group-data-[required=true]:after:content-[\"*\"]',\n outerWrapper: 'place-content-center',\n startContent: '',\n thumb: '',\n thumbIcon: '',\n wrapper: '',\n },\n});\n\ntype VariantProps = TVProps<typeof switchVariants>;\ntype ClassName = TVClassName<typeof switchVariants>;\n\nexport interface SwitchProps extends VariantProps {\n /** CSS class name */\n className?: ClassName;\n /** whether the select should be disabled */\n disabled?: boolean;\n /** Icon to be displayed at the end of the switch (when enabled) */\n endContent?: ReactNode;\n /** component displayed next to the switch */\n label?: ReactNode;\n /** name the field is registered under */\n name: string;\n /* Size of the switch */\n size?: 'sm' | 'md' | 'lg';\n /** Icon to be displayed at the start of the switch (when disabled) */\n startContent?: ReactNode;\n /** HTML data-testid attribute used in e2e tests */\n testId?: string;\n /** Icon to be displayed inside the thumb */\n thumbIcon?: HeroSwitchProps['thumbIcon'];\n}\n\n/**\n * Switch component based on [HeroUI Switch](https://www.heroui.com//docs/components/switch)\n */\nconst Switch = ({\n className = undefined,\n disabled = false,\n endContent = undefined,\n label: _label = undefined,\n name,\n size = undefined,\n startContent = undefined,\n testId: _testId = undefined,\n thumbIcon = undefined,\n}: SwitchProps) => {\n const { control, debugMode, getFieldState } = useFormContext();\n const { error, required, testId, invalid } = getFieldState(name, _testId);\n\n const { field } = useController({ name, control, disabled });\n const { disabled: isDisabled, value, ref, onBlur, onChange } = field;\n\n const { label, getInputProps, getErrorMessageProps } = useInput({\n errorMessage: JSON.stringify(error),\n isInvalid: invalid,\n isRequired: required,\n label: _label,\n labelPlacement: 'outside',\n placeholder: ' ',\n });\n\n const variants = switchVariants();\n const classNames = variantsToClassNames(variants, className, 'outerWrapper');\n\n const showTestIdCopyButton = debugMode === 'debug-testids';\n\n return (\n <div className={classNames.outerWrapper}>\n <HeroSwitch\n ref={ref}\n // see HeroUI styles for group-data condition (data-invalid),\n // e.g.: https://github.com/heroui-inc/heroui/blob/main/packages/components/select/src/use-select.ts\n aria-describedby={getInputProps()['aria-describedby']}\n classNames={classNames}\n data-invalid={invalid}\n data-required={required}\n data-testid={testId}\n endContent={endContent}\n isDisabled={isDisabled}\n isSelected={!!value}\n name={name}\n onBlur={onBlur}\n onValueChange={onChange}\n required={required}\n size={size}\n startContent={startContent}\n thumbIcon={thumbIcon}\n value={value}\n >\n {label}\n {showTestIdCopyButton ? (\n <FieldCopyTestIdButton testId={testId} />\n ) : null}\n </HeroSwitch>\n {error ? (\n <div className={classNames.errorMessage}>\n <div {...getErrorMessageProps()}>\n <FieldValidationError error={error} testId={testId} />\n </div>\n </div>\n ) : null}\n </div>\n );\n};\n\nexport default Switch;\n","import Switch from './Switch';\n\nexport type { SwitchProps } from './Switch';\n\nexport { Switch };\n\nexport default Switch;\n"],"mappings":";;;;;;;;;;;;;;;;;AAIA,SAAS,UAAU,kBAAkB;AAErC,SAAS,IAAI,4BAA4B;AAmFnC,SAuBI,KAvBJ;AA7EC,IAAM,iBAAiB,GAAG;AAAA,EAC/B,OAAO;AAAA,IACL,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,cAAc;AAAA;AAAA;AAAA,IAGd,OACE;AAAA,IACF,cAAc;AAAA,IACd,cAAc;AAAA,IACd,OAAO;AAAA,IACP,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AACF,CAAC;AA6BD,IAAM,SAAS,CAAC;AAAA,EACd,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,aAAa;AAAA,EACb,OAAO,SAAS;AAAA,EAChB;AAAA,EACA,OAAO;AAAA,EACP,eAAe;AAAA,EACf,QAAQ,UAAU;AAAA,EAClB,YAAY;AACd,MAAmB;AACjB,QAAM,EAAE,SAAS,WAAW,cAAc,IAAI,eAAe;AAC7D,QAAM,EAAE,OAAO,UAAU,QAAQ,QAAQ,IAAI,cAAc,MAAM,OAAO;AAExE,QAAM,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,SAAS,SAAS,CAAC;AAC3D,QAAM,EAAE,UAAU,YAAY,OAAO,KAAK,QAAQ,SAAS,IAAI;AAE/D,QAAM,EAAE,OAAO,eAAe,qBAAqB,IAAI,SAAS;AAAA,IAC9D,cAAc,KAAK,UAAU,KAAK;AAAA,IAClC,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,gBAAgB;AAAA,IAChB,aAAa;AAAA,EACf,CAAC;AAED,QAAM,WAAW,eAAe;AAChC,QAAM,aAAa,qBAAqB,UAAU,WAAW,cAAc;AAE3E,QAAM,uBAAuB,cAAc;AAE3C,SACE,qBAAC,SAAI,WAAW,WAAW,cACzB;AAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QAGA,oBAAkB,cAAc,EAAE,kBAAkB;AAAA,QACpD;AAAA,QACA,gBAAc;AAAA,QACd,iBAAe;AAAA,QACf,eAAa;AAAA,QACb;AAAA,QACA;AAAA,QACA,YAAY,CAAC,CAAC;AAAA,QACd;AAAA,QACA;AAAA,QACA,eAAe;AAAA,QACf;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QAEC;AAAA;AAAA,UACA,uBACC,oBAAC,iCAAsB,QAAgB,IACrC;AAAA;AAAA;AAAA,IACN;AAAA,IACC,QACC,oBAAC,SAAI,WAAW,WAAW,cACzB,8BAAC,wCAAQ,qBAAqB,IAA7B,EACC,8BAAC,gCAAqB,OAAc,QAAgB,IACtD,GACF,IACE;AAAA,KACN;AAEJ;AAEA,IAAO,iBAAQ;;;ACxHf,IAAOA,kBAAQ;","names":["Switch_default"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/work/pixels/pixels/packages/uniform/dist/chunk-N2EEOWEP.cjs","../src/CheckboxGroup/CheckboxGroup.tsx","../src/CheckboxGroup/index.ts"],"names":["CheckboxGroup_default"],"mappings":"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","file":"/home/runner/work/pixels/pixels/packages/uniform/dist/chunk-N2EEOWEP.cjs","sourcesContent":[null,"import type { TVClassName, TVProps } from '@fuf-stack/pixel-utils';\nimport type { ReactNode } from 'react';\nimport type { FieldError } from 'react-hook-form';\n\nimport {\n Checkbox as HeroCheckbox,\n CheckboxGroup as HeroCheckboxGroup,\n} from '@heroui/checkbox';\nimport { checkbox as heroCheckboxVariants } from '@heroui/theme';\n\nimport { slugify, tv, variantsToClassNames } from '@fuf-stack/pixel-utils';\n\nimport { useController, useFormContext } from '../hooks';\nimport { FieldCopyTestIdButton } from '../partials/FieldCopyTestIdButton';\nimport { FieldValidationError } from '../partials/FieldValidationError';\n\nexport const checkboxGroupVariants = tv({\n slots: {\n base: 'group', // Needs group for group-data condition\n errorMessage: 'text-tiny',\n // see HeroUI styles for group-data condition,\n // e.g.: https://github.com/heroui-inc/heroui/blob/main/packages/core/theme/src/components/select.ts\n label:\n 'text-foreground group-data-[invalid=true]:!text-danger text-sm subpixel-antialiased',\n optionBase: '',\n optionIcon: '',\n optionLabel: '',\n optionLabelSubline: '!text-small text-foreground-400',\n optionWrapper: '',\n wrapper: '',\n },\n variants: {\n // see: https://github.com/heroui-inc/heroui/blob/canary/packages/core/theme/src/components/checkbox.ts\n color: {\n info: {\n wrapper:\n 'text-info-foreground after:bg-info after:text-info-foreground',\n },\n ...heroCheckboxVariants.variants.color,\n } as const,\n lineThrough: {\n true: {\n optionLabel: [\n ...heroCheckboxVariants.variants.lineThrough.true.label,\n // fix stroke position when used with subline and enable animation\n 'relative before:transition-all before:duration-200',\n ],\n optionLabelSubline: 'group-data-[selected=true]:opacity-60',\n },\n },\n },\n});\n\ntype VariantProps = TVProps<typeof checkboxGroupVariants>;\ntype ClassName = TVClassName<typeof checkboxGroupVariants>;\n\nexport interface CheckboxGroupOption {\n /** option label */\n label?: ReactNode;\n /** subline displayed below the label */\n labelSubline?: ReactNode;\n /** option value */\n value: string;\n /** disables the option */\n disabled?: boolean;\n /** HTML data-testid attribute of the option */\n testId?: string;\n}\n\nexport interface CheckboxGroupProps extends VariantProps {\n /** CSS class name */\n className?: ClassName;\n /** Color scheme of the checkboxes */\n color?: VariantProps['color'];\n /** Sets all checkboxes disabled */\n disabled?: boolean;\n /** Orientation of the checkboxes */\n inline?: boolean;\n /** Label displayed above the checkboxes */\n label?: ReactNode;\n /** Whether the checkboxes label should be crossed out */\n lineThrough?: boolean;\n /** Name the Field is registered on the form */\n name: string;\n /** Checkboxes that should be displayed. */\n options: CheckboxGroupOption[];\n /** HTML data-testid attribute used in e2e tests */\n testId?: string;\n}\n\n/**\n * CheckboxGroup component based on [HeroUI CheckboxGroup](https://www.heroui.com//docs/components/checkbox-group)\n */\nconst CheckboxGroup = ({\n className = undefined,\n color = 'primary',\n inline = false,\n label = undefined,\n lineThrough = false,\n options,\n disabled = false,\n name,\n testId: _testId = undefined,\n}: CheckboxGroupProps) => {\n const { control, debugMode, getFieldState } = useFormContext();\n const {\n error: _error,\n invalid,\n required,\n testId,\n } = getFieldState(name, _testId);\n\n const { field } = useController({ control, name, disabled });\n const { onChange, value = [], ref, onBlur } = field;\n\n const showTestIdCopyButton = debugMode === 'debug-testids';\n const showLabel = label || showTestIdCopyButton;\n\n const variants = checkboxGroupVariants({ lineThrough });\n const classNames = variantsToClassNames(variants, className, 'base');\n\n // map slots to HeroUI class names\n const heroCheckboxGroupClassNames = {\n base: classNames.base,\n label: classNames.label,\n wrapper: classNames.wrapper,\n };\n const heroCheckboxClassNames = {\n base: classNames.optionBase,\n icon: classNames.optionIcon,\n label: classNames.optionLabel,\n wrapper: classNames.optionWrapper,\n };\n\n // Convert React Hook Form's nested error object structure to a flat array\n // RHF errors can be nested like: checkboxField.0 (individual checkbox errors)\n // and checkboxField._error (global field errors) - this flattens all\n // error values into a single array for rendering with FieldValidationError\n const errorFlat: FieldError[] =\n (_error &&\n Object.values(\n _error as unknown as Record<string, FieldError[]>,\n ).flat()) ||\n [];\n\n /**\n * Handles the checkbox group value changes based on the number of options:\n * 1. For single checkbox (options.length === 1):\n * - Converts undefined/empty array to [] for consistent controlled behavior\n * - Extracts single value from array for onChange\n *\n * Example: undefined → []\n * [value] → value\n *\n * 2. For multiple checkboxes:\n * - Uses raw value array with fallback to empty array\n * - Passes through onChange directly\n *\n * Example: undefined → []\n * ['value1', 'value2'] → ['value1', 'value2']\n */\n const getCheckboxValue = (inputValue: unknown): string[] => {\n if (Array.isArray(inputValue)) {\n return inputValue;\n }\n if (inputValue) {\n return [inputValue as string];\n }\n return [];\n };\n\n const singleCheckboxProps = {\n value: getCheckboxValue(value),\n onChange: (newValue: string[]) => {\n onChange(newValue?.[0]);\n },\n };\n\n const multipleCheckboxProps = {\n onChange,\n value: getCheckboxValue(value),\n };\n\n const checkboxGroupProps =\n options.length === 1 ? singleCheckboxProps : multipleCheckboxProps;\n\n return (\n <HeroCheckboxGroup\n classNames={heroCheckboxGroupClassNames}\n color={color === 'info' ? 'primary' : color}\n // see HeroUI styles for group-data condition (data-invalid),\n // e.g.: https://github.com/heroui-inc/heroui/blob/main/packages/components/select/src/use-select.ts\n data-invalid={invalid}\n data-testid={testId}\n isDisabled={disabled}\n isInvalid={invalid}\n isRequired={required}\n name={name}\n onBlur={onBlur}\n orientation={inline ? 'horizontal' : 'vertical'}\n errorMessage={\n errorFlat.length > 0 && (\n <FieldValidationError\n className={classNames.errorMessage}\n error={errorFlat}\n testId={testId}\n />\n )\n }\n label={\n showLabel && (\n // eslint-disable-next-line jsx-a11y/label-has-associated-control\n <label>\n {label}\n {showTestIdCopyButton && <FieldCopyTestIdButton testId={testId} />}\n </label>\n )\n }\n ref={ref}\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...checkboxGroupProps}\n >\n {options?.map((option) => {\n const optionTestId = slugify(\n `${testId}_option_${option?.testId || option?.value}`,\n { replaceDots: true },\n );\n\n // set content and classes depending option has subline\n const hasSubline = !!option.labelSubline;\n let labelContent: ReactNode;\n let optionClassNames = heroCheckboxClassNames;\n if (hasSubline) {\n labelContent = (\n <div className=\"flex grow flex-col items-start\">\n <span className={classNames.optionLabel}>{option.label}</span>\n <span className={classNames.optionLabelSubline}>\n {option.labelSubline}\n </span>\n </div>\n );\n // remove label classes from outer label when subline is used\n optionClassNames = { ...optionClassNames, label: '' };\n } else {\n labelContent = option.label;\n }\n\n return (\n <HeroCheckbox\n key={`index_${option.value}`}\n classNames={optionClassNames}\n data-invalid={invalid}\n data-testid={optionTestId}\n isDisabled={disabled || option.disabled}\n value={option?.value}\n aria-label={\n typeof option.label === 'string' ? option.label : option.value\n }\n >\n {labelContent}\n </HeroCheckbox>\n );\n })}\n </HeroCheckboxGroup>\n );\n};\n\nexport default CheckboxGroup;\n","import CheckboxGroup from './CheckboxGroup';\n\nexport type { CheckboxGroupProps, CheckboxGroupOption } from './CheckboxGroup';\n\nexport { CheckboxGroup };\n\nexport default CheckboxGroup;\n"]}