iryx-ui 0.24.1 → 0.25.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 (32) hide show
  1. package/dist/components/AvatarGroup.vue.d.ts +8 -2
  2. package/dist/components/AvatarGroup.vue_vue_type_script_setup_true_lang.js +57 -23
  3. package/dist/components/Breadcrumb.vue.d.ts +10 -2
  4. package/dist/components/Breadcrumb.vue_vue_type_script_setup_true_lang.js +66 -34
  5. package/dist/components/ConfirmPopover.vue.d.ts +1 -1
  6. package/dist/components/FileUpload.vue.d.ts +23 -1
  7. package/dist/components/FileUpload.vue_vue_type_script_setup_true_lang.js +139 -96
  8. package/dist/components/Input.vue.d.ts +14 -0
  9. package/dist/components/Input.vue_vue_type_script_setup_true_lang.js +86 -69
  10. package/dist/components/SignaturePad.vue.d.ts +1 -1
  11. package/dist/components/Textarea.vue.d.ts +14 -0
  12. package/dist/components/Textarea.vue_vue_type_script_setup_true_lang.js +90 -42
  13. package/dist/components/Toaster.vue_vue_type_script_setup_true_lang.js +42 -41
  14. package/dist/components/index.js +144 -144
  15. package/dist/composables/character-count.d.ts +6 -0
  16. package/dist/composables/character-count.js +18 -0
  17. package/dist/composables/toast.d.ts +16 -1
  18. package/dist/composables/toast.js +23 -2
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.js +154 -154
  21. package/dist/theme/avatar.d.ts +21 -0
  22. package/dist/theme/avatar.js +28 -21
  23. package/dist/theme/bar-chart.d.ts +3 -3
  24. package/dist/theme/donut-chart.d.ts +3 -3
  25. package/dist/theme/file-upload.d.ts +24 -0
  26. package/dist/theme/file-upload.js +6 -2
  27. package/dist/theme/input.d.ts +46 -0
  28. package/dist/theme/input.js +10 -2
  29. package/dist/theme/line-chart.d.ts +3 -3
  30. package/dist/theme/toast.d.ts +9 -0
  31. package/dist/theme/toast.js +2 -1
  32. package/package.json +1 -1
@@ -3,23 +3,28 @@ import t from "./Icon.js";
3
3
  import n from "./Button.js";
4
4
  import { useFormField as r } from "../composables/form.js";
5
5
  import { fileUploadTheme as i } from "../theme/file-upload.js";
6
- import { Fragment as a, computed as o, createCommentVNode as s, createElementBlock as c, createElementVNode as l, createTextVNode as ee, createVNode as u, defineComponent as d, mergeModels as f, normalizeClass as p, onBeforeUnmount as m, openBlock as h, ref as g, renderList as _, toDisplayString as v, unref as y, useModel as b, watch as x, withCtx as S, withModifiers as C } from "vue";
7
- import { Delete02Icon as w, File01Icon as T, Upload05Icon as E } from "@hugeicons/core-free-icons";
6
+ import a from "./Progress.js";
7
+ import { Fragment as o, computed as s, createBlock as c, createCommentVNode as l, createElementBlock as u, createElementVNode as d, createTextVNode as f, createVNode as p, defineComponent as m, mergeModels as h, normalizeClass as g, onBeforeUnmount as _, openBlock as v, ref as y, renderList as b, toDisplayString as x, toRaw as S, unref as C, useModel as w, watch as T, withCtx as E, withModifiers as D } from "vue";
8
+ import { Delete02Icon as O, File01Icon as k, Refresh01Icon as A, Upload05Icon as j } from "@hugeicons/core-free-icons";
8
9
  //#region src/components/FileUpload.vue?vue&type=script&setup=true&lang.ts
