sit-onyx 0.0.0 → 0.1.0-alpha.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.
@@ -1,30 +1,64 @@
1
- declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
2
- /** The current input value */
3
- modelValue?: string | undefined;
1
+ export type TestInputProps = {
2
+ /**
3
+ * The current input value
4
+ * TODO: remove the "number" once we separated number inputs from the other types.
5
+ */
6
+ modelValue?: string | number;
4
7
  /** Label to show next to the input */
5
- label?: string | undefined;
6
- required?: boolean | undefined;
7
- }>, {
8
+ label?: string;
9
+ /**
10
+ * Error message to show when the input is invalid.
11
+ * If unset, a default error message is used that is provided by Onyx depending
12
+ * on your current locale/language and validation.
13
+ */
14
+ errorMessage?: string;
15
+ /** For validation: Whether a non-empty value is required */
16
+ required?: boolean;
17
+ /** For validation: The pattern that the value must match */
18
+ pattern?: string;
19
+ /** For validation: The expected type of the input's value */
20
+ type?: InputType;
21
+ /** For validation: The upper limit of a number value */
22
+ max?: number;
23
+ /**
24
+ * For validation: Expected maximal length of a string value. Warning: when the value is (pre)set by code,
25
+ * the input invalidity can not be detected by the browser, it will only show as invalid
26
+ * as soon as a user interacts with the input (types something).
27
+ */
28
+ maxLength?: number;
29
+ /** For validation: The lower limit of a number value */
30
+ min?: number;
31
+ /** Step size of a number value */
32
+ step?: number;
33
+ /**
34
+ * For validation: Expected minimal length of a string value. Warning: when the value is (pre)set by code,
35
+ * the input invalidity can not be detected by the browser, it will only show as invalid
36
+ * as soon as a user interacts with the input (types something).
37
+ */
38
+ minLength?: number;
39
+ };
40
+ export declare const INPUT_TYPES: readonly ["email", "number", "password", "search", "tel", "text", "url"];
41
+ export type InputType = (typeof INPUT_TYPES)[number];
42
+ declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<TestInputProps>, {
8
43
  modelValue: string;
9
44
  label: string;
45
+ type: string;
10
46
  }>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
11
- "update:modelValue": (value: string) => void;
47
+ "update:modelValue": (value: string | number) => void;
12
48
  change: (value: string) => void;
