@effect-app/vue-components 0.4.6 → 0.6.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.
Files changed (48) hide show
  1. package/dist/types/components/OmegaForm/OmegaAutoGen.vue.d.ts +30 -0
  2. package/dist/types/components/OmegaForm/OmegaFormStuff.d.ts +1 -1
  3. package/dist/types/components/OmegaForm/OmegaWrapper.vue.d.ts +5 -5
  4. package/dist/types/components/OmegaForm/index.d.ts +2 -6
  5. package/dist/types/components/OmegaForm/useOmegaForm.d.ts +1 -1
  6. package/dist/vue-components.es.js +24 -27
  7. package/dist/vue-components.es10.js +6 -23
  8. package/dist/vue-components.es11.js +76 -43
  9. package/dist/vue-components.es15.js +1 -1
  10. package/dist/vue-components.es17.js +2 -5
  11. package/dist/vue-components.es18.js +5 -32
  12. package/dist/vue-components.es19.js +32 -2
  13. package/dist/vue-components.es2.js +16 -19
  14. package/dist/vue-components.es20.js +98 -2
  15. package/dist/vue-components.es21.js +11 -96
  16. package/dist/vue-components.es22.js +2 -11
  17. package/dist/vue-components.es23.js +1 -1
  18. package/dist/vue-components.es24.js +2 -115
  19. package/dist/vue-components.es25.js +117 -0
  20. package/dist/{vue-components.es26.js → vue-components.es27.js} +1 -1
  21. package/dist/vue-components.es3.js +3 -3
  22. package/dist/vue-components.es4.js +2 -2
  23. package/dist/vue-components.es5.js +78 -36
  24. package/dist/vue-components.es6.js +34 -131
  25. package/dist/vue-components.es7.js +128 -211
  26. package/dist/vue-components.es8.js +216 -6
  27. package/dist/vue-components.es9.js +4 -4
  28. package/package.json +9 -3
  29. package/src/components/OmegaForm/OmegaAutoGen.vue +110 -0
  30. package/src/components/OmegaForm/OmegaErrors.vue +3 -3
  31. package/src/components/OmegaForm/OmegaFormStuff.ts +1 -1
  32. package/src/components/OmegaForm/OmegaInternalInput.vue +9 -6
  33. package/src/components/OmegaForm/OmegaWrapper.vue +59 -12
  34. package/src/components/OmegaForm/index.ts +2 -19
  35. package/src/components/OmegaForm/useOmegaForm.ts +1 -1
  36. package/src/env.d.ts +0 -8
  37. package/src/stories/OmegaForm/ComplexForm.vue +0 -87
  38. package/src/stories/OmegaForm/EmailForm.vue +0 -48
  39. package/src/stories/OmegaForm/Meta.vue +0 -47
  40. package/src/stories/OmegaForm/OneHundredWaysToWriteAForm.vue +0 -188
  41. package/src/stories/OmegaForm/PersistencyForm.vue +0 -58
  42. package/src/stories/OmegaForm/SimpleForm.vue +0 -30
  43. package/src/stories/OmegaForm/SimpleFormVuetifyDefault.vue +0 -15
  44. package/src/stories/OmegaForm/SumExample.vue +0 -37
  45. package/src/stories/OmegaForm/form.Input.vue +0 -98
  46. package/src/stories/OmegaForm.stories.ts +0 -106
  47. package/src/stories/README.md +0 -29
  48. package/src/stories/tsconfig.json +0 -4