9
- var D = [
10
+ var ee = [
10
11
  "id",
11
12
  "multiple",
12
13
  "accept",
13
14
  "disabled",
14
15
  "aria-invalid",
15
16
  "aria-describedby"
16
- ], O = ["src"], k = [
17
+ ], te = ["src"], ne = [
17
18
  "aria-label",
18
19
  "disabled",
19
20
  "onClick"
20
- ], A = /*@__PURE__*/ d({
21
+ ], re = [
22
+ "aria-label",
23
+ "disabled",
24
+ "onClick"
25
+ ], M = /*@__PURE__*/ m({
21
26
  __name: "FileUpload",
22
- props: /*@__PURE__*/ f({
27
+ props: /*@__PURE__*/ h({
23
28
  multiple: { type: Boolean },
24
29
  accept: {},
25
30
  maxSize: {},
@@ -33,7 +38,11 @@ var D = [
33
38
  label: { default: "Drag and drop a file here" },
34
39
  hint: {},
35
40
  browseLabel: { default: "Browse files" },
41
+ statusFor: {},
36
42
  removeLabel: { default: "Remove" },
43
+ retryLabel: { default: "Retry" },
44
+ doneText: { default: "Uploaded" },
45
+ failedText: { default: "Upload failed" },
37
46
  tooLargeText: { default: "is too large" },
38
47
  wrongTypeText: { default: "is not an accepted type" },
39
48
  tooManyText: { default: "exceeds the file limit" },
@@ -52,34 +61,34 @@ var D = [
52
61
  modelValue: { default: () => [] },
53
62
  modelModifiers: {}
54
63
  }),
55
- emits: /*@__PURE__*/ f(["reject"], ["update:modelValue"]),
56
- setup(d, { emit: f }) {
57
- let A = d, j = f, M = b(d, "modelValue"), N = r(), P = o(() => A.id ?? N?.id.value);
58
- N && A.id && (N.id.value = A.id);
59
- let F = o(() => A.invalid ?? N?.invalid.value ?? !1), I = e(), L = o(() => A.unstyled ?? I.unstyled), R = g([]);
60
- function z(e) {
61
- if (!A.accept) return !0;
64
+ emits: /*@__PURE__*/ h(["reject", "retry"], ["update:modelValue"]),
65
+ setup(m, { emit: h }) {
66
+ let M = m, N = h, P = w(m, "modelValue"), F = r(), I = s(() => M.id ?? F?.id.value);
67
+ F && M.id && (F.id.value = M.id);
68
+ let L = s(() => M.invalid ?? F?.invalid.value ?? !1), R = e(), z = s(() => M.unstyled ?? R.unstyled), B = y([]);
69
+ function V(e) {
70
+ if (!M.accept) return !0;
62
71
  let t = e.name.toLowerCase(), n = e.type.toLowerCase();
63
- return A.accept.split(",").map((e) => e.trim().toLowerCase()).filter(Boolean).some((e) => e.startsWith(".") ? t.endsWith(e) : e.endsWith("/*") ? n.startsWith(e.slice(0, -1)) : n === e);
72
+ return M.accept.split(",").map((e) => e.trim().toLowerCase()).filter(Boolean).some((e) => e.startsWith(".") ? t.endsWith(e) : e.endsWith("/*") ? n.startsWith(e.slice(0, -1)) : n === e);
64
73
  }
65
- function B(e) {
66
- let t = [], n = [], r = A.multiple ? M.value : [];
74
+ function H(e) {
75
+ let t = [], n = [], r = M.multiple ? P.value : [];
67
76
  for (let i of e) {
68
- if (!z(i)) {
77
+ if (!V(i)) {
69
78
  n.push({
70
79
  file: i,
71
80
  reason: "type"
72
81
  });
73
82
  continue;
74
83
  }
75
- if (A.maxSize != null && i.size > A.maxSize) {
84
+ if (M.maxSize != null && i.size > M.maxSize) {
76
85
  n.push({
77
86
  file: i,
78
87
  reason: "size"
79
88
  });
80
89
  continue;
81
90
  }
82
- let e = A.multiple ? A.maxFiles : 1;
91
+ let e = M.multiple ? M.maxFiles : 1;
83
92
  if (e != null && r.length + t.length >= e) {
84
93
  n.push({
85
94
  file: i,
@@ -89,37 +98,40 @@ var D = [
89
98
  }
90
99
  t.push(i);
91
100
  }
92
- R.value = n, n.length && j("reject", n), t.length && (M.value = [...r, ...t]);
101
+ B.value = n, n.length && N("reject", n), t.length && (P.value = [...r, ...t]);
93
102
  }
94
- let V = g();
95
- function H(e) {
103
+ let U = y();
104
+ function W(e) {
96
105
  let t = e.target;
97
- B([...t.files ?? []]), t.value = "";
106
+ H([...t.files ?? []]), t.value = "";
98
107
  }
99
- function U(e) {
100
- M.value = M.value.filter((t, n) => n !== e);
108
+ function G(e) {
109
+ P.value = P.value.filter((t, n) => n !== e);
101
110
  }
102
- let W = g(0), G = o(() => W.value > 0);
103
- function K() {
104
- A.disabled || W.value++;
111
+ let K = y(0), q = s(() => K.value > 0);
112
+ function J() {
113
+ M.disabled || K.value++;
105
114
  }
106
- function q() {
107
- W.value > 0 && W.value--;
115
+ function Y() {
116
+ K.value > 0 && K.value--;
108
117
  }
109
- function J(e) {
110
- W.value = 0, !A.disabled && B([...e.dataTransfer?.files ?? []]);
118
+ function ie(e) {
119
+ K.value = 0, !M.disabled && H([...e.dataTransfer?.files ?? []]);
111
120
  }
112
- let Y = g(/* @__PURE__ */ new Map());
113
- x(M, (e) => {
114
- for (let [t, n] of Y.value) e.includes(t) || (URL.revokeObjectURL(n), Y.value.delete(t));
115
- for (let t of e) t.type.startsWith("image/") && !Y.value.has(t) && Y.value.set(t, URL.createObjectURL(t));
121
+ let X = y(/* @__PURE__ */ new Map());
122
+ T(P, (e) => {
123
+ for (let [t, n] of X.value) e.includes(t) || (URL.revokeObjectURL(n), X.value.delete(t));
124
+ for (let t of e) t.type.startsWith("image/") && !X.value.has(t) && X.value.set(t, URL.createObjectURL(t));
116
125
  }, {
117
126
  immediate: !0,
118
127
  deep: !0
119
- }), m(() => {
120
- for (let e of Y.value.values()) URL.revokeObjectURL(e);
128
+ }), _(() => {
129
+ for (let e of X.value.values()) URL.revokeObjectURL(e);
121
130
  });
122
- function X(e) {
131
+ function Z(e) {
132
+ return M.statusFor?.(S(e));
133
+ }
134
+ function ae(e) {
123
135
  let t = [
124
136
  "B",
125
137
  "kB",
@@ -129,88 +141,119 @@ var D = [
129
141
  for (; n >= 1024 && r < t.length - 1;) n /= 1024, r++;
130
142
  return `${r === 0 ? n : Math.round(n * 10) / 10} ${t[r]}`;
131
143
  }
132
- function Z(e) {
133
- let t = e.reason === "size" ? A.tooLargeText : e.reason === "type" ? A.wrongTypeText : A.tooManyText;
144
+ function oe(e) {
145
+ let t = e.reason === "size" ? M.tooLargeText : e.reason === "type" ? M.wrongTypeText : M.tooManyText;
134
146
  return `${e.file.name} ${t}`;
135
147
  }
136
- let Q = o(() => i({
137
- dragging: G.value,
138
- invalid: F.value,
139
- disabled: A.disabled
148
+ let Q = s(() => i({
149
+ dragging: q.value,
150
+ invalid: L.value,
151
+ disabled: M.disabled,
152
+ withStatus: !!M.statusFor
140
153
  }));
141
154
  function $(e, t) {
142
- let n = A.ui?.[e];
143
- return L.value ? [n, t] : Q.value[e]({ class: [n, t] });
155
+ let n = M.ui?.[e];
156
+ return z.value ? [n, t] : Q.value[e]({ class: [n, t] });
144
157
  }
145
- let te = o(() => L.value ? A.ui?.browse : Q.value.browse({ class: A.ui?.browse }));
146
- return (e, r) => (h(), c("div", { class: p($("root", A.class)) }, [
147
- l("label", {
148
- class: p($("dropzone")),
149
- onDragenter: C(K, ["prevent"]),
150
- onDragover: r[0] ||= C(() => {}, ["prevent"]),
151
- onDragleave: C(q, ["prevent"]),
152
- onDrop: C(J, ["prevent"])
158
+ let se = s(() => z.value ? M.ui?.browse : Q.value.browse({ class: M.ui?.browse }));
159
+ return (e, r) => (v(), u("div", { class: g($("root", M.class)) }, [
160
+ d("label", {
161
+ class: g($("dropzone")),
162
+ onDragenter: D(J, ["prevent"]),
163
+ onDragover: r[0] ||= D(() => {}, ["prevent"]),
164
+ onDragleave: D(Y, ["prevent"]),
165
+ onDrop: D(ie, ["prevent"])
153
166
  }, [
154
- l("input", {
155
- id: P.value,
167
+ d("input", {
168
+ id: I.value,
156
169
  ref_key: "inputEl",
157
- ref: V,
170
+ ref: U,
158
171
  type: "file",
159
- multiple: A.multiple,
160
- accept: A.accept,
161
- disabled: A.disabled,
162
- "aria-invalid": F.value || void 0,
163
- "aria-describedby": y(N)?.describedBy.value,
164
- class: p($("input")),
165
- onChange: H
166
- }, null, 42, D),
167
- l("span", { class: p($("icon")) }, [u(t, { icon: y(E) }, null, 8, ["icon"])], 2),
168
- l("span", { class: p($("label")) }, v(A.label), 3),
169
- A.hint ? (h(), c("span", {
172
+ multiple: M.multiple,
173
+ accept: M.accept,
174
+ disabled: M.disabled,
175
+ "aria-invalid": L.value || void 0,
176
+ "aria-describedby": C(F)?.describedBy.value,
177
+ class: g($("input")),
178
+ onChange: W
179
+ }, null, 42, ee),
180
+ d("span", { class: g($("icon")) }, [p(t, { icon: C(j) }, null, 8, ["icon"])], 2),
181
+ d("span", { class: g($("label")) }, x(M.label), 3),
182
+ M.hint ? (v(), u("span", {
170
183
  key: 0,
171
- class: p($("hint"))
172
- }, v(A.hint), 3)) : s("", !0),
173
- u(n, {
184
+ class: g($("hint"))
185
+ }, x(M.hint), 3)) : l("", !0),
186
+ p(n, {
174
187
  as: "span",
175
188
  variant: "outline",
176
189
  size: "sm",
177
- class: p(te.value)
190
+ class: g(se.value)
178
191
  }, {
179
- default: S(() => [ee(v(A.browseLabel), 1)]),
192
+ default: E(() => [f(x(M.browseLabel), 1)]),
180
193
  _: 1
181
194
  }, 8, ["class"])
182
195
  ], 34),
183
- (h(!0), c(a, null, _(R.value, (e) => (h(), c("p", {
196
+ (v(!0), u(o, null, b(B.value, (e) => (v(), u("p", {
184
197
  key: e.file.name,
185
- class: p($("error"))
186
- }, v(Z(e)), 3))), 128)),
187
- M.value.length ? (h(), c("ul", {
198
+ class: g($("error"))
199
+ }, x(oe(e)), 3))), 128)),
200
+ P.value.length ? (v(), u("ul", {
188
201
  key: 0,
189
- class: p($("list"))
190
- }, [(h(!0), c(a, null, _(M.value, (e, n) => (h(), c("li", {
202
+ class: g($("list"))
203
+ }, [(v(!0), u(o, null, b(P.value, (e, n) => (v(), u("li", {
191
204
  key: `${e.name}-${n}`,
192
- class: p($("item"))
205
+ class: g($("item"))
193
206
  }, [
194
- Y.value.get(e) ? (h(), c("img", {
207
+ X.value.get(e) ? (v(), u("img", {
195
208
  key: 0,
196
- src: Y.value.get(e),
209
+ src: X.value.get(e),
197
210
  alt: "",
198
- class: p($("thumbnail"))
199
- }, null, 10, O)) : (h(), c("span", {
211
+ class: g($("thumbnail"))
212
+ }, null, 10, te)) : (v(), u("span", {
200
213
  key: 1,
201
- class: p($("placeholder"))
202
- }, [u(t, { icon: y(T) }, null, 8, ["icon"])], 2)),
203
- l("span", { class: p($("details")) }, [l("span", { class: p($("name")) }, v(e.name), 3), l("span", { class: p($("meta")) }, v(X(e.size)), 3)], 2),
204
- l("button", {
214
+ class: g($("placeholder"))
215
+ }, [p(t, { icon: C(k) }, null, 8, ["icon"])], 2)),
216
+ d("span", { class: g($("details")) }, [
217
+ d("span", { class: g($("name")) }, x(e.name), 3),
218
+ Z(e)?.state === "error" ? (v(), u("span", {
219
+ key: 0,
220
+ role: "alert",
221
+ class: g($("error"))
222
+ }, x(Z(e).error ?? M.failedText), 3)) : (v(), u("span", {
223
+ key: 1,
224
+ class: g($("meta"))
225
+ }, [f(x(ae(e.size)), 1), Z(e)?.state === "uploading" && Z(e).progress != null ? (v(), u(o, { key: 0 }, [f(" · " + x(Math.round(Z(e).progress)) + "%", 1)], 64)) : Z(e)?.state === "done" ? (v(), u(o, { key: 1 }, [f(" · " + x(M.doneText), 1)], 64)) : l("", !0)], 2)),
226
+ Z(e)?.state === "uploading" ? (v(), c(a, {
227
+ key: 2,
228
+ "model-value": Z(e).progress ?? null,
229
+ size: "sm",
230
+ "aria-label": e.name,
231
+ unstyled: z.value,
232
+ class: g($("progress"))
233
+ }, null, 8, [
234
+ "model-value",
235
+ "aria-label",
236
+ "unstyled",
237
+ "class"
238
+ ])) : l("", !0)
239
+ ], 2),
240
+ d("span", { class: g($("actions")) }, [Z(e)?.state === "error" ? (v(), u("button", {
241
+ key: 0,
242
+ type: "button",
243
+ "aria-label": `${M.retryLabel} ${e.name}`,
244
+ disabled: M.disabled,
245
+ class: g($("retry")),
246
+ onClick: (t) => N("retry", S(e))
247
+ }, [p(t, { icon: C(A) }, null, 8, ["icon"])], 10, ne)) : l("", !0), d("button", {
205
248
  type: "button",
206
- "aria-label": `${A.removeLabel} ${e.name}`,
207
- disabled: A.disabled,
208
- class: p($("remove")),
209
- onClick: (e) => U(n)
210
- }, [u(t, { icon: y(w) }, null, 8, ["icon"])], 10, k)
211
- ], 2))), 128))], 2)) : s("", !0)
249
+ "aria-label": `${M.removeLabel} ${e.name}`,
250
+ disabled: M.disabled,
251
+ class: g($("remove")),
252
+ onClick: (e) => G(n)
253
+ }, [p(t, { icon: C(O) }, null, 8, ["icon"])], 10, re)], 2)
254
+ ], 2))), 128))], 2)) : l("", !0)
212
255
  ], 2));
213
256
  }
214
257
  });
215
258
  //#endregion
216
- export { A as default };
259
+ export { M as default };
@@ -20,6 +20,18 @@ export interface InputProps {
20
20
  debounce?: number;
21
21
  /** Accessible name for the clear button — override for non-English apps. */
22
22
  clearLabel?: string;
23
+ /** Hard limit in characters, enforced by the browser. */
24
+ maxlength?: number;
25
+ /**
26
+ * Show a character count in the trailing area — "12/50" with `maxlength`,
27
+ * turning red within the last tenth of the limit.
28
+ */
29
+ showCount?: boolean;
30
+ /**
31
+ * What a screen reader announces near the limit. Override for non-English
32
+ * apps.
33
+ */
34
+ countLabel?: (remaining: number) => string;
23
35
  /** Skip built-in classes; you take over styling entirely. */
24
36
  unstyled?: boolean;
25
37
  /** Applied to the outer field, which is the element carrying the chrome. */
@@ -31,6 +43,7 @@ export interface InputProps {
31
43
  leading?: string;
32
44
  trailing?: string;
33
45
  clear?: string;
46
+ count?: string;
34
47
  };
35
48
  }
36
49
  type __VLS_Props = InputProps;
@@ -57,6 +70,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
57
70
  invalid: boolean;
58
71
  clearLabel: string;
59
72
  debounce: number;
73
+ countLabel: (remaining: number) => string;
60
74
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
61
75
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
62
76
  declare const _default: typeof __VLS_export;
@@ -2,10 +2,11 @@ import { useIryxUiConfig as e } from "../config.js";
2
2
  import t from "./Icon.js";
3
3
  import { useFormField as n } from "../composables/form.js";
4
4
  import { inputTheme as r } from "../theme/input.js";
5
- import { computed as i, createBlock as a, createCommentVNode as o, createElementBlock as s, createElementVNode as c, createVNode as l, defineComponent as u, mergeModels as d, mergeProps as f, normalizeClass as p, onBeforeUnmount as m, openBlock as h, ref as g, renderSlot as _, unref as v, useModel as y, useSlots as b, watch as x, withKeys as S } from "vue";
6
- import { Cancel01Icon as C, Loading03Icon as w } from "@hugeicons/core-free-icons";
5
+ import { defaultCountLabel as i, useCharacterCount as a } from "../composables/character-count.js";
6
+ import { Fragment as o, computed as s, createBlock as c, createCommentVNode as l, createElementBlock as u, createElementVNode as d, createVNode as f, defineComponent as p, mergeModels as m, mergeProps as h, normalizeClass as g, onBeforeUnmount as _, openBlock as v, ref as y, renderSlot as b, toDisplayString as x, unref as S, useModel as C, useSlots as w, watch as T, withKeys as E } from "vue";
7
+ import { Cancel01Icon as D, Loading03Icon as O } from "@hugeicons/core-free-icons";
7
8
  //#region src/components/Input.vue?vue&type=script&setup=true&lang.ts
8
- var T = [
9
+ var k = [
9
10
  "id",
10
11
  "value",
11
12
  "type",
@@ -14,11 +15,15 @@ var T = [
14
15
  "disabled",
15
16
  "required",
16
17
  "aria-invalid",
17
- "aria-describedby"
18
- ], E = ["aria-label"], D = /*@__PURE__*/ u({
18
+ "aria-describedby",
19
+ "maxlength"
20
+ ], ee = {
21
+ class: "sr-only",
22
+ "aria-live": "polite"
23
+ }, A = ["aria-label"], j = /*@__PURE__*/ p({
19
24
  inheritAttrs: !1,
20
25
  __name: "Input",
21
- props: /*@__PURE__*/ d({
26
+ props: /*@__PURE__*/ m({
22
27
  type: { default: "text" },
23
28
  size: {},
24
29
  placeholder: {},
@@ -33,6 +38,12 @@ var T = [
33
38
  loading: { type: Boolean },
34
39
  debounce: { default: 0 },
35
40
  clearLabel: { default: "Clear" },
41
+ maxlength: {},
42
+ showCount: { type: Boolean },
43
+ countLabel: {
44
+ type: Function,
45
+ default: i
46
+ },
36
47
  unstyled: {
37
48
  type: Boolean,
38
49
  default: void 0
@@ -49,92 +60,98 @@ var T = [
49
60
  modelModifiers: {}
50
61
  }),
51
62
  emits: ["update:modelValue"],
52
- setup(u, { expose: d }) {
53
- let D = u, O = i(() => [
63
+ setup(i, { expose: p }) {
64
+ let m = i, j = s(() => [
54
65
  "email",
55
66
  "url",
56
67
  "tel",
57
68
  "password"
58
- ].includes(D.type) ? !1 : void 0), k = y(u, "modelValue"), A = b(), j = n(), M = i(() => D.id ?? j?.id.value);
59
- j && D.id && (j.id.value = D.id);
60
- let N = i(() => D.invalid ?? j?.invalid.value ?? !1), P = e(), F = i(() => D.unstyled ?? P.unstyled), I = g(k.value), L;
61
- function R() {
62
- L !== void 0 && (clearTimeout(L), L = void 0);
69
+ ].includes(m.type) ? !1 : void 0), M = C(i, "modelValue"), N = w(), P = n(), F = s(() => m.id ?? P?.id.value);
70
+ P && m.id && (P.id.value = m.id);
71
+ let I = s(() => m.invalid ?? P?.invalid.value ?? !1), L = e(), R = s(() => m.unstyled ?? L.unstyled), z = y(M.value), B;
72
+ function V() {
73
+ B !== void 0 && (clearTimeout(B), B = void 0);
63
74
  }
64
- x(k, (e) => {
65
- R(), I.value = e;
75
+ T(M, (e) => {
76
+ V(), z.value = e;
66
77
  });
67
- function z(e) {
78
+ function H(e) {
68
79
  let t = e.target.value;
69
- if (I.value = t, R(), !D.debounce) {
70
- k.value = t;
80
+ if (z.value = t, V(), !m.debounce) {
81
+ M.value = t;
71
82
  return;
72
83
  }
73
- L = setTimeout(() => {
74
- L = void 0, k.value = t;
75
- }, D.debounce);
84
+ B = setTimeout(() => {
85
+ B = void 0, M.value = t;
86
+ }, m.debounce);
76
87
  }
77
- function B() {
78
- L !== void 0 && (R(), k.value = I.value);
88
+ function U() {
89
+ B !== void 0 && (V(), M.value = z.value);
79
90
  }
80
- m(R);
81
- let V = g();
82
- function H() {
83
- R(), I.value = "", k.value = "", V.value?.focus();
91
+ _(V);
92
+ let W = y();
93
+ function G() {
94
+ V(), z.value = "", M.value = "", W.value?.focus();
84
95
  }
85
- d({ input: V });
86
- let U = i(() => I.value !== "" && I.value != null), W = i(() => D.clearable && U.value && !D.disabled), G = i(() => D.loading || W.value || !!A.trailing), K = i(() => r({
87
- size: D.size,
88
- invalid: N.value
96
+ p({ input: W });
97
+ let K = s(() => z.value !== "" && z.value != null), q = s(() => m.clearable && K.value && !m.disabled), J = s(() => m.loading || q.value || m.showCount || !!N.trailing), { remaining: Y, nearLimit: X, text: Z } = a(() => z.value, () => m.maxlength), Q = s(() => r({
98
+ size: m.size,
99
+ invalid: I.value,
100
+ nearLimit: X.value
89
101
  }));
90
- function q(e, t) {
91
- let n = D.ui?.[e];
92
- return F.value ? [n, t] : K.value[e]({ class: [n, t] });
102
+ function $(e, t) {
103
+ let n = m.ui?.[e];
104
+ return R.value ? [n, t] : Q.value[e]({ class: [n, t] });
93
105
  }
94
- return (e, n) => (h(), s("div", { class: p(q("root", D.class)) }, [
95
- v(A).leading ? (h(), s("span", {
106
+ return (e, n) => (v(), u("div", { class: g($("root", m.class)) }, [
107
+ S(N).leading ? (v(), u("span", {
96
108
  key: 0,
97
- class: p(q("leading"))
98
- }, [_(e.$slots, "leading")], 2)) : o("", !0),
99
- c("input", f({
100
- id: M.value,
109
+ class: g($("leading"))
110
+ }, [b(e.$slots, "leading")], 2)) : l("", !0),
111
+ d("input", h({
112
+ id: F.value,
101
113
  ref_key: "inputEl",
102
- ref: V,
103
- value: I.value,
104
- type: D.type,
105
- spellcheck: O.value,
106
- placeholder: D.placeholder,
107
- disabled: D.disabled,
108
- required: D.required,
109
- "aria-invalid": N.value || void 0,
110
- "aria-describedby": v(j)?.describedBy.value,
111
- class: q("input")
114
+ ref: W,
115
+ value: z.value,
116
+ type: m.type,
117
+ spellcheck: j.value,
118
+ placeholder: m.placeholder,
119
+ disabled: m.disabled,
120
+ required: m.required,
121
+ "aria-invalid": I.value || void 0,
122
+ "aria-describedby": S(P)?.describedBy.value,
123
+ maxlength: m.maxlength,
124
+ class: $("input")
112
125
  }, e.$attrs, {
113
- onInput: z,
114
- onBlur: B,
115
- onKeydown: S(B, ["enter"])
116
- }), null, 16, T),
117
- G.value ? (h(), s("span", {
126
+ onInput: H,
127
+ onBlur: U,
128
+ onKeydown: E(U, ["enter"])
129
+ }), null, 16, k),
130
+ J.value ? (v(), u("span", {
118
131
  key: 1,
119
- class: p(q("trailing"))
132
+ class: g($("trailing"))
120
133
  }, [
121
- _(e.$slots, "trailing"),
122
- W.value ? (h(), s("button", {
123
- key: 0,
134
+ b(e.$slots, "trailing"),
135
+ m.showCount ? (v(), u(o, { key: 0 }, [d("span", {
136
+ "aria-hidden": "true",
137
+ class: g($("count"))
138
+ }, x(S(Z)), 3), d("span", ee, x(S(X) ? m.countLabel(S(Y)) : ""), 1)], 64)) : l("", !0),
139
+ q.value ? (v(), u("button", {
140
+ key: 1,
124
141
  type: "button",
125
142
  tabindex: "-1",
126
- "aria-label": D.clearLabel,
127
- class: p(q("clear")),
128
- onClick: H
129
- }, [l(t, { icon: v(C) }, null, 8, ["icon"])], 10, E)) : o("", !0),
130
- D.loading ? (h(), a(t, {
131
- key: 1,
132
- icon: v(w),
143
+ "aria-label": m.clearLabel,
144
+ class: g($("clear")),
145
+ onClick: G
146
+ }, [f(t, { icon: S(D) }, null, 8, ["icon"])], 10, A)) : l("", !0),
147
+ m.loading ? (v(), c(t, {
148
+ key: 2,
149
+ icon: S(O),
133
150
  class: "animate-spin"
134
- }, null, 8, ["icon"])) : o("", !0)
135
- ], 2)) : o("", !0)
151
+ }, null, 8, ["icon"])) : l("", !0)
152
+ ], 2)) : l("", !0)
136
153
  ], 2));
137
154
  }
138
155
  });
139
156
  //#endregion
140
- export { D as default };
157
+ export { j as default };
@@ -50,9 +50,9 @@ declare const __VLS_export: import("vue").DefineComponent<SignaturePadProps, {
50
50
  }>, {
51
51
  unstyled: boolean;
52
52
  height: number;
53
+ ariaLabel: string;
53
54
  invalid: boolean;
54
55
  clearLabel: string;
55
- ariaLabel: string;
56
56
  penColor: string;
57
57
  penWidth: number;
58
58
  undoLabel: string;
@@ -19,9 +19,22 @@ export interface TextareaProps {
19
19
  required?: boolean;
20
20
  /** Mark the field as invalid — styles the border and ring red. */
21
21
  invalid?: boolean;
22
+ /** Hard limit in characters, enforced by the browser. */
23
+ maxlength?: number;
24
+ /**
25
+ * Show a character count under the field — "120/500" with `maxlength`,
26
+ * turning red within the last tenth of the limit.
27
+ */
28
+ showCount?: boolean;
29
+ /**
30
+ * What a screen reader announces near the limit. Override for non-English
31
+ * apps.
32
+ */
33
+ countLabel?: (remaining: number) => string;
22
34
  id?: string;
23
35
  /** Skip built-in classes; you take over styling entirely. */
24
36
  unstyled?: boolean;
37
+ /** Applied to the wrapper when `showCount` is on, otherwise to the textarea. */
25
38
  class?: ClassValue;
26
39
  }
27
40
  type __VLS_Props = TextareaProps;
@@ -39,6 +52,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
39
52
  }>, {
40
53
  unstyled: boolean;
41
54
  invalid: boolean;
55
+ countLabel: (remaining: number) => string;
42
56
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
43
57
  declare const _default: typeof __VLS_export;
44
58
  export default _default;