@effect-app/vue-components 0.3.3 → 0.4.2

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 (31) hide show
  1. package/dist/types/components/OmegaForm/OmegaFormStuff.d.ts +13 -0
  2. package/dist/types/components/OmegaForm/OmegaInput.vue.d.ts +2 -14
  3. package/dist/types/components/OmegaForm/OmegaWrapper.vue.d.ts +7 -3
  4. package/dist/types/components/OmegaForm/index.d.ts +2 -42
  5. package/dist/types/components/OmegaForm/useOmegaForm.d.ts +6 -2
  6. package/dist/vue-components.es11.js +43 -33
  7. package/dist/vue-components.es15.js +1 -1
  8. package/dist/vue-components.es16.js +2 -93
  9. package/dist/vue-components.es17.js +96 -11
  10. package/dist/vue-components.es18.js +11 -2
  11. package/dist/vue-components.es19.js +1 -1
  12. package/dist/vue-components.es5.js +88 -61
  13. package/dist/vue-components.es7.js +2 -2
  14. package/dist/vue-components.es8.js +1 -1
  15. package/package.json +3 -1
  16. package/src/components/OmegaForm/OmegaFormStuff.ts +11 -0
  17. package/src/components/OmegaForm/OmegaInput.vue +2 -15
  18. package/src/components/OmegaForm/OmegaInternalInput.vue +1 -1
  19. package/src/components/OmegaForm/OmegaWrapper.vue +61 -23
  20. package/src/components/OmegaForm/index.ts +3 -3
  21. package/src/components/OmegaForm/useOmegaForm.ts +50 -4
  22. package/src/stories/OmegaForm/ComplexForm.vue +39 -33
  23. package/src/stories/OmegaForm/EmailForm.vue +1 -1
  24. package/src/stories/OmegaForm/Meta.vue +1 -1
  25. package/src/stories/OmegaForm/OneHundredWaysToWriteAForm.vue +188 -0
  26. package/src/stories/OmegaForm/PersistencyForm.vue +6 -6
  27. package/src/stories/OmegaForm/SimpleForm.vue +1 -1
  28. package/src/stories/OmegaForm/SimpleFormVuetifyDefault.vue +1 -1
  29. package/src/stories/OmegaForm/SumExample.vue +3 -5
  30. package/src/stories/OmegaForm/form.Input.vue +86 -0
  31. package/src/stories/OmegaForm.stories.ts +16 -1
