@juantroconisf/lib 11.4.0 → 11.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -137,8 +137,12 @@ If your schema contains arrays inside objects inside arrays (infinite depth), yo
137
137
 
138
138
  ```tsx
139
139
  // Schema: items[].form_response.input_values[].value
140
- <Input {...on.input("items", itemId, "form_response.input_values", inputId, "value")} label="Deep Value" />
140
+ <Input
141
+ {...on.input("items", itemId, "form_response.input_values", inputId, "value")}
142
+ label='Deep Value'
143
+ />
141
144
  ```
145
+
142
146
  The library dynamically traverses your state, mapping IDs securely to their array indices natively, regardless of depth.
143
147
 
144
148
  ---
@@ -154,15 +158,15 @@ Each `on.*` method returns a set of props that you spread directly onto a HeroUI
154
158
 
155
159
  All methods support **scalar/nested** paths, standard **array item** paths (composite `"array.field"` + `itemId`), and **variadic sequences** for N-level deep structures.
156
160
 
157
- | Method | HeroUI Component | Key props returned |
158
- | --------------------------------- | ------------------- | ----------------------------------------------- |
159
- | `on.input(...args)` | `Input`, `Textarea` | `value: string`, `onValueChange(string)` |
160
- | `on.numberInput(...args)` | `NumberInput` | `value: number`, `onValueChange(number)` |
161
- | `on.select(...args)` | `Select` | `selectedKeys`, `onSelectionChange` |
162
- | `on.autocomplete(...args)` | `Autocomplete` | `selectedKey`, `onSelectionChange` |
163
- | `on.checkbox(...args)` | `Checkbox` | `isSelected: boolean`, `onValueChange(boolean)` |
164
- | `on.switch(...args)` | `Switch` | `isSelected: boolean`, `onValueChange(boolean)` |
165
- | `on.radio(...args)` | `RadioGroup` | `value: string`, `onValueChange(string)` |
161
+ | Method | HeroUI Component | Key props returned |
162
+ | -------------------------- | ------------------- | ----------------------------------------------- |
163
+ | `on.input(...args)` | `Input`, `Textarea` | `value: string`, `onValueChange(string)` |
164
+ | `on.numberInput(...args)` | `NumberInput` | `value: number`, `onValueChange(number)` |
165
+ | `on.select(...args)` | `Select` | `selectedKeys`, `onSelectionChange` |
166
+ | `on.autocomplete(...args)` | `Autocomplete` | `selectedKey`, `onSelectionChange` |
167
+ | `on.checkbox(...args)` | `Checkbox` | `isSelected: boolean`, `onValueChange(boolean)` |
168
+ | `on.switch(...args)` | `Switch` | `isSelected: boolean`, `onValueChange(boolean)` |
169
+ | `on.radio(...args)` | `RadioGroup` | `value: string`, `onValueChange(string)` |
166
170
 
167
171
  > **Why separate methods?** Each HeroUI component has a different prop contract (e.g. `isSelected` vs `value`, `onSelectionChange` vs `onValueChange`). Separate methods give accurate intellisense for each component.
168
172
 
@@ -233,7 +237,7 @@ Extracted from `helpers` on the `useForm` return value. Items in object arrays a
233
237
  | Method | Description |
234
238
  | ------------------------------------------- | -------------------------------------------------- |
235
239
  | `addItem(path, item, index?)` | Adds an item to the end (or at `index`) |
236
- | `removeItemByIndexByIndex(path, index)` | Removes by index |
240
+ | `removeItemByIndex(path, index)` | Removes by index |
237
241
  | `removeById(path, id)` | Removes by item ID |
238
242
  | `updateByIndex(path, index, partial)` | Partially updates an item by index (shallow merge) |
239
243
  | `updateById(path, id, partial)` | Partially updates an item by ID (shallow merge) |
