@effect-app/vue-components 2.1.6 → 2.2.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.
@@ -12,6 +12,7 @@ export type InputProps<From extends Record<PropertyKey, any>, TName extends Deep
12
12
  error: boolean;
13
13
  label: string;
14
14
  type: string;
15
+ inputClass: string | undefined | null;
15
16
  };
16
17
  field: OmegaFieldInternalApi<From, TName>;
17
18
  /** be sure to use this state and not `field.state` as it is not reactive */
@@ -6,12 +6,19 @@ import { type OF, type OmegaFormReturn } from "./useOmegaForm";
6
6
  export type Leaves<T, Path extends string = ""> = T extends ReadonlyArray<infer U> ? Leaves<U, `${Path}[number]`> & {} : {
7
7
  [K in keyof T]: T[K] extends string | boolean | number | null | undefined | symbol | bigint ? `${Path extends "" ? "" : `${Path}.`}${K & string}` : Leaves<T[K], `${Path extends "" ? "" : `${Path}.`}${K & string}`> & {};
8
8
  }[keyof T];
9
- export type FlexibleArrayPath<T extends string> = T extends `${infer Before}[number]${infer After}` ? T | `${Before}[${number}]${FlexibleArrayPath<After>}` : T;
9
+ export type FlexibleArrayPath<T extends string> = T extends `${string}[${string}]${string}` ? T : never;
10
10
  export type BaseProps<From, TName extends DeepKeys<From> = DeepKeys<From>> = {
11
11
  /** Will fallback to i18n when not specified */
12
12
  label?: string;
13
13
  validators?: FieldValidators<From>;
14
- name: TName;
14
+ name: FlexibleArrayPath<TName> extends never ? Leaves<From> : TName;
15
+ /**
16
+ * Optional class to apply to the input element.
17
+ * - If a string is provided, it will be used instead of the general class
18
+ * - If null is provided, no class will be applied (neither inputClass nor general class)
19
+ * - If undefined (not provided), the general class will be used
20
+ */
21
+ inputClass?: string | null;
15
22
  };
16
23
  export type TypesWithOptions = "radio" | "select" | "multiple" | "autocomplete" | "autocompletemultiple";
17
24
  export type DefaultTypeProps = {
@@ -17,6 +17,7 @@ declare const __VLS_export: <From extends Record<PropertyKey, any>, To extends R
17
17
  error: boolean;
18
18
  label: string;
19
19
  type: string;
20
+ inputClass: string | undefined | null;
20
21
  }) => any;
21
22
  };
22
23
  emit: {};
@@ -11,6 +11,7 @@ declare const __VLS_export: <From extends Record<PropertyKey, any>, Name extends
11
11
  type?: TypeOverride;
12
12
  validators?: FieldValidators<From>;
13
13
  required?: boolean;
14
+ inputClass?: string | null;
14
15
  register: (field: ComputedRef<{
15
16
  name: string;
16
17
  label: string;
@@ -37,6 +38,7 @@ declare const __VLS_export: <From extends Record<PropertyKey, any>, Name extends
37
38
  error: boolean;
38
39
  label: string;
39
40
  type: string;
41
+ inputClass: string | undefined | null;
40
42
  }) => any;
41
43
  };
42
44
  emit: {};