13
- }, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
14
- /** The current input value */
15
- modelValue?: string | undefined;
16
- /** Label to show next to the input */
17
- label?: string | undefined;
18
- required?: boolean | undefined;
19
- }>, {
49
+ validityChange: (state: ValidityState) => void;
50
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<TestInputProps>, {
20
51
  modelValue: string;
21
52
  label: string;
53
+ type: string;
22
54
  }>>> & {
23
- "onUpdate:modelValue"?: ((value: string) => any) | undefined;
55
+ "onUpdate:modelValue"?: ((value: string | number) => any) | undefined;
24
56
  onChange?: ((value: string) => any) | undefined;
57
+ onValidityChange?: ((state: ValidityState) => any) | undefined;
25
58
  }, {
26
- modelValue: string;
59
+ modelValue: string | number;
27
60
  label: string;
61
+ type: "number" | "search" | "email" | "tel" | "url" | "password" | "text";
28
62
  }, {}>;
29
63
  export default _default;
30
64
  type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
@@ -0,0 +1,45 @@
1
+ import type { ObjectToDottedStrings } from '../types/i18n';
2
+ import type { DeepPartial } from '../types/utils';
3
+ import { type MaybeRef } from "vue";
4
+ import enUS from "./locales/en-US.json";
5
+ /** Available translations that are used by Onyx components. */
6
+ export type OnyxTranslations = typeof enUS;
7
+ export type ProvideI18nOptions = {
8
+ /**
9
+ * Current locale / language to use.
10
+ * If a ref is passed (e.g. the locale from the `vue-i18n` package)
11
+ * all Onyx messages will be updated if it changes (if locale is supported).
12
+ * If a message is missing for your currently set locale, English will be used as fallback.
13
+ *
14
+ * @default "en-US"
15
+ */
16
+ locale?: MaybeRef<string>;
17
+ /**
18
+ * Available translations / messages. English is always supported. For build-in translations, see:
19
+ * https://onyx.schwarz/i18n/
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * import deDE from "sit-onyx/locales/de-DE.json";
24
+ * {
25
+ * messages: {
26
+ * // English is always supported so we don't need to add it here
27
+ * 'de-DE': deDE
28
+ * }
29
+ * }
30
+ * ```
31
+ */
32
+ messages?: Record<string, DeepPartial<OnyxTranslations>>;
33
+ };
34
+ /**
35
+ * Provides a global i18n instance that is used by Onyx.
36
+ * Must only be called once in the `App.vue` file of a project that consumes Onyx.
37
+ */
38
+ export declare const provideI18n: (options: ProvideI18nOptions) => void;
39
+ /**
40
+ * Injects the Onyx i18n instance.
41
+ */
42
+ export declare const injectI18n: () => {
43
+ locale: import("vue").ComputedRef<string>;
44
+ t: import("vue").ComputedRef<(key: ObjectToDottedStrings<OnyxTranslations>, placeholders?: Record<string, string | number | undefined>) => string>;
45
+ };
@@ -0,0 +1,22 @@
1
+ declare const _default: {
2
+ "validations": {
3
+ "tooShort": "Please lengthen this text to {minLength} characters or more (you are currently using 1 character) | Please lengthen this text to {minLength} characters or more (you are currently using {n} characters)",
4
+ "tooLong": "Please shorten this text to {maxLength} characters or less (you are currently using 1 character) | Please shorten this text to {maxLength} characters or less (you are currently using {n} characters)",
5
+ "rangeUnderflow": "Value must be greater than or equal to {min}",
6
+ "rangeOverflow": "Value must be less than or equal to {max}",
7
+ "patternMismatch": "Please match the format requested.",
8
+ "valueMissing": "Please fill in this field.",
9
+ "stepMismatch": "Please enter a value that is a multiple of {step}.",
10
+ "badInput": "\"{value}\" does not match the expected type.",
11
+ "typeMismatch": {
12
+ "generic": "\"{value}\" does not match the expected type.",
13
+ "email": "\"{value}\" must be a valid email address.",
14
+ "number": "\"{value}\" must be a number.",
15
+ "tel": "\"{value}\" must be a valid phone number.",
16
+ "url": "\"{value}\" must a valid URL."
17
+ }
18
+ }
19
+ }
20
+ ;
21
+
22
+ export default _default;
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),c=["required"],i=e.defineComponent({__name:"TestInput",props:{modelValue:{default:""},label:{default:""},required:{type:Boolean}},emits:["update:modelValue","change"],setup(n,{emit:r}){const t=n,a=r,l=e.computed({get:()=>t.modelValue,set:o=>a("update:modelValue",o)}),s=o=>{const u=o.target;a("change",u.value)};return(o,u)=>(e.openBlock(),e.createElementBlock("label",null,[e.createElementVNode("span",{class:e.normalizeClass(["input__label",{"input__label--required":t.required}])},e.toDisplayString(t.label),3),e.withDirectives(e.createElementVNode("input",{"onUpdate:modelValue":u[0]||(u[0]=d=>l.value=d),required:t.required,onChange:s},null,40,c),[[e.vModelText,l.value]]),e.createElementVNode("p",null,"Model value: "+e.toDisplayString(l.value),1)]))}}),p=(n,r)=>{const t=n.__vccOpts||n;for(const[a,l]of r)t[a]=l;return t},m=p(i,[["__scopeId","data-v-ec7909ed"]]);exports.TestInput=m;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("vue"),M={tooShort:"Please lengthen this text to {minLength} characters or more (you are currently using 1 character) | Please lengthen this text to {minLength} characters or more (you are currently using {n} characters)",tooLong:"Please shorten this text to {maxLength} characters or less (you are currently using 1 character) | Please shorten this text to {maxLength} characters or less (you are currently using {n} characters)",rangeUnderflow:"Value must be greater than or equal to {min}",rangeOverflow:"Value must be less than or equal to {max}",patternMismatch:"Please match the format requested.",valueMissing:"Please fill in this field.",stepMismatch:"Please enter a value that is a multiple of {step}.",badInput:'"{value}" does not match the expected type.',typeMismatch:{generic:'"{value}" does not match the expected type.',email:'"{value}" must be a valid email address.',number:'"{value}" must be a number.',tel:'"{value}" must be a valid phone number.',url:'"{value}" must a valid URL.'}},p={validations:M},y=Symbol(),_=a=>{const n=t.computed(()=>t.unref(a==null?void 0:a.locale)??"en-US"),e=t.computed(()=>a!=null&&a.messages&&n.value in a.messages?a.messages[n.value]:p),r=t.computed(()=>(l,u={})=>{let i=f(l,e.value)??f(l,p)??"";const o=typeof u.n=="number"?u.n:void 0;return i=P(i,o),E(i,u)});return{locale:n,t:r}},S=a=>{t.provide(y,_(a))},I=()=>{const a=_();return t.inject(y,a)},f=(a,n)=>{const e=a.split(".").reduce((r,l)=>!r||typeof r=="string"?r:r[l],n);return e&&typeof e=="string"?e:void 0},P=(a,n)=>{const e=a.split(" | ").map(l=>l.trim());if(e.length<=1)return a;let r=1;return n===0&&(r=0),n&&(n<=0||n>1)&&(r=2),e.length===2?r===1?e[0]:e[1]:e[r]},E=(a,n)=>n?Object.entries(n).reduce((r,[l,u])=>u===void 0?r:r.replace(new RegExp(`{${l}}`,"gi"),u.toString()),a).replace(/\s?{.*}\s?/gi,""):a,L=a=>{if(a.valueMissing)return"valueMissing";const n=Object.entries(Object.getOwnPropertyDescriptors(ValidityState.prototype)).filter(([e,r])=>e!=="valid"&&r.enumerable).map(([e])=>e);for(const e of n)if(e in a&&a[e])return e},T={key:0,class:"input__error","aria-live":"polite"},V={class:"input__info"},C=Object.keys(p.validations.typeMismatch),N=t.defineComponent({__name:"TestInput",props:{modelValue:{default:""},label:{default:""},errorMessage:{},required:{type:Boolean},pattern:{},type:{default:"text"},max:{},maxLength:{},min:{},step:{},minLength:{}},emits:["update:modelValue","change","validityChange"],setup(a,{emit:n}){var d;const e=a,r=n,{t:l}=I(),u=t.ref(!1),i=t.ref(null),o=t.ref((d=i.value)==null?void 0:d.validity),m=t.computed({get:()=>e.modelValue,set:s=>r("update:modelValue",s)}),b=t.computed(()=>{if(!o.value||o.value.valid)return"";const s=L(o.value);if(e.errorMessage||s==="customError")return e.errorMessage;if(!s)return"";if(s==="typeMismatch"){const c=C.includes(e.type)?e.type:"generic";return l.value(`validations.typeMismatch.${c}`,{value:m.value})}return l.value(`validations.${s}`,{value:m.value,n:m.value.toString().length,minLength:e.minLength,maxLength:e.maxLength,min:e.min,max:e.max,step:e.step})}),x=s=>{const c=s.target;r("change",c.value)};return t.watch([m,i],()=>{i.value&&(o.value=i.value.validity)}),t.watch(o,s=>{s&&r("validityChange",s)},{deep:!0}),(s,c)=>{var v,g;return t.openBlock(),t.createElementBlock("label",{class:t.normalizeClass(["input",{"input--touched":u.value}])},[t.createElementVNode("span",{class:t.normalizeClass(["input__label",{"input__label--required":e.required}])},t.toDisplayString(e.label),3),t.withDirectives(t.createElementVNode("input",t.mergeProps(e,{ref_key:"inputElement",ref:i,"onUpdate:modelValue":c[0]||(c[0]=h=>m.value=h),onChange:x,onBlur:c[1]||(c[1]=h=>u.value=!0)}),null,16),[[t.vModelDynamic,m.value]]),u.value&&!((v=o.value)!=null&&v.valid)?(t.openBlock(),t.createElementBlock("p",T,t.toDisplayString(b.value),1)):t.createCommentVNode("",!0),t.createElementVNode("p",V,'Model value: "'+t.toDisplayString(m.value)+'", is valid: '+t.toDisplayString((g=o.value)==null?void 0:g.valid),1)],2)}}}),O=(a,n)=>{const e=a.__vccOpts||a;for(const[r,l]of n)e[r]=l;return e},k=O(N,[["__scopeId","data-v-5c77ef30"]]);exports.TestInput=k;exports.provideI18n=S;
package/dist/index.d.ts CHANGED
@@ -1 +1,4 @@
1
1
  export { default as TestInput } from './components/TestInput/TestInput.vue';
