@dragonmastery/zinia-forms-core 0.5.6 → 0.5.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/dist/index.d.ts +29 -18
- package/dist/index.js +33 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -278,13 +278,13 @@ interface SelectOption<TData = Record<string, any>> {
|
|
|
278
278
|
*/
|
|
279
279
|
type ZodEnumValues<T extends z.ZodEnum<[string, ...string[]]>> = T['_def']['values'][number];
|
|
280
280
|
/**
|
|
281
|
-
* Type for a mapping of enum values to labels
|
|
281
|
+
* Type for a mapping of enum values to labels (values and labels can be string or number)
|
|
282
282
|
*/
|
|
283
|
-
type EnumValueToLabelMap<T extends string> = Record<T, string>;
|
|
283
|
+
type EnumValueToLabelMap<T extends string | number = string | number> = Record<T, string | number>;
|
|
284
284
|
/**
|
|
285
285
|
* Type for a value-to-label mapping that can be either a function or an object map
|
|
286
286
|
*/
|
|
287
|
-
type ValueToLabelMapping<T extends string = string> = ((value:
|
|
287
|
+
type ValueToLabelMapping<T extends string | number = string | number> = ((value: T) => string | number) | EnumValueToLabelMap<T>;
|
|
288
288
|
/**
|
|
289
289
|
* Helper type to extract the type of a field at a given path
|
|
290
290
|
*/
|
|
@@ -671,7 +671,7 @@ type ArrayFieldComponent<T, P extends Path<T>> = vue.FunctionalComponent<Omit<Ar
|
|
|
671
671
|
* Type for enum field components that require valueToLabel
|
|
672
672
|
*/
|
|
673
673
|
type EnumFieldComponent<T, P extends Path<T>> = (props: Omit<SelectFieldProps<T>, 'name' | 'valueToLabel'> & {
|
|
674
|
-
valueToLabel: Record<FieldPathToEnum<T, P>, string>;
|
|
674
|
+
valueToLabel: Record<FieldPathToEnum<T, P>, string | number>;
|
|
675
675
|
}, context?: any) => any;
|
|
676
676
|
/**
|
|
677
677
|
* Type for combobox field components (searchable select with optional creation)
|
|
@@ -753,9 +753,9 @@ interface FieldMetadata$1 {
|
|
|
753
753
|
max?: number;
|
|
754
754
|
/** Regular expression pattern for validation */
|
|
755
755
|
pattern?: RegExp;
|
|
756
|
-
/** Options for enum fields */
|
|
756
|
+
/** Options for enum fields (value can be string or number when valueType is 'number') */
|
|
757
757
|
options?: Array<{
|
|
758
|
-
value: string;
|
|
758
|
+
value: string | number;
|
|
759
759
|
label: string;
|
|
760
760
|
}>;
|
|
761
761
|
/** Default value for the field */
|
|
@@ -774,8 +774,13 @@ interface FieldMetadata$1 {
|
|
|
774
774
|
rows?: number;
|
|
775
775
|
/** For textarea fields, number of columns to display */
|
|
776
776
|
cols?: number;
|
|
777
|
-
/** For enum fields, map values to display labels */
|
|
778
|
-
valueToLabel?: Record<string, string>;
|
|
777
|
+
/** For enum fields, map values to display labels (keys and values can be string or number) */
|
|
778
|
+
valueToLabel?: Record<string | number, string | number>;
|
|
779
|
+
/**
|
|
780
|
+
* Coerce select/combobox values to this type when setting form state.
|
|
781
|
+
* Use 'number' when valueToLabel has numeric keys - stores numbers instead of strings.
|
|
782
|
+
*/
|
|
783
|
+
valueType?: 'number';
|
|
779
784
|
/** Whether the field should be disabled */
|
|
780
785
|
disabled?: boolean;
|
|
781
786
|
/** Whether the field should be hidden */
|
|
@@ -854,7 +859,7 @@ declare function createTypedComboboxField<T, P extends Path<T>>(baseComboboxFiel
|
|
|
854
859
|
* @returns A factory function that creates a type-safe select field
|
|
855
860
|
*/
|
|
856
861
|
declare function createTypedSelectField<T, P extends Path<T>>(baseSelectField: FunctionalComponent<SelectFieldProps<T>>, fieldPath: P): <E extends FieldPathToEnum<T, P> = FieldPathToEnum<T, P>>(props: Omit<SelectFieldProps<T>, "name" | "valueToLabel"> & {
|
|
857
|
-
valueToLabel: Record<E, string>;
|
|
862
|
+
valueToLabel: Record<E, string | number>;
|
|
858
863
|
}, context?: any) => any;
|
|
859
864
|
/**
|
|
860
865
|
* Type-safe select field component with valueToLabel based on field path
|
|
@@ -862,7 +867,7 @@ declare function createTypedSelectField<T, P extends Path<T>>(baseSelectField: F
|
|
|
862
867
|
interface TypedSelectFieldComponent<T> {
|
|
863
868
|
<P extends Path<T>>(props: Omit<SelectFieldProps<T>, 'valueToLabel'> & {
|
|
864
869
|
name: P;
|
|
865
|
-
valueToLabel?: Record<string, string>;
|
|
870
|
+
valueToLabel?: Record<string | number, string | number>;
|
|
866
871
|
}): ReturnType<FunctionalComponent>;
|
|
867
872
|
}
|
|
868
873
|
|
|
@@ -880,7 +885,7 @@ type DisplayFieldComponent<T, P extends Path<T>, _FieldType extends string = 'st
|
|
|
880
885
|
size?: string;
|
|
881
886
|
variant?: string;
|
|
882
887
|
copyable?: boolean;
|
|
883
|
-
valueToLabel?: Record<string, string>;
|
|
888
|
+
valueToLabel?: Record<string | number, string | number>;
|
|
884
889
|
separator?: string;
|
|
885
890
|
itemRenderer?: (item: any, index: number) => string;
|
|
886
891
|
maxItems?: number;
|
|
@@ -996,10 +1001,10 @@ declare function generateFieldComponents<T extends z.ZodObject<any>>(schema: T,
|
|
|
996
1001
|
default: () => any;
|
|
997
1002
|
}, {}>;
|
|
998
1003
|
createTypedSelectField: <P extends Path<z.TypeOf<T>>>(fieldPath: P) => <E extends FieldPathToEnum<z.TypeOf<T>, P> = FieldPathToEnum<z.TypeOf<T>, P>>(props: Omit<SelectFieldProps<z.TypeOf<T>, Path<z.TypeOf<T>>, any>, "name" | "valueToLabel"> & {
|
|
999
|
-
valueToLabel: Record<E, string>;
|
|
1004
|
+
valueToLabel: Record<E, string | number>;
|
|
1000
1005
|
}, context?: any) => any;
|
|
1001
1006
|
typedSelectFields: { [K in Path<z.TypeOf<T>>]?: (<E extends FieldPathToEnum<z.TypeOf<T>, K> = FieldPathToEnum<z.TypeOf<T>, K>>(props: Omit<SelectFieldProps<z.TypeOf<T>, Path<z.TypeOf<T>>, any>, "name" | "valueToLabel"> & {
|
|
1002
|
-
valueToLabel: Record<E, string>;
|
|
1007
|
+
valueToLabel: Record<E, string | number>;
|
|
1003
1008
|
}, context?: any) => any) | undefined; };
|
|
1004
1009
|
fields: Record<Path<z.TypeOf<T>>, any>;
|
|
1005
1010
|
field: <P extends Path<z.TypeOf<T>>>(path: P) => any;
|
|
@@ -1445,7 +1450,7 @@ interface DisplayFieldProps<FormType> {
|
|
|
1445
1450
|
class: string;
|
|
1446
1451
|
label?: string;
|
|
1447
1452
|
}>;
|
|
1448
|
-
valueToLabel?: Record<string, string>;
|
|
1453
|
+
valueToLabel?: Record<string | number, string | number>;
|
|
1449
1454
|
separator?: string;
|
|
1450
1455
|
itemRenderer?: (item: any, index: number) => string;
|
|
1451
1456
|
maxItems?: number;
|
|
@@ -1688,8 +1693,14 @@ interface SchemaFieldMetadata {
|
|
|
1688
1693
|
rows?: number;
|
|
1689
1694
|
/** For textarea fields, number of columns to display */
|
|
1690
1695
|
cols?: number;
|
|
1691
|
-
/** For enum fields, map values to display labels */
|
|
1692
|
-
valueToLabel?: Record<string, string>;
|
|
1696
|
+
/** For enum fields, map values to display labels (keys and values can be string or number) */
|
|
1697
|
+
valueToLabel?: Record<string | number, string | number>;
|
|
1698
|
+
/**
|
|
1699
|
+
* Coerce select/combobox values to this type when setting form state.
|
|
1700
|
+
* Use 'number' when valueToLabel has numeric keys - stores numbers instead of strings.
|
|
1701
|
+
* Keeps Zod strict (no transforms needed); the field handles coercion at input time.
|
|
1702
|
+
*/
|
|
1703
|
+
valueType?: 'number';
|
|
1693
1704
|
/** Whether to hide validation errors */
|
|
1694
1705
|
hideError?: boolean;
|
|
1695
1706
|
/** Step value for numeric fields */
|
|
@@ -2817,10 +2828,10 @@ declare function useForm<T extends z.ZodObject<any>, CalcType = (values: z.infer
|
|
|
2817
2828
|
default: () => any;
|
|
2818
2829
|
}, {}>;
|
|
2819
2830
|
createTypedSelectField: <P extends Path<z.TypeOf<T>>>(fieldPath: P) => <E extends FieldPathToEnum<z.TypeOf<T>, P> = FieldPathToEnum<z.TypeOf<T>, P>>(props: Omit<SelectFieldProps<z.TypeOf<T>, Path<z.TypeOf<T>>, any>, "name" | "valueToLabel"> & {
|
|
2820
|
-
valueToLabel: Record<E, string>;
|
|
2831
|
+
valueToLabel: Record<E, string | number>;
|
|
2821
2832
|
}, context?: any) => any;
|
|
2822
2833
|
typedSelectFields: { [K in Path<z.TypeOf<T>>]?: (<E extends FieldPathToEnum<z.TypeOf<T>, K> = FieldPathToEnum<z.TypeOf<T>, K>>(props: Omit<SelectFieldProps<z.TypeOf<T>, Path<z.TypeOf<T>>, any>, "name" | "valueToLabel"> & {
|
|
2823
|
-
valueToLabel: Record<E, string>;
|
|
2834
|
+
valueToLabel: Record<E, string | number>;
|
|
2824
2835
|
}, context?: any) => any) | undefined; };
|
|
2825
2836
|
fields: Record<Path<z.TypeOf<T>>, any>;
|
|
2826
2837
|
field: <P extends Path<z.TypeOf<T>>>(path: P) => any;
|
package/dist/index.js
CHANGED
|
@@ -1252,18 +1252,24 @@ function extractFieldMetadata(schema, path = "", parentSchema, schemaId) {
|
|
|
1252
1252
|
metadata.inputType = "textarea";
|
|
1253
1253
|
}
|
|
1254
1254
|
if (customMetadata.valueToLabel && metadata.type === "enum" && metadata.options) {
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1255
|
+
const valueType = customMetadata.valueType;
|
|
1256
|
+
metadata.options = metadata.options.map((option) => {
|
|
1257
|
+
const rawValue = option.value;
|
|
1258
|
+
const value = valueType === "number" ? Number(rawValue) : rawValue;
|
|
1259
|
+
return {
|
|
1260
|
+
value,
|
|
1261
|
+
label: String(customMetadata.valueToLabel?.[rawValue] ?? option.label)
|
|
1262
|
+
};
|
|
1263
|
+
});
|
|
1259
1264
|
}
|
|
1260
1265
|
if (customMetadata.inputType === "select") {
|
|
1261
1266
|
metadata.type = "enum";
|
|
1262
1267
|
if (!metadata.options || metadata.options.length === 0) {
|
|
1263
1268
|
if (customMetadata.valueToLabel) {
|
|
1269
|
+
const valueType = customMetadata.valueType;
|
|
1264
1270
|
metadata.options = Object.entries(customMetadata.valueToLabel).map(([value, label]) => ({
|
|
1265
|
-
value,
|
|
1266
|
-
label
|
|
1271
|
+
value: valueType === "number" ? Number(value) : value,
|
|
1272
|
+
label: String(label)
|
|
1267
1273
|
}));
|
|
1268
1274
|
} else if (customMetadata.options) {
|
|
1269
1275
|
metadata.options = customMetadata.options;
|
|
@@ -5053,7 +5059,7 @@ function createDaisyUISelectField() {
|
|
|
5053
5059
|
const valueToLabel = normalizedProps.valueToLabel;
|
|
5054
5060
|
return schemaOptions.map((option) => ({
|
|
5055
5061
|
value: option.value,
|
|
5056
|
-
label: typeof valueToLabel === "function" ? valueToLabel(option.value) : valueToLabel[option.value]
|
|
5062
|
+
label: typeof valueToLabel === "function" ? valueToLabel(option.value) : valueToLabel[option.value] ?? option.value
|
|
5057
5063
|
}));
|
|
5058
5064
|
}
|
|
5059
5065
|
return schemaOptions;
|
|
@@ -5112,7 +5118,9 @@ function createDaisyUISelectField() {
|
|
|
5112
5118
|
value: formState.getValue(props.name),
|
|
5113
5119
|
onChange: (event) => {
|
|
5114
5120
|
const target = event.target;
|
|
5115
|
-
|
|
5121
|
+
const rawValue = target.value;
|
|
5122
|
+
const value = fieldMetadata?.valueType === "number" && rawValue !== "" ? Number(rawValue) : rawValue;
|
|
5123
|
+
formState.setValue(props.name, value);
|
|
5116
5124
|
formState.touchField(props.name);
|
|
5117
5125
|
formState.validateField(props.name);
|
|
5118
5126
|
},
|
|
@@ -8968,6 +8976,7 @@ var EnumMultiSelectFilter = (props) => {
|
|
|
8968
8976
|
e.preventDefault();
|
|
8969
8977
|
e.stopPropagation();
|
|
8970
8978
|
closeDropdown();
|
|
8979
|
+
document.activeElement?.blur();
|
|
8971
8980
|
},
|
|
8972
8981
|
onMousedown: (e) => {
|
|
8973
8982
|
e.preventDefault();
|
|
@@ -10240,6 +10249,10 @@ function convertToDataType(metadataType) {
|
|
|
10240
10249
|
}
|
|
10241
10250
|
}
|
|
10242
10251
|
var FilterDrawer = (props) => {
|
|
10252
|
+
const handleClose = () => {
|
|
10253
|
+
props.onClose();
|
|
10254
|
+
document.activeElement?.blur();
|
|
10255
|
+
};
|
|
10243
10256
|
const injectedFilterOptionsState = inject(
|
|
10244
10257
|
ZINIA_DATA_TABLE_FILTER_OPTIONS_STATE_KEY,
|
|
10245
10258
|
void 0
|
|
@@ -10261,7 +10274,7 @@ var FilterDrawer = (props) => {
|
|
|
10261
10274
|
"div",
|
|
10262
10275
|
{
|
|
10263
10276
|
class: "absolute inset-0 bg-black/50 transition-opacity opacity-100 pointer-events-auto",
|
|
10264
|
-
onClick:
|
|
10277
|
+
onClick: handleClose
|
|
10265
10278
|
}
|
|
10266
10279
|
),
|
|
10267
10280
|
/* @__PURE__ */ jsxs(
|
|
@@ -10313,7 +10326,7 @@ var FilterDrawer = (props) => {
|
|
|
10313
10326
|
"button",
|
|
10314
10327
|
{
|
|
10315
10328
|
class: "btn btn-ghost btn-sm btn-circle hover:bg-base-300",
|
|
10316
|
-
onClick:
|
|
10329
|
+
onClick: handleClose,
|
|
10317
10330
|
"aria-label": "Close filters",
|
|
10318
10331
|
children: /* @__PURE__ */ jsx(
|
|
10319
10332
|
"svg",
|
|
@@ -10458,7 +10471,7 @@ var FilterDrawer = (props) => {
|
|
|
10458
10471
|
"button",
|
|
10459
10472
|
{
|
|
10460
10473
|
class: "btn btn-primary w-full btn-sm text-xs md:text-sm",
|
|
10461
|
-
onClick:
|
|
10474
|
+
onClick: handleClose,
|
|
10462
10475
|
"data-testid": `${props.tableName || "datatable"}-filter-drawer-apply`,
|
|
10463
10476
|
children: "Done"
|
|
10464
10477
|
}
|
|
@@ -10708,6 +10721,10 @@ var LoadingSkeletons = (props) => {
|
|
|
10708
10721
|
] });
|
|
10709
10722
|
};
|
|
10710
10723
|
var SortDrawer = (props) => {
|
|
10724
|
+
const handleClose = () => {
|
|
10725
|
+
props.onClose();
|
|
10726
|
+
document.activeElement?.blur();
|
|
10727
|
+
};
|
|
10711
10728
|
watch(
|
|
10712
10729
|
() => props.isOpen,
|
|
10713
10730
|
(isOpen) => {
|
|
@@ -10719,7 +10736,7 @@ var SortDrawer = (props) => {
|
|
|
10719
10736
|
}
|
|
10720
10737
|
);
|
|
10721
10738
|
if (!props.isOpen) return null;
|
|
10722
|
-
return /* @__PURE__ */ jsx(Teleport, { to: "body", children: /* @__PURE__ */ jsx("div", { class: "fixed inset-0 z-50 bg-black/50", onClick:
|
|
10739
|
+
return /* @__PURE__ */ jsx(Teleport, { to: "body", children: /* @__PURE__ */ jsx("div", { class: "fixed inset-0 z-50 bg-black/50", onClick: handleClose, children: /* @__PURE__ */ jsx(
|
|
10723
10740
|
"div",
|
|
10724
10741
|
{
|
|
10725
10742
|
class: "fixed bottom-0 left-0 right-0 bg-base-100 rounded-t-lg animate-slide-up",
|
|
@@ -10728,7 +10745,7 @@ var SortDrawer = (props) => {
|
|
|
10728
10745
|
children: /* @__PURE__ */ jsxs("div", { class: "p-4", children: [
|
|
10729
10746
|
/* @__PURE__ */ jsxs("div", { class: "flex items-center justify-between mb-4", children: [
|
|
10730
10747
|
/* @__PURE__ */ jsx("h3", { class: "text-lg font-semibold", children: "Sort Options" }),
|
|
10731
|
-
/* @__PURE__ */ jsx("button", { class: "btn btn-ghost btn-sm btn-circle", onClick:
|
|
10748
|
+
/* @__PURE__ */ jsx("button", { class: "btn btn-ghost btn-sm btn-circle", onClick: handleClose, children: "\u2715" })
|
|
10732
10749
|
] }),
|
|
10733
10750
|
/* @__PURE__ */ jsxs("div", { class: "space-y-2 max-h-96 overflow-y-auto", children: [
|
|
10734
10751
|
/* @__PURE__ */ jsxs(
|
|
@@ -10737,7 +10754,7 @@ var SortDrawer = (props) => {
|
|
|
10737
10754
|
class: `w-full text-left p-3 rounded-lg transition-colors ${!props.sortingField ? "bg-primary text-primary-content" : "hover:bg-base-200"}`,
|
|
10738
10755
|
onClick: () => {
|
|
10739
10756
|
props.onClearSort();
|
|
10740
|
-
|
|
10757
|
+
handleClose();
|
|
10741
10758
|
},
|
|
10742
10759
|
"data-testid": `${props.tableName || "datatable"}-sort-drawer-clear`,
|
|
10743
10760
|
children: [
|
|
@@ -10758,7 +10775,7 @@ var SortDrawer = (props) => {
|
|
|
10758
10775
|
class: `w-full text-left p-3 rounded-lg transition-colors ${props.sortingField === field && props.sortingDirection === "asc" ? "bg-primary text-primary-content" : "hover:bg-base-200"}`,
|
|
10759
10776
|
onClick: () => {
|
|
10760
10777
|
props.onSort(field, "asc");
|
|
10761
|
-
|
|
10778
|
+
handleClose();
|
|
10762
10779
|
},
|
|
10763
10780
|
"data-testid": `${props.tableName || "datatable"}-sort-drawer-${field}-asc`,
|
|
10764
10781
|
children: /* @__PURE__ */ jsxs("div", { class: "font-medium", children: [
|
|
@@ -10776,7 +10793,7 @@ var SortDrawer = (props) => {
|
|
|
10776
10793
|
class: `w-full text-left p-3 rounded-lg transition-colors ${props.sortingField === field && props.sortingDirection === "desc" ? "bg-primary text-primary-content" : "hover:bg-base-200"}`,
|
|
10777
10794
|
onClick: () => {
|
|
10778
10795
|
props.onSort(field, "desc");
|
|
10779
|
-
|
|
10796
|
+
handleClose();
|
|
10780
10797
|
},
|
|
10781
10798
|
"data-testid": `${props.tableName || "datatable"}-sort-drawer-${field}-desc`,
|
|
10782
10799
|
children: /* @__PURE__ */ jsxs("div", { class: "font-medium", children: [
|