@treeui/vue 0.19.1 → 0.21.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.
- package/dist/components/TAppShell.cjs.map +1 -1
- package/dist/components/TAppShell.js.map +1 -1
- package/dist/components/TAppShell.vue.d.ts +5 -1
- package/dist/components/TAppShell.vue.d.ts.map +1 -1
- package/dist/components/TAppShell.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TAppShell.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TAppShell.vue_vue_type_script_setup_true_lang.js +51 -44
- package/dist/components/TAppShell.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TBrandLockup.cjs +2 -0
- package/dist/components/TBrandLockup.cjs.map +1 -0
- package/dist/components/TBrandLockup.js +7 -0
- package/dist/components/TBrandLockup.js.map +1 -0
- package/dist/components/TBrandLockup.vue.d.ts +43 -0
- package/dist/components/TBrandLockup.vue.d.ts.map +1 -0
- package/dist/components/TBrandLockup.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TBrandLockup.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TBrandLockup.vue_vue_type_script_setup_true_lang.js +54 -0
- package/dist/components/TBrandLockup.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TButton.cjs.map +1 -1
- package/dist/components/TButton.js.map +1 -1
- package/dist/components/TButton.vue.d.ts.map +1 -1
- package/dist/components/TButton.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TButton.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TButton.vue_vue_type_script_setup_true_lang.js +36 -32
- package/dist/components/TButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TCard.cjs.map +1 -1
- package/dist/components/TCard.js.map +1 -1
- package/dist/components/TCard.vue.d.ts +8 -0
- package/dist/components/TCard.vue.d.ts.map +1 -1
- package/dist/components/TCard.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TCard.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TCard.vue_vue_type_script_setup_true_lang.js +7 -2
- package/dist/components/TCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TCheckbox.vue.d.ts +1 -1
- package/dist/components/TCheckbox.vue.d.ts.map +1 -1
- package/dist/components/TCodeBlock.cjs +2 -0
- package/dist/components/TCodeBlock.cjs.map +1 -0
- package/dist/components/TCodeBlock.js +7 -0
- package/dist/components/TCodeBlock.js.map +1 -0
- package/dist/components/TCodeBlock.vue.d.ts +47 -0
- package/dist/components/TCodeBlock.vue.d.ts.map +1 -0
- package/dist/components/TCodeBlock.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TCodeBlock.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TCodeBlock.vue_vue_type_script_setup_true_lang.js +53 -0
- package/dist/components/TCodeBlock.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TCombobox.vue.d.ts +2 -2
- package/dist/components/TCombobox.vue.d.ts.map +1 -1
- package/dist/components/TConfirmDialog.vue.d.ts +2 -2
- package/dist/components/TDatePicker.vue.d.ts +2 -2
- package/dist/components/TDatePicker.vue.d.ts.map +1 -1
- package/dist/components/TDateTimePicker.vue.d.ts +4 -4
- package/dist/components/TDateTimePicker.vue.d.ts.map +1 -1
- package/dist/components/TFileUpload.vue.d.ts +1 -1
- package/dist/components/TFileUpload.vue.d.ts.map +1 -1
- package/dist/components/TGrid.vue.d.ts +1 -1
- package/dist/components/TGrid.vue.d.ts.map +1 -1
- package/dist/components/TInput.vue.d.ts +1 -1
- package/dist/components/TInput.vue.d.ts.map +1 -1
- package/dist/components/TLanguageSelect.vue.d.ts +2 -2
- package/dist/components/TLanguageSelect.vue.d.ts.map +1 -1
- package/dist/components/TLanguageSelect.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TLanguageSelect.vue_vue_type_script_setup_true_lang.js +15 -15
- package/dist/components/TLink.cjs.map +1 -1
- package/dist/components/TLink.js.map +1 -1
- package/dist/components/TLink.vue.d.ts +8 -0
- package/dist/components/TLink.vue.d.ts.map +1 -1
- package/dist/components/TLink.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TLink.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TLink.vue_vue_type_script_setup_true_lang.js +5 -1
- package/dist/components/TLink.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TLinkTile.cjs +2 -0
- package/dist/components/TLinkTile.cjs.map +1 -0
- package/dist/components/TLinkTile.js +7 -0
- package/dist/components/TLinkTile.js.map +1 -0
- package/dist/components/TLinkTile.vue.d.ts +41 -0
- package/dist/components/TLinkTile.vue.d.ts.map +1 -0
- package/dist/components/TLinkTile.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TLinkTile.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TLinkTile.vue_vue_type_script_setup_true_lang.js +62 -0
- package/dist/components/TLinkTile.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TMultiSelect.vue.d.ts +2 -2
- package/dist/components/TMultiSelect.vue.d.ts.map +1 -1
- package/dist/components/TNavMenu.vue.d.ts +1 -1
- package/dist/components/TNavMenu.vue.d.ts.map +1 -1
- package/dist/components/TNumberInput.vue.d.ts +1 -1
- package/dist/components/TNumberInput.vue.d.ts.map +1 -1
- package/dist/components/TPage.vue.d.ts +1 -1
- package/dist/components/TPage.vue.d.ts.map +1 -1
- package/dist/components/TPageHeader.vue.d.ts +1 -1
- package/dist/components/TPageHeader.vue.d.ts.map +1 -1
- package/dist/components/TPopover.cjs.map +1 -1
- package/dist/components/TPopover.js.map +1 -1
- package/dist/components/TPopover.vue.d.ts +4 -1
- package/dist/components/TPopover.vue.d.ts.map +1 -1
- package/dist/components/TPopover.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TPopover.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TPopover.vue_vue_type_script_setup_true_lang.js +3 -1
- package/dist/components/TPopover.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TRadioGroup.vue.d.ts +1 -1
- package/dist/components/TRadioGroup.vue.d.ts.map +1 -1
- package/dist/components/TSelect.vue.d.ts +2 -2
- package/dist/components/TSelect.vue.d.ts.map +1 -1
- package/dist/components/TSidebar.vue.d.ts +1 -1
- package/dist/components/TSidebar.vue.d.ts.map +1 -1
- package/dist/components/TSparkline.vue.d.ts +1 -1
- package/dist/components/TSparkline.vue.d.ts.map +1 -1
- package/dist/components/TSplit.vue.d.ts +1 -1
- package/dist/components/TSplit.vue.d.ts.map +1 -1
- package/dist/components/TStack.cjs.map +1 -1
- package/dist/components/TStack.js.map +1 -1
- package/dist/components/TStack.vue.d.ts +11 -2
- package/dist/components/TStack.vue.d.ts.map +1 -1
- package/dist/components/TStack.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TStack.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TStack.vue_vue_type_script_setup_true_lang.js +3 -1
- package/dist/components/TStack.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TSteps.vue.d.ts +1 -1
- package/dist/components/TSteps.vue.d.ts.map +1 -1
- package/dist/components/TTable.cjs.map +1 -1
- package/dist/components/TTable.js.map +1 -1
- package/dist/components/TTable.vue.d.ts +16 -0
- package/dist/components/TTable.vue.d.ts.map +1 -1
- package/dist/components/TTable.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TTable.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TTable.vue_vue_type_script_setup_true_lang.js +29 -9
- package/dist/components/TTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TText.cjs.map +1 -1
- package/dist/components/TText.js.map +1 -1
- package/dist/components/TText.vue.d.ts +9 -0
- package/dist/components/TText.vue.d.ts.map +1 -1
- package/dist/components/TText.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TText.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TText.vue_vue_type_script_setup_true_lang.js +2 -0
- package/dist/components/TText.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TTextarea.vue.d.ts +1 -1
- package/dist/components/TTextarea.vue.d.ts.map +1 -1
- package/dist/components/index.d.ts +8 -4
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +74 -71
- package/dist/index.cjs +1 -1
- package/dist/index.js +84 -81
- package/dist/plugin.cjs +1 -1
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +148 -142
- package/dist/plugin.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +3 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useControllableOpen as e } from "../composables/useControllableOpen.js";
|
|
2
2
|
import { treeSidebarInjectionKey as t } from "./sidebar.js";
|
|
3
3
|
import { Transition as n, computed as r, createBlock as i, createCommentVNode as a, createElementBlock as o, createElementVNode as s, createVNode as c, defineComponent as l, guardReactiveProps as u, mergeProps as d, nextTick as f, normalizeClass as ee, normalizeProps as p, onBeforeUnmount as te, onMounted as ne, openBlock as m, provide as re, ref as h, renderSlot as g, resolveDynamicComponent as ie, toRef as _, unref as v, useAttrs as ae, watch as y, withCtx as b } from "vue";
|
|
4
|
-
import { createId as oe, focusFirst as x, focusLast as
|
|
4
|
+
import { createId as oe, focusFirst as x, focusLast as S, getFocusableElements as se, isEscapeKey as ce } from "@treeui/utils";
|
|
5
5
|
import { getTreeIcon as C, treeIconDefaults as w } from "@treeui/icons";
|
|
6
6
|
//#region src/components/TAppShell.vue?vue&type=script&setup=true&lang.ts
|
|
7
7
|
var le = [
|
|
@@ -11,23 +11,26 @@ var le = [
|
|
|
11
11
|
], ue = {
|
|
12
12
|
key: 1,
|
|
13
13
|
class: "t-app-shell__header-start"
|
|
14
|
-
}, de = { class: "t-app-shell__header-content" }, fe =
|
|
14
|
+
}, de = { class: "t-app-shell__header-content" }, fe = {
|
|
15
|
+
key: 2,
|
|
16
|
+
class: "t-app-shell__header-end"
|
|
17
|
+
}, pe = ["id", "aria-label"], me = {
|
|
15
18
|
key: 0,
|
|
16
19
|
class: "t-app-shell__sidebar-header"
|
|
17
|
-
},
|
|
20
|
+
}, he = { class: "t-app-shell__sidebar-body" }, ge = {
|
|
18
21
|
key: 1,
|
|
19
22
|
class: "t-app-shell__sidebar-footer"
|
|
20
|
-
},
|
|
23
|
+
}, _e = [
|
|
21
24
|
"aria-label",
|
|
22
25
|
"aria-expanded",
|
|
23
26
|
"aria-controls"
|
|
24
|
-
],
|
|
27
|
+
], ve = { class: "t-app-shell__main" }, ye = {
|
|
25
28
|
key: 0,
|
|
26
29
|
class: "t-app-shell__overlay"
|
|
27
|
-
},
|
|
30
|
+
}, be = ["id", "aria-label"], xe = { class: "t-app-shell__drawer-topbar" }, Se = ["aria-label"], Ce = { class: "t-app-shell__drawer-body" }, we = {
|
|
28
31
|
key: 0,
|
|
29
32
|
class: "t-app-shell__sidebar-header"
|
|
30
|
-
},
|
|
33
|
+
}, Te = { class: "t-app-shell__sidebar-body" }, Ee = {
|
|
31
34
|
key: 1,
|
|
32
35
|
class: "t-app-shell__sidebar-footer"
|
|
33
36
|
}, T = /*@__PURE__*/ l({
|
|
@@ -102,21 +105,21 @@ var le = [
|
|
|
102
105
|
"immersive-change"
|
|
103
106
|
],
|
|
104
107
|
setup(l, { emit: T }) {
|
|
105
|
-
let
|
|
108
|
+
let De = r(() => C("x")), Oe = r(() => C("menu")), E = l, D = T, O = ae(), k = oe("t-app-shell-sidebar"), { value: A, setValue: ke } = e(_(E, "collapsed"), E.defaultCollapsed, (e) => {
|
|
106
109
|
D("update:collapsed", e), D("collapse-change", e);
|
|
107
110
|
}), { value: j, setValue: M } = e(_(E, "sidebarOpen"), E.defaultSidebarOpen, (e) => {
|
|
108
111
|
D("update:sidebarOpen", e), D("sidebar-open-change", e);
|
|
109
|
-
}), { value: N, setValue:
|
|
112
|
+
}), { value: N, setValue: Ae } = e(_(E, "immersive"), E.defaultImmersive, (e) => {
|
|
110
113
|
D("update:immersive", e), D("immersive-change", e);
|
|
111
114
|
}), P = () => {
|
|
112
|
-
|
|
115
|
+
Ae(!N.value);
|
|
113
116
|
}, F = h(!1), I = null, L = (e) => {
|
|
114
117
|
F.value = e.matches;
|
|
115
118
|
}, R = () => {
|
|
116
119
|
typeof window > "u" || typeof window.matchMedia != "function" || (z(), I = window.matchMedia(`(max-width: ${E.breakpoint})`), F.value = I.matches, I.addEventListener?.("change", L));
|
|
117
120
|
}, z = () => {
|
|
118
121
|
I?.removeEventListener?.("change", L), I = null;
|
|
119
|
-
}, B = r(() => E.mobile ?? F.value), V = r(() => !B.value && E.collapsible && E.showCollapseButton), H = r(() => !B.value && A.value),
|
|
122
|
+
}, B = r(() => E.mobile ?? F.value), V = r(() => !B.value && E.collapsible && E.showCollapseButton), H = r(() => !B.value && A.value), je = r(() => C((E.side === "right" ? H.value : !H.value) ? "panel-left" : "panel-right")), U = h(null), W = h(null), G = "", K = !1, q = () => {
|
|
120
123
|
typeof document > "u" || K || (G = document.body.style.overflow, document.body.style.overflow = "hidden", K = !0);
|
|
121
124
|
}, J = () => {
|
|
122
125
|
typeof document > "u" || !K || (document.body.style.overflow = G, K = !1);
|
|
@@ -124,30 +127,30 @@ var le = [
|
|
|
124
127
|
f(() => {
|
|
125
128
|
U.value && (x(U.value) || U.value.focus());
|
|
126
129
|
});
|
|
127
|
-
},
|
|
130
|
+
}, Me = () => {
|
|
128
131
|
W.value = typeof document > "u" ? null : document.activeElement, M(!0);
|
|
129
132
|
}, X = () => {
|
|
130
133
|
M(!1);
|
|
131
134
|
}, Z = () => {
|
|
132
|
-
j.value ? X() :
|
|
135
|
+
j.value ? X() : Me();
|
|
133
136
|
}, Q = () => {
|
|
134
|
-
E.collapsible &&
|
|
135
|
-
},
|
|
137
|
+
E.collapsible && ke(!A.value);
|
|
138
|
+
}, Ne = () => {
|
|
136
139
|
E.closeOnOverlay && X();
|
|
137
|
-
},
|
|
140
|
+
}, Pe = (e) => {
|
|
138
141
|
if (ce(e) && E.closeOnEscape) {
|
|
139
142
|
e.preventDefault(), X();
|
|
140
143
|
return;
|
|
141
144
|
}
|
|
142
145
|
if (e.key !== "Tab" || !U.value) return;
|
|
143
|
-
let t =
|
|
146
|
+
let t = se(U.value);
|
|
144
147
|
if (!t.length) {
|
|
145
148
|
e.preventDefault(), U.value.focus();
|
|
146
149
|
return;
|
|
147
150
|
}
|
|
148
151
|
let n = t[0], r = t[t.length - 1], i = document.activeElement;
|
|
149
|
-
e.shiftKey && i === n && (e.preventDefault(),
|
|
150
|
-
},
|
|
152
|
+
e.shiftKey && i === n && (e.preventDefault(), S(U.value)), !e.shiftKey && i === r && (e.preventDefault(), x(U.value));
|
|
153
|
+
}, Fe = (e, t) => {
|
|
151
154
|
if (e && B.value) {
|
|
152
155
|
q(), Y();
|
|
153
156
|
return;
|
|
@@ -157,7 +160,7 @@ var le = [
|
|
|
157
160
|
}));
|
|
158
161
|
};
|
|
159
162
|
y(j, (e, t) => {
|
|
160
|
-
|
|
163
|
+
Fe(e, !!t);
|
|
161
164
|
}), y(N, (e) => {
|
|
162
165
|
!j.value || !B.value || (e ? (J(), f(() => {
|
|
163
166
|
W.value?.focus();
|
|
@@ -171,7 +174,7 @@ var le = [
|
|
|
171
174
|
}), te(() => {
|
|
172
175
|
z(), J();
|
|
173
176
|
}), re(t, { collapsed: H });
|
|
174
|
-
let
|
|
177
|
+
let Ie = r(() => [
|
|
175
178
|
"t-app-shell",
|
|
176
179
|
`t-app-shell--${E.side}`,
|
|
177
180
|
{
|
|
@@ -181,10 +184,10 @@ var le = [
|
|
|
181
184
|
"is-immersive": N.value
|
|
182
185
|
},
|
|
183
186
|
O.class
|
|
184
|
-
]),
|
|
187
|
+
]), Le = r(() => [{
|
|
185
188
|
"--tree-app-shell-sidebar-width": E.sidebarWidth,
|
|
186
189
|
"--tree-app-shell-collapsed-width": E.collapsedWidth
|
|
187
|
-
}, O.style]),
|
|
190
|
+
}, O.style]), Re = r(() => {
|
|
188
191
|
let { class: e, style: t, ...n } = O;
|
|
189
192
|
return n;
|
|
190
193
|
}), $ = r(() => ({
|
|
@@ -197,13 +200,16 @@ var le = [
|
|
|
197
200
|
toggleCollapsed: Q,
|
|
198
201
|
toggleImmersive: P
|
|
199
202
|
}));
|
|
200
|
-
return (e, t) => (m(), i(ie(l.as), d(
|
|
201
|
-
class:
|
|
202
|
-
style:
|
|
203
|
+
return (e, t) => (m(), i(ie(l.as), d(Re.value, {
|
|
204
|
+
class: Ie.value,
|
|
205
|
+
style: Le.value,
|
|
203
206
|
"data-mobile": B.value ? "true" : "false"
|
|
204
207
|
}), {
|
|
205
208
|
default: b(() => [
|
|
206
|
-
s("header", { class: ee(["t-app-shell__header", {
|
|
209
|
+
s("header", { class: ee(["t-app-shell__header", {
|
|
210
|
+
"has-start": !!e.$slots["header-start"],
|
|
211
|
+
"has-end": !!e.$slots["header-end"]
|
|
212
|
+
}]) }, [
|
|
207
213
|
B.value && l.showMenuButton ? (m(), o("button", {
|
|
208
214
|
key: 0,
|
|
209
215
|
type: "button",
|
|
@@ -212,12 +218,13 @@ var le = [
|
|
|
212
218
|
"aria-expanded": v(j),
|
|
213
219
|
"aria-controls": v(k),
|
|
214
220
|
onClick: Z
|
|
215
|
-
}, [g(e.$slots, "menu-icon", { sidebarOpen: v(j) }, () => [c(v(
|
|
221
|
+
}, [g(e.$slots, "menu-icon", { sidebarOpen: v(j) }, () => [c(v(Oe), d(v(w), {
|
|
216
222
|
size: 24,
|
|
217
223
|
"aria-hidden": "true"
|
|
218
224
|
}), null, 16)])], 8, le)) : a("", !0),
|
|
219
225
|
e.$slots["header-start"] ? (m(), o("div", ue, [g(e.$slots, "header-start", p(u($.value)))])) : a("", !0),
|
|
220
|
-
s("div", de, [g(e.$slots, "header", p(u($.value)))])
|
|
226
|
+
s("div", de, [g(e.$slots, "header", p(u($.value)))]),
|
|
227
|
+
e.$slots["header-end"] ? (m(), o("div", fe, [g(e.$slots, "header-end", p(u($.value)))])) : a("", !0)
|
|
221
228
|
], 2),
|
|
222
229
|
B.value ? a("", !0) : (m(), o("aside", {
|
|
223
230
|
key: 0,
|
|
@@ -225,9 +232,9 @@ var le = [
|
|
|
225
232
|
class: "t-app-shell__sidebar",
|
|
226
233
|
"aria-label": l.sidebarLabel
|
|
227
234
|
}, [
|
|
228
|
-
e.$slots["sidebar-header"] ? (m(), o("div",
|
|
229
|
-
s("div",
|
|
230
|
-
e.$slots["sidebar-footer"] || V.value ? (m(), o("div",
|
|
235
|
+
e.$slots["sidebar-header"] ? (m(), o("div", me, [g(e.$slots, "sidebar-header", p(u($.value)))])) : a("", !0),
|
|
236
|
+
s("div", he, [g(e.$slots, "sidebar", p(u($.value)))]),
|
|
237
|
+
e.$slots["sidebar-footer"] || V.value ? (m(), o("div", ge, [g(e.$slots, "sidebar-footer", p(u($.value))), V.value ? (m(), o("button", {
|
|
231
238
|
key: 0,
|
|
232
239
|
type: "button",
|
|
233
240
|
class: "t-app-shell__collapse-button",
|
|
@@ -235,19 +242,19 @@ var le = [
|
|
|
235
242
|
"aria-expanded": !v(A),
|
|
236
243
|
"aria-controls": v(k),
|
|
237
244
|
onClick: Q
|
|
238
|
-
}, [g(e.$slots, "collapse-icon", { collapsed: H.value }, () => [c(v(
|
|
239
|
-
], 8,
|
|
240
|
-
s("main",
|
|
245
|
+
}, [g(e.$slots, "collapse-icon", { collapsed: H.value }, () => [c(v(je), d(v(w), { "aria-hidden": "true" }), null, 16)])], 8, _e)) : a("", !0)])) : a("", !0)
|
|
246
|
+
], 8, pe)),
|
|
247
|
+
s("main", ve, [g(e.$slots, "default", {
|
|
241
248
|
mobile: B.value,
|
|
242
249
|
collapsed: H.value,
|
|
243
250
|
immersive: v(N),
|
|
244
251
|
toggleImmersive: P
|
|
245
252
|
})]),
|
|
246
253
|
c(n, { name: "t-app-shell-fade" }, {
|
|
247
|
-
default: b(() => [B.value && v(j) && !v(N) ? (m(), o("div",
|
|
254
|
+
default: b(() => [B.value && v(j) && !v(N) ? (m(), o("div", ye, [s("div", {
|
|
248
255
|
class: "t-app-shell__backdrop",
|
|
249
256
|
"aria-hidden": "true",
|
|
250
|
-
onClick:
|
|
257
|
+
onClick: Ne
|
|
251
258
|
}), s("aside", {
|
|
252
259
|
id: v(k),
|
|
253
260
|
ref_key: "surfaceRef",
|
|
@@ -257,17 +264,17 @@ var le = [
|
|
|
257
264
|
"aria-modal": "true",
|
|
258
265
|
"aria-label": l.sidebarLabel,
|
|
259
266
|
tabindex: "-1",
|
|
260
|
-
onKeydown:
|
|
261
|
-
}, [s("div",
|
|
267
|
+
onKeydown: Pe
|
|
268
|
+
}, [s("div", xe, [s("button", {
|
|
262
269
|
type: "button",
|
|
263
270
|
class: "t-app-shell__drawer-close",
|
|
264
271
|
"aria-label": l.closeLabel,
|
|
265
272
|
onClick: X
|
|
266
|
-
}, [c(v(
|
|
267
|
-
e.$slots["sidebar-header"] ? (m(), o("div",
|
|
268
|
-
s("div",
|
|
269
|
-
e.$slots["sidebar-footer"] ? (m(), o("div",
|
|
270
|
-
])], 40,
|
|
273
|
+
}, [c(v(De), p(u(v(w))), null, 16)], 8, Se)]), s("div", Ce, [
|
|
274
|
+
e.$slots["sidebar-header"] ? (m(), o("div", we, [g(e.$slots, "sidebar-header", p(u($.value)))])) : a("", !0),
|
|
275
|
+
s("div", Te, [g(e.$slots, "sidebar", p(u($.value)))]),
|
|
276
|
+
e.$slots["sidebar-footer"] ? (m(), o("div", Ee, [g(e.$slots, "sidebar-footer", p(u($.value)))])) : a("", !0)
|
|
277
|
+
])], 40, be)])) : a("", !0)]),
|
|
271
278
|
_: 3
|
|
272
279
|
})
|
|
273
280
|
]),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TAppShell.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../src/components/TAppShell.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n createId,\n focusFirst,\n focusLast,\n getFocusableElements,\n isEscapeKey,\n} from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport {\n computed,\n nextTick,\n onBeforeUnmount,\n onMounted,\n provide,\n ref,\n toRef,\n useAttrs,\n watch,\n} from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSidebarSide } from './TSidebar.vue';\nimport { treeSidebarInjectionKey } from './sidebar';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst CloseIcon = computed(() => getTreeIcon('x'));\nconst MenuIcon = computed(() => getTreeIcon('menu'));\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n side?: TSidebarSide;\n sidebarWidth?: string;\n collapsedWidth?: string;\n collapsible?: boolean;\n collapsed?: boolean;\n defaultCollapsed?: boolean;\n mobile?: boolean;\n breakpoint?: string;\n sidebarOpen?: boolean;\n defaultSidebarOpen?: boolean;\n /**\n * Hide the shell chrome (header and sidebar) so the content fills the\n * viewport. The default slot stays mounted across the toggle.\n */\n immersive?: boolean;\n defaultImmersive?: boolean;\n closeOnEscape?: boolean;\n closeOnOverlay?: boolean;\n showMenuButton?: boolean;\n /** Render the built-in collapse toggle in the sidebar footer (desktop). */\n showCollapseButton?: boolean;\n menuLabel?: string;\n closeLabel?: string;\n sidebarLabel?: string;\n collapseLabel?: string;\n expandLabel?: string;\n }>(),\n {\n as: 'div',\n side: 'left',\n sidebarWidth: '17.5rem',\n collapsedWidth: '4.75rem',\n collapsible: false,\n collapsed: undefined,\n defaultCollapsed: false,\n mobile: undefined,\n breakpoint: '768px',\n sidebarOpen: undefined,\n defaultSidebarOpen: false,\n immersive: undefined,\n defaultImmersive: false,\n closeOnEscape: true,\n closeOnOverlay: true,\n showMenuButton: true,\n showCollapseButton: true,\n menuLabel: 'Open menu',\n closeLabel: 'Close menu',\n sidebarLabel: 'Sidebar',\n collapseLabel: 'Collapse sidebar',\n expandLabel: 'Expand sidebar',\n },\n);\n\nconst emit = defineEmits<{\n 'update:collapsed': [value: boolean];\n 'collapse-change': [value: boolean];\n 'update:sidebarOpen': [value: boolean];\n 'sidebar-open-change': [value: boolean];\n 'update:immersive': [value: boolean];\n 'immersive-change': [value: boolean];\n}>();\n\nexport interface AppShellSlotProps {\n mobile: boolean;\n collapsed: boolean;\n sidebarOpen: boolean;\n immersive: boolean;\n toggleSidebar: () => void;\n closeSidebar: () => void;\n toggleCollapsed: () => void;\n toggleImmersive: () => void;\n}\n\ndefineSlots<{\n header?: (props: AppShellSlotProps) => unknown;\n /** Header region over the sidebar rail; the `header` slot then aligns with the content panel. */\n 'header-start'?: (props: AppShellSlotProps) => unknown;\n /** Pinned above the sidebar body, inset to line up with nav item icons. */\n 'sidebar-header'?: (props: AppShellSlotProps) => unknown;\n sidebar?: (props: AppShellSlotProps) => unknown;\n /** Pinned to the bottom of the sidebar, inset to line up with nav item icons. */\n 'sidebar-footer'?: (props: AppShellSlotProps) => unknown;\n /**\n * Immersive hides the chrome, so the content is the only place an exit\n * control can live — `immersive` and `toggleImmersive` are passed through.\n */\n default?: (\n props: Pick<AppShellSlotProps, 'mobile' | 'collapsed' | 'immersive' | 'toggleImmersive'>,\n ) => unknown;\n 'menu-icon'?: (props: { sidebarOpen: boolean }) => unknown;\n 'collapse-icon'?: (props: { collapsed: boolean }) => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst sidebarId = createId('t-app-shell-sidebar');\n\nconst { value: isCollapsed, setValue: setCollapsed } = useControllableOpen(\n toRef(props, 'collapsed'),\n props.defaultCollapsed,\n (value) => {\n emit('update:collapsed', value);\n emit('collapse-change', value);\n },\n);\n\nconst { value: isSidebarOpen, setValue: setSidebarOpen } = useControllableOpen(\n toRef(props, 'sidebarOpen'),\n props.defaultSidebarOpen,\n (value) => {\n emit('update:sidebarOpen', value);\n emit('sidebar-open-change', value);\n },\n);\n\nconst { value: isImmersive, setValue: setImmersive } = useControllableOpen(\n toRef(props, 'immersive'),\n props.defaultImmersive,\n (value) => {\n emit('update:immersive', value);\n emit('immersive-change', value);\n },\n);\n\nconst toggleImmersive = () => {\n setImmersive(!isImmersive.value);\n};\n\n// Auto responsive detection when `mobile` is not explicitly controlled.\nconst autoMobile = ref(false);\nlet mediaQuery: MediaQueryList | null = null;\n\nconst onMediaChange = (event: MediaQueryListEvent | MediaQueryList) => {\n autoMobile.value = event.matches;\n};\n\nconst setupMediaQuery = () => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {\n return;\n }\n\n teardownMediaQuery();\n mediaQuery = window.matchMedia(`(max-width: ${props.breakpoint})`);\n autoMobile.value = mediaQuery.matches;\n mediaQuery.addEventListener?.('change', onMediaChange);\n};\n\nconst teardownMediaQuery = () => {\n mediaQuery?.removeEventListener?.('change', onMediaChange);\n mediaQuery = null;\n};\n\nconst isMobile = computed(() => props.mobile ?? autoMobile.value);\n\n// Collapsing is desktop-only, so the built-in toggle follows the same rule.\nconst showCollapseToggle = computed(\n () => !isMobile.value && props.collapsible && props.showCollapseButton,\n);\n\n// Collapse is a desktop-only concept; the mobile drawer always shows the\n// expanded sidebar, so descendants and slots see `collapsed: false` there.\nconst effectiveCollapsed = computed(() =>\n isMobile.value ? false : isCollapsed.value,\n);\n\n// The glyph points the way the rail will move: collapsing a left sidebar folds\n// it left, expanding it pushes right (mirrored for a right-anchored sidebar).\nconst CollapseIcon = computed(() => {\n const pointsStart = props.side === 'right' ? effectiveCollapsed.value : !effectiveCollapsed.value;\n return getTreeIcon(pointsStart ? 'panel-left' : 'panel-right');\n});\n\nconst surfaceRef = ref<HTMLElement | null>(null);\nconst previousFocusedElement = ref<HTMLElement | null>(null);\nlet previousBodyOverflow = '';\nlet bodyLocked = false;\n\nconst lockBodyScroll = () => {\n if (typeof document === 'undefined' || bodyLocked) {\n return;\n }\n\n previousBodyOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n bodyLocked = true;\n};\n\nconst unlockBodyScroll = () => {\n if (typeof document === 'undefined' || !bodyLocked) {\n return;\n }\n\n document.body.style.overflow = previousBodyOverflow;\n bodyLocked = false;\n};\n\nconst focusSurface = () => {\n nextTick(() => {\n if (!surfaceRef.value) {\n return;\n }\n\n const focused = focusFirst(surfaceRef.value);\n if (!focused) {\n surfaceRef.value.focus();\n }\n });\n};\n\nconst openSidebar = () => {\n previousFocusedElement.value =\n typeof document === 'undefined'\n ? null\n : (document.activeElement as HTMLElement | null);\n setSidebarOpen(true);\n};\n\nconst closeSidebar = () => {\n setSidebarOpen(false);\n};\n\nconst toggleSidebar = () => {\n if (isSidebarOpen.value) {\n closeSidebar();\n } else {\n openSidebar();\n }\n};\n\nconst toggleCollapsed = () => {\n if (!props.collapsible) {\n return;\n }\n\n setCollapsed(!isCollapsed.value);\n};\n\nconst onOverlayClick = () => {\n if (props.closeOnOverlay) {\n closeSidebar();\n }\n};\n\nconst onKeydown = (event: KeyboardEvent) => {\n if (isEscapeKey(event) && props.closeOnEscape) {\n event.preventDefault();\n closeSidebar();\n return;\n }\n\n if (event.key !== 'Tab' || !surfaceRef.value) {\n return;\n }\n\n const focusable = getFocusableElements(surfaceRef.value);\n\n if (!focusable.length) {\n event.preventDefault();\n surfaceRef.value.focus();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const activeElement = document.activeElement as HTMLElement | null;\n\n if (event.shiftKey && activeElement === first) {\n event.preventDefault();\n focusLast(surfaceRef.value);\n }\n\n if (!event.shiftKey && activeElement === last) {\n event.preventDefault();\n focusFirst(surfaceRef.value);\n }\n};\n\n// The off-canvas drawer only exists in mobile mode; keep body-scroll lock and\n// focus handling in sync with both the open flag and the responsive mode.\nconst syncOverlayState = (open: boolean, wasOpen: boolean) => {\n if (open && isMobile.value) {\n lockBodyScroll();\n focusSurface();\n return;\n }\n\n if (wasOpen) {\n unlockBodyScroll();\n nextTick(() => {\n previousFocusedElement.value?.focus();\n });\n }\n};\n\nwatch(isSidebarOpen, (value, previousValue) => {\n syncOverlayState(value, Boolean(previousValue));\n});\n\n// Entering immersive removes the drawer from the DOM without changing\n// `sidebarOpen`, so the sidebarOpen watcher never fires and would leave the\n// body scroll-locked with focus stranded on an unmounted surface. Release and\n// re-arm here, mirroring the responsive-mode watcher below.\nwatch(isImmersive, (immersive) => {\n if (!isSidebarOpen.value || !isMobile.value) {\n return;\n }\n\n if (immersive) {\n unlockBodyScroll();\n nextTick(() => {\n previousFocusedElement.value?.focus();\n });\n } else {\n lockBodyScroll();\n focusSurface();\n }\n});\n\nwatch(isMobile, (mobile) => {\n if (!isSidebarOpen.value) {\n return;\n }\n\n // Leaving mobile removes the drawer from the DOM, so release the lock and\n // restore focus; re-entering mobile while \"open\" re-arms the overlay.\n if (mobile) {\n lockBodyScroll();\n focusSurface();\n } else {\n unlockBodyScroll();\n }\n});\n\nwatch(\n () => props.breakpoint,\n () => {\n if (typeof window !== 'undefined') {\n setupMediaQuery();\n }\n },\n);\n\nonMounted(() => {\n setupMediaQuery();\n});\n\nonBeforeUnmount(() => {\n teardownMediaQuery();\n unlockBodyScroll();\n});\n\nprovide(treeSidebarInjectionKey, {\n collapsed: effectiveCollapsed,\n});\n\nconst rootClasses = computed(() => [\n 't-app-shell',\n `t-app-shell--${props.side}`,\n {\n 'is-mobile': isMobile.value,\n 'is-collapsed':\n !isMobile.value && props.collapsible && isCollapsed.value,\n 'is-sidebar-open': isMobile.value && isSidebarOpen.value,\n 'is-immersive': isImmersive.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => [\n {\n '--tree-app-shell-sidebar-width': props.sidebarWidth,\n '--tree-app-shell-collapsed-width': props.collapsedWidth,\n },\n attrs.style,\n]);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst slotProps = computed<AppShellSlotProps>(() => ({\n mobile: isMobile.value,\n collapsed: effectiveCollapsed.value,\n sidebarOpen: isSidebarOpen.value,\n immersive: isImmersive.value,\n toggleSidebar,\n closeSidebar,\n toggleCollapsed,\n toggleImmersive,\n}));\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-mobile=\"isMobile ? 'true' : 'false'\"\n >\n <header\n class=\"t-app-shell__header\"\n :class=\"{ 'has-start': Boolean($slots['header-start']) }\"\n >\n <button\n v-if=\"isMobile && showMenuButton\"\n type=\"button\"\n class=\"t-app-shell__menu-button\"\n :aria-label=\"menuLabel\"\n :aria-expanded=\"isSidebarOpen\"\n :aria-controls=\"sidebarId\"\n @click=\"toggleSidebar\"\n >\n <slot\n name=\"menu-icon\"\n :sidebar-open=\"isSidebarOpen\"\n >\n <MenuIcon\n v-bind=\"treeIconDefaults\"\n :size=\"24\"\n aria-hidden=\"true\"\n />\n </slot>\n </button>\n\n <div\n v-if=\"$slots['header-start']\"\n class=\"t-app-shell__header-start\"\n >\n <slot\n name=\"header-start\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div class=\"t-app-shell__header-content\">\n <slot\n name=\"header\"\n v-bind=\"slotProps\"\n />\n </div>\n </header>\n\n <aside\n v-if=\"!isMobile\"\n :id=\"sidebarId\"\n class=\"t-app-shell__sidebar\"\n :aria-label=\"sidebarLabel\"\n >\n <div\n v-if=\"$slots['sidebar-header']\"\n class=\"t-app-shell__sidebar-header\"\n >\n <slot\n name=\"sidebar-header\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div class=\"t-app-shell__sidebar-body\">\n <slot\n name=\"sidebar\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div\n v-if=\"$slots['sidebar-footer'] || showCollapseToggle\"\n class=\"t-app-shell__sidebar-footer\"\n >\n <slot\n name=\"sidebar-footer\"\n v-bind=\"slotProps\"\n />\n\n <button\n v-if=\"showCollapseToggle\"\n type=\"button\"\n class=\"t-app-shell__collapse-button\"\n :aria-label=\"isCollapsed ? expandLabel : collapseLabel\"\n :aria-expanded=\"!isCollapsed\"\n :aria-controls=\"sidebarId\"\n @click=\"toggleCollapsed\"\n >\n <slot\n name=\"collapse-icon\"\n :collapsed=\"effectiveCollapsed\"\n >\n <CollapseIcon\n v-bind=\"treeIconDefaults\"\n aria-hidden=\"true\"\n />\n </slot>\n </button>\n </div>\n </aside>\n\n <main class=\"t-app-shell__main\">\n <slot\n :mobile=\"isMobile\"\n :collapsed=\"effectiveCollapsed\"\n :immersive=\"isImmersive\"\n :toggle-immersive=\"toggleImmersive\"\n />\n </main>\n\n <transition name=\"t-app-shell-fade\">\n <div\n v-if=\"isMobile && isSidebarOpen && !isImmersive\"\n class=\"t-app-shell__overlay\"\n >\n <div\n class=\"t-app-shell__backdrop\"\n aria-hidden=\"true\"\n @click=\"onOverlayClick\"\n />\n <aside\n :id=\"sidebarId\"\n ref=\"surfaceRef\"\n class=\"t-app-shell__drawer\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-label=\"sidebarLabel\"\n tabindex=\"-1\"\n @keydown=\"onKeydown\"\n >\n <div class=\"t-app-shell__drawer-topbar\">\n <button\n type=\"button\"\n class=\"t-app-shell__drawer-close\"\n :aria-label=\"closeLabel\"\n @click=\"closeSidebar\"\n >\n <CloseIcon v-bind=\"treeIconDefaults\" />\n </button>\n </div>\n <div class=\"t-app-shell__drawer-body\">\n <div\n v-if=\"$slots['sidebar-header']\"\n class=\"t-app-shell__sidebar-header\"\n >\n <slot\n name=\"sidebar-header\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div class=\"t-app-shell__sidebar-body\">\n <slot\n name=\"sidebar\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div\n v-if=\"$slots['sidebar-footer']\"\n class=\"t-app-shell__sidebar-footer\"\n >\n <slot\n name=\"sidebar-footer\"\n v-bind=\"slotProps\"\n />\n </div>\n </div>\n </aside>\n </div>\n </transition>\n </component>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BA,IAAM,KAAY,QAAe,EAAY,GAAG,CAAC,GAC3C,KAAW,QAAe,EAAY,MAAM,CAAC,GAE7C,IAAQ,GAwDR,IAAO,GAwCP,IAAQ,GAAS,GACjB,IAAY,GAAS,qBAAqB,GAE1C,EAAE,OAAO,GAAa,UAAU,OAAiB,EACrD,EAAM,GAAO,WAAW,GACxB,EAAM,mBACL,MAAU;GAET,AADA,EAAK,oBAAoB,CAAK,GAC9B,EAAK,mBAAmB,CAAK;EAC/B,CACF,GAEM,EAAE,OAAO,GAAe,UAAU,MAAmB,EACzD,EAAM,GAAO,aAAa,GAC1B,EAAM,qBACL,MAAU;GAET,AADA,EAAK,sBAAsB,CAAK,GAChC,EAAK,uBAAuB,CAAK;EACnC,CACF,GAEM,EAAE,OAAO,GAAa,UAAU,OAAiB,EACrD,EAAM,GAAO,WAAW,GACxB,EAAM,mBACL,MAAU;GAET,AADA,EAAK,oBAAoB,CAAK,GAC9B,EAAK,oBAAoB,CAAK;EAChC,CACF,GAEM,UAAwB;GAC5B,GAAa,CAAC,EAAY,KAAK;EACjC,GAGM,IAAa,EAAI,EAAK,GACxB,IAAoC,MAElC,KAAiB,MAAgD;GACrE,EAAW,QAAQ,EAAM;EAC3B,GAEM,UAAwB;GACxB,OAAO,SAAW,OAAe,OAAO,OAAO,cAAe,eAIlE,EAAmB,GACnB,IAAa,OAAO,WAAW,eAAe,EAAM,WAAW,EAAE,GACjE,EAAW,QAAQ,EAAW,SAC9B,EAAW,mBAAmB,UAAU,CAAa;EACvD,GAEM,UAA2B;GAE/B,AADA,GAAY,sBAAsB,UAAU,CAAa,GACzD,IAAa;EACf,GAEM,IAAW,QAAe,EAAM,UAAU,EAAW,KAAK,GAG1D,IAAqB,QACnB,CAAC,EAAS,SAAS,EAAM,eAAe,EAAM,kBACtD,GAIM,IAAqB,QACzB,GAAS,SAAgB,EAAY,KACvC,GAIM,KAAe,QAEZ,GADa,EAAM,SAAS,UAAU,EAAmB,QAAQ,CAAC,EAAmB,SAC3D,eAAe,aAAa,CAC9D,GAEK,IAAa,EAAwB,IAAI,GACzC,IAAyB,EAAwB,IAAI,GACvD,IAAuB,IACvB,IAAa,IAEX,UAAuB;GACvB,OAAO,WAAa,OAAe,MAIvC,IAAuB,SAAS,KAAK,MAAM,UAC3C,SAAS,KAAK,MAAM,WAAW,UAC/B,IAAa;EACf,GAEM,UAAyB;GACzB,OAAO,WAAa,OAAe,CAAC,MAIxC,SAAS,KAAK,MAAM,WAAW,GAC/B,IAAa;EACf,GAEM,UAAqB;GACzB,QAAe;IACR,EAAW,UAIA,EAAW,EAAW,KACjC,KACH,EAAW,MAAM,MAAM;GAE3B,CAAC;EACH,GAEM,WAAoB;GAKxB,AAJA,EAAuB,QACrB,OAAO,WAAa,MAChB,OACC,SAAS,eAChB,EAAe,EAAI;EACrB,GAEM,UAAqB;GACzB,EAAe,EAAK;EACtB,GAEM,UAAsB;GAC1B,AAAI,EAAc,QAChB,EAAa,IAEb,GAAY;EAEhB,GAEM,UAAwB;GACvB,EAAM,eAIX,GAAa,CAAC,EAAY,KAAK;EACjC,GAEM,WAAuB;GAC3B,AAAI,EAAM,kBACR,EAAa;EAEjB,GAEM,MAAa,MAAyB;GAC1C,IAAI,GAAY,CAAK,KAAK,EAAM,eAAe;IAE7C,AADA,EAAM,eAAe,GACrB,EAAa;IACb;GACF;GAEA,IAAI,EAAM,QAAQ,SAAS,CAAC,EAAW,OACrC;GAGF,IAAM,IAAY,EAAqB,EAAW,KAAK;GAEvD,IAAI,CAAC,EAAU,QAAQ;IAErB,AADA,EAAM,eAAe,GACrB,EAAW,MAAM,MAAM;IACvB;GACF;GAEA,IAAM,IAAQ,EAAU,IAClB,IAAO,EAAU,EAAU,SAAS,IACpC,IAAgB,SAAS;GAO/B,AALI,EAAM,YAAY,MAAkB,MACtC,EAAM,eAAe,GACrB,GAAU,EAAW,KAAK,IAGxB,CAAC,EAAM,YAAY,MAAkB,MACvC,EAAM,eAAe,GACrB,EAAW,EAAW,KAAK;EAE/B,GAIM,MAAoB,GAAe,MAAqB;GAC5D,IAAI,KAAQ,EAAS,OAAO;IAE1B,AADA,EAAe,GACf,EAAa;IACb;GACF;GAEA,AAAI,MACF,EAAiB,GACjB,QAAe;IACb,EAAuB,OAAO,MAAM;GACtC,CAAC;EAEL;EA2DA,AAzDA,EAAM,IAAgB,GAAO,MAAkB;GAC7C,GAAiB,GAAO,EAAQ,CAAc;EAChD,CAAC,GAMD,EAAM,IAAc,MAAc;GAC5B,CAAC,EAAc,SAAS,CAAC,EAAS,UAIlC,KACF,EAAiB,GACjB,QAAe;IACb,EAAuB,OAAO,MAAM;GACtC,CAAC,MAED,EAAe,GACf,EAAa;EAEjB,CAAC,GAED,EAAM,IAAW,MAAW;GACrB,EAAc,UAMf,KACF,EAAe,GACf,EAAa,KAEb,EAAiB;EAErB,CAAC,GAED,QACQ,EAAM,kBACN;GACJ,AAAI,OAAO,SAAW,OACpB,EAAgB;EAEpB,CACF,GAEA,SAAgB;GACd,EAAgB;EAClB,CAAC,GAED,SAAsB;GAEpB,AADA,EAAmB,GACnB,EAAiB;EACnB,CAAC,GAED,GAAQ,GAAyB,EAC/B,WAAW,EACb,CAAC;EAED,IAAM,KAAc,QAAe;GACjC;GACA,gBAAgB,EAAM;GACtB;IACE,aAAa,EAAS;IACtB,gBACE,CAAC,EAAS,SAAS,EAAM,eAAe,EAAY;IACtD,mBAAmB,EAAS,SAAS,EAAc;IACnD,gBAAgB,EAAY;GAC9B;GACA,EAAM;EACR,CAAC,GAEK,KAAY,QAAe,CAC/B;GACE,kCAAkC,EAAM;GACxC,oCAAoC,EAAM;EAC5C,GACA,EAAM,KACR,CAAC,GAEK,KAAY,QAAe;GAC/B,IAAM,EAAE,OAAO,GAAQ,OAAO,GAAQ,GAAG,MAAS;GAClD,OAAO;EACT,CAAC,GAEK,IAAY,SAAmC;GACnD,QAAQ,EAAS;GACjB,WAAW,EAAmB;GAC9B,aAAa,EAAc;GAC3B,WAAW,EAAY;GACvB;GACA;GACA;GACA;EACF,EAAE;yBAIA,EA8KY,GA7KL,EAAA,EAAE,GADT,EAEU,GA4KE,OA5KO;GAChB,OAAO,GAAA;GACP,OAAO,GAAA;GACP,eAAa,EAAA,QAAQ,SAAA;;oBA2Cb;IAzCT,EAyCS,UAAA,EAxCP,OAAK,GAAA,CAAC,uBAAqB,EAAA,aACJ,EAAQA,EAAAA,OAAM,gBAAA,CAAA,CAAA,EAAA,GAAA;KAG7B,EAAA,SAAY,EAAA,kBAAA,EAAA,GADpB,EAmBS,UAAA;;MAjBP,MAAK;MACL,OAAM;MACL,cAAY,EAAA;MACZ,iBAAe,EAAA,CAAA;MACf,iBAAe,EAAA,CAAA;MACf,SAAO;SAER,EASO,EAAA,QAAA,aAAA,EAPJ,aAAc,EAAA,CAAA,EAAa,SAOvB,CALL,EAIE,EAAA,EAAA,GAJF,EACU,EAGR,CAAA,GAHwB;MACvB,MAAM;MACP,eAAY;;KAMVA,EAAAA,OAAM,mBAAA,EAAA,GADd,EAQM,OARN,IAQM,CAJJ,EAGE,EAAA,QAAA,gBAAA,EAAA,EADQ,EAAA,KAAS,CAAA,CAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA;KAIrB,EAKM,OALN,IAKM,CAJJ,EAGE,EAAA,QAAA,UAAA,EAAA,EADQ,EAAA,KAAS,CAAA,CAAA,CAAA,CAAA;;IAMd,EAAA,qBAAA,EAAA,GADT,EAoDQ,SAAA;;KAlDL,IAAI,EAAA,CAAA;KACL,OAAM;KACL,cAAY,EAAA;;KAGLA,EAAAA,OAAM,qBAAA,EAAA,GADd,EAQM,OARN,IAQM,CAJJ,EAGE,EAAA,QAAA,kBAAA,EAAA,EADQ,EAAA,KAAS,CAAA,CAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA;KAIrB,EAKM,OALN,IAKM,CAJJ,EAGE,EAAA,QAAA,WAAA,EAAA,EADQ,EAAA,KAAS,CAAA,CAAA,CAAA,CAAA;KAKbA,EAAAA,OAAM,qBAAsB,EAAA,SAAA,EAAA,GADpC,EA4BM,OA5BN,IA4BM,CAxBJ,EAGE,EAAA,QAAA,kBAAA,EAAA,EADQ,EAAA,KAAS,CAAA,CAAA,GAIX,EAAA,SAAA,EAAA,GADR,EAkBS,UAAA;;MAhBP,MAAK;MACL,OAAM;MACL,cAAY,EAAA,CAAA,IAAc,EAAA,cAAc,EAAA;MACxC,iBAAa,CAAG,EAAA,CAAA;MAChB,iBAAe,EAAA,CAAA;MACf,SAAO;SAER,EAQO,EAAA,QAAA,iBAAA,EANJ,WAAW,EAAA,MAAkB,SAMzB,CAJL,EAGE,EAAA,EAAA,GAHF,EACU,EAER,CAAA,GAFwB,EACxB,eAAY,OAAM,CAAA,GAAA,MAAA,EAAA,CAAA,CAAA,CAAA,GAAA,GAAA,EAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA;;IAO5B,EAOO,QAPP,IAOO,CANL,EAKE,EAAA,QAAA,WAAA;KAJC,QAAQ,EAAA;KACR,WAAW,EAAA;KACX,WAAW,EAAA,CAAA;KACO;;IAIvB,EA4Da,GAAA,EA5DD,MAAK,mBAAkB,GAAA;uBAEzB,EAAA,SAAY,EAAA,CAAA,KAAa,CAAK,EAAA,CAAA,KAAA,EAAA,GADtC,EA0DM,OA1DN,IA0DM,CAtDJ,EAIE,OAAA;MAHA,OAAM;MACN,eAAY;MACX,SAAO;SAEV,EAgDQ,SAAA;MA/CL,IAAI,EAAA,CAAA;eACD;MAAJ,KAAI;MACJ,OAAM;MACN,MAAK;MACL,cAAW;MACV,cAAY,EAAA;MACb,UAAS;MACC;SAEV,EASM,OATN,IASM,CARJ,EAOS,UAAA;MANP,MAAK;MACL,OAAM;MACL,cAAY,EAAA;MACZ,SAAO;SAER,EAAuC,EAAA,EAAA,GAAA,EAAA,EAApB,EAAA,CAAA,CAAgB,CAAA,GAAA,MAAA,EAAA,CAAA,GAAA,GAAA,EAAA,CAAA,CAAA,GAGvC,EA2BM,OA3BN,IA2BM;MAzBIA,EAAAA,OAAM,qBAAA,EAAA,GADd,EAQM,OARN,IAQM,CAJJ,EAGE,EAAA,QAAA,kBAAA,EAAA,EADQ,EAAA,KAAS,CAAA,CAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA;MAIrB,EAKM,OALN,IAKM,CAJJ,EAGE,EAAA,QAAA,WAAA,EAAA,EADQ,EAAA,KAAS,CAAA,CAAA,CAAA,CAAA;MAKbA,EAAAA,OAAM,qBAAA,EAAA,GADd,EAQM,OARN,IAQM,CAJJ,EAGE,EAAA,QAAA,kBAAA,EAAA,EADQ,EAAA,KAAS,CAAA,CAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA"}
|
|
1
|
+
{"version":3,"file":"TAppShell.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../src/components/TAppShell.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n createId,\n focusFirst,\n focusLast,\n getFocusableElements,\n isEscapeKey,\n} from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport {\n computed,\n nextTick,\n onBeforeUnmount,\n onMounted,\n provide,\n ref,\n toRef,\n useAttrs,\n watch,\n} from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSidebarSide } from './TSidebar.vue';\nimport { treeSidebarInjectionKey } from './sidebar';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst CloseIcon = computed(() => getTreeIcon('x'));\nconst MenuIcon = computed(() => getTreeIcon('menu'));\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n side?: TSidebarSide;\n sidebarWidth?: string;\n collapsedWidth?: string;\n collapsible?: boolean;\n collapsed?: boolean;\n defaultCollapsed?: boolean;\n mobile?: boolean;\n breakpoint?: string;\n sidebarOpen?: boolean;\n defaultSidebarOpen?: boolean;\n /**\n * Hide the shell chrome (header and sidebar) so the content fills the\n * viewport. The default slot stays mounted across the toggle.\n */\n immersive?: boolean;\n defaultImmersive?: boolean;\n closeOnEscape?: boolean;\n closeOnOverlay?: boolean;\n showMenuButton?: boolean;\n /** Render the built-in collapse toggle in the sidebar footer (desktop). */\n showCollapseButton?: boolean;\n menuLabel?: string;\n closeLabel?: string;\n sidebarLabel?: string;\n collapseLabel?: string;\n expandLabel?: string;\n }>(),\n {\n as: 'div',\n side: 'left',\n sidebarWidth: '17.5rem',\n collapsedWidth: '4.75rem',\n collapsible: false,\n collapsed: undefined,\n defaultCollapsed: false,\n mobile: undefined,\n breakpoint: '768px',\n sidebarOpen: undefined,\n defaultSidebarOpen: false,\n immersive: undefined,\n defaultImmersive: false,\n closeOnEscape: true,\n closeOnOverlay: true,\n showMenuButton: true,\n showCollapseButton: true,\n menuLabel: 'Open menu',\n closeLabel: 'Close menu',\n sidebarLabel: 'Sidebar',\n collapseLabel: 'Collapse sidebar',\n expandLabel: 'Expand sidebar',\n },\n);\n\nconst emit = defineEmits<{\n 'update:collapsed': [value: boolean];\n 'collapse-change': [value: boolean];\n 'update:sidebarOpen': [value: boolean];\n 'sidebar-open-change': [value: boolean];\n 'update:immersive': [value: boolean];\n 'immersive-change': [value: boolean];\n}>();\n\nexport interface AppShellSlotProps {\n mobile: boolean;\n collapsed: boolean;\n sidebarOpen: boolean;\n immersive: boolean;\n toggleSidebar: () => void;\n closeSidebar: () => void;\n toggleCollapsed: () => void;\n toggleImmersive: () => void;\n}\n\ndefineSlots<{\n header?: (props: AppShellSlotProps) => unknown;\n /** Header region over the sidebar rail; the `header` slot then aligns with the content panel. */\n 'header-start'?: (props: AppShellSlotProps) => unknown;\n /** Trailing header region, pinned to the far end of the row (actions, controls). */\n 'header-end'?: (props: AppShellSlotProps) => unknown;\n /** Pinned above the sidebar body, inset to line up with nav item icons. */\n 'sidebar-header'?: (props: AppShellSlotProps) => unknown;\n sidebar?: (props: AppShellSlotProps) => unknown;\n /** Pinned to the bottom of the sidebar, inset to line up with nav item icons. */\n 'sidebar-footer'?: (props: AppShellSlotProps) => unknown;\n /**\n * Immersive hides the chrome, so the content is the only place an exit\n * control can live — `immersive` and `toggleImmersive` are passed through.\n */\n default?: (\n props: Pick<AppShellSlotProps, 'mobile' | 'collapsed' | 'immersive' | 'toggleImmersive'>,\n ) => unknown;\n 'menu-icon'?: (props: { sidebarOpen: boolean }) => unknown;\n 'collapse-icon'?: (props: { collapsed: boolean }) => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst sidebarId = createId('t-app-shell-sidebar');\n\nconst { value: isCollapsed, setValue: setCollapsed } = useControllableOpen(\n toRef(props, 'collapsed'),\n props.defaultCollapsed,\n (value) => {\n emit('update:collapsed', value);\n emit('collapse-change', value);\n },\n);\n\nconst { value: isSidebarOpen, setValue: setSidebarOpen } = useControllableOpen(\n toRef(props, 'sidebarOpen'),\n props.defaultSidebarOpen,\n (value) => {\n emit('update:sidebarOpen', value);\n emit('sidebar-open-change', value);\n },\n);\n\nconst { value: isImmersive, setValue: setImmersive } = useControllableOpen(\n toRef(props, 'immersive'),\n props.defaultImmersive,\n (value) => {\n emit('update:immersive', value);\n emit('immersive-change', value);\n },\n);\n\nconst toggleImmersive = () => {\n setImmersive(!isImmersive.value);\n};\n\n// Auto responsive detection when `mobile` is not explicitly controlled.\nconst autoMobile = ref(false);\nlet mediaQuery: MediaQueryList | null = null;\n\nconst onMediaChange = (event: MediaQueryListEvent | MediaQueryList) => {\n autoMobile.value = event.matches;\n};\n\nconst setupMediaQuery = () => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {\n return;\n }\n\n teardownMediaQuery();\n mediaQuery = window.matchMedia(`(max-width: ${props.breakpoint})`);\n autoMobile.value = mediaQuery.matches;\n mediaQuery.addEventListener?.('change', onMediaChange);\n};\n\nconst teardownMediaQuery = () => {\n mediaQuery?.removeEventListener?.('change', onMediaChange);\n mediaQuery = null;\n};\n\nconst isMobile = computed(() => props.mobile ?? autoMobile.value);\n\n// Collapsing is desktop-only, so the built-in toggle follows the same rule.\nconst showCollapseToggle = computed(\n () => !isMobile.value && props.collapsible && props.showCollapseButton,\n);\n\n// Collapse is a desktop-only concept; the mobile drawer always shows the\n// expanded sidebar, so descendants and slots see `collapsed: false` there.\nconst effectiveCollapsed = computed(() =>\n isMobile.value ? false : isCollapsed.value,\n);\n\n// The glyph points the way the rail will move: collapsing a left sidebar folds\n// it left, expanding it pushes right (mirrored for a right-anchored sidebar).\nconst CollapseIcon = computed(() => {\n const pointsStart = props.side === 'right' ? effectiveCollapsed.value : !effectiveCollapsed.value;\n return getTreeIcon(pointsStart ? 'panel-left' : 'panel-right');\n});\n\nconst surfaceRef = ref<HTMLElement | null>(null);\nconst previousFocusedElement = ref<HTMLElement | null>(null);\nlet previousBodyOverflow = '';\nlet bodyLocked = false;\n\nconst lockBodyScroll = () => {\n if (typeof document === 'undefined' || bodyLocked) {\n return;\n }\n\n previousBodyOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n bodyLocked = true;\n};\n\nconst unlockBodyScroll = () => {\n if (typeof document === 'undefined' || !bodyLocked) {\n return;\n }\n\n document.body.style.overflow = previousBodyOverflow;\n bodyLocked = false;\n};\n\nconst focusSurface = () => {\n nextTick(() => {\n if (!surfaceRef.value) {\n return;\n }\n\n const focused = focusFirst(surfaceRef.value);\n if (!focused) {\n surfaceRef.value.focus();\n }\n });\n};\n\nconst openSidebar = () => {\n previousFocusedElement.value =\n typeof document === 'undefined'\n ? null\n : (document.activeElement as HTMLElement | null);\n setSidebarOpen(true);\n};\n\nconst closeSidebar = () => {\n setSidebarOpen(false);\n};\n\nconst toggleSidebar = () => {\n if (isSidebarOpen.value) {\n closeSidebar();\n } else {\n openSidebar();\n }\n};\n\nconst toggleCollapsed = () => {\n if (!props.collapsible) {\n return;\n }\n\n setCollapsed(!isCollapsed.value);\n};\n\nconst onOverlayClick = () => {\n if (props.closeOnOverlay) {\n closeSidebar();\n }\n};\n\nconst onKeydown = (event: KeyboardEvent) => {\n if (isEscapeKey(event) && props.closeOnEscape) {\n event.preventDefault();\n closeSidebar();\n return;\n }\n\n if (event.key !== 'Tab' || !surfaceRef.value) {\n return;\n }\n\n const focusable = getFocusableElements(surfaceRef.value);\n\n if (!focusable.length) {\n event.preventDefault();\n surfaceRef.value.focus();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const activeElement = document.activeElement as HTMLElement | null;\n\n if (event.shiftKey && activeElement === first) {\n event.preventDefault();\n focusLast(surfaceRef.value);\n }\n\n if (!event.shiftKey && activeElement === last) {\n event.preventDefault();\n focusFirst(surfaceRef.value);\n }\n};\n\n// The off-canvas drawer only exists in mobile mode; keep body-scroll lock and\n// focus handling in sync with both the open flag and the responsive mode.\nconst syncOverlayState = (open: boolean, wasOpen: boolean) => {\n if (open && isMobile.value) {\n lockBodyScroll();\n focusSurface();\n return;\n }\n\n if (wasOpen) {\n unlockBodyScroll();\n nextTick(() => {\n previousFocusedElement.value?.focus();\n });\n }\n};\n\nwatch(isSidebarOpen, (value, previousValue) => {\n syncOverlayState(value, Boolean(previousValue));\n});\n\n// Entering immersive removes the drawer from the DOM without changing\n// `sidebarOpen`, so the sidebarOpen watcher never fires and would leave the\n// body scroll-locked with focus stranded on an unmounted surface. Release and\n// re-arm here, mirroring the responsive-mode watcher below.\nwatch(isImmersive, (immersive) => {\n if (!isSidebarOpen.value || !isMobile.value) {\n return;\n }\n\n if (immersive) {\n unlockBodyScroll();\n nextTick(() => {\n previousFocusedElement.value?.focus();\n });\n } else {\n lockBodyScroll();\n focusSurface();\n }\n});\n\nwatch(isMobile, (mobile) => {\n if (!isSidebarOpen.value) {\n return;\n }\n\n // Leaving mobile removes the drawer from the DOM, so release the lock and\n // restore focus; re-entering mobile while \"open\" re-arms the overlay.\n if (mobile) {\n lockBodyScroll();\n focusSurface();\n } else {\n unlockBodyScroll();\n }\n});\n\nwatch(\n () => props.breakpoint,\n () => {\n if (typeof window !== 'undefined') {\n setupMediaQuery();\n }\n },\n);\n\nonMounted(() => {\n setupMediaQuery();\n});\n\nonBeforeUnmount(() => {\n teardownMediaQuery();\n unlockBodyScroll();\n});\n\nprovide(treeSidebarInjectionKey, {\n collapsed: effectiveCollapsed,\n});\n\nconst rootClasses = computed(() => [\n 't-app-shell',\n `t-app-shell--${props.side}`,\n {\n 'is-mobile': isMobile.value,\n 'is-collapsed':\n !isMobile.value && props.collapsible && isCollapsed.value,\n 'is-sidebar-open': isMobile.value && isSidebarOpen.value,\n 'is-immersive': isImmersive.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => [\n {\n '--tree-app-shell-sidebar-width': props.sidebarWidth,\n '--tree-app-shell-collapsed-width': props.collapsedWidth,\n },\n attrs.style,\n]);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst slotProps = computed<AppShellSlotProps>(() => ({\n mobile: isMobile.value,\n collapsed: effectiveCollapsed.value,\n sidebarOpen: isSidebarOpen.value,\n immersive: isImmersive.value,\n toggleSidebar,\n closeSidebar,\n toggleCollapsed,\n toggleImmersive,\n}));\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-mobile=\"isMobile ? 'true' : 'false'\"\n >\n <header\n class=\"t-app-shell__header\"\n :class=\"{\n 'has-start': Boolean($slots['header-start']),\n 'has-end': Boolean($slots['header-end']),\n }\"\n >\n <button\n v-if=\"isMobile && showMenuButton\"\n type=\"button\"\n class=\"t-app-shell__menu-button\"\n :aria-label=\"menuLabel\"\n :aria-expanded=\"isSidebarOpen\"\n :aria-controls=\"sidebarId\"\n @click=\"toggleSidebar\"\n >\n <slot\n name=\"menu-icon\"\n :sidebar-open=\"isSidebarOpen\"\n >\n <MenuIcon\n v-bind=\"treeIconDefaults\"\n :size=\"24\"\n aria-hidden=\"true\"\n />\n </slot>\n </button>\n\n <div\n v-if=\"$slots['header-start']\"\n class=\"t-app-shell__header-start\"\n >\n <slot\n name=\"header-start\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div class=\"t-app-shell__header-content\">\n <slot\n name=\"header\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div\n v-if=\"$slots['header-end']\"\n class=\"t-app-shell__header-end\"\n >\n <slot\n name=\"header-end\"\n v-bind=\"slotProps\"\n />\n </div>\n </header>\n\n <aside\n v-if=\"!isMobile\"\n :id=\"sidebarId\"\n class=\"t-app-shell__sidebar\"\n :aria-label=\"sidebarLabel\"\n >\n <div\n v-if=\"$slots['sidebar-header']\"\n class=\"t-app-shell__sidebar-header\"\n >\n <slot\n name=\"sidebar-header\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div class=\"t-app-shell__sidebar-body\">\n <slot\n name=\"sidebar\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div\n v-if=\"$slots['sidebar-footer'] || showCollapseToggle\"\n class=\"t-app-shell__sidebar-footer\"\n >\n <slot\n name=\"sidebar-footer\"\n v-bind=\"slotProps\"\n />\n\n <button\n v-if=\"showCollapseToggle\"\n type=\"button\"\n class=\"t-app-shell__collapse-button\"\n :aria-label=\"isCollapsed ? expandLabel : collapseLabel\"\n :aria-expanded=\"!isCollapsed\"\n :aria-controls=\"sidebarId\"\n @click=\"toggleCollapsed\"\n >\n <slot\n name=\"collapse-icon\"\n :collapsed=\"effectiveCollapsed\"\n >\n <CollapseIcon\n v-bind=\"treeIconDefaults\"\n aria-hidden=\"true\"\n />\n </slot>\n </button>\n </div>\n </aside>\n\n <main class=\"t-app-shell__main\">\n <slot\n :mobile=\"isMobile\"\n :collapsed=\"effectiveCollapsed\"\n :immersive=\"isImmersive\"\n :toggle-immersive=\"toggleImmersive\"\n />\n </main>\n\n <transition name=\"t-app-shell-fade\">\n <div\n v-if=\"isMobile && isSidebarOpen && !isImmersive\"\n class=\"t-app-shell__overlay\"\n >\n <div\n class=\"t-app-shell__backdrop\"\n aria-hidden=\"true\"\n @click=\"onOverlayClick\"\n />\n <aside\n :id=\"sidebarId\"\n ref=\"surfaceRef\"\n class=\"t-app-shell__drawer\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-label=\"sidebarLabel\"\n tabindex=\"-1\"\n @keydown=\"onKeydown\"\n >\n <div class=\"t-app-shell__drawer-topbar\">\n <button\n type=\"button\"\n class=\"t-app-shell__drawer-close\"\n :aria-label=\"closeLabel\"\n @click=\"closeSidebar\"\n >\n <CloseIcon v-bind=\"treeIconDefaults\" />\n </button>\n </div>\n <div class=\"t-app-shell__drawer-body\">\n <div\n v-if=\"$slots['sidebar-header']\"\n class=\"t-app-shell__sidebar-header\"\n >\n <slot\n name=\"sidebar-header\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div class=\"t-app-shell__sidebar-body\">\n <slot\n name=\"sidebar\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div\n v-if=\"$slots['sidebar-footer']\"\n class=\"t-app-shell__sidebar-footer\"\n >\n <slot\n name=\"sidebar-footer\"\n v-bind=\"slotProps\"\n />\n </div>\n </div>\n </aside>\n </div>\n </transition>\n </component>\n</template>\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TBrandLockup.cjs","names":[],"sources":["../../src/components/TBrandLockup.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, getCurrentInstance, type Component } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport TText from './TText.vue';\n\nconst props = withDefaults(\n defineProps<{\n /** Product name. Truncates on overflow. */\n title?: string;\n /** Optional supporting line under the title. Truncates on overflow. */\n subtitle?: string;\n size?: TSize;\n /**\n * Collapse to the logo only, hiding the text — for a shell's collapsed rail.\n * When collapsed and used as a link, supply an accessible name on the logo\n * (e.g. `alt` on the `<img>`) since the visible text is gone.\n */\n collapsed?: boolean;\n /** Native href. Renders the lockup as an anchor. */\n href?: string;\n /** Route target. Renders as RouterLink when vue-router is available. */\n to?: string | Record<string, unknown>;\n }>(),\n {\n title: undefined,\n subtitle: undefined,\n size: 'md',\n collapsed: false,\n href: undefined,\n to: undefined,\n },\n);\n\nconst instance = getCurrentInstance();\n\nconst routerLink = computed<Component | null>(() => {\n if (!props.to) return null;\n return (instance?.appContext.components.RouterLink as Component | undefined) ?? null;\n});\n\nconst isLink = computed(() => Boolean(props.href || props.to));\n\nconst tag = computed<string | Component>(() => {\n if (props.to && routerLink.value) return routerLink.value;\n if (isLink.value) return 'a';\n return 'div';\n});\n\nconst linkProps = computed(() => {\n if (props.to && routerLink.value) return { to: props.to };\n if (isLink.value) {\n return { href: props.href ?? (typeof props.to === 'string' ? props.to : undefined) };\n }\n return {};\n});\n\nconst classes = computed(() => [\n 't-brand-lockup',\n `t-brand-lockup--${props.size}`,\n { 'is-collapsed': props.collapsed },\n]);\n\nconst showText = computed(() => !props.collapsed && Boolean(props.title || props.subtitle));\n</script>\n\n<template>\n <component\n :is=\"tag\"\n v-bind=\"linkProps\"\n :class=\"classes\"\n >\n <span class=\"t-brand-lockup__logo\">\n <slot name=\"logo\" />\n </span>\n <span\n v-if=\"showText\"\n class=\"t-brand-lockup__text\"\n >\n <TText\n v-if=\"title\"\n as=\"span\"\n class=\"t-brand-lockup__title\"\n weight=\"semibold\"\n truncate\n >\n {{ title }}\n </TText>\n <TText\n v-if=\"subtitle\"\n as=\"span\"\n class=\"t-brand-lockup__subtitle\"\n tone=\"muted\"\n size=\"sm\"\n truncate\n >\n {{ subtitle }}\n </TText>\n </span>\n </component>\n</template>\n"],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TBrandLockup.js","names":[],"sources":["../../src/components/TBrandLockup.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, getCurrentInstance, type Component } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport TText from './TText.vue';\n\nconst props = withDefaults(\n defineProps<{\n /** Product name. Truncates on overflow. */\n title?: string;\n /** Optional supporting line under the title. Truncates on overflow. */\n subtitle?: string;\n size?: TSize;\n /**\n * Collapse to the logo only, hiding the text — for a shell's collapsed rail.\n * When collapsed and used as a link, supply an accessible name on the logo\n * (e.g. `alt` on the `<img>`) since the visible text is gone.\n */\n collapsed?: boolean;\n /** Native href. Renders the lockup as an anchor. */\n href?: string;\n /** Route target. Renders as RouterLink when vue-router is available. */\n to?: string | Record<string, unknown>;\n }>(),\n {\n title: undefined,\n subtitle: undefined,\n size: 'md',\n collapsed: false,\n href: undefined,\n to: undefined,\n },\n);\n\nconst instance = getCurrentInstance();\n\nconst routerLink = computed<Component | null>(() => {\n if (!props.to) return null;\n return (instance?.appContext.components.RouterLink as Component | undefined) ?? null;\n});\n\nconst isLink = computed(() => Boolean(props.href || props.to));\n\nconst tag = computed<string | Component>(() => {\n if (props.to && routerLink.value) return routerLink.value;\n if (isLink.value) return 'a';\n return 'div';\n});\n\nconst linkProps = computed(() => {\n if (props.to && routerLink.value) return { to: props.to };\n if (isLink.value) {\n return { href: props.href ?? (typeof props.to === 'string' ? props.to : undefined) };\n }\n return {};\n});\n\nconst classes = computed(() => [\n 't-brand-lockup',\n `t-brand-lockup--${props.size}`,\n { 'is-collapsed': props.collapsed },\n]);\n\nconst showText = computed(() => !props.collapsed && Boolean(props.title || props.subtitle));\n</script>\n\n<template>\n <component\n :is=\"tag\"\n v-bind=\"linkProps\"\n :class=\"classes\"\n >\n <span class=\"t-brand-lockup__logo\">\n <slot name=\"logo\" />\n </span>\n <span\n v-if=\"showText\"\n class=\"t-brand-lockup__text\"\n >\n <TText\n v-if=\"title\"\n as=\"span\"\n class=\"t-brand-lockup__title\"\n weight=\"semibold\"\n truncate\n >\n {{ title }}\n </TText>\n <TText\n v-if=\"subtitle\"\n as=\"span\"\n class=\"t-brand-lockup__subtitle\"\n tone=\"muted\"\n size=\"sm\"\n truncate\n >\n {{ subtitle }}\n </TText>\n </span>\n </component>\n</template>\n"],"mappings":""}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { TSize } from '../types/contracts';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
/** Product name. Truncates on overflow. */
|
|
4
|
+
title?: string;
|
|
5
|
+
/** Optional supporting line under the title. Truncates on overflow. */
|
|
6
|
+
subtitle?: string;
|
|
7
|
+
size?: TSize;
|
|
8
|
+
/**
|
|
9
|
+
* Collapse to the logo only, hiding the text — for a shell's collapsed rail.
|
|
10
|
+
* When collapsed and used as a link, supply an accessible name on the logo
|
|
11
|
+
* (e.g. `alt` on the `<img>`) since the visible text is gone.
|
|
12
|
+
*/
|
|
13
|
+
collapsed?: boolean;
|
|
14
|
+
/** Native href. Renders the lockup as an anchor. */
|
|
15
|
+
href?: string;
|
|
16
|
+
/** Route target. Renders as RouterLink when vue-router is available. */
|
|
17
|
+
to?: string | Record<string, unknown>;
|
|
18
|
+
};
|
|
19
|
+
declare function __VLS_template(): {
|
|
20
|
+
attrs: Partial<{}>;
|
|
21
|
+
slots: {
|
|
22
|
+
logo?(_: {}): any;
|
|
23
|
+
};
|
|
24
|
+
refs: {};
|
|
25
|
+
rootEl: any;
|
|
26
|
+
};
|
|
27
|
+
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
|
|
28
|
+
declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
29
|
+
size: TSize;
|
|
30
|
+
title: string;
|
|
31
|
+
href: string;
|
|
32
|
+
to: string | Record<string, unknown>;
|
|
33
|
+
subtitle: string;
|
|
34
|
+
collapsed: boolean;
|
|
35
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
36
|
+
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
|
|
37
|
+
export default _default;
|
|
38
|
+
type __VLS_WithTemplateSlots<T, S> = T & {
|
|
39
|
+
new (): {
|
|
40
|
+
$slots: S;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=TBrandLockup.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TBrandLockup.vue.d.ts","sourceRoot":"","sources":["../../src/components/TBrandLockup.vue"],"names":[],"mappings":"AAuGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAGhD,KAAK,WAAW,GAAG;IACf,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,KAAK,CAAC;IACb;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC,CAAC;AAsDJ,iBAAS,cAAc;WAoFT,OAAO,IAA6B;;sBAVxB,GAAG;;;;EAe5B;AAcD,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAC9D,QAAA,MAAM,eAAe;UAzKV,KAAK;WAHJ,MAAM;UAWP,MAAM;QAER,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;cAX1B,MAAM;eAOL,OAAO;6EA2KrB,CAAC;wBACkB,uBAAuB,CAAC,OAAO,eAAe,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAAnG,wBAAoG;AAapG,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IACxC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("./TText.cjs");let t=require("vue");var n={class:`t-brand-lockup__logo`},r={key:0,class:`t-brand-lockup__text`},i=(0,t.defineComponent)({__name:`TBrandLockup`,props:{title:{default:void 0},subtitle:{default:void 0},size:{default:`md`},collapsed:{type:Boolean,default:!1},href:{default:void 0},to:{default:void 0}},setup(i){let a=i,o=(0,t.getCurrentInstance)(),s=(0,t.computed)(()=>a.to?o?.appContext.components.RouterLink??null:null),c=(0,t.computed)(()=>!!(a.href||a.to)),l=(0,t.computed)(()=>a.to&&s.value?s.value:c.value?`a`:`div`),u=(0,t.computed)(()=>a.to&&s.value?{to:a.to}:c.value?{href:a.href??(typeof a.to==`string`?a.to:void 0)}:{}),d=(0,t.computed)(()=>[`t-brand-lockup`,`t-brand-lockup--${a.size}`,{"is-collapsed":a.collapsed}]),f=(0,t.computed)(()=>!a.collapsed&&!!(a.title||a.subtitle));return(a,o)=>((0,t.openBlock)(),(0,t.createBlock)((0,t.resolveDynamicComponent)(l.value),(0,t.mergeProps)(u.value,{class:d.value}),{default:(0,t.withCtx)(()=>[(0,t.createElementVNode)(`span`,n,[(0,t.renderSlot)(a.$slots,`logo`)]),f.value?((0,t.openBlock)(),(0,t.createElementBlock)(`span`,r,[i.title?((0,t.openBlock)(),(0,t.createBlock)(e.default,{key:0,as:`span`,class:`t-brand-lockup__title`,weight:`semibold`,truncate:``},{default:(0,t.withCtx)(()=>[(0,t.createTextVNode)((0,t.toDisplayString)(i.title),1)]),_:1})):(0,t.createCommentVNode)(``,!0),i.subtitle?((0,t.openBlock)(),(0,t.createBlock)(e.default,{key:1,as:`span`,class:`t-brand-lockup__subtitle`,tone:`muted`,size:`sm`,truncate:``},{default:(0,t.withCtx)(()=>[(0,t.createTextVNode)((0,t.toDisplayString)(i.subtitle),1)]),_:1})):(0,t.createCommentVNode)(``,!0)])):(0,t.createCommentVNode)(``,!0)]),_:3},16,[`class`]))}});exports.default=i;
|
|
2
|
+
//# sourceMappingURL=TBrandLockup.vue_vue_type_script_setup_true_lang.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TBrandLockup.vue_vue_type_script_setup_true_lang.cjs","names":[],"sources":["../../src/components/TBrandLockup.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, getCurrentInstance, type Component } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport TText from './TText.vue';\n\nconst props = withDefaults(\n defineProps<{\n /** Product name. Truncates on overflow. */\n title?: string;\n /** Optional supporting line under the title. Truncates on overflow. */\n subtitle?: string;\n size?: TSize;\n /**\n * Collapse to the logo only, hiding the text — for a shell's collapsed rail.\n * When collapsed and used as a link, supply an accessible name on the logo\n * (e.g. `alt` on the `<img>`) since the visible text is gone.\n */\n collapsed?: boolean;\n /** Native href. Renders the lockup as an anchor. */\n href?: string;\n /** Route target. Renders as RouterLink when vue-router is available. */\n to?: string | Record<string, unknown>;\n }>(),\n {\n title: undefined,\n subtitle: undefined,\n size: 'md',\n collapsed: false,\n href: undefined,\n to: undefined,\n },\n);\n\nconst instance = getCurrentInstance();\n\nconst routerLink = computed<Component | null>(() => {\n if (!props.to) return null;\n return (instance?.appContext.components.RouterLink as Component | undefined) ?? null;\n});\n\nconst isLink = computed(() => Boolean(props.href || props.to));\n\nconst tag = computed<string | Component>(() => {\n if (props.to && routerLink.value) return routerLink.value;\n if (isLink.value) return 'a';\n return 'div';\n});\n\nconst linkProps = computed(() => {\n if (props.to && routerLink.value) return { to: props.to };\n if (isLink.value) {\n return { href: props.href ?? (typeof props.to === 'string' ? props.to : undefined) };\n }\n return {};\n});\n\nconst classes = computed(() => [\n 't-brand-lockup',\n `t-brand-lockup--${props.size}`,\n { 'is-collapsed': props.collapsed },\n]);\n\nconst showText = computed(() => !props.collapsed && Boolean(props.title || props.subtitle));\n</script>\n\n<template>\n <component\n :is=\"tag\"\n v-bind=\"linkProps\"\n :class=\"classes\"\n >\n <span class=\"t-brand-lockup__logo\">\n <slot name=\"logo\" />\n </span>\n <span\n v-if=\"showText\"\n class=\"t-brand-lockup__text\"\n >\n <TText\n v-if=\"title\"\n as=\"span\"\n class=\"t-brand-lockup__title\"\n weight=\"semibold\"\n truncate\n >\n {{ title }}\n </TText>\n <TText\n v-if=\"subtitle\"\n as=\"span\"\n class=\"t-brand-lockup__subtitle\"\n tone=\"muted\"\n size=\"sm\"\n truncate\n >\n {{ subtitle }}\n </TText>\n </span>\n </component>\n</template>\n"],"mappings":"mVAKA,IAAM,EAAQ,EA4BR,GAAA,EAAA,EAAA,mBAAA,CAA8B,EAE9B,GAAA,EAAA,EAAA,SAAA,KACC,EAAM,GACH,GAAU,WAAW,WAAW,YAAwC,KAD1D,IAEvB,EAEK,GAAA,EAAA,EAAA,SAAA,KAAwB,GAAQ,EAAM,MAAQ,EAAM,GAAG,EAEvD,GAAA,EAAA,EAAA,SAAA,KACA,EAAM,IAAM,EAAW,MAAc,EAAW,MAChD,EAAO,MAAc,IAClB,KACR,EAEK,GAAA,EAAA,EAAA,SAAA,KACA,EAAM,IAAM,EAAW,MAAc,CAAE,GAAI,EAAM,EAAG,EACpD,EAAO,MACF,CAAE,KAAM,EAAM,OAAS,OAAO,EAAM,IAAO,SAAW,EAAM,GAAK,IAAA,GAAW,EAE9E,CAAC,CACT,EAEK,GAAA,EAAA,EAAA,SAAA,KAAyB,CAC7B,iBACA,mBAAmB,EAAM,OACzB,CAAE,eAAgB,EAAM,SAAU,CACpC,CAAC,EAEK,GAAA,EAAA,EAAA,SAAA,KAA0B,CAAC,EAAM,WAAa,GAAQ,EAAM,OAAS,EAAM,SAAS,kFAKjF,EAAA,KAAG,GAAA,EAAA,EAAA,WAAA,CACA,EA8BE,MA9BO,CAChB,MAAO,EAAA,KAAO,CAAA,EAAA,2BAIR,EAAA,EAAA,EAAA,mBAAA,CAAA,OAFP,EAEO,EAAA,EAAA,EAAA,WAAA,CADe,EAAA,OAAA,MAAA,CAAA,CAAA,EAGd,EAAA,QAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAsBD,OAvBP,EAuBO,CAlBG,EAAA,QAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,YAAA,CAOA,EAAA,QAAA,OANN,GAAG,OACH,MAAM,wBACN,OAAO,WACP,SAAA,+BAEW,EAAA,EAAA,EAAA,gBAAA,EAAA,EAAA,EAAA,gBAAA,CAAR,EAAA,KAAK,EAAA,CAAA,CAAA,CAAA,yCAGF,EAAA,WAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,YAAA,CAQA,EAAA,QAAA,OAPN,GAAG,OACH,MAAM,2BACN,KAAK,QACL,KAAK,KACL,SAAA,+BAEc,EAAA,EAAA,EAAA,gBAAA,EAAA,EAAA,EAAA,gBAAA,CAAX,EAAA,QAAQ,EAAA,CAAA,CAAA,CAAA"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import e from "./TText.js";
|
|
2
|
+
import { computed as t, createBlock as n, createCommentVNode as r, createElementBlock as i, createElementVNode as a, createTextVNode as o, defineComponent as s, getCurrentInstance as c, mergeProps as l, openBlock as u, renderSlot as d, resolveDynamicComponent as f, toDisplayString as p, withCtx as m } from "vue";
|
|
3
|
+
//#region src/components/TBrandLockup.vue?vue&type=script&setup=true&lang.ts
|
|
4
|
+
var h = { class: "t-brand-lockup__logo" }, g = {
|
|
5
|
+
key: 0,
|
|
6
|
+
class: "t-brand-lockup__text"
|
|
7
|
+
}, _ = /*@__PURE__*/ s({
|
|
8
|
+
__name: "TBrandLockup",
|
|
9
|
+
props: {
|
|
10
|
+
title: { default: void 0 },
|
|
11
|
+
subtitle: { default: void 0 },
|
|
12
|
+
size: { default: "md" },
|
|
13
|
+
collapsed: {
|
|
14
|
+
type: Boolean,
|
|
15
|
+
default: !1
|
|
16
|
+
},
|
|
17
|
+
href: { default: void 0 },
|
|
18
|
+
to: { default: void 0 }
|
|
19
|
+
},
|
|
20
|
+
setup(s) {
|
|
21
|
+
let _ = s, v = c(), y = t(() => _.to ? v?.appContext.components.RouterLink ?? null : null), b = t(() => !!(_.href || _.to)), x = t(() => _.to && y.value ? y.value : b.value ? "a" : "div"), S = t(() => _.to && y.value ? { to: _.to } : b.value ? { href: _.href ?? (typeof _.to == "string" ? _.to : void 0) } : {}), C = t(() => [
|
|
22
|
+
"t-brand-lockup",
|
|
23
|
+
`t-brand-lockup--${_.size}`,
|
|
24
|
+
{ "is-collapsed": _.collapsed }
|
|
25
|
+
]), w = t(() => !_.collapsed && !!(_.title || _.subtitle));
|
|
26
|
+
return (t, c) => (u(), n(f(x.value), l(S.value, { class: C.value }), {
|
|
27
|
+
default: m(() => [a("span", h, [d(t.$slots, "logo")]), w.value ? (u(), i("span", g, [s.title ? (u(), n(e, {
|
|
28
|
+
key: 0,
|
|
29
|
+
as: "span",
|
|
30
|
+
class: "t-brand-lockup__title",
|
|
31
|
+
weight: "semibold",
|
|
32
|
+
truncate: ""
|
|
33
|
+
}, {
|
|
34
|
+
default: m(() => [o(p(s.title), 1)]),
|
|
35
|
+
_: 1
|
|
36
|
+
})) : r("", !0), s.subtitle ? (u(), n(e, {
|
|
37
|
+
key: 1,
|
|
38
|
+
as: "span",
|
|
39
|
+
class: "t-brand-lockup__subtitle",
|
|
40
|
+
tone: "muted",
|
|
41
|
+
size: "sm",
|
|
42
|
+
truncate: ""
|
|
43
|
+
}, {
|
|
44
|
+
default: m(() => [o(p(s.subtitle), 1)]),
|
|
45
|
+
_: 1
|
|
46
|
+
})) : r("", !0)])) : r("", !0)]),
|
|
47
|
+
_: 3
|
|
48
|
+
}, 16, ["class"]));
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
//#endregion
|
|
52
|
+
export { _ as default };
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=TBrandLockup.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TBrandLockup.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../src/components/TBrandLockup.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, getCurrentInstance, type Component } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport TText from './TText.vue';\n\nconst props = withDefaults(\n defineProps<{\n /** Product name. Truncates on overflow. */\n title?: string;\n /** Optional supporting line under the title. Truncates on overflow. */\n subtitle?: string;\n size?: TSize;\n /**\n * Collapse to the logo only, hiding the text — for a shell's collapsed rail.\n * When collapsed and used as a link, supply an accessible name on the logo\n * (e.g. `alt` on the `<img>`) since the visible text is gone.\n */\n collapsed?: boolean;\n /** Native href. Renders the lockup as an anchor. */\n href?: string;\n /** Route target. Renders as RouterLink when vue-router is available. */\n to?: string | Record<string, unknown>;\n }>(),\n {\n title: undefined,\n subtitle: undefined,\n size: 'md',\n collapsed: false,\n href: undefined,\n to: undefined,\n },\n);\n\nconst instance = getCurrentInstance();\n\nconst routerLink = computed<Component | null>(() => {\n if (!props.to) return null;\n return (instance?.appContext.components.RouterLink as Component | undefined) ?? null;\n});\n\nconst isLink = computed(() => Boolean(props.href || props.to));\n\nconst tag = computed<string | Component>(() => {\n if (props.to && routerLink.value) return routerLink.value;\n if (isLink.value) return 'a';\n return 'div';\n});\n\nconst linkProps = computed(() => {\n if (props.to && routerLink.value) return { to: props.to };\n if (isLink.value) {\n return { href: props.href ?? (typeof props.to === 'string' ? props.to : undefined) };\n }\n return {};\n});\n\nconst classes = computed(() => [\n 't-brand-lockup',\n `t-brand-lockup--${props.size}`,\n { 'is-collapsed': props.collapsed },\n]);\n\nconst showText = computed(() => !props.collapsed && Boolean(props.title || props.subtitle));\n</script>\n\n<template>\n <component\n :is=\"tag\"\n v-bind=\"linkProps\"\n :class=\"classes\"\n >\n <span class=\"t-brand-lockup__logo\">\n <slot name=\"logo\" />\n </span>\n <span\n v-if=\"showText\"\n class=\"t-brand-lockup__text\"\n >\n <TText\n v-if=\"title\"\n as=\"span\"\n class=\"t-brand-lockup__title\"\n weight=\"semibold\"\n truncate\n >\n {{ title }}\n </TText>\n <TText\n v-if=\"subtitle\"\n as=\"span\"\n class=\"t-brand-lockup__subtitle\"\n tone=\"muted\"\n size=\"sm\"\n truncate\n >\n {{ subtitle }}\n </TText>\n </span>\n </component>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;EAKA,IAAM,IAAQ,GA4BR,IAAW,EAAmB,GAE9B,IAAa,QACZ,EAAM,KACH,GAAU,WAAW,WAAW,cAAwC,OAD1D,IAEvB,GAEK,IAAS,QAAe,GAAQ,EAAM,QAAQ,EAAM,GAAG,GAEvD,IAAM,QACN,EAAM,MAAM,EAAW,QAAc,EAAW,QAChD,EAAO,QAAc,MAClB,KACR,GAEK,IAAY,QACZ,EAAM,MAAM,EAAW,QAAc,EAAE,IAAI,EAAM,GAAG,IACpD,EAAO,QACF,EAAE,MAAM,EAAM,SAAS,OAAO,EAAM,MAAO,WAAW,EAAM,KAAK,KAAA,GAAW,IAE9E,CAAC,CACT,GAEK,IAAU,QAAe;GAC7B;GACA,mBAAmB,EAAM;GACzB,EAAE,gBAAgB,EAAM,UAAU;EACpC,CAAC,GAEK,IAAW,QAAe,CAAC,EAAM,aAAa,GAAQ,EAAM,SAAS,EAAM,SAAS;yBAIxF,EAgCY,EA/BL,EAAA,KAAG,GADV,EAEU,EA8BE,OA9BO,EAChB,OAAO,EAAA,MAAO,CAAA,GAAA;oBAIR,CAFP,EAEO,QAFP,GAEO,CADL,EAAoB,EAAA,QAAA,MAAA,CAAA,CAAA,GAGd,EAAA,SAAA,EAAA,GADR,EAuBO,QAvBP,GAuBO,CAlBG,EAAA,SAAA,EAAA,GADR,EAQQ,GAAA;;IANN,IAAG;IACH,OAAM;IACN,QAAO;IACP,UAAA;;qBAEW,CAAA,EAAA,EAAR,EAAA,KAAK,GAAA,CAAA,CAAA,CAAA;;oBAGF,EAAA,YAAA,EAAA,GADR,EASQ,GAAA;;IAPN,IAAG;IACH,OAAM;IACN,MAAK;IACL,MAAK;IACL,UAAA;;qBAEc,CAAA,EAAA,EAAX,EAAA,QAAQ,GAAA,CAAA,CAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TButton.cjs","names":[],"sources":["../../src/components/TButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { tv } from '@treeui/utils';\nimport type { TSize, TVariant } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n variant?: TVariant | 'brand';\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n /**\n * Accessible announcement while `loading`, forwarded to the spinner.\n * The default is English; pass the active locale's string to localize it.\n */\n loadingLabel?: string;\n /**\n * While `loading`, hide the `icon` slot so the spinner replaces the icon\n * instead of rendering beside it. Set to `false` to keep both visible.\n */\n hideIconWhileLoading?: boolean;\n /**\n * Square, icon-only button. The visible label is dropped, so an accessible\n * name is required — pass `label` (or `aria-label`).\n */\n iconOnly?: boolean;\n /** Accessible name, rendered as `aria-label`. Required when `iconOnly`. */\n label?: string;\n type?: 'button' | 'submit' | 'reset';\n /** Stretch to the full width of the container. */\n block?: boolean;\n /** Content alignment — only meaningful together with `block`. */\n align?: 'start' | 'center' | 'end';\n }>(),\n {\n as: 'button',\n variant: 'solid',\n size: 'md',\n disabled: false,\n loading: false,\n loadingLabel: 'Loading',\n hideIconWhileLoading: true,\n iconOnly: false,\n label: undefined,\n type: 'button',\n block: false,\n align: 'center',\n },\n);\n\nconst emit = defineEmits<{\n click: [event: MouseEvent];\n}>();\n\nconst buttonClass = tv({\n base: 't-button',\n variants: {\n variant: {\n solid: 't-button--solid',\n outline: 't-button--outline',\n ghost: 't-button--ghost',\n soft: 't-button--soft',\n danger: 't-button--danger',\n brand: 't-button--brand',\n },\n size: {\n sm: 't-button--sm',\n md: 't-button--md',\n lg: 't-button--lg',\n },\n },\n});\n\nconst isNativeButton = computed(() => props.as === 'button');\nconst isDisabled = computed(() => props.disabled || props.loading);\n\n// The spinner takes the icon's leading position, so rendering both would show\n// two glyphs and widen the button mid-action.\nconst isIconHidden = computed(() => props.loading && props.hideIconWhileLoading);\n\nconst classes = computed(() =>\n buttonClass({\n variant: props.variant,\n size: props.size,\n class: {\n 'is-loading': props.loading,\n 'is-disabled': isDisabled.value,\n 't-button--block': props.block,\n 't-button--icon': props.iconOnly,\n 't-button--align-start': props.align === 'start',\n 't-button--align-end': props.align === 'end',\n },\n }),\n);\n\nconst onClick = (event: MouseEvent) => {\n if (isDisabled.value) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n emit('click', event);\n};\n</script>\n\n<template>\n <component\n :is=\"as\"\n :type=\"isNativeButton ? type : undefined\"\n :class=\"classes\"\n :disabled=\"isNativeButton ? isDisabled : undefined\"\n :aria-disabled=\"!isNativeButton && isDisabled ? 'true' : undefined\"\n :aria-busy=\"loading || undefined\"\n :aria-label=\"label\"\n :tabindex=\"!isNativeButton && isDisabled ? -1 : undefined\"\n @click=\"onClick\"\n >\n <span\n v-if=\"loading\"\n class=\"t-button__spinner\"\n >\n <TSpinner\n size=\"sm\"\n :label=\"loadingLabel\"\n />\n </span>\n <span\n v-if=\"$slots.icon && !isIconHidden\"\n class=\"t-button__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\" />\n </span>\n <span\n v-if=\"!iconOnly\"\n class=\"t-button__label\"\n >\n <slot />\n </span>\n </component>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"TButton.cjs","names":[],"sources":["../../src/components/TButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, useAttrs, watchEffect } from 'vue';\nimport { tv } from '@treeui/utils';\nimport type { TSize, TVariant } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n variant?: TVariant | 'brand';\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n /**\n * Accessible announcement while `loading`, forwarded to the spinner.\n * The default is English; pass the active locale's string to localize it.\n */\n loadingLabel?: string;\n /**\n * While `loading`, hide the `icon` slot so the spinner replaces the icon\n * instead of rendering beside it. Set to `false` to keep both visible.\n */\n hideIconWhileLoading?: boolean;\n /**\n * Square, icon-only button. The visible label is dropped, so an accessible\n * name is required — pass `label` (or `aria-label`).\n */\n iconOnly?: boolean;\n /** Accessible name, rendered as `aria-label`. Required when `iconOnly`. */\n label?: string;\n type?: 'button' | 'submit' | 'reset';\n /** Stretch to the full width of the container. */\n block?: boolean;\n /** Content alignment — only meaningful together with `block`. */\n align?: 'start' | 'center' | 'end';\n }>(),\n {\n as: 'button',\n variant: 'solid',\n size: 'md',\n disabled: false,\n loading: false,\n loadingLabel: 'Loading',\n hideIconWhileLoading: true,\n iconOnly: false,\n label: undefined,\n type: 'button',\n block: false,\n align: 'center',\n },\n);\n\nconst emit = defineEmits<{\n click: [event: MouseEvent];\n}>();\n\nconst buttonClass = tv({\n base: 't-button',\n variants: {\n variant: {\n solid: 't-button--solid',\n outline: 't-button--outline',\n ghost: 't-button--ghost',\n soft: 't-button--soft',\n danger: 't-button--danger',\n brand: 't-button--brand',\n },\n size: {\n sm: 't-button--sm',\n md: 't-button--md',\n lg: 't-button--lg',\n },\n },\n});\n\nconst attrs = useAttrs();\nconst isNativeButton = computed(() => props.as === 'button');\nconst isDisabled = computed(() => props.disabled || props.loading);\n\n// An icon-only button has no visible text and an aria-hidden icon, so without a\n// name it is unlabelled for assistive tech. This is a BARE `process.env.NODE_ENV`\n// compare, inlined (no `typeof process` guard, no function wrapper): the\n// consumer's bundler statically replaces it, so the whole block runs in their\n// dev build and is dead-code-eliminated — string literals included — from their\n// production build. A `typeof process` guard would be `false` in the browser\n// (where `process` does not exist), silently disabling the warning; a function\n// wrapper would be opaque to tree-shaking. TreeUI's own build keeps\n// `process.env.NODE_ENV` as a runtime reference (vite.config `define`) so the\n// decision belongs to the consumer's environment, not this build.\nif (process.env.NODE_ENV !== 'production') {\n watchEffect(() => {\n if (\n props.iconOnly &&\n !props.label &&\n !attrs['aria-label'] &&\n !attrs['aria-labelledby']\n ) {\n console.warn(\n '[TButton] `iconOnly` needs an accessible name — pass the `label` prop (or `aria-label`).',\n );\n }\n });\n}\n\n// The spinner takes the icon's leading position, so rendering both would show\n// two glyphs and widen the button mid-action.\nconst isIconHidden = computed(() => props.loading && props.hideIconWhileLoading);\n\nconst classes = computed(() =>\n buttonClass({\n variant: props.variant,\n size: props.size,\n class: {\n 'is-loading': props.loading,\n 'is-disabled': isDisabled.value,\n 't-button--block': props.block,\n 't-button--icon': props.iconOnly,\n 't-button--align-start': props.align === 'start',\n 't-button--align-end': props.align === 'end',\n },\n }),\n);\n\nconst onClick = (event: MouseEvent) => {\n if (isDisabled.value) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n emit('click', event);\n};\n</script>\n\n<template>\n <component\n :is=\"as\"\n :type=\"isNativeButton ? type : undefined\"\n :class=\"classes\"\n :disabled=\"isNativeButton ? isDisabled : undefined\"\n :aria-disabled=\"!isNativeButton && isDisabled ? 'true' : undefined\"\n :aria-busy=\"loading || undefined\"\n :aria-label=\"label\"\n :tabindex=\"!isNativeButton && isDisabled ? -1 : undefined\"\n @click=\"onClick\"\n >\n <span\n v-if=\"loading\"\n class=\"t-button__spinner\"\n >\n <TSpinner\n size=\"sm\"\n :label=\"loadingLabel\"\n />\n </span>\n <span\n v-if=\"$slots.icon && !isIconHidden\"\n class=\"t-button__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\" />\n </span>\n <span\n v-if=\"!iconOnly\"\n class=\"t-button__label\"\n >\n <slot />\n </span>\n </component>\n</template>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TButton.js","names":[],"sources":["../../src/components/TButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { tv } from '@treeui/utils';\nimport type { TSize, TVariant } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n variant?: TVariant | 'brand';\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n /**\n * Accessible announcement while `loading`, forwarded to the spinner.\n * The default is English; pass the active locale's string to localize it.\n */\n loadingLabel?: string;\n /**\n * While `loading`, hide the `icon` slot so the spinner replaces the icon\n * instead of rendering beside it. Set to `false` to keep both visible.\n */\n hideIconWhileLoading?: boolean;\n /**\n * Square, icon-only button. The visible label is dropped, so an accessible\n * name is required — pass `label` (or `aria-label`).\n */\n iconOnly?: boolean;\n /** Accessible name, rendered as `aria-label`. Required when `iconOnly`. */\n label?: string;\n type?: 'button' | 'submit' | 'reset';\n /** Stretch to the full width of the container. */\n block?: boolean;\n /** Content alignment — only meaningful together with `block`. */\n align?: 'start' | 'center' | 'end';\n }>(),\n {\n as: 'button',\n variant: 'solid',\n size: 'md',\n disabled: false,\n loading: false,\n loadingLabel: 'Loading',\n hideIconWhileLoading: true,\n iconOnly: false,\n label: undefined,\n type: 'button',\n block: false,\n align: 'center',\n },\n);\n\nconst emit = defineEmits<{\n click: [event: MouseEvent];\n}>();\n\nconst buttonClass = tv({\n base: 't-button',\n variants: {\n variant: {\n solid: 't-button--solid',\n outline: 't-button--outline',\n ghost: 't-button--ghost',\n soft: 't-button--soft',\n danger: 't-button--danger',\n brand: 't-button--brand',\n },\n size: {\n sm: 't-button--sm',\n md: 't-button--md',\n lg: 't-button--lg',\n },\n },\n});\n\nconst isNativeButton = computed(() => props.as === 'button');\nconst isDisabled = computed(() => props.disabled || props.loading);\n\n// The spinner takes the icon's leading position, so rendering both would show\n// two glyphs and widen the button mid-action.\nconst isIconHidden = computed(() => props.loading && props.hideIconWhileLoading);\n\nconst classes = computed(() =>\n buttonClass({\n variant: props.variant,\n size: props.size,\n class: {\n 'is-loading': props.loading,\n 'is-disabled': isDisabled.value,\n 't-button--block': props.block,\n 't-button--icon': props.iconOnly,\n 't-button--align-start': props.align === 'start',\n 't-button--align-end': props.align === 'end',\n },\n }),\n);\n\nconst onClick = (event: MouseEvent) => {\n if (isDisabled.value) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n emit('click', event);\n};\n</script>\n\n<template>\n <component\n :is=\"as\"\n :type=\"isNativeButton ? type : undefined\"\n :class=\"classes\"\n :disabled=\"isNativeButton ? isDisabled : undefined\"\n :aria-disabled=\"!isNativeButton && isDisabled ? 'true' : undefined\"\n :aria-busy=\"loading || undefined\"\n :aria-label=\"label\"\n :tabindex=\"!isNativeButton && isDisabled ? -1 : undefined\"\n @click=\"onClick\"\n >\n <span\n v-if=\"loading\"\n class=\"t-button__spinner\"\n >\n <TSpinner\n size=\"sm\"\n :label=\"loadingLabel\"\n />\n </span>\n <span\n v-if=\"$slots.icon && !isIconHidden\"\n class=\"t-button__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\" />\n </span>\n <span\n v-if=\"!iconOnly\"\n class=\"t-button__label\"\n >\n <slot />\n </span>\n </component>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"TButton.js","names":[],"sources":["../../src/components/TButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, useAttrs, watchEffect } from 'vue';\nimport { tv } from '@treeui/utils';\nimport type { TSize, TVariant } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n variant?: TVariant | 'brand';\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n /**\n * Accessible announcement while `loading`, forwarded to the spinner.\n * The default is English; pass the active locale's string to localize it.\n */\n loadingLabel?: string;\n /**\n * While `loading`, hide the `icon` slot so the spinner replaces the icon\n * instead of rendering beside it. Set to `false` to keep both visible.\n */\n hideIconWhileLoading?: boolean;\n /**\n * Square, icon-only button. The visible label is dropped, so an accessible\n * name is required — pass `label` (or `aria-label`).\n */\n iconOnly?: boolean;\n /** Accessible name, rendered as `aria-label`. Required when `iconOnly`. */\n label?: string;\n type?: 'button' | 'submit' | 'reset';\n /** Stretch to the full width of the container. */\n block?: boolean;\n /** Content alignment — only meaningful together with `block`. */\n align?: 'start' | 'center' | 'end';\n }>(),\n {\n as: 'button',\n variant: 'solid',\n size: 'md',\n disabled: false,\n loading: false,\n loadingLabel: 'Loading',\n hideIconWhileLoading: true,\n iconOnly: false,\n label: undefined,\n type: 'button',\n block: false,\n align: 'center',\n },\n);\n\nconst emit = defineEmits<{\n click: [event: MouseEvent];\n}>();\n\nconst buttonClass = tv({\n base: 't-button',\n variants: {\n variant: {\n solid: 't-button--solid',\n outline: 't-button--outline',\n ghost: 't-button--ghost',\n soft: 't-button--soft',\n danger: 't-button--danger',\n brand: 't-button--brand',\n },\n size: {\n sm: 't-button--sm',\n md: 't-button--md',\n lg: 't-button--lg',\n },\n },\n});\n\nconst attrs = useAttrs();\nconst isNativeButton = computed(() => props.as === 'button');\nconst isDisabled = computed(() => props.disabled || props.loading);\n\n// An icon-only button has no visible text and an aria-hidden icon, so without a\n// name it is unlabelled for assistive tech. This is a BARE `process.env.NODE_ENV`\n// compare, inlined (no `typeof process` guard, no function wrapper): the\n// consumer's bundler statically replaces it, so the whole block runs in their\n// dev build and is dead-code-eliminated — string literals included — from their\n// production build. A `typeof process` guard would be `false` in the browser\n// (where `process` does not exist), silently disabling the warning; a function\n// wrapper would be opaque to tree-shaking. TreeUI's own build keeps\n// `process.env.NODE_ENV` as a runtime reference (vite.config `define`) so the\n// decision belongs to the consumer's environment, not this build.\nif (process.env.NODE_ENV !== 'production') {\n watchEffect(() => {\n if (\n props.iconOnly &&\n !props.label &&\n !attrs['aria-label'] &&\n !attrs['aria-labelledby']\n ) {\n console.warn(\n '[TButton] `iconOnly` needs an accessible name — pass the `label` prop (or `aria-label`).',\n );\n }\n });\n}\n\n// The spinner takes the icon's leading position, so rendering both would show\n// two glyphs and widen the button mid-action.\nconst isIconHidden = computed(() => props.loading && props.hideIconWhileLoading);\n\nconst classes = computed(() =>\n buttonClass({\n variant: props.variant,\n size: props.size,\n class: {\n 'is-loading': props.loading,\n 'is-disabled': isDisabled.value,\n 't-button--block': props.block,\n 't-button--icon': props.iconOnly,\n 't-button--align-start': props.align === 'start',\n 't-button--align-end': props.align === 'end',\n },\n }),\n);\n\nconst onClick = (event: MouseEvent) => {\n if (isDisabled.value) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n emit('click', event);\n};\n</script>\n\n<template>\n <component\n :is=\"as\"\n :type=\"isNativeButton ? type : undefined\"\n :class=\"classes\"\n :disabled=\"isNativeButton ? isDisabled : undefined\"\n :aria-disabled=\"!isNativeButton && isDisabled ? 'true' : undefined\"\n :aria-busy=\"loading || undefined\"\n :aria-label=\"label\"\n :tabindex=\"!isNativeButton && isDisabled ? -1 : undefined\"\n @click=\"onClick\"\n >\n <span\n v-if=\"loading\"\n class=\"t-button__spinner\"\n >\n <TSpinner\n size=\"sm\"\n :label=\"loadingLabel\"\n />\n </span>\n <span\n v-if=\"$slots.icon && !isIconHidden\"\n class=\"t-button__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\" />\n </span>\n <span\n v-if=\"!iconOnly\"\n class=\"t-button__label\"\n >\n <slot />\n </span>\n </component>\n</template>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TButton.vue.d.ts","sourceRoot":"","sources":["../../src/components/TButton.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TButton.vue.d.ts","sourceRoot":"","sources":["../../src/components/TButton.vue"],"names":[],"mappings":"AA8KA,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG1D,KAAK,WAAW,GAAG;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC7B,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;IACrC,kDAAkD;IAClD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iEAAiE;IACjE,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;CACpC,CAAC;AAqHJ,iBAAS,cAAc;WAiFT,OAAO,IAA6B;;sBAXvB,GAAG;yBACA,GAAG;;;;EAehC;AAgBD,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAC9D,QAAA,MAAM,eAAe;;;;;UAjOV,QAAQ,GAAG,QAAQ,GAAG,OAAO;cAnBzB,OAAO;UADX,KAAK;WAmBJ,MAAM;aApBJ,QAAQ,GAAG,OAAO;QADvB,MAAM;aAID,OAAO;kBAKF,MAAM;0BAKE,OAAO;cAKnB,OAAO;WAKV,OAAO;WAEP,OAAO,GAAG,QAAQ,GAAG,KAAK;6EAsOpC,CAAC;wBACkB,uBAAuB,CAAC,OAAO,eAAe,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAAnG,wBAAoG;AAapG,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IACxC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./TSpinner.cjs");let t=require("vue"),n=require("@treeui/utils");var r={key:0,class:`t-button__spinner`},i={key:1,class:`t-button__icon`,"aria-hidden":`true`},a={key:2,class:`t-button__label`},o=(0,t.defineComponent)({__name:`TButton`,props:{as:{default:`button`},variant:{default:`solid`},size:{default:`md`},disabled:{type:Boolean,default:!1},loading:{type:Boolean,default:!1},loadingLabel:{default:`Loading`},hideIconWhileLoading:{type:Boolean,default:!0},iconOnly:{type:Boolean,default:!1},label:{default:void 0},type:{default:`button`},block:{type:Boolean,default:!1},align:{default:`center`}},emits:[`click`],setup(o,{emit:s}){let c=o,l=s,u=(0,n.tv)({base:`t-button`,variants:{variant:{solid:`t-button--solid`,outline:`t-button--outline`,ghost:`t-button--ghost`,soft:`t-button--soft`,danger:`t-button--danger`,brand:`t-button--brand`},size:{sm:`t-button--sm`,md:`t-button--md`,lg:`t-button--lg`}}}),d=(0,t.computed)(()=>c.as===`button`),
|
|
1
|
+
const e=require("./TSpinner.cjs");let t=require("vue"),n=require("@treeui/utils");var r={key:0,class:`t-button__spinner`},i={key:1,class:`t-button__icon`,"aria-hidden":`true`},a={key:2,class:`t-button__label`},o=(0,t.defineComponent)({__name:`TButton`,props:{as:{default:`button`},variant:{default:`solid`},size:{default:`md`},disabled:{type:Boolean,default:!1},loading:{type:Boolean,default:!1},loadingLabel:{default:`Loading`},hideIconWhileLoading:{type:Boolean,default:!0},iconOnly:{type:Boolean,default:!1},label:{default:void 0},type:{default:`button`},block:{type:Boolean,default:!1},align:{default:`center`}},emits:[`click`],setup(o,{emit:s}){let c=o,l=s,u=(0,n.tv)({base:`t-button`,variants:{variant:{solid:`t-button--solid`,outline:`t-button--outline`,ghost:`t-button--ghost`,soft:`t-button--soft`,danger:`t-button--danger`,brand:`t-button--brand`},size:{sm:`t-button--sm`,md:`t-button--md`,lg:`t-button--lg`}}}),d=(0,t.useAttrs)(),f=(0,t.computed)(()=>c.as===`button`),p=(0,t.computed)(()=>c.disabled||c.loading);process.env.NODE_ENV!==`production`&&(0,t.watchEffect)(()=>{c.iconOnly&&!c.label&&!d[`aria-label`]&&!d[`aria-labelledby`]&&console.warn("[TButton] `iconOnly` needs an accessible name — pass the `label` prop (or `aria-label`).")});let m=(0,t.computed)(()=>c.loading&&c.hideIconWhileLoading),h=(0,t.computed)(()=>u({variant:c.variant,size:c.size,class:{"is-loading":c.loading,"is-disabled":p.value,"t-button--block":c.block,"t-button--icon":c.iconOnly,"t-button--align-start":c.align===`start`,"t-button--align-end":c.align===`end`}})),g=e=>{if(p.value){e.preventDefault(),e.stopPropagation();return}l(`click`,e)};return(n,s)=>((0,t.openBlock)(),(0,t.createBlock)((0,t.resolveDynamicComponent)(o.as),{type:f.value?o.type:void 0,class:(0,t.normalizeClass)(h.value),disabled:f.value?p.value:void 0,"aria-disabled":!f.value&&p.value?`true`:void 0,"aria-busy":o.loading||void 0,"aria-label":o.label,tabindex:!f.value&&p.value?-1:void 0,onClick:g},{default:(0,t.withCtx)(()=>[o.loading?((0,t.openBlock)(),(0,t.createElementBlock)(`span`,r,[(0,t.createVNode)(e.default,{size:`sm`,label:o.loadingLabel},null,8,[`label`])])):(0,t.createCommentVNode)(``,!0),n.$slots.icon&&!m.value?((0,t.openBlock)(),(0,t.createElementBlock)(`span`,i,[(0,t.renderSlot)(n.$slots,`icon`)])):(0,t.createCommentVNode)(``,!0),o.iconOnly?(0,t.createCommentVNode)(``,!0):((0,t.openBlock)(),(0,t.createElementBlock)(`span`,a,[(0,t.renderSlot)(n.$slots,`default`)]))]),_:3},8,[`type`,`class`,`disabled`,`aria-disabled`,`aria-busy`,`aria-label`,`tabindex`]))}});exports.default=o;
|
|
2
2
|
//# sourceMappingURL=TButton.vue_vue_type_script_setup_true_lang.cjs.map
|