@effect-app/vue-components 3.0.1 → 3.0.3
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useForm as K } from "@tanstack/vue-form";
|
|
2
|
-
import { Data as T, S as W, Effect as d, Fiber as $, Option as
|
|
2
|
+
import { Data as T, S as W, Effect as d, Fiber as $, Option as j, Array as F } from "effect-app";
|
|
3
3
|
import { runtimeFiberAsPromise as z } from "./vue-components.es17.js";
|
|
4
4
|
import { computed as x, onUnmounted as D, onMounted as G, onBeforeUnmount as Z, watch as R, ref as Q, h as J } from "vue";
|
|
5
5
|
import { useIntl as X } from "./vue-components.es3.js";
|
|
@@ -29,19 +29,19 @@ const M = (i) => function(s) {
|
|
|
29
29
|
}, ce = (i) => function(s) {
|
|
30
30
|
return {
|
|
31
31
|
setup() {
|
|
32
|
-
const { fieldMap: f, form: m } = i, a = m.useStore((v) => v.errors), g = m.useStore((v) => v.fieldMeta), p = m.useStore((v) => v.errorMap),
|
|
32
|
+
const { fieldMap: f, form: m } = i, a = m.useStore((v) => v.errors), g = m.useStore((v) => v.fieldMeta), p = m.useStore((v) => v.errorMap), A = ae(m), L = x(() => {
|
|
33
33
|
const v = F.filterMap(
|
|
34
34
|
Object.entries(g.value),
|
|
35
35
|
([O, h]) => {
|
|
36
36
|
const w = h.errors ?? [];
|
|
37
|
-
if (!w.length) return
|
|
37
|
+
if (!w.length) return j.none();
|
|
38
38
|
const u = f.value.get(O);
|
|
39
|
-
return u ?
|
|
39
|
+
return u ? j.some({
|
|
40
40
|
label: u.label,
|
|
41
41
|
inputId: u.id,
|
|
42
42
|
// Only show the first error
|
|
43
43
|
errors: [w[0]?.message].filter(Boolean)
|
|
44
|
-
}) :
|
|
44
|
+
}) : j.none();
|
|
45
45
|
}
|
|
46
46
|
), o = [];
|
|
47
47
|
if (p.value.onSubmit) {
|
|
@@ -53,7 +53,7 @@ const M = (i) => function(s) {
|
|
|
53
53
|
const E = u.path.join(".");
|
|
54
54
|
if (!f.value.has(E)) {
|
|
55
55
|
o.push({
|
|
56
|
-
label:
|
|
56
|
+
label: A(E),
|
|
57
57
|
inputId: E,
|
|
58
58
|
errors: [u.message].filter(Boolean)
|
|
59
59
|
});
|
|
@@ -66,7 +66,7 @@ const M = (i) => function(s) {
|
|
|
66
66
|
});
|
|
67
67
|
return {
|
|
68
68
|
generalErrors: a,
|
|
69
|
-
errors:
|
|
69
|
+
errors: L
|
|
70
70
|
};
|
|
71
71
|
},
|
|
72
72
|
render({ errors: f, generalErrors: m }) {
|
|
@@ -84,12 +84,12 @@ const M = (i) => function(s) {
|
|
|
84
84
|
return s.persistency.id;
|
|
85
85
|
const e = window.location.pathname, r = Object.keys(a);
|
|
86
86
|
return `${e}-${r.join("-")}`;
|
|
87
|
-
}),
|
|
87
|
+
}), A = () => {
|
|
88
88
|
const e = new URLSearchParams(window.location.search);
|
|
89
89
|
e.delete(p.value);
|
|
90
90
|
const r = new URL(window.location.href);
|
|
91
91
|
r.search = e.toString(), window.history.replaceState({}, "", r.toString());
|
|
92
|
-
},
|
|
92
|
+
}, L = x(() => {
|
|
93
93
|
let e;
|
|
94
94
|
const r = s?.persistency;
|
|
95
95
|
if (
|
|
@@ -110,7 +110,7 @@ const M = (i) => function(s) {
|
|
|
110
110
|
if (r?.policies && b(r.policies, "querystring"))
|
|
111
111
|
try {
|
|
112
112
|
const t = new URLSearchParams(window.location.search).get(p.value);
|
|
113
|
-
|
|
113
|
+
A(), t && (e = N(e || {}, JSON.parse(t)));
|
|
114
114
|
} catch (n) {
|
|
115
115
|
console.error(n);
|
|
116
116
|
}
|
|
@@ -145,7 +145,7 @@ const M = (i) => function(s) {
|
|
|
145
145
|
)
|
|
146
146
|
) : t;
|
|
147
147
|
}) : void 0,
|
|
148
|
-
defaultValues:
|
|
148
|
+
defaultValues: L.value
|
|
149
149
|
}), O = () => {
|
|
150
150
|
Object.keys(a).forEach((e) => {
|
|
151
151
|
o.setFieldValue(e, void 0);
|
|
@@ -195,13 +195,13 @@ const M = (i) => function(s) {
|
|
|
195
195
|
const I = (e) => d.currentSpan.pipe(
|
|
196
196
|
d.option,
|
|
197
197
|
d.flatMap(
|
|
198
|
-
(r) => d.promise(() => o.handleSubmit(
|
|
198
|
+
(r) => d.promise(() => o.handleSubmit(j.isSome(r) ? { currentSpan: r.value, ...e } : e))
|
|
199
199
|
)
|
|
200
200
|
), q = (e) => e?.checkErrors ? I(e?.meta).pipe(d.flatMap(d.fnUntraced(function* () {
|
|
201
201
|
const r = o.getAllErrors();
|
|
202
202
|
if (Object.keys(r.fields).length || r.form.errors.length)
|
|
203
203
|
return yield* new ie({ form: r.form, fields: r.fields });
|
|
204
|
-
}))) : I(e?.meta), B = o.handleSubmit,
|
|
204
|
+
}))) : I(e?.meta), B = o.handleSubmit, P = Q(/* @__PURE__ */ new Map()), y = Object.assign(o, {
|
|
205
205
|
i18nNamespace: s?.i18nNamespace,
|
|
206
206
|
ignorePreventCloseEvents: s?.ignorePreventCloseEvents,
|
|
207
207
|
meta: a,
|
|
@@ -214,9 +214,13 @@ const M = (i) => function(s) {
|
|
|
214
214
|
// /** @experimental */
|
|
215
215
|
handleSubmitEffect: q,
|
|
216
216
|
registerField: (e) => {
|
|
217
|
-
R(e, (r) =>
|
|
217
|
+
R(e, (r) => {
|
|
218
|
+
P.value.set(r.name, { label: r.label, id: r.id });
|
|
219
|
+
}, { immediate: !0 }), D(() => {
|
|
220
|
+
P.value.get(e.value.name)?.id === e.value.id && P.value.delete(e.value.name);
|
|
221
|
+
});
|
|
218
222
|
}
|
|
219
|
-
}), V = { form: y, fieldMap:
|
|
223
|
+
}), V = { form: y, fieldMap: P };
|
|
220
224
|
return Object.assign(y, {
|
|
221
225
|
// Type-level properties for performance optimization (not used at runtime)
|
|
222
226
|
_paths: void 0,
|
package/package.json
CHANGED
|
@@ -102,6 +102,7 @@ props.register(computed(() => ({ name: props.field.name, label: props.label, id
|
|
|
102
102
|
// This ensures errors persist when Field components re-mount due to :key changes
|
|
103
103
|
const _errors = computed(() => {
|
|
104
104
|
const fieldMeta = formFieldMeta.value[props.field.name] as any
|
|
105
|
+
// Treat errors as an array (like useOmegaForm does)
|
|
105
106
|
return fieldMeta?.errors ?? []
|
|
106
107
|
})
|
|
107
108
|
const errors = computed(() =>
|
|
@@ -962,8 +962,18 @@ export const useOmegaForm = <
|
|
|
962
962
|
// /** @experimental */
|
|
963
963
|
handleSubmitEffect,
|
|
964
964
|
registerField: (field: ComputedRef<{ name: string; label: string; id: string }>) => {
|
|
965
|
-
watch(field, (f) =>
|
|
966
|
-
|
|
965
|
+
watch(field, (f) => {
|
|
966
|
+
fieldMap.value.set(f.name, { label: f.label, id: f.id })
|
|
967
|
+
}, { immediate: true })
|
|
968
|
+
onUnmounted(() => {
|
|
969
|
+
// Only delete if we still own this entry (id matches)
|
|
970
|
+
// This prevents old components from deleting entries registered by new components
|
|
971
|
+
// during re-mount transitions (e.g., when :key changes)
|
|
972
|
+
const currentEntry = fieldMap.value.get(field.value.name)
|
|
973
|
+
if (currentEntry?.id === field.value.id) {
|
|
974
|
+
fieldMap.value.delete(field.value.name)
|
|
975
|
+
}
|
|
976
|
+
})
|
|
967
977
|
}
|
|
968
978
|
})
|
|
969
979
|
|
|
@@ -5,7 +5,9 @@ const Key = Symbol("injected") as InjectionKey<Map<string, { label: string; id:
|
|
|
5
5
|
|
|
6
6
|
export const useRegisterField = (field: ComputedRef<{ name: string; label: string; id: string }>) => {
|
|
7
7
|
const map = injectCertain(Key)
|
|
8
|
-
watch(field, (f) =>
|
|
8
|
+
watch(field, (f) => {
|
|
9
|
+
map.set(f.name, { label: f.label, id: f.id })
|
|
10
|
+
}, { immediate: true })
|
|
9
11
|
onUnmounted(() => map.delete(field.value.name)) // todo; perhap only when owned
|
|
10
12
|
}
|
|
11
13
|
|