@effect-app/vue-components 0.3.3 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/types/components/OmegaForm/OmegaFormStuff.d.ts +13 -0
- package/dist/types/components/OmegaForm/OmegaInput.vue.d.ts +2 -14
- package/dist/types/components/OmegaForm/OmegaWrapper.vue.d.ts +7 -3
- package/dist/types/components/OmegaForm/index.d.ts +2 -42
- package/dist/types/components/OmegaForm/useOmegaForm.d.ts +6 -2
- package/dist/vue-components.es11.js +43 -33
- package/dist/vue-components.es15.js +1 -1
- package/dist/vue-components.es16.js +2 -93
- package/dist/vue-components.es17.js +93 -11
- package/dist/vue-components.es18.js +11 -2
- package/dist/vue-components.es19.js +1 -1
- package/dist/vue-components.es5.js +88 -61
- package/dist/vue-components.es7.js +2 -2
- package/dist/vue-components.es8.js +1 -1
- package/package.json +3 -1
- package/src/components/OmegaForm/OmegaFormStuff.ts +11 -0
- package/src/components/OmegaForm/OmegaInput.vue +2 -15
- package/src/components/OmegaForm/OmegaWrapper.vue +61 -23
- package/src/components/OmegaForm/index.ts +3 -3
- package/src/components/OmegaForm/useOmegaForm.ts +50 -4
- package/src/stories/OmegaForm/ComplexForm.vue +39 -33
- package/src/stories/OmegaForm/EmailForm.vue +1 -1
- package/src/stories/OmegaForm/Meta.vue +1 -1
- package/src/stories/OmegaForm/OneHundredWaysToWriteAForm.vue +188 -0
- package/src/stories/OmegaForm/PersistencyForm.vue +6 -6
- package/src/stories/OmegaForm/SimpleForm.vue +1 -1
- package/src/stories/OmegaForm/SimpleFormVuetifyDefault.vue +1 -1
- package/src/stories/OmegaForm/SumExample.vue +3 -5
- package/src/stories/OmegaForm/form.Input.vue +86 -0
- package/src/stories/OmegaForm.stories.ts +16 -1
|
@@ -1,125 +1,152 @@
|
|
|
1
|
-
import { useForm as
|
|
2
|
-
import { S as
|
|
1
|
+
import { useForm as P } from "@tanstack/vue-form";
|
|
2
|
+
import { S as A } from "effect-app";
|
|
3
3
|
import { generateMetaFromSchema as N } from "./vue-components.es6.js";
|
|
4
|
-
import { computed as
|
|
5
|
-
import { isObject as
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
import { computed as b, onUnmounted as R, onMounted as p, onBeforeUnmount as q, defineComponent as D, h as J } from "vue";
|
|
5
|
+
import { isObject as K } from "./vue-components.es15.js";
|
|
6
|
+
import M from "./vue-components.es8.js";
|
|
7
|
+
const G = (w, s, i) => {
|
|
8
|
+
if (!w) throw new Error("Schema is required");
|
|
9
|
+
const V = A.standardSchemaV1(w), { filterItems: L, meta: t } = N(w), d = b(() => {
|
|
9
10
|
var l;
|
|
10
11
|
if ((l = i == null ? void 0 : i.persistency) != null && l.id)
|
|
11
12
|
return i.persistency.id;
|
|
12
13
|
const e = window.location.pathname, r = Object.keys(t);
|
|
13
14
|
return `${e}-${r.join("-")}`;
|
|
14
|
-
}),
|
|
15
|
+
}), U = () => {
|
|
15
16
|
const e = new URLSearchParams(window.location.search);
|
|
16
|
-
e.delete(
|
|
17
|
+
e.delete(d.value);
|
|
17
18
|
const r = new URL(window.location.href);
|
|
18
19
|
r.search = e.toString(), window.history.replaceState({}, "", r.toString());
|
|
19
20
|
};
|
|
20
|
-
function
|
|
21
|
+
function h(e, r) {
|
|
21
22
|
for (const l in r)
|
|
22
|
-
r[l] &&
|
|
23
|
+
r[l] && K(r[l]) ? (e[l] || (e[l] = {}), h(e[l], r[l])) : e[l] = r[l];
|
|
23
24
|
return e;
|
|
24
25
|
}
|
|
25
|
-
const
|
|
26
|
+
const j = b(() => {
|
|
26
27
|
var l;
|
|
27
|
-
if (
|
|
28
|
-
return
|
|
28
|
+
if (s != null && s.defaultValues && !((l = i == null ? void 0 : i.persistency) != null && l.overrideDefaultValues))
|
|
29
|
+
return s == null ? void 0 : s.defaultValues;
|
|
29
30
|
let e;
|
|
30
31
|
const r = i == null ? void 0 : i.persistency;
|
|
31
32
|
if (!(r != null && r.policies) || r.policies.length === 0) return {};
|
|
32
33
|
if (r.policies.includes("querystring"))
|
|
33
34
|
try {
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
} catch (
|
|
37
|
-
console.error(
|
|
35
|
+
const n = new URLSearchParams(window.location.search).get(d.value);
|
|
36
|
+
U(), n && (e = JSON.parse(n));
|
|
37
|
+
} catch (u) {
|
|
38
|
+
console.error(u);
|
|
38
39
|
}
|
|
39
40
|
if (
|
|
40
41
|
// query string has higher priority than local/session storage
|
|
41
42
|
!e && (r.policies.includes("local") || r.policies.includes("session"))
|
|
42
43
|
) {
|
|
43
|
-
const
|
|
44
|
-
if (
|
|
44
|
+
const u = r.policies.includes("local") ? localStorage : sessionStorage;
|
|
45
|
+
if (u)
|
|
45
46
|
try {
|
|
46
|
-
const
|
|
47
|
-
|
|
47
|
+
const n = JSON.parse(
|
|
48
|
+
u.getItem(d.value) || "{}"
|
|
48
49
|
);
|
|
49
|
-
|
|
50
|
-
} catch (
|
|
51
|
-
console.error(
|
|
50
|
+
u.removeItem(d.value), e = n;
|
|
51
|
+
} catch (n) {
|
|
52
|
+
console.error(n);
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
|
-
if (e ?? (e = {}), (
|
|
55
|
+
if (e ?? (e = {}), (s == null ? void 0 : s.defaultValues) == null)
|
|
55
56
|
return e;
|
|
56
57
|
{
|
|
57
|
-
const
|
|
58
|
-
return
|
|
58
|
+
const u = s == null ? void 0 : s.defaultValues;
|
|
59
|
+
return h(u, e);
|
|
59
60
|
}
|
|
60
|
-
}),
|
|
61
|
-
...
|
|
61
|
+
}), c = P({
|
|
62
|
+
...s,
|
|
62
63
|
validators: {
|
|
63
|
-
onSubmit:
|
|
64
|
-
...(
|
|
64
|
+
onSubmit: V,
|
|
65
|
+
...(s == null ? void 0 : s.validators) || {}
|
|
65
66
|
},
|
|
66
|
-
onSubmit:
|
|
67
|
-
var
|
|
68
|
-
return (
|
|
67
|
+
onSubmit: s != null && s.onSubmit ? ({ formApi: e, meta: r, value: l }) => {
|
|
68
|
+
var u;
|
|
69
|
+
return (u = s.onSubmit) == null ? void 0 : u.call(s, {
|
|
69
70
|
formApi: e,
|
|
70
71
|
meta: r,
|
|
71
72
|
value: l
|
|
72
73
|
});
|
|
73
74
|
} : void 0,
|
|
74
|
-
defaultValues:
|
|
75
|
-
}),
|
|
75
|
+
defaultValues: j.value
|
|
76
|
+
}), E = () => {
|
|
76
77
|
Object.keys(t).forEach((e) => {
|
|
77
|
-
|
|
78
|
+
c.setFieldValue(e, void 0);
|
|
78
79
|
});
|
|
79
|
-
},
|
|
80
|
+
}, a = (e) => e.reduce(
|
|
80
81
|
(r, l) => {
|
|
81
|
-
const
|
|
82
|
-
return
|
|
82
|
+
const u = l.split(".");
|
|
83
|
+
return u.reduce((n, o, I) => (I === u.length - 1 ? n[o] = c.getFieldValue(l) : n[o] = n[o] ?? {}, n[o]), r), r;
|
|
83
84
|
},
|
|
84
85
|
{}
|
|
85
|
-
),
|
|
86
|
+
), S = (e) => {
|
|
86
87
|
if (e) {
|
|
87
88
|
if (Array.isArray(e.keys))
|
|
88
|
-
return
|
|
89
|
+
return a(e.keys);
|
|
89
90
|
if (Array.isArray(e.banKeys)) {
|
|
90
91
|
const r = Object.keys(t).filter(
|
|
91
92
|
(l) => {
|
|
92
|
-
var
|
|
93
|
-
return (
|
|
93
|
+
var u;
|
|
94
|
+
return (u = e.banKeys) == null ? void 0 : u.includes(l);
|
|
94
95
|
}
|
|
95
96
|
);
|
|
96
|
-
return
|
|
97
|
+
return a(r);
|
|
97
98
|
}
|
|
98
|
-
return
|
|
99
|
+
return c.store.state.values;
|
|
99
100
|
}
|
|
100
|
-
},
|
|
101
|
+
}, f = () => {
|
|
101
102
|
const e = i == null ? void 0 : i.persistency;
|
|
102
103
|
if (!(!(e != null && e.policies) || e.policies.length === 0) && (e.policies.includes("local") || e.policies.includes("session"))) {
|
|
103
104
|
const r = e.policies.includes("local") ? localStorage : sessionStorage;
|
|
104
105
|
if (!r) return;
|
|
105
|
-
const l =
|
|
106
|
-
return r.setItem(
|
|
106
|
+
const l = S(e);
|
|
107
|
+
return r.setItem(d.value, JSON.stringify(l));
|
|
107
108
|
}
|
|
108
|
-
},
|
|
109
|
+
}, v = () => {
|
|
109
110
|
const e = i == null ? void 0 : i.persistency;
|
|
110
111
|
if (!(!(e != null && e.policies) || e.policies.length === 0) && e.policies.includes("querystring")) {
|
|
111
|
-
const r =
|
|
112
|
-
l.set(
|
|
113
|
-
const
|
|
114
|
-
|
|
112
|
+
const r = S(e), l = new URLSearchParams(window.location.search);
|
|
113
|
+
l.set(d.value, JSON.stringify(r));
|
|
114
|
+
const u = new URL(window.location.href);
|
|
115
|
+
u.search = l.toString(), window.history.replaceState({}, "", u.toString());
|
|
115
116
|
}
|
|
116
117
|
};
|
|
117
|
-
|
|
118
|
-
window.addEventListener("beforeunload",
|
|
119
|
-
}),
|
|
120
|
-
window.removeEventListener("beforeunload",
|
|
121
|
-
})
|
|
118
|
+
R(f), p(() => {
|
|
119
|
+
window.addEventListener("beforeunload", f), window.addEventListener("blur", v);
|
|
120
|
+
}), q(() => {
|
|
121
|
+
window.removeEventListener("beforeunload", f), window.removeEventListener("blur", v);
|
|
122
|
+
});
|
|
123
|
+
const y = Object.assign(c, {
|
|
124
|
+
meta: t,
|
|
125
|
+
filterItems: L,
|
|
126
|
+
clear: E
|
|
127
|
+
});
|
|
128
|
+
return Object.assign(y, {
|
|
129
|
+
Input: D({
|
|
130
|
+
name: "FormInput",
|
|
131
|
+
inheritAttrs: !0,
|
|
132
|
+
setup(e, { attrs: r, slots: l }) {
|
|
133
|
+
const u = r.name, n = r.label;
|
|
134
|
+
if (!u || !n)
|
|
135
|
+
throw new Error("OmegaForm.Input requires name and label props");
|
|
136
|
+
return () => J(
|
|
137
|
+
M,
|
|
138
|
+
{
|
|
139
|
+
...r,
|
|
140
|
+
name: u,
|
|
141
|
+
label: n,
|
|
142
|
+
form: y
|
|
143
|
+
},
|
|
144
|
+
l
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
})
|
|
148
|
+
});
|
|
122
149
|
};
|
|
123
150
|
export {
|
|
124
|
-
|
|
151
|
+
G as useOmegaForm
|
|
125
152
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
(function(){"use strict";try{if(typeof document<"u"){var n=document.createElement("style");if(n.appendChild(document.createTextNode("fieldset[data-v-
|
|
1
|
+
(function(){"use strict";try{if(typeof document<"u"){var n=document.createElement("style");if(n.appendChild(document.createTextNode("fieldset[data-v-6833e150]{display:contents}")),document.head.appendChild(n),window.customElements){const e=window.customElements.define;window.customElements.define=function(i,t){const o=t.prototype.connectedCallback;return t.prototype.connectedCallback=function(){if(o&&o.call(this),this.shadowRoot){const d=document.createElement("style");d.appendChild(document.createTextNode("fieldset[data-v-6833e150]{display:contents}")),this.shadowRoot.appendChild(d)}},e.call(window.customElements,i,t)}}}}catch(e){console.error("vite-plugin-css-injected-by-js",e)}})();
|
|
2
2
|
import o from "./vue-components.es11.js";
|
|
3
3
|
import m from "./vue-components.es12.js";
|
|
4
|
-
const a = /* @__PURE__ */ m(o, [["__scopeId", "data-v-
|
|
4
|
+
const a = /* @__PURE__ */ m(o, [["__scopeId", "data-v-6833e150"]]);
|
|
5
5
|
export {
|
|
6
6
|
a as default
|
|
7
7
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineComponent as i, computed as t, createBlock as p, openBlock as d, resolveDynamicComponent as u, withCtx as r, createVNode as f, mergeProps as c, renderSlot as v, normalizeProps as h, guardReactiveProps as g } from "vue";
|
|
2
2
|
import { generateInputStandardSchemaFromFieldMeta as y } from "./vue-components.es6.js";
|
|
3
|
-
import b from "./vue-components.
|
|
3
|
+
import b from "./vue-components.es17.js";
|
|
4
4
|
const S = /* @__PURE__ */ i({
|
|
5
5
|
inheritAttrs: !1,
|
|
6
6
|
__name: "OmegaInput",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect-app/vue-components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"@mdi/js": "^7.4.47",
|
|
6
6
|
"@tanstack/vue-form": "^1.2.4",
|
|
@@ -50,6 +50,8 @@
|
|
|
50
50
|
"./dist/vue-components.css": "./dist/vue-components.css"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
+
"highlight.js": "^11.11.1",
|
|
54
|
+
"vue3-highlightjs": "^1.0.5",
|
|
53
55
|
"@effect-app/vue": "2.40.1",
|
|
54
56
|
"effect-app": "2.39.1"
|
|
55
57
|
},
|
|
@@ -18,6 +18,17 @@ import { useIntl } from "../../utils"
|
|
|
18
18
|
|
|
19
19
|
export type ShowErrorsOn = "onChange" | "onBlur" | "onSubmit"
|
|
20
20
|
|
|
21
|
+
export type OmegaInputProps<From, To> = {
|
|
22
|
+
form: FormType<From, To> & {
|
|
23
|
+
meta: MetaRecord<To>
|
|
24
|
+
}
|
|
25
|
+
name: NestedKeyOf<To>
|
|
26
|
+
validators?: FieldValidators<From>
|
|
27
|
+
label: string
|
|
28
|
+
options?: { title: string; value: string }[]
|
|
29
|
+
type?: TypeOverride
|
|
30
|
+
}
|
|
31
|
+
|
|
21
32
|
export type TypeOverride =
|
|
22
33
|
| "string"
|
|
23
34
|
| "text"
|
|
@@ -28,25 +28,12 @@
|
|
|
28
28
|
import { computed } from "vue"
|
|
29
29
|
import {
|
|
30
30
|
generateInputStandardSchemaFromFieldMeta,
|
|
31
|
-
type
|
|
32
|
-
type FormType,
|
|
33
|
-
type MetaRecord,
|
|
34
|
-
type NestedKeyOf,
|
|
35
|
-
type TypeOverride,
|
|
31
|
+
type OmegaInputProps,
|
|
36
32
|
} from "./OmegaFormStuff"
|
|
37
33
|
import OmegaInternalInput from "./OmegaInternalInput.vue"
|
|
38
34
|
import type { OmegaFieldInternalApi } from "./InputProps"
|
|
39
35
|
|
|
40
|
-
const props = defineProps<
|
|
41
|
-
form: FormType<From, To> & {
|
|
42
|
-
meta: MetaRecord<To>
|
|
43
|
-
}
|
|
44
|
-
name: NestedKeyOf<To>
|
|
45
|
-
validators?: FieldValidators<From>
|
|
46
|
-
label: string
|
|
47
|
-
options?: { title: string; value: string }[]
|
|
48
|
-
type?: TypeOverride
|
|
49
|
-
}>()
|
|
36
|
+
const props = defineProps<OmegaInputProps<From, To>>()
|
|
50
37
|
|
|
51
38
|
defineOptions({
|
|
52
39
|
inheritAttrs: false,
|
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<form novalidate @submit.prevent.stop="
|
|
2
|
+
<form novalidate @submit.prevent.stop="formToUse.handleSubmit()">
|
|
3
3
|
<fieldset :disabled="formIsSubmitting">
|
|
4
|
-
|
|
4
|
+
<!-- Render externalForm + default slots if props.form is provided -->
|
|
5
|
+
<template v-if="props.form">
|
|
6
|
+
<slot name="externalForm" :subscribed-values="subscribedValues" />
|
|
7
|
+
<slot />
|
|
8
|
+
<!-- default slot -->
|
|
9
|
+
</template>
|
|
10
|
+
<!-- Render internalForm slot if form was created locally -->
|
|
11
|
+
<slot
|
|
12
|
+
v-else-if="localForm"
|
|
13
|
+
name="internalForm"
|
|
14
|
+
:form="localForm"
|
|
15
|
+
:subscribed-values="subscribedValues"
|
|
16
|
+
/>
|
|
5
17
|
</fieldset>
|
|
6
18
|
</form>
|
|
7
19
|
</template>
|
|
@@ -62,7 +74,7 @@ import {
|
|
|
62
74
|
type OmegaFormReturn,
|
|
63
75
|
useOmegaForm,
|
|
64
76
|
} from "./useOmegaForm"
|
|
65
|
-
import { watch } from "vue"
|
|
77
|
+
import { computed, watch, defineSlots } from "vue"
|
|
66
78
|
|
|
67
79
|
const props = defineProps<
|
|
68
80
|
{
|
|
@@ -81,32 +93,40 @@ const props = defineProps<
|
|
|
81
93
|
)
|
|
82
94
|
>()
|
|
83
95
|
|
|
84
|
-
const
|
|
85
|
-
props.form
|
|
96
|
+
const localForm = computed(() => {
|
|
97
|
+
if (props.form || !props.schema) {
|
|
98
|
+
return undefined
|
|
99
|
+
}
|
|
100
|
+
return useOmegaForm<From, To>(props.schema, props, props.omegaConfig)
|
|
101
|
+
})
|
|
86
102
|
|
|
87
|
-
const
|
|
103
|
+
const formToUse = computed(() => props.form ?? localForm.value!)
|
|
88
104
|
|
|
89
|
-
|
|
105
|
+
const formIsSubmitting = useStore(
|
|
106
|
+
formToUse.value.store,
|
|
107
|
+
state => state.isSubmitting,
|
|
108
|
+
)
|
|
90
109
|
|
|
91
110
|
const subscribedValues = getOmegaStore(
|
|
92
|
-
|
|
111
|
+
formToUse.value as OmegaFormApi<To, From>,
|
|
93
112
|
props.subscribe,
|
|
94
113
|
)
|
|
95
114
|
|
|
96
115
|
const formSubmissionAttempts = useStore(
|
|
97
|
-
|
|
116
|
+
formToUse.value.store,
|
|
98
117
|
state => state.submissionAttempts,
|
|
99
118
|
)
|
|
100
119
|
|
|
101
|
-
const errors =
|
|
120
|
+
const errors = computed(() => formToUse.value.useStore(state => state.errors))
|
|
102
121
|
|
|
103
122
|
watch(
|
|
104
|
-
() => [
|
|
123
|
+
() => [formToUse.value.filterItems, errors.value.value],
|
|
105
124
|
() => {
|
|
106
|
-
const filterItems: FilterItems | undefined =
|
|
125
|
+
const filterItems: FilterItems | undefined = formToUse.value.filterItems
|
|
126
|
+
const currentErrors = errors.value.value
|
|
107
127
|
if (!filterItems) return {}
|
|
108
|
-
if (!
|
|
109
|
-
const errorList = Object.values(
|
|
128
|
+
if (!currentErrors) return {}
|
|
129
|
+
const errorList = Object.values(currentErrors)
|
|
110
130
|
.filter(
|
|
111
131
|
(fieldErrors): fieldErrors is Record<string, StandardSchemaV1Issue[]> =>
|
|
112
132
|
Boolean(fieldErrors),
|
|
@@ -116,22 +136,40 @@ watch(
|
|
|
116
136
|
.flat()
|
|
117
137
|
.map((issue: StandardSchemaV1Issue) => issue.message),
|
|
118
138
|
)
|
|
139
|
+
|
|
119
140
|
if (errorList.some(e => e === filterItems.message)) {
|
|
120
|
-
filterItems.items
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
141
|
+
// TODO: Investigate if filterItems.items should be typed based on DeepKeys<To>.
|
|
142
|
+
filterItems.items.forEach((item: keyof From) => {
|
|
143
|
+
const m = formToUse.value.getFieldMeta(item as any)
|
|
144
|
+
if (m) {
|
|
145
|
+
formToUse.value.setFieldMeta(item as any, {
|
|
146
|
+
...m,
|
|
147
|
+
errorMap: {
|
|
148
|
+
onSubmit: [
|
|
149
|
+
{ path: [item as string], message: filterItems.message },
|
|
150
|
+
],
|
|
151
|
+
},
|
|
152
|
+
})
|
|
153
|
+
}
|
|
128
154
|
})
|
|
129
155
|
}
|
|
130
156
|
return {}
|
|
131
157
|
},
|
|
132
158
|
)
|
|
133
159
|
|
|
134
|
-
provideOmegaErrors(formSubmissionAttempts, errors, props.showErrorsOn)
|
|
160
|
+
provideOmegaErrors(formSubmissionAttempts, errors.value, props.showErrorsOn)
|
|
161
|
+
|
|
162
|
+
defineSlots<{
|
|
163
|
+
// Default slot (no props)
|
|
164
|
+
default(): void
|
|
165
|
+
// Named slot when form is created internally via schema
|
|
166
|
+
internalForm(props: {
|
|
167
|
+
form: OmegaFormReturn<To, From>
|
|
168
|
+
subscribedValues: typeof subscribedValues.value
|
|
169
|
+
}): void
|
|
170
|
+
// Named slot when form is passed via props (provides subscribedValues)
|
|
171
|
+
externalForm(props: { subscribedValues: typeof subscribedValues.value }): void
|
|
172
|
+
}>()
|
|
135
173
|
</script>
|
|
136
174
|
|
|
137
175
|
<style scoped>
|
|
@@ -10,9 +10,9 @@ export { default } from "./OmegaWrapper.vue"
|
|
|
10
10
|
|
|
11
11
|
export { OmegaForm, OmegaInput, OmegaErrors }
|
|
12
12
|
|
|
13
|
-
const OmegaFormCE = defineCustomElement(OmegaForm)
|
|
14
|
-
const OmegaInputCE = defineCustomElement(OmegaInput)
|
|
15
|
-
const OmegaErrorsCE = defineCustomElement(OmegaErrors)
|
|
13
|
+
const OmegaFormCE = defineCustomElement(OmegaForm as any)
|
|
14
|
+
const OmegaInputCE = defineCustomElement(OmegaInput as any)
|
|
15
|
+
const OmegaErrorsCE = defineCustomElement(OmegaErrors as any)
|
|
16
16
|
|
|
17
17
|
export { OmegaFormCE, OmegaInputCE, OmegaErrorsCE }
|
|
18
18
|
|
|
@@ -13,9 +13,20 @@ import {
|
|
|
13
13
|
type FormProps,
|
|
14
14
|
type MetaRecord,
|
|
15
15
|
type OmegaFormApi,
|
|
16
|
+
type OmegaInputProps,
|
|
16
17
|
} from "./OmegaFormStuff"
|
|
17
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
computed,
|
|
20
|
+
onBeforeUnmount,
|
|
21
|
+
onMounted,
|
|
22
|
+
onUnmounted,
|
|
23
|
+
defineComponent,
|
|
24
|
+
h,
|
|
25
|
+
type DefineComponent,
|
|
26
|
+
type Component,
|
|
27
|
+
} from "vue"
|
|
18
28
|
import { isObject } from "effect/Predicate"
|
|
29
|
+
import OmegaInput from "./OmegaInput.vue"
|
|
19
30
|
|
|
20
31
|
type keysRule<T> =
|
|
21
32
|
| {
|
|
@@ -39,11 +50,14 @@ export type OmegaConfig<T> = {
|
|
|
39
50
|
} & keysRule<T>
|
|
40
51
|
}
|
|
41
52
|
|
|
42
|
-
|
|
53
|
+
interface OF<To, From> extends OmegaFormApi<To, From> {
|
|
43
54
|
meta: MetaRecord<To>
|
|
44
55
|
filterItems?: FilterItems
|
|
45
56
|
clear: () => void
|
|
46
57
|
}
|
|
58
|
+
export interface OmegaFormReturn<To, From> extends OF<To, From> {
|
|
59
|
+
Input: DefineComponent<Omit<OmegaInputProps<From, To>, "form">, {}, {}>
|
|
60
|
+
}
|
|
47
61
|
|
|
48
62
|
export const useOmegaForm = <
|
|
49
63
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -265,7 +279,39 @@ export const useOmegaForm = <
|
|
|
265
279
|
window.removeEventListener("blur", saveDataInUrl)
|
|
266
280
|
})
|
|
267
281
|
|
|
268
|
-
const
|
|
282
|
+
const formWithExtras: OF<To, From> = Object.assign(form, {
|
|
283
|
+
meta,
|
|
284
|
+
filterItems,
|
|
285
|
+
clear,
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
return Object.assign(formWithExtras, {
|
|
289
|
+
Input: defineComponent({
|
|
290
|
+
name: "FormInput",
|
|
291
|
+
inheritAttrs: true,
|
|
292
|
+
setup(_, { attrs, slots }) {
|
|
293
|
+
const name = attrs.name as NestedKeyOf<To>
|
|
294
|
+
const label = attrs.label as string
|
|
295
|
+
if (!name || !label) {
|
|
296
|
+
throw new Error("OmegaForm.Input requires name and label props")
|
|
297
|
+
}
|
|
269
298
|
|
|
270
|
-
|
|
299
|
+
return () =>
|
|
300
|
+
h(
|
|
301
|
+
OmegaInput as Component,
|
|
302
|
+
{
|
|
303
|
+
...attrs,
|
|
304
|
+
name,
|
|
305
|
+
label,
|
|
306
|
+
form: formWithExtras,
|
|
307
|
+
},
|
|
308
|
+
slots,
|
|
309
|
+
)
|
|
310
|
+
},
|
|
311
|
+
}) as any as DefineComponent<
|
|
312
|
+
Omit<OmegaInputProps<From, To>, "form">,
|
|
313
|
+
{},
|
|
314
|
+
{}
|
|
315
|
+
>,
|
|
316
|
+
})
|
|
271
317
|
}
|
|
@@ -1,36 +1,42 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<OmegaForm :form="
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
2
|
+
<OmegaForm :form="exampleForm">
|
|
3
|
+
<OmegaInput label="aString" :form="exampleForm" name="aString" />
|
|
4
|
+
<OmegaInput label="aStringMin2" :form="exampleForm" name="aStringMin2" />
|
|
5
|
+
<OmegaInput
|
|
6
|
+
label="aStringMin2Max4"
|
|
7
|
+
:form="exampleForm"
|
|
8
|
+
name="aStringMin2Max4"
|
|
9
|
+
/>
|
|
10
|
+
<OmegaInput
|
|
11
|
+
label="aStringMin2Max3Nullable"
|
|
12
|
+
:form="exampleForm"
|
|
13
|
+
name="aStringMin2Max3Nullable"
|
|
14
|
+
/>
|
|
15
|
+
<OmegaInput label="aNumber" :form="exampleForm" name="aNumber" />
|
|
16
|
+
<OmegaInput label="aNumberMin2" :form="exampleForm" name="aNumberMin2" />
|
|
17
|
+
<OmegaInput
|
|
18
|
+
label="aNumberMin2Max"
|
|
19
|
+
:form="exampleForm"
|
|
20
|
+
name="aNumberMin2Max"
|
|
21
|
+
/>
|
|
22
|
+
<OmegaInput
|
|
23
|
+
label="aNumberMin2Max4Nullable"
|
|
24
|
+
:form="exampleForm"
|
|
25
|
+
name="aNumberMin2Max4Nullable"
|
|
26
|
+
/>
|
|
27
|
+
<OmegaInput
|
|
28
|
+
label="aSelect"
|
|
29
|
+
:form="exampleForm"
|
|
30
|
+
name="aSelect"
|
|
31
|
+
:options="[
|
|
32
|
+
{ title: 'a', value: 'a' },
|
|
33
|
+
{ title: 'b', value: 'b' },
|
|
34
|
+
{ title: 'c', value: 'c' },
|
|
35
|
+
]"
|
|
36
|
+
/>
|
|
37
|
+
<button>Submit</button>
|
|
38
|
+
<button type="reset" @click.prevent="exampleForm.clear()">Clear</button>
|
|
39
|
+
<button type="button" @click="exampleForm.reset()">Reset</button>
|
|
34
40
|
</OmegaForm>
|
|
35
41
|
</template>
|
|
36
42
|
|
|
@@ -38,7 +44,7 @@
|
|
|
38
44
|
import { S } from "effect-app"
|
|
39
45
|
import { OmegaForm, OmegaInput, useOmegaForm } from "../../components/OmegaForm"
|
|
40
46
|
|
|
41
|
-
const
|
|
47
|
+
const exampleForm = useOmegaForm(
|
|
42
48
|
S.Struct({
|
|
43
49
|
aString: S.String,
|
|
44
50
|
aStringMin2: S.String.pipe(S.minLength(2)),
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
:on-submit="onSubmit"
|
|
5
5
|
:default-values="defaultValues"
|
|
6
6
|
>
|
|
7
|
-
<template #
|
|
7
|
+
<template #internalForm="{ form }">
|
|
8
8
|
<OmegaInput label="email" name="email" :form="form" />
|
|
9
9
|
<OmegaInput label="confirm" name="confirm" :form="form" />
|
|
10
10
|
<button>submit</button>
|