@effect-app/vue-components 0.5.0 → 0.6.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 (42) hide show
  1. package/dist/types/components/OmegaForm/OmegaAutoGen.vue.d.ts +30 -0
  2. package/dist/types/components/OmegaForm/index.d.ts +3 -7
  3. package/dist/vue-components.es.js +24 -27
  4. package/dist/vue-components.es10.js +6 -23
  5. package/dist/vue-components.es11.js +3 -3
  6. package/dist/vue-components.es15.js +1 -1
  7. package/dist/vue-components.es17.js +2 -5
  8. package/dist/vue-components.es18.js +5 -32
  9. package/dist/vue-components.es19.js +32 -2
  10. package/dist/vue-components.es2.js +16 -19
  11. package/dist/vue-components.es20.js +2 -2
  12. package/dist/vue-components.es21.js +2 -98
  13. package/dist/vue-components.es22.js +98 -11
  14. package/dist/vue-components.es23.js +11 -2
  15. package/dist/vue-components.es24.js +2 -115
  16. package/dist/vue-components.es25.js +117 -0
  17. package/dist/{vue-components.es26.js → vue-components.es27.js} +1 -1
  18. package/dist/vue-components.es3.js +3 -3
  19. package/dist/vue-components.es4.js +2 -2
  20. package/dist/vue-components.es5.js +78 -36
  21. package/dist/vue-components.es6.js +34 -131
  22. package/dist/vue-components.es7.js +128 -211
  23. package/dist/vue-components.es8.js +216 -6
  24. package/dist/vue-components.es9.js +4 -4
  25. package/package.json +9 -3
  26. package/src/components/OmegaForm/OmegaAutoGen.vue +110 -0
  27. package/src/components/OmegaForm/OmegaWrapper.vue +1 -1
  28. package/src/components/OmegaForm/index.ts +3 -21
  29. package/src/env.d.ts +0 -8
  30. package/src/stories/OmegaForm/Clearable.vue +0 -20
  31. package/src/stories/OmegaForm/ComplexForm.vue +0 -87
  32. package/src/stories/OmegaForm/EmailForm.vue +0 -48
  33. package/src/stories/OmegaForm/Meta.vue +0 -47
  34. package/src/stories/OmegaForm/OneHundredWaysToWriteAForm.vue +0 -188
  35. package/src/stories/OmegaForm/PersistencyForm.vue +0 -58
  36. package/src/stories/OmegaForm/SimpleForm.vue +0 -30
  37. package/src/stories/OmegaForm/SimpleFormVuetifyDefault.vue +0 -15
  38. package/src/stories/OmegaForm/SumExample.vue +0 -37
  39. package/src/stories/OmegaForm/form.Input.vue +0 -98
  40. package/src/stories/OmegaForm.stories.ts +0 -114
  41. package/src/stories/README.md +0 -29
  42. package/src/stories/tsconfig.json +0 -4
@@ -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>
@@ -74,7 +74,7 @@ import {
74
74
  type OmegaFormReturn,
75
75
  useOmegaForm,
76
76
  } from "./useOmegaForm"
77
- import { computed, watch, defineSlots, onBeforeMount } from "vue"
77
+ import { computed, watch, onBeforeMount } from "vue"
78
78
 
79
79
  const props = defineProps<
