@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,117 +1,4 @@
1
- import { defineComponent as P, resolveComponent as u, createElementBlock as g, openBlock as o, createBlock as n, createCommentVNode as l, mergeProps as s } from "vue";
2
- const b = /* @__PURE__ */ P({
3
- inheritAttrs: !1,
4
- __name: "OmegaInputVuetify",
5
- props: {
6
- inputProps: {},
7
- vuetifyValue: {}
8
- },
9
- emits: ["focus", "blur"],
10
- setup(y) {
11
- return (e, r) => {
12
- const a = u("v-checkbox"), i = u("v-text-field"), t = u("v-textarea"), m = u("v-select"), d = u("v-autocomplete");
13
- return o(), g("div", {
14
- class: "omega-input",
15
- onFocusout: r[4] || (r[4] = (p) => e.$emit("blur", p)),
16
- onFocusin: r[5] || (r[5] = (p) => e.$emit("focus", p))
17
- }, [
18
- e.inputProps.type === "boolean" ? (o(), n(a, s({
19
- key: 0,
20
- id: e.inputProps.id,
21
- name: e.inputProps.name,
22
- label: e.inputProps.label,
23
- "error-messages": e.inputProps.errorMessages,
24
- error: e.inputProps.error,
25
- ripple: ""
26
- }, e.$attrs, {
27
- "model-value": e.vuetifyValue,
28
- onChange: r[0] || (r[0] = (p) => e.inputProps.field.handleChange(p.target.checked))
29
- }), null, 16, ["id", "name", "label", "error-messages", "error", "model-value"])) : l("", !0),
30
- e.inputProps.type === "email" || e.inputProps.type === "string" ? (o(), n(i, s({
31
- key: 1,
32
- id: e.inputProps.id,
33
- required: e.inputProps.required,
34
- "min-length": e.inputProps.minLength,
35
- "max-length": e.inputProps.maxLength,
36
- type: e.inputProps.type,
37
- name: e.inputProps.name,
38
- label: e.inputProps.label,
39
- "error-messages": e.inputProps.errorMessages,
40
- error: e.inputProps.error
41
- }, e.$attrs, {
42
- "model-value": e.vuetifyValue,
43
- "onUpdate:modelValue": e.inputProps.field.handleChange
44
- }), null, 16, ["id", "required", "min-length", "max-length", "type", "name", "label", "error-messages", "error", "model-value", "onUpdate:modelValue"])) : l("", !0),
45
- e.inputProps.type === "text" ? (o(), n(t, s({
46
- key: 2,
47
- id: e.inputProps.id,
48
- required: e.inputProps.required,
49
- "min-length": e.inputProps.minLength,
50
- "max-length": e.inputProps.maxLength,
51
- type: e.inputProps.type,
52
- name: e.inputProps.name,
53
- label: e.inputProps.label,
54
- "error-messages": e.inputProps.errorMessages,
55
- error: e.inputProps.error
56
- }, e.$attrs, {
57
- "model-value": e.vuetifyValue,
58
- "onUpdate:modelValue": e.inputProps.field.handleChange
59
- }), null, 16, ["id", "required", "min-length", "max-length", "type", "name", "label", "error-messages", "error", "model-value", "onUpdate:modelValue"])) : l("", !0),
60
- e.inputProps.type === "number" ? (o(), n(i, s({
61
- key: 3,
62
- id: e.inputProps.id,
63
- required: e.inputProps.required,
64
- min: e.inputProps.min,
65
- max: e.inputProps.max,
66
- type: e.inputProps.type,
67
- name: e.inputProps.name,
68
- label: e.inputProps.label,
69
- "error-messages": e.inputProps.errorMessages,
70
- error: e.inputProps.error
71
- }, e.$attrs, {
72
- "model-value": e.vuetifyValue,
73
- "onUpdate:modelValue": r[1] || (r[1] = (p) => {
74
- e.inputProps.field.handleChange(Number(p));
75
- })
76
- }), null, 16, ["id", "required", "min", "max", "type", "name", "label", "error-messages", "error", "model-value"])) : l("", !0),
77
- e.inputProps.type === "select" || e.inputProps.type === "multiple" ? (o(), n(m, s({
78
- key: 4,
79
- id: e.inputProps.id,
80
- clearable: e.inputProps.type === "select",
81
- required: e.inputProps.required,
82
- multiple: e.inputProps.type === "multiple",
83
- chips: e.inputProps.type === "multiple",
84
- name: e.inputProps.name,
85
- label: e.inputProps.label,
86
- items: e.inputProps.options,
87
- "error-messages": e.inputProps.errorMessages,
88
- error: e.inputProps.error
89
- }, e.$attrs, {
90
- "model-value": e.vuetifyValue,
91
- onClear: r[2] || (r[2] = (p) => e.inputProps.field.handleChange(void 0)),
92
- "onUpdate:modelValue": e.inputProps.field.handleChange
93
- }), null, 16, ["id", "clearable", "required", "multiple", "chips", "name", "label", "items", "error-messages", "error", "model-value", "onUpdate:modelValue"])) : l("", !0),
94
- e.inputProps.type === "autocomplete" || e.inputProps.type === "autocompletemultiple" ? (o(), n(d, s({
95
- key: 5,
96
- id: e.inputProps.id,
97
- clearable: e.inputProps.type === "autocomplete",
98
- multiple: e.inputProps.type === "autocompletemultiple",
99
- required: e.inputProps.required,
100
- name: e.inputProps.name,
101
- label: e.inputProps.label,
102
- items: e.inputProps.options,
103
- "error-messages": e.inputProps.errorMessages,
104
- error: e.inputProps.error,
105
- chips: e.inputProps.type === "autocompletemultiple"
106
- }, e.$attrs, {
107
- "model-value": e.vuetifyValue,
108
- onClear: r[3] || (r[3] = (p) => e.inputProps.field.handleChange(void 0)),
109
- "onUpdate:modelValue": e.inputProps.field.handleChange
110
- }), null, 16, ["id", "clearable", "multiple", "required", "name", "label", "items", "error-messages", "error", "chips", "model-value", "onUpdate:modelValue"])) : l("", !0)
111
- ], 32);
112
- };
113
- }
114
- });
1
+ import f from "./vue-components.es16.js";
115
2
  export {
116
- b as default
3
+ f as default
117
4
  };
