@uniform-ts/core 0.0.6 → 0.0.8
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 +20 -17
- package/dist/field-KKjnXn-d.d.mts +748 -0
- package/dist/field-KKjnXn-d.d.ts +748 -0
- package/dist/index.d.mts +53 -721
- package/dist/index.d.ts +53 -721
- package/dist/index.js +108 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +109 -51
- package/dist/index.mjs.map +1 -1
- package/dist/locales/en.d.mts +8 -0
- package/dist/locales/en.d.ts +8 -0
- package/dist/locales/en.js +24 -0
- package/dist/locales/en.js.map +1 -0
- package/dist/locales/en.mjs +22 -0
- package/dist/locales/en.mjs.map +1 -0
- package/dist/locales/es.d.mts +8 -0
- package/dist/locales/es.d.ts +8 -0
- package/dist/locales/es.js +24 -0
- package/dist/locales/es.js.map +1 -0
- package/dist/locales/es.mjs +22 -0
- package/dist/locales/es.mjs.map +1 -0
- package/dist/locales/he.d.mts +8 -0
- package/dist/locales/he.d.ts +8 -0
- package/dist/locales/he.js +24 -0
- package/dist/locales/he.js.map +1 -0
- package/dist/locales/he.mjs +22 -0
- package/dist/locales/he.mjs.map +1 -0
- package/package.json +20 -6
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as z from 'zod/v4/core';
|
|
2
2
|
import * as React3 from 'react';
|
|
3
3
|
import { useMemo, useRef, useEffect, useCallback, useState } from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { useWatch, useFormState, useForm, useFieldArray, Controller } from 'react-hook-form';
|
|
5
5
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
6
6
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
7
|
|
|
@@ -635,6 +635,24 @@ function SelectField({
|
|
|
635
635
|
}
|
|
636
636
|
);
|
|
637
637
|
}
|
|
638
|
+
function useConditionalFields(fields, control, scopeName) {
|
|
639
|
+
const allValues = useWatch({ control });
|
|
640
|
+
const scopedValues = useWatch({ control, name: scopeName });
|
|
641
|
+
const values = scopeName ? scopedValues : allValues;
|
|
642
|
+
return useMemo(() => {
|
|
643
|
+
return fields.filter((field) => {
|
|
644
|
+
if (field.meta.hidden) return false;
|
|
645
|
+
if (typeof field.meta.condition === "function") {
|
|
646
|
+
return field.meta.condition(values);
|
|
647
|
+
}
|
|
648
|
+
return true;
|
|
649
|
+
}).sort((a, b) => {
|
|
650
|
+
const orderA = typeof a.meta.order === "number" ? a.meta.order : Infinity;
|
|
651
|
+
const orderB = typeof b.meta.order === "number" ? b.meta.order : Infinity;
|
|
652
|
+
return orderA - orderB;
|
|
653
|
+
});
|
|
654
|
+
}, [fields, values]);
|
|
655
|
+
}
|
|
638
656
|
function ObjectField({
|
|
639
657
|
field,
|
|
640
658
|
control,
|
|
@@ -643,7 +661,7 @@ function ObjectField({
|
|
|
643
661
|
shouldUnregister
|
|
644
662
|
}) {
|
|
645
663
|
const { classNames, layout } = useAutoFormContext();
|
|
646
|
-
const children = field.children;
|
|
664
|
+
const children = useConditionalFields(field.children, control, namePrefix);
|
|
647
665
|
const content = children.map((child, idx) => /* @__PURE__ */ jsx(
|
|
648
666
|
FieldRenderer,
|
|
649
667
|
{
|
|
@@ -698,7 +716,7 @@ function getDefaultValue(field) {
|
|
|
698
716
|
return void 0;
|
|
699
717
|
}
|
|
700
718
|
}
|
|
701
|
-
function getRowSummary(row, itemConfig, index) {
|
|
719
|
+
function getRowSummary(row, itemConfig, index, itemSummary) {
|
|
702
720
|
if (itemConfig.type === "object") {
|
|
703
721
|
for (const child of itemConfig.children) {
|
|
704
722
|
const key = child.name.split(".").pop() ?? child.name;
|
|
@@ -708,7 +726,7 @@ function getRowSummary(row, itemConfig, index) {
|
|
|
708
726
|
}
|
|
709
727
|
}
|
|
710
728
|
}
|
|
711
|
-
return `Item ${index + 1}`;
|
|
729
|
+
return itemSummary?.(index) ?? `Item ${index + 1}`;
|
|
712
730
|
}
|
|
713
731
|
function ArrayField({ field, control, effectiveName }) {
|
|
714
732
|
const { classNames, layout, labels } = useAutoFormContext();
|
|
@@ -759,13 +777,13 @@ function ArrayField({ field, control, effectiveName }) {
|
|
|
759
777
|
const RowLayout = layout.arrayRowLayout;
|
|
760
778
|
const renderedRows = rows.map((row, index) => {
|
|
761
779
|
const isCollapsed = showCollapse && collapsed.has(index);
|
|
762
|
-
const collapseButton = showCollapse ? /* @__PURE__ */ jsxs(
|
|
780
|
+
const collapseButton = showCollapse && CollapseBtn ? /* @__PURE__ */ jsxs(
|
|
763
781
|
CollapseBtn,
|
|
764
782
|
{
|
|
765
783
|
type: "button",
|
|
766
784
|
className: classNames.arrayCollapse,
|
|
767
785
|
onClick: () => toggleCollapse(index),
|
|
768
|
-
"aria-label": isCollapsed ? `Expand item ${index + 1}` : `Collapse item ${index + 1}`,
|
|
786
|
+
"aria-label": isCollapsed ? labels.arrayAriaExpand?.(index) ?? `Expand item ${index + 1}` : labels.arrayAriaCollapse?.(index) ?? `Collapse item ${index + 1}`,
|
|
769
787
|
isCollapsed,
|
|
770
788
|
children: [
|
|
771
789
|
isCollapsed ? labels.arrayExpand ?? "\u25BC" : labels.arrayCollapse ?? "\u25B6",
|
|
@@ -783,29 +801,29 @@ function ArrayField({ field, control, effectiveName }) {
|
|
|
783
801
|
]
|
|
784
802
|
}
|
|
785
803
|
) : null;
|
|
786
|
-
const moveUpButton = showMove && rows.length > 1 ? /* @__PURE__ */ jsx(
|
|
804
|
+
const moveUpButton = showMove && rows.length > 1 && MoveUpBtn ? /* @__PURE__ */ jsx(
|
|
787
805
|
MoveUpBtn,
|
|
788
806
|
{
|
|
789
807
|
type: "button",
|
|
790
808
|
className: classNames.arrayMove,
|
|
791
809
|
onClick: () => move(index, index - 1),
|
|
792
810
|
disabled: index === 0,
|
|
793
|
-
"aria-label": `Move item ${index + 1} up`,
|
|
811
|
+
"aria-label": labels.arrayAriaMoveUp?.(index) ?? `Move item ${index + 1} up`,
|
|
794
812
|
children: labels.arrayMoveUp ?? "\u2191"
|
|
795
813
|
}
|
|
796
814
|
) : null;
|
|
797
|
-
const moveDownButton = showMove && rows.length > 1 ? /* @__PURE__ */ jsx(
|
|
815
|
+
const moveDownButton = showMove && rows.length > 1 && MoveDownBtn ? /* @__PURE__ */ jsx(
|
|
798
816
|
MoveDownBtn,
|
|
799
817
|
{
|
|
800
818
|
type: "button",
|
|
801
819
|
className: classNames.arrayMove,
|
|
802
820
|
onClick: () => move(index, index + 1),
|
|
803
821
|
disabled: index === rows.length - 1,
|
|
804
|
-
"aria-label": `Move item ${index + 1} down`,
|
|
822
|
+
"aria-label": labels.arrayAriaMoveDown?.(index) ?? `Move item ${index + 1} down`,
|
|
805
823
|
children: labels.arrayMoveDown ?? "\u2193"
|
|
806
824
|
}
|
|
807
825
|
) : null;
|
|
808
|
-
const duplicateButton = showDuplicate && !atMax ? /* @__PURE__ */ jsx(
|
|
826
|
+
const duplicateButton = showDuplicate && !atMax && DuplicateBtn ? /* @__PURE__ */ jsx(
|
|
809
827
|
DuplicateBtn,
|
|
810
828
|
{
|
|
811
829
|
type: "button",
|
|
@@ -816,21 +834,21 @@ function ArrayField({ field, control, effectiveName }) {
|
|
|
816
834
|
);
|
|
817
835
|
insert(index + 1, values);
|
|
818
836
|
},
|
|
819
|
-
"aria-label": `Duplicate item ${index + 1}`,
|
|
837
|
+
"aria-label": labels.arrayAriaDuplicate?.(index) ?? `Duplicate item ${index + 1}`,
|
|
820
838
|
children: labels.arrayDuplicate ?? "Duplicate"
|
|
821
839
|
}
|
|
822
840
|
) : null;
|
|
823
|
-
const removeButton = /* @__PURE__ */ jsx(
|
|
841
|
+
const removeButton = RemoveBtn ? /* @__PURE__ */ jsx(
|
|
824
842
|
RemoveBtn,
|
|
825
843
|
{
|
|
826
844
|
type: "button",
|
|
827
845
|
className: classNames.arrayRemove,
|
|
828
846
|
onClick: () => remove(index),
|
|
829
847
|
disabled: atMin,
|
|
830
|
-
"aria-label": `Remove item ${index + 1}`,
|
|
848
|
+
"aria-label": labels.arrayAriaRemove?.(index) ?? `Remove item ${index + 1}`,
|
|
831
849
|
children: labels.arrayRemove ?? "Remove"
|
|
832
850
|
}
|
|
833
|
-
);
|
|
851
|
+
) : null;
|
|
834
852
|
const fieldContent = !isCollapsed ? /* @__PURE__ */ jsx(
|
|
835
853
|
FieldRenderer,
|
|
836
854
|
{
|
|
@@ -856,7 +874,7 @@ function ArrayField({ field, control, effectiveName }) {
|
|
|
856
874
|
row.id
|
|
857
875
|
);
|
|
858
876
|
});
|
|
859
|
-
const addButton = /* @__PURE__ */ jsx(
|
|
877
|
+
const addButton = AddBtn ? /* @__PURE__ */ jsx(
|
|
860
878
|
AddBtn,
|
|
861
879
|
{
|
|
862
880
|
type: "button",
|
|
@@ -865,7 +883,7 @@ function ArrayField({ field, control, effectiveName }) {
|
|
|
865
883
|
onClick: () => append(getDefaultValue(itemConfig)),
|
|
866
884
|
children: labels.arrayAdd ?? "Add"
|
|
867
885
|
}
|
|
868
|
-
);
|
|
886
|
+
) : null;
|
|
869
887
|
const content = /* @__PURE__ */ jsx(
|
|
870
888
|
ArrayFieldLayout,
|
|
871
889
|
{
|
|
@@ -896,13 +914,22 @@ function CollapseSummary({
|
|
|
896
914
|
itemConfig,
|
|
897
915
|
isCollapsed
|
|
898
916
|
}) {
|
|
917
|
+
const { labels } = useAutoFormContext();
|
|
918
|
+
const fallback = labels.arrayItemSummary?.(index) ?? `Item ${index + 1}`;
|
|
899
919
|
const rowValues = useWatch({ control, name: `${effectiveName}.${index}` });
|
|
900
920
|
const summary = useMemo(() => {
|
|
901
|
-
if (!isCollapsed) return
|
|
902
|
-
if (!rowValues) return
|
|
903
|
-
return getRowSummary(rowValues, itemConfig, index);
|
|
904
|
-
}, [
|
|
905
|
-
|
|
921
|
+
if (!isCollapsed) return fallback;
|
|
922
|
+
if (!rowValues) return fallback;
|
|
923
|
+
return getRowSummary(rowValues, itemConfig, index, labels.arrayItemSummary);
|
|
924
|
+
}, [
|
|
925
|
+
isCollapsed,
|
|
926
|
+
rowValues,
|
|
927
|
+
itemConfig,
|
|
928
|
+
index,
|
|
929
|
+
fallback,
|
|
930
|
+
labels.arrayItemSummary
|
|
931
|
+
]);
|
|
932
|
+
return /* @__PURE__ */ jsx(Fragment, { children: isCollapsed ? summary : fallback });
|
|
906
933
|
}
|
|
907
934
|
function getEffectiveName(field, namePrefix) {
|
|
908
935
|
if (!namePrefix) return field.name;
|
|
@@ -1018,22 +1045,6 @@ function FieldRenderer({
|
|
|
1018
1045
|
}
|
|
1019
1046
|
);
|
|
1020
1047
|
}
|
|
1021
|
-
function useConditionalFields(fields, control) {
|
|
1022
|
-
const values = useWatch({ control });
|
|
1023
|
-
return useMemo(() => {
|
|
1024
|
-
return fields.filter((field) => {
|
|
1025
|
-
if (field.meta.hidden) return false;
|
|
1026
|
-
if (typeof field.meta.condition === "function") {
|
|
1027
|
-
return field.meta.condition(values);
|
|
1028
|
-
}
|
|
1029
|
-
return true;
|
|
1030
|
-
}).sort((a, b) => {
|
|
1031
|
-
const orderA = typeof a.meta.order === "number" ? a.meta.order : Infinity;
|
|
1032
|
-
const orderB = typeof b.meta.order === "number" ? b.meta.order : Infinity;
|
|
1033
|
-
return orderA - orderB;
|
|
1034
|
-
});
|
|
1035
|
-
}, [fields, values]);
|
|
1036
|
-
}
|
|
1037
1048
|
function useSectionGrouping(fields) {
|
|
1038
1049
|
return useMemo(() => {
|
|
1039
1050
|
const ungrouped = [];
|
|
@@ -1272,6 +1283,12 @@ function buildDefaults(fields) {
|
|
|
1272
1283
|
}
|
|
1273
1284
|
return result;
|
|
1274
1285
|
}
|
|
1286
|
+
|
|
1287
|
+
// src/utils/resolveNullableSlot.ts
|
|
1288
|
+
function resolveNullableSlot(slot, fallback) {
|
|
1289
|
+
if (slot === null) return null;
|
|
1290
|
+
return slot ?? fallback;
|
|
1291
|
+
}
|
|
1275
1292
|
function AutoForm(props) {
|
|
1276
1293
|
const {
|
|
1277
1294
|
form: uniForm,
|
|
@@ -1496,24 +1513,33 @@ function AutoForm(props) {
|
|
|
1496
1513
|
const visibleFields = useConditionalFields(fieldsWithDynamic, control);
|
|
1497
1514
|
const sections = useSectionGrouping(visibleFields);
|
|
1498
1515
|
const resolvedLayout = React3.useMemo(() => {
|
|
1499
|
-
const base =
|
|
1516
|
+
const base = resolveNullableSlot(
|
|
1517
|
+
layout?.arrayButtons?.base,
|
|
1518
|
+
DefaultArrayButton
|
|
1519
|
+
);
|
|
1500
1520
|
const slots = layout?.arrayButtons;
|
|
1501
1521
|
return {
|
|
1502
1522
|
formWrapper: layout?.formWrapper ?? DefaultFormWrapper,
|
|
1503
1523
|
sectionWrapper: layout?.sectionWrapper ?? DefaultSectionWrapper,
|
|
1504
|
-
submitButton:
|
|
1524
|
+
submitButton: resolveNullableSlot(
|
|
1525
|
+
layout?.submitButton,
|
|
1526
|
+
DefaultSubmitButton
|
|
1527
|
+
),
|
|
1505
1528
|
arrayRowLayout: layout?.arrayRowLayout ?? DefaultArrayRowLayout,
|
|
1506
1529
|
arrayFieldLayout: layout?.arrayFieldLayout ?? DefaultArrayFieldLayout,
|
|
1507
1530
|
objectWrapper: layout?.objectWrapper ?? DefaultObjectWrapper,
|
|
1508
1531
|
arrayWrapper: layout?.arrayWrapper ?? DefaultArrayWrapper,
|
|
1509
1532
|
arrayButtons: {
|
|
1510
1533
|
base,
|
|
1511
|
-
add: slots?.add
|
|
1512
|
-
remove: slots?.remove
|
|
1513
|
-
moveUp: slots?.moveUp
|
|
1514
|
-
moveDown: slots?.moveDown
|
|
1515
|
-
duplicate: slots?.duplicate
|
|
1516
|
-
collapse:
|
|
1534
|
+
add: resolveNullableSlot(slots?.add, base),
|
|
1535
|
+
remove: resolveNullableSlot(slots?.remove, base),
|
|
1536
|
+
moveUp: resolveNullableSlot(slots?.moveUp, base),
|
|
1537
|
+
moveDown: resolveNullableSlot(slots?.moveDown, base),
|
|
1538
|
+
duplicate: resolveNullableSlot(slots?.duplicate, base),
|
|
1539
|
+
collapse: resolveNullableSlot(
|
|
1540
|
+
slots?.collapse,
|
|
1541
|
+
DefaultArrayCollapseButton
|
|
1542
|
+
)
|
|
1517
1543
|
},
|
|
1518
1544
|
loadingFallback: layout?.loadingFallback ?? /* @__PURE__ */ jsx("p", { children: "Loading\u2026" })
|
|
1519
1545
|
};
|
|
@@ -1535,6 +1561,7 @@ function AutoForm(props) {
|
|
|
1535
1561
|
const contextValue = React3.useMemo(
|
|
1536
1562
|
() => ({
|
|
1537
1563
|
registry,
|
|
1564
|
+
fieldConfigs: mergedFields,
|
|
1538
1565
|
fieldOverrides: fieldOverridesProp,
|
|
1539
1566
|
fieldWrapper: resolvedFieldWrapper,
|
|
1540
1567
|
layout: resolvedLayout,
|
|
@@ -1543,10 +1570,12 @@ function AutoForm(props) {
|
|
|
1543
1570
|
coercions,
|
|
1544
1571
|
messages,
|
|
1545
1572
|
labels,
|
|
1546
|
-
formMethods
|
|
1573
|
+
formMethods,
|
|
1574
|
+
control
|
|
1547
1575
|
}),
|
|
1548
1576
|
[
|
|
1549
1577
|
registry,
|
|
1578
|
+
mergedFields,
|
|
1550
1579
|
fieldOverridesProp,
|
|
1551
1580
|
resolvedFieldWrapper,
|
|
1552
1581
|
resolvedLayout,
|
|
@@ -1555,7 +1584,8 @@ function AutoForm(props) {
|
|
|
1555
1584
|
coercions,
|
|
1556
1585
|
messages,
|
|
1557
1586
|
labels,
|
|
1558
|
-
formMethods
|
|
1587
|
+
formMethods,
|
|
1588
|
+
control
|
|
1559
1589
|
]
|
|
1560
1590
|
);
|
|
1561
1591
|
if (isLoadingDefaults) {
|
|
@@ -1599,13 +1629,13 @@ function AutoForm(props) {
|
|
|
1599
1629
|
section.title
|
|
1600
1630
|
);
|
|
1601
1631
|
}),
|
|
1602
|
-
/* @__PURE__ */ jsx(
|
|
1632
|
+
SubmitButton ? /* @__PURE__ */ jsx(
|
|
1603
1633
|
SubmitButton,
|
|
1604
1634
|
{
|
|
1605
1635
|
isSubmitting: formState.isSubmitting,
|
|
1606
1636
|
label: labels.submit ?? "Submit"
|
|
1607
1637
|
}
|
|
1608
|
-
)
|
|
1638
|
+
) : null
|
|
1609
1639
|
] })
|
|
1610
1640
|
}
|
|
1611
1641
|
) });
|
|
@@ -1704,7 +1734,35 @@ var UniForm = class {
|
|
|
1704
1734
|
function createForm(schema) {
|
|
1705
1735
|
return new UniForm(schema);
|
|
1706
1736
|
}
|
|
1737
|
+
function findArrayConfig(fields, name) {
|
|
1738
|
+
for (const field of fields) {
|
|
1739
|
+
if (field.name === name) {
|
|
1740
|
+
return field.type === "array" ? field : void 0;
|
|
1741
|
+
}
|
|
1742
|
+
if (field.type === "object") {
|
|
1743
|
+
const found = findArrayConfig(field.children, name);
|
|
1744
|
+
if (found) return found;
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
return void 0;
|
|
1748
|
+
}
|
|
1749
|
+
function useArrayField(fieldName) {
|
|
1750
|
+
const { control, fieldConfigs } = useAutoFormContext();
|
|
1751
|
+
const result = useFieldArray({ control, name: fieldName });
|
|
1752
|
+
const rowCount = result.fields.length;
|
|
1753
|
+
const config = findArrayConfig(fieldConfigs, fieldName);
|
|
1754
|
+
const minItems = config?.minItems;
|
|
1755
|
+
const maxItems = config?.maxItems;
|
|
1756
|
+
const canAdd = maxItems == null || rowCount < maxItems;
|
|
1757
|
+
const atMin = minItems != null && rowCount <= minItems;
|
|
1758
|
+
return {
|
|
1759
|
+
...result,
|
|
1760
|
+
rowCount,
|
|
1761
|
+
canAdd,
|
|
1762
|
+
atMin
|
|
1763
|
+
};
|
|
1764
|
+
}
|
|
1707
1765
|
|
|
1708
|
-
export { AutoForm, DefaultArrayButton, DefaultArrayCollapseButton, DefaultArrayFieldLayout, DefaultArrayRowLayout, DefaultArrayWrapper, DefaultCheckbox, DefaultFieldWrapper, DefaultInput, DefaultObjectWrapper, DefaultSelect, DefaultSubmitButton, FieldRenderer, UniForm, coerceValue, createAutoForm, createForm, defaultCoercionMap, defaultRegistry, introspectObjectSchema, introspectSchema, mergeRegistries, useAutoFormContext, useConditionalFields, useFormPersistence, useSectionGrouping };
|
|
1766
|
+
export { AutoForm, DefaultArrayButton, DefaultArrayCollapseButton, DefaultArrayFieldLayout, DefaultArrayRowLayout, DefaultArrayWrapper, DefaultCheckbox, DefaultFieldWrapper, DefaultInput, DefaultObjectWrapper, DefaultSelect, DefaultSubmitButton, FieldRenderer, UniForm, coerceValue, createAutoForm, createForm, defaultCoercionMap, defaultRegistry, introspectObjectSchema, introspectSchema, mergeRegistries, useArrayField, useAutoFormContext, useConditionalFields, useFormPersistence, useSectionGrouping };
|
|
1709
1767
|
//# sourceMappingURL=index.mjs.map
|
|
1710
1768
|
//# sourceMappingURL=index.mjs.map
|