@@ -1,125 +1,152 @@
1
- import { useForm as E } from "@tanstack/vue-form";
2
- import { S as I } from "effect-app";
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 a, onUnmounted as R, onMounted as A, onBeforeUnmount as D } from "vue";
5
- import { isObject as J } from "./vue-components.es15.js";
6
- const z = (h, u, i) => {
7
- if (!h) throw new Error("Schema is required");
8
- const b = I.standardSchemaV1(h), { filterItems: V, meta: t } = N(h), c = a(() => {
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
- }), L = () => {
15
+ }), U = () => {
15
16
  const e = new URLSearchParams(window.location.search);
16
- e.delete(c.value);
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 f(e, r) {
21
+ function h(e, r) {
21
22
  for (const l in r)
22
- r[l] && J(r[l]) ? (e[l] || (e[l] = {}), f(e[l], r[l])) : e[l] = 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 U = a(() => {
26
+ const j = b(() => {
26
27
  var l;
27
- if (u != null && u.defaultValues && !((l = i == null ? void 0 : i.persistency) != null && l.overrideDefaultValues))
28
- return u == null ? void 0 : u.defaultValues;
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 d = new URLSearchParams(window.location.search).get(c.value);
35
- L(), d && (e = JSON.parse(d));
36
- } catch (s) {
37
- console.error(s);
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 s = r.policies.includes("local") ? localStorage : sessionStorage;
44
- if (s)
44
+ const u = r.policies.includes("local") ? localStorage : sessionStorage;
45
+ if (u)
45
46
  try {
46
- const d = JSON.parse(
47
- s.getItem(c.value) || "{}"
47
+ const n = JSON.parse(
48
+ u.getItem(d.value) || "{}"
48
49
  );
49
- s.removeItem(c.value), e = d;
50
- } catch (d) {
51
- console.error(d);
50
+ u.removeItem(d.value), e = n;
51
+ } catch (n) {
52
+ console.error(n);
52
53
  }
53
54
  }
54
- if (e ?? (e = {}), (u == null ? void 0 : u.defaultValues) == null)
55
+ if (e ?? (e = {}), (s == null ? void 0 : s.defaultValues) == null)
55
56
  return e;
56
57
  {
57
- const s = u == null ? void 0 : u.defaultValues;
58
- return f(s, e);
58
+ const u = s == null ? void 0 : s.defaultValues;
59
+ return h(u, e);
59
60
  }
60
- }), n = E({
61
- ...u,
61
+ }), c = P({
62
+ ...s,
62
63
  validators: {
63
- onSubmit: b,
64
- ...(u == null ? void 0 : u.validators) || {}
64
+ onSubmit: V,
65
+ ...(s == null ? void 0 : s.validators) || {}
65
66
  },
66
- onSubmit: u != null && u.onSubmit ? ({ formApi: e, meta: r, value: l }) => {
67
- var s;
68
- return (s = u.onSubmit) == null ? void 0 : s.call(u, {
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: U.value
75
- }), j = () => {
75
+ defaultValues: j.value
76
+ }), E = () => {
76
77
  Object.keys(t).forEach((e) => {
77
- n.setFieldValue(e, void 0);
78
+ c.setFieldValue(e, void 0);
78
79
  });
79
- }, o = (e) => e.reduce(
80
+ }, a = (e) => e.reduce(
80
81
  (r, l) => {
81
- const s = l.split(".");
82
- return s.reduce((d, w, P) => (P === s.length - 1 ? d[w] = n.getFieldValue(l) : d[w] = d[w] ?? {}, d[w]), r), r;
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
- ), v = (e) => {
86
+ ), S = (e) => {
86
87
  if (e) {
87
88
  if (Array.isArray(e.keys))
88
- return o(e.keys);
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 s;
93
- return (s = e.banKeys) == null ? void 0 : s.includes(l);
93
+ var u;
94
+ return (u = e.banKeys) == null ? void 0 : u.includes(l);
94
95
  }
95
96
  );
96
- return o(r);
97
+ return a(r);
97
98
  }
98
- return n.store.state.values;
99
+ return c.store.state.values;
99
100
  }
100
- }, S = () => {
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 = v(e);
106
- return r.setItem(c.value, JSON.stringify(l));
106
+ const l = S(e);
107
+ return r.setItem(d.value, JSON.stringify(l));
107
108
  }
108
- }, y = () => {
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 = v(e), l = new URLSearchParams(window.location.search);
112
- l.set(c.value, JSON.stringify(r));
113
- const s = new URL(window.location.href);
114
- s.search = l.toString(), window.history.replaceState({}, "", s.toString());
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
- return R(S), A(() => {
118
- window.addEventListener("beforeunload", S), window.addEventListener("blur", y);
119
- }), D(() => {
120
- window.removeEventListener("beforeunload", S), window.removeEventListener("blur", y);
121
- }), Object.assign(n, { meta: t, filterItems: V, clear: j });
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
- z as useOmegaForm
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-fd152523]{display:contents}")),document.head.appendChild(n),window.customElements){const e=window.customElements.define;window.customElements.define=function(i,t){const d=t.prototype.connectedCallback;return t.prototype.connectedCallback=function(){if(d&&d.call(this),this.shadowRoot){const o=document.createElement("style");o.appendChild(document.createTextNode("fieldset[data-v-fd152523]{display:contents}")),this.shadowRoot.appendChild(o)}},e.call(window.customElements,i,t)}}}}catch(e){console.error("vite-plugin-css-injected-by-js",e)}})();
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-fd152523"]]);
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.es16.js";
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.3",
3
+ "version": "0.4.2",
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 FieldValidators,
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,6 +1,6 @@
1
1
  <template>
2
2
  <slot v-bind="inputProps">
3
- <div @focusout="setRealDirty">
3
+ <div :class="$attrs.class" @focusout="setRealDirty">
4
4
  <OmegaInputVuetify
5
5
  v-if="vuetified"
6
6
  :input-props="inputProps"
@@ -1,7 +1,19 @@
1
1
  <template>
2
- <form novalidate @submit.prevent.stop="form.handleSubmit()">
2
+ <form novalidate @submit.prevent.stop="formToUse.handleSubmit()">
3
3
  <fieldset :disabled="formIsSubmitting">
4
- <slot :form="form" :subscribed-values="subscribedValues" />
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 form =
85
- props.form ?? useOmegaForm<From, To>(props.schema, props, props.omegaConfig)
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 formIsSubmitting = useStore(form.store, state => state.isSubmitting)
103
+ const formToUse = computed(() => props.form ?? localForm.value!)
88
104
 
89
- defineExpose(form)
105
+ const formIsSubmitting = useStore(
106
+ formToUse.value.store,
107
+ state => state.isSubmitting,
108
+ )
90
109
 
91
110
  const subscribedValues = getOmegaStore(
92
- form as OmegaFormApi<To, From>,
111
+ formToUse.value as OmegaFormApi<To, From>,
93
112
  props.subscribe,
94
113
  )
95
114
 
96
115
  const formSubmissionAttempts = useStore(
97
- form.store,
116
+ formToUse.value.store,
98
117
  state => state.submissionAttempts,
99
118
  )
100
119
 
101
- const errors = form.useStore(state => state.errors)
120
+ const errors = computed(() => formToUse.value.useStore(state => state.errors))
102
121
 
103
122
  watch(
104
- () => [form.filterItems, errors.value],
123
+ () => [formToUse.value.filterItems, errors.value.value],
105
124
  () => {
106
- const filterItems: FilterItems | undefined = form.filterItems
125
+ const filterItems: FilterItems | undefined = formToUse.value.filterItems
126
+ const currentErrors = errors.value.value
107
127
  if (!filterItems) return {}
108
- if (!errors.value) return {}
109
- const errorList = Object.values(errors.value)
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.forEach((item: any) => {
121
- const m: any = form.getFieldMeta(item)
122
- form.setFieldMeta(item, {
123
- ...m,
124
- errorMap: {
125
- onSubmit: [{ path: [item], message: filterItems.message }],
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 { computed, onBeforeUnmount, onMounted, onUnmounted } from "vue"
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
- export interface OmegaFormReturn<To, From> extends OmegaFormApi<To, From> {
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 exposed = Object.assign(form, { meta, filterItems, clear })
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
- return exposed
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="form">
3
- <template #default="{ form }">
4
- <OmegaInput label="aString" :form="form" name="aString" />
5
- <OmegaInput label="aStringMin2" :form="form" name="aStringMin2" />
6
- <OmegaInput label="aStringMin2Max4" :form="form" name="aStringMin2Max4" />
7
- <OmegaInput
8
- label="aStringMin2Max3Nullable"
9
- :form="form"
10
- name="aStringMin2Max3Nullable"
11
- />
12
- <OmegaInput label="aNumber" :form="form" name="aNumber" />
13
- <OmegaInput label="aNumberMin2" :form="form" name="aNumberMin2" />
14
- <OmegaInput label="aNumberMin2Max" :form="form" name="aNumberMin2Max" />
15
- <OmegaInput
16
- label="aNumberMin2Max4Nullable"
17
- :form="form"
18
- name="aNumberMin2Max4Nullable"
19
- />
20
- <OmegaInput
21
- label="aSelect"
22
- :form="form"
23
- name="aSelect"
24
- :options="[
25
- { title: 'a', value: 'a' },
26
- { title: 'b', value: 'b' },
27
- { title: 'c', value: 'c' },
28
- ]"
29
- />
30
- <button>Submit</button>
31
- <button type="reset" @click.prevent="form.clear()">Clear</button>
32
- <button type="button" @click="form.reset()">Reset</button>
33
- </template>
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 form = useOmegaForm(
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 #default="{ form }">
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>
@@ -19,7 +19,7 @@
19
19
  })
20
20
  "
21
21
  >
22
- <template #default="{ form }">
22
+ <template #internalForm="{ form }">
23
23
  <ul>
24
24
  <li v-for="key in Object.keys(form.meta)" :key="key">
25
25
  {{ key }}: {{ (form.meta as any)[key] }}