@effect-app/vue-components 4.0.0-beta.3 → 4.0.0-beta.300
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 +36 -8
- package/dist/reset.css +52 -0
- package/dist/types/components/CommandButton.vue.d.ts +24 -5
- package/dist/types/components/Dialog.vue.d.ts +3 -1
- package/dist/types/components/FixedNuxtErrorBoundary.vue.d.ts +39 -0
- package/dist/types/components/OmegaForm/InputProps.d.ts +1 -1
- package/dist/types/components/OmegaForm/OmegaArray.vue.d.ts +1 -1
- package/dist/types/components/OmegaForm/OmegaAutoGen.vue.d.ts +1 -1
- package/dist/types/components/OmegaForm/OmegaErrorsInternal.vue.d.ts +1 -1
- package/dist/types/components/OmegaForm/OmegaFormInput.vue.d.ts +1 -1
- package/dist/types/components/OmegaForm/OmegaInput.vue.d.ts +1 -1
- package/dist/types/components/OmegaForm/OmegaInputVuetify.vue.d.ts +6 -0
- package/dist/types/components/OmegaForm/OmegaInternalInput.vue.d.ts +6 -9
- package/dist/types/components/OmegaForm/OmegaTaggedUnion.vue.d.ts +2 -2
- package/dist/types/components/OmegaForm/OmegaTaggedUnionInternal.vue.d.ts +3 -3
- package/dist/types/components/OmegaForm/OmegaWrapper.vue.d.ts +1 -1
- package/dist/types/components/OmegaForm/createUseFormWithCustomInput.d.ts +4 -2
- package/dist/types/components/OmegaForm/errors.d.ts +33 -0
- package/dist/types/components/OmegaForm/getOmegaStore.d.ts +1 -1
- package/dist/types/components/OmegaForm/hocs.d.ts +3 -0
- package/dist/types/components/OmegaForm/index.d.ts +14 -3
- package/dist/types/components/OmegaForm/inputs.d.ts +4 -0
- package/dist/types/components/OmegaForm/meta/checks.d.ts +4 -0
- package/dist/types/components/OmegaForm/meta/createMeta.d.ts +33 -0
- package/dist/types/components/OmegaForm/meta/defaults.d.ts +21 -0
- package/dist/types/components/OmegaForm/meta/redacted.d.ts +2 -0
- package/dist/types/components/OmegaForm/meta/types.d.ts +56 -0
- package/dist/types/components/OmegaForm/meta/walker.d.ts +18 -0
- package/dist/types/components/OmegaForm/persistency.d.ts +58 -0
- package/dist/types/components/OmegaForm/submit.d.ts +60 -0
- package/dist/types/components/OmegaForm/types.d.ts +312 -0
- package/dist/types/components/OmegaForm/useOmegaForm.d.ts +9 -215
- package/dist/types/components/OmegaForm/validation/localized.d.ts +10 -0
- package/dist/types/components/index.d.ts +1 -0
- package/dist/types/index.d.ts +0 -1
- package/dist/types/utils/index.d.ts +8 -9
- package/dist/vue-components.es.js +30 -44
- package/dist/vue-components10.es.js +5 -0
- package/dist/vue-components11.es.js +56 -0
- package/dist/vue-components12.es.js +5 -0
- package/dist/vue-components13.es.js +20 -0
- package/dist/vue-components14.es.js +49 -0
- package/dist/vue-components15.es.js +128 -0
- package/dist/vue-components16.es.js +65 -0
- package/dist/vue-components17.es.js +114 -0
- package/dist/vue-components18.es.js +22 -0
- package/dist/vue-components19.es.js +5 -0
- package/dist/vue-components2.es.js +11 -0
- package/dist/vue-components20.es.js +80 -0
- package/dist/vue-components21.es.js +93 -0
- package/dist/vue-components22.es.js +73 -0
- package/dist/vue-components23.es.js +12 -0
- package/dist/vue-components24.es.js +57 -0
- package/dist/vue-components25.es.js +5 -0
- package/dist/vue-components26.es.js +44 -0
- package/dist/vue-components27.es.js +5 -0
- package/dist/vue-components28.es.js +84 -0
- package/dist/vue-components3.es.js +98 -0
- package/dist/vue-components30.es.js +8 -0
- package/dist/vue-components31.es.js +9 -0
- package/dist/vue-components32.es.js +24 -0
- package/dist/vue-components33.es.js +300 -0
- package/dist/vue-components35.es.js +8 -0
- package/dist/vue-components36.es.js +73 -0
- package/dist/vue-components37.es.js +5 -0
- package/dist/vue-components38.es.js +64 -0
- package/dist/vue-components39.es.js +5 -0
- package/dist/vue-components4.es.js +5 -0
- package/dist/vue-components40.es.js +24 -0
- package/dist/vue-components41.es.js +5 -0
- package/dist/vue-components42.es.js +59 -0
- package/dist/vue-components43.es.js +5 -0
- package/dist/vue-components44.es.js +12 -0
- package/dist/vue-components45.es.js +22 -0
- package/dist/vue-components47.es.js +9 -0
- package/dist/vue-components48.es.js +4 -0
- package/dist/vue-components49.es.js +38 -0
- package/dist/vue-components5.es.js +24 -0
- package/dist/vue-components50.es.js +27 -0
- package/dist/vue-components51.es.js +28 -0
- package/dist/vue-components52.es.js +7 -0
- package/dist/vue-components53.es.js +18 -0
- package/dist/vue-components54.es.js +36 -0
- package/dist/vue-components55.es.js +18 -0
- package/dist/vue-components56.es.js +21 -0
- package/dist/vue-components57.es.js +30 -0
- package/dist/vue-components58.es.js +7 -0
- package/dist/vue-components59.es.js +9 -0
- package/dist/vue-components6.es.js +13 -0
- package/dist/vue-components60.es.js +38 -0
- package/dist/vue-components61.es.js +25 -0
- package/dist/vue-components62.es.js +128 -0
- package/dist/vue-components63.es.js +24 -0
- package/dist/vue-components64.es.js +21 -0
- package/dist/vue-components65.es.js +9 -0
- package/dist/vue-components66.es.js +19 -0
- package/dist/vue-components67.es.js +5 -0
- package/dist/vue-components68.es.js +29 -0
- package/dist/vue-components69.es.js +5 -0
- package/dist/vue-components7.es.js +13 -0
- package/dist/vue-components70.es.js +43 -0
- package/dist/vue-components71.es.js +101 -0
- package/dist/vue-components72.es.js +36 -0
- package/dist/vue-components73.es.js +19 -0
- package/dist/vue-components74.es.js +50 -0
- package/dist/vue-components8.es.js +35 -0
- package/dist/vue-components9.es.js +47 -0
- package/package.json +44 -34
- package/src/components/CommandButton.vue +96 -16
- package/src/components/Dialog.vue +0 -1
- package/src/components/FixedNuxtErrorBoundary.vue +112 -0
- package/src/components/OmegaForm/InputProps.ts +1 -1
- package/src/components/OmegaForm/OmegaArray.vue +8 -9
- package/src/components/OmegaForm/OmegaAutoGen.vue +26 -30
- package/src/components/OmegaForm/OmegaErrorsInternal.vue +3 -4
- package/src/components/OmegaForm/OmegaFormInput.vue +1 -1
- package/src/components/OmegaForm/OmegaInput.vue +26 -40
- package/src/components/OmegaForm/OmegaInputVuetify.vue +58 -8
- package/src/components/OmegaForm/OmegaInternalInput.vue +41 -18
- package/src/components/OmegaForm/OmegaTaggedUnion.vue +10 -3
- package/src/components/OmegaForm/OmegaTaggedUnionInternal.vue +6 -6
- package/src/components/OmegaForm/OmegaWrapper.vue +1 -1
- package/src/components/OmegaForm/blockDialog.ts +18 -6
- package/src/components/OmegaForm/createUseFormWithCustomInput.ts +16 -14
- package/src/components/OmegaForm/errors.ts +136 -0
- package/src/components/OmegaForm/getOmegaStore.ts +1 -1
- package/src/components/OmegaForm/hocs.ts +19 -0
- package/src/components/OmegaForm/index.ts +17 -4
- package/src/components/OmegaForm/inputs.ts +22 -0
- package/src/components/OmegaForm/meta/checks.ts +82 -0
- package/src/components/OmegaForm/meta/createMeta.ts +140 -0
- package/src/components/OmegaForm/meta/defaults.ts +261 -0
- package/src/components/OmegaForm/meta/redacted.ts +66 -0
- package/src/components/OmegaForm/meta/types.ts +78 -0
- package/src/components/OmegaForm/meta/walker.ts +248 -0
- package/src/components/OmegaForm/persistency.ts +247 -0
- package/src/components/OmegaForm/submit.ts +131 -0
- package/src/components/OmegaForm/types.ts +801 -0
- package/src/components/OmegaForm/useOmegaForm.ts +103 -898
- package/src/components/OmegaForm/useRegisterField.ts +1 -1
- package/src/components/OmegaForm/validation/localized.ts +203 -0
- package/src/components/index.ts +1 -0
- package/src/index.ts +0 -1
- package/src/reset.css +52 -0
- package/src/utils/index.ts +10 -11
- package/dist/types/components/OmegaForm/OmegaFormStuff.d.ts +0 -157
- package/dist/types/constants/index.d.ts +0 -1
- package/dist/vue-components.es10.js +0 -237
- package/dist/vue-components.es100.js +0 -4
- package/dist/vue-components.es11.js +0 -32
- package/dist/vue-components.es12.js +0 -439
- package/dist/vue-components.es13.js +0 -49
- package/dist/vue-components.es14.js +0 -4
- package/dist/vue-components.es15.js +0 -4
- package/dist/vue-components.es16.js +0 -725
- package/dist/vue-components.es17.js +0 -143
- package/dist/vue-components.es18.js +0 -6
- package/dist/vue-components.es19.js +0 -13
- package/dist/vue-components.es2.js +0 -30
- package/dist/vue-components.es20.js +0 -5
- package/dist/vue-components.es21.js +0 -26
- package/dist/vue-components.es22.js +0 -6
- package/dist/vue-components.es23.js +0 -10
- package/dist/vue-components.es24.js +0 -57
- package/dist/vue-components.es25.js +0 -71
- package/dist/vue-components.es26.js +0 -8
- package/dist/vue-components.es27.js +0 -8
- package/dist/vue-components.es28.js +0 -5
- package/dist/vue-components.es29.js +0 -5
- package/dist/vue-components.es3.js +0 -16
- package/dist/vue-components.es30.js +0 -4
- package/dist/vue-components.es31.js +0 -4
- package/dist/vue-components.es32.js +0 -4
- package/dist/vue-components.es33.js +0 -4
- package/dist/vue-components.es34.js +0 -19
- package/dist/vue-components.es35.js +0 -13
- package/dist/vue-components.es36.js +0 -40
- package/dist/vue-components.es37.js +0 -6
- package/dist/vue-components.es38.js +0 -85
- package/dist/vue-components.es39.js +0 -54
- package/dist/vue-components.es4.js +0 -52
- package/dist/vue-components.es40.js +0 -563
- package/dist/vue-components.es41.js +0 -43
- package/dist/vue-components.es42.js +0 -29
- package/dist/vue-components.es43.js +0 -7
- package/dist/vue-components.es44.js +0 -42
- package/dist/vue-components.es45.js +0 -316
- package/dist/vue-components.es46.js +0 -33
- package/dist/vue-components.es47.js +0 -6
- package/dist/vue-components.es48.js +0 -26
- package/dist/vue-components.es49.js +0 -77
- package/dist/vue-components.es5.js +0 -52
- package/dist/vue-components.es50.js +0 -101
- package/dist/vue-components.es51.js +0 -4
- package/dist/vue-components.es52.js +0 -320
- package/dist/vue-components.es53.js +0 -66
- package/dist/vue-components.es54.js +0 -4
- package/dist/vue-components.es55.js +0 -4
- package/dist/vue-components.es56.js +0 -113
- package/dist/vue-components.es58.js +0 -9
- package/dist/vue-components.es59.js +0 -34
- package/dist/vue-components.es6.js +0 -69
- package/dist/vue-components.es61.js +0 -194
- package/dist/vue-components.es63.js +0 -6
- package/dist/vue-components.es64.js +0 -103
- package/dist/vue-components.es65.js +0 -84
- package/dist/vue-components.es66.js +0 -17
- package/dist/vue-components.es67.js +0 -34
- package/dist/vue-components.es68.js +0 -4
- package/dist/vue-components.es69.js +0 -23
- package/dist/vue-components.es7.js +0 -83
- package/dist/vue-components.es70.js +0 -14
- package/dist/vue-components.es71.js +0 -115
- package/dist/vue-components.es72.js +0 -5
- package/dist/vue-components.es73.js +0 -4
- package/dist/vue-components.es74.js +0 -4
- package/dist/vue-components.es75.js +0 -17
- package/dist/vue-components.es76.js +0 -72
- package/dist/vue-components.es77.js +0 -25
- package/dist/vue-components.es78.js +0 -7
- package/dist/vue-components.es79.js +0 -23
- package/dist/vue-components.es8.js +0 -63
- package/dist/vue-components.es80.js +0 -32
- package/dist/vue-components.es81.js +0 -24
- package/dist/vue-components.es82.js +0 -14
- package/dist/vue-components.es83.js +0 -7
- package/dist/vue-components.es84.js +0 -21
- package/dist/vue-components.es85.js +0 -11
- package/dist/vue-components.es86.js +0 -33
- package/dist/vue-components.es87.js +0 -50
- package/dist/vue-components.es88.js +0 -28
- package/dist/vue-components.es89.js +0 -18
- package/dist/vue-components.es9.js +0 -21
- package/dist/vue-components.es90.js +0 -10
- package/dist/vue-components.es91.js +0 -13
- package/dist/vue-components.es92.js +0 -67
- package/dist/vue-components.es93.js +0 -58
- package/dist/vue-components.es94.js +0 -19
- package/dist/vue-components.es95.js +0 -35
- package/dist/vue-components.es96.js +0 -31
- package/dist/vue-components.es97.js +0 -44
- package/dist/vue-components.es98.js +0 -4
- package/dist/vue-components.es99.js +0 -46
- package/src/components/OmegaForm/OmegaFormStuff.ts +0 -1174
- package/src/constants/index.ts +0 -1
|
@@ -1,778 +1,97 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/consistent-type-imports */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
3
|
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import { Component, computed, ComputedRef, ConcreteComponent, h, type InjectionKey, onBeforeUnmount, onMounted, onUnmounted, Ref, ref, watch } from "vue"
|
|
14
|
-
import { useIntl } from "../../utils"
|
|
15
|
-
import { MergedInputProps } from "./InputProps"
|
|
4
|
+
import { type DeepKeys, type DeepValue, type FormAsyncValidateOrFn, type FormValidateOrFn, revalidateLogic, type StandardSchemaV1, useForm } from "@tanstack/vue-form"
|
|
5
|
+
import * as Context from "effect-app/Context"
|
|
6
|
+
import * as S from "effect-app/Schema"
|
|
7
|
+
import { type InjectionKey, watch } from "vue"
|
|
8
|
+
import { eHoc, makeFieldMap } from "./errors"
|
|
9
|
+
import { fHoc } from "./hocs"
|
|
10
|
+
import { generateMetaFromSchema, unwrapDeclaration } from "./meta/createMeta"
|
|
11
|
+
import { defaultsValueFromSchema, fillNestedDefaults } from "./meta/defaults"
|
|
12
|
+
import { toFormSchema } from "./meta/redacted"
|
|
16
13
|
import OmegaArray from "./OmegaArray.vue"
|
|
17
14
|
import OmegaAutoGen from "./OmegaAutoGen.vue"
|
|
18
15
|
import OmegaErrorsInternal from "./OmegaErrorsInternal.vue"
|
|
19
|
-
import { BaseProps, deepMerge, defaultsValueFromSchema, DefaultTypeProps, FieldPath, type FormProps, generateMetaFromSchema, type MetaRecord, type NestedKeyOf, OmegaArrayProps, OmegaAutoGenMeta, OmegaError, type OmegaFormApi, OmegaFormState } from "./OmegaFormStuff"
|
|
20
16
|
import OmegaInput from "./OmegaInput.vue"
|
|
21
17
|
import OmegaTaggedUnion from "./OmegaTaggedUnion.vue"
|
|
22
18
|
import OmegaForm from "./OmegaWrapper.vue"
|
|
19
|
+
import { usePersistency } from "./persistency"
|
|
20
|
+
import { makeSubmitHandlers, wrapOnSubmit } from "./submit"
|
|
21
|
+
import type { FormProps, OF, OmegaConfig, OmegaFormApi, OmegaFormReturn, TypePropsFor } from "./types"
|
|
22
|
+
import { annotateLiteralUnionMessages, toLocalizedStandardSchemaV1 } from "./validation/localized"
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
keys?: NestedKeyOf<T>[]
|
|
27
|
-
banKeys?: "You should only use one of banKeys or keys, not both, moron"
|
|
28
|
-
}
|
|
29
|
-
| {
|
|
30
|
-
keys?: "You should only use one of banKeys or keys, not both, moron"
|
|
31
|
-
banKeys?: NestedKeyOf<T>[]
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export class FormErrors<From> extends Data.TaggedError("FormErrors")<{
|
|
35
|
-
form: {
|
|
36
|
-
// TODO: error shapes seem off, with `undefined` etc..
|
|
37
|
-
errors: (Record<string, StandardSchemaV1Issue[]> | undefined)[]
|
|
38
|
-
errorMap: ValidationErrorMap<
|
|
39
|
-
undefined,
|
|
40
|
-
undefined,
|
|
41
|
-
Record<string, StandardSchemaV1Issue[]>,
|
|
42
|
-
undefined,
|
|
43
|
-
undefined,
|
|
44
|
-
undefined,
|
|
45
|
-
undefined,
|
|
46
|
-
undefined,
|
|
47
|
-
undefined,
|
|
48
|
-
undefined
|
|
49
|
-
>
|
|
50
|
-
}
|
|
51
|
-
fields: Record<DeepKeys<From>, {
|
|
52
|
-
errors: ValidationError[]
|
|
53
|
-
errorMap: ValidationErrorMap
|
|
54
|
-
}>
|
|
55
|
-
}> {}
|
|
56
|
-
|
|
57
|
-
const fHoc = (form: OF<any, any>) => {
|
|
58
|
-
return function FormHoc<P>(
|
|
59
|
-
WrappedComponent: Component<P>
|
|
60
|
-
): ConcreteComponent<P> {
|
|
61
|
-
return {
|
|
62
|
-
render() {
|
|
63
|
-
return h(WrappedComponent, {
|
|
64
|
-
form,
|
|
65
|
-
...this.$attrs
|
|
66
|
-
} as any, this.$slots)
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export const useErrorLabel = (form: OF<any, any>) => {
|
|
73
|
-
const { formatMessage } = useIntl()
|
|
74
|
-
const humanize = (str: string) => {
|
|
75
|
-
return str
|
|
76
|
-
.replace(/([A-Z])/g, " $1") // Add space before capital letters
|
|
77
|
-
.replace(/^./, (char) => char.toUpperCase()) // Capitalize the first letter
|
|
78
|
-
.trim() // Remove leading/trailing spaces
|
|
79
|
-
}
|
|
80
|
-
const fallback = (propsName: string) =>
|
|
81
|
-
formatMessage
|
|
82
|
-
? formatMessage({ id: `general.fields.${propsName}`, defaultMessage: humanize(propsName) })
|
|
83
|
-
: humanize(propsName)
|
|
84
|
-
const i18n = (propsName: string) =>
|
|
85
|
-
form.i18nNamespace
|
|
86
|
-
? formatMessage({ id: `${form.i18nNamespace}.fields.${propsName}`, defaultMessage: fallback(propsName) })
|
|
87
|
-
: fallback(propsName)
|
|
88
|
-
|
|
89
|
-
return i18n
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const eHoc = (errorProps: {
|
|
93
|
-
form: OF<any, any>
|
|
94
|
-
fieldMap: Ref<Map<string, { id: string; label: string }>>
|
|
95
|
-
}) => {
|
|
96
|
-
return function FormHoc<P>(
|
|
97
|
-
WrappedComponent: Component<P>
|
|
98
|
-
): ConcreteComponent<P> {
|
|
99
|
-
return {
|
|
100
|
-
setup() {
|
|
101
|
-
const { fieldMap, form } = errorProps
|
|
102
|
-
const generalErrors = form.useStore((state) => state.errors)
|
|
103
|
-
const fieldMeta = form.useStore((state) => state.fieldMeta)
|
|
104
|
-
const errorMap = form.useStore((state) => state.errorMap)
|
|
105
|
-
|
|
106
|
-
const errorLabel = useErrorLabel(form)
|
|
107
|
-
|
|
108
|
-
const errors = computed(() => {
|
|
109
|
-
// Collect errors from fieldMeta (field-level errors for registered fields)
|
|
110
|
-
const fieldErrors = Object
|
|
111
|
-
.entries(fieldMeta.value)
|
|
112
|
-
.reduce<OmegaError[]>((acc, [key, m]) => {
|
|
113
|
-
const fieldErrors = (m as { errors?: Array<{ message?: string }> } | undefined)?.errors ?? []
|
|
114
|
-
if (!fieldErrors.length) {
|
|
115
|
-
return acc
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const fieldInfo = fieldMap.value.get(key)
|
|
119
|
-
if (!fieldInfo) {
|
|
120
|
-
return acc
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
acc.push({
|
|
124
|
-
label: fieldInfo.label,
|
|
125
|
-
inputId: fieldInfo.id,
|
|
126
|
-
errors: [fieldErrors[0]?.message].filter(Boolean) as string[]
|
|
127
|
-
})
|
|
128
|
-
return acc
|
|
129
|
-
}, [])
|
|
130
|
-
|
|
131
|
-
// Collect errors from errorMap.onSubmit ONLY for fields that are NOT registered
|
|
132
|
-
// (registered fields already have their errors in fieldMeta)
|
|
133
|
-
const submitErrors: OmegaError[] = []
|
|
134
|
-
if (errorMap.value.onSubmit) {
|
|
135
|
-
for (const [_, issues] of Object.entries(errorMap.value.onSubmit)) {
|
|
136
|
-
if (Array.isArray(issues) && issues.length) {
|
|
137
|
-
for (const issue of issues) {
|
|
138
|
-
const issAny: any = issue
|
|
139
|
-
if (issAny?.path && Array.isArray(issAny.path) && issAny.path.length) {
|
|
140
|
-
// Use the path from the issue to identify the field
|
|
141
|
-
const fieldPath = issAny.path.join(".")
|
|
142
|
-
// Only add errors for fields that are NOT registered (not in fieldMap)
|
|
143
|
-
// Registered fields will already have their errors from fieldMeta
|
|
144
|
-
if (!fieldMap.value.has(fieldPath)) {
|
|
145
|
-
submitErrors.push({
|
|
146
|
-
label: errorLabel(fieldPath),
|
|
147
|
-
inputId: fieldPath,
|
|
148
|
-
errors: [issAny.message].filter(Boolean)
|
|
149
|
-
})
|
|
150
|
-
// Only show first error per field, so break after adding
|
|
151
|
-
break
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Combine both error sources (no need to check for duplicates since they're mutually exclusive)
|
|
160
|
-
return [...fieldErrors, ...submitErrors]
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
return {
|
|
164
|
-
generalErrors,
|
|
165
|
-
errors
|
|
166
|
-
}
|
|
167
|
-
},
|
|
168
|
-
render({ errors, generalErrors }: any) {
|
|
169
|
-
return h(WrappedComponent, {
|
|
170
|
-
errors,
|
|
171
|
-
generalErrors,
|
|
172
|
-
...this.$attrs
|
|
173
|
-
} as any, this.$slots)
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
export type Policies = "local" | "session" | "querystring"
|
|
180
|
-
export type defaultValuesPriorityUnion = "tanstack" | "persistency" | "schema"
|
|
181
|
-
|
|
182
|
-
const includesPolicy = (arr: Policies[], policy: Policies) => {
|
|
183
|
-
return arr.includes(policy)
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
export type OmegaConfig<T> = {
|
|
187
|
-
i18nNamespace?: string
|
|
188
|
-
|
|
189
|
-
persistency?: {
|
|
190
|
-
/** Order of importance:
|
|
191
|
-
* - "querystring": Highest priority when persisting
|
|
192
|
-
* - "local" and then "session": Lower priority storage options
|
|
193
|
-
*/
|
|
194
|
-
policies?: UnionToTuples<Policies>
|
|
195
|
-
overrideDefaultValues?: "deprecated: use defaultValuesPriority"
|
|
196
|
-
id?: string
|
|
197
|
-
} & keysRule<T>
|
|
198
|
-
|
|
199
|
-
ignorePreventCloseEvents?: boolean
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Prevents browser window/tab exit when form has unsaved changes.
|
|
203
|
-
* Shows native browser "Leave site?" dialog.
|
|
204
|
-
*
|
|
205
|
-
* @remarks
|
|
206
|
-
* - Opt-in only: Must explicitly enable
|
|
207
|
-
* - Independent from data persistence feature
|
|
208
|
-
*/
|
|
209
|
-
preventWindowExit?: "prevent" | "prevent-and-reset" | "nope"
|
|
210
|
-
|
|
211
|
-
input?: any
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Default values order is: Tanstack default values passed as second parameter to useOmegaForm, then persistency
|
|
215
|
-
* default values from querystring or local/session storage, then defaults from schema
|
|
216
|
-
* You can customize the order and with omegaConfig.defaultValuesPriority
|
|
217
|
-
* default value = ['tanstack', 'persistency', 'schema']
|
|
218
|
-
*/
|
|
219
|
-
defaultValuesPriority?: UnionToTuples<defaultValuesPriorityUnion>
|
|
220
|
-
|
|
221
|
-
defaultFromSchema?: "deprecated: use defaultValuesPriority"
|
|
222
|
-
}
|
|
24
|
+
import { makeRunPromise } from "@effect-app/vue/runtime"
|
|
25
|
+
import { useIntl } from "../../utils"
|
|
223
26
|
|
|
224
|
-
export
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
clear: () => void
|
|
228
|
-
i18nNamespace?: string
|
|
229
|
-
ignorePreventCloseEvents?: boolean
|
|
230
|
-
registerField: (
|
|
231
|
-
field: ComputedRef<{
|
|
232
|
-
name: string
|
|
233
|
-
label: string
|
|
234
|
-
id: string
|
|
235
|
-
}>
|
|
236
|
-
) => void
|
|
237
|
-
/** @experimental */
|
|
238
|
-
handleSubmitEffect: {
|
|
239
|
-
/**
|
|
240
|
-
* when `checkErrors` is true, the Effect will fail with `FormErrors<From>` when there are validation errors
|
|
241
|
-
* @experimental */
|
|
242
|
-
(options: { checkErrors: true; meta?: Record<string, any> }): Effect.Effect<void, FormErrors<From>>
|
|
243
|
-
/** @experimental */
|
|
244
|
-
(options?: { meta?: Record<string, any> }): Effect.Effect<void>
|
|
245
|
-
}
|
|
246
|
-
}
|
|
27
|
+
export { useErrorLabel } from "./errors"
|
|
28
|
+
export { FormErrors } from "./submit"
|
|
29
|
+
export type { defaultValuesPriorityUnion, OF, OmegaConfig, OmegaFormReturn, Policies } from "./types"
|
|
247
30
|
|
|
248
31
|
export const OmegaFormKey = Symbol("OmegaForm") as InjectionKey<OF<any, any>>
|
|
249
32
|
|
|
250
|
-
|
|
251
|
-
& {
|
|
252
|
-
[K in keyof T]: T[K]
|
|
253
|
-
}
|
|
254
|
-
& {}
|
|
255
|
-
|
|
256
|
-
// Type aliases for Array component slots - using cached types for performance
|
|
257
|
-
type CachedFieldApi<From, To, TypeProps = DefaultTypeProps> = import("@tanstack/vue-form").FieldApi<
|
|
258
|
-
From,
|
|
259
|
-
OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
260
|
-
DeepValue<From, OmegaFormReturn<From, To, TypeProps>["_keys"]>,
|
|
261
|
-
| import("@tanstack/vue-form").FieldValidateOrFn<
|
|
262
|
-
From,
|
|
263
|
-
OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
264
|
-
DeepValue<From, OmegaFormReturn<From, To, TypeProps>["_keys"]>
|
|
265
|
-
>
|
|
266
|
-
| undefined,
|
|
267
|
-
| import("@tanstack/vue-form").FieldValidateOrFn<
|
|
268
|
-
From,
|
|
269
|
-
OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
270
|
-
DeepValue<From, OmegaFormReturn<From, To, TypeProps>["_keys"]>
|
|
271
|
-
>
|
|
272
|
-
| undefined,
|
|
273
|
-
| import("@tanstack/vue-form").FieldAsyncValidateOrFn<
|
|
274
|
-
From,
|
|
275
|
-
OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
276
|
-
DeepValue<From, OmegaFormReturn<From, To, TypeProps>["_keys"]>
|
|
277
|
-
>
|
|
278
|
-
| undefined,
|
|
279
|
-
| import("@tanstack/vue-form").FieldValidateOrFn<
|
|
280
|
-
From,
|
|
281
|
-
OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
282
|
-
DeepValue<From, OmegaFormReturn<From, To, TypeProps>["_keys"]>
|
|
283
|
-
>
|
|
284
|
-
| undefined,
|
|
285
|
-
| import("@tanstack/vue-form").FieldAsyncValidateOrFn<
|
|
286
|
-
From,
|
|
287
|
-
OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
288
|
-
DeepValue<From, OmegaFormReturn<From, To, TypeProps>["_keys"]>
|
|
289
|
-
>
|
|
290
|
-
| undefined,
|
|
291
|
-
| import("@tanstack/vue-form").FieldValidateOrFn<
|
|
292
|
-
From,
|
|
293
|
-
OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
294
|
-
DeepValue<From, OmegaFormReturn<From, To, TypeProps>["_keys"]>
|
|
295
|
-
>
|
|
296
|
-
| undefined,
|
|
297
|
-
| import("@tanstack/vue-form").FieldAsyncValidateOrFn<
|
|
298
|
-
From,
|
|
299
|
-
OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
300
|
-
DeepValue<From, OmegaFormReturn<From, To, TypeProps>["_keys"]>
|
|
301
|
-
>
|
|
302
|
-
| undefined,
|
|
303
|
-
| import("@tanstack/vue-form").FieldValidateOrFn<
|
|
304
|
-
From,
|
|
305
|
-
OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
306
|
-
DeepValue<From, OmegaFormReturn<From, To, TypeProps>["_keys"]>
|
|
307
|
-
>
|
|
308
|
-
| undefined,
|
|
309
|
-
| import("@tanstack/vue-form").FieldAsyncValidateOrFn<
|
|
310
|
-
From,
|
|
311
|
-
OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
312
|
-
DeepValue<From, OmegaFormReturn<From, To, TypeProps>["_keys"]>
|
|
313
|
-
>
|
|
314
|
-
| undefined,
|
|
315
|
-
import("@tanstack/vue-form").FormValidateOrFn<From> | undefined,
|
|
316
|
-
import("@tanstack/vue-form").FormValidateOrFn<From> | undefined,
|
|
317
|
-
import("@tanstack/vue-form").StandardSchemaV1<From, To>,
|
|
318
|
-
import("@tanstack/vue-form").FormValidateOrFn<From> | undefined,
|
|
319
|
-
import("@tanstack/vue-form").FormAsyncValidateOrFn<From> | undefined,
|
|
320
|
-
import("@tanstack/vue-form").FormValidateOrFn<From> | undefined,
|
|
321
|
-
import("@tanstack/vue-form").FormAsyncValidateOrFn<From> | undefined,
|
|
322
|
-
import("@tanstack/vue-form").FormValidateOrFn<From> | undefined,
|
|
323
|
-
import("@tanstack/vue-form").FormAsyncValidateOrFn<From> | undefined,
|
|
324
|
-
import("@tanstack/vue-form").FormAsyncValidateOrFn<From> | undefined,
|
|
325
|
-
Record<string, any> | undefined
|
|
326
|
-
>
|
|
327
|
-
|
|
328
|
-
type CachedFieldState<From, To, TypeProps = DefaultTypeProps> = import("@tanstack/vue-form").FieldState<
|
|
329
|
-
From,
|
|
330
|
-
OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
331
|
-
DeepValue<From, OmegaFormReturn<From, To, TypeProps>["_keys"]>,
|
|
332
|
-
| import("@tanstack/vue-form").FieldValidateOrFn<
|
|
333
|
-
From,
|
|
334
|
-
OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
335
|
-
DeepValue<From, OmegaFormReturn<From, To, TypeProps>["_keys"]>
|
|
336
|
-
>
|
|
337
|
-
| undefined,
|
|
338
|
-
| import("@tanstack/vue-form").FieldValidateOrFn<
|
|
339
|
-
From,
|
|
340
|
-
OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
341
|
-
DeepValue<From, OmegaFormReturn<From, To, TypeProps>["_keys"]>
|
|
342
|
-
>
|
|
343
|
-
| undefined,
|
|
344
|
-
| import("@tanstack/vue-form").FieldAsyncValidateOrFn<
|
|
345
|
-
From,
|
|
346
|
-
OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
347
|
-
DeepValue<From, OmegaFormReturn<From, To, TypeProps>["_keys"]>
|
|
348
|
-
>
|
|
349
|
-
| undefined,
|
|
350
|
-
| import("@tanstack/vue-form").FieldValidateOrFn<
|
|
351
|
-
From,
|
|
352
|
-
OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
353
|
-
DeepValue<From, OmegaFormReturn<From, To, TypeProps>["_keys"]>
|
|
354
|
-
>
|
|
355
|
-
| undefined,
|
|
356
|
-
| import("@tanstack/vue-form").FieldAsyncValidateOrFn<
|
|
357
|
-
From,
|
|
358
|
-
OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
359
|
-
DeepValue<From, OmegaFormReturn<From, To, TypeProps>["_keys"]>
|
|
360
|
-
>
|
|
361
|
-
| undefined,
|
|
362
|
-
| import("@tanstack/vue-form").FieldValidateOrFn<
|
|
363
|
-
From,
|
|
364
|
-
OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
365
|
-
DeepValue<From, OmegaFormReturn<From, To, TypeProps>["_keys"]>
|
|
366
|
-
>
|
|
367
|
-
| undefined,
|
|
368
|
-
| import("@tanstack/vue-form").FieldAsyncValidateOrFn<
|
|
369
|
-
From,
|
|
370
|
-
OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
371
|
-
DeepValue<From, OmegaFormReturn<From, To, TypeProps>["_keys"]>
|
|
372
|
-
>
|
|
373
|
-
| undefined,
|
|
374
|
-
| import("@tanstack/vue-form").FieldValidateOrFn<
|
|
375
|
-
From,
|
|
376
|
-
OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
377
|
-
DeepValue<From, OmegaFormReturn<From, To, TypeProps>["_keys"]>
|
|
378
|
-
>
|
|
379
|
-
| undefined,
|
|
380
|
-
| import("@tanstack/vue-form").FieldAsyncValidateOrFn<
|
|
381
|
-
From,
|
|
382
|
-
OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
383
|
-
DeepValue<From, OmegaFormReturn<From, To, TypeProps>["_keys"]>
|
|
384
|
-
>
|
|
385
|
-
| undefined,
|
|
386
|
-
import("@tanstack/vue-form").FormValidateOrFn<From> | undefined,
|
|
387
|
-
import("@tanstack/vue-form").FormValidateOrFn<From> | undefined,
|
|
388
|
-
import("@tanstack/vue-form").StandardSchemaV1<From, To>,
|
|
389
|
-
import("@tanstack/vue-form").FormValidateOrFn<From> | undefined,
|
|
390
|
-
import("@tanstack/vue-form").FormAsyncValidateOrFn<From> | undefined,
|
|
391
|
-
import("@tanstack/vue-form").FormValidateOrFn<From> | undefined,
|
|
392
|
-
import("@tanstack/vue-form").FormAsyncValidateOrFn<From> | undefined,
|
|
393
|
-
import("@tanstack/vue-form").FormValidateOrFn<From> | undefined,
|
|
394
|
-
import("@tanstack/vue-form").FormAsyncValidateOrFn<From> | undefined
|
|
395
|
-
>
|
|
396
|
-
|
|
397
|
-
export interface OmegaFormReturn<
|
|
398
|
-
From extends Record<PropertyKey, any>,
|
|
399
|
-
To extends Record<PropertyKey, any>,
|
|
400
|
-
TypeProps = DefaultTypeProps
|
|
401
|
-
> extends OF<From, To> {
|
|
402
|
-
// Pre-computed type aliases - computed ONCE for performance
|
|
403
|
-
_paths: FieldPath<From>
|
|
404
|
-
_keys: DeepKeys<From>
|
|
405
|
-
_schema: S.Codec<To, From, never>
|
|
406
|
-
|
|
407
|
-
// this crazy thing here is copied from the OmegaFormInput.vue.d.ts, with `From` removed as Generic, instead closed over from the From generic above..
|
|
408
|
-
Input: <Name extends OmegaFormReturn<From, To, TypeProps>["_paths"]>(
|
|
409
|
-
__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"],
|
|
410
|
-
__VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>,
|
|
411
|
-
__VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"],
|
|
412
|
-
__VLS_setup?: Promise<{
|
|
413
|
-
props:
|
|
414
|
-
& __VLS_PrettifyLocal<
|
|
415
|
-
& Pick<
|
|
416
|
-
& Partial<{}>
|
|
417
|
-
& Omit<
|
|
418
|
-
{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps,
|
|
419
|
-
never
|
|
420
|
-
>,
|
|
421
|
-
never
|
|
422
|
-
>
|
|
423
|
-
& TypeProps
|
|
424
|
-
& Partial<{}>
|
|
425
|
-
>
|
|
426
|
-
& BaseProps<From, Name>
|
|
427
|
-
& import("vue").PublicProps
|
|
428
|
-
expose(exposed: import("vue").ShallowUnwrapRef<{}>): void
|
|
429
|
-
attrs: any
|
|
430
|
-
slots: {
|
|
431
|
-
default?(props: MergedInputProps<From, Name>): void
|
|
432
|
-
label?: (props: { required: boolean; id: string; label: string }) => void
|
|
433
|
-
}
|
|
434
|
-
emit: {}
|
|
435
|
-
}>
|
|
436
|
-
) => import("vue").VNode & {
|
|
437
|
-
__ctx?: Awaited<typeof __VLS_setup>
|
|
438
|
-
}
|
|
439
|
-
Errors: (
|
|
440
|
-
__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"],
|
|
441
|
-
__VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>,
|
|
442
|
-
__VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"],
|
|
443
|
-
__VLS_setup?: Promise<{
|
|
444
|
-
props:
|
|
445
|
-
& __VLS_PrettifyLocal<
|
|
446
|
-
& Pick<
|
|
447
|
-
& Partial<{}>
|
|
448
|
-
& Omit<
|
|
449
|
-
{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps,
|
|
450
|
-
never
|
|
451
|
-
>,
|
|
452
|
-
never
|
|
453
|
-
>
|
|
454
|
-
& Partial<{}>
|
|
455
|
-
>
|
|
456
|
-
& import("vue").PublicProps
|
|
457
|
-
expose(exposed: import("vue").ShallowUnwrapRef<{}>): void
|
|
458
|
-
attrs: any
|
|
459
|
-
slots: {
|
|
460
|
-
default: (props: { errors: readonly OmegaError[]; showedGeneralErrors: string[] }) => void
|
|
461
|
-
}
|
|
462
|
-
emit: {}
|
|
463
|
-
}>
|
|
464
|
-
) => import("vue").VNode & {
|
|
465
|
-
__ctx?: Awaited<typeof __VLS_setup>
|
|
466
|
-
}
|
|
467
|
-
TaggedUnion: <Name extends OmegaFormReturn<From, To, TypeProps>["_keys"]>(
|
|
468
|
-
__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"],
|
|
469
|
-
__VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>,
|
|
470
|
-
__VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"],
|
|
471
|
-
__VLS_setup?: Promise<{
|
|
472
|
-
props:
|
|
473
|
-
& __VLS_PrettifyLocal<
|
|
474
|
-
& Pick<
|
|
475
|
-
& Partial<{}>
|
|
476
|
-
& Omit<
|
|
477
|
-
{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps,
|
|
478
|
-
never
|
|
479
|
-
>,
|
|
480
|
-
never
|
|
481
|
-
>
|
|
482
|
-
& {
|
|
483
|
-
name?: Name
|
|
484
|
-
type?: "select" | "radio"
|
|
485
|
-
options: import("./InputProps").TaggedUnionOptionsArray<From, Name>
|
|
486
|
-
_debugName?: [NoInfer<Name>]
|
|
487
|
-
label?: string
|
|
488
|
-
}
|
|
489
|
-
& {}
|
|
490
|
-
>
|
|
491
|
-
& import("vue").PublicProps
|
|
492
|
-
expose(exposed: import("vue").ShallowUnwrapRef<{}>): void
|
|
493
|
-
attrs: any
|
|
494
|
-
slots: Record<
|
|
495
|
-
string,
|
|
496
|
-
(props: {
|
|
497
|
-
field: import("@tanstack/vue-form").FieldApi<
|
|
498
|
-
From,
|
|
499
|
-
Name,
|
|
500
|
-
DeepValue<From, Name>,
|
|
501
|
-
any,
|
|
502
|
-
any,
|
|
503
|
-
any,
|
|
504
|
-
any,
|
|
505
|
-
any,
|
|
506
|
-
any,
|
|
507
|
-
any,
|
|
508
|
-
any,
|
|
509
|
-
any,
|
|
510
|
-
any,
|
|
511
|
-
any,
|
|
512
|
-
any,
|
|
513
|
-
any,
|
|
514
|
-
any,
|
|
515
|
-
any,
|
|
516
|
-
any,
|
|
517
|
-
any,
|
|
518
|
-
any,
|
|
519
|
-
any,
|
|
520
|
-
any
|
|
521
|
-
>
|
|
522
|
-
state: import("@tanstack/vue-form").FieldState<
|
|
523
|
-
From,
|
|
524
|
-
Name,
|
|
525
|
-
DeepValue<From, Name>,
|
|
526
|
-
any,
|
|
527
|
-
any,
|
|
528
|
-
any,
|
|
529
|
-
any,
|
|
530
|
-
any,
|
|
531
|
-
any,
|
|
532
|
-
any,
|
|
533
|
-
any,
|
|
534
|
-
any,
|
|
535
|
-
any,
|
|
536
|
-
any,
|
|
537
|
-
any,
|
|
538
|
-
any,
|
|
539
|
-
any,
|
|
540
|
-
any,
|
|
541
|
-
any,
|
|
542
|
-
any,
|
|
543
|
-
any
|
|
544
|
-
>
|
|
545
|
-
}) => any
|
|
546
|
-
>
|
|
547
|
-
emit: {}
|
|
548
|
-
}>
|
|
549
|
-
) => import("vue").VNode & {
|
|
550
|
-
__ctx?: Awaited<typeof __VLS_setup>
|
|
551
|
-
}
|
|
552
|
-
Array: <Name extends OmegaFormReturn<From, To, TypeProps>["_keys"]>(
|
|
553
|
-
__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"],
|
|
554
|
-
__VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>,
|
|
555
|
-
__VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"],
|
|
556
|
-
__VLS_setup?: Promise<{
|
|
557
|
-
props:
|
|
558
|
-
& __VLS_PrettifyLocal<
|
|
559
|
-
& Pick<
|
|
560
|
-
& Partial<{}>
|
|
561
|
-
& Omit<
|
|
562
|
-
{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps,
|
|
563
|
-
never
|
|
564
|
-
>,
|
|
565
|
-
never
|
|
566
|
-
>
|
|
567
|
-
& (Omit<OmegaArrayProps<From, To, Name>, "form">)
|
|
568
|
-
& {}
|
|
569
|
-
>
|
|
570
|
-
& import("vue").PublicProps
|
|
571
|
-
expose(exposed: import("vue").ShallowUnwrapRef<{}>): void
|
|
572
|
-
attrs: any
|
|
573
|
-
slots: {
|
|
574
|
-
"pre-array"?: (props: {
|
|
575
|
-
field: CachedFieldApi<From, To, TypeProps>
|
|
576
|
-
state: CachedFieldState<From, To, TypeProps>
|
|
577
|
-
}) => any
|
|
578
|
-
} & {
|
|
579
|
-
default?: (props: {
|
|
580
|
-
subField: CachedFieldApi<From, To, TypeProps>
|
|
581
|
-
subState: CachedFieldState<From, To, TypeProps>
|
|
582
|
-
index: number
|
|
583
|
-
field: CachedFieldApi<From, To, TypeProps>
|
|
584
|
-
}) => any
|
|
585
|
-
} & {
|
|
586
|
-
"post-array"?: (props: {
|
|
587
|
-
field: CachedFieldApi<From, To, TypeProps>
|
|
588
|
-
state: CachedFieldState<From, To, TypeProps>
|
|
589
|
-
}) => any
|
|
590
|
-
} & {
|
|
591
|
-
field?: (props: {
|
|
592
|
-
field: CachedFieldApi<From, To, TypeProps>
|
|
593
|
-
}) => any
|
|
594
|
-
}
|
|
595
|
-
emit: {}
|
|
596
|
-
}>
|
|
597
|
-
) => import("vue").VNode & {
|
|
598
|
-
__ctx?: Awaited<typeof __VLS_setup>
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
AutoGen: <Name extends OmegaFormReturn<From, To, TypeProps>["_keys"]>(
|
|
602
|
-
__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"],
|
|
603
|
-
__VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>,
|
|
604
|
-
__VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"],
|
|
605
|
-
__VLS_setup?: Promise<{
|
|
606
|
-
props:
|
|
607
|
-
& __VLS_PrettifyLocal<
|
|
608
|
-
Pick<
|
|
609
|
-
& Partial<{}>
|
|
610
|
-
& Omit<
|
|
611
|
-
{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps,
|
|
612
|
-
never
|
|
613
|
-
>,
|
|
614
|
-
never
|
|
615
|
-
> & {
|
|
616
|
-
// form: OmegaInputProps<From, To>["form"]
|
|
617
|
-
pick?: OmegaFormReturn<From, To, TypeProps>["_keys"][]
|
|
618
|
-
omit?: OmegaFormReturn<From, To, TypeProps>["_keys"][]
|
|
619
|
-
labelMap?: (key: OmegaFormReturn<From, To, TypeProps>["_keys"]) => string | undefined
|
|
620
|
-
filterMap?: <M extends OmegaAutoGenMeta<From, To, Name>>(
|
|
621
|
-
key: OmegaFormReturn<From, To, TypeProps>["_keys"],
|
|
622
|
-
meta: M
|
|
623
|
-
) => boolean | M
|
|
624
|
-
order?: OmegaFormReturn<From, To, TypeProps>["_keys"][]
|
|
625
|
-
sort?: Order.Order<OmegaAutoGenMeta<From, To, Name>>
|
|
626
|
-
} & {}
|
|
627
|
-
>
|
|
628
|
-
& import("vue").PublicProps
|
|
629
|
-
expose(exposed: import("vue").ShallowUnwrapRef<{}>): void
|
|
630
|
-
attrs: any
|
|
631
|
-
slots: {
|
|
632
|
-
default(props: {
|
|
633
|
-
child: OmegaAutoGenMeta<From, To, Name>
|
|
634
|
-
}): void
|
|
635
|
-
}
|
|
636
|
-
emit: {}
|
|
637
|
-
}>
|
|
638
|
-
) => import("vue").VNode & {
|
|
639
|
-
__ctx?: Awaited<typeof __VLS_setup>
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
Form: <K extends keyof OmegaFormState<To, From>>(
|
|
643
|
-
__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"],
|
|
644
|
-
__VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>,
|
|
645
|
-
__VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"],
|
|
646
|
-
__VLS_setup?: Promise<{
|
|
647
|
-
props:
|
|
648
|
-
& __VLS_PrettifyLocal<
|
|
649
|
-
Pick<
|
|
650
|
-
& Partial<{}>
|
|
651
|
-
& Omit<
|
|
652
|
-
{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps,
|
|
653
|
-
never
|
|
654
|
-
>,
|
|
655
|
-
never
|
|
656
|
-
> & {
|
|
657
|
-
// form: OmegaFormReturn<From, To, Props>
|
|
658
|
-
disabled?: boolean
|
|
659
|
-
subscribe?: K[]
|
|
660
|
-
} & {}
|
|
661
|
-
>
|
|
662
|
-
& import("vue").PublicProps
|
|
663
|
-
expose(exposed: import("vue").ShallowUnwrapRef<{}>): void
|
|
664
|
-
attrs: any
|
|
665
|
-
slots: {
|
|
666
|
-
default(props: {
|
|
667
|
-
subscribedValues: K[] extends undefined[] ? Record<string, never> : Pick<OmegaFormState<From, To>, K>
|
|
668
|
-
}): void
|
|
669
|
-
}
|
|
670
|
-
emit: {}
|
|
671
|
-
}>
|
|
672
|
-
) => import("vue").VNode & {
|
|
673
|
-
__ctx?: Awaited<typeof __VLS_setup>
|
|
674
|
-
}
|
|
675
|
-
}
|
|
33
|
+
const runPromise = makeRunPromise(Context.empty())
|
|
676
34
|
|
|
677
35
|
export const useOmegaForm = <
|
|
678
36
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
679
37
|
From extends Record<PropertyKey, any>,
|
|
680
38
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
681
39
|
To extends Record<PropertyKey, any>,
|
|
682
|
-
|
|
40
|
+
const Cfg extends OmegaConfig<To> = OmegaConfig<To>
|
|
683
41
|
>(
|
|
684
|
-
schema: S.Codec<To, From
|
|
42
|
+
schema: S.Codec<To, From>,
|
|
685
43
|
tanstackFormOptions?: NoInfer<FormProps<From, To>>,
|
|
686
|
-
omegaConfig?:
|
|
687
|
-
): OmegaFormReturn<From, To,
|
|
44
|
+
omegaConfig?: Cfg
|
|
45
|
+
): OmegaFormReturn<From, To, TypePropsFor<Cfg extends { inputs?: infer I } ? I : {}>> => {
|
|
688
46
|
if (!schema) throw new Error("Schema is required")
|
|
689
|
-
const
|
|
690
|
-
const
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
const
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
console.error(error)
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
if (persistency?.policies && includesPolicy(persistency.policies, "querystring")) {
|
|
740
|
-
try {
|
|
741
|
-
const params = new URLSearchParams(window.location.search)
|
|
742
|
-
const value = params.get(persistencyKey.value)
|
|
743
|
-
clearUrlParams()
|
|
744
|
-
if (value) {
|
|
745
|
-
persistencyDefaultValues = deepMerge(persistencyDefaultValues || {}, JSON.parse(value))
|
|
746
|
-
}
|
|
747
|
-
} catch (error) {
|
|
748
|
-
console.error(error)
|
|
749
|
-
}
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
// to be sure we have a valid object at the end of the gathering process
|
|
753
|
-
persistencyDefaultValues ??= {}
|
|
754
|
-
|
|
755
|
-
const defaults: Record<defaultValuesPriorityUnion, any> = {
|
|
756
|
-
tanstack: tanstackFormOptions?.defaultValues || {},
|
|
757
|
-
persistency: persistencyDefaultValues,
|
|
758
|
-
schema: defaultsValueFromSchema(schema)
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
return (omegaConfig?.defaultValuesPriority || ["tanstack", "persistency", "schema"] as const).reverse().reduce(
|
|
762
|
-
(acc, m) => {
|
|
763
|
-
if (!Object.keys(acc).length) {
|
|
764
|
-
return defaults[m]
|
|
765
|
-
}
|
|
766
|
-
return deepMerge(acc, defaults[m])
|
|
767
|
-
},
|
|
768
|
-
{}
|
|
769
|
-
)
|
|
47
|
+
const { trans } = useIntl()
|
|
48
|
+
const formCompatibleSchema = toFormSchema(schema)
|
|
49
|
+
// Effect's Standard Schema formatter emits `Expected X | Y, got Z` for
|
|
50
|
+
// `AnyOf` issues without consulting our hooks. Pre-annotate literal-union
|
|
51
|
+
// (select) and literal-array (multiple) AST nodes with a localized
|
|
52
|
+
// `message` so the formatter picks them up via `findMessage`.
|
|
53
|
+
const localizedSchema = annotateLiteralUnionMessages(formCompatibleSchema, trans)
|
|
54
|
+
|
|
55
|
+
// A nullable struct (`S.NullOr(S.Struct(...))`) has no slot in the form
|
|
56
|
+
// value until a child is filled. Once it materialises, its untouched
|
|
57
|
+
// children are still `undefined` — which strict `S.NullOr(...)` children
|
|
58
|
+
// reject. Deep-fill those children with their defaults before both
|
|
59
|
+
// validation and decoding so they validate as `null` (or their default).
|
|
60
|
+
const formAst = unwrapDeclaration(formCompatibleSchema.ast)
|
|
61
|
+
const normalizeFormValue = (value: unknown) => fillNestedDefaults(formAst, value)
|
|
62
|
+
|
|
63
|
+
const baseStandardSchema = toLocalizedStandardSchemaV1(
|
|
64
|
+
localizedSchema,
|
|
65
|
+
trans
|
|
66
|
+
)
|
|
67
|
+
const standardSchema: typeof baseStandardSchema = {
|
|
68
|
+
...baseStandardSchema,
|
|
69
|
+
"~standard": {
|
|
70
|
+
...baseStandardSchema["~standard"],
|
|
71
|
+
validate: (value) => baseStandardSchema["~standard"].validate(normalizeFormValue(value))
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const baseDecode = S.decodeUnknownEffectConcurrently(formCompatibleSchema)
|
|
76
|
+
const decode = (value: From) => baseDecode(normalizeFormValue(value))
|
|
77
|
+
|
|
78
|
+
const { meta, unionMeta } = generateMetaFromSchema(formCompatibleSchema)
|
|
79
|
+
|
|
80
|
+
// Persistency must be created before `useForm` so its merged
|
|
81
|
+
// `defaultValues` (tanstack + storage/querystring + schema) can flow into
|
|
82
|
+
// the form. The `getForm` accessor is lazy because the form is constructed
|
|
83
|
+
// immediately after, and persistency's listeners only fire later.
|
|
84
|
+
const formHolder: { form: any } = { form: undefined }
|
|
85
|
+
const persistency = usePersistency<From>({
|
|
86
|
+
meta,
|
|
87
|
+
persistency: omegaConfig?.persistency,
|
|
88
|
+
preventWindowExit: omegaConfig?.preventWindowExit,
|
|
89
|
+
defaultValuesPriority: omegaConfig?.defaultValuesPriority,
|
|
90
|
+
tanstackDefaultValues: tanstackFormOptions?.defaultValues,
|
|
91
|
+
schemaDefaultValues: () => defaultsValueFromSchema(schema),
|
|
92
|
+
getForm: () => formHolder.form
|
|
770
93
|
})
|
|
771
94
|
|
|
772
|
-
const wrapWithSpan = (span: api.Span | undefined, toWrap: () => any) => {
|
|
773
|
-
return span ? api.context.with(api.trace.setSpan(api.context.active(), span), toWrap) : toWrap()
|
|
774
|
-
}
|
|
775
|
-
|
|
776
95
|
const form = useForm<
|
|
777
96
|
From,
|
|
778
97
|
FormValidateOrFn<From> | undefined,
|
|
@@ -788,31 +107,37 @@ export const useOmegaForm = <
|
|
|
788
107
|
Record<string, any> | undefined
|
|
789
108
|
>({
|
|
790
109
|
...tanstackFormOptions,
|
|
110
|
+
validationLogic: revalidateLogic(),
|
|
791
111
|
validators: {
|
|
792
|
-
|
|
793
|
-
|
|
112
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
113
|
+
onDynamic: standardSchema,
|
|
114
|
+
...tanstackFormOptions?.validators
|
|
794
115
|
},
|
|
795
|
-
onSubmit: tanstackFormOptions?.onSubmit
|
|
796
|
-
|
|
797
|
-
wrapWithSpan(meta?.currentSpan, async () => {
|
|
798
|
-
// validators only validate, they don't actually transform, so we have to do that manually here.
|
|
799
|
-
const parsedValue = await Effect.runPromise(decode(value))
|
|
800
|
-
const r = tanstackFormOptions.onSubmit!({
|
|
801
|
-
formApi: formApi as OmegaFormApi<From, To>,
|
|
802
|
-
meta,
|
|
803
|
-
value: parsedValue
|
|
804
|
-
})
|
|
805
|
-
if (Fiber.isFiber(r)) {
|
|
806
|
-
return await runtimeFiberAsPromise(r as any)
|
|
807
|
-
}
|
|
808
|
-
if (Effect.isEffect(r)) {
|
|
809
|
-
return await Effect.runPromise(r)
|
|
810
|
-
}
|
|
811
|
-
return r
|
|
812
|
-
})
|
|
813
|
-
: undefined,
|
|
814
|
-
defaultValues: defaultValues.value as any
|
|
116
|
+
onSubmit: wrapOnSubmit<From, To>(tanstackFormOptions?.onSubmit, decode, runPromise),
|
|
117
|
+
defaultValues: persistency.defaultValues.value
|
|
815
118
|
}) satisfies OmegaFormApi<To, From>
|
|
119
|
+
formHolder.form = form
|
|
120
|
+
|
|
121
|
+
// Keep the live form state consistent with the schema: when a nullable
|
|
122
|
+
// struct materialises (a child got a value), backfill its untouched
|
|
123
|
+
// children so `values` reflects what is validated and submitted. Called
|
|
124
|
+
// from the field change handler — the only point a struct can materialise.
|
|
125
|
+
const normalizeNullableStructs = () => {
|
|
126
|
+
const current = form.state.values
|
|
127
|
+
const filled = fillNestedDefaults(formAst, current)
|
|
128
|
+
if (filled === current || !filled || typeof filled !== "object") return
|
|
129
|
+
const currentRecord = current as Partial<Record<Extract<keyof From, string>, unknown>>
|
|
130
|
+
const filledRecord = filled as Partial<Record<Extract<keyof From, string>, unknown>>
|
|
131
|
+
for (const key of Object.keys(filledRecord) as Array<Extract<keyof From, string>>) {
|
|
132
|
+
if (filledRecord[key] !== currentRecord[key]) {
|
|
133
|
+
const field = key as DeepKeys<From>
|
|
134
|
+
form.setFieldValue(field, filledRecord[key] as DeepValue<From, typeof field>, {
|
|
135
|
+
dontUpdateMeta: true,
|
|
136
|
+
dontValidate: true
|
|
137
|
+
})
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
816
141
|
|
|
817
142
|
const clear = () => {
|
|
818
143
|
Object.keys(meta).forEach((key: any) => {
|
|
@@ -820,88 +145,6 @@ export const useOmegaForm = <
|
|
|
820
145
|
})
|
|
821
146
|
}
|
|
822
147
|
|
|
823
|
-
const createNestedObjectFromPaths = (paths: string[]) =>
|
|
824
|
-
paths.reduce((result, path) => {
|
|
825
|
-
const parts = path.split(".")
|
|
826
|
-
parts.reduce((acc, part, i) => {
|
|
827
|
-
if (i === parts.length - 1) {
|
|
828
|
-
acc[part] = form.getFieldValue(path as any)
|
|
829
|
-
} else {
|
|
830
|
-
acc[part] = acc[part] ?? {}
|
|
831
|
-
}
|
|
832
|
-
return acc[part]
|
|
833
|
-
}, result)
|
|
834
|
-
return result
|
|
835
|
-
}, {} as Record<string, any>)
|
|
836
|
-
|
|
837
|
-
const persistFilter = (persistency: OmegaConfig<From>["persistency"]) => {
|
|
838
|
-
if (!persistency) return
|
|
839
|
-
if (Array.isArray(persistency.keys)) {
|
|
840
|
-
return createNestedObjectFromPaths(persistency.keys)
|
|
841
|
-
}
|
|
842
|
-
if (Array.isArray(persistency.banKeys)) {
|
|
843
|
-
const subs = Object.keys(meta).filter((metakey) => persistency.banKeys?.includes(metakey as any))
|
|
844
|
-
return createNestedObjectFromPaths(subs)
|
|
845
|
-
}
|
|
846
|
-
return form.store.state.values
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
const persistData = () => {
|
|
850
|
-
const persistency = omegaConfig?.persistency
|
|
851
|
-
if (!persistency?.policies || persistency.policies.length === 0) {
|
|
852
|
-
return
|
|
853
|
-
}
|
|
854
|
-
if (
|
|
855
|
-
includesPolicy(persistency.policies, "local")
|
|
856
|
-
|| includesPolicy(persistency.policies, "session")
|
|
857
|
-
) {
|
|
858
|
-
const storage = includesPolicy(persistency.policies, "local")
|
|
859
|
-
? localStorage
|
|
860
|
-
: sessionStorage
|
|
861
|
-
if (!storage) return
|
|
862
|
-
const values = persistFilter(persistency)
|
|
863
|
-
return storage.setItem(persistencyKey.value, JSON.stringify(values))
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
|
|
867
|
-
const saveDataInUrl = () => {
|
|
868
|
-
const persistency = omegaConfig?.persistency
|
|
869
|
-
if (!persistency?.policies || persistency.policies.length === 0) {
|
|
870
|
-
return
|
|
871
|
-
}
|
|
872
|
-
if (includesPolicy(persistency.policies, "querystring")) {
|
|
873
|
-
const values = persistFilter(persistency)
|
|
874
|
-
const searchParams = new URLSearchParams(window.location.search)
|
|
875
|
-
searchParams.set(persistencyKey.value, JSON.stringify(values))
|
|
876
|
-
const url = new URL(window.location.href)
|
|
877
|
-
url.search = searchParams.toString()
|
|
878
|
-
window.history.replaceState({}, "", url.toString())
|
|
879
|
-
}
|
|
880
|
-
}
|
|
881
|
-
|
|
882
|
-
const preventWindowExit = (e: BeforeUnloadEvent) => {
|
|
883
|
-
if (form.store.state.isDirty) {
|
|
884
|
-
e.preventDefault()
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
|
-
|
|
888
|
-
onUnmounted(persistData)
|
|
889
|
-
|
|
890
|
-
onMounted(() => {
|
|
891
|
-
window.addEventListener("beforeunload", persistData)
|
|
892
|
-
window.addEventListener("blur", saveDataInUrl)
|
|
893
|
-
if (omegaConfig?.preventWindowExit && omegaConfig.preventWindowExit !== "nope") {
|
|
894
|
-
window.addEventListener("beforeunload", preventWindowExit)
|
|
895
|
-
}
|
|
896
|
-
})
|
|
897
|
-
onBeforeUnmount(() => {
|
|
898
|
-
window.removeEventListener("beforeunload", persistData)
|
|
899
|
-
window.removeEventListener("blur", saveDataInUrl)
|
|
900
|
-
if (omegaConfig?.preventWindowExit && omegaConfig.preventWindowExit !== "nope") {
|
|
901
|
-
window.removeEventListener("beforeunload", preventWindowExit)
|
|
902
|
-
}
|
|
903
|
-
})
|
|
904
|
-
|
|
905
148
|
// Watch for successful form submissions and auto-reset if prevent-and-reset is enabled
|
|
906
149
|
// We put it as a side effect, so we don't overwhelm submit handler and we can support
|
|
907
150
|
// effects submission more freely
|
|
@@ -920,60 +163,22 @@ export const useOmegaForm = <
|
|
|
920
163
|
})
|
|
921
164
|
}
|
|
922
165
|
|
|
923
|
-
const
|
|
924
|
-
Effect.currentSpan.pipe(
|
|
925
|
-
Effect.option,
|
|
926
|
-
Effect
|
|
927
|
-
.flatMap((span) =>
|
|
928
|
-
Effect.promise(() => form.handleSubmit(Option.isSome(span) ? { currentSpan: span.value, ...meta } : meta))
|
|
929
|
-
)
|
|
930
|
-
)
|
|
166
|
+
const { handleSubmit, handleSubmitEffect } = makeSubmitHandlers<From, To>(form)
|
|
931
167
|
|
|
932
|
-
const
|
|
933
|
-
(options: { checkErrors: true; meta?: Record<string, any> }): Effect.Effect<void, FormErrors<From>>
|
|
934
|
-
(options?: { meta?: Record<string, any> }): Effect.Effect<void>
|
|
935
|
-
} = (
|
|
936
|
-
options?: { meta?: Record<string, any>; checkErrors?: true }
|
|
937
|
-
): any =>
|
|
938
|
-
options?.checkErrors
|
|
939
|
-
? handleSubmitEffect_(options?.meta).pipe(Effect.flatMap(Effect.fnUntraced(function*() {
|
|
940
|
-
const errors = form.getAllErrors()
|
|
941
|
-
if (Object.keys(errors.fields).length || errors.form.errors.length) {
|
|
942
|
-
return yield* new FormErrors({ form: errors.form, fields: errors.fields })
|
|
943
|
-
}
|
|
944
|
-
})))
|
|
945
|
-
: handleSubmitEffect_(options?.meta)
|
|
946
|
-
|
|
947
|
-
const handleSubmit = form.handleSubmit
|
|
948
|
-
|
|
949
|
-
const fieldMap = ref(new Map<string, { label: string; id: string }>())
|
|
168
|
+
const { fieldMap, registerField } = makeFieldMap()
|
|
950
169
|
|
|
951
170
|
const formWithExtras: OF<From, To> = Object.assign(form, {
|
|
952
171
|
i18nNamespace: omegaConfig?.i18nNamespace,
|
|
953
172
|
ignorePreventCloseEvents: omegaConfig?.ignorePreventCloseEvents,
|
|
173
|
+
inputs: omegaConfig?.inputs,
|
|
954
174
|
meta,
|
|
955
175
|
unionMeta,
|
|
956
176
|
clear,
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
return handleSubmit({ currentSpan: span, ...meta })
|
|
960
|
-
},
|
|
177
|
+
normalizeNullableStructs,
|
|
178
|
+
handleSubmit,
|
|
961
179
|
// /** @experimental */
|
|
962
180
|
handleSubmitEffect,
|
|
963
|
-
registerField
|
|
964
|
-
watch(field, (f) => {
|
|
965
|
-
fieldMap.value.set(f.name, { label: f.label, id: f.id })
|
|
966
|
-
}, { immediate: true })
|
|
967
|
-
onUnmounted(() => {
|
|
968
|
-
// Only delete if we still own this entry (id matches)
|
|
969
|
-
// This prevents old components from deleting entries registered by new components
|
|
970
|
-
// during re-mount transitions (e.g., when :key changes)
|
|
971
|
-
const currentEntry = fieldMap.value.get(field.value.name)
|
|
972
|
-
if (currentEntry?.id === field.value.id) {
|
|
973
|
-
fieldMap.value.delete(field.value.name)
|
|
974
|
-
}
|
|
975
|
-
})
|
|
976
|
-
}
|
|
181
|
+
registerField
|
|
977
182
|
})
|
|
978
183
|
|
|
979
184
|
const errorContext = { form: formWithExtras, fieldMap }
|