@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,437 @@
1
+ import { defineComponent as g, onMounted as R, onBeforeUnmount as w, h as t, ref as y, watch as T, nextTick as S, Teleport as C, computed as U, cloneVNode as F, shallowRef as A } from "vue";
2
+ import { bem as p, cx as L, uid as M, clickOutside as I, focusTrap as H, scrollLock as V, computePosition as j } from "@thl-ui/core";
3
+ import { usePrefix as b, useI18n as x, useDefaults as $, useThlContext as G, useStore as J } from "../context.js";
4
+ import { icon as P, str as k, any as q } from "./util.js";
5
+ import { ThlButton as O } from "./basic.js";
6
+ const Q = /* @__PURE__ */ g({
7
+ name: "ThlModal",
8
+ props: {
9
+ open: Boolean,
10
+ title: String,
11
+ size: String,
12
+ closeOnBackdrop: { type: Boolean, default: void 0 },
13
+ closeOnEsc: { type: Boolean, default: void 0 },
14
+ centered: { type: Boolean, default: void 0 },
15
+ scrollable: Boolean,
16
+ hideClose: Boolean,
17
+ modalClass: String
18
+ },
19
+ emits: ["update:open", "close"],
20
+ setup(e, { slots: r, emit: u }) {
21
+ const o = b(), { t: n } = x(), l = $("Modal", e), a = y(), c = M("modal-title");
22
+ let i = null, m = null;
23
+ const v = () => {
24
+ u("update:open", !1), u("close");
25
+ }, f = (s) => {
26
+ s.key === "Escape" && l.value.closeOnEsc !== !1 && (s.stopPropagation(), v());
27
+ }, h = () => {
28
+ i?.(), m?.(), i = m = null, document.removeEventListener("keydown", f);
29
+ };
30
+ return T(
31
+ () => e.open,
32
+ async (s) => {
33
+ s ? (await S(), a.value && (i = H(a.value), m = V(), document.addEventListener("keydown", f))) : h();
34
+ },
35
+ { immediate: !0 }
36
+ ), w(h), () => {
37
+ if (!e.open) return null;
38
+ const s = p("modal", o.value);
39
+ return t(
40
+ C,
41
+ { to: "body" },
42
+ t(
43
+ "div",
44
+ {
45
+ class: p("modal-backdrop", o.value)({ centered: l.value.centered }),
46
+ onMousedown: (d) => {
47
+ d.target === d.currentTarget && l.value.closeOnBackdrop !== !1 && v();
48
+ }
49
+ },
50
+ t(
51
+ "div",
52
+ {
53
+ ref: a,
54
+ role: "dialog",
55
+ "aria-modal": "true",
56
+ "aria-labelledby": e.title ? c : void 0,
57
+ tabindex: -1,
58
+ class: L(s({ [l.value.size ?? "md"]: !!l.value.size && l.value.size !== "md", scrollable: e.scrollable }), e.modalClass)
59
+ },
60
+ [
61
+ e.title || r.title || !e.hideClose ? t("div", { class: s("header") }, [
62
+ t("h2", { id: c, class: s("title") }, r.title ? r.title() : e.title),
63
+ e.hideClose ? null : t("button", { type: "button", class: s("close"), "aria-label": n("modal.close"), onClick: v }, "×")
64
+ ]) : null,
65
+ t("div", { class: s("body") }, r.default?.()),
66
+ r.footer ? t("div", { class: s("footer") }, r.footer({ close: v })) : null
67
+ ]
68
+ )
69
+ )
70
+ );
71
+ };
72
+ }
73
+ }), z = A(null);
74
+ let B = 0;
75
+ function te(e = {}) {
76
+ return new Promise((r) => {
77
+ if (!B) {
78
+ r(typeof window < "u" ? window.confirm(e.title ?? "") : !1);
79
+ return;
80
+ }
81
+ z.value = { ...e, resolve: r };
82
+ });
83
+ }
84
+ const oe = /* @__PURE__ */ g({
85
+ name: "ThlConfirmHost",
86
+ setup() {
87
+ const e = b(), { t: r } = x();
88
+ R(() => B++), w(() => B--);
89
+ const u = (o) => {
90
+ z.value?.resolve(o), z.value = null;
91
+ };
92
+ return () => {
93
+ const o = z.value, n = o?.icon ?? "warning", l = { warning: "triangle-alert", danger: "circle-x", success: "check", info: "info", question: "circle-help" }[n];
94
+ return t(
95
+ Q,
96
+ { open: !!o, hideClose: !0, modalClass: `${e.value}-modal--confirm`, "onUpdate:open": (a) => !a && u(!1) },
97
+ {
98
+ default: () => [
99
+ t("div", { class: p("modal", e.value)("confirm-icon", { [n]: !0 }) }, P(l)),
100
+ t("h2", o?.title ?? r("modal.confirmTitle")),
101
+ t("p", o?.text ?? r("modal.confirmText"))
102
+ ],
103
+ footer: () => [
104
+ o?.showCancel !== !1 ? t(O, { onClick: () => u(!1) }, () => o?.cancelText ?? r("common.cancel")) : null,
105
+ t(
106
+ O,
107
+ { variant: o?.confirmVariant ?? (n === "danger" || n === "warning" ? "danger" : "primary"), onClick: () => u(!0), autofocus: !0 },
108
+ () => o?.confirmText ?? r("common.ok")
109
+ )
110
+ ]
111
+ }
112
+ );
113
+ };
114
+ }
115
+ }), le = /* @__PURE__ */ g({
116
+ name: "ThlDrawer",
117
+ props: { open: Boolean, title: String, side: k("end"), wide: Boolean },
118
+ emits: ["update:open", "close"],
119
+ setup(e, { slots: r, emit: u }) {
120
+ const o = b(), { t: n } = x(), l = y(), a = () => {
121
+ u("update:open", !1), u("close");
122
+ }, c = (i) => i.key === "Escape" && a();
123
+ return T(
124
+ () => e.open,
125
+ (i) => {
126
+ i ? (document.addEventListener("keydown", c), S(() => l.value?.focus())) : document.removeEventListener("keydown", c);
127
+ }
128
+ ), w(() => document.removeEventListener("keydown", c)), () => {
129
+ const i = p("drawer", o.value);
130
+ return t(C, { to: "body" }, [
131
+ e.open ? t("div", { class: `${o.value}-drawer-backdrop`, onClick: a }) : null,
132
+ t(
133
+ "aside",
134
+ {
135
+ ref: l,
136
+ tabindex: -1,
137
+ role: "dialog",
138
+ "aria-modal": e.open,
139
+ "aria-hidden": !e.open,
140
+ "aria-label": e.title,
141
+ inert: !e.open || void 0,
142
+ class: L(i({ start: e.side === "start", wide: e.wide }), { "is-open": e.open })
143
+ },
144
+ [
145
+ t("div", { class: i("header") }, [
146
+ t("span", e.title),
147
+ t("button", { type: "button", class: i("close"), onClick: a, "aria-label": n("common.close") }, "×")
148
+ ]),
149
+ t("div", { class: i("body") }, r.default?.())
150
+ ]
151
+ )
152
+ ]);
153
+ };
154
+ }
155
+ });
156
+ function K(e, r) {
157
+ const u = y(), o = y(), n = y({ top: "-9999px", left: "-9999px" }), l = () => {
158
+ if (!u.value || !o.value) return;
159
+ const a = u.value.firstElementChild ?? u.value, c = o.value.getBoundingClientRect(), i = j(a.getBoundingClientRect(), { width: c.width, height: c.height }, r());
160
+ n.value = { top: `${i.top}px`, left: `${i.left}px` };
161
+ };
162
+ return T(e, async (a) => {
163
+ a ? (await S(), l(), window.addEventListener("scroll", l, !0), window.addEventListener("resize", l)) : (window.removeEventListener("scroll", l, !0), window.removeEventListener("resize", l), n.value = { top: "-9999px", left: "-9999px" });
164
+ }), w(() => {
165
+ window.removeEventListener("scroll", l, !0), window.removeEventListener("resize", l);
166
+ }), { anchor: u, float: o, style: n };
167
+ }
168
+ const ne = /* @__PURE__ */ g({
169
+ name: "ThlTooltip",
170
+ props: { content: String, placement: k("top"), color: String, delay: Number },
171
+ setup(e, { slots: r }) {
172
+ const u = b(), o = $("Tooltip", e), n = y(!1), l = M("tip"), { anchor: a, float: c, style: i } = K(
173
+ () => n.value,
174
+ () => e.placement
175
+ );
176
+ let m;
177
+ const v = () => {
178
+ clearTimeout(m), m = setTimeout(() => n.value = !0, o.value.delay ?? 100);
179
+ }, f = () => {
180
+ clearTimeout(m), n.value = !1;
181
+ };
182
+ return () => [
183
+ t(
184
+ "span",
185
+ {
186
+ ref: a,
187
+ style: { display: "inline-flex" },
188
+ onMouseenter: v,
189
+ onMouseleave: f,
190
+ onFocusin: v,
191
+ onFocusout: f,
192
+ "aria-describedby": n.value ? l : void 0
193
+ },
194
+ r.default?.()
195
+ ),
196
+ n.value ? t(
197
+ C,
198
+ { to: "body" },
199
+ t(
200
+ "div",
201
+ {
202
+ ref: c,
203
+ id: l,
204
+ role: "tooltip",
205
+ class: p("tooltip", u.value)({ [e.color ?? ""]: !!e.color }),
206
+ style: { position: "absolute", ...i.value }
207
+ },
208
+ r.content ? r.content() : e.content
209
+ )
210
+ ) : null
211
+ ];
212
+ }
213
+ }), ae = /* @__PURE__ */ g({
214
+ name: "ThlPopover",
215
+ props: { title: String, content: String, placement: k("bottom"), color: String, trigger: k("click") },
216
+ setup(e, { slots: r }) {
217
+ const u = b(), o = y(!1), n = M("pop"), { anchor: l, float: a, style: c } = K(
218
+ () => o.value,
219
+ () => e.placement
220
+ );
221
+ let i = null;
222
+ const m = (v) => v.key === "Escape" && (o.value = !1);
223
+ return T(o, async (v) => {
224
+ i?.(), i = null, document.removeEventListener("keydown", m), v && e.trigger === "click" && (await S(), i = I([l.value, a.value], () => o.value = !1), document.addEventListener("keydown", m));
225
+ }), w(() => {
226
+ i?.(), document.removeEventListener("keydown", m);
227
+ }), () => {
228
+ const v = p("popover", u.value), f = e.trigger === "click" ? { onClick: () => o.value = !o.value } : {
229
+ onMouseenter: () => o.value = !0,
230
+ onMouseleave: () => o.value = !1,
231
+ onFocusin: () => o.value = !0,
232
+ onFocusout: () => o.value = !1
233
+ };
234
+ return [
235
+ t(
236
+ "span",
237
+ { ref: l, style: { display: "inline-flex" }, ...f },
238
+ (r.default?.() ?? []).map(
239
+ (h, s) => s === 0 ? F(h, { "aria-haspopup": "dialog", "aria-expanded": String(o.value), "aria-controls": o.value ? n : void 0 }) : h
240
+ )
241
+ ),
242
+ o.value ? t(
243
+ C,
244
+ { to: "body" },
245
+ t("div", { ref: a, id: n, role: "dialog", class: v({ [e.color ?? ""]: !!e.color }), style: { position: "absolute", ...c.value } }, [
246
+ e.title ? t("div", { class: v("title") }, e.title) : null,
247
+ t("div", { class: v("body") }, r.content ? r.content() : e.content)
248
+ ])
249
+ ) : null
250
+ ];
251
+ };
252
+ }
253
+ }), re = /* @__PURE__ */ g({
254
+ name: "ThlDropdown",
255
+ props: {
256
+ items: q(),
257
+ align: k("start"),
258
+ placement: k("bottom"),
259
+ menuClass: String,
260
+ animation: String
261
+ },
262
+ emits: ["select"],
263
+ setup(e, { slots: r, emit: u }) {
264
+ const o = b(), n = y(!1), l = y(-1), a = y(), c = M("menu");
265
+ let i = null;
266
+ const m = () => {
267
+ n.value = !1, l.value = -1;
268
+ }, v = U(() => (e.items ?? []).filter((s) => !s.divider && !s.header && !s.disabled)), f = (s) => {
269
+ u("select", s.key), m();
270
+ }, h = (s) => {
271
+ if (s.key === "Escape" && (m(), a.value?.querySelector('[aria-haspopup="menu"]')?.focus()), !e.items) return;
272
+ const d = v.value.length;
273
+ s.key === "ArrowDown" && (s.preventDefault(), l.value = (l.value + 1) % d), s.key === "ArrowUp" && (s.preventDefault(), l.value = (l.value - 1 + d) % d), s.key === "Enter" && l.value >= 0 && (s.preventDefault(), f(v.value[l.value]));
274
+ };
275
+ return T(n, (s) => {
276
+ i?.(), i = null, document.removeEventListener("keydown", h), s && (i = I([a.value], m), document.addEventListener("keydown", h));
277
+ }), w(() => {
278
+ i?.(), document.removeEventListener("keydown", h);
279
+ }), () => {
280
+ const s = p("menu", o.value);
281
+ return t("div", { ref: a, class: `${o.value}-dropdown` }, [
282
+ t(
283
+ "span",
284
+ { style: { display: "contents" }, onClick: () => n.value = !n.value },
285
+ (r.trigger?.({ open: n.value }) ?? []).map(
286
+ (d, E) => E === 0 ? F(d, { "aria-haspopup": "menu", "aria-expanded": String(n.value), "aria-controls": n.value ? c : void 0 }) : d
287
+ )
288
+ ),
289
+ n.value ? t(
290
+ "div",
291
+ { id: c, role: "menu", class: L(s({ end: e.align === "end", start: e.align === "start", [e.placement]: !0 }), e.animation, e.menuClass) },
292
+ [
293
+ r.default?.({ close: m }),
294
+ ...(e.items ?? []).map((d) => {
295
+ if (d.divider) return t("div", { key: d.key, class: s("divider"), role: "separator" });
296
+ if (d.header) return t("div", { key: d.key, class: s("header") }, d.label);
297
+ const E = v.value.indexOf(d), D = L(s("item", { danger: d.danger }), { "is-highlighted": E === l.value, "is-disabled": d.disabled }), N = [P(d.icon), d.label];
298
+ return d.href ? t("a", { key: d.key, role: "menuitem", href: d.href, class: D, onClick: () => f(d) }, N) : t(
299
+ "button",
300
+ {
301
+ key: d.key,
302
+ role: "menuitem",
303
+ type: "button",
304
+ class: D,
305
+ disabled: d.disabled,
306
+ onClick: () => f(d),
307
+ onMouseenter: () => l.value = E
308
+ },
309
+ N
310
+ );
311
+ })
312
+ ]
313
+ ) : null
314
+ ]);
315
+ };
316
+ }
317
+ }), W = { success: "circle-check", info: "info", warning: "triangle-alert", error: "circle-x" }, se = /* @__PURE__ */ g({
318
+ name: "ThlToaster",
319
+ setup() {
320
+ const e = G(), r = J(e.toast.state), u = b(), { t: o } = x();
321
+ return () => t(
322
+ C,
323
+ { to: "body" },
324
+ Object.entries(e.toast.byPosition(r.value)).map(
325
+ ([n, l]) => t(
326
+ "div",
327
+ { key: n, class: p("toaster", u.value)({ [n]: !0 }), "aria-live": "polite" },
328
+ l.map((a) => {
329
+ const c = p("toast", u.value), i = a.icon ?? W[a.type];
330
+ return t("div", { key: a.id, role: a.type === "error" ? "alert" : "status", class: c({ [a.type]: !0 }) }, [
331
+ i ? t("span", { class: c("icon") }, P(i)) : null,
332
+ t("div", { class: c("body") }, [a.title ? t("div", { class: c("title") }, a.title) : null, t("div", { class: c("message") }, a.message)]),
333
+ a.closable ? t("button", { type: "button", class: c("close"), "aria-label": o("common.close"), onClick: () => e.toast.dismiss(a.id) }, "×") : null,
334
+ a.duration > 0 ? t("span", { class: c("progress"), style: { animationDuration: `${a.duration}ms` } }) : null
335
+ ]);
336
+ })
337
+ )
338
+ )
339
+ );
340
+ }
341
+ }), ie = /* @__PURE__ */ g({
342
+ name: "ThlProgress",
343
+ props: {
344
+ value: { type: Number, required: !0 },
345
+ max: { type: Number, default: 100 },
346
+ color: String,
347
+ size: String,
348
+ striped: { type: Boolean, default: void 0 },
349
+ animated: { type: Boolean, default: void 0 },
350
+ vertical: Boolean,
351
+ label: q()
352
+ },
353
+ setup(e) {
354
+ const r = b(), { t: u } = x(), o = $("Progress", e);
355
+ return () => {
356
+ const n = Math.max(0, Math.min(100, e.value / (e.max || 1) * 100)), l = p("progress", r.value), a = e.label === !0 ? `${Math.round(n)}%` : e.label || void 0;
357
+ return t(
358
+ "div",
359
+ {
360
+ role: "progressbar",
361
+ "aria-valuenow": e.value,
362
+ "aria-valuemin": 0,
363
+ "aria-valuemax": e.max,
364
+ "aria-label": typeof a == "string" ? a : u("layout.complete", { percent: Math.round(n) }),
365
+ class: l({
366
+ [e.color ?? "primary"]: !0,
367
+ size: o.value.size,
368
+ striped: o.value.striped || o.value.animated,
369
+ animated: o.value.animated,
370
+ vertical: e.vertical
371
+ })
372
+ },
373
+ t("div", { class: l("bar"), style: e.vertical ? { height: `${n}%` } : { width: `${n}%` } }, o.value.size === "lg" ? a : void 0)
374
+ );
375
+ };
376
+ }
377
+ }), ce = /* @__PURE__ */ g({
378
+ name: "ThlProgressCircle",
379
+ props: {
380
+ value: { type: Number, required: !0 },
381
+ max: { type: Number, default: 100 },
382
+ size: { type: Number, default: 120 },
383
+ stroke: { type: Number, default: 8 },
384
+ color: k("primary"),
385
+ label: String,
386
+ ariaLabel: String
387
+ },
388
+ setup(e, { slots: r }) {
389
+ const u = b(), { t: o } = x();
390
+ return () => {
391
+ const n = (e.size - e.stroke) / 2, l = 2 * Math.PI * n, a = Math.max(0, Math.min(1, e.value / e.max)), c = p("progress-circle", u.value);
392
+ return t(
393
+ "div",
394
+ {
395
+ class: c(),
396
+ role: "progressbar",
397
+ "aria-valuenow": e.value,
398
+ "aria-valuemin": 0,
399
+ "aria-valuemax": e.max,
400
+ "aria-label": e.ariaLabel ?? e.label ?? o("common.progress"),
401
+ style: { width: `${e.size}px`, height: `${e.size}px` }
402
+ },
403
+ [
404
+ t("svg", { width: e.size, height: e.size }, [
405
+ t("circle", { class: c("track"), cx: e.size / 2, cy: e.size / 2, r: n, fill: "none", "stroke-width": e.stroke }),
406
+ t("circle", {
407
+ class: c("value"),
408
+ cx: e.size / 2,
409
+ cy: e.size / 2,
410
+ r: n,
411
+ fill: "none",
412
+ stroke: `var(--${u.value}-color-${e.color})`,
413
+ "stroke-width": e.stroke,
414
+ "stroke-linecap": "round",
415
+ "stroke-dasharray": l,
416
+ "stroke-dashoffset": l * (1 - a)
417
+ })
418
+ ]),
419
+ t("span", { class: c("label") }, r.default ? r.default() : e.label ?? `${Math.round(a * 100)}%`)
420
+ ]
421
+ );
422
+ };
423
+ }
424
+ });
425
+ export {
426
+ oe as ThlConfirmHost,
427
+ le as ThlDrawer,
428
+ re as ThlDropdown,
429
+ Q as ThlModal,
430
+ ae as ThlPopover,
431
+ ie as ThlProgress,
432
+ ce as ThlProgressCircle,
433
+ se as ThlToaster,
434
+ ne as ThlTooltip,
435
+ te as confirm
436
+ };
437
+ //# sourceMappingURL=overlay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay.js","sources":["../../src/components/overlay.ts"],"sourcesContent":["import { defineComponent, h, ref, watch, onMounted, onBeforeUnmount, nextTick, Teleport, computed, shallowRef, cloneVNode } from 'vue';\nimport { bem, cx, focusTrap, scrollLock, clickOutside, computePosition, uid, type Placement, type ThlSemanticColor, type Toast } from '@thl-ui/core';\nimport { useDefaults, usePrefix, useI18n, useStore, useThlContext } from '../context';\nimport { icon, str, any } from './util';\nimport { ThlButton } from './basic';\n\n/* ---------------- Modal ---------------- */\nexport const ThlModal = /*#__PURE__*/ defineComponent({\n name: 'ThlModal',\n props: {\n open: Boolean,\n title: String,\n size: String,\n closeOnBackdrop: { type: Boolean, default: undefined },\n closeOnEsc: { type: Boolean, default: undefined },\n centered: { type: Boolean, default: undefined },\n scrollable: Boolean,\n hideClose: Boolean,\n modalClass: String,\n },\n emits: ['update:open', 'close'],\n setup(p, { slots, emit }) {\n const pre = usePrefix();\n const { t } = useI18n();\n const d = useDefaults('Modal', p as any);\n const el = ref<HTMLElement>();\n const titleId = uid('modal-title');\n let release: (() => void) | null = null,\n unlock: (() => void) | null = null;\n const close = () => {\n emit('update:open', false);\n emit('close');\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && d.value.closeOnEsc !== false) {\n e.stopPropagation();\n close();\n }\n };\n const teardown = () => {\n release?.();\n unlock?.();\n release = unlock = null;\n document.removeEventListener('keydown', onKey);\n };\n watch(\n () => p.open,\n async (o) => {\n if (o) {\n await nextTick();\n if (el.value) {\n release = focusTrap(el.value);\n unlock = scrollLock();\n document.addEventListener('keydown', onKey);\n }\n } else teardown();\n },\n { immediate: true },\n );\n onBeforeUnmount(teardown);\n return () => {\n if (!p.open) return null;\n const b = bem('modal', pre.value);\n return h(\n Teleport,\n { to: 'body' },\n h(\n 'div',\n {\n class: bem('modal-backdrop', pre.value)({ centered: d.value.centered }),\n onMousedown: (e: MouseEvent) => {\n if (e.target === e.currentTarget && d.value.closeOnBackdrop !== false) close();\n },\n },\n h(\n 'div',\n {\n ref: el,\n role: 'dialog',\n 'aria-modal': 'true',\n 'aria-labelledby': p.title ? titleId : undefined,\n tabindex: -1,\n class: cx(b({ [d.value.size ?? 'md']: !!d.value.size && d.value.size !== 'md', scrollable: p.scrollable }), p.modalClass),\n },\n [\n p.title || slots.title || !p.hideClose\n ? h('div', { class: b('header') }, [\n h('h2', { id: titleId, class: b('title') }, slots.title ? slots.title() : p.title),\n !p.hideClose ? h('button', { type: 'button', class: b('close'), 'aria-label': t('modal.close'), onClick: close }, '×') : null,\n ])\n : null,\n h('div', { class: b('body') }, slots.default?.()),\n slots.footer ? h('div', { class: b('footer') }, slots.footer({ close })) : null,\n ],\n ),\n ),\n );\n };\n },\n});\n\n/* ---------------- confirm() ---------------- */\nexport interface ConfirmOptions {\n title?: string;\n text?: string;\n icon?: 'warning' | 'danger' | 'success' | 'info' | 'question';\n confirmText?: string;\n cancelText?: string;\n confirmVariant?: ThlSemanticColor;\n showCancel?: boolean;\n}\nconst confirmState = shallowRef<(ConfirmOptions & { resolve: (v: boolean) => void }) | null>(null);\nlet hostMounted = 0;\nexport function confirm(opts: ConfirmOptions = {}): Promise<boolean> {\n return new Promise((resolve) => {\n if (!hostMounted) {\n resolve(typeof window !== 'undefined' ? window.confirm(opts.title ?? '') : false);\n return;\n }\n confirmState.value = { ...opts, resolve };\n });\n}\nexport const ThlConfirmHost = /*#__PURE__*/ defineComponent({\n name: 'ThlConfirmHost',\n setup() {\n const pre = usePrefix();\n const { t } = useI18n();\n onMounted(() => hostMounted++);\n onBeforeUnmount(() => hostMounted--);\n const done = (v: boolean) => {\n confirmState.value?.resolve(v);\n confirmState.value = null;\n };\n return () => {\n const s = confirmState.value;\n const ic = s?.icon ?? 'warning';\n const name = { warning: 'triangle-alert', danger: 'circle-x', success: 'check', info: 'info', question: 'circle-help' }[ic];\n return h(\n ThlModal,\n { open: !!s, hideClose: true, modalClass: `${pre.value}-modal--confirm`, 'onUpdate:open': (v: boolean) => !v && done(false) },\n {\n default: () => [\n h('div', { class: bem('modal', pre.value)('confirm-icon', { [ic]: true }) }, icon(name)),\n h('h2', s?.title ?? t('modal.confirmTitle')),\n h('p', s?.text ?? t('modal.confirmText')),\n ],\n footer: () => [\n s?.showCancel !== false ? h(ThlButton, { onClick: () => done(false) }, () => s?.cancelText ?? t('common.cancel')) : null,\n h(\n ThlButton,\n { variant: s?.confirmVariant ?? (ic === 'danger' || ic === 'warning' ? 'danger' : 'primary'), onClick: () => done(true), autofocus: true },\n () => s?.confirmText ?? t('common.ok'),\n ),\n ],\n },\n );\n };\n },\n});\n\n/* ---------------- Drawer ---------------- */\nexport const ThlDrawer = /*#__PURE__*/ defineComponent({\n name: 'ThlDrawer',\n props: { open: Boolean, title: String, side: str<'start' | 'end'>('end'), wide: Boolean },\n emits: ['update:open', 'close'],\n setup(p, { slots, emit }) {\n const pre = usePrefix();\n const { t } = useI18n();\n const el = ref<HTMLElement>();\n const close = () => {\n emit('update:open', false);\n emit('close');\n };\n const onKey = (e: KeyboardEvent) => e.key === 'Escape' && close();\n watch(\n () => p.open,\n (o) => {\n if (o) {\n document.addEventListener('keydown', onKey);\n nextTick(() => el.value?.focus());\n } else document.removeEventListener('keydown', onKey);\n },\n );\n onBeforeUnmount(() => document.removeEventListener('keydown', onKey));\n return () => {\n const b = bem('drawer', pre.value);\n return h(Teleport, { to: 'body' }, [\n p.open ? h('div', { class: `${pre.value}-drawer-backdrop`, onClick: close }) : null,\n h(\n 'aside',\n {\n ref: el,\n tabindex: -1,\n role: 'dialog',\n 'aria-modal': p.open,\n 'aria-hidden': !p.open,\n 'aria-label': p.title,\n inert: !p.open || undefined,\n class: cx(b({ start: p.side === 'start', wide: p.wide }), { 'is-open': p.open }),\n },\n [\n h('div', { class: b('header') }, [\n h('span', p.title),\n h('button', { type: 'button', class: b('close'), onClick: close, 'aria-label': t('common.close') }, '×'),\n ]),\n h('div', { class: b('body') }, slots.default?.()),\n ],\n ),\n ]);\n };\n },\n});\n\n/* ---------------- Tooltip / Popover (wrapper element as anchor) ---------------- */\nfunction useFloating(open: () => boolean, placement: () => Placement) {\n const anchor = ref<HTMLElement>();\n const float = ref<HTMLElement>();\n const style = ref<Record<string, string>>({ top: '-9999px', left: '-9999px' });\n const update = () => {\n if (!anchor.value || !float.value) return;\n const target = (anchor.value.firstElementChild as HTMLElement) ?? anchor.value;\n const f = float.value.getBoundingClientRect();\n const pos = computePosition(target.getBoundingClientRect(), { width: f.width, height: f.height }, placement());\n style.value = { top: `${pos.top}px`, left: `${pos.left}px` };\n };\n watch(open, async (o) => {\n if (o) {\n await nextTick();\n update();\n window.addEventListener('scroll', update, true);\n window.addEventListener('resize', update);\n } else {\n window.removeEventListener('scroll', update, true);\n window.removeEventListener('resize', update);\n style.value = { top: '-9999px', left: '-9999px' };\n }\n });\n onBeforeUnmount(() => {\n window.removeEventListener('scroll', update, true);\n window.removeEventListener('resize', update);\n });\n return { anchor, float, style };\n}\n\nexport const ThlTooltip = /*#__PURE__*/ defineComponent({\n name: 'ThlTooltip',\n props: { content: String, placement: str<Placement>('top'), color: String, delay: Number },\n setup(p, { slots }) {\n const pre = usePrefix();\n const d = useDefaults('Tooltip', p as any);\n const open = ref(false);\n const id = uid('tip');\n const { anchor, float, style } = useFloating(\n () => open.value,\n () => p.placement,\n );\n let timer: ReturnType<typeof setTimeout> | undefined;\n const show = () => {\n clearTimeout(timer);\n timer = setTimeout(() => (open.value = true), (d.value.delay as number) ?? 100);\n };\n const hide = () => {\n clearTimeout(timer);\n open.value = false;\n };\n return () => [\n h(\n 'span',\n {\n ref: anchor,\n style: { display: 'inline-flex' },\n onMouseenter: show,\n onMouseleave: hide,\n onFocusin: show,\n onFocusout: hide,\n 'aria-describedby': open.value ? id : undefined,\n },\n slots.default?.(),\n ),\n open.value\n ? h(\n Teleport,\n { to: 'body' },\n h(\n 'div',\n {\n ref: float,\n id,\n role: 'tooltip',\n class: bem('tooltip', pre.value)({ [p.color ?? '']: !!p.color }),\n style: { position: 'absolute', ...style.value },\n },\n slots.content ? slots.content() : p.content,\n ),\n )\n : null,\n ];\n },\n});\n\nexport const ThlPopover = /*#__PURE__*/ defineComponent({\n name: 'ThlPopover',\n props: { title: String, content: String, placement: str<Placement>('bottom'), color: String, trigger: str<'click' | 'hover'>('click') },\n setup(p, { slots }) {\n const pre = usePrefix();\n const open = ref(false);\n const id = uid('pop');\n const { anchor, float, style } = useFloating(\n () => open.value,\n () => p.placement,\n );\n let off: (() => void) | null = null;\n const onKey = (e: KeyboardEvent) => e.key === 'Escape' && (open.value = false);\n watch(open, async (o) => {\n off?.();\n off = null;\n document.removeEventListener('keydown', onKey);\n if (o && p.trigger === 'click') {\n await nextTick();\n off = clickOutside([anchor.value, float.value], () => (open.value = false));\n document.addEventListener('keydown', onKey);\n }\n });\n onBeforeUnmount(() => {\n off?.();\n document.removeEventListener('keydown', onKey);\n });\n return () => {\n const b = bem('popover', pre.value);\n const handlers =\n p.trigger === 'click'\n ? { onClick: () => (open.value = !open.value) }\n : {\n onMouseenter: () => (open.value = true),\n onMouseleave: () => (open.value = false),\n onFocusin: () => (open.value = true),\n onFocusout: () => (open.value = false),\n };\n return [\n h(\n 'span',\n { ref: anchor, style: { display: 'inline-flex' }, ...handlers },\n (slots.default?.() ?? []).map((v, i) =>\n i === 0 ? cloneVNode(v, { 'aria-haspopup': 'dialog', 'aria-expanded': String(open.value), 'aria-controls': open.value ? id : undefined }) : v,\n ),\n ),\n open.value\n ? h(\n Teleport,\n { to: 'body' },\n h('div', { ref: float, id, role: 'dialog', class: b({ [p.color ?? '']: !!p.color }), style: { position: 'absolute', ...style.value } }, [\n p.title ? h('div', { class: b('title') }, p.title) : null,\n h('div', { class: b('body') }, slots.content ? slots.content() : p.content),\n ]),\n )\n : null,\n ];\n };\n },\n});\n\n/* ---------------- Dropdown ---------------- */\nexport interface DropdownItem {\n key: string;\n label?: string;\n icon?: string;\n href?: string;\n disabled?: boolean;\n danger?: boolean;\n divider?: boolean;\n header?: boolean;\n}\nexport const ThlDropdown = /*#__PURE__*/ defineComponent({\n name: 'ThlDropdown',\n props: {\n items: any<DropdownItem[]>(),\n align: str<'start' | 'end'>('start'),\n placement: str<'top' | 'bottom'>('bottom'),\n menuClass: String,\n animation: String,\n },\n emits: ['select'],\n setup(p, { slots, emit }) {\n const pre = usePrefix();\n const open = ref(false);\n const hi = ref(-1);\n const root = ref<HTMLElement>();\n const menuId = uid('menu');\n let off: (() => void) | null = null;\n const close = () => {\n open.value = false;\n hi.value = -1;\n };\n const enabled = computed(() => (p.items ?? []).filter((i) => !i.divider && !i.header && !i.disabled));\n const choose = (it: DropdownItem) => {\n emit('select', it.key);\n close();\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n close();\n (root.value?.querySelector('[aria-haspopup=\"menu\"]') as HTMLElement)?.focus();\n }\n if (!p.items) return;\n const n = enabled.value.length;\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n hi.value = (hi.value + 1) % n;\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n hi.value = (hi.value - 1 + n) % n;\n }\n if (e.key === 'Enter' && hi.value >= 0) {\n e.preventDefault();\n choose(enabled.value[hi.value]);\n }\n };\n watch(open, (o) => {\n off?.();\n off = null;\n document.removeEventListener('keydown', onKey);\n if (o) {\n off = clickOutside([root.value], close);\n document.addEventListener('keydown', onKey);\n }\n });\n onBeforeUnmount(() => {\n off?.();\n document.removeEventListener('keydown', onKey);\n });\n return () => {\n const m = bem('menu', pre.value);\n return h('div', { ref: root, class: `${pre.value}-dropdown` }, [\n h(\n 'span',\n { style: { display: 'contents' }, onClick: () => (open.value = !open.value) },\n (slots.trigger?.({ open: open.value }) ?? []).map((v, i) =>\n i === 0 ? cloneVNode(v, { 'aria-haspopup': 'menu', 'aria-expanded': String(open.value), 'aria-controls': open.value ? menuId : undefined }) : v,\n ),\n ),\n open.value\n ? h(\n 'div',\n { id: menuId, role: 'menu', class: cx(m({ end: p.align === 'end', start: p.align === 'start', [p.placement]: true }), p.animation, p.menuClass) },\n [\n slots.default?.({ close }),\n ...(p.items ?? []).map((it) => {\n if (it.divider) return h('div', { key: it.key, class: m('divider'), role: 'separator' });\n if (it.header) return h('div', { key: it.key, class: m('header') }, it.label);\n const idx = enabled.value.indexOf(it);\n const cls = cx(m('item', { danger: it.danger }), { 'is-highlighted': idx === hi.value, 'is-disabled': it.disabled });\n const inner = [icon(it.icon), it.label];\n return it.href\n ? h('a', { key: it.key, role: 'menuitem', href: it.href, class: cls, onClick: () => choose(it) }, inner)\n : h(\n 'button',\n {\n key: it.key,\n role: 'menuitem',\n type: 'button',\n class: cls,\n disabled: it.disabled,\n onClick: () => choose(it),\n onMouseenter: () => (hi.value = idx),\n },\n inner,\n );\n }),\n ],\n )\n : null,\n ]);\n };\n },\n});\n\n/* ---------------- Toaster ---------------- */\nconst toastIcons: Record<string, string> = { success: 'circle-check', info: 'info', warning: 'triangle-alert', error: 'circle-x' };\nexport const ThlToaster = /*#__PURE__*/ defineComponent({\n name: 'ThlToaster',\n setup() {\n const ctx = useThlContext();\n const list = useStore(ctx.toast.state);\n const pre = usePrefix();\n const { t } = useI18n();\n return () =>\n h(\n Teleport,\n { to: 'body' },\n Object.entries(ctx.toast.byPosition(list.value)).map(([pos, items]) =>\n h(\n 'div',\n { key: pos, class: bem('toaster', pre.value)({ [pos]: true }), 'aria-live': 'polite' },\n items.map((it: Toast) => {\n const b = bem('toast', pre.value);\n const ic = it.icon ?? toastIcons[it.type];\n return h('div', { key: it.id, role: it.type === 'error' ? 'alert' : 'status', class: b({ [it.type]: true }) }, [\n ic ? h('span', { class: b('icon') }, icon(ic)) : null,\n h('div', { class: b('body') }, [it.title ? h('div', { class: b('title') }, it.title) : null, h('div', { class: b('message') }, it.message)]),\n it.closable\n ? h('button', { type: 'button', class: b('close'), 'aria-label': t('common.close'), onClick: () => ctx.toast.dismiss(it.id) }, '×')\n : null,\n it.duration > 0 ? h('span', { class: b('progress'), style: { animationDuration: `${it.duration}ms` } }) : null,\n ]);\n }),\n ),\n ),\n );\n },\n});\n\n/* ---------------- Progress ---------------- */\nexport const ThlProgress = /*#__PURE__*/ defineComponent({\n name: 'ThlProgress',\n props: {\n value: { type: Number, required: true },\n max: { type: Number, default: 100 },\n color: String,\n size: String,\n striped: { type: Boolean, default: undefined },\n animated: { type: Boolean, default: undefined },\n vertical: Boolean,\n label: any<boolean | string>(),\n },\n setup(p) {\n const pre = usePrefix();\n const { t } = useI18n();\n const d = useDefaults('Progress', p as any);\n return () => {\n const pct = Math.max(0, Math.min(100, (p.value / (p.max || 1)) * 100));\n const b = bem('progress', pre.value);\n const text = p.label === true ? `${Math.round(pct)}%` : p.label || undefined;\n return h(\n 'div',\n {\n role: 'progressbar',\n 'aria-valuenow': p.value,\n 'aria-valuemin': 0,\n 'aria-valuemax': p.max,\n 'aria-label': typeof text === 'string' ? text : t('layout.complete', { percent: Math.round(pct) }),\n class: b({\n [p.color ?? 'primary']: true,\n size: d.value.size,\n striped: d.value.striped || d.value.animated,\n animated: d.value.animated,\n vertical: p.vertical,\n }),\n },\n h('div', { class: b('bar'), style: p.vertical ? { height: `${pct}%` } : { width: `${pct}%` } }, d.value.size === 'lg' ? text : undefined),\n );\n };\n },\n});\nexport const ThlProgressCircle = /*#__PURE__*/ defineComponent({\n name: 'ThlProgressCircle',\n props: {\n value: { type: Number, required: true },\n max: { type: Number, default: 100 },\n size: { type: Number, default: 120 },\n stroke: { type: Number, default: 8 },\n color: str('primary'),\n label: String,\n ariaLabel: String,\n },\n setup(p, { slots }) {\n const pre = usePrefix();\n const { t } = useI18n();\n return () => {\n const r = (p.size - p.stroke) / 2,\n c = 2 * Math.PI * r,\n pct = Math.max(0, Math.min(1, p.value / p.max));\n const b = bem('progress-circle', pre.value);\n return h(\n 'div',\n {\n class: b(),\n role: 'progressbar',\n 'aria-valuenow': p.value,\n 'aria-valuemin': 0,\n 'aria-valuemax': p.max,\n 'aria-label': p.ariaLabel ?? p.label ?? t('common.progress'),\n style: { width: `${p.size}px`, height: `${p.size}px` },\n },\n [\n h('svg', { width: p.size, height: p.size }, [\n h('circle', { class: b('track'), cx: p.size / 2, cy: p.size / 2, r, fill: 'none', 'stroke-width': p.stroke }),\n h('circle', {\n class: b('value'),\n cx: p.size / 2,\n cy: p.size / 2,\n r,\n fill: 'none',\n stroke: `var(--${pre.value}-color-${p.color})`,\n 'stroke-width': p.stroke,\n 'stroke-linecap': 'round',\n 'stroke-dasharray': c,\n 'stroke-dashoffset': c * (1 - pct),\n }),\n ]),\n h('span', { class: b('label') }, slots.default ? slots.default() : (p.label ?? `${Math.round(pct * 100)}%`)),\n ],\n );\n };\n },\n});\n"],"names":["ThlModal","defineComponent","p","slots","emit","pre","usePrefix","t","useI18n","d","useDefaults","el","ref","titleId","uid","release","unlock","close","onKey","e","teardown","watch","o","nextTick","focusTrap","scrollLock","onBeforeUnmount","b","bem","h","Teleport","cx","confirmState","shallowRef","hostMounted","confirm","opts","resolve","ThlConfirmHost","onMounted","done","v","s","ic","name","icon","ThlButton","ThlDrawer","str","useFloating","open","placement","anchor","float","style","update","target","f","pos","computePosition","ThlTooltip","id","timer","show","hide","ThlPopover","off","clickOutside","handlers","i","cloneVNode","ThlDropdown","any","hi","root","menuId","enabled","computed","choose","it","n","m","idx","cls","inner","toastIcons","ThlToaster","ctx","useThlContext","list","useStore","items","ThlProgress","pct","text","ThlProgressCircle","r","c"],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { PropType, VNode, Slots } from 'vue';
2
+ export declare const str: <T extends string = string>(def?: NoInfer<T>) => {
3
+ type: PropType<T>;
4
+ default: T;
5
+ };
6
+ export declare const bool: (def?: boolean) => {
7
+ type: BooleanConstructor;
8
+ default: boolean | undefined;
9
+ };
10
+ export declare const num: (def?: number) => {
11
+ type: NumberConstructor;
12
+ default: number | undefined;
13
+ };
14
+ export declare const any: <T>() => {
15
+ type: PropType<T>;
16
+ required: false;
17
+ };
18
+ /** Render an icon by name as a VNode. */
19
+ export declare function icon(name: string | undefined, opts?: {
20
+ size?: number | string;
21
+ class?: string;
22
+ label?: string;
23
+ strokeWidth?: number;
24
+ }): VNode | undefined;
25
+ /** Slot or prop content */
26
+ export declare const slotOr: (slots: Slots, name: string, fallback?: unknown, args?: unknown) => {} | null;
@@ -0,0 +1,35 @@
1
+ import { h as n } from "vue";
2
+ import { resolveIcon as u } from "@thl-ui/icons";
3
+ import { cx as t } from "@thl-ui/core";
4
+ const v = (r) => ({ type: String, default: r }), g = (r) => ({ type: Boolean, default: r }), h = () => ({ type: null, required: !1 });
5
+ function w(r, i = {}) {
6
+ if (!r) return;
7
+ const e = u(r);
8
+ if (!e) return;
9
+ if ("className" in e) return n("i", { class: t(e.className, i.class), "aria-hidden": "true" });
10
+ const o = i.size ?? "1em", l = i.label ? { role: "img", "aria-label": i.label } : { "aria-hidden": "true", focusable: "false" }, s = {
11
+ xmlns: "http://www.w3.org/2000/svg",
12
+ width: o,
13
+ height: o,
14
+ viewBox: "svg" in e ? e.viewBox ?? "0 0 24 24" : "0 0 24 24",
15
+ fill: "none",
16
+ stroke: "currentColor",
17
+ "stroke-width": i.strokeWidth ?? 2,
18
+ "stroke-linecap": "round",
19
+ "stroke-linejoin": "round",
20
+ class: t("thl-icon", i.class),
21
+ ...l
22
+ };
23
+ return "svg" in e ? n("svg", { ...s, innerHTML: e.svg }) : n(
24
+ "svg",
25
+ s,
26
+ e.map(([a, c]) => n(a, c))
27
+ );
28
+ }
29
+ export {
30
+ h as any,
31
+ g as bool,
32
+ w as icon,
33
+ v as str
34
+ };
35
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sources":["../../src/components/util.ts"],"sourcesContent":["import { h, type PropType, type VNode, type Slots } from 'vue';\nimport { resolveIcon, type IconNode } from '@thl-ui/icons';\nimport { cx } from '@thl-ui/core';\n\nexport const str = <T extends string = string>(def?: NoInfer<T>) => ({ type: String as unknown as PropType<T>, default: def as T });\nexport const bool = (def?: boolean) => ({ type: Boolean, default: def });\nexport const num = (def?: number) => ({ type: Number, default: def });\nexport const any = <T>() => ({ type: null as unknown as PropType<T>, required: false as const });\n\n/** Render an icon by name as a VNode. */\nexport function icon(name: string | undefined, opts: { size?: number | string; class?: string; label?: string; strokeWidth?: number } = {}): VNode | undefined {\n if (!name) return undefined;\n const def = resolveIcon(name);\n if (!def) return undefined;\n if ('className' in def) return h('i', { class: cx(def.className, opts.class), 'aria-hidden': 'true' });\n const size = opts.size ?? '1em';\n const a11y = opts.label ? { role: 'img', 'aria-label': opts.label } : { 'aria-hidden': 'true', focusable: 'false' };\n const base = {\n xmlns: 'http://www.w3.org/2000/svg',\n width: size,\n height: size,\n viewBox: 'svg' in def ? (def.viewBox ?? '0 0 24 24') : '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n 'stroke-width': opts.strokeWidth ?? 2,\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n class: cx('thl-icon', opts.class),\n ...a11y,\n };\n if ('svg' in def) return h('svg', { ...base, innerHTML: def.svg });\n return h(\n 'svg',\n base,\n (def as IconNode).map(([tag, attrs]) => h(tag, attrs)),\n );\n}\n\n/** Slot or prop content */\nexport const slotOr = (slots: Slots, name: string, fallback?: unknown, args?: unknown) => (slots[name] ? slots[name]!(args) : (fallback ?? null));\n"],"names":["str","def","bool","any","icon","name","opts","resolveIcon","h","cx","size","a11y","base","tag","attrs"],"mappings":";;;AAIO,MAAMA,IAAM,CAA4BC,OAAsB,EAAE,MAAM,QAAkC,SAASA,EAAA,IAC3GC,IAAO,CAACD,OAAmB,EAAE,MAAM,SAAS,SAASA,EAAA,IAErDE,IAAM,OAAU,EAAE,MAAM,MAAgC,UAAU,GAAA;AAGxE,SAASC,EAAKC,GAA0BC,IAAyF,IAAuB;AAC7J,MAAI,CAACD,EAAM;AACX,QAAMJ,IAAMM,EAAYF,CAAI;AAC5B,MAAI,CAACJ,EAAK;AACV,MAAI,eAAeA,EAAK,QAAOO,EAAE,KAAK,EAAE,OAAOC,EAAGR,EAAI,WAAWK,EAAK,KAAK,GAAG,eAAe,QAAQ;AACrG,QAAMI,IAAOJ,EAAK,QAAQ,OACpBK,IAAOL,EAAK,QAAQ,EAAE,MAAM,OAAO,cAAcA,EAAK,MAAA,IAAU,EAAE,eAAe,QAAQ,WAAW,QAAA,GACpGM,IAAO;AAAA,IACX,OAAO;AAAA,IACP,OAAOF;AAAA,IACP,QAAQA;AAAA,IACR,SAAS,SAAST,IAAOA,EAAI,WAAW,cAAe;AAAA,IACvD,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,gBAAgBK,EAAK,eAAe;AAAA,IACpC,kBAAkB;AAAA,IAClB,mBAAmB;AAAA,IACnB,OAAOG,EAAG,YAAYH,EAAK,KAAK;AAAA,IAChC,GAAGK;AAAA,EAAA;AAEL,SAAI,SAASV,IAAYO,EAAE,OAAO,EAAE,GAAGI,GAAM,WAAWX,EAAI,KAAK,IAC1DO;AAAA,IACL;AAAA,IACAI;AAAA,IACCX,EAAiB,IAAI,CAAC,CAACY,GAAKC,CAAK,MAAMN,EAAEK,GAAKC,CAAK,CAAC;AAAA,EAAA;AAEzD;"}
@@ -0,0 +1,47 @@
1
+ import { App, InjectionKey, Ref, ComputedRef } from 'vue';
2
+ import { ThlInstance, ThlUserConfig, ThlConfig, Store, ToastManager, ThlComponentDefaults, TParams } from '@thl-ui/core';
3
+ import { IconRegistry } from '@thl-ui/icons';
4
+ export interface ThlContext {
5
+ thl: ThlInstance;
6
+ toast: ToastManager;
7
+ config: Ref<ThlConfig>;
8
+ locale: Ref<string>;
9
+ rev: Ref<number>;
10
+ }
11
+ export declare const THL_KEY: InjectionKey<ThlContext>;
12
+ /** Bridge a core Store to a Vue ref (auto-unsubscribes with the current effect scope). */
13
+ export declare function useStore<T>(store: Store<T>): Ref<T>;
14
+ export declare function createContext(user?: ThlUserConfig & {
15
+ icons?: IconRegistry;
16
+ }, instance?: ThlInstance): ThlContext;
17
+ export declare function useThlContext(): ThlContext;
18
+ /** Vue plugin: app.use(ThlUI, config). Exposes $t and $thl globally. */
19
+ export declare const ThlUI: {
20
+ install(app: App, options?: ThlUserConfig & {
21
+ icons?: IconRegistry;
22
+ instance?: ThlInstance;
23
+ components?: any;
24
+ }): void;
25
+ };
26
+ export declare const createThlUI: (options?: Parameters<typeof ThlUI.install>[1]) => {
27
+ install: (app: App) => void;
28
+ };
29
+ export declare function useThl(): ThlInstance;
30
+ export declare function useThlConfig(): {
31
+ config: Ref<ThlConfig, ThlConfig>;
32
+ set: (patch: Partial<ThlConfig> | ((c: ThlConfig) => Partial<ThlConfig>)) => void;
33
+ };
34
+ export declare function usePrefix(): ComputedRef<string>;
35
+ /** Reactive translator: tracks locale + message revision so templates re-render. */
36
+ export declare function useI18n(): {
37
+ t: (key: string, params?: TParams) => string;
38
+ te: (k: string) => boolean;
39
+ n: (v: number, o?: Intl.NumberFormatOptions) => string;
40
+ d: (v: Date | number | string, o?: Intl.DateTimeFormatOptions) => string;
41
+ locale: Ref<string, string>;
42
+ setLocale: (l: string) => void;
43
+ intlLocale: () => string;
44
+ i18n: import('@thl-ui/core').I18n;
45
+ };
46
+ export declare function useDefaults<K extends keyof ThlComponentDefaults>(name: K, props: Record<string, unknown>): ComputedRef<NonNullable<ThlComponentDefaults[K]>>;
47
+ export declare function useToast(): ToastManager;