@@ -1,8 +1,218 @@
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
- import o from "./vue-components.es11.js";
3
-
4
- import m from "./vue-components.es13.js";
5
- const e = /* @__PURE__ */ m(o, [["__scopeId", "data-v-6833e150"]]);
1
+ import { S as i, pipe as p, Option as f } from "effect-app";
2
+ import { useIntl as S } from "./vue-components.es3.js";
3
+ const y = i.NonEmptyArray(i.String), v = (e) => i.AST.isUnion(e) && e.types.find((t) => t._tag === "UndefinedKeyword" || t === i.Null.ast), x = (e) => !e || !i.AST.isUnion(e) ? !1 : e.types.find((t) => t._tag === "UndefinedKeyword") ? "undefined" : e.types.find((t) => t === i.Null.ast) ? "null" : !1, m = ({ meta: e = {}, parent: t = "", property: n, propertySignatures: a }, l = {}) => {
4
+ if (n && n._tag === "Transformation")
5
+ return m({
6
+ parent: t,
7
+ meta: e,
8
+ property: n.from
9
+ });
10
+ if ((n == null ? void 0 : n._tag) === "TypeLiteral" && "propertySignatures" in n)
11
+ return m({
12
+ meta: e,
13
+ propertySignatures: n.propertySignatures
14
+ });
15
+ if (a) {
16
+ for (const s of a) {
17
+ const u = t ? `${t}.${s.name.toString()}` : s.name.toString(), r = x(s.type), o = !r;
18
+ let d = s.type;
19
+ if (i.AST.isUnion(s.type) && (d = s.type.types.find(
20
+ (g) => g._tag !== "UndefinedKeyword" && g !== i.Null.ast
21
+ )), "propertySignatures" in d)
22
+ Object.assign(
23
+ l,
24
+ m({
25
+ parent: u,
26
+ propertySignatures: d.propertySignatures,
27
+ meta: { required: o, nullableOrUndefined: r }
28
+ })
29
+ );
30
+ else {
31
+ const g = m({
32
+ parent: u,
33
+ property: s.type,
34
+ meta: { required: o, nullableOrUndefined: r }
35
+ });
36
+ l[u] = g;
37
+ }
38
+ }
39
+ return l;
40
+ }
41
+ if (n) {
42
+ const s = v(n);
43
+ if (Object.hasOwnProperty.call(e, "required") || (e.required = !s), i.AST.isUnion(n)) {
44
+ const r = n.types.find(
45
+ (o) => o._tag !== "UndefinedKeyword" && o !== i.Null.ast
46
+ );
47
+ return "propertySignatures" in r ? m({
48
+ propertySignatures: r.propertySignatures,
49
+ parent: t,
50
+ meta: e
51
+ }) : n.types.every(i.AST.isLiteral) ? {
52
+ ...e,
53
+ type: "select",
54
+ members: n.types.map((o) => o.literal)
55
+ } : {
56
+ ...e,
57
+ ...m({
58
+ parent: t,
59
+ meta: e,
60
+ property: r
61
+ })
62
+ };
63
+ }
64
+ if (i.AST.isTupleType(n))
65
+ return {
66
+ ...e,
67
+ type: "multiple",
68
+ members: n.elements
69
+ };
70
+ const u = i.AST.getAnnotation(
71
+ n,
72
+ i.AST.JSONSchemaAnnotationId
73
+ ).pipe(f.getOrElse(() => ({})));
74
+ return e = { ...e, ...u }, "from" in n ? m({
75
+ parent: t,
76
+ meta: e,
77
+ property: n.from
78
+ }) : (e.type = i.AST.getAnnotation(
79
+ n,
80
+ i.AST.TitleAnnotationId
81
+ ).pipe(
82
+ f.getOrElse(() => "unknown")
83
+ ), e);
84
+ }
85
+ return l;
86
+ }, c = (e) => {
87
+ const t = e.ast, n = {};
88
+ if (t._tag === "Transformation" || t._tag === "Refinement")
89
+ return c(i.make(t.from));
90
+ if ("propertySignatures" in t) {
91
+ const a = m({
92
+ propertySignatures: t.propertySignatures
93
+ });
94
+ if (Object.values(a).every((s) => s && "type" in s))
95
+ return a;
96
+ const l = (s, u = "") => {
97
+ for (const r in s) {
98
+ const o = u ? `${u}.${r}` : r;
99
+ s[r] && typeof s[r] == "object" && "type" in s[r] ? n[o] = s[r] : s[r] && typeof s[r] == "object" && l(s[r], o);
100
+ }
101
+ };
102
+ l(a);
103
+ }
104
+ return n;
105
+ }, b = (e) => i.extend(e, i.Struct({})), A = (e) => {
106
+ const t = c(e), n = p(
107
+ e.ast,
108
+ f.liftPredicate((a) => a._tag === "Refinement" && "filter" in a),
109
+ f.flatMap((a) => i.AST.getJSONSchemaAnnotation(a)),
110
+ f.filter((a) => "items" in a),
111
+ f.filterMap(
112
+ ({ items: a }) => i.decodeUnknownOption(y)(a)
113
+ ),
114
+ f.zipWith(
115
+ i.AST.getMessageAnnotation(e.ast),
116
+ (a, l) => ({
117
+ items: a,
118
+ message: l("")
119
+ })
120
+ ),
121
+ f.getOrUndefined
122
+ );
123
+ return { schema: e, meta: t, filterItems: n };
124
+ }, O = (e) => {
125
+ const { trans: t } = S();
126
+ let n;
127
+ switch (e.type) {
128
+ case "string":
129
+ n = i.String.annotations({
130
+ message: () => t("validation.empty")
131
+ }), e.format === "email" && (n = i.compose(
132
+ n,
133
+ i.Email.annotations({
134
+ message: () => t("validation.email.invalid")
135
+ })
136
+ )), e.required && n.annotations({
137
+ message: () => t("validation.empty")
138
+ }), e.maxLength && (n = n.pipe(i.maxLength(e.maxLength)).annotations({
139
+ message: () => t("validation.string.maxLength", {
140
+ maxLength: e.maxLength
141
+ })
142
+ })), e.minLength && (n = n.pipe(i.minLength(e.minLength)).annotations({
143
+ message: () => t("validation.string.minLength", {
144
+ minLength: e.minLength
145
+ })
146
+ }));
147
+ break;
148
+ case "number":
149
+ n = i.Number.annotations({
150
+ message: () => t("validation.empty")
151
+ }), e.required && n.annotations({
152
+ message: () => t("validation.empty")
153
+ }), e.minimum && (n = n.pipe(i.greaterThanOrEqualTo(e.minimum)).annotations({
154
+ message: () => t("validation.number.min", {
155
+ minimum: e.minimum,
156
+ isExclusive: !0
157
+ })
158
+ })), e.maximum && (n = n.pipe(i.lessThanOrEqualTo(e.maximum)).annotations({
159
+ message: () => t("validation.number.max", {
160
+ maximum: e.maximum,
161
+ isExclusive: !0
162
+ })
163
+ })), e.exclusiveMinimum && (n = n.pipe(i.greaterThan(e.exclusiveMinimum)).annotations({
164
+ message: () => t("validation.number.min", {
165
+ minimum: e.exclusiveMinimum,
166
+ isExclusive: !1
167
+ })
168
+ })), e.exclusiveMaximum && (n = n.pipe(i.lessThan(e.exclusiveMaximum)).annotations({
169
+ message: () => t("validation.number.max", {
170
+ maximum: e.exclusiveMaximum,
171
+ isExclusive: !1
172
+ })
173
+ }));
174
+ break;
175
+ case "select":
176
+ n = i.Literal(...e.members).annotations({
177
+ message: () => ({
178
+ message: t("validation.not_a_valid", {
179
+ type: "select",
180
+ message: e.members.join(", ")
181
+ }),
182
+ override: !0
183
+ })
184
+ });
185
+ break;
186
+ case "multiple":
187
+ n = i.Array(i.String).annotations({
188
+ message: () => t("validation.not_a_valid", {
189
+ type: "multiple",
190
+ message: e.members.join(", ")
191
+ })
192
+ });
193
+ break;
194
+ case "boolean":
195
+ n = i.Boolean;
196
+ break;
197
+ // todo: switch must be exhaustive or have default case, otherwise falls through with schema undefined.
198
+ case "unknown":
199
+ n = i.Unknown;
200
+ break;
201
+ }
202
+ return e.required ? n.pipe(
203
+ i.annotations({
204
+ message: () => t("validation.empty")
205
+ })
206
+ ) : n = i.NullishOr(n), i.standardSchemaV1(n);
207
+ }, L = (e, t) => i.NullOr(e).pipe(
208
+ i.transform(i.typeSchema(e), {
209
+ decode: (n) => n ?? t(),
210
+ encode: (n) => n
211
+ })
212
+ );
6
213
  export {
7
- e as default
214
+ b as duplicateSchema,
215
+ O as generateInputStandardSchemaFromFieldMeta,
216
+ A as generateMetaFromSchema,
217
+ L as nullableInput
8
218
  };
