@fuf-stack/uniform 0.16.0 → 0.16.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
3
 
4
- var _chunkTJESSWIBcjs = require('../chunk-TJESSWIB.cjs');
4
+ var _chunkTA4JEORCcjs = require('../chunk-TA4JEORC.cjs');
5
5
  require('../chunk-JU5RT22Y.cjs');
6
6
  require('../chunk-OE5IW4ZG.cjs');
7
7
  require('../chunk-IUVEFLF3.cjs');
@@ -10,5 +10,5 @@ require('../chunk-4DAZAO6Y.cjs');
10
10
 
11
11
 
12
12
 
13
- exports.FieldArray = _chunkTJESSWIBcjs.FieldArray_default; exports.default = _chunkTJESSWIBcjs.FieldArray_default2;
13
+ exports.FieldArray = _chunkTA4JEORCcjs.FieldArray_default; exports.default = _chunkTA4JEORCcjs.FieldArray_default2;
14
14
  //# sourceMappingURL=index.cjs.map
@@ -1,5 +1,5 @@
1
- import { F as FieldArray } from '../FieldArray-AqM2XKIh.cjs';
2
- export { a as FieldArrayChildrenRenderFn, b as FieldArrayFeatures, c as FieldArrayProps } from '../FieldArray-AqM2XKIh.cjs';
1
+ import { F as FieldArray } from '../FieldArray-hqxjr18x.cjs';
2
+ export { a as FieldArrayChildrenRenderFn, b as FieldArrayFeatures, c as FieldArrayProps } from '../FieldArray-hqxjr18x.cjs';
3
3
  import 'react/jsx-runtime';
4
4
  import 'tailwind-variants/dist/config.js';
5
5
  import 'tailwind-variants';
@@ -1,5 +1,5 @@
1
- import { F as FieldArray } from '../FieldArray-AqM2XKIh.js';
2
- export { a as FieldArrayChildrenRenderFn, b as FieldArrayFeatures, c as FieldArrayProps } from '../FieldArray-AqM2XKIh.js';
1
+ import { F as FieldArray } from '../FieldArray-hqxjr18x.js';
2
+ export { a as FieldArrayChildrenRenderFn, b as FieldArrayFeatures, c as FieldArrayProps } from '../FieldArray-hqxjr18x.js';
3
3
  import 'react/jsx-runtime';
4
4
  import 'tailwind-variants/dist/config.js';
5
5
  import 'tailwind-variants';
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  FieldArray_default,
3
3
  FieldArray_default2
4
- } from "../chunk-IBQCNI5H.js";
4
+ } from "../chunk-P6SZXKR2.js";
5
5
  import "../chunk-2CRY7VDQ.js";
6
6
  import "../chunk-ASPOGQPS.js";
7
7
  import "../chunk-T4N6TMUL.js";
