@effect-app/vue-components 0.2.7 → 0.3.0

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 (39) hide show
  1. package/dist/types/components/OmegaForm/OmegaErrors.vue.d.ts +2 -2
  2. package/dist/types/components/OmegaForm/OmegaErrorsContext.d.ts +8 -5
  3. package/dist/types/components/OmegaForm/OmegaFormStuff.d.ts +1 -0
  4. package/dist/types/components/OmegaForm/OmegaInput.vue.d.ts +0 -1
  5. package/dist/types/components/OmegaForm/OmegaInternalInput.vue.d.ts +0 -1
  6. package/dist/types/components/OmegaForm/OmegaWrapper.vue.d.ts +8 -14
  7. package/dist/types/components/OmegaForm/getOmegaStore.d.ts +1 -1
  8. package/dist/types/components/OmegaForm/index.d.ts +5 -4
  9. package/dist/types/components/OmegaForm/useOmegaForm.d.ts +20 -3
  10. package/dist/vue-components.es11.js +27 -24
  11. package/dist/vue-components.es14.js +29 -29
  12. package/dist/vue-components.es15.js +4 -87
  13. package/dist/vue-components.es16.js +93 -11
  14. package/dist/vue-components.es17.js +11 -2
  15. package/dist/vue-components.es18.js +2 -115
  16. package/dist/vue-components.es19.js +117 -0
  17. package/dist/{vue-components.es20.js → vue-components.es21.js} +1 -1
  18. package/dist/vue-components.es4.js +29 -21
  19. package/dist/vue-components.es5.js +82 -16
  20. package/dist/vue-components.es7.js +2 -2
  21. package/dist/vue-components.es8.js +1 -1
  22. package/dist/vue-components.es9.js +2 -2
  23. package/package.json +11 -2
  24. package/src/components/OmegaForm/OmegaErrors.vue +2 -5
  25. package/src/components/OmegaForm/OmegaErrorsContext.ts +16 -3
  26. package/src/components/OmegaForm/OmegaFormStuff.ts +2 -0
  27. package/src/components/OmegaForm/OmegaInternalInput.vue +20 -12
  28. package/src/components/OmegaForm/OmegaWrapper.vue +13 -9
  29. package/src/components/OmegaForm/getOmegaStore.ts +1 -1
  30. package/src/components/OmegaForm/useOmegaForm.ts +133 -11
  31. package/src/stories/OmegaForm/ComplexForm.vue +81 -0
  32. package/src/stories/OmegaForm/EmailForm.vue +48 -0
  33. package/src/stories/OmegaForm/PersistencyForm.vue +65 -0
  34. package/src/stories/OmegaForm/SimpleForm.vue +30 -0
  35. package/src/stories/OmegaForm/SimpleFormVuetifyDefault.vue +15 -0
  36. package/src/stories/OmegaForm/SumExample.vue +39 -0
  37. package/src/stories/OmegaForm.stories.ts +83 -0
  38. package/src/stories/README.md +29 -0
  39. package/src/stories/tsconfig.json +4 -0
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <form @submit.prevent.stop="form.handleSubmit()">
2
+ <form novalidate @submit.prevent.stop="form.handleSubmit()">
3
3
  <fieldset :disabled="formIsSubmitting">
4
4
  <slot :form="form" :subscribed-values="subscribedValues" />
5
5
  </fieldset>
@@ -51,24 +51,27 @@ import { type S } from "effect-app"
51
51
  import {
52
52
  type FilterItems,
53
53
  type FormProps,
54
- type MetaRecord,
55
54
  type OmegaFormApi,
56
55
  type OmegaFormState,
56
+ type ShowErrorsOn,
57
57
  } from "./OmegaFormStuff"
58
58
  import { getOmegaStore } from "./getOmegaStore"
59
59
  import { provideOmegaErrors } from "./OmegaErrorsContext"
60
- import { useOmegaForm } from "./useOmegaForm"
60
+ import {
61
+ type OmegaConfig,
62
+ type OmegaFormReturn,
63
+ useOmegaForm,
64
+ } from "./useOmegaForm"
61
65
  import { watch } from "vue"
62
66
 
63
67
  const props = defineProps<