@@ -0,0 +1,117 @@
1
+ import { defineComponent as P, resolveComponent as u, createElementBlock as g, openBlock as o, createBlock as n, createCommentVNode as l, mergeProps as s } from "vue";
2
+ const b = /* @__PURE__ */ P({
3
+ inheritAttrs: !1,
4
+ __name: "OmegaInputVuetify",
5
+ props: {
6
+ inputProps: {},
7
+ vuetifyValue: {}
8
+ },
9
+ emits: ["focus", "blur"],
10
+ setup(y) {
11
+ return (e, r) => {
12
+ const a = u("v-checkbox"), i = u("v-text-field"), t = u("v-textarea"), m = u("v-select"), d = u("v-autocomplete");
13
+ return o(), g("div", {
14
+ class: "omega-input",
15
+ onFocusout: r[4] || (r[4] = (p) => e.$emit("blur", p)),
16
+ onFocusin: r[5] || (r[5] = (p) => e.$emit("focus", p))
17
+ }, [
18
+ e.inputProps.type === "boolean" ? (o(), n(a, s({
19
+ key: 0,
20
+ id: e.inputProps.id,
21
+ name: e.inputProps.name,
22
+ label: e.inputProps.label,
23
+ "error-messages": e.inputProps.errorMessages,
24
+ error: e.inputProps.error,
25
+ ripple: ""
26
+ }, e.$attrs, {
27
+ "model-value": e.vuetifyValue,
28
+ onChange: r[0] || (r[0] = (p) => e.inputProps.field.handleChange(p.target.checked))
29
+ }), null, 16, ["id", "name", "label", "error-messages", "error", "model-value"])) : l("", !0),
30
+ e.inputProps.type === "email" || e.inputProps.type === "string" ? (o(), n(i, s({
31
+ key: 1,
32
+ id: e.inputProps.id,
33
+ required: e.inputProps.required,
34
+ "min-length": e.inputProps.minLength,
35
+ "max-length": e.inputProps.maxLength,
36
+ type: e.inputProps.type,
37
+ name: e.inputProps.name,
38
+ label: e.inputProps.label,
39
+ "error-messages": e.inputProps.errorMessages,
40
+ error: e.inputProps.error
41
+ }, e.$attrs, {
42
+ "model-value": e.vuetifyValue,
43
+ "onUpdate:modelValue": e.inputProps.field.handleChange
44
+ }), null, 16, ["id", "required", "min-length", "max-length", "type", "name", "label", "error-messages", "error", "model-value", "onUpdate:modelValue"])) : l("", !0),
45
+ e.inputProps.type === "text" ? (o(), n(t, s({
46
+ key: 2,
47
+ id: e.inputProps.id,
48
+ required: e.inputProps.required,
49
+ "min-length": e.inputProps.minLength,
50
+ "max-length": e.inputProps.maxLength,
51
+ type: e.inputProps.type,
52
+ name: e.inputProps.name,
53
+ label: e.inputProps.label,
54
+ "error-messages": e.inputProps.errorMessages,
55
+ error: e.inputProps.error
56
+ }, e.$attrs, {
57
+ "model-value": e.vuetifyValue,
58
+ "onUpdate:modelValue": e.inputProps.field.handleChange
59
+ }), null, 16, ["id", "required", "min-length", "max-length", "type", "name", "label", "error-messages", "error", "model-value", "onUpdate:modelValue"])) : l("", !0),
60
+ e.inputProps.type === "number" ? (o(), n(i, s({
61
+ key: 3,
62
+ id: e.inputProps.id,
63
+ required: e.inputProps.required,
64
+ min: e.inputProps.min,
65
+ max: e.inputProps.max,
66
+ type: e.inputProps.type,
67
+ name: e.inputProps.name,
68
+ label: e.inputProps.label,
69
+ "error-messages": e.inputProps.errorMessages,
70
+ error: e.inputProps.error
71
+ }, e.$attrs, {
72
+ "model-value": e.vuetifyValue,
73
+ "onUpdate:modelValue": r[1] || (r[1] = (p) => {
74
+ e.inputProps.field.handleChange(Number(p));
75
+ })
76
+ }), null, 16, ["id", "required", "min", "max", "type", "name", "label", "error-messages", "error", "model-value"])) : l("", !0),
77
+ e.inputProps.type === "select" || e.inputProps.type === "multiple" ? (o(), n(m, s({
78
+ key: 4,
79
+ id: e.inputProps.id,
80
+ clearable: e.inputProps.type === "select",
81
+ required: e.inputProps.required,
82
+ multiple: e.inputProps.type === "multiple",
83
+ chips: e.inputProps.type === "multiple",
84
+ name: e.inputProps.name,
85
+ label: e.inputProps.label,
86
+ items: e.inputProps.options,
87
+ "error-messages": e.inputProps.errorMessages,
88
+ error: e.inputProps.error
89
+ }, e.$attrs, {
90
+ "model-value": e.vuetifyValue,
91
+ onClear: r[2] || (r[2] = (p) => e.inputProps.field.handleChange(void 0)),
92
+ "onUpdate:modelValue": e.inputProps.field.handleChange
93
+ }), null, 16, ["id", "clearable", "required", "multiple", "chips", "name", "label", "items", "error-messages", "error", "model-value", "onUpdate:modelValue"])) : l("", !0),
94
+ e.inputProps.type === "autocomplete" || e.inputProps.type === "autocompletemultiple" ? (o(), n(d, s({
95
+ key: 5,
96
+ id: e.inputProps.id,
97
+ clearable: e.inputProps.type === "autocomplete",
98
+ multiple: e.inputProps.type === "autocompletemultiple",
99
+ required: e.inputProps.required,
100
+ name: e.inputProps.name,
101
+ label: e.inputProps.label,
102
+ items: e.inputProps.options,
103
+ "error-messages": e.inputProps.errorMessages,
104
+ error: e.inputProps.error,
105
+ chips: e.inputProps.type === "autocompletemultiple"
106
+ }, e.$attrs, {
107
+ "model-value": e.vuetifyValue,
108
+ onClear: r[3] || (r[3] = (p) => e.inputProps.field.handleChange(void 0)),
109
+ "onUpdate:modelValue": e.inputProps.field.handleChange
110
+ }), null, 16, ["id", "clearable", "multiple", "required", "name", "label", "items", "error-messages", "error", "chips", "model-value", "onUpdate:modelValue"])) : l("", !0)
111
+ ], 32);
112
+ };
113
+ }
114
+ });
115
+ export {
116
+ b as default
117
+ };
@@ -1,5 +1,5 @@
1
1
  (function(){"use strict";try{if(typeof document<"u"){var n=document.createElement("style");if(n.appendChild(document.createTextNode(".omega-input .v-input__details:has(.v-messages:empty){grid-template-rows:0fr;transition:all .2s}.omega-input .v-messages:empty{min-height:0}.omega-input .v-input__details:has(.v-messages){transition:all .2s;overflow:hidden;min-height:0;display:grid;grid-template-rows:1fr}.omega-input .v-messages{transition:all .2s}.omega-input .v-messages>*{transition-duration:0s!important}.omega-input [role=alert]:has(.v-messages:empty){padding:0}.omega-input .v-btn{cursor:pointer;width:auto;-webkit-appearance:none;-moz-appearance:none;appearance:none;box-shadow:none;display:block;min-width:auto;height:auto;padding:.5em .5em .5em 1em}")),document.head.appendChild(n),window.customElements){const e=window.customElements.define;window.customElements.define=function(o,t){const a=t.prototype.connectedCallback;return t.prototype.connectedCallback=function(){if(a&&a.call(this),this.shadowRoot){const i=document.createElement("style");i.appendChild(document.createTextNode(".omega-input .v-input__details:has(.v-messages:empty){grid-template-rows:0fr;transition:all .2s}.omega-input .v-messages:empty{min-height:0}.omega-input .v-input__details:has(.v-messages){transition:all .2s;overflow:hidden;min-height:0;display:grid;grid-template-rows:1fr}.omega-input .v-messages{transition:all .2s}.omega-input .v-messages>*{transition-duration:0s!important}.omega-input [role=alert]:has(.v-messages:empty){padding:0}.omega-input .v-btn{cursor:pointer;width:auto;-webkit-appearance:none;-moz-appearance:none;appearance:none;box-shadow:none;display:block;min-width:auto;height:auto;padding:.5em .5em .5em 1em}")),this.shadowRoot.appendChild(i)}},e.call(window.customElements,o,t)}}}}catch(e){console.error("vite-plugin-css-injected-by-js",e)}})();