@@ -1,8 +1,8 @@
1
- (function(){"use strict";try{if(typeof document<"u"){var t=document.createElement("style");if(t.appendChild(document.createTextNode(".v-enter-from[data-v-502ecb3a],.v-leave-to[data-v-502ecb3a]{max-height:0px;grid-template-rows:0fr;opacity:0}.v-enter-active[data-v-502ecb3a],.v-leave-active[data-v-502ecb3a]{display:grid;transition:all .15s}.v-enter-to[data-v-502ecb3a],.v-leave-from[data-v-502ecb3a]{grid-template-rows:1fr;max-height:50vh;opacity:1}.error-alert[data-v-502ecb3a]{transition-behavior:allow-discrete;display:grid;overflow:hidden;min-height:0}.error-alert>*[data-v-502ecb3a]{min-height:0}.error-list[data-v-502ecb3a]{container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;gap:.5em;align-items:start}@container (max-width: 28.125rem){.error-list[data-v-502ecb3a]{grid-template-columns:auto 1fr}.error-link[data-v-502ecb3a]{grid-column:1 / -1;justify-self:end}}@container (max-width: 18.75rem){.error-list[data-v-502ecb3a]{grid-template-columns:1fr}.error-message[data-v-502ecb3a]{grid-column:1 / -1}}.error-item[data-v-502ecb3a]{display:contents}a[data-v-502ecb3a]{min-width:min-content}.error-link[data-v-502ecb3a]{align-items:center;color:inherit;display:inline-flex;flex-wrap:wrap;gap:.25em;padding-bottom:1em;text-decoration:none}")),document.head.appendChild(t),window.customElements){const e=window.customElements.define;window.customElements.define=function(n,a){const i=a.prototype.connectedCallback;return a.prototype.connectedCallback=function(){if(i&&i.call(this),this.shadowRoot){const r=document.createElement("style");r.appendChild(document.createTextNode(".v-enter-from[data-v-502ecb3a],.v-leave-to[data-v-502ecb3a]{max-height:0px;grid-template-rows:0fr;opacity:0}.v-enter-active[data-v-502ecb3a],.v-leave-active[data-v-502ecb3a]{display:grid;transition:all .15s}.v-enter-to[data-v-502ecb3a],.v-leave-from[data-v-502ecb3a]{grid-template-rows:1fr;max-height:50vh;opacity:1}.error-alert[data-v-502ecb3a]{transition-behavior:allow-discrete;display:grid;overflow:hidden;min-height:0}.error-alert>*[data-v-502ecb3a]{min-height:0}.error-list[data-v-502ecb3a]{container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;gap:.5em;align-items:start}@container (max-width: 28.125rem){.error-list[data-v-502ecb3a]{grid-template-columns:auto 1fr}.error-link[data-v-502ecb3a]{grid-column:1 / -1;justify-self:end}}@container (max-width: 18.75rem){.error-list[data-v-502ecb3a]{grid-template-columns:1fr}.error-message[data-v-502ecb3a]{grid-column:1 / -1}}.error-item[data-v-502ecb3a]{display:contents}a[data-v-502ecb3a]{min-width:min-content}.error-link[data-v-502ecb3a]{align-items:center;color:inherit;display:inline-flex;flex-wrap:wrap;gap:.25em;padding-bottom:1em;text-decoration:none}")),this.shadowRoot.appendChild(r)}},e.call(window.customElements,n,a)}}}}catch(e){console.error("vite-plugin-css-injected-by-js",e)}})();
2
- import o from "./vue-components.es15.js";
1
+ (function(){"use strict";try{if(typeof document<"u"){var n=document.createElement("style");if(n.appendChild(document.createTextNode("fieldset[data-v-a32b1c91]{display:contents}")),document.head.appendChild(n),window.customElements){const e=window.customElements.define;window.customElements.define=function(c,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-a32b1c91]{display:contents}")),this.shadowRoot.appendChild(d)}},e.call(window.customElements,c,t)}}}}catch(e){console.error("vite-plugin-css-injected-by-js",e)}})();
2
+ import o from "./vue-components.es11.js";
3
3
 
4
4
  import r from "./vue-components.es13.js";
5
- const e = /* @__PURE__ */ r(o, [["__scopeId", "data-v-502ecb3a"]]);
5
+ const m = /* @__PURE__ */ r(o, [["__scopeId", "data-v-a32b1c91"]]);
6
6
  export {
7
- e as default
7
+ m as default
8
8
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect-app/vue-components",
3
- "version": "0.4.6",
3
+ "version": "0.6.1",
4
4
  "peerDependencies": {
5
5
  "@mdi/js": "^7.4.47",
6
6
  "@tanstack/vue-form": "^1.2.4",
@@ -26,8 +26,10 @@
26
26
  "@vitejs/plugin-vue": "^5.2.3",
27
27
  "@vue/eslint-config-prettier": "^10.2.0",
28
28
  "@vue/eslint-config-typescript": "^14.5.0",
29
+ "@vue/test-utils": "^2.4.6",
29
30
  "eslint-plugin-prettier": "^5.2.6",
30
31
  "eslint-plugin-vue": "^10.0.0",
32
+ "jsdom": "^26.1.0",
31
33
  "rimraf": "^6.0.1",
32
34
  "sass": "^1.86.0",
33
35
  "storybook": "^8.6.12",
@@ -56,13 +58,17 @@
56
58
  "effect-app": "2.40.1"
57
59
  },
58
60
  "scripts": {
59
- "build": "rimraf dist && vue-tsc && vite build",
61
+ "build": "pnpm test:run && pnpm build:run",
62
+ "build:run": "rimraf dist && vue-tsc && vite build",
60
63
  "docs:dev": "vitepress dev docs",
61
64
  "docs:build": "vitepress build docs",
62
65
  "docs:serve": "vitepress serve docs",
63
66
  "lint": "NODE_OPTIONS=--max-old-space-size=8192 eslint src",
64
67
  "autofix": "pnpm lint --fix",
65
68
  "storybook": "storybook dev -p 6006",
66
- "build-storybook": "storybook build"
69
+ "build-storybook": "storybook build",
70
+ "test": "vitest",
71
+ "test:run": "vitest run",
72
+ "test:watch": "vitest watch"
67
73
  }
68
74
  }
@@ -0,0 +1,110 @@
1
+ <template>
2
+ <slot
3
+ v-for="{ name, label, ...attrs } in children"
4
+ :child="{ name, label, ...attrs }"
5
+ >
6
+ <OmegaInput :form="props.form" :name="name" :label="label" v-bind="attrs" />
7
+ </slot>
8
+ </template>
9
+
10
+ <script setup lang="ts" generic="From, To">
11
+ import { computed } from "vue"
12
+ import {
13
+ type NestedKeyOf,
14
+ type MetaRecord,
15
+ type FormType,
16
+ type FieldMeta,
17
+ type OmegaInputProps,
18
+ } from "./OmegaFormStuff"
19
+ import { pipe, Order, Array as A } from "effect-app"
20
+ import OmegaInput from "./OmegaInput.vue"
21
+
22
+ export type OmegaAutoGenMeta<From, To> = Omit<OmegaInputProps<From, To>, "form">
23
+ type NewMeta = OmegaAutoGenMeta<From, To>
24
+
25
+ const mapObject =
26
+ <K extends string, A, B>(fn: (value: A, key: K) => B) =>
27
+ (obj: Record<K, A>): Record<K, B> =>
28
+ Object.fromEntries(
29
+ (Object.entries(obj) as [K, A][]).map(([k, v]) => [k, fn(v, k)]),
30
+ ) as Record<K, B> // Cast needed for Object.fromEntries
31
+
32
+ const filterRecord =
33
+ <K extends string, V>(predicate: (value: V, key: K) => boolean) =>
34
+ (obj: Record<K, V>): Record<K, V> =>
35
+ Object.fromEntries(
36
+ (Object.entries(obj) as [K, V][]).filter(([k, v]) => predicate(v, k)),
37
+ ) as Record<K, V>
38
+
39
+ const filterMapRecord =
40
+ <K extends string, A, B>(fn: (value: A, key: K) => false | B) =>
41
+ (obj: Record<K, A>): Record<K, B> =>
42
+ (Object.entries(obj) as [K, A][]).reduce(
43
+ (acc, [key, value]) => {
44
+ const result = fn(value, key)
45
+ if (result !== false) {
46
+ acc[key] = result
47
+ }
48
+ return acc
49
+ },
50
+ {} as Record<K, B>,
51
+ )
52
+
53
+ const props = defineProps<{
54
+ form: FormType<From, To> & {
55
+ meta: MetaRecord<To>
56
+ }
57
+ pick?: NestedKeyOf<To>[]
58
+ omit?: NestedKeyOf<To>[]
59
+ labelMap?: (key: NestedKeyOf<To>) => string | undefined
60
+ filterMap?: <M extends NewMeta>(key: NestedKeyOf<To>, meta: M) => boolean | M
61
+ order?: NestedKeyOf<To>[]
62
+ sort?: Order.Order<NewMeta>
63
+ }>()
64
+
65
+ const namePosition = (name: NestedKeyOf<To>, order: NestedKeyOf<To>[]) => {
66
+ const index = order?.indexOf(name) ?? -1
67
+ return index === -1 ? Number.MAX_SAFE_INTEGER : index
68
+ }
69
+
70
+ const orderBy: Order.Order<NewMeta> = Order.mapInput(
71
+ Order.number,
72
+ (x: NewMeta) => namePosition(x.name, props.order || []),
73
+ )
74
+
75
+ const children = computed<NewMeta[]>(() =>
76
+ pipe(
77
+ props.form.meta as Record<NestedKeyOf<To>, FieldMeta | undefined>,
78
+ // include / exclude
79
+ filterRecord((_, metaKey) =>
80
+ props.pick
81
+ ? props.pick.includes(metaKey) && !props.omit?.includes(metaKey)
82
+ : !props.omit?.includes(metaKey),
83
+ ),
84
+ x => x,
85
+ // labelMap and adding name
86
+ mapObject((metaValue, metaKey) => ({
87
+ name: metaKey,
88
+ label: props.labelMap?.(metaKey) || metaKey,
89
+ ...metaValue,
90
+ })),
91
+ // filterMap
92
+ props.filterMap
93
+ ? filterMapRecord(m => {
94
+ const result = props.filterMap?.(m.name!, m as NewMeta)
95
+ return result === undefined || result === true ? m : result
96
+ })
97
+ : x => x,
98
+ // transform to array
99
+ obj => Object.values(obj) as NewMeta[],
100
+ // order
101
+ A.sort(orderBy),
102
+ // sort
103
+ props.sort ? A.sort(props.sort) : x => x,
104
+ ),
105
+ )
106
+
107
+ defineSlots<{
108
+ default(props: { child: NewMeta }): void
109
+ }>()
110
+ </script>
@@ -130,7 +130,7 @@ const showedGeneralErrors = computed(() => {
130
130
  }
131
131
  }
132
132
 
133
- .error-list {
133
+ div.error-list {
134
134
  container-type: inline-size;
135
135
  display: grid;
136
136
  grid-template-columns: auto 1fr auto;
@@ -139,7 +139,7 @@ const showedGeneralErrors = computed(() => {
139
139
  }
140
140
 
141
141
  @container (max-width: 28.125rem) {
142
- .error-list {
142
+ div.error-list {
143
143
  grid-template-columns: auto 1fr;
144
144
  }
145
145
 
@@ -150,7 +150,7 @@ const showedGeneralErrors = computed(() => {
150
150
  }
151
151
 
152
152
  @container (max-width: 18.75rem) {
153
- .error-list {
153
+ div.error-list {
154
154
  grid-template-columns: 1fr;
155
155
  }
156
156
 
@@ -122,7 +122,7 @@ export type FormComponent<T, S> = FieldComponent<
122
122
  > &
123
123
  Component
124
124
 
125
- export type FormType<T, S> = OmegaFormApi<T, S> & {
125
+ export type FormType<T, S = unknown> = OmegaFormApi<T, S> & {
126
126
  Field: Component
127
127
  }
128
128
 
@@ -22,6 +22,7 @@ import {
22
22
  watchEffect,
23
23
  type ComputedRef,
24
24
  getCurrentInstance,
25
+ nextTick,
25
26
  } from "vue"
26
27
  import type {
27
28
  FieldValidators,
@@ -73,12 +74,14 @@ const errors = computed(() =>
73
74
  // we remove value and errors when the field is empty and not required
74
75
  //watchEffect will trigger infinite times with both free fieldValue and errors, so bet to watch a stupid boolean
75
76
  watch(
76
- () => [!!fieldValue.value],
77
- () => {
78
- if (errors.value.length && !fieldValue.value && !props.meta?.required) {
79
- fieldApi.setValue(
80
- props.meta?.nullableOrUndefined === "undefined" ? undefined : null,
81
- )
77
+ () => !!fieldValue.value,
78
+ value => {
79
+ if (!value) {
80
+ nextTick(() => {
81
+ fieldApi.setValue(
82
+ props.meta?.nullableOrUndefined === "undefined" ? undefined : null,
83
+ )
84
+ })
82
85
  }
83
86
  },
84
87
  )
@@ -61,8 +61,8 @@
61
61
  import { useStore, type StandardSchemaV1Issue } from "@tanstack/vue-form"
62
62
  import { type S } from "effect-app"
63
63
  import {
64
- type FilterItems,
65
64
  type FormProps,
65
+ type FilterItems,
66
66
  type OmegaFormApi,
67
67
  type OmegaFormState,
68
68
  type ShowErrorsOn,
@@ -74,23 +74,24 @@ import {
74
74
  type OmegaFormReturn,
75
75
  useOmegaForm,
76
76
  } from "./useOmegaForm"
77
- import { computed, watch, defineSlots } from "vue"
77
+ import { computed, watch, onBeforeMount } from "vue"
78
78
 
79
79
  const props = defineProps<
80
80
  {
81
81
  omegaConfig?: OmegaConfig<From>
82
82
  subscribe?: K[]
83
83
  showErrorsOn?: ShowErrorsOn
84
- } & (
85
- | {
86
- form: OmegaFormReturn<To, From>
87
- schema?: undefined
88
- }
89
- | (FormProps<To, From> & {
90
- form?: undefined
91
- schema: S.Schema<From, To, never>
92
- })
93
- )
84
+ } & FormProps<To, From> &
85
+ (
86
+ | {
87
+ form: OmegaFormReturn<To, From>
88
+ schema?: undefined
89
+ }
90
+ | {
91
+ form?: undefined
92
+ schema: S.Schema<From, To, never>
93
+ }
94
+ )
94
95
  >()
95
96
 
96
97
  const localForm = computed(() => {
@@ -102,6 +103,52 @@ const localForm = computed(() => {
102
103
 
103
104
  const formToUse = computed(() => props.form ?? localForm.value!)
104
105
 
106
+ onBeforeMount(() => {
107
+ if (!props.form) return
108
+ const formOptionsKeys = Object.keys(props.form.options || {})
109
+
110
+ const excludedKeys: Set<keyof typeof props> = new Set([
111
+ "omegaConfig",
112
+ "subscribe",
113
+ "showErrorsOn",
114
+ "asyncAlways",
115
+ "form",
116
+ "schema",
117
+ ])
118
+
119
+ const filteredProps = Object.fromEntries(
120
+ Object.entries(props).filter(
121
+ ([key, value]) =>
122
+ !excludedKeys.has(key as keyof typeof props) && value !== undefined,
123
+ ),
124
+ ) as Partial<typeof props>
125
+
126
+ const propsKeys = Object.keys(filteredProps)
127
+
128
+ const overlappingKeys = formOptionsKeys.filter(
129
+ key =>
130
+ propsKeys.includes(key) &&
131
+ filteredProps[key as keyof typeof props] !== undefined,
132
+ )
133
+
134
+ if (overlappingKeys.length > 0) {
135
+ console.warn(
136
+ `[OmegaWrapper] Overlapping keys found between form options and filtered props:\n${overlappingKeys.join(
137
+ ", \n",
138
+ )}.\nProps will overwrite existing form options. This might indicate a configuration issue.`,
139
+ )
140
+ }
141
+
142
+ const mergedOptions = {
143
+ ...formToUse.value.options,
144
+ ...filteredProps,
145
+ }
146
+
147
+ formToUse.value.options = Object.fromEntries(
148
+ Object.entries(mergedOptions).filter(([_, value]) => value !== undefined),
149
+ )
150
+ })
151
+
105
152
  const formIsSubmitting = useStore(
106
153
  formToUse.value.store,
107
154
  state => state.isSubmitting,
@@ -2,28 +2,11 @@ import { defineCustomElement } from "vue"
2
2
  import { default as OmegaForm } from "./OmegaWrapper.vue"
3
3
  import { default as OmegaInput } from "./OmegaInput.vue"
4
4
  import { default as OmegaErrors } from "./OmegaErrors.vue"
5
+ import { default as OmegaAutoGen } from "./OmegaAutoGen.vue"
5
6
 
6
7
  export * as OmegaErrorsContext from "./OmegaErrorsContext"
7
8
  export * from "./OmegaFormStuff"
8
9
  export { useOmegaForm } from "./useOmegaForm"
9
10
  export { default } from "./OmegaWrapper.vue"
10
11
 
11
- export { OmegaForm, OmegaInput, OmegaErrors }
12
-
13
- const OmegaFormCE = defineCustomElement(OmegaForm as any)
14
- const OmegaInputCE = defineCustomElement(OmegaInput as any)
15
- const OmegaErrorsCE = defineCustomElement(OmegaErrors as any)
16
-
17
- export { OmegaFormCE, OmegaInputCE, OmegaErrorsCE }
18
-
19
- export function registerOmegaForm() {
20
- if (!customElements.get("omega-form")) {
21
- customElements.define("omega-form", OmegaFormCE)
22
- }
23
- if (!customElements.get("omega-input")) {
24
- customElements.define("omega-input", OmegaInputCE)
25
- }
26
- if (!customElements.get("omega-errors")) {
27
- customElements.define("omega-errors", OmegaErrorsCE)
28
- }
29
- }
12
+ export { OmegaForm, OmegaInput, OmegaErrors, OmegaAutoGen }
@@ -57,7 +57,7 @@ export const OmegaFormKey = Symbol("OmegaForm") as InjectionKey<OF<any, any>>
57
57
 
58
58
  export interface OmegaFormReturn<To extends Record<PropertyKey, any>, From>
59
59
  extends OF<To, From> {
60
- Input: typeof OmegaFormInput<From, To>
60
+ Input: typeof OmegaFormInput
61
61
  }
62
62
 
63
63
  export const useOmegaForm = <
package/src/env.d.ts DELETED
@@ -1,8 +0,0 @@
1
- /// <reference types="vite/client" />
2
-
3
- declare module "*.vue" {
4
- import { DefineComponent } from "vue"
5
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
6
- const component: DefineComponent<{}, {}, any>
7
- export default component
8
- }