package/dist/index.d.mts CHANGED
@@ -225,7 +225,7 @@ interface HelpersFunc<O extends StateType> {
225
225
  /** Adds a new item to an array. */
226
226
  addItem: <K extends ArrayPaths<O>>(arrayKey: K, item: NestedFieldValue<O, K> extends (infer E)[] ? E : never, index?: number) => void;
227
227
  /** Removes an item from an array by its index. */
228
- removeItemByIndexByIndex: <K extends ArrayPaths<O>>(arrayKey: K, index: number) => void;
228
+ removeItemByIndex: <K extends ArrayPaths<O>>(arrayKey: K, index: number) => void;
229
229
  /** Removes an item from an array by its unique identifier. */
230
230
  removeById: <K extends ArrayPaths<O>>(arrayKey: K, itemId: string | number) => void;
231
231
  /** Updates an item in an array at the given index (supports partial updates). */
package/dist/index.d.ts CHANGED
@@ -225,7 +225,7 @@ interface HelpersFunc<O extends StateType> {
225
225
  /** Adds a new item to an array. */
226
226
  addItem: <K extends ArrayPaths<O>>(arrayKey: K, item: NestedFieldValue<O, K> extends (infer E)[] ? E : never, index?: number) => void;
227
227
  /** Removes an item from an array by its index. */
228
- removeItemByIndexByIndex: <K extends ArrayPaths<O>>(arrayKey: K, index: number) => void;
228
+ removeItemByIndex: <K extends ArrayPaths<O>>(arrayKey: K, index: number) => void;
229
229
  /** Removes an item from an array by its unique identifier. */
230
230
  removeById: <K extends ArrayPaths<O>>(arrayKey: K, itemId: string | number) => void;
231
231
  /** Updates an item in an array at the given index (supports partial updates). */
package/dist/index.js CHANGED
@@ -234,7 +234,7 @@ function useComponentLanguage() {
234
234
  }
235
235
 
236
236
  // src/hooks/useForm.utils.ts
237
- function resolveFieldData(args, state, getIndex, getNestedValue2) {
237
+ function resolveFieldData(args, state, getIndex, getNestedValue2, getRule, validationSchema) {
238
238
  const argCount = args.length;
239
239
  if (argCount === 1) {
240
240
  const id = args[0];
@@ -339,7 +339,15 @@ function resolveFieldData(args, state, getIndex, getNestedValue2) {
339
339
  (arg) => typeof arg === "string" ? arg.split(".") : [arg]
340
340
  );
341
341
  for (const part of parts) {
342
- if (Array.isArray(current)) {
342
+ let isArrayContext = Array.isArray(current);
343
+ if (!isArrayContext && getRule && validationSchema) {
344
+ const currentFieldPath = fieldPathParts.filter(Boolean).join(".");
345
+ const rule = getRule(currentFieldPath, validationSchema);
346
+ if (rule && rule.type === "array") {
347
+ isArrayContext = true;
348
+ }
349
+ }
350
+ if (isArrayContext) {
343
351
  let indexNum = getIndex(currentPath, part);
344
352
  if (indexNum === void 0 && typeof part === "number") {
345
353
  indexNum = part;
@@ -347,7 +355,7 @@ function resolveFieldData(args, state, getIndex, getNestedValue2) {
347
355
  if (indexNum === void 0) return null;
348
356
  compositeKeyParts.push(String(part));
349
357
  realPathParts.push(String(indexNum));
350
- current = current[indexNum];
358
+ current = current?.[indexNum];
351
359
  } else {
352
360
  compositeKeyParts.push(String(part));
353
361
  fieldPathParts.push(String(part));
@@ -711,7 +719,9 @@ function useForm(schema, {
711
719
  args,
712
720
  stateRef.current,
713
721
  getIndex,
714
- getNestedValue
722
+ getNestedValue,
723
+ getRule,
724
+ validationSchema
715
725
  );
716
726
  if (!data) return {};
717
727
  return {
@@ -725,7 +735,9 @@ function useForm(schema, {
725
735
  args,
726
736
  stateRef.current,
727
737
  getIndex,
728
- getNestedValue
738
+ getNestedValue,
739
+ getRule,
740
+ validationSchema
729
741
  );
730
742
  if (!data) return {};
731
743
  const isArray = Array.isArray(data.value);
@@ -743,7 +755,9 @@ function useForm(schema, {
743
755
  args,
744
756
  stateRef.current,
745
757
  getIndex,
746
- getNestedValue
758
+ getNestedValue,
759
+ getRule,
760
+ validationSchema
747
761
  );
748
762
  if (!data) return {};
749
763
  return {
@@ -760,7 +774,9 @@ function useForm(schema, {
760
774
  args,
761
775
  stateRef.current,
762
776
  getIndex,
763
- getNestedValue
777
+ getNestedValue,
778
+ getRule,
779
+ validationSchema
764
780
  );
765
781
  if (!data) return {};
766
782
  return {
@@ -774,7 +790,9 @@ function useForm(schema, {
774
790
  args,
775
791
  stateRef.current,
776
792
  getIndex,
777
- getNestedValue
793
+ getNestedValue,
794
+ getRule,
795
+ validationSchema
778
796
  );
779
797
  if (!data) return {};
780
798
  return {
@@ -788,7 +806,9 @@ function useForm(schema, {
788
806
  args,
789
807
  stateRef.current,
790
808
  getIndex,
791
- getNestedValue
809
+ getNestedValue,
810
+ getRule,
811
+ validationSchema
792
812
  );
793
813
  if (!data) return {};
794
814
  return {
@@ -802,7 +822,9 @@ function useForm(schema, {
802
822
  args,
803
823
  stateRef.current,
804
824
  getIndex,
805
- getNestedValue
825
+ getNestedValue,
826
+ getRule,
827
+ validationSchema
806
828
  );
807
829
  if (!data) return {};
808
830
  return {
@@ -812,7 +834,7 @@ function useForm(schema, {
812
834
  };
813
835
  }
814
836
  }),
815
- [createHandlers, getIndex, handleFieldChange]
837
+ [createHandlers, getIndex, handleFieldChange, getRule, validationSchema]
816
838
  );
817
839
  const helpers = (0, import_react2.useMemo)(
818
840
  () => ({
@@ -829,7 +851,7 @@ function useForm(schema, {
829
851
  });
830
852
  });
831
853
  },
832
- removeItemByIndexByIndex: (arrayKey, index) => {
854
+ removeItemByIndex: (arrayKey, index) => {
833
855
  const currentArr = getNestedValue(stateRef.current, arrayKey) || [];
834
856
  const item = currentArr[index];
835
857
  const idKey = arrayIdentifiers?.[arrayKey] || "id";
@@ -963,7 +985,7 @@ function useForm(schema, {
963
985
  );
964
986
  if (data) handleFieldChange(data, value);
965
987
  },
966
- [getIndex, handleFieldChange]
988
+ [getIndex, handleFieldChange, getRule, validationSchema]
967
989
  );
968
990
  const arrayItemChange = (0, import_react2.useCallback)(
969
991
  ({
@@ -979,7 +1001,7 @@ function useForm(schema, {
979
1001
  );
980
1002
  if (data) handleFieldChange(data, value);
981
1003
  },
982
- [getIndex, handleFieldChange]
1004
+ [getIndex, handleFieldChange, getRule, validationSchema]
983
1005
  );
984
1006
  const scalarOnSelectionChange = (0, import_react2.useCallback)(
985
1007
  (id, val) => {
@@ -1010,7 +1032,7 @@ function useForm(schema, {
1010
1032
  );
1011
1033
  if (data) handleFieldChange(data, fixed);
1012
1034
  },
1013
- [getIndex, handleFieldChange]
1035
+ [getIndex, handleFieldChange, getRule, validationSchema]
1014
1036
  );
1015
1037
  const onFormSubmit = (0, import_react2.useCallback)(
1016
1038
  (fn) => (e) => {
package/dist/index.mjs CHANGED
@@ -208,7 +208,7 @@ function useComponentLanguage() {
208
208
  }
209
209
 
210
210
  // src/hooks/useForm.utils.ts
211
- function resolveFieldData(args, state, getIndex, getNestedValue2) {
211
+ function resolveFieldData(args, state, getIndex, getNestedValue2, getRule, validationSchema) {
212
212
  const argCount = args.length;
213
213
  if (argCount === 1) {
214
214
  const id = args[0];
@@ -313,7 +313,15 @@ function resolveFieldData(args, state, getIndex, getNestedValue2) {
313
313
  (arg) => typeof arg === "string" ? arg.split(".") : [arg]
314
314
  );
315
315
  for (const part of parts) {
316
- if (Array.isArray(current)) {
316
+ let isArrayContext = Array.isArray(current);
317
+ if (!isArrayContext && getRule && validationSchema) {
318
+ const currentFieldPath = fieldPathParts.filter(Boolean).join(".");
319
+ const rule = getRule(currentFieldPath, validationSchema);
320
+ if (rule && rule.type === "array") {
321
+ isArrayContext = true;
322
+ }
323
+ }
324
+ if (isArrayContext) {
317
325
  let indexNum = getIndex(currentPath, part);
318
326
  if (indexNum === void 0 && typeof part === "number") {
319
327
  indexNum = part;
@@ -321,7 +329,7 @@ function resolveFieldData(args, state, getIndex, getNestedValue2) {
321
329
  if (indexNum === void 0) return null;
322
330
  compositeKeyParts.push(String(part));
323
331
  realPathParts.push(String(indexNum));
324
- current = current[indexNum];
332
+ current = current?.[indexNum];
325
333
  } else {
326
334
  compositeKeyParts.push(String(part));
327
335
  fieldPathParts.push(String(part));
@@ -685,7 +693,9 @@ function useForm(schema, {
685
693
  args,
686
694
  stateRef.current,
687
695
  getIndex,
688
- getNestedValue
696
+ getNestedValue,
697
+ getRule,
698
+ validationSchema
689
699
  );
690
700
  if (!data) return {};
691
701
  return {
@@ -699,7 +709,9 @@ function useForm(schema, {
699
709
  args,
700
710
  stateRef.current,
701
711
  getIndex,
702
- getNestedValue
712
+ getNestedValue,
713
+ getRule,
714
+ validationSchema
703
715
  );
704
716
  if (!data) return {};
705
717
  const isArray = Array.isArray(data.value);
@@ -717,7 +729,9 @@ function useForm(schema, {
717
729
  args,
718
730
  stateRef.current,
719
731
  getIndex,
720
- getNestedValue
732
+ getNestedValue,
733
+ getRule,
734
+ validationSchema
721
735
  );
722
736
  if (!data) return {};
723
737
  return {
@@ -734,7 +748,9 @@ function useForm(schema, {
734
748
  args,
735
749
  stateRef.current,
736
750
  getIndex,
737
- getNestedValue
751
+ getNestedValue,
752
+ getRule,
753
+ validationSchema
738
754
  );
739
755
  if (!data) return {};
740
756
  return {
@@ -748,7 +764,9 @@ function useForm(schema, {
748
764
  args,
749
765
  stateRef.current,
750
766
  getIndex,
751
- getNestedValue
767
+ getNestedValue,
768
+ getRule,
769
+ validationSchema
752
770
  );
753
771
  if (!data) return {};
754
772
  return {
@@ -762,7 +780,9 @@ function useForm(schema, {
762
780
  args,
763
781
  stateRef.current,
764
782
  getIndex,
765
- getNestedValue
783
+ getNestedValue,
784
+ getRule,
785
+ validationSchema
766
786
  );
767
787
  if (!data) return {};
768
788
  return {
@@ -776,7 +796,9 @@ function useForm(schema, {
776
796
  args,
777
797
  stateRef.current,
778
798
  getIndex,
779
- getNestedValue
799
+ getNestedValue,
800
+ getRule,
801
+ validationSchema
780
802
  );
781
803
  if (!data) return {};
782
804
  return {
@@ -786,7 +808,7 @@ function useForm(schema, {
786
808
  };
787
809
  }
788
810
  }),
789
- [createHandlers, getIndex, handleFieldChange]
811
+ [createHandlers, getIndex, handleFieldChange, getRule, validationSchema]
790
812
  );
791
813
  const helpers = useMemo(
792
814
  () => ({
@@ -803,7 +825,7 @@ function useForm(schema, {
803
825
  });
804
826
  });
805
827
  },
806
- removeItemByIndexByIndex: (arrayKey, index) => {
828
+ removeItemByIndex: (arrayKey, index) => {
807
829
  const currentArr = getNestedValue(stateRef.current, arrayKey) || [];
808
830
  const item = currentArr[index];
809
831
  const idKey = arrayIdentifiers?.[arrayKey] || "id";
@@ -937,7 +959,7 @@ function useForm(schema, {
937
959
  );
938
960
  if (data) handleFieldChange(data, value);
939
961
  },
940
- [getIndex, handleFieldChange]
962
+ [getIndex, handleFieldChange, getRule, validationSchema]
941
963
  );
942
964
  const arrayItemChange = useCallback(
943
965
  ({
@@ -953,7 +975,7 @@ function useForm(schema, {
953
975
  );
954
976
  if (data) handleFieldChange(data, value);
955
977
  },
956
- [getIndex, handleFieldChange]
978
+ [getIndex, handleFieldChange, getRule, validationSchema]
957
979
  );
958
980
  const scalarOnSelectionChange = useCallback(
959
981
  (id, val) => {
@@ -984,7 +1006,7 @@ function useForm(schema, {
984
1006
  );
985
1007
  if (data) handleFieldChange(data, fixed);
986
1008
  },
987
- [getIndex, handleFieldChange]
1009
+ [getIndex, handleFieldChange, getRule, validationSchema]
988
1010
  );
989
1011
  const onFormSubmit = useCallback(
990
1012
  (fn) => (e) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juantroconisf/lib",
3
- "version": "11.4.0",
3
+ "version": "11.6.0",
4
4
  "description": "A form validation library for HeroUI.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",