@dragonmastery/zinia-forms-core 0.3.10 → 0.3.11
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 +7 -0
- package/dist/index.js +147 -7
- package/dist/index.js.map +1 -1
- package/package.json +11 -10
package/dist/index.d.ts
CHANGED
|
@@ -882,6 +882,8 @@ interface TextareaFieldProps<FormType> {
|
|
|
882
882
|
size?: string;
|
|
883
883
|
variant?: string;
|
|
884
884
|
rows?: number;
|
|
885
|
+
autoExpand?: boolean;
|
|
886
|
+
maxRows?: number;
|
|
885
887
|
}
|
|
886
888
|
|
|
887
889
|
interface TextFieldProps<FormType> {
|
|
@@ -1359,6 +1361,11 @@ declare function useForm<T extends z.ZodObject<any>, CalcType = (values: z.infer
|
|
|
1359
1361
|
getDisplayText: (path: string) => string;
|
|
1360
1362
|
setSelectedIndex: (path: string, index: number) => void;
|
|
1361
1363
|
getSelectedIndex: (path: string) => number;
|
|
1364
|
+
getArrayItemId: (path: string, index: number) => string;
|
|
1365
|
+
addArrayItemId: (path: string, index?: number) => string;
|
|
1366
|
+
removeArrayItemId: (path: string, index: number) => void;
|
|
1367
|
+
swapArrayItemIds: (path: string, indexA: number, indexB: number) => void;
|
|
1368
|
+
syncArrayItemIds: (path: string) => void;
|
|
1362
1369
|
};
|
|
1363
1370
|
ZiniaForm: vue.FunctionalComponent<FormProps<z.TypeOf<T>>, {}, any, {}>;
|
|
1364
1371
|
ZiniaSubmitButton: vue.FunctionalComponent<SubmitButtonProps<z.TypeOf<T>>, {}, any, {}>;
|
package/dist/index.js
CHANGED
|
@@ -849,6 +849,71 @@ function setFieldSelectedIndex(formState, path, index) {
|
|
|
849
849
|
function getFieldSelectedIndex(formState, path) {
|
|
850
850
|
return formState.selectedIndex[path] ?? -1;
|
|
851
851
|
}
|
|
852
|
+
function generateArrayItemId() {
|
|
853
|
+
return `item-${Math.random().toString(36).substr(2, 9)}-${Date.now()}`;
|
|
854
|
+
}
|
|
855
|
+
function getArrayItemId(formState, path, index) {
|
|
856
|
+
if (!formState.arrayItemIds[path]) {
|
|
857
|
+
formState.arrayItemIds[path] = [];
|
|
858
|
+
}
|
|
859
|
+
const ids = formState.arrayItemIds[path];
|
|
860
|
+
const arrayValue = getFieldValue(formState, path);
|
|
861
|
+
const arrayLength = Array.isArray(arrayValue) ? arrayValue.length : 0;
|
|
862
|
+
while (ids.length < arrayLength) {
|
|
863
|
+
ids.push(generateArrayItemId());
|
|
864
|
+
}
|
|
865
|
+
if (index >= ids.length) {
|
|
866
|
+
ids.push(generateArrayItemId());
|
|
867
|
+
}
|
|
868
|
+
return ids[index];
|
|
869
|
+
}
|
|
870
|
+
function addArrayItemId(formState, path, index) {
|
|
871
|
+
if (!formState.arrayItemIds[path]) {
|
|
872
|
+
formState.arrayItemIds[path] = [];
|
|
873
|
+
}
|
|
874
|
+
const ids = formState.arrayItemIds[path];
|
|
875
|
+
const newId = generateArrayItemId();
|
|
876
|
+
if (index !== void 0 && index >= 0 && index <= ids.length) {
|
|
877
|
+
ids.splice(index, 0, newId);
|
|
878
|
+
} else {
|
|
879
|
+
ids.push(newId);
|
|
880
|
+
}
|
|
881
|
+
return newId;
|
|
882
|
+
}
|
|
883
|
+
function removeArrayItemId(formState, path, index) {
|
|
884
|
+
if (!formState.arrayItemIds[path]) {
|
|
885
|
+
return;
|
|
886
|
+
}
|
|
887
|
+
const ids = formState.arrayItemIds[path];
|
|
888
|
+
if (index >= 0 && index < ids.length) {
|
|
889
|
+
ids.splice(index, 1);
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
function swapArrayItemIds(formState, path, indexA, indexB) {
|
|
893
|
+
if (!formState.arrayItemIds[path]) {
|
|
894
|
+
return;
|
|
895
|
+
}
|
|
896
|
+
const ids = formState.arrayItemIds[path];
|
|
897
|
+
if (indexA >= 0 && indexA < ids.length && indexB >= 0 && indexB < ids.length) {
|
|
898
|
+
const temp = ids[indexA];
|
|
899
|
+
ids[indexA] = ids[indexB];
|
|
900
|
+
ids[indexB] = temp;
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
function syncArrayItemIds(formState, path) {
|
|
904
|
+
const arrayValue = getFieldValue(formState, path);
|
|
905
|
+
const arrayLength = Array.isArray(arrayValue) ? arrayValue.length : 0;
|
|
906
|
+
if (!formState.arrayItemIds[path]) {
|
|
907
|
+
formState.arrayItemIds[path] = [];
|
|
908
|
+
}
|
|
909
|
+
const ids = formState.arrayItemIds[path];
|
|
910
|
+
while (ids.length < arrayLength) {
|
|
911
|
+
ids.push(generateArrayItemId());
|
|
912
|
+
}
|
|
913
|
+
if (ids.length > arrayLength) {
|
|
914
|
+
ids.splice(arrayLength);
|
|
915
|
+
}
|
|
916
|
+
}
|
|
852
917
|
|
|
853
918
|
// src/registry/metadataRegistry.ts
|
|
854
919
|
var globalRegistry = {};
|
|
@@ -1526,6 +1591,7 @@ function useFormState(initialData, options) {
|
|
|
1526
1591
|
undoHistory: {},
|
|
1527
1592
|
redoHistory: {},
|
|
1528
1593
|
pendingOperations: {},
|
|
1594
|
+
arrayItemIds: {},
|
|
1529
1595
|
// Form status
|
|
1530
1596
|
isSubmitting: false,
|
|
1531
1597
|
hasAttemptedSubmit: false,
|
|
@@ -2009,7 +2075,13 @@ function useForm(schema, options) {
|
|
|
2009
2075
|
setDisplayText: (path, text) => setFieldDisplayText(formState.state, path, text),
|
|
2010
2076
|
getDisplayText: (path) => getFieldDisplayText(formState.state, path),
|
|
2011
2077
|
setSelectedIndex: (path, index) => setFieldSelectedIndex(formState.state, path, index),
|
|
2012
|
-
getSelectedIndex: (path) => getFieldSelectedIndex(formState.state, path)
|
|
2078
|
+
getSelectedIndex: (path) => getFieldSelectedIndex(formState.state, path),
|
|
2079
|
+
// Array item ID management (for stable keys in ArrayField)
|
|
2080
|
+
getArrayItemId: (path, index) => getArrayItemId(formState.state, path, index),
|
|
2081
|
+
addArrayItemId: (path, index) => addArrayItemId(formState.state, path, index),
|
|
2082
|
+
removeArrayItemId: (path, index) => removeArrayItemId(formState.state, path, index),
|
|
2083
|
+
swapArrayItemIds: (path, indexA, indexB) => swapArrayItemIds(formState.state, path, indexA, indexB),
|
|
2084
|
+
syncArrayItemIds: (path) => syncArrayItemIds(formState.state, path)
|
|
2013
2085
|
};
|
|
2014
2086
|
if (options.autoProvide !== false) {
|
|
2015
2087
|
provide(ZINIA_FORM_SCHEMA_KEY, schema);
|
|
@@ -3736,6 +3808,7 @@ function createDaisyUIArrayField() {
|
|
|
3736
3808
|
}
|
|
3737
3809
|
const fieldMetadata = formState.fieldsMetadata[props.name] || {};
|
|
3738
3810
|
const arrayValue = formState.getValue(props.name) || [];
|
|
3811
|
+
formState.syncArrayItemIds(props.name);
|
|
3739
3812
|
const fieldName = String(props.name);
|
|
3740
3813
|
if (!formState.collapsedFields[fieldName]) {
|
|
3741
3814
|
formState.collapsedFields[fieldName] = {
|
|
@@ -3874,7 +3947,19 @@ function createDaisyUIArrayField() {
|
|
|
3874
3947
|
const currentActualArray = formState.getValue(props.name) || [];
|
|
3875
3948
|
const newArray = [...currentActualArray];
|
|
3876
3949
|
const removedItem = newArray[opToConfirm.index];
|
|
3877
|
-
|
|
3950
|
+
const removedIndex = opToConfirm.index;
|
|
3951
|
+
newArray.splice(removedIndex, 1);
|
|
3952
|
+
formState.removeArrayItemId(props.name, removedIndex);
|
|
3953
|
+
const collapsedItems = collapseState.collapsedItems;
|
|
3954
|
+
const deletedIndexPos = collapsedItems.indexOf(removedIndex);
|
|
3955
|
+
if (deletedIndexPos > -1) {
|
|
3956
|
+
collapsedItems.splice(deletedIndexPos, 1);
|
|
3957
|
+
}
|
|
3958
|
+
for (let i = 0; i < collapsedItems.length; i++) {
|
|
3959
|
+
if (collapsedItems[i] > removedIndex) {
|
|
3960
|
+
collapsedItems[i] = collapsedItems[i] - 1;
|
|
3961
|
+
}
|
|
3962
|
+
}
|
|
3878
3963
|
formState.setValue(props.name, newArray);
|
|
3879
3964
|
formState.validateField(props.name);
|
|
3880
3965
|
const instance = getCurrentInstance();
|
|
@@ -3886,10 +3971,10 @@ function createDaisyUIArrayField() {
|
|
|
3886
3971
|
}
|
|
3887
3972
|
formState.pendingOperations[fieldName] = ops.filter((op) => op.timestamp !== opToConfirm.timestamp);
|
|
3888
3973
|
if (opToConfirm.type === "remove" && opToConfirm.index !== void 0) {
|
|
3889
|
-
const
|
|
3974
|
+
const removedIndex2 = opToConfirm.index;
|
|
3890
3975
|
const remainingOps = formState.pendingOperations[fieldName];
|
|
3891
3976
|
const updatedOps = remainingOps.map((op) => {
|
|
3892
|
-
if (op.type === "remove" && op.index !== void 0 && op.index >
|
|
3977
|
+
if (op.type === "remove" && op.index !== void 0 && op.index > removedIndex2) {
|
|
3893
3978
|
const newIndex = op.index - 1;
|
|
3894
3979
|
const currentArray = formState.getValue(props.name) || [];
|
|
3895
3980
|
const newCurrentState = [...currentArray];
|
|
@@ -3942,6 +4027,7 @@ function createDaisyUIArrayField() {
|
|
|
3942
4027
|
}
|
|
3943
4028
|
const itemCopy = JSON.parse(JSON.stringify(item));
|
|
3944
4029
|
const newArray = [...currentArray, itemCopy];
|
|
4030
|
+
formState.addArrayItemId(props.name, newArray.length - 1);
|
|
3945
4031
|
formState.setValue(props.name, newArray);
|
|
3946
4032
|
formState.validateField(props.name);
|
|
3947
4033
|
if (props.onAddItem) {
|
|
@@ -3965,6 +4051,17 @@ function createDaisyUIArrayField() {
|
|
|
3965
4051
|
createPendingOperation("remove", previousState, newArray, index);
|
|
3966
4052
|
return;
|
|
3967
4053
|
}
|
|
4054
|
+
formState.removeArrayItemId(props.name, index);
|
|
4055
|
+
const collapsedItems = collapseState.collapsedItems;
|
|
4056
|
+
const deletedIndexPos = collapsedItems.indexOf(index);
|
|
4057
|
+
if (deletedIndexPos > -1) {
|
|
4058
|
+
collapsedItems.splice(deletedIndexPos, 1);
|
|
4059
|
+
}
|
|
4060
|
+
for (let i = 0; i < collapsedItems.length; i++) {
|
|
4061
|
+
if (collapsedItems[i] > index) {
|
|
4062
|
+
collapsedItems[i] = collapsedItems[i] - 1;
|
|
4063
|
+
}
|
|
4064
|
+
}
|
|
3968
4065
|
formState.setValue(props.name, newArray);
|
|
3969
4066
|
formState.validateField(props.name);
|
|
3970
4067
|
if (props.onRemoveItem) {
|
|
@@ -3984,6 +4081,7 @@ function createDaisyUIArrayField() {
|
|
|
3984
4081
|
const temp = newArray[indexA];
|
|
3985
4082
|
newArray[indexA] = newArray[indexB];
|
|
3986
4083
|
newArray[indexB] = temp;
|
|
4084
|
+
formState.swapArrayItemIds(props.name, indexA, indexB);
|
|
3987
4085
|
formState.setValue(props.name, newArray);
|
|
3988
4086
|
formState.validateField(props.name);
|
|
3989
4087
|
if (props.onSwapItems) {
|
|
@@ -4180,11 +4278,14 @@ function createDaisyUIArrayField() {
|
|
|
4180
4278
|
`remove-${itemPendingOp.timestamp}`
|
|
4181
4279
|
);
|
|
4182
4280
|
}
|
|
4183
|
-
const
|
|
4281
|
+
const itemId = formState.getArrayItemId(props.name, index);
|
|
4282
|
+
const itemKey = `item-${index}-${itemId}`;
|
|
4184
4283
|
return /* @__PURE__ */ jsxs(
|
|
4185
4284
|
"div",
|
|
4186
4285
|
{
|
|
4187
4286
|
class: "border border-base-300 rounded-lg bg-base-100 shadow-sm hover:shadow-md transition-shadow",
|
|
4287
|
+
"data-item-key": itemKey,
|
|
4288
|
+
"data-item-index": index,
|
|
4188
4289
|
children: [
|
|
4189
4290
|
/* @__PURE__ */ jsxs("div", { class: "border-b border-base-200 bg-base-50 rounded-t-lg", children: [
|
|
4190
4291
|
/* @__PURE__ */ jsxs("div", { class: "flex items-center justify-between gap-2 p-1 sm:p-3 sm:px-4", children: [
|
|
@@ -6192,11 +6293,47 @@ function createDaisyUITextareaField() {
|
|
|
6192
6293
|
return null;
|
|
6193
6294
|
}
|
|
6194
6295
|
const fieldMetadata = formState.fieldsMetadata[props.name] || {};
|
|
6296
|
+
const textareaRef = ref(null);
|
|
6297
|
+
const autoExpand = props.autoExpand !== false;
|
|
6298
|
+
const defaultMaxRows = 10;
|
|
6299
|
+
const maxRows = props.maxRows ?? (autoExpand ? defaultMaxRows : void 0);
|
|
6300
|
+
const minRows = props.rows ?? 3;
|
|
6301
|
+
const getLineHeight = () => {
|
|
6302
|
+
const textarea = textareaRef.value;
|
|
6303
|
+
if (!textarea) return 24;
|
|
6304
|
+
const style = window.getComputedStyle(textarea);
|
|
6305
|
+
const lineHeight = parseFloat(style.lineHeight);
|
|
6306
|
+
return isNaN(lineHeight) ? 24 : lineHeight;
|
|
6307
|
+
};
|
|
6308
|
+
const autoResize = async () => {
|
|
6309
|
+
const textarea = textareaRef.value;
|
|
6310
|
+
if (!textarea || !autoExpand) return;
|
|
6311
|
+
textarea.style.height = "auto";
|
|
6312
|
+
await nextTick();
|
|
6313
|
+
const scrollHeight = textarea.scrollHeight;
|
|
6314
|
+
const lineHeight = getLineHeight();
|
|
6315
|
+
const minHeight = minRows * lineHeight;
|
|
6316
|
+
const maxHeight = maxRows ? maxRows * lineHeight : void 0;
|
|
6317
|
+
const newHeight = maxHeight ? Math.min(Math.max(scrollHeight, minHeight), maxHeight) : Math.max(scrollHeight, minHeight);
|
|
6318
|
+
textarea.style.height = `${newHeight}px`;
|
|
6319
|
+
textarea.style.overflowY = maxHeight && scrollHeight > maxHeight ? "auto" : "hidden";
|
|
6320
|
+
};
|
|
6321
|
+
const setTextareaRef = (el) => {
|
|
6322
|
+
textareaRef.value = el;
|
|
6323
|
+
if (el && autoExpand && formState.getValue(props.name)) {
|
|
6324
|
+
nextTick(() => {
|
|
6325
|
+
autoResize();
|
|
6326
|
+
});
|
|
6327
|
+
}
|
|
6328
|
+
};
|
|
6195
6329
|
const textareaProps = {
|
|
6196
6330
|
value: formState.getValue(props.name),
|
|
6197
|
-
onInput: (event) => {
|
|
6331
|
+
onInput: async (event) => {
|
|
6198
6332
|
const target = event.target;
|
|
6199
6333
|
formState.setValue(props.name, target.value);
|
|
6334
|
+
if (autoExpand) {
|
|
6335
|
+
await autoResize();
|
|
6336
|
+
}
|
|
6200
6337
|
},
|
|
6201
6338
|
onBlur: () => {
|
|
6202
6339
|
formState.touchField(props.name);
|
|
@@ -6223,6 +6360,7 @@ function createDaisyUITextareaField() {
|
|
|
6223
6360
|
/* @__PURE__ */ jsx(
|
|
6224
6361
|
"textarea",
|
|
6225
6362
|
{
|
|
6363
|
+
ref: setTextareaRef,
|
|
6226
6364
|
class: textareaClass,
|
|
6227
6365
|
placeholder: props.placeholder,
|
|
6228
6366
|
disabled: props.disabled,
|
|
@@ -6248,7 +6386,9 @@ function createDaisyUITextareaField() {
|
|
|
6248
6386
|
"required",
|
|
6249
6387
|
"size",
|
|
6250
6388
|
"variant",
|
|
6251
|
-
"rows"
|
|
6389
|
+
"rows",
|
|
6390
|
+
"autoExpand",
|
|
6391
|
+
"maxRows"
|
|
6252
6392
|
];
|
|
6253
6393
|
return DaisyUITextareaField;
|
|
6254
6394
|
}
|