@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,7 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
3
|
class="omega-input"
|
|
4
|
-
@focusout="
|
|
4
|
+
@focusout="(e) => {
|
|
5
|
+
$emit('blur', e)
|
|
6
|
+
field.handleBlur()
|
|
7
|
+
}"
|
|
5
8
|
@focusin="$emit('focus', $event)"
|
|
6
9
|
>
|
|
7
10
|
<component
|
|
@@ -31,7 +34,12 @@
|
|
|
31
34
|
v-if="inputProps.type === 'email'
|
|
32
35
|
|| inputProps.type === 'string'
|
|
33
36
|
|| inputProps.type === 'password'
|
|
34
|
-
|| inputProps.type === 'date'
|
|
37
|
+
|| inputProps.type === 'date'
|
|
38
|
+
|| inputProps.type === 'tel'
|
|
39
|
+
|| inputProps.type === 'url'
|
|
40
|
+
|| inputProps.type === 'color'
|
|
41
|
+
|| inputProps.type === 'time'
|
|
42
|
+
|| inputProps.type === 'search'"
|
|
35
43
|
:id="inputProps.id"
|
|
36
44
|
:required="inputProps.required"
|
|
37
45
|
:min-length="inputProps.minLength"
|
|
@@ -43,7 +51,7 @@
|
|
|
43
51
|
:error="inputProps.error"
|
|
44
52
|
v-bind="$attrs"
|
|
45
53
|
:model-value="state.value"
|
|
46
|
-
@update:model-value="field.handleChange"
|
|
54
|
+
@update:model-value="(v: any) => field.handleChange(v)"
|
|
47
55
|
>
|
|
48
56
|
<template
|
|
49
57
|
v-if="$slots.label"
|
|
@@ -67,7 +75,7 @@
|
|
|
67
75
|
:error="inputProps.error"
|
|
68
76
|
v-bind="$attrs"
|
|
69
77
|
:model-value="state.value"
|
|
70
|
-
@update:model-value="field.handleChange"
|
|
78
|
+
@update:model-value="(v: any) => field.handleChange(v)"
|
|
71
79
|
>
|
|
72
80
|
<template
|
|
73
81
|
v-if="$slots.label"
|
|
@@ -120,7 +128,7 @@
|
|
|
120
128
|
:error="inputProps.error"
|
|
121
129
|
v-bind="$attrs"
|
|
122
130
|
:model-value="state.value"
|
|
123
|
-
@update:model-value="field.handleChange"
|
|
131
|
+
@update:model-value="(v: any) => field.handleChange(v)"
|
|
124
132
|
>
|
|
125
133
|
<template
|
|
126
134
|
v-if="$slots.label"
|
|
@@ -133,7 +141,7 @@
|
|
|
133
141
|
</template>
|
|
134
142
|
<v-radio
|
|
135
143
|
v-for="option in inputProps.options"
|
|
136
|
-
:key="option.value"
|
|
144
|
+
:key="option.value as PropertyKey"
|
|
137
145
|
:label="option.title"
|
|
138
146
|
:value="option.value"
|
|
139
147
|
/>
|
|
@@ -195,6 +203,33 @@
|
|
|
195
203
|
/>
|
|
196
204
|
</template>
|
|
197
205
|
</v-autocomplete>
|
|
206
|
+
|
|
207
|
+
<!-- Fallback for any type not handled by a dedicated branch above (e.g. an
|
|
208
|
+
unrecognized schema type resolved to "unknown", or a custom `type` with
|
|
209
|
+
no renderer). Renders an editable text input instead of nothing. -->
|
|
210
|
+
<v-text-field
|
|
211
|
+
v-if="isUnhandledType"
|
|
212
|
+
:id="inputProps.id"
|
|
213
|
+
:required="inputProps.required"
|
|
214
|
+
:type="getInputType(inputProps.type)"
|
|
215
|
+
:name="field.name"
|
|
216
|
+
:label="inputProps.label"
|
|
217
|
+
:error-messages="inputProps.errorMessages"
|
|
218
|
+
:error="inputProps.error"
|
|
219
|
+
v-bind="$attrs"
|
|
220
|
+
:model-value="state.value"
|
|
221
|
+
@update:model-value="(v: any) => field.handleChange(v)"
|
|
222
|
+
>
|
|
223
|
+
<template
|
|
224
|
+
v-if="$slots.label"
|
|
225
|
+
#label
|
|
226
|
+
>
|
|
227
|
+
<slot
|
|
228
|
+
name="label"
|
|
229
|
+
v-bind="{ required: inputProps.required, id: inputProps.id, label: inputProps.label }"
|
|
230
|
+
/>
|
|
231
|
+
</template>
|
|
232
|
+
</v-text-field>
|
|
198
233
|
</div>
|
|
199
234
|
</template>
|
|
200
235
|
|
|
@@ -204,10 +239,12 @@
|
|
|
204
239
|
generic="From extends Record<PropertyKey, any>, Name extends DeepKeys<From>"
|
|
205
240
|
>
|
|
206
241
|
import { type DeepKeys } from "@tanstack/vue-form"
|
|
207
|
-
import {
|
|
242
|
+
import { computed, watchEffect } from "vue"
|
|
208
243
|
import type { VuetifyInputProps } from "./InputProps"
|
|
244
|
+
import { getInputType } from "./inputs"
|
|
245
|
+
import { typeOverrides } from "./types"
|
|
209
246
|
|
|
210
|
-
defineProps<VuetifyInputProps<From, Name>>()
|
|
247
|
+
const props = defineProps<VuetifyInputProps<From, Name>>()
|
|
211
248
|
|
|
212
249
|
defineEmits<{
|
|
213
250
|
(e: "focus", event: Event): void
|
|
@@ -217,6 +254,19 @@ defineEmits<{
|
|
|
217
254
|
defineOptions({
|
|
218
255
|
inheritAttrs: false
|
|
219
256
|
})
|
|
257
|
+
|
|
258
|
+
// True when no dedicated branch handles `inputProps.type` (it's outside the
|
|
259
|
+
// built-in `typeOverrides`): the fallback text input renders and we warn.
|
|
260
|
+
const isUnhandledType = computed(() => !(typeOverrides as readonly string[]).includes(props.inputProps.type))
|
|
261
|
+
|
|
262
|
+
watchEffect(() => {
|
|
263
|
+
if (isUnhandledType.value) {
|
|
264
|
+
// eslint-disable-next-line no-console
|
|
265
|
+
console.warn(
|
|
266
|
+
`[OmegaForm] Unhandled input type "${props.inputProps.type}", falling back to a text input.`
|
|
267
|
+
)
|
|
268
|
+
}
|
|
269
|
+
})
|
|
220
270
|
</script>
|
|
221
271
|
|
|
222
272
|
<style>
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<slot v-bind="{ ...inputProps.inputProps, field: inputProps.field, state: inputProps.state }">
|
|
3
|
-
<div :class="
|
|
4
|
-
<
|
|
5
|
-
|
|
3
|
+
<div :class="rootClass">
|
|
4
|
+
<component
|
|
5
|
+
:is="renderComponent"
|
|
6
|
+
v-if="renderComponent"
|
|
6
7
|
v-bind="{ ...attrsWithoutClass, ...inputProps, class: props.inputClass }"
|
|
7
8
|
>
|
|
8
9
|
<template
|
|
@@ -14,7 +15,7 @@
|
|
|
14
15
|
v-bind="labelProps"
|
|
15
16
|
/>
|
|
16
17
|
</template>
|
|
17
|
-
</
|
|
18
|
+
</component>
|
|
18
19
|
</div>
|
|
19
20
|
</slot>
|
|
20
21
|
</template>
|
|
@@ -24,11 +25,13 @@
|
|
|
24
25
|
lang="ts"
|
|
25
26
|
generic="From extends Record<PropertyKey, any>, Name extends DeepKeys<From>"
|
|
26
27
|
>
|
|
28
|
+
/* eslint-disable @typescript-eslint/no-explicit-any -- TanStack Form / Vue attrs interop */
|
|
27
29
|
import { type DeepKeys, useStore } from "@tanstack/vue-form"
|
|
28
|
-
import { computed, type ComputedRef, getCurrentInstance, useAttrs, useId, useSlots } from "vue"
|
|
30
|
+
import { type Component, computed, type ComputedRef, getCurrentInstance, useAttrs, useId, useSlots } from "vue"
|
|
29
31
|
import type { InputProps, OmegaFieldInternalApi } from "./InputProps"
|
|
30
|
-
import type {
|
|
32
|
+
import type { MetaRecord, NestedKeyOf } from "./meta/types"
|
|
31
33
|
import OmegaInputVuetify from "./OmegaInputVuetify.vue"
|
|
34
|
+
import type { TypeOverride } from "./types"
|
|
32
35
|
|
|
33
36
|
defineOptions({
|
|
34
37
|
inheritAttrs: false
|
|
@@ -41,7 +44,6 @@ const props = withDefaults(
|
|
|
41
44
|
meta: MetaRecord<From>[NestedKeyOf<From>]
|
|
42
45
|
label: string
|
|
43
46
|
type?: TypeOverride
|
|
44
|
-
validators?: FieldValidators<From>
|
|
45
47
|
required?: boolean
|
|
46
48
|
inputClass?: string | null
|
|
47
49
|
|
|
@@ -54,14 +56,16 @@ const props = withDefaults(
|
|
|
54
56
|
) => void
|
|
55
57
|
|
|
56
58
|
// TODO: these should really be optional, depending on the input type (and the custom input type for custom inputs :s)
|
|
57
|
-
options?: { title: string; value:
|
|
59
|
+
options?: { title: string; value: unknown }[]
|
|
60
|
+
|
|
61
|
+
inputs?: Record<string, Component>
|
|
58
62
|
}>(),
|
|
59
63
|
{
|
|
60
64
|
required: undefined,
|
|
61
65
|
type: undefined,
|
|
62
66
|
options: undefined,
|
|
63
|
-
|
|
64
|
-
|
|
67
|
+
inputClass: undefined,
|
|
68
|
+
inputs: undefined
|
|
65
69
|
}
|
|
66
70
|
)
|
|
67
71
|
|
|
@@ -78,11 +82,14 @@ const attrsWithoutClass = computed(() => {
|
|
|
78
82
|
return rest
|
|
79
83
|
})
|
|
80
84
|
|
|
85
|
+
const rootClass = computed(() => attrs.class as any)
|
|
86
|
+
|
|
81
87
|
const id = useId()
|
|
82
88
|
|
|
83
89
|
const fieldApi = props.field
|
|
84
90
|
|
|
85
|
-
|
|
91
|
+
// Subscribed for side-effect: keeps component reactive to fieldApi.store changes
|
|
92
|
+
useStore(fieldApi.store, (state) => state)
|
|
86
93
|
|
|
87
94
|
// Get errors from form-level fieldMeta (persists across Field re-mounts)
|
|
88
95
|
const formFieldMeta = useStore(fieldApi.form.store, (state) => state.fieldMeta)
|
|
@@ -96,6 +103,11 @@ const fieldType = computed(() => {
|
|
|
96
103
|
return props.meta?.type || "unknown"
|
|
97
104
|
})
|
|
98
105
|
|
|
106
|
+
const renderComponent = computed(() =>
|
|
107
|
+
props.inputs?.[fieldType.value]
|
|
108
|
+
?? (vuetified ? OmegaInputVuetify : undefined)
|
|
109
|
+
)
|
|
110
|
+
|
|
99
111
|
props.register(computed(() => ({ name: props.field.name, label: props.label, id })))
|
|
100
112
|
|
|
101
113
|
// Get errors from form-level fieldMeta instead of field-level state
|
|
@@ -126,6 +138,13 @@ const handleChange: OmegaFieldInternalApi<From, Name>["handleChange"] = (value)
|
|
|
126
138
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
127
139
|
: null as any
|
|
128
140
|
)
|
|
141
|
+
} else if (props.meta?.isOptionalKey) {
|
|
142
|
+
// `S.optionalKey` expects the key to be ABSENT from the submitted
|
|
143
|
+
// object, not present-with-undefined. Remove it from form state
|
|
144
|
+
// rather than setting it to `undefined`. Note: this is distinct
|
|
145
|
+
// from `required: false`, which may also just mean "empty string
|
|
146
|
+
// is valid" for unconstrained `S.String` fields.
|
|
147
|
+
props.field.form.deleteField(props.field.name)
|
|
129
148
|
} else {
|
|
130
149
|
// Keep the actual value (e.g., empty string for S.String fields)
|
|
131
150
|
props.field.handleChange(value)
|
|
@@ -134,9 +153,11 @@ const handleChange: OmegaFieldInternalApi<From, Name>["handleChange"] = (value)
|
|
|
134
153
|
props.field.handleChange(value)
|
|
135
154
|
}
|
|
136
155
|
|
|
137
|
-
//
|
|
138
|
-
//
|
|
139
|
-
|
|
156
|
+
// A change here may have materialised a nullable struct (this field is one
|
|
157
|
+
// of its children); backfill the untouched siblings so the live `values`
|
|
158
|
+
// matches what validation and decoding see.
|
|
159
|
+
const form = props.field.form as { normalizeNullableStructs?: () => void }
|
|
160
|
+
form.normalizeNullableStructs?.()
|
|
140
161
|
}
|
|
141
162
|
|
|
142
163
|
// Note: Default value normalization (converting empty strings to null/undefined for nullable fields)
|
|
@@ -163,11 +184,13 @@ const inputProps: ComputedRef<InputProps<From, Name>> = computed(() => ({
|
|
|
163
184
|
minLength: props.meta?.type === "string" && props.meta?.minLength,
|
|
164
185
|
maxLength: props.meta?.type === "string" && props.meta?.maxLength,
|
|
165
186
|
max: (props.meta?.type === "number")
|
|
166
|
-
|
|
167
|
-
?? (typeof props.meta?.exclusiveMaximum === "number"
|
|
187
|
+
? (props.meta?.maximum
|
|
188
|
+
?? (typeof props.meta?.exclusiveMaximum === "number" ? props.meta.exclusiveMaximum - 1 : undefined))
|
|
189
|
+
: undefined,
|
|
168
190
|
min: (props.meta?.type === "number")
|
|
169
|
-
|
|
170
|
-
?? (typeof props.meta?.exclusiveMinimum === "number"
|
|
191
|
+
? (props.meta?.minimum
|
|
192
|
+
?? (typeof props.meta?.exclusiveMinimum === "number" ? props.meta.exclusiveMinimum + 1 : undefined))
|
|
193
|
+
: undefined,
|
|
171
194
|
errorMessages: errors.value,
|
|
172
195
|
error: !!errors.value.length,
|
|
173
196
|
type: fieldType.value,
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
import { type DeepKeys } from "@tanstack/vue-form"
|
|
9
9
|
import { computed, provide, ref, watch } from "vue"
|
|
10
10
|
import { type TaggedUnionOption } from "./InputProps"
|
|
11
|
-
import { type FieldPath } from "./OmegaFormStuff"
|
|
12
11
|
import OmegaTaggedUnionInternal from "./OmegaTaggedUnionInternal.vue"
|
|
12
|
+
import { type FieldPath } from "./types"
|
|
13
13
|
import { type useOmegaForm } from "./useOmegaForm"
|
|
14
14
|
|
|
15
15
|
const props = defineProps<{
|
|
@@ -30,6 +30,7 @@ watch(
|
|
|
30
30
|
() => {
|
|
31
31
|
const path = tagPath.value
|
|
32
32
|
// Navigate to the nested value
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- traversing arbitrary nested values
|
|
33
34
|
return path.split(".").reduce((acc: any, key) => acc?.[key], formValues.value) as string | null
|
|
34
35
|
},
|
|
35
36
|
(newTag) => {
|
|
@@ -74,9 +75,15 @@ provide("getMetaFromArray", getMetaFromArray)
|
|
|
74
75
|
/>
|
|
75
76
|
</slot>
|
|
76
77
|
<slot />
|
|
78
|
+
<!--
|
|
79
|
+
Drive the branch off `currentTag`: the tag is read from the form store
|
|
80
|
+
(the canonical state), the same single source of truth that feeds
|
|
81
|
+
`getMetaFromArray` above — rather than the `Field` slot's `state`,
|
|
82
|
+
which is only a projection of it.
|
|
83
|
+
-->
|
|
77
84
|
<OmegaTaggedUnionInternal
|
|
78
85
|
:field="inputProps.field as any"
|
|
79
|
-
:
|
|
86
|
+
:tag="currentTag"
|
|
80
87
|
:name="name"
|
|
81
88
|
:form="form"
|
|
82
89
|
>
|
|
@@ -91,7 +98,7 @@ provide("getMetaFromArray", getMetaFromArray)
|
|
|
91
98
|
</template>
|
|
92
99
|
</OmegaTaggedUnionInternal>
|
|
93
100
|
<slot
|
|
94
|
-
v-if="
|
|
101
|
+
v-if="currentTag"
|
|
95
102
|
name="OmegaCommon"
|
|
96
103
|
/>
|
|
97
104
|
</template>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<slot
|
|
3
|
-
v-if="
|
|
4
|
-
:name="`${name ? `${name}.` : ''}${
|
|
5
|
-
v-bind="{ field,
|
|
3
|
+
v-if="tag"
|
|
4
|
+
:name="`${name ? `${name}.` : ''}${tag}`"
|
|
5
|
+
v-bind="{ field, tag }"
|
|
6
6
|
/>
|
|
7
7
|
</template>
|
|
8
8
|
|
|
@@ -17,7 +17,7 @@ import { type OmegaFieldInternalApi } from "./InputProps"
|
|
|
17
17
|
import { type useOmegaForm } from "./useOmegaForm"
|
|
18
18
|
|
|
19
19
|
const props = defineProps<{
|
|
20
|
-
|
|
20
|
+
tag: string | null
|
|
21
21
|
field: OmegaFieldInternalApi<From, Name>
|
|
22
22
|
name?: DeepKeys<From>
|
|
23
23
|
form: ReturnType<typeof useOmegaForm<From, To>>
|
|
@@ -26,7 +26,7 @@ const props = defineProps<{
|
|
|
26
26
|
const values = props.form.useStore(({ values }) => values)
|
|
27
27
|
|
|
28
28
|
// Watch for _tag changes
|
|
29
|
-
watch(() => props.
|
|
29
|
+
watch(() => props.tag, (newTag, oldTag) => {
|
|
30
30
|
if (newTag === null) {
|
|
31
31
|
props.field.setValue(null as DeepValue<From, Name>)
|
|
32
32
|
}
|
|
@@ -34,7 +34,7 @@ watch(() => props.state, (newTag, oldTag) => {
|
|
|
34
34
|
if (newTag !== oldTag) {
|
|
35
35
|
props.form.reset(values.value)
|
|
36
36
|
setTimeout(() => {
|
|
37
|
-
props.field.validate("change")
|
|
37
|
+
void props.field.validate("change")
|
|
38
38
|
}, 0)
|
|
39
39
|
}
|
|
40
40
|
}, { immediate: true })
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
import { useStore } from "@tanstack/vue-form"
|
|
31
31
|
import { usePreventClose } from "./blockDialog"
|
|
32
32
|
import { getOmegaStore } from "./getOmegaStore"
|
|
33
|
-
import { type DefaultTypeProps, type OmegaFormApi, type OmegaFormState } from "./
|
|
33
|
+
import { type DefaultTypeProps, type OmegaFormApi, type OmegaFormState } from "./types"
|
|
34
34
|
import { type OmegaFormReturn } from "./useOmegaForm"
|
|
35
35
|
|
|
36
36
|
type OmegaWrapperProps = {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import mitt from "mitt"
|
|
2
2
|
import { inject, type InjectionKey, provide, type Ref } from "vue"
|
|
3
|
+
import { useIntl } from "../../utils"
|
|
3
4
|
import { onMountedWithCleanup } from "./onMountedWithCleanup"
|
|
4
5
|
|
|
5
6
|
export type DialogClosing = { prevent?: boolean | Promise<boolean> }
|
|
@@ -19,11 +20,19 @@ export const usePreventClose = (mkIsDirty: () => Ref<boolean>) => {
|
|
|
19
20
|
if (!bus) {
|
|
20
21
|
return
|
|
21
22
|
}
|
|
23
|
+
const { formatMessage, trans } = useIntl()
|
|
22
24
|
const isDirty = mkIsDirty()
|
|
25
|
+
const defaultMessage = "There are unsaved changes. Are you sure you want to close?"
|
|
23
26
|
onMountedWithCleanup(() => {
|
|
24
27
|
const onDialogClosing = (evt: DialogClosing) => {
|
|
25
28
|
if (isDirty.value) {
|
|
26
|
-
|
|
29
|
+
// Mirror the guard pattern in errors.ts: a custom `useIntl` mock may
|
|
30
|
+
// only provide `trans`, so fall back through trans → defaultMessage.
|
|
31
|
+
const message = formatMessage
|
|
32
|
+
? formatMessage({ id: "form.unsaved_changes_confirm", defaultMessage })
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- key may not be registered in the locale catalog
|
|
34
|
+
: trans?.("form.unsaved_changes_confirm" as any) ?? defaultMessage
|
|
35
|
+
if (!confirm(message)) {
|
|
27
36
|
evt.prevent = true
|
|
28
37
|
}
|
|
29
38
|
}
|
|
@@ -46,11 +55,14 @@ export const useOnClose = (close: () => void) => {
|
|
|
46
55
|
bus.emit("dialog-closing", evt)
|
|
47
56
|
if (evt.prevent) {
|
|
48
57
|
if (typeof evt.prevent === "object" && "then" in evt.prevent) {
|
|
49
|
-
evt
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
58
|
+
evt
|
|
59
|
+
.prevent
|
|
60
|
+
.then((r) => {
|
|
61
|
+
if (r) {
|
|
62
|
+
close()
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
.catch(console.error)
|
|
54
66
|
}
|
|
55
67
|
} else {
|
|
56
68
|
close()
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any -- TanStack Form / Vue render-fn slot interop */
|
|
1
2
|
import type { DeepKeys } from "@tanstack/vue-form"
|
|
2
3
|
import { type Component, h } from "vue"
|
|
3
4
|
import type { MergedInputProps } from "./InputProps"
|
|
4
|
-
import { type DefaultTypeProps } from "./OmegaFormStuff"
|
|
5
5
|
import OmegaInput from "./OmegaInput.vue"
|
|
6
|
+
import type { OmegaConfig } from "./types"
|
|
6
7
|
import { useOmegaForm } from "./useOmegaForm"
|
|
7
8
|
|
|
8
|
-
export const createUseFormWithCustomInput =
|
|
9
|
-
TypeProps = DefaultTypeProps
|
|
10
|
-
>(CustomInputComponent: Component) => {
|
|
9
|
+
export const createUseFormWithCustomInput = (CustomInputComponent: Component) => {
|
|
11
10
|
return <
|
|
12
11
|
From extends Record<PropertyKey, any>,
|
|
13
|
-
To extends Record<PropertyKey, any
|
|
12
|
+
To extends Record<PropertyKey, any>,
|
|
13
|
+
const Cfg extends OmegaConfig<To> = OmegaConfig<To>
|
|
14
14
|
>(
|
|
15
|
-
|
|
15
|
+
schema: Parameters<typeof useOmegaForm<From, To>>[0],
|
|
16
|
+
tanstackFormOptions?: Parameters<typeof useOmegaForm<From, To>>[1],
|
|
17
|
+
omegaConfig?: Cfg
|
|
16
18
|
) => {
|
|
17
|
-
const [schema, tanstackFormOptions, omegaConfig] = args
|
|
18
|
-
|
|
19
19
|
// Create a wrapper that extends OmegaInput and overrides its default slot
|
|
20
20
|
const WrappedInput = {
|
|
21
21
|
name: "WrappedInput",
|
|
@@ -35,7 +35,10 @@ export const createUseFormWithCustomInput = <
|
|
|
35
35
|
&& key !== "form"
|
|
36
36
|
)
|
|
37
37
|
)
|
|
38
|
-
|
|
38
|
+
// A per-type registration (omegaConfig.inputs) wins over the
|
|
39
|
+
// universal CustomInputComponent; otherwise fall back to it.
|
|
40
|
+
const LeafComponent = omegaConfig?.inputs?.[inputProps.type] ?? CustomInputComponent
|
|
41
|
+
return h(LeafComponent, { ...filteredAttrs, field, state, inputProps }, {
|
|
39
42
|
// Pass through label slot if it exists
|
|
40
43
|
...(slots.label && {
|
|
41
44
|
label: (labelProps: any) => slots.label(labelProps)
|
|
@@ -54,13 +57,12 @@ export const createUseFormWithCustomInput = <
|
|
|
54
57
|
}
|
|
55
58
|
}
|
|
56
59
|
|
|
57
|
-
|
|
60
|
+
// Thread `Cfg` so `omegaConfig.inputs` keys are inferred into the `type`
|
|
61
|
+
// union (`<form.Input type="...">`), exactly like a bare `useOmegaForm`.
|
|
62
|
+
const form = useOmegaForm<From, To, Cfg>(
|
|
58
63
|
schema,
|
|
59
64
|
tanstackFormOptions,
|
|
60
|
-
{
|
|
61
|
-
...omegaConfig,
|
|
62
|
-
input: WrappedInput
|
|
63
|
-
}
|
|
65
|
+
{ ...omegaConfig, input: WrappedInput } as Cfg
|
|
64
66
|
)
|
|
65
67
|
|
|
66
68
|
return form
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
|
|
3
|
+
import { type Component, computed, type ComputedRef, type ConcreteComponent, h, onUnmounted, type Ref, ref, watch } from "vue"
|
|
4
|
+
import { useIntl } from "../../utils"
|
|
5
|
+
import type { OmegaError } from "./types"
|
|
6
|
+
import type { OF } from "./useOmegaForm"
|
|
7
|
+
|
|
8
|
+
export const useErrorLabel = (form: OF<any, any>) => {
|
|
9
|
+
const { formatMessage } = useIntl()
|
|
10
|
+
const humanize = (str: string) => {
|
|
11
|
+
return str
|
|
12
|
+
.replace(/([A-Z])/g, " $1") // Add space before capital letters
|
|
13
|
+
.replace(/^./, (char) => char.toUpperCase()) // Capitalize the first letter
|
|
14
|
+
.trim() // Remove leading/trailing spaces
|
|
15
|
+
}
|
|
16
|
+
const fallback = (propsName: string) =>
|
|
17
|
+
formatMessage
|
|
18
|
+
? formatMessage({ id: `general.fields.${propsName}`, defaultMessage: humanize(propsName) })
|
|
19
|
+
: humanize(propsName)
|
|
20
|
+
const i18n = (propsName: string) =>
|
|
21
|
+
form.i18nNamespace
|
|
22
|
+
? formatMessage({ id: `${form.i18nNamespace}.fields.${propsName}`, defaultMessage: fallback(propsName) })
|
|
23
|
+
: fallback(propsName)
|
|
24
|
+
|
|
25
|
+
return i18n
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const eHoc = (errorProps: {
|
|
29
|
+
form: OF<any, any>
|
|
30
|
+
fieldMap: Ref<Map<string, { id: string; label: string }>>
|
|
31
|
+
}) => {
|
|
32
|
+
return function FormHoc<P>(
|
|
33
|
+
WrappedComponent: Component<P>
|
|
34
|
+
): ConcreteComponent<P> {
|
|
35
|
+
return {
|
|
36
|
+
setup() {
|
|
37
|
+
const { fieldMap, form } = errorProps
|
|
38
|
+
const generalErrors = form.useStore((state) => state.errors)
|
|
39
|
+
const fieldMeta = form.useStore((state) => state.fieldMeta)
|
|
40
|
+
const errorMap = form.useStore((state) => state.errorMap)
|
|
41
|
+
|
|
42
|
+
const errorLabel = useErrorLabel(form)
|
|
43
|
+
|
|
44
|
+
const errors = computed(() => {
|
|
45
|
+
// Collect errors from fieldMeta (field-level errors for registered fields)
|
|
46
|
+
const fieldErrors = Object.entries(fieldMeta.value).reduce<OmegaError[]>((acc, [key, m]) => {
|
|
47
|
+
const fieldErrors = (m as { errors?: Array<{ message?: string }> } | undefined)?.errors ?? []
|
|
48
|
+
if (!fieldErrors.length) {
|
|
49
|
+
return acc
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const fieldInfo = fieldMap.value.get(key)
|
|
53
|
+
if (!fieldInfo) {
|
|
54
|
+
return acc
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
acc.push({
|
|
58
|
+
label: fieldInfo.label,
|
|
59
|
+
inputId: fieldInfo.id,
|
|
60
|
+
errors: [fieldErrors[0]?.message].filter(Boolean) as string[]
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
return acc
|
|
64
|
+
}, [])
|
|
65
|
+
|
|
66
|
+
// Collect errors from errorMap.onDynamic / errorMap.onSubmit ONLY for fields that are NOT registered
|
|
67
|
+
// (registered fields already have their errors in fieldMeta).
|
|
68
|
+
// Our localized standard schema writes to onDynamic via validationLogic: revalidateLogic();
|
|
69
|
+
// caller-provided validators.onSubmit (via tanstackFormOptions spread) writes to onSubmit.
|
|
70
|
+
const submitErrors: OmegaError[] = []
|
|
71
|
+
const submitIssueMaps = [errorMap.value.onDynamic, errorMap.value.onSubmit].filter(
|
|
72
|
+
Boolean
|
|
73
|
+
) as unknown as Array<
|
|
74
|
+
Record<string, unknown>
|
|
75
|
+
>
|
|
76
|
+
const seenPaths = new Set<string>()
|
|
77
|
+
for (const issuesByPath of submitIssueMaps) {
|
|
78
|
+
for (const [_, issues] of Object.entries(issuesByPath)) {
|
|
79
|
+
if (Array.isArray(issues) && issues.length) {
|
|
80
|
+
for (const issue of issues) {
|
|
81
|
+
const issAny: any = issue
|
|
82
|
+
if (issAny?.path && Array.isArray(issAny.path) && issAny.path.length) {
|
|
83
|
+
const fieldPath = issAny.path.join(".")
|
|
84
|
+
if (!fieldMap.value.has(fieldPath) && !seenPaths.has(fieldPath)) {
|
|
85
|
+
seenPaths.add(fieldPath)
|
|
86
|
+
submitErrors.push({
|
|
87
|
+
label: errorLabel(fieldPath),
|
|
88
|
+
inputId: fieldPath,
|
|
89
|
+
errors: [issAny.message].filter(Boolean)
|
|
90
|
+
})
|
|
91
|
+
break
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Combine both error sources (no need to check for duplicates since they're mutually exclusive)
|
|
100
|
+
return [...fieldErrors, ...submitErrors]
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
generalErrors,
|
|
105
|
+
errors
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
render({ errors, generalErrors }: any) {
|
|
109
|
+
return h(WrappedComponent, {
|
|
110
|
+
errors,
|
|
111
|
+
generalErrors,
|
|
112
|
+
...this.$attrs
|
|
113
|
+
}, this.$slots)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export const makeFieldMap = () => {
|
|
120
|
+
const fieldMap = ref(new Map<string, { label: string; id: string }>())
|
|
121
|
+
const registerField = (field: ComputedRef<{ name: string; label: string; id: string }>) => {
|
|
122
|
+
watch(field, (f) => {
|
|
123
|
+
fieldMap.value.set(f.name, { label: f.label, id: f.id })
|
|
124
|
+
}, { immediate: true })
|
|
125
|
+
onUnmounted(() => {
|
|
126
|
+
// Only delete if we still own this entry (id matches)
|
|
127
|
+
// This prevents old components from deleting entries registered by new components
|
|
128
|
+
// during re-mount transitions (e.g., when :key changes)
|
|
129
|
+
const currentEntry = fieldMap.value.get(field.value.name)
|
|
130
|
+
if (currentEntry?.id === field.value.id) {
|
|
131
|
+
fieldMap.value.delete(field.value.name)
|
|
132
|
+
}
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
return { fieldMap, registerField }
|
|
136
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
|
|
3
|
+
import { type Component, type ConcreteComponent, h } from "vue"
|
|
4
|
+
import type { OF } from "./useOmegaForm"
|
|
5
|
+
|
|
6
|
+
export const fHoc = (form: OF<any, any>) => {
|
|
7
|
+
return function FormHoc<P>(
|
|
8
|
+
WrappedComponent: Component<P>
|
|
9
|
+
): ConcreteComponent<P> {
|
|
10
|
+
return {
|
|
11
|
+
render() {
|
|
12
|
+
return h(WrappedComponent, {
|
|
13
|
+
form,
|
|
14
|
+
...this.$attrs
|
|
15
|
+
}, this.$slots)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -1,7 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import type * as S from "effect-app/Schema"
|
|
2
|
+
|
|
3
|
+
export { getInputType, type SupportedInputs } from "./inputs"
|
|
4
|
+
export { createMeta, generateMetaFromSchema, isNullableOrUndefined, metadataFromAst } from "./meta/createMeta"
|
|
5
|
+
export type { CreateMeta, FilterItems } from "./meta/createMeta"
|
|
6
|
+
export { defaultsValueFromSchema } from "./meta/defaults"
|
|
7
|
+
export { toFormSchema } from "./meta/redacted"
|
|
8
|
+
export type { BaseFieldMeta, BooleanFieldMeta, DateFieldMeta, FieldMeta, MetaRecord, MultipleFieldMeta, NestedKeyOf, NumberFieldMeta, SelectFieldMeta, StringFieldMeta, UnknownFieldMeta } from "./meta/types"
|
|
9
|
+
export { deepMerge } from "./persistency"
|
|
10
|
+
export type { BaseProps, DefaultTypeProps, FieldPath, FieldPath_, FieldValidators, FormComponent, FormProps, FormType, OmegaArrayProps, OmegaAutoGenMeta, OmegaError, OmegaFormApi, OmegaFormParams, OmegaFormState, OmegaInputProps, OmegaInputPropsBase, PrefixFromDepth, TypeOverride, TypesWithOptions } from "./types"
|
|
11
|
+
export { makeStandardSchemaV1Hooks, toLocalizedStandardSchemaV1 } from "./validation/localized"
|
|
12
|
+
|
|
13
|
+
export { FormErrors, OmegaFormKey, useErrorLabel, useOmegaForm } from "./useOmegaForm"
|
|
14
|
+
export type { defaultValuesPriorityUnion, OF, OmegaConfig, OmegaFormReturn, Policies } from "./useOmegaForm"
|
|
3
15
|
|
|
4
16
|
export { type ExtractTagValue, type ExtractUnionBranch, type InputProps, type MergedInputProps, type TaggedUnionOption, type TaggedUnionOptionsArray, type TaggedUnionProps } from "./InputProps"
|
|
17
|
+
export type { VuetifyInputProps, VuetifyInputProps as OmegaRendererProps } from "./InputProps"
|
|
5
18
|
export { default as OmegaInput } from "./OmegaInput.vue"
|
|
6
19
|
export { default as OmegaVuetifyInput } from "./OmegaInternalInput.vue"
|
|
7
20
|
export { default as OmegaTaggedUnion } from "./OmegaTaggedUnion.vue"
|
|
@@ -9,6 +22,6 @@ export { default as OmegaTaggedUnionInternal } from "./OmegaTaggedUnionInternal.
|
|
|
9
22
|
|
|
10
23
|
export { useOnClose, usePreventClose } from "./blockDialog"
|
|
11
24
|
|
|
12
|
-
export { getInputType } from "./OmegaFormStuff"
|
|
13
|
-
|
|
14
25
|
export { createUseFormWithCustomInput } from "./createUseFormWithCustomInput"
|
|
26
|
+
|
|
27
|
+
export const duplicateSchema = <From, To>(schema: S.Codec<To, From>) => schema
|