64
68
  {
69
+ omegaConfig?: OmegaConfig<From>
65
70
  subscribe?: K[]
71
+ showErrorsOn?: ShowErrorsOn
66
72
  } & (
67
73
  | {
68
- form: OmegaFormApi<To, From> & {
69
- meta: MetaRecord<To>
70
- filterItems?: FilterItems
71
- }
74
+ form: OmegaFormReturn<To, From>
72
75
  schema?: undefined
73
76
  }
74
77
  | (FormProps<To, From> & {
@@ -78,7 +81,8 @@ const props = defineProps<
78
81
  )
79
82
  >()
80
83
 
81
- const form = props.form ?? useOmegaForm<From, To>(props.schema, props)
84
+ const form =
85
+ props.form ?? useOmegaForm<From, To>(props.schema, props, props.omegaConfig)
82
86
 
83
87
  const formIsSubmitting = useStore(form.store, state => state.isSubmitting)
84
88
 
@@ -127,7 +131,7 @@ watch(
127
131
  },
128
132
  )
129
133
 
130
- provideOmegaErrors(formSubmissionAttempts, errors)
134
+ provideOmegaErrors(formSubmissionAttempts, errors, props.showErrorsOn)
131
135
  </script>
132
136
 
133
137
  <style scoped>
@@ -10,7 +10,7 @@ export function getOmegaStore<
10
10
  form: OmegaFormApi<To, From>,
11
11
  subscribe?: K[],
12
12
  ): Ref<
13
- K[] extends undefined
13
+ K[] extends undefined[]
14
14
  ? Record<string, never>
15
15
  : Pick<OmegaFormState<To, From>, K>
