{"version":3,"file":"useFieldArray.mjs","names":[],"sources":["../../../../../../../react-form/src/hooks/useFieldArray.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { FieldArrayHelpers, FieldArrayItem } from \"../types\";\nimport { useForm } from \"./useForm\";\n\n/**\n * Manage a dynamic list of repeated field rows (add / remove / reorder) with\n * **stable keys** that survive reordering and removal.\n *\n * Rows are keyed by a stable `key`; each row's input names derive from its\n * current `index` (`addresses.0.city`, `addresses.1.city`, …), so the form's\n * dot-notation collection nests them into an array automatically. Because rows\n * keep their identity, a surviving row carries its own value when others are\n * removed or moved.\n *\n * ```tsx\n * const { fields, append, remove } = useFieldArray(\"addresses\");\n *\n * {fields.map((field) => (\n *   <div key={field.key}>\n *     <TextInput name={`${field.name}.city`} />\n *     <button type=\"button\" onClick={() => remove(field.index)}>Remove</button>\n *   </div>\n * ))}\n * <button type=\"button\" onClick={() => append()}>Add address</button>\n * ```\n */\nexport function useFieldArray(name: string): FieldArrayHelpers {\n  const form = useForm();\n\n  const keyCounter = useRef(0);\n\n  const makeKey = () => `${name}-${keyCounter.current++}`;\n\n  const makeKeys = (count: number) =>\n    Array.from({ length: Math.max(0, count) }, () => makeKey());\n\n  const [keys, setKeys] = useState<string[]>(() => {\n    const initial = form?.getInitialValue(name);\n    const length = Array.isArray(initial) ? initial.length : 0;\n    return makeKeys(length);\n  });\n\n  // Snapshot of the initial row count, restored on form reset.\n  const initialLength = useRef(keys.length);\n\n  useEffect(() => {\n    if (!form) return;\n\n    // Grow rows to match data that arrives after mount (reactive `values` /\n    // `form.fill()`), so async edit forms render every loaded row. Never\n    // shrinks — explicit removal is the user's call.\n    const changeEvent = form.on(\"change\", () => {\n      const hydrated = form.getInitialValue(name);\n      const length = Array.isArray(hydrated) ? hydrated.length : 0;\n\n      setKeys((current) =>\n        length > current.length\n          ? [...current, ...makeKeys(length - current.length)]\n          : current\n      );\n    });\n\n    const resetEvent = form.on(\"reset\", () => {\n      setKeys(makeKeys(initialLength.current));\n    });\n\n    return () => {\n      changeEvent.unsubscribe();\n      resetEvent.unsubscribe();\n    };\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [form]);\n\n  const fields: FieldArrayItem[] = keys.map((key, index) => ({\n    key,\n    index,\n    name: `${name}.${index}`,\n  }));\n\n  const append = (count = 1) =>\n    setKeys((current) => [...current, ...makeKeys(count)]);\n\n  const prepend = (count = 1) =>\n    setKeys((current) => [...makeKeys(count), ...current]);\n\n  const remove = (index?: number) =>\n    setKeys((current) => {\n      if (index === undefined) return current.slice(0, -1);\n      const next = [...current];\n      next.splice(index, 1);\n      return next;\n    });\n\n  const insert = (index: number) =>\n    setKeys((current) => {\n      const next = [...current];\n      next.splice(index, 0, makeKey());\n      return next;\n    });\n\n  const move = (from: number, to: number) =>\n    setKeys((current) => {\n      const next = [...current];\n      const [moved] = next.splice(from, 1);\n      next.splice(to, 0, moved);\n      return next;\n    });\n\n  const swap = (a: number, b: number) =>\n    setKeys((current) => {\n      const next = [...current];\n      [next[a], next[b]] = [next[b], next[a]];\n      return next;\n    });\n\n  const replace = (count: number) => setKeys(makeKeys(count));\n\n  return { fields, append, prepend, remove, insert, move, swap, replace };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,SAAgB,cAAc,MAAiC;CAC7D,MAAM,OAAO,QAAQ;CAErB,MAAM,aAAa,OAAO,CAAC;CAE3B,MAAM,gBAAgB,GAAG,KAAK,GAAG,WAAW;CAE5C,MAAM,YAAY,UAChB,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,KAAK,EAAE,SAAS,QAAQ,CAAC;CAE5D,MAAM,CAAC,MAAM,WAAW,eAAyB;EAC/C,MAAM,UAAU,MAAM,gBAAgB,IAAI;EAE1C,OAAO,SADQ,MAAM,QAAQ,OAAO,IAAI,QAAQ,SAAS,CACnC;CACxB,CAAC;CAGD,MAAM,gBAAgB,OAAO,KAAK,MAAM;CAExC,gBAAgB;EACd,IAAI,CAAC,MAAM;EAKX,MAAM,cAAc,KAAK,GAAG,gBAAgB;GAC1C,MAAM,WAAW,KAAK,gBAAgB,IAAI;GAC1C,MAAM,SAAS,MAAM,QAAQ,QAAQ,IAAI,SAAS,SAAS;GAE3D,SAAS,YACP,SAAS,QAAQ,SACb,CAAC,GAAG,SAAS,GAAG,SAAS,SAAS,QAAQ,MAAM,CAAC,IACjD,OACN;EACF,CAAC;EAED,MAAM,aAAa,KAAK,GAAG,eAAe;GACxC,QAAQ,SAAS,cAAc,OAAO,CAAC;EACzC,CAAC;EAED,aAAa;GACX,YAAY,YAAY;GACxB,WAAW,YAAY;EACzB;CAEF,GAAG,CAAC,IAAI,CAAC;CAET,MAAM,SAA2B,KAAK,KAAK,KAAK,WAAW;EACzD;EACA;EACA,MAAM,GAAG,KAAK,GAAG;CACnB,EAAE;CAEF,MAAM,UAAU,QAAQ,MACtB,SAAS,YAAY,CAAC,GAAG,SAAS,GAAG,SAAS,KAAK,CAAC,CAAC;CAEvD,MAAM,WAAW,QAAQ,MACvB,SAAS,YAAY,CAAC,GAAG,SAAS,KAAK,GAAG,GAAG,OAAO,CAAC;CAEvD,MAAM,UAAU,UACd,SAAS,YAAY;EACnB,IAAI,UAAU,QAAW,OAAO,QAAQ,MAAM,GAAG,EAAE;EACnD,MAAM,OAAO,CAAC,GAAG,OAAO;EACxB,KAAK,OAAO,OAAO,CAAC;EACpB,OAAO;CACT,CAAC;CAEH,MAAM,UAAU,UACd,SAAS,YAAY;EACnB,MAAM,OAAO,CAAC,GAAG,OAAO;EACxB,KAAK,OAAO,OAAO,GAAG,QAAQ,CAAC;EAC/B,OAAO;CACT,CAAC;CAEH,MAAM,QAAQ,MAAc,OAC1B,SAAS,YAAY;EACnB,MAAM,OAAO,CAAC,GAAG,OAAO;EACxB,MAAM,CAAC,SAAS,KAAK,OAAO,MAAM,CAAC;EACnC,KAAK,OAAO,IAAI,GAAG,KAAK;EACxB,OAAO;CACT,CAAC;CAEH,MAAM,QAAQ,GAAW,MACvB,SAAS,YAAY;EACnB,MAAM,OAAO,CAAC,GAAG,OAAO;EACxB,CAAC,KAAK,IAAI,KAAK,MAAM,CAAC,KAAK,IAAI,KAAK,EAAE;EACtC,OAAO;CACT,CAAC;CAEH,MAAM,WAAW,UAAkB,QAAQ,SAAS,KAAK,CAAC;CAE1D,OAAO;EAAE;EAAQ;EAAQ;EAAS;EAAQ;EAAQ;EAAM;EAAM;CAAQ;AACxE"}