@@ -17,11 +17,17 @@ type FieldArrayElementMethods = {
17
17
 
18
18
  type VariantProps = TVProps<typeof fieldArrayVariants>;
19
19
  type ClassName = TVClassName<typeof fieldArrayVariants>;
20
+ /** provided all data and methods to render a field array element */
20
21
  type FieldArrayChildrenRenderFn = (args: {
22
+ /** index of the current element in the field array */
21
23
  index: number;
24
+ /** total length of the field array */
22
25
  length: number;
26
+ /** methods of the current element to change the field array */
23
27
  methods: FieldArrayElementMethods;
28
+ /** HTML data-testid attribute used in e2e tests of the current element */
24
29
  name: string;
30
+ /** field name of the current element */
25
31
  testId: string;
26
32
  }) => JSX.Element;
27
33
  interface FieldArrayFeatures {
@@ -42,8 +48,8 @@ interface FieldArrayProps extends FieldArrayFeatures, VariantProps {
42
48
  elementInitialValue?: unknown;
43
49
  /** label of the field array */
44
50
  label?: React.ReactNode;
45
- /** when true last element can not be deleted and will be shown even if empty */
46
- lastElementNotDeletable?: boolean;
51
+ /** when true (default false) last element can not be removed and will be shown even if field array is empty */
52
+ lastElementNotRemovable?: boolean;
47
53
  /** form field name */
48
54
  name: string;
49
55
  /** HTML data-testid attribute used in e2e tests */
@@ -56,7 +62,7 @@ declare const fieldArrayVariants: tailwind_variants.TVReturnType<{
56
62
  label?: tailwind_variants.ClassValue;
57
63
  list?: tailwind_variants.ClassValue;
58
64
  appendButton?: tailwind_variants.ClassValue;
59
- elementContent?: tailwind_variants.ClassValue;
65
+ elementWrapper?: tailwind_variants.ClassValue;
60
66
  insertAfterButton?: tailwind_variants.ClassValue;
61
67
  listItem?: tailwind_variants.ClassValue;
62
68
  removeButton?: tailwind_variants.ClassValue;
@@ -69,7 +75,7 @@ declare const fieldArrayVariants: tailwind_variants.TVReturnType<{
69
75
  label?: tailwind_variants.ClassValue;
70
76
  list?: tailwind_variants.ClassValue;
71
77
  appendButton?: tailwind_variants.ClassValue;
72
- elementContent?: tailwind_variants.ClassValue;
78
+ elementWrapper?: tailwind_variants.ClassValue;
73
79
  insertAfterButton?: tailwind_variants.ClassValue;
74
80
  listItem?: tailwind_variants.ClassValue;
75
81
  removeButton?: tailwind_variants.ClassValue;
@@ -78,7 +84,7 @@ declare const fieldArrayVariants: tailwind_variants.TVReturnType<{
78
84
  };
79
85
  } | {}, {
80
86
  appendButton: string;
81
- elementContent: string;
87
+ elementWrapper: string;
82
88
  insertAfterButton: string;
83
89
  label: string;
84
90
  list: string;
@@ -91,7 +97,7 @@ declare const fieldArrayVariants: tailwind_variants.TVReturnType<{
91
97
  label?: tailwind_variants.ClassValue;
92
98
  list?: tailwind_variants.ClassValue;
93
99
  appendButton?: tailwind_variants.ClassValue;
94
- elementContent?: tailwind_variants.ClassValue;
100
+ elementWrapper?: tailwind_variants.ClassValue;
95
101
  insertAfterButton?: tailwind_variants.ClassValue;
96
102
  listItem?: tailwind_variants.ClassValue;
97
103
  removeButton?: tailwind_variants.ClassValue;
@@ -104,7 +110,7 @@ declare const fieldArrayVariants: tailwind_variants.TVReturnType<{
104
110
  label?: tailwind_variants.ClassValue;
105
111
  list?: tailwind_variants.ClassValue;
106
112
  appendButton?: tailwind_variants.ClassValue;
107
- elementContent?: tailwind_variants.ClassValue;
113
+ elementWrapper?: tailwind_variants.ClassValue;
108
114
  insertAfterButton?: tailwind_variants.ClassValue;
109
115
  listItem?: tailwind_variants.ClassValue;
110
116
  removeButton?: tailwind_variants.ClassValue;
@@ -113,7 +119,7 @@ declare const fieldArrayVariants: tailwind_variants.TVReturnType<{
113
119
  };
114
120
  } | {}, {
115
121
  appendButton: string;
116
- elementContent: string;
122
+ elementWrapper: string;
117
123
  insertAfterButton: string;
118
124
  label: string;
119
125
  list: string;
@@ -122,7 +128,7 @@ declare const fieldArrayVariants: tailwind_variants.TVReturnType<{
122
128
  sortDragHandle: string;
123
129
  }, tailwind_variants.TVReturnType<unknown, {
124
130
  appendButton: string;
125
- elementContent: string;
131
+ elementWrapper: string;
126
132
  insertAfterButton: string;
127
133
  label: string;
128
134
  list: string;
@@ -135,7 +141,7 @@ declare const fieldArrayVariants: tailwind_variants.TVReturnType<{
135
141
  label?: tailwind_variants.ClassValue;
136
142
  list?: tailwind_variants.ClassValue;
137
143
  appendButton?: tailwind_variants.ClassValue;
138
- elementContent?: tailwind_variants.ClassValue;
144
+ elementWrapper?: tailwind_variants.ClassValue;
139
145
  insertAfterButton?: tailwind_variants.ClassValue;
140
146
  listItem?: tailwind_variants.ClassValue;
141
147
  removeButton?: tailwind_variants.ClassValue;
@@ -144,8 +150,8 @@ declare const fieldArrayVariants: tailwind_variants.TVReturnType<{
144
150
  };
145
151
  } | {}>, unknown, unknown, undefined>>;
146
152
  /**
147
- * FieldArray component using TODO
153
+ * FieldArray component based in [RHF useFieldArray](https://react-hook-form.com/docs/usefieldarray)
148
154
  */
149
- declare const FieldArray: ({ appendButtonText, children, className: _className, duplicate, elementInitialValue: _elementInitialValue, insertAfter, label: _label, lastElementNotDeletable, name, sortable, testId: _testId, }: FieldArrayProps) => react_jsx_runtime.JSX.Element;
155
+ declare const FieldArray: ({ appendButtonText, children, className: _className, duplicate, elementInitialValue: _elementInitialValue, insertAfter, label: _label, lastElementNotRemovable, name, sortable, testId: _testId, }: FieldArrayProps) => react_jsx_runtime.JSX.Element;
150
156
 
151
157
  export { FieldArray as F, type FieldArrayChildrenRenderFn as a, type FieldArrayFeatures as b, type FieldArrayProps as c };
@@ -17,11 +17,17 @@ type FieldArrayElementMethods = {
17
17
 
18
18
  type VariantProps = TVProps<typeof fieldArrayVariants>;
19
19
  type ClassName = TVClassName<typeof fieldArrayVariants>;
20
+ /** provided all data and methods to render a field array element */
20
21
  type FieldArrayChildrenRenderFn = (args: {
22
+ /** index of the current element in the field array */
21
23
  index: number;
24
+ /** total length of the field array */
22
25
  length: number;
26
+ /** methods of the current element to change the field array */
23
27
  methods: FieldArrayElementMethods;
28
+ /** HTML data-testid attribute used in e2e tests of the current element */
24
29
  name: string;
30
+ /** field name of the current element */
25
31
  testId: string;
26
32
  }) => JSX.Element;
27
33
  interface FieldArrayFeatures {
@@ -42,8 +48,8 @@ interface FieldArrayProps extends FieldArrayFeatures, VariantProps {
42
48
  elementInitialValue?: unknown;
43
49
  /** label of the field array */
44
50
  label?: React.ReactNode;
45
- /** when true last element can not be deleted and will be shown even if empty */
46
- lastElementNotDeletable?: boolean;
51
+ /** when true (default false) last element can not be removed and will be shown even if field array is empty */
52
+ lastElementNotRemovable?: boolean;
47
53
  /** form field name */
48
54
  name: string;
49
55
  /** HTML data-testid attribute used in e2e tests */
@@ -56,7 +62,7 @@ declare const fieldArrayVariants: tailwind_variants.TVReturnType<{
56
62
  label?: tailwind_variants.ClassValue;
57
63
  list?: tailwind_variants.ClassValue;
58
64
  appendButton?: tailwind_variants.ClassValue;
59
- elementContent?: tailwind_variants.ClassValue;
65
+ elementWrapper?: tailwind_variants.ClassValue;
60
66
  insertAfterButton?: tailwind_variants.ClassValue;
61
67
  listItem?: tailwind_variants.ClassValue;
62
68
  removeButton?: tailwind_variants.ClassValue;
@@ -69,7 +75,7 @@ declare const fieldArrayVariants: tailwind_variants.TVReturnType<{
69
75
  label?: tailwind_variants.ClassValue;
70
76
  list?: tailwind_variants.ClassValue;
71
77
  appendButton?: tailwind_variants.ClassValue;
72
- elementContent?: tailwind_variants.ClassValue;
78
+ elementWrapper?: tailwind_variants.ClassValue;
73
79
  insertAfterButton?: tailwind_variants.ClassValue;
74
80
  listItem?: tailwind_variants.ClassValue;
75
81
  removeButton?: tailwind_variants.ClassValue;
@@ -78,7 +84,7 @@ declare const fieldArrayVariants: tailwind_variants.TVReturnType<{
78
84
  };
79
85
  } | {}, {
80
86
  appendButton: string;
81
- elementContent: string;
87
+ elementWrapper: string;
82
88
  insertAfterButton: string;
83
89
  label: string;
84
90
  list: string;
@@ -91,7 +97,7 @@ declare const fieldArrayVariants: tailwind_variants.TVReturnType<{
91
97
  label?: tailwind_variants.ClassValue;
92
98
  list?: tailwind_variants.ClassValue;
93
99
  appendButton?: tailwind_variants.ClassValue;
94
- elementContent?: tailwind_variants.ClassValue;
100
+ elementWrapper?: tailwind_variants.ClassValue;
95
101
  insertAfterButton?: tailwind_variants.ClassValue;
96
102
  listItem?: tailwind_variants.ClassValue;
97
103
  removeButton?: tailwind_variants.ClassValue;
@@ -104,7 +110,7 @@ declare const fieldArrayVariants: tailwind_variants.TVReturnType<{
104
110
  label?: tailwind_variants.ClassValue;
105
111
  list?: tailwind_variants.ClassValue;
106
112
  appendButton?: tailwind_variants.ClassValue;
107
- elementContent?: tailwind_variants.ClassValue;
113
+ elementWrapper?: tailwind_variants.ClassValue;
108
114
  insertAfterButton?: tailwind_variants.ClassValue;
109
115
  listItem?: tailwind_variants.ClassValue;
110
116
  removeButton?: tailwind_variants.ClassValue;
@@ -113,7 +119,7 @@ declare const fieldArrayVariants: tailwind_variants.TVReturnType<{
113
119
  };
114
120
  } | {}, {
115
121
  appendButton: string;
116
- elementContent: string;
122
+ elementWrapper: string;
117
123
  insertAfterButton: string;
118
124
  label: string;
119
125
  list: string;
@@ -122,7 +128,7 @@ declare const fieldArrayVariants: tailwind_variants.TVReturnType<{
122
128
  sortDragHandle: string;
123
129
  }, tailwind_variants.TVReturnType<unknown, {
124
130
  appendButton: string;
125
- elementContent: string;
131
+ elementWrapper: string;
126
132
  insertAfterButton: string;
127
133
  label: string;
128
134
  list: string;
@@ -135,7 +141,7 @@ declare const fieldArrayVariants: tailwind_variants.TVReturnType<{
135
141
  label?: tailwind_variants.ClassValue;
136
142
  list?: tailwind_variants.ClassValue;
137
143
  appendButton?: tailwind_variants.ClassValue;
138
- elementContent?: tailwind_variants.ClassValue;
144
+ elementWrapper?: tailwind_variants.ClassValue;
139
145
  insertAfterButton?: tailwind_variants.ClassValue;
140
146
  listItem?: tailwind_variants.ClassValue;
141
147
  removeButton?: tailwind_variants.ClassValue;
@@ -144,8 +150,8 @@ declare const fieldArrayVariants: tailwind_variants.TVReturnType<{
144
150
  };
145
151
  } | {}>, unknown, unknown, undefined>>;
146
152
  /**
147
- * FieldArray component using TODO
153
+ * FieldArray component based in [RHF useFieldArray](https://react-hook-form.com/docs/usefieldarray)
148
154
  */
149
- declare const FieldArray: ({ appendButtonText, children, className: _className, duplicate, elementInitialValue: _elementInitialValue, insertAfter, label: _label, lastElementNotDeletable, name, sortable, testId: _testId, }: FieldArrayProps) => react_jsx_runtime.JSX.Element;
155
+ declare const FieldArray: ({ appendButtonText, children, className: _className, duplicate, elementInitialValue: _elementInitialValue, insertAfter, label: _label, lastElementNotRemovable, name, sortable, testId: _testId, }: FieldArrayProps) => react_jsx_runtime.JSX.Element;
150
156
 
151
157
  export { FieldArray as F, type FieldArrayChildrenRenderFn as a, type FieldArrayFeatures as b, type FieldArrayProps as c };
@@ -102,6 +102,7 @@ var SortDragHandle_default = SortDragHandle;
102
102
  // src/FieldArray/subcomponents/FieldArrayElement.tsx
103
103
  import { Fragment, jsx as jsx4, jsxs } from "react/jsx-runtime";
104
104
  var FieldArrayElement = ({
105
+ arrayFieldName,
105
106
  children,
106
107
  className,
107
108
  fields,
@@ -110,13 +111,12 @@ var FieldArrayElement = ({
110
111
  insertAfter = false,
111
112
  lastNotDeletable = true,
112
113
  methods,
113
- name,
114
114
  sortable = false,
115
115
  testId = void 0
116
116
  }) => {
117
117
  var _a;
118
118
  const { getFieldState } = useFormContext();
119
- const { error, invalid } = getFieldState(`${name}`, void 0);
119
+ const { error, invalid } = getFieldState(arrayFieldName, void 0);
120
120
  const { getHelperWrapperProps, getErrorMessageProps } = useInput({
121
121
  classNames: { helperWrapper: "block" },
122
122
  errorMessage: JSON.stringify(error),
@@ -145,7 +145,14 @@ var FieldArrayElement = ({
145
145
  testId: `${testId}_sort_drag_handle`
146
146
  }
147
147
  ),
148
- /* @__PURE__ */ jsx4("div", { className: cn4(className.elementContent), "data-testid": testId, children }),
148
+ /* @__PURE__ */ jsx4(
149
+ "div",
150
+ {
151
+ className: cn4(className.elementWrapper),
152
+ "data-testid": `${testId}_element_wrapper`,
153
+ children
154
+ }
155
+ ),
149
156
  lastNotDeletable && fields.length === 1 ? null : /* @__PURE__ */ jsx4(
150
157
  ElementRemoveButton_default,
151
158
  {
@@ -239,7 +246,7 @@ import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs2 } from "react/jsx-run
239
246
  var fieldArrayVariants = tv({
240
247
  slots: {
241
248
  appendButton: "w-full",
242
- elementContent: "flex-grow",
249
+ elementWrapper: "flex-grow",
243
250
  insertAfterButton: "text-xs font-medium",
244
251
  label: "!pointer-events-auto !static !z-0 -mb-1 ml-1 !inline-block",
245
252
  list: "m-0 w-full list-none",
@@ -256,7 +263,7 @@ var FieldArray = ({
256
263
  elementInitialValue: _elementInitialValue = null,
257
264
  insertAfter = false,
258
265
  label: _label = void 0,
259
- lastElementNotDeletable = true,
266
+ lastElementNotRemovable = false,
260
267
  name,
261
268
  sortable = false,
262
269
  testId: _testId = void 0
@@ -287,7 +294,7 @@ var FieldArray = ({
287
294
  classNames: { helperWrapper: "block" }
288
295
  });
289
296
  const elementInitialValue = toNullishString(_elementInitialValue);
290
- if (lastElementNotDeletable && fields.length === 0) {
297
+ if (lastElementNotRemovable && fields.length === 0) {
291
298
  append(elementInitialValue);
292
299
  }
293
300
  const showTestIdCopyButton = debugMode === "debug-testids";
@@ -311,7 +318,9 @@ var FieldArray = ({
311
318
  showTestIdCopyButton && /* @__PURE__ */ jsx6(FieldCopyTestIdButton_default, { testId })
312
319
  ] }),
313
320
  fields.map((field, index) => {
314
- const methods = {
321
+ const elementName = `${name}.${index}`;
322
+ const elementTestId = `${testId}${index}`;
323
+ const elementMethods = {
315
324
  append: () => append(elementInitialValue),
316
325
  duplicate: () => {
317
326
  const values = getValues(name);
@@ -323,23 +332,23 @@ var FieldArray = ({
323
332
  return /* @__PURE__ */ jsx6(
324
333
  FieldArrayElement_default,
325
334
  {
335
+ arrayFieldName: name,
326
336
  className,
327
337
  fields,
328
338
  id: field.id,
329
339
  index,
330
340
  duplicate,
331
341
  insertAfter,
332
- lastNotDeletable: lastElementNotDeletable,
333
- methods,
334
- name,
342
+ lastNotDeletable: lastElementNotRemovable,
343
+ methods: elementMethods,
335
344
  sortable,
336
- testId: `${testId}_${index}`,
345
+ testId: elementTestId,
337
346
  children: children({
338
347
  index,
339
348
  length: fields.length,
340
- methods,
341
- name: `${name}.${index}`,
342
- testId: `${testId}_${index}`
349
+ methods: elementMethods,
350
+ name: elementName,
351
+ testId: elementTestId
343
352
  })
344
353
  },
345
354
  field.id
@@ -369,4 +378,4 @@ export {
369
378
  FieldArray_default,
370
379
  FieldArray_default2
371
380
  };
372
- //# sourceMappingURL=chunk-IBQCNI5H.js.map
381
+ //# sourceMappingURL=chunk-P6SZXKR2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../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"],"sourcesContent":["/* eslint-disable react/jsx-props-no-spreading */\n\nimport 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: 'flex-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 items-center',\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 sortable={sortable} move={move} fields={fields}>\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={() => trigger(`${name}`)}\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 )}\n {showTestIdCopyButton && <FieldCopyTestIdButton testId={testId} />}\n </>\n )}\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: () => append(elementInitialValue),\n duplicate: () => {\n const values = getValues(name);\n insert(index + 1, values[index]);\n },\n insert: () => insert(index + 1, elementInitialValue),\n remove: () => remove(index),\n };\n\n return (\n <FieldArrayElement\n arrayFieldName={name}\n className={className}\n fields={fields}\n id={field.id}\n index={index}\n duplicate={duplicate}\n insertAfter={insertAfter}\n key={field.id}\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 className={className.appendButton}\n onClick={() => append(elementInitialValue)}\n size=\"sm\"\n testId={`${testId}_append_button`}\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} />\n </div>\n </div>\n )}\n </ul>\n </SortContext>\n );\n};\n\nexport default FieldArray;\n","/* eslint-disable react/jsx-props-no-spreading */\n\nimport 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 { useFormContext, useInput } from '../../hooks';\nimport { FieldValidationError } from '../../partials/FieldValidationError';\nimport ElementInsertAfterButton from './ElementInsertAfterButton';\nimport ElementRemoveButton from './ElementRemoveButton';\nimport SortDragHandle from './SortDragHandle';\n\nexport type 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 className={cn(className.listItem)}\n ref={setNodeRef}\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 )}\n\n {/** render element fields */}\n <div\n className={cn(className.elementWrapper)}\n data-testid={`${testId}_element_wrapper`}\n >\n {children}\n </div>\n\n {/** remove element */}\n {lastNotDeletable && fields.length === 1 ? null : (\n <ElementRemoveButton\n className={className.removeButton}\n onClick={() => methods.remove()}\n testId={`${testId}_remove_button`}\n />\n )}\n\n {/** insertAfter feature when not last element */}\n {insertAfter && index !== fields.length - 1 && (\n <ElementInsertAfterButton\n className={className.insertAfterButton}\n onClick={() => methods.insert()}\n testId={`${testId}_insert_after_button`}\n />\n )}\n </li>\n\n {/** element error */}\n {error && 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 />\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 // eslint-disable-next-line react/jsx-props-no-spreading\n {...attributes}\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...listeners}\n >\n <FaGripVertical />\n </div>\n );\n};\n\nexport default SortDragHandle;\n","/* eslint-disable react/jsx-props-no-spreading */\n\nimport 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) => {\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) => field.id === active.id);\n const newIndex = fields.findIndex((field) => field.id === over?.id);\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 items={fields.map((field) => field.id)}\n strategy={verticalListSortingStrategy}\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"],"mappings":"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","names":["cn","Button","useSortable","cn","cn","Button","jsx","cn","jsx","cn","jsx","useSortable","cn","jsx","Fragment","jsx","jsxs","cn","Button","FieldArray_default"]}
@@ -102,6 +102,7 @@ var SortDragHandle_default = SortDragHandle;
102
102
  // src/FieldArray/subcomponents/FieldArrayElement.tsx
103
103
 
104
104
  var FieldArrayElement = ({
105
+ arrayFieldName,
105
106
  children,
106
107
  className,
107
108
  fields,
@@ -110,13 +111,12 @@ var FieldArrayElement = ({
110
111
  insertAfter = false,
111
112
  lastNotDeletable = true,
112
113
  methods,
113
- name,
114
114
  sortable = false,
115
115
  testId = void 0
116
116
  }) => {
117
117
  var _a;
118
118
  const { getFieldState } = _chunkIUVEFLF3cjs.useFormContext.call(void 0, );
119
- const { error, invalid } = getFieldState(`${name}`, void 0);
119
+ const { error, invalid } = getFieldState(arrayFieldName, void 0);
120
120
  const { getHelperWrapperProps, getErrorMessageProps } = _chunkIUVEFLF3cjs.useInput.call(void 0, {
121
121
  classNames: { helperWrapper: "block" },
122
122
  errorMessage: JSON.stringify(error),
@@ -145,7 +145,14 @@ var FieldArrayElement = ({
145
145
  testId: `${testId}_sort_drag_handle`
146
146
  }
147
147
  ),
148
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _pixelutils.cn.call(void 0, className.elementContent), "data-testid": testId, children }),
148
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
149
+ "div",
150
+ {
151
+ className: _pixelutils.cn.call(void 0, className.elementWrapper),
152
+ "data-testid": `${testId}_element_wrapper`,
153
+ children
154
+ }
155
+ ),
149
156
  lastNotDeletable && fields.length === 1 ? null : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
150
157
  ElementRemoveButton_default,
151
158
  {
@@ -239,7 +246,7 @@ var SortContext_default = SortContext;
239
246
  var fieldArrayVariants = _pixelutils.tv.call(void 0, {
240
247
  slots: {
241
248
  appendButton: "w-full",
242
- elementContent: "flex-grow",
249
+ elementWrapper: "flex-grow",
243
250
  insertAfterButton: "text-xs font-medium",
244
251
  label: "!pointer-events-auto !static !z-0 -mb-1 ml-1 !inline-block",
245
252
  list: "m-0 w-full list-none",
@@ -256,7 +263,7 @@ var FieldArray = ({
256
263
  elementInitialValue: _elementInitialValue = null,
257
264
  insertAfter = false,
258
265
  label: _label = void 0,
259
- lastElementNotDeletable = true,
266
+ lastElementNotRemovable = false,
260
267
  name,
261
268
  sortable = false,
262
269
  testId: _testId = void 0
@@ -287,7 +294,7 @@ var FieldArray = ({
287
294
  classNames: { helperWrapper: "block" }
288
295
  });
289
296
  const elementInitialValue = _chunkCESGUF6Fcjs.toNullishString.call(void 0, _elementInitialValue);
290
- if (lastElementNotDeletable && fields.length === 0) {
297
+ if (lastElementNotRemovable && fields.length === 0) {
291
298
  append(elementInitialValue);
292
299
  }
293
300
  const showTestIdCopyButton = debugMode === "debug-testids";
@@ -311,7 +318,9 @@ var FieldArray = ({
311
318
  showTestIdCopyButton && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJU5RT22Ycjs.FieldCopyTestIdButton_default, { testId })
312
319
  ] }),
313
320
  fields.map((field, index) => {
314
- const methods = {
321
+ const elementName = `${name}.${index}`;
322
+ const elementTestId = `${testId}${index}`;
323
+ const elementMethods = {
315
324
  append: () => append(elementInitialValue),
316
325
  duplicate: () => {
317
326
  const values = getValues(name);
@@ -323,23 +332,23 @@ var FieldArray = ({
323
332
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
324
333
  FieldArrayElement_default,
325
334
  {
335
+ arrayFieldName: name,
326
336
  className,
327
337
  fields,
328
338
  id: field.id,
329
339
  index,
330
340
  duplicate,
331
341
  insertAfter,
332
- lastNotDeletable: lastElementNotDeletable,
333
- methods,
334
- name,
342
+ lastNotDeletable: lastElementNotRemovable,
343
+ methods: elementMethods,
335
344
  sortable,
336
- testId: `${testId}_${index}`,
345
+ testId: elementTestId,
337
346
  children: children({
338
347
  index,
339
348
  length: fields.length,
340
- methods,
341
- name: `${name}.${index}`,
342
- testId: `${testId}_${index}`
349
+ methods: elementMethods,
350
+ name: elementName,
351
+ testId: elementTestId
343
352
  })
344
353
  },
345
354
  field.id
@@ -369,4 +378,4 @@ var FieldArray_default2 = FieldArray_default;
369
378
 
370
379
 
371
380
  exports.FieldArray_default = FieldArray_default; exports.FieldArray_default2 = FieldArray_default2;
372
- //# sourceMappingURL=chunk-TJESSWIB.cjs.map
381
+ //# sourceMappingURL=chunk-TA4JEORC.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/pixels/pixels/packages/uniform/dist/chunk-TA4JEORC.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":"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","file":"/home/runner/work/pixels/pixels/packages/uniform/dist/chunk-TA4JEORC.cjs","sourcesContent":[null,"/* eslint-disable react/jsx-props-no-spreading */\n\nimport 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: 'flex-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 items-center',\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 sortable={sortable} move={move} fields={fields}>\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={() => trigger(`${name}`)}\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 )}\n {showTestIdCopyButton && <FieldCopyTestIdButton testId={testId} />}\n </>\n )}\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: () => append(elementInitialValue),\n duplicate: () => {\n const values = getValues(name);\n insert(index + 1, values[index]);\n },\n insert: () => insert(index + 1, elementInitialValue),\n remove: () => remove(index),\n };\n\n return (\n <FieldArrayElement\n arrayFieldName={name}\n className={className}\n fields={fields}\n id={field.id}\n index={index}\n duplicate={duplicate}\n insertAfter={insertAfter}\n key={field.id}\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 className={className.appendButton}\n onClick={() => append(elementInitialValue)}\n size=\"sm\"\n testId={`${testId}_append_button`}\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} />\n </div>\n </div>\n )}\n </ul>\n </SortContext>\n );\n};\n\nexport default FieldArray;\n","/* eslint-disable react/jsx-props-no-spreading */\n\nimport 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 { useFormContext, useInput } from '../../hooks';\nimport { FieldValidationError } from '../../partials/FieldValidationError';\nimport ElementInsertAfterButton from './ElementInsertAfterButton';\nimport ElementRemoveButton from './ElementRemoveButton';\nimport SortDragHandle from './SortDragHandle';\n\nexport type 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 className={cn(className.listItem)}\n ref={setNodeRef}\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 )}\n\n {/** render element fields */}\n <div\n className={cn(className.elementWrapper)}\n data-testid={`${testId}_element_wrapper`}\n >\n {children}\n </div>\n\n {/** remove element */}\n {lastNotDeletable && fields.length === 1 ? null : (\n <ElementRemoveButton\n className={className.removeButton}\n onClick={() => methods.remove()}\n testId={`${testId}_remove_button`}\n />\n )}\n\n {/** insertAfter feature when not last element */}\n {insertAfter && index !== fields.length - 1 && (\n <ElementInsertAfterButton\n className={className.insertAfterButton}\n onClick={() => methods.insert()}\n testId={`${testId}_insert_after_button`}\n />\n )}\n </li>\n\n {/** element error */}\n {error && 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 />\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 // eslint-disable-next-line react/jsx-props-no-spreading\n {...attributes}\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...listeners}\n >\n <FaGripVertical />\n </div>\n );\n};\n\nexport default SortDragHandle;\n","/* eslint-disable react/jsx-props-no-spreading */\n\nimport 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) => {\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) => field.id === active.id);\n const newIndex = fields.findIndex((field) => field.id === over?.id);\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 items={fields.map((field) => field.id)}\n strategy={verticalListSortingStrategy}\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"]}
package/dist/index.cjs CHANGED
@@ -15,12 +15,15 @@ var _chunkKIAIGPG7cjs = require('./chunk-KIAIGPG7.cjs');
15
15
  var _chunkBDVAK232cjs = require('./chunk-BDVAK232.cjs');
16
16
 
17
17
 
18
- var _chunkTJESSWIBcjs = require('./chunk-TJESSWIB.cjs');
18
+ var _chunkTA4JEORCcjs = require('./chunk-TA4JEORC.cjs');
19
19
 
20
20
 
21
21
  var _chunkQ23XGBJ5cjs = require('./chunk-Q23XGBJ5.cjs');
22
22
 
23
23
 
24
+ var _chunk6GN255GPcjs = require('./chunk-6GN255GP.cjs');
25
+
26
+
24
27
  var _chunkY7MJBI4Acjs = require('./chunk-Y7MJBI4A.cjs');
25
28
 
26
29
 
@@ -46,9 +49,6 @@ var _chunkIUVEFLF3cjs = require('./chunk-IUVEFLF3.cjs');
46
49
 
47
50
 
48
51
  var _chunkCESGUF6Fcjs = require('./chunk-CESGUF6F.cjs');
49
-
50
-
51
- var _chunk6GN255GPcjs = require('./chunk-6GN255GP.cjs');
52
52
  require('./chunk-4DAZAO6Y.cjs');
53
53
 
54
54
 
@@ -72,5 +72,5 @@ require('./chunk-4DAZAO6Y.cjs');
72
72
 
73
73
 
74
74
 
75
- exports.CheckboxGroup = _chunkBDVAK232cjs.CheckboxGroup_default; exports.Controller = _chunkPHGFXKPUcjs.Controller_default; exports.FieldArray = _chunkTJESSWIBcjs.FieldArray_default; exports.FieldCopyTestIdButton = _chunkJU5RT22Ycjs.FieldCopyTestIdButton_default; exports.FieldValidationError = _chunkOE5IW4ZGcjs.FieldValidationError_default; exports.Form = _chunkQ23XGBJ5cjs.Form_default; exports.Grid = _chunk6GN255GPcjs.Grid_default; exports.Input = _chunkY7MJBI4Acjs.Input_default; exports.RadioGroup = _chunkWRIXKFKWcjs.RadioGroup_default; exports.Select = _chunkHCQJGNWTcjs.Select_default; exports.SubmitButton = _chunkH65I56SIcjs.SubmitButton_default; exports.Switch = _chunk7ROOJK7Gcjs.Switch_default; exports.TextArea = _chunkKIAIGPG7cjs.TextArea_default; exports.checkFieldIsRequired = _chunkIUVEFLF3cjs.checkFieldIsRequired; exports.fromNullishString = _chunkCESGUF6Fcjs.fromNullishString; exports.toFormFormat = _chunkCESGUF6Fcjs.toFormFormat; exports.toNullishString = _chunkCESGUF6Fcjs.toNullishString; exports.toValidationFormat = _chunkCESGUF6Fcjs.toValidationFormat; exports.useFieldArray = _chunkIUVEFLF3cjs.useFieldArray; exports.useFormContext = _chunkIUVEFLF3cjs.useFormContext; exports.useInput = _chunkIUVEFLF3cjs.useInput;
75
+ exports.CheckboxGroup = _chunkBDVAK232cjs.CheckboxGroup_default; exports.Controller = _chunkPHGFXKPUcjs.Controller_default; exports.FieldArray = _chunkTA4JEORCcjs.FieldArray_default; exports.FieldCopyTestIdButton = _chunkJU5RT22Ycjs.FieldCopyTestIdButton_default; exports.FieldValidationError = _chunkOE5IW4ZGcjs.FieldValidationError_default; exports.Form = _chunkQ23XGBJ5cjs.Form_default; exports.Grid = _chunk6GN255GPcjs.Grid_default; exports.Input = _chunkY7MJBI4Acjs.Input_default; exports.RadioGroup = _chunkWRIXKFKWcjs.RadioGroup_default; exports.Select = _chunkHCQJGNWTcjs.Select_default; exports.SubmitButton = _chunkH65I56SIcjs.SubmitButton_default; exports.Switch = _chunk7ROOJK7Gcjs.Switch_default; exports.TextArea = _chunkKIAIGPG7cjs.TextArea_default; exports.checkFieldIsRequired = _chunkIUVEFLF3cjs.checkFieldIsRequired; exports.fromNullishString = _chunkCESGUF6Fcjs.fromNullishString; exports.toFormFormat = _chunkCESGUF6Fcjs.toFormFormat; exports.toNullishString = _chunkCESGUF6Fcjs.toNullishString; exports.toValidationFormat = _chunkCESGUF6Fcjs.toValidationFormat; exports.useFieldArray = _chunkIUVEFLF3cjs.useFieldArray; exports.useFormContext = _chunkIUVEFLF3cjs.useFormContext; exports.useInput = _chunkIUVEFLF3cjs.useInput;
76
76
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/pixels/pixels/packages/uniform/dist/index.cjs"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B,gCAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,8tCAAC","file":"/home/runner/work/pixels/pixels/packages/uniform/dist/index.cjs"}
1
+ {"version":3,"sources":["/home/runner/work/pixels/pixels/packages/uniform/dist/index.cjs"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACF,wDAA6B;AAC7B,gCAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,8tCAAC","file":"/home/runner/work/pixels/pixels/packages/uniform/dist/index.cjs"}
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { C as Controller, a as ControllerProps } from './Controller-8Nqugui5.cjs';
2
2
  export { C as CheckboxGroup, b as CheckboxGroupOption, a as CheckboxGroupProps } from './CheckboxGroup-fAdey3Td.cjs';
3
- export { F as FieldArray, a as FieldArrayChildrenRenderFn, b as FieldArrayFeatures, c as FieldArrayProps } from './FieldArray-AqM2XKIh.cjs';
3
+ export { F as FieldArray, a as FieldArrayChildrenRenderFn, b as FieldArrayFeatures, c as FieldArrayProps } from './FieldArray-hqxjr18x.cjs';
4
4
  export { F as Form, a as FormProps } from './Form-D0grgL6G.cjs';
5
5
  export { G as Grid, a as GridProps } from './Grid-DF3L9NF3.cjs';
6
6
  export { fromNullishString, toFormFormat, toNullishString, toValidationFormat } from './helpers/index.cjs';
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { C as Controller, a as ControllerProps } from './Controller-8Nqugui5.js';
2
2
  export { C as CheckboxGroup, b as CheckboxGroupOption, a as CheckboxGroupProps } from './CheckboxGroup-fAdey3Td.js';
3
- export { F as FieldArray, a as FieldArrayChildrenRenderFn, b as FieldArrayFeatures, c as FieldArrayProps } from './FieldArray-AqM2XKIh.js';
3
+ export { F as FieldArray, a as FieldArrayChildrenRenderFn, b as FieldArrayFeatures, c as FieldArrayProps } from './FieldArray-hqxjr18x.js';
4
4
  export { F as Form, a as FormProps } from './Form-DX5NTR-H.js';
5
5
  export { G as Grid, a as GridProps } from './Grid-DF3L9NF3.js';
6
6
  export { fromNullishString, toFormFormat, toNullishString, toValidationFormat } from './helpers/index.js';
package/dist/index.js CHANGED
@@ -15,10 +15,13 @@ import {
15
15
  } from "./chunk-WKJN5A2E.js";
16
16
  import {
17
17
  FieldArray_default
18
- } from "./chunk-IBQCNI5H.js";
18
+ } from "./chunk-P6SZXKR2.js";
19
19
  import {
20
20
  Form_default
21
21
  } from "./chunk-DS7GUNDT.js";
22
+ import {
23
+ Grid_default
24
+ } from "./chunk-PDCEKC3G.js";
22
25
  import {
23
26
  Input_default
24
27
  } from "./chunk-MEK7YR46.js";
@@ -46,9 +49,6 @@ import {
46
49
  toNullishString,
47
50
  toValidationFormat
48
51
  } from "./chunk-UAV6PVB4.js";
49
- import {
50
- Grid_default
51
- } from "./chunk-PDCEKC3G.js";
52
52
  import "./chunk-CRTRMMJ7.js";
53
53
  export {
54
54
  CheckboxGroup_default as CheckboxGroup,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fuf-stack/uniform",
3
- "version": "0.16.0",
3
+ "version": "0.16.2",
4
4
  "description": "fuf react form library",
5
5
  "author": "Hannes Tiede",
6
6
  "homepage": "https://github.com/fuf-stack/pixels#readme",
@@ -129,8 +129,8 @@
129
129
  "react-hook-form": "7.54.2",
130
130
  "react-select": "5.10.0",
131
131
  "@fuf-stack/pixel-utils": "0.5.0",
132
- "@fuf-stack/pixels": "0.32.4",
133
- "@fuf-stack/veto": "0.9.4"
132
+ "@fuf-stack/veto": "0.9.4",
133
+ "@fuf-stack/pixels": "0.32.4"
134
134
  },
135
135
  "devDependencies": {
136
136
  "@types/debug": "4.1.12",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../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"],"sourcesContent":["/* eslint-disable react/jsx-props-no-spreading */\n\nimport 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 elementContent: 'flex-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 items-center',\n removeButton: 'ml-1',\n sortDragHandle: 'mr-2 text-base text-xl',\n },\n});\n\n/**\n * FieldArray component using TODO\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 lastElementNotDeletable = true,\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 if (lastElementNotDeletable && fields.length === 0) {\n append(elementInitialValue);\n }\n\n const showTestIdCopyButton = debugMode === 'debug-testids';\n const showLabel = label || showTestIdCopyButton;\n\n return (\n <SortContext sortable={sortable} move={move} fields={fields}>\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={() => trigger(`${name}`)}\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 )}\n {showTestIdCopyButton && <FieldCopyTestIdButton testId={testId} />}\n </>\n )}\n\n {fields.map((field, index) => {\n // create methods for element\n const methods: FieldArrayElementMethods = {\n append: () => append(elementInitialValue),\n duplicate: () => {\n const values = getValues(name);\n insert(index + 1, values[index]);\n },\n insert: () => insert(index + 1, elementInitialValue),\n remove: () => remove(index),\n };\n\n return (\n <FieldArrayElement\n className={className}\n fields={fields}\n id={field.id}\n index={index}\n duplicate={duplicate}\n insertAfter={insertAfter}\n key={field.id}\n lastNotDeletable={lastElementNotDeletable}\n methods={methods}\n name={name}\n sortable={sortable}\n testId={`${testId}_${index}`}\n >\n {children({\n index,\n length: fields.length,\n methods,\n name: `${name}.${index}`,\n testId: `${testId}_${index}`,\n })}\n </FieldArrayElement>\n );\n })}\n\n {/* append elements */}\n <Button\n className={className.appendButton}\n onClick={() => append(elementInitialValue)}\n size=\"sm\"\n testId={`${testId}_append_button`}\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} />\n </div>\n </div>\n )}\n </ul>\n </SortContext>\n );\n};\n\nexport default FieldArray;\n","/* eslint-disable react/jsx-props-no-spreading */\n\nimport 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 { useFormContext, useInput } from '../../hooks';\nimport { FieldValidationError } from '../../partials/FieldValidationError';\nimport ElementInsertAfterButton from './ElementInsertAfterButton';\nimport ElementRemoveButton from './ElementRemoveButton';\nimport SortDragHandle from './SortDragHandle';\n\nexport type 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 /** Form elements to render inside array element */\n children: React.ReactNode;\n /** CSS class names for component parts */\n className: {\n /** Class of the content of the li */\n elementContent?: 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 /** Base field name for form context */\n name: string;\n /** HTML data-testid attribute used in e2e tests */\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 children,\n className,\n fields,\n id,\n index,\n insertAfter = false,\n lastNotDeletable = true,\n methods,\n name,\n sortable = false,\n testId = undefined,\n}: FieldArrayElementProps) => {\n const { getFieldState } = useFormContext();\n const { error, invalid } = getFieldState(`${name}`, 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 className={cn(className.listItem)}\n ref={setNodeRef}\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 )}\n\n {/** render element fields */}\n <div className={cn(className.elementContent)} data-testid={testId}>\n {children}\n </div>\n\n {/** remove element */}\n {lastNotDeletable && fields.length === 1 ? null : (\n <ElementRemoveButton\n className={className.removeButton}\n onClick={() => methods.remove()}\n testId={`${testId}_remove_button`}\n />\n )}\n\n {/** insertAfter feature when not last element */}\n {insertAfter && index !== fields.length - 1 && (\n <ElementInsertAfterButton\n className={className.insertAfterButton}\n onClick={() => methods.insert()}\n testId={`${testId}_insert_after_button`}\n />\n )}\n </li>\n\n {/** element error */}\n {error && 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 />\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 // eslint-disable-next-line react/jsx-props-no-spreading\n {...attributes}\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...listeners}\n >\n <FaGripVertical />\n </div>\n );\n};\n\nexport default SortDragHandle;\n","/* eslint-disable react/jsx-props-no-spreading */\n\nimport 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) => {\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) => field.id === active.id);\n const newIndex = fields.findIndex((field) => field.id === over?.id);\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 items={fields.map((field) => field.id)}\n strategy={verticalListSortingStrategy}\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"],"mappings":"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","names":["cn","Button","useSortable","cn","cn","Button","jsx","cn","jsx","cn","jsx","useSortable","cn","jsx","Fragment","jsx","jsxs","cn","Button","FieldArray_default"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/work/pixels/pixels/packages/uniform/dist/chunk-TJESSWIB.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","Fragment"],"mappings":"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","file":"/home/runner/work/pixels/pixels/packages/uniform/dist/chunk-TJESSWIB.cjs","sourcesContent":[null,"/* eslint-disable react/jsx-props-no-spreading */\n\nimport 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 elementContent: 'flex-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 items-center',\n removeButton: 'ml-1',\n sortDragHandle: 'mr-2 text-base text-xl',\n },\n});\n\n/**\n * FieldArray component using TODO\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 lastElementNotDeletable = true,\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 if (lastElementNotDeletable && fields.length === 0) {\n append(elementInitialValue);\n }\n\n const showTestIdCopyButton = debugMode === 'debug-testids';\n const showLabel = label || showTestIdCopyButton;\n\n return (\n <SortContext sortable={sortable} move={move} fields={fields}>\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={() => trigger(`${name}`)}\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 )}\n {showTestIdCopyButton && <FieldCopyTestIdButton testId={testId} />}\n </>\n )}\n\n {fields.map((field, index) => {\n // create methods for element\n const methods: FieldArrayElementMethods = {\n append: () => append(elementInitialValue),\n duplicate: () => {\n const values = getValues(name);\n insert(index + 1, values[index]);\n },\n insert: () => insert(index + 1, elementInitialValue),\n remove: () => remove(index),\n };\n\n return (\n <FieldArrayElement\n className={className}\n fields={fields}\n id={field.id}\n index={index}\n duplicate={duplicate}\n insertAfter={insertAfter}\n key={field.id}\n lastNotDeletable={lastElementNotDeletable}\n methods={methods}\n name={name}\n sortable={sortable}\n testId={`${testId}_${index}`}\n >\n {children({\n index,\n length: fields.length,\n methods,\n name: `${name}.${index}`,\n testId: `${testId}_${index}`,\n })}\n </FieldArrayElement>\n );\n })}\n\n {/* append elements */}\n <Button\n className={className.appendButton}\n onClick={() => append(elementInitialValue)}\n size=\"sm\"\n testId={`${testId}_append_button`}\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} />\n </div>\n </div>\n )}\n </ul>\n </SortContext>\n );\n};\n\nexport default FieldArray;\n","/* eslint-disable react/jsx-props-no-spreading */\n\nimport 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 { useFormContext, useInput } from '../../hooks';\nimport { FieldValidationError } from '../../partials/FieldValidationError';\nimport ElementInsertAfterButton from './ElementInsertAfterButton';\nimport ElementRemoveButton from './ElementRemoveButton';\nimport SortDragHandle from './SortDragHandle';\n\nexport type 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 /** Form elements to render inside array element */\n children: React.ReactNode;\n /** CSS class names for component parts */\n className: {\n /** Class of the content of the li */\n elementContent?: 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 /** Base field name for form context */\n name: string;\n /** HTML data-testid attribute used in e2e tests */\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 children,\n className,\n fields,\n id,\n index,\n insertAfter = false,\n lastNotDeletable = true,\n methods,\n name,\n sortable = false,\n testId = undefined,\n}: FieldArrayElementProps) => {\n const { getFieldState } = useFormContext();\n const { error, invalid } = getFieldState(`${name}`, 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 className={cn(className.listItem)}\n ref={setNodeRef}\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 )}\n\n {/** render element fields */}\n <div className={cn(className.elementContent)} data-testid={testId}>\n {children}\n </div>\n\n {/** remove element */}\n {lastNotDeletable && fields.length === 1 ? null : (\n <ElementRemoveButton\n className={className.removeButton}\n onClick={() => methods.remove()}\n testId={`${testId}_remove_button`}\n />\n )}\n\n {/** insertAfter feature when not last element */}\n {insertAfter && index !== fields.length - 1 && (\n <ElementInsertAfterButton\n className={className.insertAfterButton}\n onClick={() => methods.insert()}\n testId={`${testId}_insert_after_button`}\n />\n )}\n </li>\n\n {/** element error */}\n {error && 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 />\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 // eslint-disable-next-line react/jsx-props-no-spreading\n {...attributes}\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...listeners}\n >\n <FaGripVertical />\n </div>\n );\n};\n\nexport default SortDragHandle;\n","/* eslint-disable react/jsx-props-no-spreading */\n\nimport 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) => {\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) => field.id === active.id);\n const newIndex = fields.findIndex((field) => field.id === over?.id);\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 items={fields.map((field) => field.id)}\n strategy={verticalListSortingStrategy}\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"]}