2
- import o from "./vue-components.es18.js";
2
+ import o from "./vue-components.es19.js";
3
3
 
4
4
  export {
5
5
  o as default
@@ -1,30 +1,38 @@
1
- import { ref as m, readonly as d, provide as l, inject as p } from "vue";
2
- const s = Symbol();
3
- function E(e, u) {
4
- const r = m([]), t = (o) => {
5
- r.value = r.value.filter((i) => i.inputId !== o);
6
- }, a = (o) => {
7
- t(o.inputId), r.value.push(o);
8
- }, c = () => {
1
+ import { ref as l, computed as p, readonly as v, provide as E, inject as f } from "vue";
2
+ const u = Symbol();
3
+ function h(e, a, t = "onSubmit") {
4
+ const r = l([]), n = (o) => {
5
+ r.value = r.value.filter((d) => d.inputId !== o);
6
+ }, c = (o) => {
7
+ n(o.inputId), r.value.push(o);
8
+ }, i = () => {
9
9
  r.value = [];
10
- }, n = {
11
- errors: d(r),
12
- addError: a,
13
- removeError: t,
14
- clearErrors: c,
15
- formSubmissionAttempts: e,
16
- generalErrors: u
10
+ }, m = p(() => {
11
+ switch (t) {
12
+ case "onChange":
13
+ return !0;
14
+ default:
15
+ return e.value > 0;
16
+ }
17
+ }), s = {
18
+ errors: v(r),
19
+ addError: c,
20
+ removeError: n,
21
+ clearErrors: i,
22
+ showErrors: m,
23
+ generalErrors: a,
24
+ showErrorsOn: t ?? "onSubmit"
17
25
  };
18
- return l(s, n), n;
26
+ return E(u, s), s;
19
27
  }
20
- function f() {
21
- const e = p(s);
28
+ function w() {
29
+ const e = f(u);
22
30
  if (!e)
23
31
  throw new Error("useOmegaErrors must be used within an OmegaForm provider");
24
32
  return e;
25
33
  }
26
34
  export {
27
- s as OmegaErrorsKey,
28
- E as provideOmegaErrors,
29
- f as useOmegaErrors
35
+ u as OmegaErrorsKey,
36
+ h as provideOmegaErrors,
37
+ w as useOmegaErrors
30
38
  };
@@ -1,25 +1,91 @@
1
- import { useForm as b } from "@tanstack/vue-form";
2
- import { S as g } from "effect-app";
3
- import { generateMetaFromSchema as h } from "./vue-components.es6.js";
4
- const v = (r, e) => {
5
- if (!r) throw new Error("Schema is required");
6
- const a = g.standardSchemaV1(r), { filterItems: t, meta: d } = h(r), u = b({
1
+ import { useForm as E } from "@tanstack/vue-form";
2
+ import { S as j, Match as n } from "effect-app";
3
+ import { generateMetaFromSchema as A } from "./vue-components.es6.js";
4
+ import { computed as b, onUnmounted as I, onMounted as K, onBeforeUnmount as M } from "vue";
5
+ import { constVoid as x } from "./vue-components.es15.js";
6
+ const m = (i, e, u) => {
7
+ if (!i) throw new Error("Schema is required");
8
+ const a = j.standardSchemaV1(i), { filterItems: f, meta: y } = A(i), o = b(() => {
9
+ var d;
10
+ if ((d = u == null ? void 0 : u.persistency) != null && d.id)
11
+ return u.persistency.id;
12
+ const l = window.location.pathname, r = Object.keys(y);
13
+ return `${l}-${r.join("-")}`;
14
+ }), w = b(() => {
15
+ var r;
16
+ if (e != null && e.defaultValues && !((r = u == null ? void 0 : u.persistency) != null && r.overrideDefaultValues))
17
+ return e.defaultValues;
18
+ const l = u == null ? void 0 : u.persistency;
19
+ return n.value(l).pipe(
20
+ n.when(
21
+ { method: (d) => ["local", "session"].includes(d) },
22
+ (d) => {
23
+ const c = d.method === "local" ? localStorage : sessionStorage;
24
+ if (c)
25
+ try {
26
+ const s = JSON.parse(
27
+ c.getItem(o.value) || "{}"
28
+ );
29
+ return c.removeItem(o.value), s;
30
+ } catch (s) {
31
+ return console.error(s), {};
32
+ }
33
+ return {};
34
+ }
35
+ ),
36
+ n.orElse(() => ({}))
37
+ );
38
+ }), h = E({
7
39
  ...e,
8
40
  validators: {
9
41
  onSubmit: a,
10
42
  ...(e == null ? void 0 : e.validators) || {}
11
43
  },
12
- onSubmit: e != null && e.onSubmit ? ({ formApi: S, meta: c, value: f }) => {
13
- var m;
14
- return (m = e.onSubmit) == null ? void 0 : m.call(e, {
15
- formApi: S,
16
- meta: c,
17
- value: f
44
+ onSubmit: e != null && e.onSubmit ? ({ formApi: l, meta: r, value: d }) => {
45
+ var t;
46
+ return (t = e.onSubmit) == null ? void 0 : t.call(e, {
47
+ formApi: l,
48
+ meta: r,
49
+ value: d
18
50
  });
19
- } : void 0
20
- });
21
- return Object.assign(u, { meta: d, filterItems: t });
51
+ } : void 0,
52
+ defaultValues: w.value
53
+ }), V = Object.assign(h, { meta: y, filterItems: f, clear: () => {
54
+ Object.keys(y).forEach((l) => {
55
+ h.setFieldValue(l, void 0);
56
+ });
57
+ } }), v = () => {
58
+ const l = u == null ? void 0 : u.persistency;
59
+ n.value(l).pipe(
60
+ n.when(
61
+ { method: (r) => ["local", "session"].includes(r) },
62
+ (r) => {
63
+ const t = r.method === "local" ? localStorage : sessionStorage;
64
+ if (t)
65
+ return Array.isArray(r.keys) && Object.keys(y).filter(
66
+ (s) => {
67
+ var S;
68
+ return !((S = r.keys) != null && S.includes(s));
69
+ }
70
+ ).forEach((s) => {
71
+ h.setFieldValue(s, void 0);
72
+ }), Array.isArray(r.banKeys) && r.banKeys.forEach((c) => {
73
+ h.setFieldValue(c, void 0);
74
+ }), t.setItem(
75
+ o.value,
76
+ JSON.stringify(h.store.state.values)
77
+ );
78
+ }
79
+ ),
80
+ n.orElse(x)
81
+ );
82
+ };
83
+ return I(v), K(() => {
84
+ window.addEventListener("beforeunload", v);
85
+ }), M(() => {
86
+ window.removeEventListener("beforeunload", v);
87
+ }), V;
22
88
  };
23
89
  export {
24
- v as useOmegaForm
90
+ m as useOmegaForm
25
91
  };
@@ -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-0de09910]{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-0de09910]{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-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)}})();
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-0de09910"]]);
4
+ const a = /* @__PURE__ */ m(o, [["__scopeId", "data-v-fd152523"]]);
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.es15.js";
3
+ import b from "./vue-components.es16.js";
4
4
  const S = /* @__PURE__ */ i({
5
5
  inheritAttrs: !1,
6
6
  __name: "OmegaInput",
@@ -1,7 +1,7 @@
1
- (function(){"use strict";try{if(typeof document<"u"){var t=document.createElement("style");if(t.appendChild(document.createTextNode(".v-enter-from[data-v-fde7a2c8],.v-leave-to[data-v-fde7a2c8]{max-height:0px;grid-template-rows:0fr;opacity:0}.v-enter-active[data-v-fde7a2c8],.v-leave-active[data-v-fde7a2c8]{display:grid;transition:all .15s}.v-enter-to[data-v-fde7a2c8],.v-leave-from[data-v-fde7a2c8]{grid-template-rows:1fr;max-height:50vh;opacity:1}.error-alert[data-v-fde7a2c8]{transition-behavior:allow-discrete;display:grid;overflow:hidden;min-height:0}.error-alert>*[data-v-fde7a2c8]{min-height:0}.error-list[data-v-fde7a2c8]{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-fde7a2c8]{grid-template-columns:auto 1fr}.error-link[data-v-fde7a2c8]{grid-column:1 / -1;justify-self:end}}@container (max-width: 18.75rem){.error-list[data-v-fde7a2c8]{grid-template-columns:1fr}.error-message[data-v-fde7a2c8]{grid-column:1 / -1}}.error-item[data-v-fde7a2c8]{display:contents}a[data-v-fde7a2c8]{min-width:min-content}.error-link[data-v-fde7a2c8]{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(d,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-fde7a2c8],.v-leave-to[data-v-fde7a2c8]{max-height:0px;grid-template-rows:0fr;opacity:0}.v-enter-active[data-v-fde7a2c8],.v-leave-active[data-v-fde7a2c8]{display:grid;transition:all .15s}.v-enter-to[data-v-fde7a2c8],.v-leave-from[data-v-fde7a2c8]{grid-template-rows:1fr;max-height:50vh;opacity:1}.error-alert[data-v-fde7a2c8]{transition-behavior:allow-discrete;display:grid;overflow:hidden;min-height:0}.error-alert>*[data-v-fde7a2c8]{min-height:0}.error-list[data-v-fde7a2c8]{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-fde7a2c8]{grid-template-columns:auto 1fr}.error-link[data-v-fde7a2c8]{grid-column:1 / -1;justify-self:end}}@container (max-width: 18.75rem){.error-list[data-v-fde7a2c8]{grid-template-columns:1fr}.error-message[data-v-fde7a2c8]{grid-column:1 / -1}}.error-item[data-v-fde7a2c8]{display:contents}a[data-v-fde7a2c8]{min-width:min-content}.error-link[data-v-fde7a2c8]{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,d,a)}}}}catch(e){console.error("vite-plugin-css-injected-by-js",e)}})();
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
2
  import o from "./vue-components.es14.js";
3
3
  import r from "./vue-components.es12.js";
4
- const e = /* @__PURE__ */ r(o, [["__scopeId", "data-v-fde7a2c8"]]);
4
+ const e = /* @__PURE__ */ r(o, [["__scopeId", "data-v-502ecb3a"]]);
5
5
  export {
6
6
  e as default
7
7
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect-app/vue-components",
3
- "version": "0.2.7",
3
+ "version": "0.3.0",
4
4
  "peerDependencies": {
5
5
  "@mdi/js": "^7.4.47",
6
6
  "@tanstack/vue-form": "^1.2.4",
@@ -14,6 +14,12 @@
14
14
  "vuetify": "^3.7.19"
15
15
  },
16
16
  "devDependencies": {
17
+ "@storybook/addon-essentials": "^8.6.12",
18
+ "@storybook/addon-interactions": "^8.6.12",
19
+ "@storybook/blocks": "^8.6.12",
20
+ "@storybook/testing-library": "^0.2.2",
21
+ "@storybook/vue3": "^8.6.12",
22
+ "@storybook/vue3-vite": "^8.6.12",
17
23
  "@types/node": "^22.13.14",
18
24
  "@typescript-eslint/eslint-plugin": "8.29.0",
19
25
  "@typescript-eslint/parser": "8.29.0",
@@ -24,6 +30,7 @@
24
30
  "eslint-plugin-vue": "^10.0.0",
25
31
  "rimraf": "^6.0.1",
26
32
  "sass": "^1.86.0",
33
+ "storybook": "^8.6.12",
27
34
  "typescript": "^5.8.2",
28
35
  "vite": "^6.2.3",
29
36
  "vite-plugin-css-injected-by-js": "^3.5.2",
@@ -52,6 +59,8 @@
52
59
  "docs:build": "vitepress build docs",
53
60
  "docs:serve": "vitepress serve docs",
54
61
  "lint": "NODE_OPTIONS=--max-old-space-size=8192 eslint src",
55
- "autofix": "pnpm lint --fix"
62
+ "autofix": "pnpm lint --fix",
63
+ "storybook": "storybook dev -p 6006",
64
+ "build-storybook": "storybook build"
56
65
  }
57
66
  }
@@ -1,10 +1,7 @@
1
1
  <template>
2
2
  <Transition>
3
3
  <div
4
- v-if="
5
- formSubmissionAttempts > 0 &&
6
- (errors.length || showedGeneralErrors.length)
7
- "
4
+ v-if="showErrors && (errors.length || showedGeneralErrors.length)"
8
5
  class="error-alert"
9
6
  >
10
7
  <slot v-bind="{ errors, showedGeneralErrors }">
@@ -75,7 +72,7 @@ import { computed, getCurrentInstance } from "vue"
75
72
  const instance = getCurrentInstance()
76
73
  const vuetified = instance?.appContext.components["VAlert"]
77
74
 
78
- const { errors, formSubmissionAttempts, generalErrors } = useOmegaErrors()
75
+ const { errors, generalErrors, showErrors } = useOmegaErrors()
79
76
 
80
77
  const { trans } = useIntl()
81
78
 
@@ -5,8 +5,9 @@ import {
5
5
  ref,
6
6
  readonly,
7
7
  type Ref,
8
+ computed,
8
9
  } from "vue"
9
- import type { OmegaError } from "./OmegaFormStuff"
10
+ import { type OmegaError, type ShowErrorsOn } from "./OmegaFormStuff"
10
11
  import type { StandardSchemaV1Issue } from "@tanstack/vue-form"
11
12
 
12
13
  export const OmegaErrorsKey = Symbol() as InjectionKey<{
@@ -14,7 +15,8 @@ export const OmegaErrorsKey = Symbol() as InjectionKey<{
14
15
  addError: (error: OmegaError) => void
15
16
  removeError: (inputId: string) => void
16
17
  clearErrors: () => void
17
- formSubmissionAttempts: Ref<number>
18
+ showErrors: Ref<boolean>
19
+ showErrorsOn: ShowErrorsOn
18
20
  generalErrors: Ref<
19
21
  (Record<string, StandardSchemaV1Issue[]> | undefined)[] | undefined
20
22
  >
@@ -25,6 +27,7 @@ export function provideOmegaErrors(
25
27
  generalErrors: Ref<
26
28
  (Record<string, StandardSchemaV1Issue[]> | undefined)[] | undefined
27
29
  >,
30
+ showErrorsOn: ShowErrorsOn = "onSubmit",
28
31
  ) {
29
32
  const errors = ref<OmegaError[]>([])
30
33
 
@@ -41,13 +44,23 @@ export function provideOmegaErrors(
41
44
  errors.value = []
42
45
  }
43
46
 
47
+ const showErrors = computed(() => {
48
+ switch (showErrorsOn) {
49
+ case "onChange":
50
+ return true
51
+ default:
52
+ return formSubmissionAttempts.value > 0
53
+ }
54
+ })
55
+
44
56
  const context = {
45
57
  errors: readonly(errors),
46
58
  addError,
47
59
  removeError,
48
60
  clearErrors,
49
- formSubmissionAttempts,
61
+ showErrors,
50
62
  generalErrors,
63
+ showErrorsOn: showErrorsOn ?? "onSubmit",
51
64
  }
52
65
 
53
66
  provide(OmegaErrorsKey, context)
@@ -16,6 +16,8 @@ import {
16
16
  import type { Component } from "vue"
17
17
  import { useIntl } from "../../utils"
18
18
 
19
+ export type ShowErrorsOn = "onChange" | "onBlur" | "onSubmit"
20
+
19
21
  export type TypeOverride =
20
22
  | "string"
21
23
  | "text"
@@ -1,11 +1,13 @@
1
1
  <template>
2
- <slot v-bind="inputProps" @focusout="setRealDirty">
3
- <OmegaInputVuetify
4
- v-if="vuetified"
5
- :input-props="inputProps"
6
- v-bind="$attrs"
7
- :vuetify-value="inputProps.field.state.value"
8
- />
2
+ <slot v-bind="inputProps">
3
+ <div @focusout="setRealDirty">
4
+ <OmegaInputVuetify
5
+ v-if="vuetified"
6
+ :input-props="inputProps"
7
+ v-bind="$attrs"
8
+ :vuetify-value="inputProps.field.state.value"
9
+ />
10
+ </div>
9
11
  </slot>
10
12
  </template>
11
13
 
@@ -90,17 +92,23 @@ onMounted(() => {
90
92
  fieldApi.setValue(null)
91
93
  }
92
94
  })
95
+ const { addError, removeError, showErrors, showErrorsOn } = useOmegaErrors()
93
96
 
94
97
  const realDirty = ref(false)
98
+
99
+ watchEffect(() => {
100
+ if (showErrors.value || showErrorsOn === "onChange") {
101
+ realDirty.value = true
102
+ }
103
+ })
104
+
95
105
  const setRealDirty = () => {
96
106
  realDirty.value = true
97
107
  }
98
108
 
99
- const { addError, formSubmissionAttempts, removeError } = useOmegaErrors()
100
-
101
- watchEffect(() => {
102
- if (formSubmissionAttempts.value > 0) {
103
- realDirty.value = true
109
+ onMounted(() => {
110
+ if (fieldValue.value) {
111
+ setRealDirty()
104
112
  }
105
113
  })
106
114