80
80
  {
@@ -1,29 +1,11 @@
1
- import { defineCustomElement } from "vue"
2
1
  import { default as OmegaForm } from "./OmegaWrapper.vue"
3
2
  import { default as OmegaInput } from "./OmegaInput.vue"
4
3
  import { default as OmegaErrors } from "./OmegaErrors.vue"
4
+ import { default as OmegaAutoGen } from "./OmegaAutoGen.vue"
5
5
 
6
6
  export * as OmegaErrorsContext from "./OmegaErrorsContext"
7
7
  export * from "./OmegaFormStuff"
8
- export { useOmegaForm } from "./useOmegaForm"
8
+ export { useOmegaForm, type OmegaFormReturn } from "./useOmegaForm"
9
9
  export { default } from "./OmegaWrapper.vue"
10
10
 
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
- }
11
+ export { OmegaForm, OmegaInput, OmegaErrors, OmegaAutoGen }
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
- }
@@ -1,20 +0,0 @@
1
- <template>
2
- <OmegaForm
3
- :form="form"
4
- :subscribe="['values']"
5
- :on-submit="() => console.log('submitted1')"
6
- >
7
- <template #externalForm="{ subscribedValues: { values } }">
8
- <div>values: {{ values }}</div>
9
- <form.Input name="a" label="Nullable value" clearable />
10
- <button type="submit">submit</button>
11
- </template>
12
- </OmegaForm>
13
- </template>
14
-
15
- <script setup lang="ts" generic="_, To">
16
- import { S } from "effect-app"
17
- import { OmegaForm, useOmegaForm } from "../../components/OmegaForm"
18
-
19
- const form = useOmegaForm(S.Struct({ a: S.NullOr(S.String) }), {})
20
- </script>
@@ -1,87 +0,0 @@
1
- <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>
40
- </OmegaForm>
41
- </template>
42
-
43
- <script setup lang="ts">
44
- import { S } from "effect-app"
45
- import { OmegaForm, OmegaInput, useOmegaForm } from "../../components/OmegaForm"
46
-
47
- const exampleForm = useOmegaForm(
48
- S.Struct({
49
- aString: S.String,
50
- aStringMin2: S.String.pipe(S.minLength(2)),
51
- aStringMin2Max4: S.String.pipe(S.minLength(2)).pipe(S.maxLength(4)),
52
- aStringMin2Max3Nullable: S.UndefinedOr(
53
- S.String.pipe(S.minLength(2)).pipe(S.maxLength(3)),
54
- ),
55
- aNumber: S.Number,
56
- aNumberMin2: S.Number.pipe(S.greaterThan(2)),
57
- aNumberMin2Max: S.Number.pipe(S.greaterThan(2)).pipe(S.lessThan(4)),
58
- aNumberMin2Max4Nullable: S.NullOr(S.Number.pipe(S.between(2, 4))),
59
- aSelect: S.Union(S.Literal("a"), S.Literal("b"), S.Literal("c")),
60
- }),
61
- {
62
- onSubmit: ({
63
- value,
64
- }: {
65
- value: {
66
- aString: string
67
- aStringMin2: string
68
- aStringMin2Max4: string
69
- aStringMin2Max3Nullable?: string
70
- aNumber: number
71
- aNumberMin2: number
72
- aNumberMin2Max: number
73
- aNumberMin2Max4Nullable: number | null
74
- aSelect: "a" | "b" | "c"
75
- }
76
- }) => {
77
- console.log(value)
78
- },
79
- },
80
- {
81
- persistency: {
82
- policies: ["local"],
83
- overrideDefaultValues: true,
84
- },
85
- },
86
- )
87
- </script>
@@ -1,48 +0,0 @@
1
- <template>
2
- <OmegaForm
3
- :schema="schema"
4
- :on-submit="onSubmit"
5
- :default-values="defaultValues"
6
- >
7
- <template #internalForm="{ form }">
8
- <OmegaInput label="email" name="email" :form="form" />
9
- <OmegaInput label="confirm" name="confirm" :form="form" />
10
- <button>submit</button>
11
- <OmegaErrors />
12
- </template>
13
- </OmegaForm>
14
- </template>
15
-
16
- <script setup lang="ts">
17
- import { S } from "effect-app"
18
- import { OmegaForm, OmegaInput, OmegaErrors } from "../../components/OmegaForm"
19
-
20
- const schema = S.Struct({
21
- email: S.Email,
22
- confirm: S.Email,
23
- }).pipe(
24
- S.filter(
25
- form => {
26
- if (form.email !== form.confirm) {
27
- return false
28
- }
29
- return true
30
- },
31
- {
32
- message: () => "Email and confirmation must match",
33
- jsonSchema: {
34
- items: ["confirm"],
35
- },
36
- },
37
- ),
38
- )
39
-
40
- const defaultValues = {
41
- email: "mimmo@asd.it",
42
- confirm: "amerelli@asd.it",
43
- }
44
-
45
- const onSubmit = ({ value }: { value: { email: string; confirm: string } }) => {
46
- console.log(value)
47
- }
48
- </script>
@@ -1,47 +0,0 @@
1
- <template>
2
- <OmegaForm
3
- :schema="
4
- S.Struct({
5
- a: S.NullOr(S.String),
6
- b: S.UndefinedOr(S.Number),
7
- c: S.NullishOr(S.Number),
8
- d: S.String,
9
- e: S.Number,
10
- f: S.Number,
11
- struct: S.Struct({
12
- a: S.NullOr(S.String),
13
- b: S.UndefinedOr(S.Number),
14
- c: S.NullishOr(S.Number),
15
- d: S.String,
16
- e: S.Number,
17
- f: S.Number,
18
- }),
19
- })
20
- "
21
- >
22
- <template #internalForm="{ form }">
23
- <ul>
24
- <li v-for="key in Object.keys(form.meta)" :key="key">
25
- {{ key }}: {{ (form.meta as any)[key] }}
26
- </li>
27
- </ul>
28
- <OmegaInput label="a" :form="form" name="a" />
29
- <OmegaInput label="b" :form="form" name="b" />
30
- <OmegaInput label="c" :form="form" name="c" />
31
- <OmegaInput label="d" :form="form" name="d" />
32
- <OmegaInput label="e" :form="form" name="e" />
33
- <OmegaInput label="f" :form="form" name="f" />
34
- <OmegaInput label="struct.a" :form="form" name="struct.a" />
35
- <OmegaInput label="struct.b" :form="form" name="struct.b" />
36
- <OmegaInput label="struct.c" :form="form" name="struct.c" />
37
- <OmegaInput label="struct.d" :form="form" name="struct.d" />
38
- <OmegaInput label="struct.e" :form="form" name="struct.e" />
39
- <OmegaInput label="struct.f" :form="form" name="struct.f" />
40
- </template>
41
- </OmegaForm>
42
- </template>
43
-
44
- <script setup lang="ts">
45
- import { OmegaForm, OmegaInput } from "../../components/OmegaForm"
46
- import { S } from "effect-app"
47
- </script>
@@ -1,188 +0,0 @@
1
- <template>
2
- <div class="container">
3
- <h1>One hundred ways to write a form</h1>
4
- <p>
5
- OmegaForm is a powerful and flexible form library that wraps
6
- <a href="https://tanstack.com/form/latest" target="_blank">TanStack Form</a>
7
- and uses
8
- <a href="https://effect.website/docs/schema/introduction/" target="_blank">
9
- Effect Schema
10
- </a>
11
- as the schema definition. All of this allows you to create forms in a
12
- declarative way.
13
- We also use
14
- <a href="https://vuetifyjs.com/" target="_blank">Vuetify</a> as peer dependency
15
- for the UI components, but you can use any other UI library you want or custom inputs.
16
- Here are some examples of how to write forms using
17
- different approaches
18
- </p>
19
- <p>for our example, we will use the following dependencies</p>
20
- <pre v-highlightjs><code class="javascript">{{ `import { S } from "effect-app"
21
- import { OmegaForm, OmegaInput, useOmegaForm } from "@effect-app/vue-components"` }}</code></pre>
22
-
23
- <h2>Simplest way</h2>
24
- <p>Now, let's write a form using the following schema:</p>
25
- <pre v-highlightjs><code class="typescript">{{ `const schema = S.Struct({
26
- name: S.String,
27
- age: S.Number,
28
- })` }}</code></pre>
29
-
30
- <p>Now, let's write in the template the form using the following schema:</p>
31
- <pre
32
- v-highlightjs
33
- ><code class="vue">{{ `<OmegaForm :schema="schema" :on-submit="console.log">
34
- <template #internalForm="{ form }">
35
- <OmegaInput label="name" :form="form" name="name" />
36
- <OmegaInput label="age" :form="form" name="age" />
37
- </template>
38
- </OmegaForm>` }}</code></pre>
39
-
40
- <OmegaForm :schema="schema" :on-submit="console.log">
41
- <template #internalForm="{ form }">
42
- <OmegaInput label="name" :form="form" name="name" />
43
- <OmegaInput label="age" :form="form" name="age" />
44
- </template>
45
- </OmegaForm>
46
-
47
- <p>
48
- <code>OmegaInput</code>
49
- is a component that will render a form input based on the schema. It's
50
- alread embedded inside the
51
- <code>OmegaForm</code>
52
- component, so you don't need to import it separately or pass form as a prop:
53
- </p>
54
- <pre v-highlightjs><code class="vue">{{ `<OmegaForm :schema="schema">
55
- <template #internalForm="{ form }">
56
- <component :is="form.Input" label="name" name="name" />
57
- <component :is="form.Input" label="age" name="age" />
58
- </template>
59
- </OmegaForm>` }}</code></pre>
60
- <p>you can also register to the values via the `subscribe` prop</p>
61
- <pre
62
- v-highlightjs
63
- ><code class="vue">{{ `<OmegaForm :schema="schema" :subscribe="['values']">
64
- <template #internalForm="{ form, subscribedValues: { values } }">
65
- <component :is="form.Input" label="name" name="name" />
66
- <component :is="form.Input" label="age" name="age" />
67
- <pre>\{\{ values \}\}</pre>
68
- </template>
69
- </OmegaForm>` }}</code></pre>
70
-
71
- <OmegaForm :schema="schema" :subscribe="['values']">
72
- <template #internalForm="{ form, subscribedValues: { values } }">
73
- <component :is="form.Input" label="name" name="name" />
74
- <component :is="form.Input" label="age" name="age" />
75
- <pre>{{ values }}</pre>
76
- </template>
77
- </OmegaForm>
78
-
79
- <h2>Using the useOmegaForm hook</h2>
80
- <p>
81
- The useOmegaForm hook is a hook that returns the form instance and the
82
- values. It's a good way to create a form in a functional way.
83
- </p>
84
- <pre
85
- v-highlightjs
86
- ><code class="typescript">{{ `const form = useOmegaForm(schema)` }}</code></pre>
87
- <p>
88
- Now, you can use the form instance to create the form in the template.
89
- </p>
90
- <pre v-highlightjs><code class="vue">{{ `<OmegaForm :form="form">
91
- <form.Input" label="name" name="name" />
92
- <form.Input" label="age" name="age" />
93
- </OmegaForm>` }}</code></pre>
94
-
95
- <p>you can still register to the values via the `subscribe` prop</p>
96
- <pre
97
- v-highlightjs
98
- ><code class="vue">{{ `<OmegaForm :form="form" :subscribe="['values']">
99
- <template #externalForm="{ subscribedValues: { values } }">
100
- <form.Input" label="name" name="name" />
101
- <form.Input" label="age" name="age" />
102
- <pre>\{\{ values \}\}</pre>
103
- </template>
104
- </OmegaForm>` }}</code></pre>
105
- <p>
106
- <strong>Note:</strong> the template name is <code>externalForm</code>
107
- because the form is not inside the component, it's outside. And you don't
108
- have access to the form instance inside the template variables anymore.
109
- </p>
110
-
111
- <h3>Using custom inputs</h3>
112
- <p>
113
- You can use custom inputs by passing an OmegaInput a child component.
114
- </p>
115
- <pre v-highlightjs><code class="vue">{{ `<OmegaForm :form="form">
116
- <form.Input label="name" name="name">
117
- <template #default="{ field, label }">
118
- <label :for="name">\{\{ label \}\}</label>
119
- <input
120
- :id="name"
121
- v-model="field.state.value"
122
- :name="name"
123
- style="border: 1px solid red"
124
- @change="(e) => field.handleChange(e.target.value)"
125
- />
126
- </template>
127
- </form.Input>
128
- </OmegaForm>` }}</code></pre>
129
- <OmegaForm :form="form">
130
- <form.Input label="name" name="name">
131
- <template #default="{ field, label, name }">
132
- <label :for="name">{{ label }}</label>
133
- <input
134
- :id="name"
135
- v-model="field.state.value"
136
- :name="name"
137
- style="border: 1px solid red"
138
- @change="(e: any) => field.handleChange(e.target.value)"
139
- />
140
- </template>
141
- </form.Input>
142
- </OmegaForm>
143
- <h3>Known issues</h3>
144
- <p>
145
- You can't write something like this:
146
- </p>
147
- <pre v-highlightjs><code class="vue">{{ `<OmegaForm :schema="schema">
148
- <template #internalForm="{ form }">
149
- <form.Input label="name" name="name" />
150
- <form.Input label="age" name="age" />
151
- </template>
152
- </OmegaForm>` }}</code></pre>
153
- <p>
154
- because When Vue's template compiler encounters <code>form.Input</code>, it try to resolve or analyze the form object and its Input property earlier in the rendering pipeline. Since form.Input is provided by the parent OmegaForm through the slot, this direct usage inside the slot might create a tighter, more immediate dependency loop that the compiler/renderer detects or falls into, leading to the stack overflow.
155
- </p>
156
- </div>
157
- </template>
158
-
159
- <script setup lang="ts">
160
- import { S } from "effect-app"
161
- import { OmegaForm, OmegaInput, useOmegaForm } from "../../components/OmegaForm"
162
-
163
- const schema = S.Struct({
164
- name: S.String,
165
- age: S.Number,
166
- })
167
- const form = useOmegaForm(schema)
168
- </script>
169
-
170
- <style scoped>
171
- p,
172
- pre {
173
- margin-bottom: 1rem;
174
- }
175
- form {
176
- margin-bottom: 2rem;
177
- }
178
-
179
- .container {
180
- max-width: 1200px;
181
- margin: 0 auto;
182
- padding: 0 1rem;
183
- }
184
-
185
- h1, h2, h3 {
186
- text-wrap: balance;
187
- }
188
- </style>
@@ -1,58 +0,0 @@
1
- <template>
2
- <OmegaForm
3
- :form="addForm"
4
- :subscribe="['errors', 'values']"
5
- show-errors-on="onChange"
6
- >
7
- <template #externalForm="{ subscribedValues: { errors, values: vvv } }">
8
- <div>Errors: {{ errors }}</div>
9
- <div>Values: {{ vvv }}</div>
10
- <OmegaInput label="first" :form="addForm" name="first" />
11
- <div>+</div>
12
- <OmegaInput label="second" :form="addForm" name="second" />
13
- <br />
14
- <hr />
15
- <br />
16
- <OmegaInput label="third.fourth" :form="addForm" name="third.fourth" />
17
- <OmegaInput label="third.fifth" :form="addForm" name="third.fifth" />
18
- </template>
19
- </OmegaForm>
20
-
21
- <!-- Technically you can do this only with a subscribe but only inside OmegaForm Context -->
22
- <div>
23
- <div>Sum: {{ sum }}</div>
24
- </div>
25
- </template>
26
-
27
- <script setup lang="ts">
28
- import { S } from "effect-app"
29
- import { OmegaForm, OmegaInput, useOmegaForm } from "../../components/OmegaForm"
30
- import { ref, watch } from "vue"
31
-
32
- const sum = ref(0)
33
- const AddSchema = S.Struct({
34
- first: S.Number,
35
- second: S.Number.pipe(S.greaterThan(3)),
36
- third: S.Struct({
37
- fourth: S.Number,
38
- fifth: S.Number,
39
- }),
40
- })
41
-
42
- const addForm = useOmegaForm(
43
- AddSchema,
44
- {},
45
- {
46
- persistency: {
47
- policies: ["session", "querystring"],
48
- keys: ["first", "third.fourth"],
49
- },
50
- },
51
- )
52
-
53
- const values = addForm.useStore(({ values }) => values)
54
-
55
- watch(values, ({ first, second }) => {
56
- sum.value = first + second
57
- })
58
- </script>
@@ -1,30 +0,0 @@
1
- <template>
2
- <OmegaForm :schema="schema" :on-submit="onSubmit" :subscribe="['values']">
3
- <template #internalForm="{ form, subscribedValues: { values } }">
4
- <div>values: {{ values }}</div>
5
- <OmegaInput label="asder2" name="asder2" :form="form">
6
- <template #default="inputProps">
7
- <label :for="inputProps.name">{{ inputProps.label }}</label>
8
- <input
9
- :id="inputProps.name"
10
- v-model="inputProps.field.state.value"
11
- :name="inputProps.name"
12
- style="border: 1px solid red"
13
- @change="(e: any) => inputProps.field.handleChange(e.target.value)"
14
- />
15
- </template>
16
- </OmegaInput>
17
- <button>submit</button>
18
- </template>
19
- </OmegaForm>
20
- </template>
21
-
22
- <script setup lang="ts">
23
- import { S } from "effect-app"
24
- import { OmegaForm, OmegaInput } from "../../components/OmegaForm"
25
-
26
- const schema = S.Struct({ asder2: S.String })
27
- const onSubmit = ({ value }: { value: { asder2: string } }) => {
28
- console.log(value)
29
- }
30
- </script>
@@ -1,15 +0,0 @@
1
- <template>
2
- <OmegaForm :schema="schema" :subscribe="['values']">
3
- <template #internalForm="{ form, subscribedValues: { values } }">
4
- <OmegaInput label="aString" :form="form" name="aString" />
5
- <pre>{{ values }}</pre>
6
- </template>
7
- </OmegaForm>
8
- </template>
9
-
10
- <script setup lang="ts">
11
- import { S } from "effect-app"
12
- import { OmegaForm, OmegaInput } from "../../components/OmegaForm"
13
-
14
- const schema = S.Struct({ aString: S.UndefinedOr(S.String) })
15
- </script>