@thl-ui/vue 0.0.0-stage → 0.1.1

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.
@@ -0,0 +1,919 @@
1
+ import { defineComponent as p, computed as P, h as e, ref as T, watch as L, onMounted as K, onBeforeUnmount as W } from "vue";
2
+ import { bem as f, addMonths as j, weekdayNames as Y, monthGrid as H, toISODate as J, cx as M, createTable as Q, pageSizeOptions as X } from "@thl-ui/core";
3
+ import { barChart as Z, colorAt as ee, formatTick as I, lineChart as ae, pieChart as te, sparkline as le } from "@thl-ui/charts";
4
+ import { usePrefix as g, useI18n as S, useThlContext as oe, useDefaults as re, useStore as ne } from "../context.js";
5
+ import { icon as x, any as A, str as D } from "./util.js";
6
+ import { ThlCheckbox as F } from "./form.js";
7
+ import { ThlPagination as se } from "./nav.js";
8
+ import { ThlButton as B, ThlLabel as ie } from "./basic.js";
9
+ import { ThlProgress as ue } from "./overlay.js";
10
+ const fe = /* @__PURE__ */ p({
11
+ name: "ThlTable",
12
+ props: { striped: Boolean, hover: Boolean, bordered: A(), compact: Boolean, color: String, full: String },
13
+ setup(a, { slots: i }) {
14
+ const r = g();
15
+ return () => e(
16
+ "div",
17
+ { class: `${r.value}-table-wrap` },
18
+ e(
19
+ "table",
20
+ {
21
+ class: f(
22
+ "table",
23
+ r.value
24
+ )({
25
+ striped: a.striped,
26
+ hover: a.hover,
27
+ bordered: a.bordered === !0 || a.bordered === "",
28
+ compact: a.compact,
29
+ [`color-${a.color}`]: !!a.color,
30
+ [`full-${a.full}`]: !!a.full,
31
+ [`bordered-${a.bordered}`]: typeof a.bordered == "string" && a.bordered !== ""
32
+ })
33
+ },
34
+ i.default?.()
35
+ )
36
+ );
37
+ }
38
+ }), xe = /* @__PURE__ */ p({
39
+ name: "ThlDataTable",
40
+ props: {
41
+ data: { type: Array, required: !0 },
42
+ columns: { type: Array, required: !0 },
43
+ rowKey: A(),
44
+ pageSize: Number,
45
+ paginate: { type: Boolean, default: !0 },
46
+ searchable: { type: Boolean, default: !0 },
47
+ selectable: Boolean,
48
+ striped: { type: Boolean, default: void 0 },
49
+ hover: { type: Boolean, default: void 0 },
50
+ bordered: { type: Boolean, default: void 0 },
51
+ color: String,
52
+ stack: Boolean,
53
+ compact: Boolean,
54
+ emptyText: String,
55
+ manual: Boolean,
56
+ total: Number,
57
+ loading: Boolean
58
+ },
59
+ emits: ["selection-change", "cell-edit", "query-change"],
60
+ setup(a, { slots: i, emit: r }) {
61
+ const t = g(), { t: n } = S(), o = re("Table", a), l = Q({
62
+ data: a.data,
63
+ columns: a.columns,
64
+ rowKey: a.rowKey,
65
+ pageSize: o.value.pageSize ?? 10,
66
+ paginate: a.paginate,
67
+ manual: a.manual,
68
+ total: a.total
69
+ });
70
+ L(
71
+ () => a.data,
72
+ (c) => l.setData(c)
73
+ ), L(
74
+ () => a.columns,
75
+ (c) => l.setColumns(c)
76
+ );
77
+ const s = ne(l.state);
78
+ L(
79
+ () => s.value.selected,
80
+ () => r("selection-change", l.selectedRows())
81
+ ), L(
82
+ () => [s.value.page, s.value.pageSize, s.value.sort, s.value.search],
83
+ () => r("query-change", { page: s.value.page, pageSize: s.value.pageSize, sort: s.value.sort, search: s.value.search })
84
+ );
85
+ const v = T(null), d = () => {
86
+ if (!v.value) return;
87
+ const c = v.value, y = l.updateCell(c.row, c.key, c.value);
88
+ r("cell-edit", { rowKey: c.row, key: c.key, value: c.value, data: y }), v.value = null;
89
+ }, u = (c) => c.hideBelow && `${t.value}-col-hidden-${c.hideBelow >= 1170 ? "lg" : c.hideBelow >= 1024 ? "md" : "sm"}`;
90
+ return () => {
91
+ s.value;
92
+ const c = s.value, y = l.view(), m = f("table", t.value), C = l.allSelected(), b = a.manual ? a.total ?? a.data.length : y.total, $ = b === 0 ? 0 : (c.page - 1) * c.pageSize + 1, U = Math.min(b, c.page * c.pageSize), _ = a.columns.length + (a.selectable ? 1 : 0);
93
+ return e("div", { "aria-busy": a.loading || void 0 }, [
94
+ e("div", { class: `${t.value}-table-toolbar` }, [
95
+ a.paginate ? e("label", [
96
+ n("table.show", { n: "\0" }).split("\0")[0],
97
+ e(
98
+ "select",
99
+ {
100
+ class: `${t.value}-input ${t.value}-input--size-sm`,
101
+ value: c.pageSize,
102
+ "aria-label": n("pagination.pageSize", { size: c.pageSize }),
103
+ onChange: (h) => l.setPageSize(Number(h.target.value))
104
+ },
105
+ X(o.value.pageSizes, c.pageSize).map((h) => e("option", { value: h, selected: h === c.pageSize }, h))
106
+ ),
107
+ n("table.show", { n: "\0" }).split("\0")[1]
108
+ ]) : e("span"),
109
+ e("div", { class: `${t.value}-flex` }, [
110
+ i.toolbar?.(),
111
+ a.searchable ? e("label", [
112
+ n("table.search"),
113
+ e("input", {
114
+ type: "search",
115
+ class: `${t.value}-input ${t.value}-input--size-sm`,
116
+ value: c.search,
117
+ "aria-label": n("common.search"),
118
+ onInput: (h) => l.setSearch(h.target.value)
119
+ })
120
+ ]) : null
121
+ ])
122
+ ]),
123
+ e(
124
+ "div",
125
+ { class: `${t.value}-table-wrap` },
126
+ e(
127
+ "table",
128
+ {
129
+ class: m({
130
+ striped: o.value.striped,
131
+ hover: o.value.hover,
132
+ bordered: o.value.bordered,
133
+ compact: a.compact,
134
+ stack: a.stack,
135
+ [`color-${a.color}`]: !!a.color
136
+ })
137
+ },
138
+ [
139
+ e(
140
+ "thead",
141
+ e("tr", [
142
+ a.selectable ? e(
143
+ "th",
144
+ { class: m("check") },
145
+ e(F, {
146
+ modelValue: C === !0,
147
+ indeterminate: C === "indeterminate",
148
+ "aria-label": n("common.selectAll"),
149
+ onChange: () => l.toggleAll()
150
+ })
151
+ ) : null,
152
+ ...a.columns.map((h) => {
153
+ const k = l.sortDir(h.key);
154
+ return e(
155
+ "th",
156
+ {
157
+ key: h.key,
158
+ style: { width: typeof h.width == "number" ? `${h.width}px` : h.width, textAlign: h.align },
159
+ "aria-sort": k ? k === "asc" ? "ascending" : "descending" : void 0,
160
+ class: u(h)
161
+ },
162
+ h.sortable ? e("button", { type: "button", class: M(m("sort"), k && `is-${k}`), onClick: () => l.toggleSort(h.key) }, [
163
+ h.title ?? h.key,
164
+ e("span", { class: m("sort-icon"), "aria-hidden": "true" }, [e("span", "▲"), e("span", "▼")])
165
+ ]) : h.title ?? h.key
166
+ );
167
+ })
168
+ ])
169
+ ),
170
+ e(
171
+ "tbody",
172
+ y.rows.length === 0 ? [e("tr", { class: m("empty") }, e("td", { colspan: _ }, a.loading ? n("common.loading") : a.emptyText ?? n("table.empty")))] : y.rows.map(
173
+ ({ row: h, key: k }, V) => e("tr", { key: k, class: M({ "is-selected": l.isSelected(k) }) }, [
174
+ a.selectable ? e(
175
+ "td",
176
+ { class: m("check") },
177
+ e(F, {
178
+ modelValue: l.isSelected(k),
179
+ "aria-label": n("common.selectRow", { n: String(k) }),
180
+ onChange: () => l.toggleRow(k)
181
+ })
182
+ ) : null,
183
+ ...a.columns.map((w) => {
184
+ const q = l.value(w, h), G = v.value && v.value.row === k && v.value.key === w.key, E = i[`cell-${w.key}`] ? i[`cell-${w.key}`]({ row: h, value: q, index: V }) : String(q ?? "");
185
+ return e(
186
+ "td",
187
+ { key: w.key, "data-label": w.title ?? w.key, style: { textAlign: w.align }, class: u(w) },
188
+ G ? e("input", {
189
+ class: `${t.value}-input ${t.value}-input--size-sm ${m("edit-input")}`,
190
+ value: v.value.value,
191
+ onVnodeMounted: (z) => z.el.focus(),
192
+ onInput: (z) => v.value.value = z.target.value,
193
+ onBlur: d,
194
+ onKeydown: (z) => {
195
+ z.key === "Enter" && d(), z.key === "Escape" && (v.value = null);
196
+ }
197
+ }) : w.editable ? e(
198
+ "span",
199
+ {
200
+ role: "button",
201
+ tabindex: 0,
202
+ class: m("editable"),
203
+ onClick: () => v.value = { row: k, key: w.key, value: String(q ?? "") },
204
+ onKeydown: (z) => z.key === "Enter" && (v.value = { row: k, key: w.key, value: String(q ?? "") })
205
+ },
206
+ E
207
+ ) : E
208
+ );
209
+ })
210
+ ])
211
+ )
212
+ )
213
+ ]
214
+ )
215
+ ),
216
+ a.paginate ? e("div", { class: `${t.value}-table-footer` }, [
217
+ e("span", [n("pagination.showing", { from: $, to: U, total: b }), c.selected.size ? ` · ${n("table.selected", { count: c.selected.size })}` : ""]),
218
+ e(se, { page: c.page, total: b, pageSize: c.pageSize, size: "sm", "onUpdate:page": l.setPage })
219
+ ]) : null
220
+ ]);
221
+ };
222
+ }
223
+ }), ke = /* @__PURE__ */ p({
224
+ name: "ThlList",
225
+ props: {
226
+ items: {
227
+ type: Array,
228
+ required: !0
229
+ },
230
+ hover: Boolean
231
+ },
232
+ emits: ["item-click"],
233
+ setup(a, { emit: i, slots: r }) {
234
+ const t = g();
235
+ return () => {
236
+ const n = f("list", t.value);
237
+ return e(
238
+ "ul",
239
+ { class: n({ hover: a.hover }) },
240
+ a.items.map(
241
+ (o, l) => e(
242
+ "li",
243
+ {
244
+ key: o.key ?? l,
245
+ class: n("item"),
246
+ tabindex: a.hover ? 0 : void 0,
247
+ onClick: () => i("item-click", o),
248
+ onKeydown: (s) => s.key === "Enter" && i("item-click", o)
249
+ },
250
+ [
251
+ o.avatar ? e("span", { class: `${t.value}-avatar` }, e("img", { src: o.avatar, alt: "" })) : null,
252
+ o.icon ? e("span", { class: n("icon", { [o.iconColor ?? "primary"]: !0 }) }, x(o.icon)) : null,
253
+ e("div", { class: n("body") }, [e("p", { class: n("title") }, o.title), o.description ? e("p", { class: n("desc") }, o.description) : null]),
254
+ r.meta ? r.meta({ item: o }) : o.meta ? e("span", { class: n("meta") }, o.meta) : null
255
+ ]
256
+ )
257
+ )
258
+ );
259
+ };
260
+ }
261
+ }), we = /* @__PURE__ */ p({
262
+ name: "ThlGallery",
263
+ props: { images: { type: Array, required: !0 } },
264
+ setup(a) {
265
+ const i = g(), { t: r } = S(), t = T(null), n = (o) => {
266
+ const l = t.value;
267
+ if (l === null) return;
268
+ const s = a.images.length;
269
+ o.key === "Escape" && (t.value = null), o.key === "ArrowRight" && (t.value = (l + 1) % s), o.key === "ArrowLeft" && (t.value = (l - 1 + s) % s);
270
+ };
271
+ return K(() => document.addEventListener("keydown", n)), W(() => document.removeEventListener("keydown", n)), () => {
272
+ const o = f("gallery", i.value), l = f("lightbox", i.value), s = a.images.length;
273
+ return [
274
+ e(
275
+ "div",
276
+ { class: o() },
277
+ a.images.map(
278
+ (v, d) => e(
279
+ "button",
280
+ { key: d, type: "button", class: o("item"), onClick: () => t.value = d },
281
+ e("img", { src: v.thumb ?? v.src, alt: v.alt ?? "", loading: "lazy" })
282
+ )
283
+ )
284
+ ),
285
+ t.value !== null ? e("div", { class: l(), role: "dialog", "aria-modal": "true", onClick: (v) => v.target === v.currentTarget && (t.value = null) }, [
286
+ e("img", { src: a.images[t.value].src, alt: a.images[t.value].alt ?? "" }),
287
+ e("button", { type: "button", class: l("close"), onClick: () => t.value = null, "aria-label": r("common.close") }, "×"),
288
+ e(
289
+ "button",
290
+ { type: "button", class: l("nav", { prev: !0 }), onClick: () => t.value = (t.value - 1 + s) % s, "aria-label": r("common.previous") },
291
+ x("chevron-left")
292
+ ),
293
+ e(
294
+ "button",
295
+ { type: "button", class: l("nav", { next: !0 }), onClick: () => t.value = (t.value + 1) % s, "aria-label": r("common.next") },
296
+ x("chevron-right")
297
+ ),
298
+ a.images[t.value].caption ? e("div", { class: l("caption") }, a.images[t.value].caption) : null
299
+ ]) : null
300
+ ];
301
+ };
302
+ }
303
+ }), $e = /* @__PURE__ */ p({
304
+ name: "ThlInfoBox",
305
+ props: { icon: String, value: A(), title: String, color: D("primary"), filled: Boolean, soft: Boolean },
306
+ setup(a, { slots: i }) {
307
+ const r = g();
308
+ return () => {
309
+ const t = f("info-box", r.value);
310
+ return e("div", { class: t({ [a.color]: !0, filled: a.filled, soft: a.soft }) }, [
311
+ a.icon ? e("span", { class: t("icon") }, x(a.icon)) : null,
312
+ e("div", { class: t("body") }, [
313
+ e("div", { class: t("value") }, a.value),
314
+ e("p", { class: t("title") }, a.title),
315
+ i.footer ? [e("span", { class: t("line") }), e("div", { class: t("foot") }, i.footer())] : null
316
+ ])
317
+ ]);
318
+ };
319
+ }
320
+ }), Te = /* @__PURE__ */ p({
321
+ name: "ThlStatBox",
322
+ props: {
323
+ title: String,
324
+ value: A(),
325
+ icon: String,
326
+ color: D("primary"),
327
+ trend: String,
328
+ delta: String,
329
+ progress: Number
330
+ },
331
+ setup(a, { slots: i }) {
332
+ const r = g();
333
+ return () => {
334
+ const t = f("stat", r.value);
335
+ return e("div", { class: t({ [a.color]: !0 }) }, [
336
+ e("div", { class: t("head") }, [e("h2", { class: t("title") }, a.title), a.icon ? e("span", { class: t("icon") }, x(a.icon)) : null]),
337
+ e("div", { class: t("value") }, [
338
+ a.value,
339
+ a.delta ? e("span", { class: t("delta", { [a.trend ?? "up"]: !0 }) }, [x(a.trend === "down" ? "trending-down" : "trending-up"), " ", a.delta]) : null
340
+ ]),
341
+ a.progress !== void 0 ? e(ue, { value: a.progress, color: a.color, size: "sm" }) : null,
342
+ i.default?.()
343
+ ]);
344
+ };
345
+ }
346
+ }), Se = /* @__PURE__ */ p({
347
+ name: "ThlColorBox",
348
+ props: { color: D("primary"), icon: String, label: String, value: A() },
349
+ setup(a, { slots: i }) {
350
+ const r = g();
351
+ return () => {
352
+ const t = f("color-box", r.value);
353
+ return e("div", { class: t({ [a.color]: !0 }) }, [
354
+ a.label ? e("div", { class: t("label") }, a.label) : null,
355
+ a.value !== void 0 ? e("div", { class: t("value") }, a.value) : null,
356
+ i.default?.(),
357
+ a.icon ? e("span", { class: t("icon") }, x(a.icon)) : null
358
+ ]);
359
+ };
360
+ }
361
+ }), Ce = /* @__PURE__ */ p({
362
+ name: "ThlStatsRow",
363
+ props: { items: { type: Array, required: !0 } },
364
+ setup(a) {
365
+ const i = g();
366
+ return () => {
367
+ const r = f("stats-row", i.value);
368
+ return e(
369
+ "div",
370
+ { class: r() },
371
+ a.items.map((t, n) => e("div", { key: n, class: r("item") }, [e("div", { class: r("label") }, t.label), e("b", t.value)]))
372
+ );
373
+ };
374
+ }
375
+ }), ze = /* @__PURE__ */ p({
376
+ name: "ThlPricingTable",
377
+ props: { plans: { type: Array, required: !0 } },
378
+ emits: ["select"],
379
+ setup(a, { emit: i }) {
380
+ const r = g(), { t } = S();
381
+ return () => {
382
+ const n = f("pricing-plan", r.value);
383
+ return e(
384
+ "div",
385
+ { class: `${r.value}-pricing-wrap` },
386
+ e(
387
+ "div",
388
+ { class: `${r.value}-pricing`, style: { "--_n": a.plans.length } },
389
+ a.plans.map(
390
+ (o, l) => e("div", { key: l, class: n({ featured: o.featured }) }, [
391
+ o.tag ? e("div", { class: n("tag") }, o.tag) : null,
392
+ e("div", { class: n("header") }, [
393
+ e("h2", o.name),
394
+ e("div", { class: n("price") }, [e("sup", o.currency ?? "$"), o.price]),
395
+ e("p", { class: n("period") }, o.period ?? t("pages.pricing.perMonth"))
396
+ ]),
397
+ e(
398
+ "ul",
399
+ { class: n("features") },
400
+ o.features.map((s, v) => e("li", { key: v, class: n("feature") }, [x(s.icon), s.text]))
401
+ ),
402
+ e(
403
+ "div",
404
+ { class: n("action") },
405
+ e(
406
+ B,
407
+ {
408
+ variant: o.ctaVariant ?? (o.featured ? "danger" : "success"),
409
+ size: o.featured ? "lg" : void 0,
410
+ onClick: () => i("select", o, l)
411
+ },
412
+ () => o.cta ?? t("pages.pricing.signUp")
413
+ )
414
+ )
415
+ ])
416
+ )
417
+ )
418
+ );
419
+ };
420
+ }
421
+ }), Be = /* @__PURE__ */ p({
422
+ name: "ThlUserCard",
423
+ props: { image: { type: String, required: !0 }, name: String, subtitle: String },
424
+ setup(a, { slots: i }) {
425
+ const r = g();
426
+ return () => {
427
+ const t = f("user-card", r.value);
428
+ return e("div", { class: t() }, [
429
+ e("div", { class: t("media"), tabindex: i.actions ? 0 : void 0 }, [
430
+ e("img", { src: a.image, alt: "" }),
431
+ i.actions ? e("div", { class: t("overlay") }, i.actions()) : null
432
+ ]),
433
+ e("div", { class: t("content") }, [e("h2", a.name), a.subtitle ? e("small", a.subtitle) : null])
434
+ ]);
435
+ };
436
+ }
437
+ }), De = /* @__PURE__ */ p({
438
+ name: "ThlProfileCard",
439
+ props: { cover: String, avatar: String, name: String, email: String, stats: Array },
440
+ setup(a, { slots: i }) {
441
+ const r = g();
442
+ return () => {
443
+ const t = f("profile-card", r.value);
444
+ return e("div", { class: t() }, [
445
+ e("div", { class: t("cover") }, [
446
+ a.cover ? e("img", { src: a.cover, alt: "" }) : null,
447
+ e("div", { class: t("overlay") }, [
448
+ a.avatar ? e("img", {
449
+ src: a.avatar,
450
+ alt: "",
451
+ style: { width: "80px", height: "80px", borderRadius: "50%", border: "3px solid #fff", objectFit: "cover" }
452
+ }) : null,
453
+ e("h2", a.name),
454
+ a.email ? e("div", a.email) : null
455
+ ])
456
+ ]),
457
+ a.stats ? e(
458
+ "div",
459
+ { class: t("stats") },
460
+ a.stats.map((n, o) => e("div", { key: o }, [e("b", n.value), e("small", n.label)]))
461
+ ) : null,
462
+ i.default ? e("div", { class: t("body") }, i.default()) : null
463
+ ]);
464
+ };
465
+ }
466
+ }), Ae = /* @__PURE__ */ p({
467
+ name: "ThlChat",
468
+ props: {
469
+ messages: {
470
+ type: Array,
471
+ required: !0
472
+ },
473
+ composer: Boolean
474
+ },
475
+ emits: ["send"],
476
+ setup(a, { emit: i }) {
477
+ const r = g(), { t } = S(), n = T("");
478
+ return () => {
479
+ const o = f("chat", r.value);
480
+ return e("div", [
481
+ e(
482
+ "ul",
483
+ { class: o(), "aria-live": "polite" },
484
+ a.messages.map(
485
+ (l) => e("li", { key: l.id, class: o("msg", { me: l.me }) }, [
486
+ l.avatar ? e("img", { src: l.avatar, alt: "", style: { width: "36px", height: "36px", borderRadius: "50%", objectFit: "cover" } }) : null,
487
+ e("div", [
488
+ l.me ? null : e("div", { class: o("name") }, l.from),
489
+ e("div", { class: o("bubble") }, l.text),
490
+ l.time ? e("div", { class: o("time") }, l.time) : null
491
+ ])
492
+ ])
493
+ )
494
+ ),
495
+ a.composer ? e(
496
+ "form",
497
+ {
498
+ class: o("composer"),
499
+ onSubmit: (l) => {
500
+ l.preventDefault(), n.value.trim() && (i("send", n.value.trim()), n.value = "");
501
+ }
502
+ },
503
+ [
504
+ e("input", {
505
+ class: `${r.value}-input`,
506
+ value: n.value,
507
+ onInput: (l) => n.value = l.target.value,
508
+ placeholder: `${t("layout.messages")}...`,
509
+ "aria-label": t("layout.messages")
510
+ }),
511
+ e(B, { type: "submit", variant: "primary", circle: !0, "aria-label": t("pages.inbox.send") }, () => x("send"))
512
+ ]
513
+ ) : null
514
+ ]);
515
+ };
516
+ }
517
+ }), qe = /* @__PURE__ */ p({
518
+ name: "ThlTodoList",
519
+ props: {
520
+ items: { type: Array, required: !0 },
521
+ addable: Boolean
522
+ },
523
+ emits: ["toggle", "remove", "add"],
524
+ setup(a, { emit: i }) {
525
+ const r = g(), { t } = S(), n = T("");
526
+ return () => {
527
+ const o = f("todo", r.value);
528
+ return e("div", [
529
+ e(
530
+ "ul",
531
+ { class: o() },
532
+ a.items.map(
533
+ (l) => e("li", { key: l.id, class: M(o("item"), { "is-done": l.done }) }, [
534
+ e("label", { class: `${r.value}-check`, style: { margin: 0 } }, [
535
+ e("input", {
536
+ type: "checkbox",
537
+ class: `${r.value}-check__input`,
538
+ checked: !!l.done,
539
+ "aria-label": `${t("common.toggleDone")}: ${l.text}`,
540
+ onChange: () => i("toggle", l.id)
541
+ }),
542
+ e("span", { class: `${r.value}-check__box` })
543
+ ]),
544
+ e("span", { class: o("text") }, l.text),
545
+ l.badge ? e(ie, { color: l.badge.color ?? "info", rounded: !0 }, () => l.badge.text) : null,
546
+ e("button", { type: "button", class: o("remove"), onClick: () => i("remove", l.id), "aria-label": t("common.delete") }, x("trash-2"))
547
+ ])
548
+ )
549
+ ),
550
+ a.addable ? e(
551
+ "form",
552
+ {
553
+ class: `${r.value}-flex ${r.value}-mt-3`,
554
+ style: { flexWrap: "nowrap" },
555
+ onSubmit: (l) => {
556
+ l.preventDefault(), n.value.trim() && (i("add", n.value.trim()), n.value = "");
557
+ }
558
+ },
559
+ [
560
+ e("input", {
561
+ class: `${r.value}-input`,
562
+ value: n.value,
563
+ onInput: (l) => n.value = l.target.value,
564
+ placeholder: `${t("common.add")}...`,
565
+ "aria-label": t("common.add")
566
+ }),
567
+ e(B, { type: "submit", variant: "success" }, () => t("common.add"))
568
+ ]
569
+ ) : null
570
+ ]);
571
+ };
572
+ }
573
+ }), Le = /* @__PURE__ */ p({
574
+ name: "ThlWeather",
575
+ props: {
576
+ city: String,
577
+ temp: Number,
578
+ condition: String,
579
+ icon: D("cloud-sun"),
580
+ days: Array
581
+ },
582
+ setup(a) {
583
+ const i = g();
584
+ return () => {
585
+ const r = f("weather", i.value);
586
+ return e("div", { class: r() }, [
587
+ e("div", { class: `${i.value}-flex-between` }, [
588
+ e("div", [
589
+ e("div", { class: r("temp") }, [a.temp, e("sup", "°")]),
590
+ e("div", a.condition),
591
+ e("small", { style: { opacity: 0.85 } }, [x("map-pin"), " ", a.city])
592
+ ]),
593
+ e("span", { class: r("icon") }, x(a.icon, { strokeWidth: 1.5 }))
594
+ ]),
595
+ a.days ? e(
596
+ "div",
597
+ { class: r("days") },
598
+ a.days.map((t, n) => e("div", { key: n }, [e("div", t.day), x(t.icon), e("b", `${t.temp}°`)]))
599
+ ) : null
600
+ ]);
601
+ };
602
+ }
603
+ });
604
+ function O() {
605
+ const a = T(), i = T(600);
606
+ let r = null;
607
+ return K(() => {
608
+ a.value && typeof ResizeObserver < "u" && (r = new ResizeObserver(([t]) => i.value = Math.max(200, Math.round(t.contentRect.width))), r.observe(a.value));
609
+ }), W(() => r?.disconnect()), { el: a, w: i };
610
+ }
611
+ const R = (a, i) => e(
612
+ "ul",
613
+ { class: `${a}-chart-legend` },
614
+ i.map((r, t) => e("li", { key: t }, [e("i", { style: { background: r.color } }), r.name]))
615
+ ), N = (a, i, r, t = "middle") => e("text", { x: a, y: i, "text-anchor": t, "font-size": 11, fill: "var(--thl-text)" }, r), Me = /* @__PURE__ */ p({
616
+ name: "ThlLineChart",
617
+ props: {
618
+ series: { type: Array, required: !0 },
619
+ labels: { type: Array, required: !0 },
620
+ height: { type: Number, default: 280 },
621
+ area: Boolean,
622
+ smooth: { type: Boolean, default: !0 },
623
+ legend: { type: Boolean, default: !0 }
624
+ },
625
+ setup(a) {
626
+ const i = g(), { intlLocale: r } = S(), { el: t, w: n } = O(), o = T(null), l = P(() => ae(a.series, a.labels, { width: n.value, height: a.height }, { smooth: a.smooth }));
627
+ return () => {
628
+ const s = l.value, v = r(), d = Math.max(1, a.labels.length - 1);
629
+ return e("div", { ref: t, class: `${i.value}-chart` }, [
630
+ a.legend ? R(
631
+ i.value,
632
+ s.series.map((u) => ({ name: u.name, color: u.color }))
633
+ ) : null,
634
+ e(
635
+ "svg",
636
+ { width: n.value, height: a.height, role: "img", "aria-label": a.series.map((u) => u.name).join(", "), onMouseleave: () => o.value = null },
637
+ [
638
+ ...s.yTicks.map(
639
+ (u) => e("g", { key: u.value }, [
640
+ e("line", { x1: s.plot.x, x2: s.plot.x + s.plot.width, y1: u.y, y2: u.y, stroke: "var(--thl-border-color)" }),
641
+ N(s.plot.x - 8, u.y + 4, I(u.value, v), "end")
642
+ ])
643
+ ),
644
+ ...s.xLabels.map((u, c) => e("g", { key: `x${c}` }, N(u.x, a.height - 8, u.label))),
645
+ ...s.series.map(
646
+ (u, c) => e("g", { key: c }, [
647
+ a.area ? e("path", { d: u.area, fill: u.color, opacity: 0.15 }) : null,
648
+ e("path", { d: u.line, fill: "none", stroke: u.color, "stroke-width": 2.5, "stroke-linejoin": "round", "stroke-linecap": "round" }),
649
+ ...u.points.map(
650
+ (y, m) => e("circle", { key: m, cx: y.x, cy: y.y, r: o.value === m ? 5 : 3, fill: "var(--thl-surface)", stroke: u.color, "stroke-width": 2 })
651
+ )
652
+ ])
653
+ ),
654
+ ...s.xLabels.map(
655
+ (u, c) => e("rect", {
656
+ key: `h${c}`,
657
+ x: u.x - s.plot.width / d / 2,
658
+ y: s.plot.y,
659
+ width: s.plot.width / d,
660
+ height: s.plot.height,
661
+ fill: "transparent",
662
+ onMouseenter: () => o.value = c
663
+ })
664
+ )
665
+ ]
666
+ ),
667
+ o.value !== null ? e(
668
+ "div",
669
+ {
670
+ class: `${i.value}-chart-tooltip`,
671
+ style: {
672
+ left: `${s.xLabels[o.value].x}px`,
673
+ top: `${Math.min(...s.series.map((u) => u.points[o.value]?.y ?? a.height)) + (a.legend ? 30 : 0)}px`
674
+ }
675
+ },
676
+ [
677
+ e("b", a.labels[o.value]),
678
+ ...s.series.map((u) => e("div", { key: u.name }, `${u.name}: ${I(u.points[o.value]?.value ?? 0, v)}`))
679
+ ]
680
+ ) : null
681
+ ]);
682
+ };
683
+ }
684
+ }), Ne = /* @__PURE__ */ p({
685
+ name: "ThlBarChart",
686
+ props: {
687
+ series: { type: Array, required: !0 },
688
+ labels: { type: Array, required: !0 },
689
+ height: { type: Number, default: 280 },
690
+ stacked: Boolean,
691
+ legend: { type: Boolean, default: !0 }
692
+ },
693
+ setup(a) {
694
+ const i = g(), { intlLocale: r, n: t } = S(), { el: n, w: o } = O(), l = P(() => Z(a.series, a.labels, { width: o.value, height: a.height }, { stacked: a.stacked }));
695
+ return () => {
696
+ const s = l.value, v = r();
697
+ return e("div", { ref: n, class: `${i.value}-chart` }, [
698
+ a.legend ? R(
699
+ i.value,
700
+ a.series.map((d, u) => ({ name: d.name, color: ee(u, d) }))
701
+ ) : null,
702
+ e("svg", { width: o.value, height: a.height, role: "img", "aria-label": a.series.map((d) => d.name).join(", ") }, [
703
+ ...s.yTicks.map(
704
+ (d) => e("g", { key: d.value }, [
705
+ e("line", { x1: s.plot.x, x2: s.plot.x + s.plot.width, y1: d.y, y2: d.y, stroke: "var(--thl-border-color)" }),
706
+ N(s.plot.x - 8, d.y + 4, I(d.value, v), "end")
707
+ ])
708
+ ),
709
+ ...s.xLabels.map((d, u) => e("g", { key: `x${u}` }, N(d.x, a.height - 8, d.label))),
710
+ ...s.bars.map(
711
+ (d, u) => e(
712
+ "rect",
713
+ { key: u, x: d.x, y: d.y, width: d.width, height: d.height, fill: d.color, rx: 2 },
714
+ e("title", `${d.series} · ${d.label}: ${t(d.value)}`)
715
+ )
716
+ )
717
+ ])
718
+ ]);
719
+ };
720
+ }
721
+ }), Pe = /* @__PURE__ */ p({
722
+ name: "ThlPieChart",
723
+ props: {
724
+ data: { type: Array, required: !0 },
725
+ size: { type: Number, default: 220 },
726
+ donut: { type: Number, default: 0.6 },
727
+ legend: { type: Boolean, default: !0 }
728
+ },
729
+ setup(a, { slots: i }) {
730
+ const r = g(), { n: t } = S(), n = T(null), o = P(() => te(a.data, a.size, { donut: a.donut }));
731
+ return () => e("div", { class: `${r.value}-chart`, style: { display: "flex", flexDirection: "column", alignItems: "center" } }, [
732
+ e("div", { style: { position: "relative", width: `${a.size}px`, height: `${a.size}px` } }, [
733
+ e(
734
+ "svg",
735
+ { width: a.size, height: a.size, role: "img", "aria-label": a.data.map((l) => `${l.label} ${l.value}`).join(", ") },
736
+ o.value.map(
737
+ (l, s) => e(
738
+ "path",
739
+ {
740
+ key: s,
741
+ d: l.path,
742
+ fill: l.color,
743
+ stroke: "var(--thl-surface)",
744
+ "stroke-width": 2,
745
+ opacity: n.value === null || n.value === s ? 1 : 0.55,
746
+ onMouseenter: () => n.value = s,
747
+ onMouseleave: () => n.value = null
748
+ },
749
+ e("title", `${l.label}: ${t(l.value)} (${l.percent.toFixed(1)}%)`)
750
+ )
751
+ )
752
+ ),
753
+ e(
754
+ "div",
755
+ {
756
+ style: {
757
+ position: "absolute",
758
+ inset: 0,
759
+ display: "flex",
760
+ alignItems: "center",
761
+ justifyContent: "center",
762
+ flexDirection: "column",
763
+ pointerEvents: "none",
764
+ textAlign: "center"
765
+ }
766
+ },
767
+ n.value !== null ? [
768
+ e("b", { style: { fontSize: "22px", color: "var(--thl-heading)" } }, `${o.value[n.value].percent.toFixed(0)}%`),
769
+ e("small", o.value[n.value].label)
770
+ ] : i.center?.()
771
+ )
772
+ ]),
773
+ a.legend ? e(
774
+ "div",
775
+ { class: `${r.value}-mt-3` },
776
+ R(
777
+ r.value,
778
+ o.value.map((l) => ({ name: l.label, color: l.color }))
779
+ )
780
+ ) : null
781
+ ]);
782
+ }
783
+ }), Ie = /* @__PURE__ */ p({
784
+ name: "ThlSparkline",
785
+ props: {
786
+ data: { type: Array, required: !0 },
787
+ width: { type: Number, default: 120 },
788
+ height: { type: Number, default: 36 },
789
+ type: D("line"),
790
+ color: D("primary")
791
+ },
792
+ setup(a) {
793
+ const i = g();
794
+ return () => {
795
+ const r = le(a.data, a.width, a.height, a.type === "bar" ? "bar" : "line"), t = `var(--${i.value}-color-${a.color})`;
796
+ return e(
797
+ "svg",
798
+ {
799
+ width: a.width,
800
+ height: a.height,
801
+ viewBox: `0 0 ${a.width} ${a.height}`,
802
+ role: "img",
803
+ "aria-label": a.data.join(", "),
804
+ style: { overflow: "visible", maxWidth: "100%", height: "auto" }
805
+ },
806
+ a.type === "bar" ? r.bars.map((n, o) => e("rect", { key: o, x: n.x, y: n.y, width: n.width, height: n.height, fill: t, rx: 1 })) : [
807
+ a.type === "area" ? e("path", { d: r.area, fill: t, opacity: 0.2 }) : null,
808
+ e("path", { d: r.line, fill: "none", stroke: t, "stroke-width": 2, "stroke-linejoin": "round" }),
809
+ r.last ? e("circle", { cx: r.last[0], cy: r.last[1], r: 3, fill: t }) : null
810
+ ]
811
+ );
812
+ };
813
+ }
814
+ }), Re = /* @__PURE__ */ p({
815
+ name: "ThlCalendar",
816
+ props: { events: { type: Array, required: !0 } },
817
+ emits: ["event-move", "date-click", "event-click"],
818
+ setup(a, { emit: i }) {
819
+ const r = g(), { t, d: n, intlLocale: o } = S(), l = oe(), s = T(new Date((/* @__PURE__ */ new Date()).getFullYear(), (/* @__PURE__ */ new Date()).getMonth(), 1)), v = T(null), d = P(() => {
820
+ const u = {};
821
+ return a.events.forEach((c) => (u[c.date] ??= []).push(c)), u;
822
+ });
823
+ return () => {
824
+ const u = l.config.value.components.DatePicker?.weekStartsOn ?? 1, c = o(), y = f("calendar", r.value);
825
+ return e("div", { class: y() }, [
826
+ e("div", { class: y("toolbar") }, [
827
+ e("div", { class: `${r.value}-btn-group` }, [
828
+ e(
829
+ B,
830
+ { size: "sm", "aria-label": t("common.previous"), onClick: () => s.value = j(s.value, -1) },
831
+ () => x("chevron-left")
832
+ ),
833
+ e(B, { size: "sm", "aria-label": t("common.next"), onClick: () => s.value = j(s.value, 1) }, () => x("chevron-right"))
834
+ ]),
835
+ e("h2", { "aria-live": "polite" }, new Intl.DateTimeFormat(c, { month: "long", year: "numeric" }).format(s.value)),
836
+ e(
837
+ B,
838
+ {
839
+ size: "sm",
840
+ variant: "primary",
841
+ onClick: () => {
842
+ const m = /* @__PURE__ */ new Date();
843
+ s.value = new Date(m.getFullYear(), m.getMonth(), 1);
844
+ }
845
+ },
846
+ () => t("datepicker.today")
847
+ )
848
+ ]),
849
+ e("div", { class: y("grid") }, [
850
+ ...Y(c, u, "short").map((m) => e("div", { key: m, class: y("dow"), "aria-hidden": "true" }, m)),
851
+ ...H(s.value.getFullYear(), s.value.getMonth(), u).flat().map((m) => {
852
+ const C = J(m.date);
853
+ return e(
854
+ "div",
855
+ {
856
+ key: m.key,
857
+ role: "group",
858
+ "aria-label": n(m.date, { dateStyle: "full" }),
859
+ class: M(y("cell"), { "is-outside": !m.inMonth, "is-today": m.today, "is-drop": v.value === C }),
860
+ onClick: () => i("date-click", C),
861
+ onDragover: (b) => {
862
+ b.preventDefault(), v.value = C;
863
+ },
864
+ onDragleave: () => v.value = null,
865
+ onDrop: (b) => {
866
+ b.preventDefault(), v.value = null;
867
+ const $ = b.dataTransfer?.getData("text/thl-event");
868
+ $ && i("event-move", isNaN(Number($)) ? $ : Number($), C);
869
+ }
870
+ },
871
+ [
872
+ e("span", { class: y("date"), "aria-hidden": "true" }, m.date.getDate()),
873
+ ...(d.value[C] ?? []).map(
874
+ (b) => e(
875
+ "button",
876
+ {
877
+ key: b.id,
878
+ type: "button",
879
+ draggable: !0,
880
+ class: y("event", { [b.color ?? "primary"]: !0 }),
881
+ title: b.title,
882
+ onDragstart: ($) => $.dataTransfer?.setData("text/thl-event", String(b.id)),
883
+ onClick: ($) => {
884
+ $.stopPropagation(), i("event-click", b);
885
+ }
886
+ },
887
+ b.title
888
+ )
889
+ )
890
+ ]
891
+ );
892
+ })
893
+ ])
894
+ ]);
895
+ };
896
+ }
897
+ });
898
+ export {
899
+ Ne as ThlBarChart,
900
+ Re as ThlCalendar,
901
+ Ae as ThlChat,
902
+ Se as ThlColorBox,
903
+ xe as ThlDataTable,
904
+ we as ThlGallery,
905
+ $e as ThlInfoBox,
906
+ Me as ThlLineChart,
907
+ ke as ThlList,
908
+ Pe as ThlPieChart,
909
+ ze as ThlPricingTable,
910
+ De as ThlProfileCard,
911
+ Ie as ThlSparkline,
912
+ Te as ThlStatBox,
913
+ Ce as ThlStatsRow,
914
+ fe as ThlTable,
915
+ qe as ThlTodoList,
916
+ Be as ThlUserCard,
917
+ Le as ThlWeather
918
+ };
919
+ //# sourceMappingURL=data.js.map