16
16
  > {
@@ -1,17 +1,45 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1
2
  import {
2
3
  useForm,
3
4
  type FormValidateOrFn,
4
5
  type FormAsyncValidateOrFn,
5
6
  type StandardSchemaV1,
6
7
  } from "@tanstack/vue-form"
7
- import { S } from "effect-app"
8
+ import { Match, S } from "effect-app"
8
9
  import {
9
10
  generateMetaFromSchema,
11
+ type NestedKeyOf,
10
12
  type FilterItems,
11
13
  type FormProps,
12
14
  type MetaRecord,
13
15
  type OmegaFormApi,
14
16
  } from "./OmegaFormStuff"
17
+ import { computed, onBeforeUnmount, onMounted, onUnmounted } from "vue"
18
+ import { constVoid } from "effect/Function"
19
+
20
+ type keysRule<T> =
21
+ | {
22
+ keys?: NestedKeyOf<T>[]
23
+ banKeys?: "You should only use one of banKeys or keys, not both, moron"
24
+ }
25
+ | {
26
+ keys?: "You should only use one of banKeys or keys, not both, moron"
27
+ banKeys?: NestedKeyOf<T>[]
28
+ }
29
+
30
+ export type OmegaConfig<T> = {
31
+ persistency?: {
32
+ method?: "session" | "local" | "none"
33
+ overrideDefaultValues?: boolean
34
+ id?: string
35
+ } & keysRule<T>
36
+ }
37
+
38
+ export interface OmegaFormReturn<To, From> extends OmegaFormApi<To, From> {
39
+ meta: MetaRecord<To>
40
+ filterItems?: FilterItems
41
+ clear: () => void
42
+ }
15
43
 
16
44
  export const useOmegaForm = <
17
45
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -20,16 +48,55 @@ export const useOmegaForm = <
20
48
  To extends Record<PropertyKey, any>,
21
49
  >(
22
50
  schema: S.Schema<From, To, never>,
23
- options?: NoInfer<FormProps<To, From>>,
24
- ): OmegaFormApi<To, From> & {
25
- meta: MetaRecord<To>
26
- filterItems?: FilterItems
27
- } => {
51
+ tanstackFormOptions?: NoInfer<FormProps<To, From>>,
52
+ omegaConfig?: OmegaConfig<From>,
53
+ ): OmegaFormReturn<To, From> => {
28
54
  if (!schema) throw new Error("Schema is required")
29
55
  const standardSchema = S.standardSchemaV1(schema)
30
56
 
31
57
  const { filterItems, meta } = generateMetaFromSchema(schema)
32
58
 
59
+ const persistencyKey = computed(() => {
60
+ if (omegaConfig?.persistency?.id) {
61
+ return omegaConfig.persistency.id
62
+ }
63
+ const path = window.location.pathname
64
+ const keys = Object.keys(meta)
65
+ return `${path}-${keys.join("-")}`
66
+ })
67
+
68
+ const defaultValues = computed(() => {
69
+ if (
70
+ tanstackFormOptions?.defaultValues &&
71
+ !omegaConfig?.persistency?.overrideDefaultValues
72
+ )
73
+ return tanstackFormOptions.defaultValues
74
+ const persistency = omegaConfig?.persistency
75
+ return Match.value(persistency).pipe(
76
+ Match.when(
77
+ { method: method => ["local", "session"].includes(method) },
78
+ persistency => {
79
+ const method = persistency.method
80
+ const storage = method === "local" ? localStorage : sessionStorage
81
+ if (storage) {
82
+ try {
83
+ const value = JSON.parse(
84
+ storage.getItem(persistencyKey.value) || "{}",
85
+ )
86
+ storage.removeItem(persistencyKey.value)
87
+ return value
88
+ } catch (error) {
89
+ console.error(error)
90
+ return {}
91
+ }
92
+ }
93
+ return {}
94
+ },
95
+ ),
96
+ Match.orElse(() => ({})),
97
+ )
98
+ })
99
+
33
100
  const form = useForm<
34
101
  To,
35
102
  FormValidateOrFn<To> | undefined,
@@ -42,22 +109,77 @@ export const useOmegaForm = <
42
109
  FormAsyncValidateOrFn<To> | undefined,
43
110
  FormAsyncValidateOrFn<To> | undefined
44
111
  >({
45
- ...options,
112
+ ...tanstackFormOptions,
46
113
  validators: {
47
114
  onSubmit: standardSchema,
48
- ...(options?.validators || {}),
115
+ ...(tanstackFormOptions?.validators || {}),
49
116
  },
50
- onSubmit: options?.onSubmit
117
+ onSubmit: tanstackFormOptions?.onSubmit
51
118
  ? ({ formApi, meta, value }) =>
52
- options.onSubmit?.({
119
+ tanstackFormOptions.onSubmit?.({
53
120
  formApi: formApi as OmegaFormApi<To, From>,
54
121
  meta,
55
122
  value: value as unknown as From,
56
123
  })
57
124
  : undefined,
125
+ defaultValues: defaultValues.value as any,
58
126
  }) satisfies OmegaFormApi<To, From>
59
127
 
60
- const exposed = Object.assign(form, { meta, filterItems })
128
+ const clear = () => {
129
+ Object.keys(meta).forEach((key: any) => {
130
+ form.setFieldValue(key, undefined)
131
+ })
132
+ }
133
+
134
+ const exposed = Object.assign(form, { meta, filterItems, clear })
135
+
136
+ // This is fragile as fuck. It's an experiment, it's only used because
137
+ // it's not a core feature of our products, so even if the this is not consistent
138
+ // it's not a big deal. So not take this code as a good example of how to do things.
139
+ // This is done only because this function is called before the component is destroyed,
140
+ // so the state would be lost anyway. So in this case we can play with the state, without
141
+ // worrying about the side effects.
142
+ const persistData = () => {
143
+ const persistency = omegaConfig?.persistency
144
+ Match.value(persistency).pipe(
145
+ Match.when(
146
+ { method: method => ["local", "session"].includes(method) },
147
+ persistency => {
148
+ const method = persistency.method
149
+ const storage = method === "local" ? localStorage : sessionStorage
150
+ if (storage) {
151
+ if (Array.isArray(persistency.keys)) {
152
+ const subs = Object.keys(meta).filter(
153
+ metakey => !persistency.keys?.includes(metakey as any),
154
+ )
155
+ subs.forEach(key => {
156
+ form.setFieldValue(key as any, undefined)
157
+ })
158
+ }
159
+ if (Array.isArray(persistency.banKeys)) {
160
+ persistency.banKeys.forEach(key => {
161
+ form.setFieldValue(key as any, undefined)
162
+ })
163
+ }
164
+ return storage.setItem(
165
+ persistencyKey.value,
166
+ JSON.stringify(form.store.state.values),
167
+ )
168
+ }
169
+ },
170
+ ),
171
+ Match.orElse(constVoid),
172
+ )
173
+ }
174
+
175
+ onUnmounted(persistData)
176
+
177
+ onMounted(() => {
178
+ window.addEventListener("beforeunload", persistData)
179
+ })
180
+ onBeforeUnmount(() => {
181
+ window.removeEventListener("beforeunload", persistData)
182
+ })
61
183
 
62
184
  return exposed
63
185
  }
@@ -0,0 +1,81 @@
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>
34
+ </OmegaForm>
35
+ </template>
36
+
37
+ <script setup lang="ts">
38
+ import { S } from "effect-app"
39
+ import { OmegaForm, OmegaInput, useOmegaForm } from "../../components/OmegaForm"
40
+
41
+ const form = useOmegaForm(
42
+ S.Struct({
43
+ aString: S.String,
44
+ aStringMin2: S.String.pipe(S.minLength(2)),
45
+ aStringMin2Max4: S.String.pipe(S.minLength(2)).pipe(S.maxLength(4)),
46
+ aStringMin2Max3Nullable: S.UndefinedOr(
47
+ S.String.pipe(S.minLength(2)).pipe(S.maxLength(3)),
48
+ ),
49
+ aNumber: S.Number,
50
+ aNumberMin2: S.Number.pipe(S.greaterThan(2)),
51
+ aNumberMin2Max: S.Number.pipe(S.greaterThan(2)).pipe(S.lessThan(4)),
52
+ aNumberMin2Max4Nullable: S.NullOr(S.Number.pipe(S.between(2, 4))),
53
+ aSelect: S.Union(S.Literal("a"), S.Literal("b"), S.Literal("c")),
54
+ }),
55
+ {
56
+ onSubmit: ({
57
+ value,
58
+ }: {
59
+ value: {
60
+ aString: string
61
+ aStringMin2: string
62
+ aStringMin2Max4: string
63
+ aStringMin2Max3Nullable?: string
64
+ aNumber: number
65
+ aNumberMin2: number
66
+ aNumberMin2Max: number
67
+ aNumberMin2Max4Nullable: number | null
68
+ aSelect: "a" | "b" | "c"
69
+ }
70
+ }) => {
71
+ console.log(value)
72
+ },
73
+ },
74
+ {
75
+ persistency: {
76
+ method: "local",
77
+ overrideDefaultValues: true,
78
+ },
79
+ },
80
+ )
81
+ </script>
@@ -0,0 +1,48 @@
1
+ <template>
2
+ <OmegaForm
3
+ :schema="schema"
4
+ :on-submit="onSubmit"
5
+ :default-values="defaultValues"
6
+ >
7
+ <template #default="{ 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>
@@ -0,0 +1,65 @@
1
+ <template>
2
+ <OmegaForm
3
+ :form="addForm"
4
+ :subscribe="['errors', 'values']"
5
+ show-errors-on="onChange"
6
+ >
7
+ <template #default="{ form, subscribedValues: { errors, values } }">
8
+ <div>Errors: {{ errors }}</div>
9
+ <div>Values: {{ values }}</div>
10
+ <OmegaInput label="first" :form="form" name="first" />
11
+ <div>+</div>
12
+ <OmegaInput label="second" :form="form" name="second" />
13
+ <br />
14
+ <hr />
15
+ <br />
16
+ <OmegaInput label="third.fourth" :form="form" name="third.fourth" />
17
+ <OmegaInput label="third.fifth" :form="form" 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
+ method: "session",
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
+
59
+ // TODO: Implement this when we have a way to persist the form values
60
+ // {
61
+ // persist: "session",
62
+ // persistKeys: ["riskCategoryPeriod"],
63
+ // persistBanKeys: ["riskCategory"],
64
+ // }
65
+ </script>
@@ -0,0 +1,30 @@
1
+ <template>
2
+ <OmegaForm :schema="schema" :on-submit="onSubmit" :subscribe="['values']">
3
+ <template #default="{ 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>
@@ -0,0 +1,15 @@
1
+ <template>
2
+ <OmegaForm :schema="schema" :subscribe="['values']">
3
+ <template #default="{ 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>
@@ -0,0 +1,39 @@
1
+ <template>
2
+ <OmegaForm :form="addForm">
3
+ <template #default="{ form }">
4
+ <OmegaInput label="first" :form="form" name="first" />
5
+ <div>+</div>
6
+ <OmegaInput label="second" :form="form" name="second" />
7
+ </template>
8
+ </OmegaForm>
9
+
10
+ <!-- Technically you can do this only with a subscribe but only inside OmegaForm Context -->
11
+ <div>
12
+ <div>Sum: {{ sum }}</div>
13
+ </div>
14
+ </template>
15
+
16
+ <script setup lang="ts">
17
+ import { S } from "effect-app"
18
+ import { OmegaForm, OmegaInput, useOmegaForm } from "../../components/OmegaForm"
19
+ import { ref, watch } from "vue"
20
+
21
+ const sum = ref(0)
22
+ const AddSchema = S.Struct({
23
+ first: S.Number,
24
+ second: S.Number,
25
+ })
26
+
27
+ const addForm = useOmegaForm(AddSchema, {
28
+ defaultValues: {
29
+ first: 0,
30
+ second: 0,
31
+ },
32
+ })
33
+
34
+ const values = addForm.useStore(({ values }) => values)
35
+
36
+ watch(values, ({ first, second }) => {
37
+ sum.value = first + second
38
+ })
39
+ </script>
@@ -0,0 +1,83 @@
1
+ import type { Meta, StoryObj } from "@storybook/vue3"
2
+ import { OmegaForm } from "../components/OmegaForm"
3
+ import { provideIntl } from "../utils"
4
+ import { type makeIntl } from "@effect-app/vue"
5
+ import { ref } from "vue"
6
+ import SimpleForm from "./OmegaForm/SimpleForm.vue"
7
+ import EmailForm from "./OmegaForm/EmailForm.vue"
8
+ import ComplexForm from "./OmegaForm/ComplexForm.vue"
9
+ import SimpleFormVuetifyDefault from "./OmegaForm/SimpleFormVuetifyDefault.vue"
10
+ import SumExample from "./OmegaForm/SumExample.vue"
11
+ import PersistencyForm from "./OmegaForm/PersistencyForm.vue"
12
+
13
+ const mockIntl = {
14
+ locale: ref("en"),
15
+ trans: (id: string) => id,
16
+ intl: ref({ formatMessage: (msg: { id: string }) => msg.id }),
17
+ } as unknown as ReturnType<ReturnType<typeof makeIntl<string>>["useIntl"]>
18
+
19
+ const meta: Meta<typeof OmegaForm> = {
20
+ title: "Components/OmegaForm",
21
+ component: OmegaForm,
22
+ tags: ["autodocs"],
23
+ argTypes: {
24
+ schema: { control: "object" },
25
+ onSubmit: { action: "submitted" },
26
+ defaultValues: { control: "object" },
27
+ },
28
+ decorators: [
29
+ story => ({
30
+ components: { story },
31
+ setup() {
32
+ provideIntl(mockIntl)
33
+ return {}
34
+ },
35
+ template: "<story />",
36
+ }),
37
+ ],
38
+ }
39
+
40
+ export default meta
41
+ type Story = StoryObj<typeof meta>
42
+
43
+ export const SimpleFormStory: Story = {
44
+ render: () => ({
45
+ components: { SimpleForm },
46
+ template: "<SimpleForm />",
47
+ }),
48
+ }
49
+
50
+ export const EmailFormStory: Story = {
51
+ render: () => ({
52
+ components: { EmailForm },
53
+ template: "<EmailForm />",
54
+ }),
55
+ }
56
+
57
+ export const ComplexFormStory: Story = {
58
+ render: () => ({
59
+ components: { ComplexForm },
60
+ template: "<ComplexForm />",
61
+ }),
62
+ }
63
+
64
+ export const SimpleFormVuetifyDefaultStory: Story = {
65
+ render: () => ({
66
+ components: { SimpleFormVuetifyDefault },
67
+ template: "<SimpleFormVuetifyDefault />",
68
+ }),
69
+ }
70
+
71
+ export const SumExampleStory: Story = {
72
+ render: () => ({
73
+ components: { SumExample },
74
+ template: "<SumExample />",
75
+ }),
76
+ }
77
+
78
+ export const PersistencyFormStory: Story = {
79
+ render: () => ({
80
+ components: { PersistencyForm },
81
+ template: "<PersistencyForm />",
82
+ }),
83
+ }
@@ -0,0 +1,29 @@
1
+ # Storybook Stories
2
+
3
+ This folder contains all the Storybook stories for the Vue Components package. Each story file corresponds to a component and demonstrates its various use cases and configurations.
4
+
5
+ ## Structure
6
+
7
+ - Each story file is named after the component it's documenting (e.g., `OmegaForm.stories.ts`)
8
+ - Stories are organized by component type and functionality
9
+ - Each story includes proper TypeScript typing and documentation
10
+
11
+ ## Running Stories
12
+
13
+ To run the Storybook:
14
+
15
+ ```bash
16
+ pnpm storybook
17
+ ```
18
+
19
+ This will start Storybook on port 6006, and you can view your components at http://localhost:6006.
20
+
21
+ ## Adding New Stories
22
+
23
+ When adding a new story:
24
+
25
+ 1. Create a new file in this folder with the naming pattern `ComponentName.stories.ts`
26
+ 2. Import the component and any dependencies
27
+ 3. Define the meta object with component information
28
+ 4. Create story objects that demonstrate different use cases
29
+ 5. Use proper TypeScript typing for all parameters
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "exclude": []
4
+ }