@thl-ui/vue 0.0.0-stage → 0.1.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.
@@ -0,0 +1,911 @@
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), V = 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: V }, a.loading ? n("common.loading") : a.emptyText ?? n("table.empty")))] : y.rows.map(
173
+ ({ row: h, key: k }, _) => 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: _ }) : 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` },
386
+ a.plans.map(
387
+ (o, l) => e("div", { key: l, class: n({ featured: o.featured }) }, [
388
+ o.tag ? e("div", { class: n("tag") }, o.tag) : null,
389
+ e("div", { class: n("header") }, [
390
+ e("h2", o.name),
391
+ e("div", { class: n("price") }, [e("sup", o.currency ?? "$"), o.price]),
392
+ e("p", { class: n("period") }, o.period ?? t("pages.pricing.perMonth"))
393
+ ]),
394
+ e(
395
+ "ul",
396
+ { class: n("features") },
397
+ o.features.map((s, v) => e("li", { key: v, class: n("feature") }, [x(s.icon), s.text]))
398
+ ),
399
+ e(
400
+ "div",
401
+ { class: n("action") },
402
+ e(
403
+ B,
404
+ { variant: o.ctaVariant ?? (o.featured ? "danger" : "success"), size: o.featured ? "lg" : void 0, onClick: () => i("select", o, l) },
405
+ () => o.cta ?? t("pages.pricing.signUp")
406
+ )
407
+ )
408
+ ])
409
+ )
410
+ );
411
+ };
412
+ }
413
+ }), Be = /* @__PURE__ */ p({
414
+ name: "ThlUserCard",
415
+ props: { image: { type: String, required: !0 }, name: String, subtitle: String },
416
+ setup(a, { slots: i }) {
417
+ const r = g();
418
+ return () => {
419
+ const t = f("user-card", r.value);
420
+ return e("div", { class: t() }, [
421
+ e("div", { class: t("media"), tabindex: i.actions ? 0 : void 0 }, [
422
+ e("img", { src: a.image, alt: "" }),
423
+ i.actions ? e("div", { class: t("overlay") }, i.actions()) : null
424
+ ]),
425
+ e("div", { class: t("content") }, [e("h2", a.name), a.subtitle ? e("small", a.subtitle) : null])
426
+ ]);
427
+ };
428
+ }
429
+ }), De = /* @__PURE__ */ p({
430
+ name: "ThlProfileCard",
431
+ props: { cover: String, avatar: String, name: String, email: String, stats: Array },
432
+ setup(a, { slots: i }) {
433
+ const r = g();
434
+ return () => {
435
+ const t = f("profile-card", r.value);
436
+ return e("div", { class: t() }, [
437
+ e("div", { class: t("cover") }, [
438
+ a.cover ? e("img", { src: a.cover, alt: "" }) : null,
439
+ e("div", { class: t("overlay") }, [
440
+ a.avatar ? e("img", {
441
+ src: a.avatar,
442
+ alt: "",
443
+ style: { width: "80px", height: "80px", borderRadius: "50%", border: "3px solid #fff", objectFit: "cover" }
444
+ }) : null,
445
+ e("h2", a.name),
446
+ a.email ? e("div", a.email) : null
447
+ ])
448
+ ]),
449
+ a.stats ? e(
450
+ "div",
451
+ { class: t("stats") },
452
+ a.stats.map((n, o) => e("div", { key: o }, [e("b", n.value), e("small", n.label)]))
453
+ ) : null,
454
+ i.default ? e("div", { class: t("body") }, i.default()) : null
455
+ ]);
456
+ };
457
+ }
458
+ }), Ae = /* @__PURE__ */ p({
459
+ name: "ThlChat",
460
+ props: {
461
+ messages: {
462
+ type: Array,
463
+ required: !0
464
+ },
465
+ composer: Boolean
466
+ },
467
+ emits: ["send"],
468
+ setup(a, { emit: i }) {
469
+ const r = g(), { t } = S(), n = T("");
470
+ return () => {
471
+ const o = f("chat", r.value);
472
+ return e("div", [
473
+ e(
474
+ "ul",
475
+ { class: o(), "aria-live": "polite" },
476
+ a.messages.map(
477
+ (l) => e("li", { key: l.id, class: o("msg", { me: l.me }) }, [
478
+ l.avatar ? e("img", { src: l.avatar, alt: "", style: { width: "36px", height: "36px", borderRadius: "50%", objectFit: "cover" } }) : null,
479
+ e("div", [
480
+ l.me ? null : e("div", { class: o("name") }, l.from),
481
+ e("div", { class: o("bubble") }, l.text),
482
+ l.time ? e("div", { class: o("time") }, l.time) : null
483
+ ])
484
+ ])
485
+ )
486
+ ),
487
+ a.composer ? e(
488
+ "form",
489
+ {
490
+ class: o("composer"),
491
+ onSubmit: (l) => {
492
+ l.preventDefault(), n.value.trim() && (i("send", n.value.trim()), n.value = "");
493
+ }
494
+ },
495
+ [
496
+ e("input", {
497
+ class: `${r.value}-input`,
498
+ value: n.value,
499
+ onInput: (l) => n.value = l.target.value,
500
+ placeholder: `${t("layout.messages")}...`,
501
+ "aria-label": t("layout.messages")
502
+ }),
503
+ e(B, { type: "submit", variant: "primary", circle: !0, "aria-label": t("pages.inbox.send") }, () => x("send"))
504
+ ]
505
+ ) : null
506
+ ]);
507
+ };
508
+ }
509
+ }), qe = /* @__PURE__ */ p({
510
+ name: "ThlTodoList",
511
+ props: {
512
+ items: { type: Array, required: !0 },
513
+ addable: Boolean
514
+ },
515
+ emits: ["toggle", "remove", "add"],
516
+ setup(a, { emit: i }) {
517
+ const r = g(), { t } = S(), n = T("");
518
+ return () => {
519
+ const o = f("todo", r.value);
520
+ return e("div", [
521
+ e(
522
+ "ul",
523
+ { class: o() },
524
+ a.items.map(
525
+ (l) => e("li", { key: l.id, class: M(o("item"), { "is-done": l.done }) }, [
526
+ e("label", { class: `${r.value}-check`, style: { margin: 0 } }, [
527
+ e("input", {
528
+ type: "checkbox",
529
+ class: `${r.value}-check__input`,
530
+ checked: !!l.done,
531
+ "aria-label": `${t("common.toggleDone")}: ${l.text}`,
532
+ onChange: () => i("toggle", l.id)
533
+ }),
534
+ e("span", { class: `${r.value}-check__box` })
535
+ ]),
536
+ e("span", { class: o("text") }, l.text),
537
+ l.badge ? e(ie, { color: l.badge.color ?? "info", rounded: !0 }, () => l.badge.text) : null,
538
+ e("button", { type: "button", class: o("remove"), onClick: () => i("remove", l.id), "aria-label": t("common.delete") }, x("trash-2"))
539
+ ])
540
+ )
541
+ ),
542
+ a.addable ? e(
543
+ "form",
544
+ {
545
+ class: `${r.value}-flex ${r.value}-mt-3`,
546
+ style: { flexWrap: "nowrap" },
547
+ onSubmit: (l) => {
548
+ l.preventDefault(), n.value.trim() && (i("add", n.value.trim()), n.value = "");
549
+ }
550
+ },
551
+ [
552
+ e("input", {
553
+ class: `${r.value}-input`,
554
+ value: n.value,
555
+ onInput: (l) => n.value = l.target.value,
556
+ placeholder: `${t("common.add")}...`,
557
+ "aria-label": t("common.add")
558
+ }),
559
+ e(B, { type: "submit", variant: "success" }, () => t("common.add"))
560
+ ]
561
+ ) : null
562
+ ]);
563
+ };
564
+ }
565
+ }), Le = /* @__PURE__ */ p({
566
+ name: "ThlWeather",
567
+ props: {
568
+ city: String,
569
+ temp: Number,
570
+ condition: String,
571
+ icon: D("cloud-sun"),
572
+ days: Array
573
+ },
574
+ setup(a) {
575
+ const i = g();
576
+ return () => {
577
+ const r = f("weather", i.value);
578
+ return e("div", { class: r() }, [
579
+ e("div", { class: `${i.value}-flex-between` }, [
580
+ e("div", [
581
+ e("div", { class: r("temp") }, [a.temp, e("sup", "°")]),
582
+ e("div", a.condition),
583
+ e("small", { style: { opacity: 0.85 } }, [x("map-pin"), " ", a.city])
584
+ ]),
585
+ e("span", { class: r("icon") }, x(a.icon, { strokeWidth: 1.5 }))
586
+ ]),
587
+ a.days ? e(
588
+ "div",
589
+ { class: r("days") },
590
+ a.days.map((t, n) => e("div", { key: n }, [e("div", t.day), x(t.icon), e("b", `${t.temp}°`)]))
591
+ ) : null
592
+ ]);
593
+ };
594
+ }
595
+ });
596
+ function O() {
597
+ const a = T(), i = T(600);
598
+ let r = null;
599
+ return K(() => {
600
+ a.value && typeof ResizeObserver < "u" && (r = new ResizeObserver(([t]) => i.value = Math.max(200, Math.round(t.contentRect.width))), r.observe(a.value));
601
+ }), W(() => r?.disconnect()), { el: a, w: i };
602
+ }
603
+ const R = (a, i) => e(
604
+ "ul",
605
+ { class: `${a}-chart-legend` },
606
+ i.map((r, t) => e("li", { key: t }, [e("i", { style: { background: r.color } }), r.name]))
607
+ ), 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({
608
+ name: "ThlLineChart",
609
+ props: {
610
+ series: { type: Array, required: !0 },
611
+ labels: { type: Array, required: !0 },
612
+ height: { type: Number, default: 280 },
613
+ area: Boolean,
614
+ smooth: { type: Boolean, default: !0 },
615
+ legend: { type: Boolean, default: !0 }
616
+ },
617
+ setup(a) {
618
+ 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 }));
619
+ return () => {
620
+ const s = l.value, v = r(), d = Math.max(1, a.labels.length - 1);
621
+ return e("div", { ref: t, class: `${i.value}-chart` }, [
622
+ a.legend ? R(
623
+ i.value,
624
+ s.series.map((u) => ({ name: u.name, color: u.color }))
625
+ ) : null,
626
+ e(
627
+ "svg",
628
+ { width: n.value, height: a.height, role: "img", "aria-label": a.series.map((u) => u.name).join(", "), onMouseleave: () => o.value = null },
629
+ [
630
+ ...s.yTicks.map(
631
+ (u) => e("g", { key: u.value }, [
632
+ e("line", { x1: s.plot.x, x2: s.plot.x + s.plot.width, y1: u.y, y2: u.y, stroke: "var(--thl-border-color)" }),
633
+ N(s.plot.x - 8, u.y + 4, I(u.value, v), "end")
634
+ ])
635
+ ),
636
+ ...s.xLabels.map((u, c) => e("g", { key: `x${c}` }, N(u.x, a.height - 8, u.label))),
637
+ ...s.series.map(
638
+ (u, c) => e("g", { key: c }, [
639
+ a.area ? e("path", { d: u.area, fill: u.color, opacity: 0.15 }) : null,
640
+ e("path", { d: u.line, fill: "none", stroke: u.color, "stroke-width": 2.5, "stroke-linejoin": "round", "stroke-linecap": "round" }),
641
+ ...u.points.map(
642
+ (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 })
643
+ )
644
+ ])
645
+ ),
646
+ ...s.xLabels.map(
647
+ (u, c) => e("rect", {
648
+ key: `h${c}`,
649
+ x: u.x - s.plot.width / d / 2,
650
+ y: s.plot.y,
651
+ width: s.plot.width / d,
652
+ height: s.plot.height,
653
+ fill: "transparent",
654
+ onMouseenter: () => o.value = c
655
+ })
656
+ )
657
+ ]
658
+ ),
659
+ o.value !== null ? e(
660
+ "div",
661
+ {
662
+ class: `${i.value}-chart-tooltip`,
663
+ style: {
664
+ left: `${s.xLabels[o.value].x}px`,
665
+ top: `${Math.min(...s.series.map((u) => u.points[o.value]?.y ?? a.height)) + (a.legend ? 30 : 0)}px`
666
+ }
667
+ },
668
+ [
669
+ e("b", a.labels[o.value]),
670
+ ...s.series.map((u) => e("div", { key: u.name }, `${u.name}: ${I(u.points[o.value]?.value ?? 0, v)}`))
671
+ ]
672
+ ) : null
673
+ ]);
674
+ };
675
+ }
676
+ }), Ne = /* @__PURE__ */ p({
677
+ name: "ThlBarChart",
678
+ props: {
679
+ series: { type: Array, required: !0 },
680
+ labels: { type: Array, required: !0 },
681
+ height: { type: Number, default: 280 },
682
+ stacked: Boolean,
683
+ legend: { type: Boolean, default: !0 }
684
+ },
685
+ setup(a) {
686
+ 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 }));
687
+ return () => {
688
+ const s = l.value, v = r();
689
+ return e("div", { ref: n, class: `${i.value}-chart` }, [
690
+ a.legend ? R(
691
+ i.value,
692
+ a.series.map((d, u) => ({ name: d.name, color: ee(u, d) }))
693
+ ) : null,
694
+ e("svg", { width: o.value, height: a.height, role: "img", "aria-label": a.series.map((d) => d.name).join(", ") }, [
695
+ ...s.yTicks.map(
696
+ (d) => e("g", { key: d.value }, [
697
+ e("line", { x1: s.plot.x, x2: s.plot.x + s.plot.width, y1: d.y, y2: d.y, stroke: "var(--thl-border-color)" }),
698
+ N(s.plot.x - 8, d.y + 4, I(d.value, v), "end")
699
+ ])
700
+ ),
701
+ ...s.xLabels.map((d, u) => e("g", { key: `x${u}` }, N(d.x, a.height - 8, d.label))),
702
+ ...s.bars.map(
703
+ (d, u) => e(
704
+ "rect",
705
+ { key: u, x: d.x, y: d.y, width: d.width, height: d.height, fill: d.color, rx: 2 },
706
+ e("title", `${d.series} · ${d.label}: ${t(d.value)}`)
707
+ )
708
+ )
709
+ ])
710
+ ]);
711
+ };
712
+ }
713
+ }), Pe = /* @__PURE__ */ p({
714
+ name: "ThlPieChart",
715
+ props: {
716
+ data: { type: Array, required: !0 },
717
+ size: { type: Number, default: 220 },
718
+ donut: { type: Number, default: 0.6 },
719
+ legend: { type: Boolean, default: !0 }
720
+ },
721
+ setup(a, { slots: i }) {
722
+ const r = g(), { n: t } = S(), n = T(null), o = P(() => te(a.data, a.size, { donut: a.donut }));
723
+ return () => e("div", { class: `${r.value}-chart`, style: { display: "flex", flexDirection: "column", alignItems: "center" } }, [
724
+ e("div", { style: { position: "relative", width: `${a.size}px`, height: `${a.size}px` } }, [
725
+ e(
726
+ "svg",
727
+ { width: a.size, height: a.size, role: "img", "aria-label": a.data.map((l) => `${l.label} ${l.value}`).join(", ") },
728
+ o.value.map(
729
+ (l, s) => e(
730
+ "path",
731
+ {
732
+ key: s,
733
+ d: l.path,
734
+ fill: l.color,
735
+ stroke: "var(--thl-surface)",
736
+ "stroke-width": 2,
737
+ opacity: n.value === null || n.value === s ? 1 : 0.55,
738
+ onMouseenter: () => n.value = s,
739
+ onMouseleave: () => n.value = null
740
+ },
741
+ e("title", `${l.label}: ${t(l.value)} (${l.percent.toFixed(1)}%)`)
742
+ )
743
+ )
744
+ ),
745
+ e(
746
+ "div",
747
+ {
748
+ style: {
749
+ position: "absolute",
750
+ inset: 0,
751
+ display: "flex",
752
+ alignItems: "center",
753
+ justifyContent: "center",
754
+ flexDirection: "column",
755
+ pointerEvents: "none",
756
+ textAlign: "center"
757
+ }
758
+ },
759
+ n.value !== null ? [
760
+ e("b", { style: { fontSize: "22px", color: "var(--thl-heading)" } }, `${o.value[n.value].percent.toFixed(0)}%`),
761
+ e("small", o.value[n.value].label)
762
+ ] : i.center?.()
763
+ )
764
+ ]),
765
+ a.legend ? e(
766
+ "div",
767
+ { class: `${r.value}-mt-3` },
768
+ R(
769
+ r.value,
770
+ o.value.map((l) => ({ name: l.label, color: l.color }))
771
+ )
772
+ ) : null
773
+ ]);
774
+ }
775
+ }), Ie = /* @__PURE__ */ p({
776
+ name: "ThlSparkline",
777
+ props: {
778
+ data: { type: Array, required: !0 },
779
+ width: { type: Number, default: 120 },
780
+ height: { type: Number, default: 36 },
781
+ type: D("line"),
782
+ color: D("primary")
783
+ },
784
+ setup(a) {
785
+ const i = g();
786
+ return () => {
787
+ const r = le(a.data, a.width, a.height, a.type === "bar" ? "bar" : "line"), t = `var(--${i.value}-color-${a.color})`;
788
+ return e(
789
+ "svg",
790
+ {
791
+ width: a.width,
792
+ height: a.height,
793
+ viewBox: `0 0 ${a.width} ${a.height}`,
794
+ role: "img",
795
+ "aria-label": a.data.join(", "),
796
+ style: { overflow: "visible", maxWidth: "100%", height: "auto" }
797
+ },
798
+ 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 })) : [
799
+ a.type === "area" ? e("path", { d: r.area, fill: t, opacity: 0.2 }) : null,
800
+ e("path", { d: r.line, fill: "none", stroke: t, "stroke-width": 2, "stroke-linejoin": "round" }),
801
+ r.last ? e("circle", { cx: r.last[0], cy: r.last[1], r: 3, fill: t }) : null
802
+ ]
803
+ );
804
+ };
805
+ }
806
+ }), Re = /* @__PURE__ */ p({
807
+ name: "ThlCalendar",
808
+ props: { events: { type: Array, required: !0 } },
809
+ emits: ["event-move", "date-click", "event-click"],
810
+ setup(a, { emit: i }) {
811
+ 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(() => {
812
+ const u = {};
813
+ return a.events.forEach((c) => (u[c.date] ??= []).push(c)), u;
814
+ });
815
+ return () => {
816
+ const u = l.config.value.components.DatePicker?.weekStartsOn ?? 1, c = o(), y = f("calendar", r.value);
817
+ return e("div", { class: y() }, [
818
+ e("div", { class: y("toolbar") }, [
819
+ e("div", { class: `${r.value}-btn-group` }, [
820
+ e(
821
+ B,
822
+ { size: "sm", "aria-label": t("common.previous"), onClick: () => s.value = j(s.value, -1) },
823
+ () => x("chevron-left")
824
+ ),
825
+ e(B, { size: "sm", "aria-label": t("common.next"), onClick: () => s.value = j(s.value, 1) }, () => x("chevron-right"))
826
+ ]),
827
+ e("h2", { "aria-live": "polite" }, new Intl.DateTimeFormat(c, { month: "long", year: "numeric" }).format(s.value)),
828
+ e(
829
+ B,
830
+ {
831
+ size: "sm",
832
+ variant: "primary",
833
+ onClick: () => {
834
+ const m = /* @__PURE__ */ new Date();
835
+ s.value = new Date(m.getFullYear(), m.getMonth(), 1);
836
+ }
837
+ },
838
+ () => t("datepicker.today")
839
+ )
840
+ ]),
841
+ e("div", { class: y("grid") }, [
842
+ ...Y(c, u, "short").map((m) => e("div", { key: m, class: y("dow"), "aria-hidden": "true" }, m)),
843
+ ...H(s.value.getFullYear(), s.value.getMonth(), u).flat().map((m) => {
844
+ const C = J(m.date);
845
+ return e(
846
+ "div",
847
+ {
848
+ key: m.key,
849
+ role: "group",
850
+ "aria-label": n(m.date, { dateStyle: "full" }),
851
+ class: M(y("cell"), { "is-outside": !m.inMonth, "is-today": m.today, "is-drop": v.value === C }),
852
+ onClick: () => i("date-click", C),
853
+ onDragover: (b) => {
854
+ b.preventDefault(), v.value = C;
855
+ },
856
+ onDragleave: () => v.value = null,
857
+ onDrop: (b) => {
858
+ b.preventDefault(), v.value = null;
859
+ const $ = b.dataTransfer?.getData("text/thl-event");
860
+ $ && i("event-move", isNaN(Number($)) ? $ : Number($), C);
861
+ }
862
+ },
863
+ [
864
+ e("span", { class: y("date"), "aria-hidden": "true" }, m.date.getDate()),
865
+ ...(d.value[C] ?? []).map(
866
+ (b) => e(
867
+ "button",
868
+ {
869
+ key: b.id,
870
+ type: "button",
871
+ draggable: !0,
872
+ class: y("event", { [b.color ?? "primary"]: !0 }),
873
+ title: b.title,
874
+ onDragstart: ($) => $.dataTransfer?.setData("text/thl-event", String(b.id)),
875
+ onClick: ($) => {
876
+ $.stopPropagation(), i("event-click", b);
877
+ }
878
+ },
879
+ b.title
880
+ )
881
+ )
882
+ ]
883
+ );
884
+ })
885
+ ])
886
+ ]);
887
+ };
888
+ }
889
+ });
890
+ export {
891
+ Ne as ThlBarChart,
892
+ Re as ThlCalendar,
893
+ Ae as ThlChat,
894
+ Se as ThlColorBox,
895
+ xe as ThlDataTable,
896
+ we as ThlGallery,
897
+ $e as ThlInfoBox,
898
+ Me as ThlLineChart,
899
+ ke as ThlList,
900
+ Pe as ThlPieChart,
901
+ ze as ThlPricingTable,
902
+ De as ThlProfileCard,
903
+ Ie as ThlSparkline,
904
+ Te as ThlStatBox,
905
+ Ce as ThlStatsRow,
906
+ fe as ThlTable,
907
+ qe as ThlTodoList,
908
+ Be as ThlUserCard,
909
+ Le as ThlWeather
910
+ };
911
+ //# sourceMappingURL=data.js.map