@@ -1,15 +1,16 @@
1
- import { defineComponent as F, computed as i, onMounted as M, provide as P, createBlock as c, openBlock as s, resolveDynamicComponent as p, withCtx as g, renderSlot as o, createElementBlock as k, normalizeProps as l, guardReactiveProps as u, Fragment as A, renderList as b, mergeProps as B } from "vue";
1
+ import { defineComponent as F, computed as f, onMounted as M, provide as P, createBlock as c, openBlock as s, resolveDynamicComponent as p, withCtx as g, renderSlot as o, createElementBlock as k, normalizeProps as l, guardReactiveProps as u, Fragment as A, renderList as C, mergeProps as b } from "vue";
2
2
  const N = /* @__PURE__ */ F({
3
3
  inheritAttrs: !1,
4
4
  __name: "OmegaArray",
5
5
  props: {
6
6
  form: {},
7
+ inputClass: {},
7
8
  name: {},
8
9
  defaultItems: {},
9
10
  items: {}
10
11
  },
11
12
  setup(n) {
12
- const a = n, y = a.form.useStore((e) => e.values), d = i(() => {
13
+ const a = n, y = a.form.useStore((e) => e.values), i = f(() => {
13
14
  const e = a.name.replace(/\[/g, ".").replace(/\]/g, "");
14
15
  try {
15
16
  return e.split(".").reduce((r, t) => r && r[t], y.value);
@@ -18,16 +19,16 @@ const N = /* @__PURE__ */ F({
18
19
  }
19
20
  });
20
21
  M(async () => {
21
- a.defaultItems && !d.value && a.form.setFieldValue(a.name, a.defaultItems);
22
+ a.defaultItems && !i.value && a.form.setFieldValue(a.name, a.defaultItems);
22
23
  });
23
- const $ = i(() => (r) => {
24
+ const $ = f(() => (r) => {
24
25
  const t = r.replace(/\[\d+\]/g, "");
25
26
  return a.form.meta[t];
26
27
  });
27
28
  return P("getMetaFromArray", $), (e, r) => (s(), c(p(n.form.Field), { name: n.name }, {
28
- default: g(({ field: t, state: f }) => [
29
- o(e.$slots, "pre-array", l(u({ field: t, state: f }))),
30
- (s(!0), k(A, null, b(d.value, (C, m) => (s(), c(p(n.form.Field), {
29
+ default: g(({ field: t, state: d }) => [
30
+ o(e.$slots, "pre-array", l(u({ field: t, state: d }))),
31
+ (s(!0), k(A, null, C(i.value, (B, m) => (s(), c(p(n.form.Field), {
31
32
  key: `${n.name}[${Number(m)}]`,
32
33
  name: (
33
34
  // eslint-disable-next-line
@@ -35,7 +36,7 @@ const N = /* @__PURE__ */ F({
35
36
  )
36
37
  }, {
37
38
  default: g(({ field: v, state: h }) => [
38
- o(e.$slots, "default", B({ ref_for: !0 }, {
39
+ o(e.$slots, "default", b({ ref_for: !0 }, {
39
40
  subField: v,
40
41
  subState: h,
41
42
  index: Number(m),
@@ -44,7 +45,7 @@ const N = /* @__PURE__ */ F({
44
45
  ]),
45
46
  _: 2
46
47
  }, 1032, ["name"]))), 128)),
47
- o(e.$slots, "post-array", l(u({ field: t, state: f }))),
48
+ o(e.$slots, "post-array", l(u({ field: t, state: d }))),
48
49
  o(e.$slots, "field", l(u({ field: t })))
49
50
  ]),
50
51
  _: 3
@@ -1,8 +1,8 @@
1
- (function(){"use strict";try{if(typeof document<"u"){var n=document.createElement("style");if(n.appendChild(document.createTextNode("fieldset[data-v-8a2f9d6f]{display:contents}fieldset[disabled][data-v-8a2f9d6f]>*{pointer-events:none}")),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-8a2f9d6f]{display:contents}fieldset[disabled][data-v-8a2f9d6f]>*{pointer-events:none}")),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-05e510ab]{display:contents}fieldset[disabled][data-v-05e510ab]>*{pointer-events:none}")),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-05e510ab]{display:contents}fieldset[disabled][data-v-05e510ab]>*{pointer-events:none}")),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.es36.js";
3
3
 
4
4
  import m from "./vue-components.es35.js";
5
- const f = /* @__PURE__ */ m(o, [["__scopeId", "data-v-8a2f9d6f"]]);
5
+ const e = /* @__PURE__ */ m(o, [["__scopeId", "data-v-05e510ab"]]);
6
6
  export {
7
- f as default
7
+ e as default
8
8
  };
@@ -1,50 +1,54 @@
1
- import { defineComponent as M, computed as l, inject as b, createBlock as f, openBlock as c, resolveDynamicComponent as C, withCtx as d, createCommentVNode as F, mergeProps as k, renderSlot as y, normalizeProps as A, guardReactiveProps as N } from "vue";
2
- import { useIntl as w } from "./vue-components.es3.js";
3
- import { generateInputStandardSchemaFromFieldMeta as I } from "./vue-components.es12.js";
4
- import P from "./vue-components.es7.js";
5
- const O = /* @__PURE__ */ M({
1
+ import { defineComponent as b, computed as s, useAttrs as F, inject as k, createBlock as c, openBlock as f, resolveDynamicComponent as y, withCtx as d, createCommentVNode as A, mergeProps as N, renderSlot as w, normalizeProps as I, guardReactiveProps as P } from "vue";
2
+ import { useIntl as S } from "./vue-components.es3.js";
3
+ import { generateInputStandardSchemaFromFieldMeta as j } from "./vue-components.es12.js";
4
+ import z from "./vue-components.es7.js";
5
+ const R = /* @__PURE__ */ b({
6
6
  inheritAttrs: !1,
7
7
  __name: "OmegaInput",
8
8
  props: {
9
9
  form: {},
10
10
  label: {},
11
11
  validators: {},
12
- name: {}
12
+ name: {},
13
+ inputClass: {}
13
14
  },
14
15
  setup(a) {
15
- const e = a, r = l(() => e.name), n = b(
16
+ const e = a, r = s(() => e.name), p = F(), v = s(() => {
17
+ if (e.inputClass !== null)
18
+ return e.inputClass !== void 0 ? e.inputClass : p.class;
19
+ }), l = k(
16
20
  "getMetaFromArray",
17
21
  null
18
- ), o = l(() => n?.value && n.value(e.name) ? n.value(r.value) : e.form.meta[r.value]), p = l(() => {
19
- if (!o.value)
22
+ ), n = s(() => l?.value && l.value(e.name) ? l.value(r.value) : e.form.meta[r.value]), g = s(() => {
23
+ if (!n.value)
20
24
  throw console.log(e.name, Object.keys(e.form.meta), e.form.meta), new Error("Meta is undefined");
21
- return I(o.value);
22
- }), { formatMessage: m } = w(), s = (t) => t.replace(/([A-Z])/g, " $1").replace(/^./, (u) => u.toUpperCase()).trim(), i = () => m ? m({ id: `general.fields.${r.value}`, defaultMessage: s(e.name) }) : s(e.name), v = () => e.form.i18nNamespace ? m({ id: `${e.form.i18nNamespace}.fields.${r.value}`, defaultMessage: i() }) : i();
23
- return (t, u) => (c(), f(C(a.form.Field), {
25
+ return j(n.value);
26
+ }), { formatMessage: o } = S(), m = (t) => t.replace(/([A-Z])/g, " $1").replace(/^./, (u) => u.toUpperCase()).trim(), i = () => o ? o({ id: `general.fields.${r.value}`, defaultMessage: m(e.name) }) : m(e.name), C = () => e.form.i18nNamespace ? o({ id: `${e.form.i18nNamespace}.fields.${r.value}`, defaultMessage: i() }) : i();
27
+ return (t, u) => (f(), c(y(a.form.Field), {
24
28
  name: a.name,
25
29
  validators: {
26
- onChange: p.value,
30
+ onChange: g.value,
27
31
  ...a.validators
28
32
  }
29
33
  }, {
30
- default: d(({ field: g, state: h }) => [
31
- o.value ? (c(), f(P, k({ key: 0 }, { ...t.$attrs, ...t.$props }, {
32
- field: g,
33
- state: h,
34
+ default: d(({ field: h, state: $ }) => [
35
+ n.value ? (f(), c(z, N({ key: 0 }, { ...t.$attrs, ...t.$props, inputClass: v.value }, {
36
+ field: h,
37
+ state: $,
34
38
  register: a.form.registerField,
35
- label: a.label ?? v(),
36
- meta: o.value
39
+ label: a.label ?? C(),
40
+ meta: n.value
37
41
  }), {
38
- default: d(($) => [
39
- y(t.$slots, "default", A(N($)))
42
+ default: d((M) => [
43
+ w(t.$slots, "default", I(P(M)))
40
44
  ]),
41
45
  _: 3
42
- }, 16, ["field", "state", "register", "label", "meta"])) : F("", !0)
46
+ }, 16, ["field", "state", "register", "label", "meta"])) : A("", !0)
43
47
  ]),
44
48
  _: 3
45
49
  }, 8, ["name", "validators"]));
46
50
  }
47
51
  });
48
52
  export {
49
- O as default
53
+ R as default
50
54
  };
@@ -1,9 +1,9 @@
1
1
  (function(){"use strict";try{if(typeof document<"u"){var i=document.createElement("style");if(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;appearance:none;box-shadow:none;display:block;min-width:auto;height:auto;padding:.5em .5em .5em 1em}")),document.head.appendChild(i),window.customElements){const e=window.customElements.define;window.customElements.define=function(s,t){const n=t.prototype.connectedCallback;return t.prototype.connectedCallback=function(){if(n&&n.call(this),this.shadowRoot){const a=document.createElement("style");a.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;appearance:none;box-shadow:none;display:block;min-width:auto;height:auto;padding:.5em .5em .5em 1em}")),this.shadowRoot.appendChild(a)}},e.call(window.customElements,s,t)}}}}catch(e){console.error("vite-plugin-css-injected-by-js",e)}})();
2
- import { defineComponent as b, computed as r, getCurrentInstance as C, useId as x, renderSlot as _, normalizeProps as m, guardReactiveProps as P, createElementVNode as N, normalizeClass as $, createBlock as q, createCommentVNode as B, unref as k, openBlock as I, mergeProps as L } from "vue";
3
- import { useStore as M } from "@tanstack/vue-form";
4
- import S from "./vue-components.es38.js";
2
+ import { defineComponent as _, computed as n, getCurrentInstance as x, useAttrs as P, useId as N, renderSlot as q, normalizeProps as i, guardReactiveProps as B, createElementVNode as $, normalizeClass as k, createBlock as I, createCommentVNode as L, unref as M, openBlock as S, mergeProps as w } from "vue";
3
+ import { useStore as A } from "@tanstack/vue-form";
4
+ import F from "./vue-components.es38.js";
5
5
 
6
- const U = /* @__PURE__ */ b({
6
+ const Z = /* @__PURE__ */ _({
7
7
  inheritAttrs: !1,
8
8
  __name: "OmegaInternalInput",
9
9
  props: {
@@ -14,54 +14,59 @@ const U = /* @__PURE__ */ b({
14
14
  type: { default: void 0 },
15
15
  validators: { default: void 0 },
16
16
  required: { type: Boolean, default: void 0 },
17
+ inputClass: { default: void 0 },
17
18
  register: {},
18
19
  options: { default: void 0 }
19
20
  },
20
21
  setup(u) {
21
- const e = u, o = r(() => e.required ?? e?.meta?.required), d = C()?.appContext.components.VTextField, l = x(), p = e.field, i = M(p.store, (t) => t), f = r(() => e.type ? e.type : e.meta?.type === "string" ? e.meta.format === "email" ? "email" : "string" : e.meta?.type || "unknown");
22
- e.register(r(() => ({ name: e.field.name, label: e.label, id: l }))), r(() => i.value.value);
23
- const c = r(() => i.value.meta.errors ?? []), s = r(
22
+ const e = u, s = n(() => e.required ?? e?.meta?.required), m = x()?.appContext.components.VTextField, d = P(), p = n(() => {
23
+ const { class: t, ...r } = d;
24
+ return r;
25
+ }), l = N(), f = e.field, c = A(f.store, (t) => t), g = n(() => e.type ? e.type : e.meta?.type === "string" ? e.meta.format === "email" ? "email" : "string" : e.meta?.type || "unknown");
26
+ e.register(n(() => ({ name: e.field.name, label: e.label, id: l })));
27
+ const h = n(() => c.value.meta.errors ?? []), o = n(
24
28
  () => (
25
29
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
- c.value.map((t) => t?.message).filter(Boolean)
30
+ h.value.map((t) => t?.message).filter(Boolean)
27
31
  )
28
- ), g = (t) => t == null || t === !1 || t === "" || Number.isNaN(t), v = (t) => {
29
- g(t) && e.meta?.type !== "boolean" && e.meta?.nullableOrUndefined ? e.field.handleChange(
32
+ ), v = (t) => t == null || t === !1 || t === "" || Number.isNaN(t), y = (t) => {
33
+ v(t) && e.meta?.type !== "boolean" && e.meta?.nullableOrUndefined ? e.field.handleChange(
30
34
  e.meta.nullableOrUndefined === "undefined" ? void 0 : null
31
- ) : e.field.handleChange(t), e.field.setMeta((n) => ({ ...n, errorMap: { ...n.errorMap, onSubmit: void 0 } }));
32
- }, h = (t) => {
33
- const n = {
34
- get(O, y, R) {
35
- return y === "handleChange" ? v : Reflect.get(...arguments);
35
+ ) : e.field.handleChange(t), e.field.setMeta((r) => ({ ...r, errorMap: { ...r.errorMap, onSubmit: void 0 } }));
36
+ }, C = (t) => {
37
+ const r = {
38
+ get(V, b, z) {
39
+ return b === "handleChange" ? y : Reflect.get(...arguments);
36
40
  }
37
41
  };
38
- return new Proxy(t, n);
39
- }, a = r(() => ({
42
+ return new Proxy(t, r);
43
+ }, a = n(() => ({
40
44
  inputProps: {
41
45
  id: l,
42
- required: o.value,
46
+ required: s.value,
43
47
  minLength: e.meta?.type === "string" && e.meta?.minLength,
44
48
  maxLength: e.meta?.type === "string" && e.meta?.maxLength,
45
49
  max: e.meta?.type === "number" && e.meta?.maximum,
46
50
  min: e.meta?.type === "number" && e.meta?.minimum,
47
- errorMessages: s.value,
48
- error: !!s.value.length,
49
- type: f.value,
50
- label: `${e.label}${o.value ? " *" : ""}`,
51
- options: e.options
51
+ errorMessages: o.value,
52
+ error: !!o.value.length,
53
+ type: g.value,
54
+ label: `${e.label}${s.value ? " *" : ""}`,
55
+ options: e.options,
56
+ inputClass: e.inputClass
52
57
  },
53
58
  state: e.state,
54
- field: h(e.field)
59
+ field: C(e.field)
55
60
  }));
56
- return (t, n) => _(t.$slots, "default", m(P({ ...a.value.inputProps, field: a.value.field, state: a.value.state })), () => [
57
- N("div", {
58
- class: $(t.$attrs.class)
61
+ return (t, r) => q(t.$slots, "default", i(B({ ...a.value.inputProps, field: a.value.field, state: a.value.state })), () => [
62
+ $("div", {
63
+ class: k(t.$attrs.class)
59
64
  }, [
60
- k(d) ? (I(), q(S, m(L({ key: 0 }, { ...t.$attrs, ...a.value })), null, 16)) : B("", !0)
65
+ M(m) ? (S(), I(F, i(w({ key: 0 }, { ...p.value, ...a.value, class: e.inputClass })), null, 16)) : L("", !0)
61
66
  ], 2)
62
67
  ]);
63
68
  }
64
69
  });
65
70
  export {
66
- U as default
71
+ Z as default
67
72
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect-app/vue-components",
3
- "version": "2.1.6",
3
+ "version": "2.2.0",
4
4
  "peerDependencies": {
5
5
  "@mdi/js": "^7.4.47",
6
6
  "effect": "^3.18.0",
@@ -39,6 +39,7 @@ export type InputProps<From extends Record<PropertyKey, any>, TName extends Deep
39
39
  error: boolean
40
40
  label: string
41
41
  type: string
42
+ inputClass: string | undefined | null
42
43
  }
43
44
  field: OmegaFieldInternalApi<From, TName>
44
45
  /** be sure to use this state and not `field.state` as it is not reactive */
@@ -15,16 +15,23 @@ export type Leaves<T, Path extends string = ""> = T extends ReadonlyArray<infer
15
15
  }[keyof T]
16
16
 
17
17
  // Helper type to make array indices flexible - accepts both [number] and numeric literals [0], [1], etc.
18
- export type FlexibleArrayPath<T extends string> = T extends `${infer Before}[number]${infer After}`
19
- ? T | `${Before}[${number}]${FlexibleArrayPath<After>}`
20
- : T
18
+ // Simplified: if there's a [] in the path, just use TName to avoid excessive type complexity
19
+ export type FlexibleArrayPath<T extends string> = T extends `${string}[${string}]${string}` ? T
20
+ : never
21
21
 
22
22
  export type BaseProps<From, TName extends DeepKeys<From> = DeepKeys<From>> = {
23
23
  /** Will fallback to i18n when not specified */
24
24
  label?: string
25
25
  validators?: FieldValidators<From>
26
- // disabled FlexibleArrayPath as it causes excessive complexity in type resolution inside user projects
27
- name: TName // & FlexibleArrayPath<Leaves<From>>
26
+ // Use FlexibleArrayPath: if name contains [], just use TName; otherwise intersect with Leaves<From>
27
+ name: FlexibleArrayPath<TName> extends never ? Leaves<From> : TName
28
+ /**
29
+ * Optional class to apply to the input element.
30
+ * - If a string is provided, it will be used instead of the general class
31
+ * - If null is provided, no class will be applied (neither inputClass nor general class)
32
+ * - If undefined (not provided), the general class will be used
33
+ */
34
+ inputClass?: string | null
28
35
  }
29
36
 
30
37
  export type TypesWithOptions = "radio" | "select" | "multiple" | "autocomplete" | "autocompletemultiple"
@@ -10,7 +10,7 @@
10
10
  <template #default="{ field, state }">
11
11
  <OmegaInternalInput
12
12
  v-if="meta"
13
- v-bind="{ ...$attrs, ...$props }"
13
+ v-bind="{ ...$attrs, ...$props, inputClass: computedClass }"
14
14
  :field="field"
15
15
  :state="state"
16
16
  :register="form.registerField"
@@ -35,7 +35,7 @@
35
35
  "
36
36
  >
37
37
  import { type DeepKeys } from "@tanstack/vue-form"
38
- import { computed, inject, type Ref } from "vue"
38
+ import { computed, inject, type Ref, useAttrs } from "vue"
39
39
  import { useIntl } from "../../utils"
40
40
  import { type FieldMeta, generateInputStandardSchemaFromFieldMeta, type OmegaInputPropsBase } from "./OmegaFormStuff"
41
41
  import OmegaInternalInput from "./OmegaInternalInput.vue"
@@ -49,6 +49,15 @@ defineOptions({
49
49
  inheritAttrs: false
50
50
  })
51
51
 
52
+ const attrs = useAttrs()
53
+
54
+ // Compute the class to use based on inputClass prop
55
+ const computedClass = computed(() => {
56
+ if (props.inputClass === null) return undefined
57
+ if (props.inputClass !== undefined) return props.inputClass
58
+ return attrs.class as string | undefined
59
+ })
60
+
52
61
  const getMetaFromArray = inject<Ref<(name: string) => FieldMeta | null> | null>(
53
62
  "getMetaFromArray",
54
63
  null
@@ -3,7 +3,7 @@
3
3
  <div :class="$attrs.class">
4
4
  <OmegaInputVuetify
5
5
  v-if="vuetified"
6
- v-bind="{ ...$attrs, ...inputProps }"
6
+ v-bind="{ ...attrsWithoutClass, ...inputProps, class: props.inputClass }"
7
7
  />
8
8
  </div>
9
9
  </slot>
@@ -15,7 +15,7 @@
15
15
  generic="From extends Record<PropertyKey, any>, Name extends DeepKeys<From>"
16
16
  >
17
17
  import { type DeepKeys, useStore } from "@tanstack/vue-form"
18
- import { computed, type ComputedRef, getCurrentInstance, useId } from "vue"
18
+ import { computed, type ComputedRef, getCurrentInstance, useAttrs, useId } from "vue"
19
19
  import type { InputProps, OmegaFieldInternalApi } from "./InputProps"
20
20
  import type { FieldValidators, MetaRecord, NestedKeyOf, TypeOverride } from "./OmegaFormStuff"
21
21
  import OmegaInputVuetify from "./OmegaInputVuetify.vue"
@@ -33,6 +33,7 @@ const props = withDefaults(
33
33
  type?: TypeOverride
34
34
  validators?: FieldValidators<From>
35
35
  required?: boolean
36
+ inputClass?: string | null
36
37
 
37
38
  register: (
38
39
  field: ComputedRef<{
@@ -49,7 +50,8 @@ const props = withDefaults(
49
50
  required: undefined,
50
51
  type: undefined,
51
52
  options: undefined,
52
- validators: undefined
53
+ validators: undefined,
54
+ inputClass: undefined
53
55
  }
54
56
  )
55
57
 
@@ -57,6 +59,13 @@ const isRequired = computed(() => props.required ?? props?.meta?.required)
57
59
 
58
60
  const instance = getCurrentInstance()
59
61
  const vuetified = instance?.appContext.components["VTextField"]
62
+ const attrs = useAttrs()
63
+
64
+ // Create attrs without the class property to avoid duplication
65
+ const attrsWithoutClass = computed(() => {
66
+ const { class: _, ...rest } = attrs
67
+ return rest
68
+ })
60
69
 
61
70
  const id = useId()
62
71
 
@@ -75,7 +84,6 @@ const fieldType = computed(() => {
75
84
 
76
85
  props.register(computed(() => ({ name: props.field.name, label: props.label, id })))
77
86
 
78
- const fieldValue = computed(() => fieldState.value.value)
79
87
  // workaround strange tanstack form issue where the errors key becomes undefined ???
80
88
  const _errors = computed(() => fieldState.value.meta.errors ?? [])
81
89
  const errors = computed(() =>
@@ -141,7 +149,8 @@ const inputProps: ComputedRef<InputProps<From, Name>> = computed(() => ({
141
149
  error: !!errors.value.length,
142
150
  type: fieldType.value,
143
151
  label: `${props.label}${isRequired.value ? " *" : ""}`,
144
- options: props.options
152
+ options: props.options,
153
+ inputClass: props.inputClass
145
154
  },
146
155
 
147
156
  state: props.state,
@@ -30,7 +30,6 @@
30
30
  */
31
31
  /* eslint-disable @typescript-eslint/no-explicit-any */
32
32
  import { useStore } from "@tanstack/vue-form"
33
- import { defineSlots } from "vue"
34
33
  import { usePreventClose } from "./blockDialog"
35
34
  import { getOmegaStore } from "./getOmegaStore"
36
35
  import { type DefaultTypeProps, type OmegaFormApi, type OmegaFormState } from "./OmegaFormStuff"