2
+ export * from './types/i18n';
3
+ export * from './types/utils';
4
+ export { provideI18n, type OnyxTranslations, type ProvideI18nOptions } from './i18n';
package/dist/index.js CHANGED
@@ -1,40 +1,141 @@
1
- import { defineComponent as c, computed as i, openBlock as m, createElementBlock as _, createElementVNode as r, normalizeClass as v, toDisplayString as s, withDirectives as g, vModelText as f } from "vue";
2
- const h = ["required"], q = /* @__PURE__ */ c({
1
+ import { provide as E, inject as C, computed as m, unref as O, defineComponent as N, ref as p, watch as b, openBlock as x, createElementBlock as M, normalizeClass as I, createElementVNode as d, toDisplayString as v, withDirectives as k, mergeProps as q, vModelDynamic as U, createCommentVNode as w } from "vue";
2
+ const D = {
3
+ tooShort: "Please lengthen this text to {minLength} characters or more (you are currently using 1 character) | Please lengthen this text to {minLength} characters or more (you are currently using {n} characters)",
4
+ tooLong: "Please shorten this text to {maxLength} characters or less (you are currently using 1 character) | Please shorten this text to {maxLength} characters or less (you are currently using {n} characters)",
5
+ rangeUnderflow: "Value must be greater than or equal to {min}",
6
+ rangeOverflow: "Value must be less than or equal to {max}",
7
+ patternMismatch: "Please match the format requested.",
8
+ valueMissing: "Please fill in this field.",
9
+ stepMismatch: "Please enter a value that is a multiple of {step}.",
10
+ badInput: '"{value}" does not match the expected type.',
11
+ typeMismatch: {
12
+ generic: '"{value}" does not match the expected type.',
13
+ email: '"{value}" must be a valid email address.',
14
+ number: '"{value}" must be a number.',
15
+ tel: '"{value}" must be a valid phone number.',
16
+ url: '"{value}" must a valid URL.'
17
+ }
18
+ }, g = {
19
+ validations: D
20
+ }, P = Symbol(), S = (t) => {
21
+ const r = m(() => O(t == null ? void 0 : t.locale) ?? "en-US"), e = m(() => t != null && t.messages && r.value in t.messages ? t.messages[r.value] : g), a = m(() => (n, l = {}) => {
22
+ let u = L(n, e.value) ?? L(n, g) ?? "";
23
+ const i = typeof l.n == "number" ? l.n : void 0;
24
+ return u = B(u, i), $(u, l);
25
+ });
26
+ return { locale: r, t: a };
27
+ }, G = (t) => {
28
+ E(P, S(t));
29
+ }, z = () => {
30
+ const t = S();
31
+ return C(P, t);
32
+ }, L = (t, r) => {
33
+ const e = t.split(".").reduce((a, n) => !a || typeof a == "string" ? a : a[n], r);
34
+ return e && typeof e == "string" ? e : void 0;
35
+ }, B = (t, r) => {
36
+ const e = t.split(" | ").map((n) => n.trim());
37
+ if (e.length <= 1)
38
+ return t;
39
+ let a = 1;
40
+ return r === 0 && (a = 0), r && (r <= 0 || r > 1) && (a = 2), e.length === 2 ? a === 1 ? e[0] : e[1] : e[a];
41
+ }, $ = (t, r) => r ? Object.entries(r).reduce((a, [n, l]) => l === void 0 ? a : a.replace(new RegExp(`{${n}}`, "gi"), l.toString()), t).replace(/\s?{.*}\s?/gi, "") : t, j = (t) => {
42
+ if (t.valueMissing)
43
+ return "valueMissing";
44
+ const r = Object.entries(
45
+ Object.getOwnPropertyDescriptors(ValidityState.prototype)
46
+ ).filter(([e, a]) => e !== "valid" && a.enumerable).map(([e]) => e);
47
+ for (const e of r)
48
+ if (e in t && t[e])
49
+ return e;
50
+ }, R = {
51
+ key: 0,
52
+ class: "input__error",
53
+ "aria-live": "polite"
54
+ }, A = { class: "input__info" }, Y = Object.keys(
55
+ g.validations.typeMismatch
56
+ ), F = /* @__PURE__ */ N({
3
57
  __name: "TestInput",
4
58
  props: {
5
59
  modelValue: { default: "" },
6
60
  label: { default: "" },
7
- required: { type: Boolean }
61
+ errorMessage: {},
62
+ required: { type: Boolean },
63
+ pattern: {},
64
+ type: { default: "text" },
65
+ max: {},
66
+ maxLength: {},
67
+ min: {},
68
+ step: {},
69
+ minLength: {}
8
70
  },
9
- emits: ["update:modelValue", "change"],
10
- setup(l, { emit: u }) {
11
- const e = l, a = u, t = i({
71
+ emits: ["update:modelValue", "change", "validityChange"],
72
+ setup(t, { emit: r }) {
73
+ var h;
74
+ const e = t, a = r, { t: n } = z(), l = p(!1), u = p(null), i = p((h = u.value) == null ? void 0 : h.validity), c = m({
12
75
  get: () => e.modelValue,
13
- set: (n) => a("update:modelValue", n)
14
- }), d = (n) => {
15
- const o = n.target;
76
+ set: (s) => a("update:modelValue", s)
77
+ }), T = m(() => {
78
+ if (!i.value || i.value.valid)
79
+ return "";
80
+ const s = j(i.value);
81
+ if (e.errorMessage || s === "customError")
82
+ return e.errorMessage;
83
+ if (!s)
84
+ return "";
85
+ if (s === "typeMismatch") {
86
+ const o = Y.includes(e.type) ? e.type : "generic";
87
+ return n.value(`validations.typeMismatch.${o}`, { value: c.value });
88
+ }
89
+ return n.value(`validations.${s}`, {
90
+ value: c.value,
91
+ n: c.value.toString().length,
92
+ minLength: e.minLength,
93
+ maxLength: e.maxLength,
94
+ min: e.min,
95
+ max: e.max,
96
+ step: e.step
97
+ });
98
+ }), V = (s) => {
99
+ const o = s.target;
16
100
  a("change", o.value);
17
101
  };
18
- return (n, o) => (m(), _("label", null, [
19
- r("span", {
20
- class: v(["input__label", { "input__label--required": e.required }])
21
- }, s(e.label), 3),
22
- g(r("input", {
23
- "onUpdate:modelValue": o[0] || (o[0] = (p) => t.value = p),
24
- required: e.required,
25
- onChange: d
26
- }, null, 40, h), [
27
- [f, t.value]
28
- ]),
29
- r("p", null, "Model value: " + s(t.value), 1)
30
- ]));
102
+ return b([c, u], () => {
103
+ u.value && (i.value = u.value.validity);
104
+ }), b(
105
+ i,
106
+ (s) => {
107
+ s && a("validityChange", s);
108
+ },
109
+ { deep: !0 }
110
+ ), (s, o) => {
111
+ var f, y;
112
+ return x(), M("label", {
113
+ class: I(["input", { "input--touched": l.value }])
114
+ }, [
115
+ d("span", {
116
+ class: I(["input__label", { "input__label--required": e.required }])
117
+ }, v(e.label), 3),
118
+ k(d("input", q(e, {
119
+ ref_key: "inputElement",
120
+ ref: u,
121
+ "onUpdate:modelValue": o[0] || (o[0] = (_) => c.value = _),
122
+ onChange: V,
123
+ onBlur: o[1] || (o[1] = (_) => l.value = !0)
124
+ }), null, 16), [
125
+ [U, c.value]
126
+ ]),
127
+ l.value && !((f = i.value) != null && f.valid) ? (x(), M("p", R, v(T.value), 1)) : w("", !0),
128
+ d("p", A, 'Model value: "' + v(c.value) + '", is valid: ' + v((y = i.value) == null ? void 0 : y.valid), 1)
129
+ ], 2);
130
+ };
31
131
  }
32
- }), V = (l, u) => {
33
- const e = l.__vccOpts || l;
34
- for (const [a, t] of u)
35
- e[a] = t;
132
+ }), J = (t, r) => {
133
+ const e = t.__vccOpts || t;
134
+ for (const [a, n] of r)
135
+ e[a] = n;
36
136
  return e;
37
- }, x = /* @__PURE__ */ V(q, [["__scopeId", "data-v-ec7909ed"]]);
137
+ }, H = /* @__PURE__ */ J(F, [["__scopeId", "data-v-5c77ef30"]]);
38
138
  export {
39
- x as TestInput
139
+ H as TestInput,
140
+ G as provideI18n
40
141
  };
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .input__label[data-v-ec7909ed]{margin-right:8px}.input__label--required[data-v-ec7909ed]:after{content:"*";color:red}
1
+ .input[data-v-5c77ef30]{width:max-content;display:inline-block}.input__label[data-v-5c77ef30]{margin-right:8px}.input__label--required[data-v-5c77ef30]:after{content:"*";color:red}.input__error[data-v-5c77ef30]{color:#8b0000;margin:0}.input__info[data-v-5c77ef30]{color:gray}.input--touched input[data-v-5c77ef30]:valid{border-bottom-color:green}.input--touched input[data-v-5c77ef30]:invalid{border-bottom-color:red}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Gets a union type from an object that contains all combinations of nested keys as arrays.
3
+ *
4
+ * @see https://stackoverflow.com/a/47058976
5
+ * @example
6
+ * ```ts
7
+ * type Test = ObjectToKeyPaths<{ a: "foo"; b: { c: "bar"; d: "baz" } }>;
8
+ * // type Test = ["a"] | ["b", "c"] | ["b", "d"]
9
+ * ```
10
+ */
11
+ type ObjectToKeyPaths<T> = T extends string ? [] : {
12
+ [K in Extract<keyof T, string>]: [K, ...ObjectToKeyPaths<T[K]>];
13
+ }[Extract<keyof T, string>];
14
+ /**
15
+ * Joins the elements in the given type `T` with the separator `D`.
16
+ *
17
+ * @see https://stackoverflow.com/a/47058976
18
+ * @example
19
+ * ```ts
20
+ * type Test = Join<["foo", "bar"], ".">
21
+ * // type Test = "foo.bar"
22
+ * ```
23
+ */
24
+ type Join<T extends string[], D extends string> = T extends [] ? never : T extends [infer F] ? F : T extends [infer F, ...infer R] ? F extends string ? `${F}${D}${Join<Extract<R, string[]>, D>}` : never : string;
25
+ type NestedMessage = {
26
+ [key: string]: string | NestedMessage;
27
+ };
28
+ /**
29
+ * Translation value. Can either by a string or nested object with more translation values.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * // simple value
34
+ * { someKey: "Hello World" }
35
+ *
36
+ * // nested value
37
+ * {
38
+ * someKey: {
39
+ * someOtherKey: "Hello World"
40
+ * }
41
+ * }
42
+ * ```
43
+ */
44
+ export type TranslationValue = string | NestedMessage;
45
+ /**
46
+ * Gets a union type of deeply joined keys from an object.
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * ObjectToDottedStrings<{
51
+ * a: "test",
52
+ * b: { c: "test" }
53
+ * }>
54
+ * // results in: "a" | "b.c"
55
+ * ```
56
+ * @see https://stackoverflow.com/a/47058976
57
+ */
58
+ export type ObjectToDottedStrings<T extends TranslationValue> = Join<ObjectToKeyPaths<T>, ".">;
59
+ export {};
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Recursive / deep implementation of TypeScript's built-in `Partial<T>` type.
3
+ */
4
+ export type DeepPartial<T> = T extends object ? {
5
+ [P in keyof T]?: DeepPartial<T[P]>;
6
+ } : T;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Extracts the first invalid validity type from the given HTML ValidityState.
3
+ * "valueMissing" is prioritized over other types to align with the default browser behavior.
4
+ */
5
+ export declare const getFirstInvalidType: (validity: ValidityState) => "tooShort" | "tooLong" | "rangeUnderflow" | "rangeOverflow" | "patternMismatch" | "valueMissing" | "stepMismatch" | "badInput" | "typeMismatch" | "customError" | undefined;
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "sit-onyx",
3
3
  "description": "A design system and Vue.js component library created by Schwarz IT",
4
- "version": "0.0.0",
4
+ "version": "0.1.0-alpha.0",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
7
7
  "files": [
8
- "dist"
8
+ "dist",
9
+ "src/i18n/locales"
9
10
  ],
10
11
  "exports": {
11
12
  ".": {
@@ -13,6 +14,7 @@
13
14
  "import": "./dist/index.js",
14
15
  "require": "./dist/index.cjs"
15
16
  },
17
+ "./locales": "./src/i18n/locales",
16
18
  "./style.css": "./dist/style.css"
17
19
  },
18
20
  "repository": {
@@ -29,23 +31,23 @@
29
31
  "devDependencies": {
30
32
  "@playwright/experimental-ct-vue": "^1.40.1",
31
33
  "@playwright/test": "^1.40.1",
32
- "@storybook/addon-essentials": "^7.6.4",
33
- "@storybook/blocks": "^7.6.4",
34
- "@storybook/vue3": "^7.6.4",
35
- "@storybook/vue3-vite": "^7.6.4",
36
- "@vue/compiler-dom": "^3.3.11",
37
- "eslint-plugin-playwright": "~0.20.0",
34
+ "@storybook/addon-essentials": "^7.6.7",
35
+ "@storybook/blocks": "^7.6.7",
36
+ "@storybook/vue3": "^7.6.7",
37
+ "@storybook/vue3-vite": "^7.6.7",
38
+ "@vue/compiler-dom": "^3.4.5",
39
+ "eslint-plugin-playwright": "~0.21.0",
38
40
  "react": "^18.2.0",
39
- "storybook": "^7.6.4",
40
- "@sit-onyx/storybook-utils": "^0.0.0"
41
+ "storybook": "^7.6.7",
42
+ "@sit-onyx/storybook-utils": "^0.1.0-alpha.0"
41
43
  },
42
44
  "scripts": {
43
- "dev": "storybook dev -p 6006 --no-open",
44
- "build": "run-p type-check build-only",
45
+ "dev": "storybook dev -p 6006",
46
+ "build": "pnpm run '/type-check|build-only/'",
45
47
  "build:storybook": "storybook build",
46
- "preview": "vite serve storybook-static",
47
- "test:unit": "vitest",
48
- "test:unit:coverage": "pnpm run test:unit --coverage",
48
+ "preview": "vite serve storybook-static --open",
49
+ "test": "vitest",
50
+ "test:coverage": "vitest run --coverage",
49
51
  "test:components": "playwright install && playwright test",
50
52
  "build-only": "vite build",
51
53
  "type-check": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false"
@@ -0,0 +1,19 @@
1
+ {
2
+ "validations": {
3
+ "tooShort": "Verlängere diesen Text auf mindestens {minLength} Zeichen. Derzeit verwendest du {n} Zeichen.",
4
+ "tooLong": "Kürze diesen Text auf max. {maxLength} Zeichen. Zurzeit verwendest du {n} Zeichen.",
5
+ "rangeUnderflow": "Wert muss größer als oder gleich {min} sein.",
6
+ "rangeOverflow": "Wert muss kleiner als oder gleich {max} sein.",
7
+ "patternMismatch": "Deine Eingabe muss mit dem geforderten Format übereinstimmen.",
8
+ "valueMissing": "Fülle dieses Feld aus.",
9
+ "stepMismatch": "Wert muss ein Vielfaches von {step} sein.",
10
+ "badInput": "\"{value}\" entspricht nicht dem erwarten Typ.",
11
+ "typeMismatch": {
12
+ "generic": "\"{value}\" entspricht nicht dem erwarten Typ.",
13
+ "email": "\"{value}\" muss eine valide E-Mail-Adresse sein.",
14
+ "number": "\"{value}\" muss eine Zahl sein.",
15
+ "tel": "\"{value}\" muss eine gültige Telefonnummer sein.",
16
+ "url": "\"{value}\" muss eine gültige URL sein."
17
+ }
18
+ }
19
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "validations": {
3
+ "tooShort": "Please lengthen this text to {minLength} characters or more (you are currently using 1 character) | Please lengthen this text to {minLength} characters or more (you are currently using {n} characters)",
4
+ "tooLong": "Please shorten this text to {maxLength} characters or less (you are currently using 1 character) | Please shorten this text to {maxLength} characters or less (you are currently using {n} characters)",
5
+ "rangeUnderflow": "Value must be greater than or equal to {min}",
6
+ "rangeOverflow": "Value must be less than or equal to {max}",
7
+ "patternMismatch": "Please match the format requested.",
8
+ "valueMissing": "Please fill in this field.",
9
+ "stepMismatch": "Please enter a value that is a multiple of {step}.",
10
+ "badInput": "\"{value}\" does not match the expected type.",
11
+ "typeMismatch": {
12
+ "generic": "\"{value}\" does not match the expected type.",
13
+ "email": "\"{value}\" must be a valid email address.",
14
+ "number": "\"{value}\" must be a number.",
15
+ "tel": "\"{value}\" must be a valid phone number.",
16
+ "url": "\"{value}\" must a valid URL."
17
+ }
18
+ }
19
+ }