@treeui/vue 0.13.0 → 0.15.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 +25 -0
- 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 +166 -104
- package/dist/components/TAppShell.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TButton.cjs.map +1 -1
- package/dist/components/TButton.js.map +1 -1
- package/dist/components/TButton.vue.d.ts +8 -2
- 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 +12 -3
- package/dist/components/TButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TChart.cjs.map +1 -1
- package/dist/components/TChart.js.map +1 -1
- package/dist/components/TChart.vue.d.ts.map +1 -1
- package/dist/components/TChart.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TChart.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TChart.vue_vue_type_script_setup_true_lang.js +58 -58
- package/dist/components/TChart.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TColorSwatch.cjs +2 -0
- package/dist/components/TColorSwatch.cjs.map +1 -0
- package/dist/components/TColorSwatch.js +7 -0
- package/dist/components/TColorSwatch.js.map +1 -0
- package/dist/components/TColorSwatch.vue.d.ts +33 -0
- package/dist/components/TColorSwatch.vue.d.ts.map +1 -0
- package/dist/components/TColorSwatch.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TColorSwatch.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TColorSwatch.vue_vue_type_script_setup_true_lang.js +63 -0
- package/dist/components/TColorSwatch.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TDropdown.vue.d.ts +1 -1
- package/dist/components/TDropdown.vue.d.ts.map +1 -1
- package/dist/components/TFileUpload.cjs.map +1 -1
- package/dist/components/TFileUpload.js.map +1 -1
- package/dist/components/TFileUpload.vue.d.ts +77 -10
- package/dist/components/TFileUpload.vue.d.ts.map +1 -1
- package/dist/components/TFileUpload.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TFileUpload.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TFileUpload.vue_vue_type_script_setup_true_lang.js +393 -144
- package/dist/components/TFileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TInput.cjs.map +1 -1
- package/dist/components/TInput.js.map +1 -1
- package/dist/components/TInput.vue.d.ts +4 -1
- package/dist/components/TInput.vue.d.ts.map +1 -1
- package/dist/components/TInput.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TInput.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TInput.vue_vue_type_script_setup_true_lang.js +2 -0
- package/dist/components/TInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TKbd.cjs +2 -0
- package/dist/components/TKbd.cjs.map +1 -0
- package/dist/components/TKbd.js +7 -0
- package/dist/components/TKbd.js.map +1 -0
- package/dist/components/TKbd.vue.d.ts +18 -0
- package/dist/components/TKbd.vue.d.ts.map +1 -0
- package/dist/components/TKbd.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TKbd.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TKbd.vue_vue_type_script_setup_true_lang.js +12 -0
- package/dist/components/TKbd.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TNavMenu.cjs.map +1 -1
- package/dist/components/TNavMenu.js.map +1 -1
- package/dist/components/TNavMenu.vue.d.ts +9 -0
- package/dist/components/TNavMenu.vue.d.ts.map +1 -1
- package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.js +67 -55
- package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TPage.cjs +2 -0
- package/dist/components/TPage.cjs.map +1 -0
- package/dist/components/TPage.js +7 -0
- package/dist/components/TPage.js.map +1 -0
- package/dist/components/TPage.vue.d.ts +35 -0
- package/dist/components/TPage.vue.d.ts.map +1 -0
- package/dist/components/TPage.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TPage.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TPage.vue_vue_type_script_setup_true_lang.js +49 -0
- package/dist/components/TPage.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TPageHeader.cjs +2 -0
- package/dist/components/TPageHeader.cjs.map +1 -0
- package/dist/components/TPageHeader.js +7 -0
- package/dist/components/TPageHeader.js.map +1 -0
- package/dist/components/TPageHeader.vue.d.ts +40 -0
- package/dist/components/TPageHeader.vue.d.ts.map +1 -0
- package/dist/components/TPageHeader.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TPageHeader.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TPageHeader.vue_vue_type_script_setup_true_lang.js +54 -0
- package/dist/components/TPageHeader.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TPopover.vue.d.ts +1 -1
- package/dist/components/TPopover.vue.d.ts.map +1 -1
- package/dist/components/TSelect.cjs.map +1 -1
- package/dist/components/TSelect.js.map +1 -1
- package/dist/components/TSelect.vue.d.ts +4 -1
- package/dist/components/TSelect.vue.d.ts.map +1 -1
- package/dist/components/TSelect.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TSelect.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TSelect.vue_vue_type_script_setup_true_lang.js +2 -0
- package/dist/components/TSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.js +1 -4
- package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TSpacer.cjs +2 -0
- package/dist/components/TSpacer.cjs.map +1 -0
- package/dist/components/TSpacer.js +7 -0
- package/dist/components/TSpacer.js.map +1 -0
- package/dist/components/TSpacer.vue.d.ts +8 -0
- package/dist/components/TSpacer.vue.d.ts.map +1 -0
- package/dist/components/TSpacer.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TSpacer.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TSpacer.vue_vue_type_script_setup_true_lang.js +16 -0
- package/dist/components/TSpacer.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TSplit.cjs +2 -0
- package/dist/components/TSplit.cjs.map +1 -0
- package/dist/components/TSplit.js +7 -0
- package/dist/components/TSplit.js.map +1 -0
- package/dist/components/TSplit.vue.d.ts +38 -0
- package/dist/components/TSplit.vue.d.ts.map +1 -0
- package/dist/components/TSplit.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TSplit.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TSplit.vue_vue_type_script_setup_true_lang.js +43 -0
- package/dist/components/TSplit.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TStack.cjs.map +1 -1
- package/dist/components/TStack.js.map +1 -1
- package/dist/components/TStack.vue.d.ts +3 -0
- 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 +6 -1
- package/dist/components/TStack.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TStackItem.cjs +2 -0
- package/dist/components/TStackItem.cjs.map +1 -0
- package/dist/components/TStackItem.js +7 -0
- package/dist/components/TStackItem.js.map +1 -0
- package/dist/components/TStackItem.vue.d.ts +38 -0
- package/dist/components/TStackItem.vue.d.ts.map +1 -0
- package/dist/components/TStackItem.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TStackItem.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TStackItem.vue_vue_type_script_setup_true_lang.js +45 -0
- package/dist/components/TStackItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TText.cjs +2 -0
- package/dist/components/TText.cjs.map +1 -0
- package/dist/components/TText.js +7 -0
- package/dist/components/TText.js.map +1 -0
- package/dist/components/TText.vue.d.ts +39 -0
- package/dist/components/TText.vue.d.ts.map +1 -0
- package/dist/components/TText.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TText.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TText.vue_vue_type_script_setup_true_lang.js +32 -0
- package/dist/components/TText.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TTextarea.cjs.map +1 -1
- package/dist/components/TTextarea.js.map +1 -1
- package/dist/components/TTextarea.vue.d.ts +4 -1
- package/dist/components/TTextarea.vue.d.ts.map +1 -1
- package/dist/components/TTextarea.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TTextarea.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TTextarea.vue_vue_type_script_setup_true_lang.js +2 -0
- package/dist/components/TTextarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/index.d.ts +12 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/composables/useTheme.cjs +2 -0
- package/dist/composables/useTheme.cjs.map +1 -0
- package/dist/composables/useTheme.d.ts +38 -0
- package/dist/composables/useTheme.d.ts.map +1 -0
- package/dist/composables/useTheme.js +54 -0
- package/dist/composables/useTheme.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +64 -55
- 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 +113 -97
- package/dist/plugin.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/types/contracts.cjs +1 -1
- package/dist/types/contracts.cjs.map +1 -1
- package/dist/types/contracts.d.ts +8 -1
- package/dist/types/contracts.d.ts.map +1 -1
- package/dist/types/contracts.js +8 -2
- package/dist/types/contracts.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { computed as e, createBlock as t, createCommentVNode as n, createElementBlock as r, createElementVNode as i, createTextVNode as a, defineComponent as o, mergeProps as s, openBlock as c, renderSlot as l, resolveDynamicComponent as u, toDisplayString as d, useAttrs as f, useSlots as p, withCtx as m } from "vue";
|
|
2
|
+
//#region src/components/TPageHeader.vue?vue&type=script&setup=true&lang.ts
|
|
3
|
+
var h = {
|
|
4
|
+
key: 0,
|
|
5
|
+
class: "t-page-header__breadcrumb"
|
|
6
|
+
}, g = { class: "t-page-header__bar" }, _ = {
|
|
7
|
+
key: 0,
|
|
8
|
+
class: "t-page-header__heading"
|
|
9
|
+
}, v = {
|
|
10
|
+
key: 1,
|
|
11
|
+
class: "t-page-header__subtitle"
|
|
12
|
+
}, y = {
|
|
13
|
+
key: 1,
|
|
14
|
+
class: "t-page-header__actions"
|
|
15
|
+
}, b = {
|
|
16
|
+
key: 1,
|
|
17
|
+
class: "t-page-header__content"
|
|
18
|
+
}, x = /*@__PURE__*/ o({
|
|
19
|
+
inheritAttrs: !1,
|
|
20
|
+
__name: "TPageHeader",
|
|
21
|
+
props: {
|
|
22
|
+
title: { default: "" },
|
|
23
|
+
subtitle: { default: "" },
|
|
24
|
+
level: { default: 1 },
|
|
25
|
+
as: { default: "header" }
|
|
26
|
+
},
|
|
27
|
+
setup(o) {
|
|
28
|
+
let x = o, S = f(), C = p(), w = e(() => ["t-page-header", S.class]), T = e(() => S.style), E = e(() => {
|
|
29
|
+
let { class: e, style: t, ...n } = S;
|
|
30
|
+
return n;
|
|
31
|
+
}), D = e(() => `h${x.level}`), O = e(() => !!(C.title || x.title)), k = e(() => !!(C.subtitle || x.subtitle));
|
|
32
|
+
return (e, f) => (c(), t(u(o.as), s(E.value, {
|
|
33
|
+
class: w.value,
|
|
34
|
+
style: T.value
|
|
35
|
+
}), {
|
|
36
|
+
default: m(() => [
|
|
37
|
+
e.$slots.breadcrumb ? (c(), r("div", h, [l(e.$slots, "breadcrumb")])) : n("", !0),
|
|
38
|
+
i("div", g, [O.value || k.value ? (c(), r("div", _, [O.value ? (c(), t(u(D.value), {
|
|
39
|
+
key: 0,
|
|
40
|
+
class: "t-page-header__title"
|
|
41
|
+
}, {
|
|
42
|
+
default: m(() => [l(e.$slots, "title", {}, () => [a(d(o.title), 1)])]),
|
|
43
|
+
_: 3
|
|
44
|
+
})) : n("", !0), k.value ? (c(), r("p", v, [l(e.$slots, "subtitle", {}, () => [a(d(o.subtitle), 1)])])) : n("", !0)])) : n("", !0), e.$slots.actions ? (c(), r("div", y, [l(e.$slots, "actions")])) : n("", !0)]),
|
|
45
|
+
e.$slots.default ? (c(), r("div", b, [l(e.$slots, "default")])) : n("", !0)
|
|
46
|
+
]),
|
|
47
|
+
_: 3
|
|
48
|
+
}, 16, ["class", "style"]));
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
//#endregion
|
|
52
|
+
export { x as default };
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=TPageHeader.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TPageHeader.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../src/components/TPageHeader.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, useAttrs, useSlots } from 'vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n title?: string;\n subtitle?: string;\n /** Heading level for the title element. Defaults to the page-level `1`. */\n level?: 1 | 2 | 3 | 4 | 5 | 6;\n as?: string;\n }>(),\n {\n title: '',\n subtitle: '',\n level: 1,\n as: 'header',\n },\n);\n\ndefineSlots<{\n breadcrumb?: () => unknown;\n title?: () => unknown;\n subtitle?: () => unknown;\n actions?: () => unknown;\n default?: () => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst slots = useSlots();\n\nconst rootClasses = computed(() => ['t-page-header', attrs.class]);\nconst rootStyle = computed(() => attrs.style);\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst titleTag = computed(() => `h${props.level}`);\nconst hasTitle = computed(() => Boolean(slots.title || props.title));\nconst hasSubtitle = computed(() => Boolean(slots.subtitle || props.subtitle));\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <div\n v-if=\"$slots.breadcrumb\"\n class=\"t-page-header__breadcrumb\"\n >\n <slot name=\"breadcrumb\" />\n </div>\n\n <div class=\"t-page-header__bar\">\n <div\n v-if=\"hasTitle || hasSubtitle\"\n class=\"t-page-header__heading\"\n >\n <component\n :is=\"titleTag\"\n v-if=\"hasTitle\"\n class=\"t-page-header__title\"\n >\n <slot name=\"title\">\n {{ title }}\n </slot>\n </component>\n\n <p\n v-if=\"hasSubtitle\"\n class=\"t-page-header__subtitle\"\n >\n <slot name=\"subtitle\">\n {{ subtitle }}\n </slot>\n </p>\n </div>\n\n <div\n v-if=\"$slots.actions\"\n class=\"t-page-header__actions\"\n >\n <slot name=\"actions\" />\n </div>\n </div>\n\n <div\n v-if=\"$slots.default\"\n class=\"t-page-header__content\"\n >\n <slot />\n </div>\n </component>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;EAOA,IAAM,IAAQ,GAwBR,IAAQ,EAAS,GACjB,IAAQ,EAAS,GAEjB,IAAc,QAAe,CAAC,iBAAiB,EAAM,KAAK,CAAC,GAC3D,IAAY,QAAe,EAAM,KAAK,GACtC,IAAY,QAAe;GAC/B,IAAM,EAAE,OAAO,GAAQ,OAAO,GAAQ,GAAG,MAAS;GAClD,OAAO;EACT,CAAC,GAEK,IAAW,QAAe,IAAI,EAAM,OAAO,GAC3C,IAAW,QAAe,GAAQ,EAAM,SAAS,EAAM,MAAM,GAC7D,IAAc,QAAe,GAAQ,EAAM,YAAY,EAAM,SAAS;yBAI1E,EAoDY,EAnDL,EAAA,EAAE,GADT,EAEU,EAkDE,OAlDO;GAChB,OAAO,EAAA;GACP,OAAO,EAAA;;oBAOF;IAJEA,EAAAA,OAAO,cAAA,EAAA,GADf,EAKM,OALN,GAKM,CADJ,EAA0B,EAAA,QAAA,YAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA;IAG5B,EA+BM,OA/BN,GA+BM,CA7BI,EAAA,SAAY,EAAA,SAAA,EAAA,GADpB,EAsBM,OAtBN,GAsBM,CAhBI,EAAA,SAAA,EAAA,GAFR,EAQY,EAPL,EAAA,KAAQ,GAAA;;KAEb,OAAM;;sBAIC,CAFP,EAEO,EAAA,QAAA,SAAA,CAAA,SAAA,CAAA,EAAA,EADF,EAAA,KAAK,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA;;qBAKJ,EAAA,SAAA,EAAA,GADR,EAOI,KAPJ,GAOI,CAHF,EAEO,EAAA,QAAA,YAAA,CAAA,SAAA,CAAA,EAAA,EADF,EAAA,QAAQ,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA,GAMTA,EAAAA,OAAO,WAAA,EAAA,GADf,EAKM,OALN,GAKM,CADJ,EAAuB,EAAA,QAAA,SAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA;IAKnBA,EAAAA,OAAO,WAAA,EAAA,GADf,EAKM,OALN,GAKM,CADJ,EAAQ,EAAA,QAAA,SAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA"}
|
|
@@ -37,10 +37,10 @@ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}
|
|
|
37
37
|
}>, {
|
|
38
38
|
disabled: boolean;
|
|
39
39
|
id: string;
|
|
40
|
+
align: "start" | "center" | "end";
|
|
40
41
|
open: boolean;
|
|
41
42
|
defaultOpen: boolean;
|
|
42
43
|
side: TTooltipSide;
|
|
43
|
-
align: "start" | "center" | "end";
|
|
44
44
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
|
|
45
45
|
rootRef: HTMLDivElement;
|
|
46
46
|
triggerRef: HTMLButtonElement;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TPopover.vue.d.ts","sourceRoot":"","sources":["../../src/components/TPopover.vue"],"names":[],"mappings":"AA6LA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAMvD,KAAK,WAAW,GAAG;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAsIJ,iBAAS,cAAc;WAyET,OAAO,IAA6B;;uBA3LjC;YAAE,MAAM,EAAE,OAAO,CAAA;SAAE,GAAG,OAAO;mBACjC,OAAO;;uBADH;YAAE,MAAM,EAAE,OAAO,CAAA;SAAE,GAAG,OAAO;mBACjC,OAAO;;;;;;;;EA+LnB;AAsBD,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAC9D,QAAA,MAAM,eAAe;;;;;;;cA/ON,OAAO;QAGb,MAAM;
|
|
1
|
+
{"version":3,"file":"TPopover.vue.d.ts","sourceRoot":"","sources":["../../src/components/TPopover.vue"],"names":[],"mappings":"AA6LA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAMvD,KAAK,WAAW,GAAG;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAsIJ,iBAAS,cAAc;WAyET,OAAO,IAA6B;;uBA3LjC;YAAE,MAAM,EAAE,OAAO,CAAA;SAAE,GAAG,OAAO;mBACjC,OAAO;;uBADH;YAAE,MAAM,EAAE,OAAO,CAAA;SAAE,GAAG,OAAO;mBACjC,OAAO;;;;;;;;EA+LnB;AAsBD,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAC9D,QAAA,MAAM,eAAe;;;;;;;cA/ON,OAAO;QAGb,MAAM;WADH,OAAO,GAAG,QAAQ,GAAG,KAAK;UAJ3B,OAAO;iBACA,OAAO;UAEd,YAAY;;;;;OAuPrB,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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TSelect.cjs","names":[],"sources":["../../src/components/TSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { createId, isActivationKey, isEscapeKey } from '@treeui/utils';\nimport { computed, nextTick, onBeforeUnmount, ref, toRef, useAttrs, watch } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TSelectOption {\n label: string;\n value: string | number;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string | number;\n options?: TSelectOption[];\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n placeholder?: string;\n }>(),\n {\n modelValue: '',\n options: () => [],\n open: undefined,\n defaultOpen: false,\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n placeholder: '',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\nconst listboxId = createId('t-select');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst listboxRef = ref<HTMLElement | null>(null);\nconst optionRefs = ref<Map<string | number, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\nconst dropUp = ref(false);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-select',\n `t-select--${props.size}`,\n {\n 't-select--drop-up': dropUp.value,\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\n// Nearest ancestor that can clip the listbox (scroll container or hidden overflow).\nconst findClippingAncestor = (element: HTMLElement): HTMLElement | null => {\n let parent = element.parentElement;\n while (parent && parent !== document.body) {\n const { overflowY } = window.getComputedStyle(parent);\n if (overflowY === 'auto' || overflowY === 'scroll' || overflowY === 'hidden') {\n return parent;\n }\n parent = parent.parentElement;\n }\n return null;\n};\n\n// Flip the listbox above the trigger when its rendered position overflows the\n// nearest clipping ancestor (e.g. a modal body) or the viewport, and there is\n// more room above the trigger than below it. Measuring the rendered rect keeps\n// the decision in sync with the CSS offset (--tree-space-2) automatically.\nconst updateDropDirection = () => {\n const trigger = triggerRef.value;\n const listbox = listboxRef.value;\n if (!trigger || !listbox) {\n dropUp.value = false;\n return;\n }\n const triggerRect = trigger.getBoundingClientRect();\n const listboxRect = listbox.getBoundingClientRect();\n const boundary = findClippingAncestor(trigger)?.getBoundingClientRect();\n const bottomLimit = Math.min(boundary?.bottom ?? Infinity, window.innerHeight);\n const topLimit = Math.max(boundary?.top ?? 0, 0);\n const spaceBelow = bottomLimit - triggerRect.bottom;\n const spaceAbove = triggerRect.top - topLimit;\n dropUp.value = listboxRect.bottom > bottomLimit && spaceAbove > spaceBelow;\n};\n\nconst rootStyle = computed(() => attrs.style);\n\nconst selectedLabel = computed(() => {\n const opt = props.options.find((o) => o.value === props.modelValue);\n return opt?.label ?? '';\n});\n\nconst enabledOptions = computed(() =>\n props.options.filter((o) => !o.disabled),\n);\n\nconst openDropdown = () => {\n if (props.disabled) return;\n const selectedIdx = props.options.findIndex((o) => o.value === props.modelValue);\n focusedIndex.value = selectedIdx >= 0 ? selectedIdx : 0;\n // Render downward first so the measurement always starts from the default position.\n dropUp.value = false;\n setValue(true);\n nextTick(() => {\n updateDropDirection();\n focusOption(focusedIndex.value);\n });\n};\n\nconst closeDropdown = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => triggerRef.value?.focus());\n }\n};\n\nconst toggleDropdown = () => {\n if (isOpen.value) {\n closeDropdown();\n } else {\n openDropdown();\n }\n};\n\nconst selectOption = (opt: TSelectOption) => {\n if (opt.disabled) return;\n emit('update:modelValue', opt.value);\n closeDropdown(true);\n};\n\nconst focusOption = (index: number) => {\n const opt = props.options[index];\n if (!opt) return;\n const el = optionRefs.value.get(opt.value);\n el?.focus();\n};\n\nconst setOptionRef = (el: Element | null, value: string | number) => {\n if (el instanceof HTMLElement) {\n optionRefs.value.set(value, el);\n } else {\n optionRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.options.length) {\n if (!props.options[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusOption(nextIndex);\n return;\n }\n nextIndex += direction;\n }\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) return;\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeDropdown();\n return;\n }\n\n if (isActivationKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n openDropdown();\n }\n};\n\nconst onOptionKeydown = (event: KeyboardEvent, opt: TSelectOption, _index: number) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeDropdown(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectOption(opt);\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(-1);\n break;\n case 'Home':\n event.preventDefault();\n focusedIndex.value = enabledOptions.value.length > 0\n ? props.options.indexOf(enabledOptions.value[0])\n : 0;\n focusOption(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledOptions.value.length > 0\n ? props.options.indexOf(enabledOptions.value[enabledOptions.value.length - 1])\n : props.options.length - 1;\n focusOption(focusedIndex.value);\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) return;\n const target = event.target;\n if (!(target instanceof Node)) return;\n if (rootRef.value?.contains(target)) return;\n closeDropdown();\n};\n\nconst hasSelection = computed(() =>\n props.modelValue !== '' && props.modelValue !== null && props.modelValue !== undefined,\n);\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n } else {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-select__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? listboxId : undefined\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"isOpen\"\n :aria-invalid=\"invalid || undefined\"\n :aria-busy=\"loading || undefined\"\n @click=\"toggleDropdown\"\n @keydown=\"onTriggerKeydown\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-select__slot t-select__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <span\n class=\"t-select__value\"\n :data-placeholder=\"!hasSelection ? true : undefined\"\n >\n {{ selectedLabel || placeholder }}\n </span>\n <TSpinner\n v-if=\"loading\"\n size=\"sm\"\n label=\"Loading\"\n />\n <svg\n v-else\n class=\"t-select__chevron\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"4 6 8 10 12 6\" />\n </svg>\n </button>\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"listboxId\"\n ref=\"listboxRef\"\n role=\"listbox\"\n class=\"t-select__listbox\"\n :aria-label=\"typeof triggerAttrs['aria-label'] === 'string' ? triggerAttrs['aria-label'] : undefined\"\n >\n <li\n v-for=\"(opt, index) in options\"\n :key=\"opt.value\"\n :ref=\"(el) => setOptionRef(el as Element | null, opt.value)\"\n role=\"option\"\n class=\"t-select__option\"\n :class=\"{\n 'is-selected': opt.value === modelValue,\n 'is-disabled': opt.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-selected=\"opt.value === modelValue\"\n :aria-disabled=\"opt.disabled || undefined\"\n :tabindex=\"opt.disabled ? -1 : 0\"\n @click=\"selectOption(opt)\"\n @keydown=\"onOptionKeydown($event, opt, index)\"\n >\n {{ opt.label }}\n <svg\n v-if=\"opt.value === modelValue\"\n class=\"t-select__check\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"3.5 8.5 6.5 11.5 12.5 4.5\" />\n </svg>\n </li>\n </ul>\n </transition>\n </div>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"TSelect.cjs","names":[],"sources":["../../src/components/TSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { createId, isActivationKey, isEscapeKey } from '@treeui/utils';\nimport { computed, nextTick, onBeforeUnmount, ref, toRef, useAttrs, watch } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TFieldWidth, TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TSelectOption {\n label: string;\n value: string | number;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string | number;\n options?: TSelectOption[];\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n /** Inline-size cap. Fluid (`full`) by default. */\n width?: TFieldWidth;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n placeholder?: string;\n }>(),\n {\n modelValue: '',\n options: () => [],\n open: undefined,\n defaultOpen: false,\n size: 'md',\n width: 'full',\n disabled: false,\n loading: false,\n invalid: false,\n placeholder: '',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\nconst listboxId = createId('t-select');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst listboxRef = ref<HTMLElement | null>(null);\nconst optionRefs = ref<Map<string | number, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\nconst dropUp = ref(false);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-select',\n `t-select--${props.size}`,\n props.width !== 'full' ? `t-field-width--${props.width}` : null,\n {\n 't-select--drop-up': dropUp.value,\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\n// Nearest ancestor that can clip the listbox (scroll container or hidden overflow).\nconst findClippingAncestor = (element: HTMLElement): HTMLElement | null => {\n let parent = element.parentElement;\n while (parent && parent !== document.body) {\n const { overflowY } = window.getComputedStyle(parent);\n if (overflowY === 'auto' || overflowY === 'scroll' || overflowY === 'hidden') {\n return parent;\n }\n parent = parent.parentElement;\n }\n return null;\n};\n\n// Flip the listbox above the trigger when its rendered position overflows the\n// nearest clipping ancestor (e.g. a modal body) or the viewport, and there is\n// more room above the trigger than below it. Measuring the rendered rect keeps\n// the decision in sync with the CSS offset (--tree-space-2) automatically.\nconst updateDropDirection = () => {\n const trigger = triggerRef.value;\n const listbox = listboxRef.value;\n if (!trigger || !listbox) {\n dropUp.value = false;\n return;\n }\n const triggerRect = trigger.getBoundingClientRect();\n const listboxRect = listbox.getBoundingClientRect();\n const boundary = findClippingAncestor(trigger)?.getBoundingClientRect();\n const bottomLimit = Math.min(boundary?.bottom ?? Infinity, window.innerHeight);\n const topLimit = Math.max(boundary?.top ?? 0, 0);\n const spaceBelow = bottomLimit - triggerRect.bottom;\n const spaceAbove = triggerRect.top - topLimit;\n dropUp.value = listboxRect.bottom > bottomLimit && spaceAbove > spaceBelow;\n};\n\nconst rootStyle = computed(() => attrs.style);\n\nconst selectedLabel = computed(() => {\n const opt = props.options.find((o) => o.value === props.modelValue);\n return opt?.label ?? '';\n});\n\nconst enabledOptions = computed(() =>\n props.options.filter((o) => !o.disabled),\n);\n\nconst openDropdown = () => {\n if (props.disabled) return;\n const selectedIdx = props.options.findIndex((o) => o.value === props.modelValue);\n focusedIndex.value = selectedIdx >= 0 ? selectedIdx : 0;\n // Render downward first so the measurement always starts from the default position.\n dropUp.value = false;\n setValue(true);\n nextTick(() => {\n updateDropDirection();\n focusOption(focusedIndex.value);\n });\n};\n\nconst closeDropdown = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => triggerRef.value?.focus());\n }\n};\n\nconst toggleDropdown = () => {\n if (isOpen.value) {\n closeDropdown();\n } else {\n openDropdown();\n }\n};\n\nconst selectOption = (opt: TSelectOption) => {\n if (opt.disabled) return;\n emit('update:modelValue', opt.value);\n closeDropdown(true);\n};\n\nconst focusOption = (index: number) => {\n const opt = props.options[index];\n if (!opt) return;\n const el = optionRefs.value.get(opt.value);\n el?.focus();\n};\n\nconst setOptionRef = (el: Element | null, value: string | number) => {\n if (el instanceof HTMLElement) {\n optionRefs.value.set(value, el);\n } else {\n optionRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.options.length) {\n if (!props.options[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusOption(nextIndex);\n return;\n }\n nextIndex += direction;\n }\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) return;\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeDropdown();\n return;\n }\n\n if (isActivationKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n openDropdown();\n }\n};\n\nconst onOptionKeydown = (event: KeyboardEvent, opt: TSelectOption, _index: number) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeDropdown(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectOption(opt);\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(-1);\n break;\n case 'Home':\n event.preventDefault();\n focusedIndex.value = enabledOptions.value.length > 0\n ? props.options.indexOf(enabledOptions.value[0])\n : 0;\n focusOption(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledOptions.value.length > 0\n ? props.options.indexOf(enabledOptions.value[enabledOptions.value.length - 1])\n : props.options.length - 1;\n focusOption(focusedIndex.value);\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) return;\n const target = event.target;\n if (!(target instanceof Node)) return;\n if (rootRef.value?.contains(target)) return;\n closeDropdown();\n};\n\nconst hasSelection = computed(() =>\n props.modelValue !== '' && props.modelValue !== null && props.modelValue !== undefined,\n);\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n } else {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-select__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? listboxId : undefined\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"isOpen\"\n :aria-invalid=\"invalid || undefined\"\n :aria-busy=\"loading || undefined\"\n @click=\"toggleDropdown\"\n @keydown=\"onTriggerKeydown\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-select__slot t-select__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <span\n class=\"t-select__value\"\n :data-placeholder=\"!hasSelection ? true : undefined\"\n >\n {{ selectedLabel || placeholder }}\n </span>\n <TSpinner\n v-if=\"loading\"\n size=\"sm\"\n label=\"Loading\"\n />\n <svg\n v-else\n class=\"t-select__chevron\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"4 6 8 10 12 6\" />\n </svg>\n </button>\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"listboxId\"\n ref=\"listboxRef\"\n role=\"listbox\"\n class=\"t-select__listbox\"\n :aria-label=\"typeof triggerAttrs['aria-label'] === 'string' ? triggerAttrs['aria-label'] : undefined\"\n >\n <li\n v-for=\"(opt, index) in options\"\n :key=\"opt.value\"\n :ref=\"(el) => setOptionRef(el as Element | null, opt.value)\"\n role=\"option\"\n class=\"t-select__option\"\n :class=\"{\n 'is-selected': opt.value === modelValue,\n 'is-disabled': opt.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-selected=\"opt.value === modelValue\"\n :aria-disabled=\"opt.disabled || undefined\"\n :tabindex=\"opt.disabled ? -1 : 0\"\n @click=\"selectOption(opt)\"\n @keydown=\"onOptionKeydown($event, opt, index)\"\n >\n {{ opt.label }}\n <svg\n v-if=\"opt.value === modelValue\"\n class=\"t-select__check\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"3.5 8.5 6.5 11.5 12.5 4.5\" />\n </svg>\n </li>\n </ul>\n </transition>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TSelect.js","names":[],"sources":["../../src/components/TSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { createId, isActivationKey, isEscapeKey } from '@treeui/utils';\nimport { computed, nextTick, onBeforeUnmount, ref, toRef, useAttrs, watch } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TSelectOption {\n label: string;\n value: string | number;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string | number;\n options?: TSelectOption[];\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n placeholder?: string;\n }>(),\n {\n modelValue: '',\n options: () => [],\n open: undefined,\n defaultOpen: false,\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n placeholder: '',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\nconst listboxId = createId('t-select');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst listboxRef = ref<HTMLElement | null>(null);\nconst optionRefs = ref<Map<string | number, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\nconst dropUp = ref(false);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-select',\n `t-select--${props.size}`,\n {\n 't-select--drop-up': dropUp.value,\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\n// Nearest ancestor that can clip the listbox (scroll container or hidden overflow).\nconst findClippingAncestor = (element: HTMLElement): HTMLElement | null => {\n let parent = element.parentElement;\n while (parent && parent !== document.body) {\n const { overflowY } = window.getComputedStyle(parent);\n if (overflowY === 'auto' || overflowY === 'scroll' || overflowY === 'hidden') {\n return parent;\n }\n parent = parent.parentElement;\n }\n return null;\n};\n\n// Flip the listbox above the trigger when its rendered position overflows the\n// nearest clipping ancestor (e.g. a modal body) or the viewport, and there is\n// more room above the trigger than below it. Measuring the rendered rect keeps\n// the decision in sync with the CSS offset (--tree-space-2) automatically.\nconst updateDropDirection = () => {\n const trigger = triggerRef.value;\n const listbox = listboxRef.value;\n if (!trigger || !listbox) {\n dropUp.value = false;\n return;\n }\n const triggerRect = trigger.getBoundingClientRect();\n const listboxRect = listbox.getBoundingClientRect();\n const boundary = findClippingAncestor(trigger)?.getBoundingClientRect();\n const bottomLimit = Math.min(boundary?.bottom ?? Infinity, window.innerHeight);\n const topLimit = Math.max(boundary?.top ?? 0, 0);\n const spaceBelow = bottomLimit - triggerRect.bottom;\n const spaceAbove = triggerRect.top - topLimit;\n dropUp.value = listboxRect.bottom > bottomLimit && spaceAbove > spaceBelow;\n};\n\nconst rootStyle = computed(() => attrs.style);\n\nconst selectedLabel = computed(() => {\n const opt = props.options.find((o) => o.value === props.modelValue);\n return opt?.label ?? '';\n});\n\nconst enabledOptions = computed(() =>\n props.options.filter((o) => !o.disabled),\n);\n\nconst openDropdown = () => {\n if (props.disabled) return;\n const selectedIdx = props.options.findIndex((o) => o.value === props.modelValue);\n focusedIndex.value = selectedIdx >= 0 ? selectedIdx : 0;\n // Render downward first so the measurement always starts from the default position.\n dropUp.value = false;\n setValue(true);\n nextTick(() => {\n updateDropDirection();\n focusOption(focusedIndex.value);\n });\n};\n\nconst closeDropdown = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => triggerRef.value?.focus());\n }\n};\n\nconst toggleDropdown = () => {\n if (isOpen.value) {\n closeDropdown();\n } else {\n openDropdown();\n }\n};\n\nconst selectOption = (opt: TSelectOption) => {\n if (opt.disabled) return;\n emit('update:modelValue', opt.value);\n closeDropdown(true);\n};\n\nconst focusOption = (index: number) => {\n const opt = props.options[index];\n if (!opt) return;\n const el = optionRefs.value.get(opt.value);\n el?.focus();\n};\n\nconst setOptionRef = (el: Element | null, value: string | number) => {\n if (el instanceof HTMLElement) {\n optionRefs.value.set(value, el);\n } else {\n optionRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.options.length) {\n if (!props.options[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusOption(nextIndex);\n return;\n }\n nextIndex += direction;\n }\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) return;\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeDropdown();\n return;\n }\n\n if (isActivationKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n openDropdown();\n }\n};\n\nconst onOptionKeydown = (event: KeyboardEvent, opt: TSelectOption, _index: number) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeDropdown(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectOption(opt);\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(-1);\n break;\n case 'Home':\n event.preventDefault();\n focusedIndex.value = enabledOptions.value.length > 0\n ? props.options.indexOf(enabledOptions.value[0])\n : 0;\n focusOption(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledOptions.value.length > 0\n ? props.options.indexOf(enabledOptions.value[enabledOptions.value.length - 1])\n : props.options.length - 1;\n focusOption(focusedIndex.value);\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) return;\n const target = event.target;\n if (!(target instanceof Node)) return;\n if (rootRef.value?.contains(target)) return;\n closeDropdown();\n};\n\nconst hasSelection = computed(() =>\n props.modelValue !== '' && props.modelValue !== null && props.modelValue !== undefined,\n);\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n } else {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-select__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? listboxId : undefined\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"isOpen\"\n :aria-invalid=\"invalid || undefined\"\n :aria-busy=\"loading || undefined\"\n @click=\"toggleDropdown\"\n @keydown=\"onTriggerKeydown\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-select__slot t-select__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <span\n class=\"t-select__value\"\n :data-placeholder=\"!hasSelection ? true : undefined\"\n >\n {{ selectedLabel || placeholder }}\n </span>\n <TSpinner\n v-if=\"loading\"\n size=\"sm\"\n label=\"Loading\"\n />\n <svg\n v-else\n class=\"t-select__chevron\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"4 6 8 10 12 6\" />\n </svg>\n </button>\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"listboxId\"\n ref=\"listboxRef\"\n role=\"listbox\"\n class=\"t-select__listbox\"\n :aria-label=\"typeof triggerAttrs['aria-label'] === 'string' ? triggerAttrs['aria-label'] : undefined\"\n >\n <li\n v-for=\"(opt, index) in options\"\n :key=\"opt.value\"\n :ref=\"(el) => setOptionRef(el as Element | null, opt.value)\"\n role=\"option\"\n class=\"t-select__option\"\n :class=\"{\n 'is-selected': opt.value === modelValue,\n 'is-disabled': opt.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-selected=\"opt.value === modelValue\"\n :aria-disabled=\"opt.disabled || undefined\"\n :tabindex=\"opt.disabled ? -1 : 0\"\n @click=\"selectOption(opt)\"\n @keydown=\"onOptionKeydown($event, opt, index)\"\n >\n {{ opt.label }}\n <svg\n v-if=\"opt.value === modelValue\"\n class=\"t-select__check\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"3.5 8.5 6.5 11.5 12.5 4.5\" />\n </svg>\n </li>\n </ul>\n </transition>\n </div>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"TSelect.js","names":[],"sources":["../../src/components/TSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { createId, isActivationKey, isEscapeKey } from '@treeui/utils';\nimport { computed, nextTick, onBeforeUnmount, ref, toRef, useAttrs, watch } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TFieldWidth, TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TSelectOption {\n label: string;\n value: string | number;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string | number;\n options?: TSelectOption[];\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n /** Inline-size cap. Fluid (`full`) by default. */\n width?: TFieldWidth;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n placeholder?: string;\n }>(),\n {\n modelValue: '',\n options: () => [],\n open: undefined,\n defaultOpen: false,\n size: 'md',\n width: 'full',\n disabled: false,\n loading: false,\n invalid: false,\n placeholder: '',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\nconst listboxId = createId('t-select');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst listboxRef = ref<HTMLElement | null>(null);\nconst optionRefs = ref<Map<string | number, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\nconst dropUp = ref(false);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-select',\n `t-select--${props.size}`,\n props.width !== 'full' ? `t-field-width--${props.width}` : null,\n {\n 't-select--drop-up': dropUp.value,\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\n// Nearest ancestor that can clip the listbox (scroll container or hidden overflow).\nconst findClippingAncestor = (element: HTMLElement): HTMLElement | null => {\n let parent = element.parentElement;\n while (parent && parent !== document.body) {\n const { overflowY } = window.getComputedStyle(parent);\n if (overflowY === 'auto' || overflowY === 'scroll' || overflowY === 'hidden') {\n return parent;\n }\n parent = parent.parentElement;\n }\n return null;\n};\n\n// Flip the listbox above the trigger when its rendered position overflows the\n// nearest clipping ancestor (e.g. a modal body) or the viewport, and there is\n// more room above the trigger than below it. Measuring the rendered rect keeps\n// the decision in sync with the CSS offset (--tree-space-2) automatically.\nconst updateDropDirection = () => {\n const trigger = triggerRef.value;\n const listbox = listboxRef.value;\n if (!trigger || !listbox) {\n dropUp.value = false;\n return;\n }\n const triggerRect = trigger.getBoundingClientRect();\n const listboxRect = listbox.getBoundingClientRect();\n const boundary = findClippingAncestor(trigger)?.getBoundingClientRect();\n const bottomLimit = Math.min(boundary?.bottom ?? Infinity, window.innerHeight);\n const topLimit = Math.max(boundary?.top ?? 0, 0);\n const spaceBelow = bottomLimit - triggerRect.bottom;\n const spaceAbove = triggerRect.top - topLimit;\n dropUp.value = listboxRect.bottom > bottomLimit && spaceAbove > spaceBelow;\n};\n\nconst rootStyle = computed(() => attrs.style);\n\nconst selectedLabel = computed(() => {\n const opt = props.options.find((o) => o.value === props.modelValue);\n return opt?.label ?? '';\n});\n\nconst enabledOptions = computed(() =>\n props.options.filter((o) => !o.disabled),\n);\n\nconst openDropdown = () => {\n if (props.disabled) return;\n const selectedIdx = props.options.findIndex((o) => o.value === props.modelValue);\n focusedIndex.value = selectedIdx >= 0 ? selectedIdx : 0;\n // Render downward first so the measurement always starts from the default position.\n dropUp.value = false;\n setValue(true);\n nextTick(() => {\n updateDropDirection();\n focusOption(focusedIndex.value);\n });\n};\n\nconst closeDropdown = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => triggerRef.value?.focus());\n }\n};\n\nconst toggleDropdown = () => {\n if (isOpen.value) {\n closeDropdown();\n } else {\n openDropdown();\n }\n};\n\nconst selectOption = (opt: TSelectOption) => {\n if (opt.disabled) return;\n emit('update:modelValue', opt.value);\n closeDropdown(true);\n};\n\nconst focusOption = (index: number) => {\n const opt = props.options[index];\n if (!opt) return;\n const el = optionRefs.value.get(opt.value);\n el?.focus();\n};\n\nconst setOptionRef = (el: Element | null, value: string | number) => {\n if (el instanceof HTMLElement) {\n optionRefs.value.set(value, el);\n } else {\n optionRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.options.length) {\n if (!props.options[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusOption(nextIndex);\n return;\n }\n nextIndex += direction;\n }\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) return;\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeDropdown();\n return;\n }\n\n if (isActivationKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n openDropdown();\n }\n};\n\nconst onOptionKeydown = (event: KeyboardEvent, opt: TSelectOption, _index: number) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeDropdown(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectOption(opt);\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(-1);\n break;\n case 'Home':\n event.preventDefault();\n focusedIndex.value = enabledOptions.value.length > 0\n ? props.options.indexOf(enabledOptions.value[0])\n : 0;\n focusOption(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledOptions.value.length > 0\n ? props.options.indexOf(enabledOptions.value[enabledOptions.value.length - 1])\n : props.options.length - 1;\n focusOption(focusedIndex.value);\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) return;\n const target = event.target;\n if (!(target instanceof Node)) return;\n if (rootRef.value?.contains(target)) return;\n closeDropdown();\n};\n\nconst hasSelection = computed(() =>\n props.modelValue !== '' && props.modelValue !== null && props.modelValue !== undefined,\n);\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n } else {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-select__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? listboxId : undefined\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"isOpen\"\n :aria-invalid=\"invalid || undefined\"\n :aria-busy=\"loading || undefined\"\n @click=\"toggleDropdown\"\n @keydown=\"onTriggerKeydown\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-select__slot t-select__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <span\n class=\"t-select__value\"\n :data-placeholder=\"!hasSelection ? true : undefined\"\n >\n {{ selectedLabel || placeholder }}\n </span>\n <TSpinner\n v-if=\"loading\"\n size=\"sm\"\n label=\"Loading\"\n />\n <svg\n v-else\n class=\"t-select__chevron\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"4 6 8 10 12 6\" />\n </svg>\n </button>\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"listboxId\"\n ref=\"listboxRef\"\n role=\"listbox\"\n class=\"t-select__listbox\"\n :aria-label=\"typeof triggerAttrs['aria-label'] === 'string' ? triggerAttrs['aria-label'] : undefined\"\n >\n <li\n v-for=\"(opt, index) in options\"\n :key=\"opt.value\"\n :ref=\"(el) => setOptionRef(el as Element | null, opt.value)\"\n role=\"option\"\n class=\"t-select__option\"\n :class=\"{\n 'is-selected': opt.value === modelValue,\n 'is-disabled': opt.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-selected=\"opt.value === modelValue\"\n :aria-disabled=\"opt.disabled || undefined\"\n :tabindex=\"opt.disabled ? -1 : 0\"\n @click=\"selectOption(opt)\"\n @keydown=\"onOptionKeydown($event, opt, index)\"\n >\n {{ opt.label }}\n <svg\n v-if=\"opt.value === modelValue\"\n class=\"t-select__check\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"3.5 8.5 6.5 11.5 12.5 4.5\" />\n </svg>\n </li>\n </ul>\n </transition>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TSize } from '../types/contracts';
|
|
1
|
+
import { TFieldWidth, TSize } from '../types/contracts';
|
|
2
2
|
export interface TSelectOption {
|
|
3
3
|
label: string;
|
|
4
4
|
value: string | number;
|
|
@@ -10,6 +10,8 @@ type __VLS_Props = {
|
|
|
10
10
|
open?: boolean;
|
|
11
11
|
defaultOpen?: boolean;
|
|
12
12
|
size?: TSize;
|
|
13
|
+
/** Inline-size cap. Fluid (`full`) by default. */
|
|
14
|
+
width?: TFieldWidth;
|
|
13
15
|
disabled?: boolean;
|
|
14
16
|
loading?: boolean;
|
|
15
17
|
invalid?: boolean;
|
|
@@ -40,6 +42,7 @@ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}
|
|
|
40
42
|
modelValue: string | number;
|
|
41
43
|
disabled: boolean;
|
|
42
44
|
size: TSize;
|
|
45
|
+
width: TFieldWidth;
|
|
43
46
|
loading: boolean;
|
|
44
47
|
invalid: boolean;
|
|
45
48
|
options: TSelectOption[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TSelect.vue.d.ts","sourceRoot":"","sources":["../../src/components/TSelect.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TSelect.vue.d.ts","sourceRoot":"","sources":["../../src/components/TSelect.vue"],"names":[],"mappings":"AA0XA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAO7D,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,KAAK,WAAW,GAAG;IACf,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,kDAAkD;IAClD,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAsQJ,iBAAS,cAAc;WAoJT,OAAO,IAA6B;;wBAbtB,GAAG;;;;;;;;EAkB9B;AA2BD,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAC9D,QAAA,MAAM,eAAe;;;;;;;;;gBAtcJ,MAAM,GAAG,MAAM;cAOjB,OAAO;UAHX,KAAK;WAEJ,WAAW;aAET,OAAO;aACP,OAAO;aARP,aAAa,EAAE;UAClB,OAAO;iBACA,OAAO;iBAOP,MAAM;;;;;OAqctB,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"),t=require("../composables/useControllableOpen.cjs");let n=require("vue"),r=require("@treeui/utils");var i=[`data-state`],a=[`disabled`,`aria-controls`,`aria-expanded`,`aria-invalid`,`aria-busy`],o={key:0,class:`t-select__slot t-select__slot--prefix`},s=[`data-placeholder`],c={key:2,class:`t-select__chevron`,viewBox:`0 0 16 16`,fill:`none`,stroke:`currentColor`,"stroke-width":`2`,"stroke-linecap":`round`,"stroke-linejoin":`round`,"aria-hidden":`true`},l=[`id`,`aria-label`],u=[`aria-selected`,`aria-disabled`,`tabindex`,`onClick`,`onKeydown`],d={key:0,class:`t-select__check`,viewBox:`0 0 16 16`,fill:`none`,stroke:`currentColor`,"stroke-width":`2`,"stroke-linecap":`round`,"stroke-linejoin":`round`,"aria-hidden":`true`},f=(0,n.defineComponent)({inheritAttrs:!1,__name:`TSelect`,props:{modelValue:{default:``},options:{default:()=>[]},open:{type:Boolean,default:void 0},defaultOpen:{type:Boolean,default:!1},size:{default:`md`},disabled:{type:Boolean,default:!1},loading:{type:Boolean,default:!1},invalid:{type:Boolean,default:!1},placeholder:{default:``}},emits:[`update:modelValue`,`update:open`,`open-change`],setup(f,{emit:p}){let m=f,h=p,g=(0,n.useAttrs)(),_=(0,r.createId)(`t-select`),v=(0,n.ref)(null),y=(0,n.ref)(null),b=(0,n.ref)(null),x=(0,n.ref)(new Map),S=(0,n.ref)(-1),C=(0,n.ref)(!1),w=(0,n.computed)(()=>{let{class:e,style:t,...n}=g;return n}),{value:T,setValue:E}=t.useControllableOpen((0,n.toRef)(m,`open`),m.defaultOpen,e=>{h(`update:open`,e),h(`open-change`,e)}),D=(0,n.computed)(()=>[`t-select`,`t-select--${m.size}`,{"t-select--drop-up":C.value,"is-disabled":m.disabled,"is-invalid":m.invalid,"is-loading":m.loading,"is-open":T.value},g.class]),O=e=>{let t=e.parentElement;for(;t&&t!==document.body;){let{overflowY:e}=window.getComputedStyle(t);if(e===`auto`||e===`scroll`||e===`hidden`)return t;t=t.parentElement}return null},k=()=>{let e=y.value,t=b.value;if(!e||!t){C.value=!1;return}let n=e.getBoundingClientRect(),r=t.getBoundingClientRect(),i=O(e)?.getBoundingClientRect(),a=Math.min(i?.bottom??1/0,window.innerHeight),o=Math.max(i?.top??0,0),s=a-n.bottom,c=n.top-o;C.value=r.bottom>a&&c>s},A=(0,n.computed)(()=>g.style),j=(0,n.computed)(()=>m.options.find(e=>e.value===m.modelValue)?.label??``),M=(0,n.computed)(()=>m.options.filter(e=>!e.disabled)),N=()=>{if(m.disabled)return;let e=m.options.findIndex(e=>e.value===m.modelValue);S.value=e>=0?e:0,C.value=!1,E(!0),(0,n.nextTick)(()=>{k(),L(S.value)})},P=(e=!1)=>{E(!1),S.value=-1,e&&(0,n.nextTick)(()=>y.value?.focus())},F=()=>{T.value?P():N()},I=e=>{e.disabled||(h(`update:modelValue`,e.value),P(!0))},L=e=>{let t=m.options[e];t&&x.value.get(t.value)?.focus()},R=(e,t)=>{e instanceof HTMLElement?x.value.set(t,e):x.value.delete(t)},z=e=>{let t=S.value+e;for(;t>=0&&t<m.options.length;){if(!m.options[t].disabled){S.value=t,L(t);return}t+=e}},B=e=>{if(!m.disabled){if((0,r.isEscapeKey)(e)&&T.value){e.preventDefault(),P();return}((0,r.isActivationKey)(e)||e.key===`ArrowDown`||e.key===`ArrowUp`)&&(e.preventDefault(),N())}},V=(e,t,n)=>{if((0,r.isEscapeKey)(e)){e.preventDefault(),P(!0);return}if((0,r.isActivationKey)(e)){e.preventDefault(),I(t);return}switch(e.key){case`ArrowDown`:e.preventDefault(),z(1);break;case`ArrowUp`:e.preventDefault(),z(-1);break;case`Home`:e.preventDefault(),S.value=M.value.length>0?m.options.indexOf(M.value[0]):0,L(S.value);break;case`End`:e.preventDefault(),S.value=M.value.length>0?m.options.indexOf(M.value[M.value.length-1]):m.options.length-1,L(S.value);break;default:break}},H=e=>{if(!T.value)return;let t=e.target;t instanceof Node&&(v.value?.contains(t)||P())},U=(0,n.computed)(()=>m.modelValue!==``&&m.modelValue!==null&&m.modelValue!==void 0);return(0,n.watch)(T,e=>{e?document.addEventListener(`pointerdown`,H):document.removeEventListener(`pointerdown`,H)}),(0,n.onBeforeUnmount)(()=>{document.removeEventListener(`pointerdown`,H)}),(t,r)=>((0,n.openBlock)(),(0,n.createElementBlock)(`div`,{ref_key:`rootRef`,ref:v,class:(0,n.normalizeClass)(D.value),style:(0,n.normalizeStyle)(A.value),"data-state":(0,n.unref)(T)?`open`:`closed`},[(0,n.createElementVNode)(`button`,(0,n.mergeProps)({ref_key:`triggerRef`,ref:y},w.value,{type:`button`,class:`t-select__trigger`,disabled:f.disabled,"aria-controls":(0,n.unref)(T)?(0,n.unref)(_):void 0,"aria-haspopup":`listbox`,"aria-expanded":(0,n.unref)(T),"aria-invalid":f.invalid||void 0,"aria-busy":f.loading||void 0,onClick:F,onKeydown:B}),[t.$slots.prefix?((0,n.openBlock)(),(0,n.createElementBlock)(`span`,o,[(0,n.renderSlot)(t.$slots,`prefix`)])):(0,n.createCommentVNode)(``,!0),(0,n.createElementVNode)(`span`,{class:`t-select__value`,"data-placeholder":!U.value||void 0},(0,n.toDisplayString)(j.value||f.placeholder),9,s),f.loading?((0,n.openBlock)(),(0,n.createBlock)(e.default,{key:1,size:`sm`,label:`Loading`})):((0,n.openBlock)(),(0,n.createElementBlock)(`svg`,c,[...r[0]||=[(0,n.createElementVNode)(`polyline`,{points:`4 6 8 10 12 6`},null,-1)]]))],16,a),(0,n.createVNode)(n.Transition,{name:`t-fade`},{default:(0,n.withCtx)(()=>[(0,n.unref)(T)&&!f.disabled?((0,n.openBlock)(),(0,n.createElementBlock)(`ul`,{key:0,id:(0,n.unref)(_),ref_key:`listboxRef`,ref:b,role:`listbox`,class:`t-select__listbox`,"aria-label":typeof w.value[`aria-label`]==`string`?w.value[`aria-label`]:void 0},[((0,n.openBlock)(!0),(0,n.createElementBlock)(n.Fragment,null,(0,n.renderList)(f.options,(e,t)=>((0,n.openBlock)(),(0,n.createElementBlock)(`li`,{key:e.value,ref_for:!0,ref:t=>R(t,e.value),role:`option`,class:(0,n.normalizeClass)([`t-select__option`,{"is-selected":e.value===f.modelValue,"is-disabled":e.disabled,"is-focused":t===S.value}]),"aria-selected":e.value===f.modelValue,"aria-disabled":e.disabled||void 0,tabindex:e.disabled?-1:0,onClick:t=>I(e),onKeydown:n=>V(n,e,t)},[(0,n.createTextVNode)((0,n.toDisplayString)(e.label)+` `,1),e.value===f.modelValue?((0,n.openBlock)(),(0,n.createElementBlock)(`svg`,d,[...r[1]||=[(0,n.createElementVNode)(`polyline`,{points:`3.5 8.5 6.5 11.5 12.5 4.5`},null,-1)]])):(0,n.createCommentVNode)(``,!0)],42,u))),128))],8,l)):(0,n.createCommentVNode)(``,!0)]),_:1})],14,i))}});exports.default=f;
|
|
1
|
+
const e=require("./TSpinner.cjs"),t=require("../composables/useControllableOpen.cjs");let n=require("vue"),r=require("@treeui/utils");var i=[`data-state`],a=[`disabled`,`aria-controls`,`aria-expanded`,`aria-invalid`,`aria-busy`],o={key:0,class:`t-select__slot t-select__slot--prefix`},s=[`data-placeholder`],c={key:2,class:`t-select__chevron`,viewBox:`0 0 16 16`,fill:`none`,stroke:`currentColor`,"stroke-width":`2`,"stroke-linecap":`round`,"stroke-linejoin":`round`,"aria-hidden":`true`},l=[`id`,`aria-label`],u=[`aria-selected`,`aria-disabled`,`tabindex`,`onClick`,`onKeydown`],d={key:0,class:`t-select__check`,viewBox:`0 0 16 16`,fill:`none`,stroke:`currentColor`,"stroke-width":`2`,"stroke-linecap":`round`,"stroke-linejoin":`round`,"aria-hidden":`true`},f=(0,n.defineComponent)({inheritAttrs:!1,__name:`TSelect`,props:{modelValue:{default:``},options:{default:()=>[]},open:{type:Boolean,default:void 0},defaultOpen:{type:Boolean,default:!1},size:{default:`md`},width:{default:`full`},disabled:{type:Boolean,default:!1},loading:{type:Boolean,default:!1},invalid:{type:Boolean,default:!1},placeholder:{default:``}},emits:[`update:modelValue`,`update:open`,`open-change`],setup(f,{emit:p}){let m=f,h=p,g=(0,n.useAttrs)(),_=(0,r.createId)(`t-select`),v=(0,n.ref)(null),y=(0,n.ref)(null),b=(0,n.ref)(null),x=(0,n.ref)(new Map),S=(0,n.ref)(-1),C=(0,n.ref)(!1),w=(0,n.computed)(()=>{let{class:e,style:t,...n}=g;return n}),{value:T,setValue:E}=t.useControllableOpen((0,n.toRef)(m,`open`),m.defaultOpen,e=>{h(`update:open`,e),h(`open-change`,e)}),D=(0,n.computed)(()=>[`t-select`,`t-select--${m.size}`,m.width===`full`?null:`t-field-width--${m.width}`,{"t-select--drop-up":C.value,"is-disabled":m.disabled,"is-invalid":m.invalid,"is-loading":m.loading,"is-open":T.value},g.class]),O=e=>{let t=e.parentElement;for(;t&&t!==document.body;){let{overflowY:e}=window.getComputedStyle(t);if(e===`auto`||e===`scroll`||e===`hidden`)return t;t=t.parentElement}return null},k=()=>{let e=y.value,t=b.value;if(!e||!t){C.value=!1;return}let n=e.getBoundingClientRect(),r=t.getBoundingClientRect(),i=O(e)?.getBoundingClientRect(),a=Math.min(i?.bottom??1/0,window.innerHeight),o=Math.max(i?.top??0,0),s=a-n.bottom,c=n.top-o;C.value=r.bottom>a&&c>s},A=(0,n.computed)(()=>g.style),j=(0,n.computed)(()=>m.options.find(e=>e.value===m.modelValue)?.label??``),M=(0,n.computed)(()=>m.options.filter(e=>!e.disabled)),N=()=>{if(m.disabled)return;let e=m.options.findIndex(e=>e.value===m.modelValue);S.value=e>=0?e:0,C.value=!1,E(!0),(0,n.nextTick)(()=>{k(),L(S.value)})},P=(e=!1)=>{E(!1),S.value=-1,e&&(0,n.nextTick)(()=>y.value?.focus())},F=()=>{T.value?P():N()},I=e=>{e.disabled||(h(`update:modelValue`,e.value),P(!0))},L=e=>{let t=m.options[e];t&&x.value.get(t.value)?.focus()},R=(e,t)=>{e instanceof HTMLElement?x.value.set(t,e):x.value.delete(t)},z=e=>{let t=S.value+e;for(;t>=0&&t<m.options.length;){if(!m.options[t].disabled){S.value=t,L(t);return}t+=e}},B=e=>{if(!m.disabled){if((0,r.isEscapeKey)(e)&&T.value){e.preventDefault(),P();return}((0,r.isActivationKey)(e)||e.key===`ArrowDown`||e.key===`ArrowUp`)&&(e.preventDefault(),N())}},V=(e,t,n)=>{if((0,r.isEscapeKey)(e)){e.preventDefault(),P(!0);return}if((0,r.isActivationKey)(e)){e.preventDefault(),I(t);return}switch(e.key){case`ArrowDown`:e.preventDefault(),z(1);break;case`ArrowUp`:e.preventDefault(),z(-1);break;case`Home`:e.preventDefault(),S.value=M.value.length>0?m.options.indexOf(M.value[0]):0,L(S.value);break;case`End`:e.preventDefault(),S.value=M.value.length>0?m.options.indexOf(M.value[M.value.length-1]):m.options.length-1,L(S.value);break;default:break}},H=e=>{if(!T.value)return;let t=e.target;t instanceof Node&&(v.value?.contains(t)||P())},U=(0,n.computed)(()=>m.modelValue!==``&&m.modelValue!==null&&m.modelValue!==void 0);return(0,n.watch)(T,e=>{e?document.addEventListener(`pointerdown`,H):document.removeEventListener(`pointerdown`,H)}),(0,n.onBeforeUnmount)(()=>{document.removeEventListener(`pointerdown`,H)}),(t,r)=>((0,n.openBlock)(),(0,n.createElementBlock)(`div`,{ref_key:`rootRef`,ref:v,class:(0,n.normalizeClass)(D.value),style:(0,n.normalizeStyle)(A.value),"data-state":(0,n.unref)(T)?`open`:`closed`},[(0,n.createElementVNode)(`button`,(0,n.mergeProps)({ref_key:`triggerRef`,ref:y},w.value,{type:`button`,class:`t-select__trigger`,disabled:f.disabled,"aria-controls":(0,n.unref)(T)?(0,n.unref)(_):void 0,"aria-haspopup":`listbox`,"aria-expanded":(0,n.unref)(T),"aria-invalid":f.invalid||void 0,"aria-busy":f.loading||void 0,onClick:F,onKeydown:B}),[t.$slots.prefix?((0,n.openBlock)(),(0,n.createElementBlock)(`span`,o,[(0,n.renderSlot)(t.$slots,`prefix`)])):(0,n.createCommentVNode)(``,!0),(0,n.createElementVNode)(`span`,{class:`t-select__value`,"data-placeholder":!U.value||void 0},(0,n.toDisplayString)(j.value||f.placeholder),9,s),f.loading?((0,n.openBlock)(),(0,n.createBlock)(e.default,{key:1,size:`sm`,label:`Loading`})):((0,n.openBlock)(),(0,n.createElementBlock)(`svg`,c,[...r[0]||=[(0,n.createElementVNode)(`polyline`,{points:`4 6 8 10 12 6`},null,-1)]]))],16,a),(0,n.createVNode)(n.Transition,{name:`t-fade`},{default:(0,n.withCtx)(()=>[(0,n.unref)(T)&&!f.disabled?((0,n.openBlock)(),(0,n.createElementBlock)(`ul`,{key:0,id:(0,n.unref)(_),ref_key:`listboxRef`,ref:b,role:`listbox`,class:`t-select__listbox`,"aria-label":typeof w.value[`aria-label`]==`string`?w.value[`aria-label`]:void 0},[((0,n.openBlock)(!0),(0,n.createElementBlock)(n.Fragment,null,(0,n.renderList)(f.options,(e,t)=>((0,n.openBlock)(),(0,n.createElementBlock)(`li`,{key:e.value,ref_for:!0,ref:t=>R(t,e.value),role:`option`,class:(0,n.normalizeClass)([`t-select__option`,{"is-selected":e.value===f.modelValue,"is-disabled":e.disabled,"is-focused":t===S.value}]),"aria-selected":e.value===f.modelValue,"aria-disabled":e.disabled||void 0,tabindex:e.disabled?-1:0,onClick:t=>I(e),onKeydown:n=>V(n,e,t)},[(0,n.createTextVNode)((0,n.toDisplayString)(e.label)+` `,1),e.value===f.modelValue?((0,n.openBlock)(),(0,n.createElementBlock)(`svg`,d,[...r[1]||=[(0,n.createElementVNode)(`polyline`,{points:`3.5 8.5 6.5 11.5 12.5 4.5`},null,-1)]])):(0,n.createCommentVNode)(``,!0)],42,u))),128))],8,l)):(0,n.createCommentVNode)(``,!0)]),_:1})],14,i))}});exports.default=f;
|
|
2
2
|
//# sourceMappingURL=TSelect.vue_vue_type_script_setup_true_lang.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TSelect.vue_vue_type_script_setup_true_lang.cjs","names":["$slots"],"sources":["../../src/components/TSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { createId, isActivationKey, isEscapeKey } from '@treeui/utils';\nimport { computed, nextTick, onBeforeUnmount, ref, toRef, useAttrs, watch } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TSelectOption {\n label: string;\n value: string | number;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string | number;\n options?: TSelectOption[];\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n placeholder?: string;\n }>(),\n {\n modelValue: '',\n options: () => [],\n open: undefined,\n defaultOpen: false,\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n placeholder: '',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\nconst listboxId = createId('t-select');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst listboxRef = ref<HTMLElement | null>(null);\nconst optionRefs = ref<Map<string | number, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\nconst dropUp = ref(false);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-select',\n `t-select--${props.size}`,\n {\n 't-select--drop-up': dropUp.value,\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\n// Nearest ancestor that can clip the listbox (scroll container or hidden overflow).\nconst findClippingAncestor = (element: HTMLElement): HTMLElement | null => {\n let parent = element.parentElement;\n while (parent && parent !== document.body) {\n const { overflowY } = window.getComputedStyle(parent);\n if (overflowY === 'auto' || overflowY === 'scroll' || overflowY === 'hidden') {\n return parent;\n }\n parent = parent.parentElement;\n }\n return null;\n};\n\n// Flip the listbox above the trigger when its rendered position overflows the\n// nearest clipping ancestor (e.g. a modal body) or the viewport, and there is\n// more room above the trigger than below it. Measuring the rendered rect keeps\n// the decision in sync with the CSS offset (--tree-space-2) automatically.\nconst updateDropDirection = () => {\n const trigger = triggerRef.value;\n const listbox = listboxRef.value;\n if (!trigger || !listbox) {\n dropUp.value = false;\n return;\n }\n const triggerRect = trigger.getBoundingClientRect();\n const listboxRect = listbox.getBoundingClientRect();\n const boundary = findClippingAncestor(trigger)?.getBoundingClientRect();\n const bottomLimit = Math.min(boundary?.bottom ?? Infinity, window.innerHeight);\n const topLimit = Math.max(boundary?.top ?? 0, 0);\n const spaceBelow = bottomLimit - triggerRect.bottom;\n const spaceAbove = triggerRect.top - topLimit;\n dropUp.value = listboxRect.bottom > bottomLimit && spaceAbove > spaceBelow;\n};\n\nconst rootStyle = computed(() => attrs.style);\n\nconst selectedLabel = computed(() => {\n const opt = props.options.find((o) => o.value === props.modelValue);\n return opt?.label ?? '';\n});\n\nconst enabledOptions = computed(() =>\n props.options.filter((o) => !o.disabled),\n);\n\nconst openDropdown = () => {\n if (props.disabled) return;\n const selectedIdx = props.options.findIndex((o) => o.value === props.modelValue);\n focusedIndex.value = selectedIdx >= 0 ? selectedIdx : 0;\n // Render downward first so the measurement always starts from the default position.\n dropUp.value = false;\n setValue(true);\n nextTick(() => {\n updateDropDirection();\n focusOption(focusedIndex.value);\n });\n};\n\nconst closeDropdown = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => triggerRef.value?.focus());\n }\n};\n\nconst toggleDropdown = () => {\n if (isOpen.value) {\n closeDropdown();\n } else {\n openDropdown();\n }\n};\n\nconst selectOption = (opt: TSelectOption) => {\n if (opt.disabled) return;\n emit('update:modelValue', opt.value);\n closeDropdown(true);\n};\n\nconst focusOption = (index: number) => {\n const opt = props.options[index];\n if (!opt) return;\n const el = optionRefs.value.get(opt.value);\n el?.focus();\n};\n\nconst setOptionRef = (el: Element | null, value: string | number) => {\n if (el instanceof HTMLElement) {\n optionRefs.value.set(value, el);\n } else {\n optionRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.options.length) {\n if (!props.options[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusOption(nextIndex);\n return;\n }\n nextIndex += direction;\n }\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) return;\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeDropdown();\n return;\n }\n\n if (isActivationKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n openDropdown();\n }\n};\n\nconst onOptionKeydown = (event: KeyboardEvent, opt: TSelectOption, _index: number) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeDropdown(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectOption(opt);\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(-1);\n break;\n case 'Home':\n event.preventDefault();\n focusedIndex.value = enabledOptions.value.length > 0\n ? props.options.indexOf(enabledOptions.value[0])\n : 0;\n focusOption(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledOptions.value.length > 0\n ? props.options.indexOf(enabledOptions.value[enabledOptions.value.length - 1])\n : props.options.length - 1;\n focusOption(focusedIndex.value);\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) return;\n const target = event.target;\n if (!(target instanceof Node)) return;\n if (rootRef.value?.contains(target)) return;\n closeDropdown();\n};\n\nconst hasSelection = computed(() =>\n props.modelValue !== '' && props.modelValue !== null && props.modelValue !== undefined,\n);\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n } else {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-select__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? listboxId : undefined\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"isOpen\"\n :aria-invalid=\"invalid || undefined\"\n :aria-busy=\"loading || undefined\"\n @click=\"toggleDropdown\"\n @keydown=\"onTriggerKeydown\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-select__slot t-select__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <span\n class=\"t-select__value\"\n :data-placeholder=\"!hasSelection ? true : undefined\"\n >\n {{ selectedLabel || placeholder }}\n </span>\n <TSpinner\n v-if=\"loading\"\n size=\"sm\"\n label=\"Loading\"\n />\n <svg\n v-else\n class=\"t-select__chevron\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"4 6 8 10 12 6\" />\n </svg>\n </button>\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"listboxId\"\n ref=\"listboxRef\"\n role=\"listbox\"\n class=\"t-select__listbox\"\n :aria-label=\"typeof triggerAttrs['aria-label'] === 'string' ? triggerAttrs['aria-label'] : undefined\"\n >\n <li\n v-for=\"(opt, index) in options\"\n :key=\"opt.value\"\n :ref=\"(el) => setOptionRef(el as Element | null, opt.value)\"\n role=\"option\"\n class=\"t-select__option\"\n :class=\"{\n 'is-selected': opt.value === modelValue,\n 'is-disabled': opt.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-selected=\"opt.value === modelValue\"\n :aria-disabled=\"opt.disabled || undefined\"\n :tabindex=\"opt.disabled ? -1 : 0\"\n @click=\"selectOption(opt)\"\n @keydown=\"onOptionKeydown($event, opt, index)\"\n >\n {{ opt.label }}\n <svg\n v-if=\"opt.value === modelValue\"\n class=\"t-select__check\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"3.5 8.5 6.5 11.5 12.5 4.5\" />\n </svg>\n </li>\n </ul>\n </transition>\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TSelect.vue_vue_type_script_setup_true_lang.cjs","names":["$slots"],"sources":["../../src/components/TSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { createId, isActivationKey, isEscapeKey } from '@treeui/utils';\nimport { computed, nextTick, onBeforeUnmount, ref, toRef, useAttrs, watch } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TFieldWidth, TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TSelectOption {\n label: string;\n value: string | number;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string | number;\n options?: TSelectOption[];\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n /** Inline-size cap. Fluid (`full`) by default. */\n width?: TFieldWidth;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n placeholder?: string;\n }>(),\n {\n modelValue: '',\n options: () => [],\n open: undefined,\n defaultOpen: false,\n size: 'md',\n width: 'full',\n disabled: false,\n loading: false,\n invalid: false,\n placeholder: '',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\nconst listboxId = createId('t-select');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst listboxRef = ref<HTMLElement | null>(null);\nconst optionRefs = ref<Map<string | number, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\nconst dropUp = ref(false);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-select',\n `t-select--${props.size}`,\n props.width !== 'full' ? `t-field-width--${props.width}` : null,\n {\n 't-select--drop-up': dropUp.value,\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\n// Nearest ancestor that can clip the listbox (scroll container or hidden overflow).\nconst findClippingAncestor = (element: HTMLElement): HTMLElement | null => {\n let parent = element.parentElement;\n while (parent && parent !== document.body) {\n const { overflowY } = window.getComputedStyle(parent);\n if (overflowY === 'auto' || overflowY === 'scroll' || overflowY === 'hidden') {\n return parent;\n }\n parent = parent.parentElement;\n }\n return null;\n};\n\n// Flip the listbox above the trigger when its rendered position overflows the\n// nearest clipping ancestor (e.g. a modal body) or the viewport, and there is\n// more room above the trigger than below it. Measuring the rendered rect keeps\n// the decision in sync with the CSS offset (--tree-space-2) automatically.\nconst updateDropDirection = () => {\n const trigger = triggerRef.value;\n const listbox = listboxRef.value;\n if (!trigger || !listbox) {\n dropUp.value = false;\n return;\n }\n const triggerRect = trigger.getBoundingClientRect();\n const listboxRect = listbox.getBoundingClientRect();\n const boundary = findClippingAncestor(trigger)?.getBoundingClientRect();\n const bottomLimit = Math.min(boundary?.bottom ?? Infinity, window.innerHeight);\n const topLimit = Math.max(boundary?.top ?? 0, 0);\n const spaceBelow = bottomLimit - triggerRect.bottom;\n const spaceAbove = triggerRect.top - topLimit;\n dropUp.value = listboxRect.bottom > bottomLimit && spaceAbove > spaceBelow;\n};\n\nconst rootStyle = computed(() => attrs.style);\n\nconst selectedLabel = computed(() => {\n const opt = props.options.find((o) => o.value === props.modelValue);\n return opt?.label ?? '';\n});\n\nconst enabledOptions = computed(() =>\n props.options.filter((o) => !o.disabled),\n);\n\nconst openDropdown = () => {\n if (props.disabled) return;\n const selectedIdx = props.options.findIndex((o) => o.value === props.modelValue);\n focusedIndex.value = selectedIdx >= 0 ? selectedIdx : 0;\n // Render downward first so the measurement always starts from the default position.\n dropUp.value = false;\n setValue(true);\n nextTick(() => {\n updateDropDirection();\n focusOption(focusedIndex.value);\n });\n};\n\nconst closeDropdown = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => triggerRef.value?.focus());\n }\n};\n\nconst toggleDropdown = () => {\n if (isOpen.value) {\n closeDropdown();\n } else {\n openDropdown();\n }\n};\n\nconst selectOption = (opt: TSelectOption) => {\n if (opt.disabled) return;\n emit('update:modelValue', opt.value);\n closeDropdown(true);\n};\n\nconst focusOption = (index: number) => {\n const opt = props.options[index];\n if (!opt) return;\n const el = optionRefs.value.get(opt.value);\n el?.focus();\n};\n\nconst setOptionRef = (el: Element | null, value: string | number) => {\n if (el instanceof HTMLElement) {\n optionRefs.value.set(value, el);\n } else {\n optionRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.options.length) {\n if (!props.options[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusOption(nextIndex);\n return;\n }\n nextIndex += direction;\n }\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) return;\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeDropdown();\n return;\n }\n\n if (isActivationKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n openDropdown();\n }\n};\n\nconst onOptionKeydown = (event: KeyboardEvent, opt: TSelectOption, _index: number) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeDropdown(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectOption(opt);\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(-1);\n break;\n case 'Home':\n event.preventDefault();\n focusedIndex.value = enabledOptions.value.length > 0\n ? props.options.indexOf(enabledOptions.value[0])\n : 0;\n focusOption(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledOptions.value.length > 0\n ? props.options.indexOf(enabledOptions.value[enabledOptions.value.length - 1])\n : props.options.length - 1;\n focusOption(focusedIndex.value);\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) return;\n const target = event.target;\n if (!(target instanceof Node)) return;\n if (rootRef.value?.contains(target)) return;\n closeDropdown();\n};\n\nconst hasSelection = computed(() =>\n props.modelValue !== '' && props.modelValue !== null && props.modelValue !== undefined,\n);\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n } else {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-select__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? listboxId : undefined\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"isOpen\"\n :aria-invalid=\"invalid || undefined\"\n :aria-busy=\"loading || undefined\"\n @click=\"toggleDropdown\"\n @keydown=\"onTriggerKeydown\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-select__slot t-select__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <span\n class=\"t-select__value\"\n :data-placeholder=\"!hasSelection ? true : undefined\"\n >\n {{ selectedLabel || placeholder }}\n </span>\n <TSpinner\n v-if=\"loading\"\n size=\"sm\"\n label=\"Loading\"\n />\n <svg\n v-else\n class=\"t-select__chevron\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"4 6 8 10 12 6\" />\n </svg>\n </button>\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"listboxId\"\n ref=\"listboxRef\"\n role=\"listbox\"\n class=\"t-select__listbox\"\n :aria-label=\"typeof triggerAttrs['aria-label'] === 'string' ? triggerAttrs['aria-label'] : undefined\"\n >\n <li\n v-for=\"(opt, index) in options\"\n :key=\"opt.value\"\n :ref=\"(el) => setOptionRef(el as Element | null, opt.value)\"\n role=\"option\"\n class=\"t-select__option\"\n :class=\"{\n 'is-selected': opt.value === modelValue,\n 'is-disabled': opt.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-selected=\"opt.value === modelValue\"\n :aria-disabled=\"opt.disabled || undefined\"\n :tabindex=\"opt.disabled ? -1 : 0\"\n @click=\"selectOption(opt)\"\n @keydown=\"onOptionKeydown($event, opt, index)\"\n >\n {{ opt.label }}\n <svg\n v-if=\"opt.value === modelValue\"\n class=\"t-select__check\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"3.5 8.5 6.5 11.5 12.5 4.5\" />\n </svg>\n </li>\n </ul>\n </transition>\n </div>\n</template>\n"],"mappings":"wqCAiBA,IAAM,EAAQ,EA4BR,EAAO,EAMP,GAAA,EAAA,EAAA,SAAA,CAAiB,EACjB,GAAA,EAAA,EAAA,SAAA,CAAqB,UAAU,EAC/B,GAAA,EAAA,EAAA,IAAA,CAAkC,IAAI,EACtC,GAAA,EAAA,EAAA,IAAA,CAA2C,IAAI,EAC/C,GAAA,EAAA,EAAA,IAAA,CAAqC,IAAI,EACzC,GAAA,EAAA,EAAA,IAAA,CAAoD,IAAI,GAAK,EAC7D,GAAA,EAAA,EAAA,IAAA,CAAmB,EAAE,EACrB,GAAA,EAAA,EAAA,IAAA,CAAa,EAAK,EAElB,GAAA,EAAA,EAAA,SAAA,KAA8B,CAClC,GAAM,CAAE,MAAO,EAAQ,MAAO,EAAQ,GAAG,GAAS,EAClD,OAAO,CACT,CAAC,EAEK,CAAE,MAAO,EAAQ,YAAa,EAAA,qBAAA,EAAA,EAAA,MAAA,CAC5B,EAAO,MAAM,EACnB,EAAM,YACL,GAAU,CACT,EAAK,cAAe,CAAK,EACzB,EAAK,cAAe,CAAK,CAC3B,CACF,EAEM,GAAA,EAAA,EAAA,SAAA,KAA6B,CACjC,WACA,aAAa,EAAM,OACnB,EAAM,QAAU,OAA2C,KAAlC,kBAAkB,EAAM,QACjD,CACE,oBAAqB,EAAO,MAC5B,cAAe,EAAM,SACrB,aAAc,EAAM,QACpB,aAAc,EAAM,QACpB,UAAW,EAAO,KACpB,EACA,EAAM,KACR,CAAC,EAGK,EAAwB,GAA6C,CACzE,IAAI,EAAS,EAAQ,cACrB,KAAO,GAAU,IAAW,SAAS,MAAM,CACzC,GAAM,CAAE,aAAc,OAAO,iBAAiB,CAAM,EACpD,GAAI,IAAc,QAAU,IAAc,UAAY,IAAc,SAClE,OAAO,EAET,EAAS,EAAO,aAClB,CACA,OAAO,IACT,EAMM,MAA4B,CAChC,IAAM,EAAU,EAAW,MACrB,EAAU,EAAW,MAC3B,GAAI,CAAC,GAAW,CAAC,EAAS,CACxB,EAAO,MAAQ,GACf,MACF,CACA,IAAM,EAAc,EAAQ,sBAAsB,EAC5C,EAAc,EAAQ,sBAAsB,EAC5C,EAAW,EAAqB,CAAO,CAAC,EAAE,sBAAsB,EAChE,EAAc,KAAK,IAAI,GAAU,QAAU,IAAU,OAAO,WAAW,EACvE,EAAW,KAAK,IAAI,GAAU,KAAO,EAAG,CAAC,EACzC,EAAa,EAAc,EAAY,OACvC,EAAa,EAAY,IAAM,EACrC,EAAO,MAAQ,EAAY,OAAS,GAAe,EAAa,CAClE,EAEM,GAAA,EAAA,EAAA,SAAA,KAA2B,EAAM,KAAK,EAEtC,GAAA,EAAA,EAAA,SAAA,KACQ,EAAM,QAAQ,KAAM,GAAM,EAAE,QAAU,EAAM,UACjD,CAAA,EAAK,OAAS,EACtB,EAEK,GAAA,EAAA,EAAA,SAAA,KACJ,EAAM,QAAQ,OAAQ,GAAM,CAAC,EAAE,QAAQ,CACzC,EAEM,MAAqB,CACzB,GAAI,EAAM,SAAU,OACpB,IAAM,EAAc,EAAM,QAAQ,UAAW,GAAM,EAAE,QAAU,EAAM,UAAU,EAC/E,EAAa,MAAQ,GAAe,EAAI,EAAc,EAEtD,EAAO,MAAQ,GACf,EAAS,EAAI,GACb,EAAA,EAAA,SAAA,KAAe,CACb,EAAoB,EACpB,EAAY,EAAa,KAAK,CAChC,CAAC,CACH,EAEM,GAAiB,EAAe,KAAU,CAC9C,EAAS,EAAK,EACd,EAAa,MAAQ,GACjB,IACF,EAAA,EAAA,SAAA,KAAe,EAAW,OAAO,MAAM,CAAC,CAE5C,EAEM,MAAuB,CACvB,EAAO,MACT,EAAc,EAEd,EAAa,CAEjB,EAEM,EAAgB,GAAuB,CACvC,EAAI,WACR,EAAK,oBAAqB,EAAI,KAAK,EACnC,EAAc,EAAI,EACpB,EAEM,EAAe,GAAkB,CACrC,IAAM,EAAM,EAAM,QAAQ,GACrB,GAEL,EADsB,MAAM,IAAI,EAAI,KACpC,CAAA,EAAI,MAAM,CACZ,EAEM,GAAgB,EAAoB,IAA2B,CAC/D,aAAc,YAChB,EAAW,MAAM,IAAI,EAAO,CAAE,EAE9B,EAAW,MAAM,OAAO,CAAK,CAEjC,EAEM,EAAa,GAAsB,CACvC,IAAI,EAAY,EAAa,MAAQ,EACrC,KAAO,GAAa,GAAK,EAAY,EAAM,QAAQ,QAAQ,CACzD,GAAI,CAAC,EAAM,QAAQ,EAAU,CAAC,SAAU,CACtC,EAAa,MAAQ,EACrB,EAAY,CAAS,EACrB,MACF,CACA,GAAa,CACf,CACF,EAEM,EAAoB,GAAyB,CAC7C,MAAM,SAEV,KAAA,EAAA,EAAA,YAAA,CAAgB,CAAK,GAAK,EAAO,MAAO,CACtC,EAAM,eAAe,EACrB,EAAc,EACd,MACF,GAEA,EAAA,EAAA,gBAAA,CAAoB,CAAK,GAAK,EAAM,MAAQ,aAAe,EAAM,MAAQ,aACvE,EAAM,eAAe,EACrB,EAAa,EAJf,CAMF,EAEM,GAAmB,EAAsB,EAAoB,IAAmB,CACpF,IAAA,EAAA,EAAA,YAAA,CAAgB,CAAK,EAAG,CACtB,EAAM,eAAe,EACrB,EAAc,EAAI,EAClB,MACF,CAEA,IAAA,EAAA,EAAA,gBAAA,CAAoB,CAAK,EAAG,CAC1B,EAAM,eAAe,EACrB,EAAa,CAAG,EAChB,MACF,CAEA,OAAQ,EAAM,IAAd,CACE,IAAK,YACH,EAAM,eAAe,EACrB,EAAU,CAAC,EACX,MACF,IAAK,UACH,EAAM,eAAe,EACrB,EAAU,EAAE,EACZ,MACF,IAAK,OACH,EAAM,eAAe,EACrB,EAAa,MAAQ,EAAe,MAAM,OAAS,EAC/C,EAAM,QAAQ,QAAQ,EAAe,MAAM,EAAE,EAC7C,EACJ,EAAY,EAAa,KAAK,EAC9B,MACF,IAAK,MACH,EAAM,eAAe,EACrB,EAAa,MAAQ,EAAe,MAAM,OAAS,EAC/C,EAAM,QAAQ,QAAQ,EAAe,MAAM,EAAe,MAAM,OAAS,EAAE,EAC3E,EAAM,QAAQ,OAAS,EAC3B,EAAY,EAAa,KAAK,EAC9B,MACF,QACE,KACJ,CACF,EAEM,EAAyB,GAAwB,CACrD,GAAI,CAAC,EAAO,MAAO,OACnB,IAAM,EAAS,EAAM,OACf,aAAkB,OACpB,EAAQ,OAAO,SAAS,CAAM,GAClC,EAAc,EAChB,EAEM,GAAA,EAAA,EAAA,SAAA,KACJ,EAAM,aAAe,IAAM,EAAM,aAAe,MAAQ,EAAM,aAAe,IAAA,EAC/E,SAEA,EAAA,EAAA,MAAA,CAAM,EAAS,GAAU,CACnB,EACF,SAAS,iBAAiB,cAAe,CAAqB,EAE9D,SAAS,oBAAoB,cAAe,CAAqB,CAErE,CAAC,GAED,EAAA,EAAA,gBAAA,KAAsB,CACpB,SAAS,oBAAoB,cAAe,CAAqB,CACnE,CAAC,qDAkGO,MAAA,SA7FA,UAAJ,IAAI,EACH,OAAA,EAAA,EAAA,eAAA,CAAO,EAAA,KAAW,EAClB,OAAA,EAAA,EAAA,eAAA,CAAO,EAAA,KAAS,EAChB,cAAA,EAAA,EAAA,MAAA,CAAY,CAAA,EAAM,OAAA,oCA8CV,UAAA,EAAA,EAAA,WAAA,CAAA,SA3CH,aAAJ,IAAI,GACI,EAAA,MAAY,CACpB,KAAK,SACL,MAAM,oBACL,SAAU,EAAA,SACV,iBAAA,EAAA,EAAA,MAAA,CAAe,CAAA,GAAA,EAAA,EAAA,MAAA,CAAS,CAAA,EAAY,IAAA,GACrC,gBAAc,UACb,iBAAA,EAAA,EAAA,MAAA,CAAe,CAAA,EACf,eAAc,EAAA,SAAW,IAAA,GACzB,YAAW,EAAA,SAAW,IAAA,GACtB,QAAO,EACP,UAAS,KAGFA,EAAAA,OAAO,SAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAIR,OALP,EAKO,EAAA,EAAA,EAAA,WAAA,CADiB,EAAA,OAAA,QAAA,CAAA,CAAA,IAAA,EAAA,EAAA,mBAAA,CAAA,GAAA,EAAA,2BAOjB,OAAA,CAJL,MAAM,kBACL,mBAAgB,CAAG,EAAA,OAAsB,IAAA,0BAEvC,EAAA,OAAiB,EAAA,WAAW,EAAA,EAAA,CAAA,EAGzB,EAAA,UAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,YAAA,CAGN,EAAA,QAAA,OAFA,KAAK,KACL,MAAM,yDAcF,MAZN,EAYM,CAAA,GAAA,AAAA,EAAA,KAAA,EAAA,EAAA,EAAA,mBAAA,CAD+B,WAAA,CAAzB,OAAO,eAAe,EAAA,KAAA,EAAA,CAAA,CAAA,CAAA,4BA6CvB,EAAA,WAAA,CA1CD,KAAK,QAAQ,EAAA,2BAyClB,EAAA,EAAA,EAAA,MAAA,CAvCG,CAAA,GAAM,CAAK,EAAA,WAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAuCd,KAAA,OAtCF,IAAA,EAAA,EAAA,MAAA,CAAI,CAAA,UACD,aAAJ,IAAI,EACJ,KAAK,UACL,MAAM,oBACL,aAAU,OAAS,EAAA,MAAY,eAAA,SAA8B,EAAA,MAAY,cAAiB,IAAA,mDAiCtF,EAAA,SAAA,MAAA,EAAA,EAAA,WAAA,CA9BoB,EAAA,SAAf,EAAK,gDA8BV,KAAA,CA7BF,IAAK,EAAI,iBACT,IAAM,GAAO,EAAa,EAAsB,EAAI,KAAK,EAC1D,KAAK,SACL,OAAA,EAAA,EAAA,eAAA,CAAK,CAAC,mBAAkB,eACa,EAAI,QAAU,EAAA,yBAAuC,EAAI,sBAAoC,IAAU,EAAA,SAK3I,gBAAe,EAAI,QAAU,EAAA,WAC7B,gBAAe,EAAI,UAAY,IAAA,GAC/B,SAAU,EAAI,SAAQ,GAAA,EACtB,QAAK,GAAE,EAAa,CAAG,EACvB,UAAO,GAAE,EAAgB,EAAQ,EAAK,CAAK,gDAEzC,EAAI,KAAK,EAAG,IACf,CAAA,EACQ,EAAI,QAAU,EAAA,aAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAWhB,MAZN,EAYM,CAAA,GAAA,AAAA,EAAA,KAAA,EAAA,EAAA,EAAA,mBAAA,CAD2C,WAAA,CAArC,OAAO,2BAA2B,EAAA,KAAA,EAAA,CAAA,CAAA,CAAA,IAAA,EAAA,EAAA,mBAAA,CAAA,GAAA,EAAA,CAAA,EAAA,GAAA,CAAA"}
|
|
@@ -53,6 +53,7 @@ var O = ["data-state"], k = [
|
|
|
53
53
|
default: !1
|
|
54
54
|
},
|
|
55
55
|
size: { default: "md" },
|
|
56
|
+
width: { default: "full" },
|
|
56
57
|
disabled: {
|
|
57
58
|
type: Boolean,
|
|
58
59
|
default: !1
|
|
@@ -81,6 +82,7 @@ var O = ["data-state"], k = [
|
|
|
81
82
|
}), W = i(() => [
|
|
82
83
|
"t-select",
|
|
83
84
|
`t-select--${j.size}`,
|
|
85
|
+
j.width === "full" ? null : `t-field-width--${j.width}`,
|
|
84
86
|
{
|
|
85
87
|
"t-select--drop-up": B.value,
|
|
86
88
|
"is-disabled": j.disabled,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TSelect.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../src/components/TSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { createId, isActivationKey, isEscapeKey } from '@treeui/utils';\nimport { computed, nextTick, onBeforeUnmount, ref, toRef, useAttrs, watch } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TSelectOption {\n label: string;\n value: string | number;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string | number;\n options?: TSelectOption[];\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n placeholder?: string;\n }>(),\n {\n modelValue: '',\n options: () => [],\n open: undefined,\n defaultOpen: false,\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n placeholder: '',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\nconst listboxId = createId('t-select');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst listboxRef = ref<HTMLElement | null>(null);\nconst optionRefs = ref<Map<string | number, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\nconst dropUp = ref(false);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-select',\n `t-select--${props.size}`,\n {\n 't-select--drop-up': dropUp.value,\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\n// Nearest ancestor that can clip the listbox (scroll container or hidden overflow).\nconst findClippingAncestor = (element: HTMLElement): HTMLElement | null => {\n let parent = element.parentElement;\n while (parent && parent !== document.body) {\n const { overflowY } = window.getComputedStyle(parent);\n if (overflowY === 'auto' || overflowY === 'scroll' || overflowY === 'hidden') {\n return parent;\n }\n parent = parent.parentElement;\n }\n return null;\n};\n\n// Flip the listbox above the trigger when its rendered position overflows the\n// nearest clipping ancestor (e.g. a modal body) or the viewport, and there is\n// more room above the trigger than below it. Measuring the rendered rect keeps\n// the decision in sync with the CSS offset (--tree-space-2) automatically.\nconst updateDropDirection = () => {\n const trigger = triggerRef.value;\n const listbox = listboxRef.value;\n if (!trigger || !listbox) {\n dropUp.value = false;\n return;\n }\n const triggerRect = trigger.getBoundingClientRect();\n const listboxRect = listbox.getBoundingClientRect();\n const boundary = findClippingAncestor(trigger)?.getBoundingClientRect();\n const bottomLimit = Math.min(boundary?.bottom ?? Infinity, window.innerHeight);\n const topLimit = Math.max(boundary?.top ?? 0, 0);\n const spaceBelow = bottomLimit - triggerRect.bottom;\n const spaceAbove = triggerRect.top - topLimit;\n dropUp.value = listboxRect.bottom > bottomLimit && spaceAbove > spaceBelow;\n};\n\nconst rootStyle = computed(() => attrs.style);\n\nconst selectedLabel = computed(() => {\n const opt = props.options.find((o) => o.value === props.modelValue);\n return opt?.label ?? '';\n});\n\nconst enabledOptions = computed(() =>\n props.options.filter((o) => !o.disabled),\n);\n\nconst openDropdown = () => {\n if (props.disabled) return;\n const selectedIdx = props.options.findIndex((o) => o.value === props.modelValue);\n focusedIndex.value = selectedIdx >= 0 ? selectedIdx : 0;\n // Render downward first so the measurement always starts from the default position.\n dropUp.value = false;\n setValue(true);\n nextTick(() => {\n updateDropDirection();\n focusOption(focusedIndex.value);\n });\n};\n\nconst closeDropdown = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => triggerRef.value?.focus());\n }\n};\n\nconst toggleDropdown = () => {\n if (isOpen.value) {\n closeDropdown();\n } else {\n openDropdown();\n }\n};\n\nconst selectOption = (opt: TSelectOption) => {\n if (opt.disabled) return;\n emit('update:modelValue', opt.value);\n closeDropdown(true);\n};\n\nconst focusOption = (index: number) => {\n const opt = props.options[index];\n if (!opt) return;\n const el = optionRefs.value.get(opt.value);\n el?.focus();\n};\n\nconst setOptionRef = (el: Element | null, value: string | number) => {\n if (el instanceof HTMLElement) {\n optionRefs.value.set(value, el);\n } else {\n optionRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.options.length) {\n if (!props.options[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusOption(nextIndex);\n return;\n }\n nextIndex += direction;\n }\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) return;\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeDropdown();\n return;\n }\n\n if (isActivationKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n openDropdown();\n }\n};\n\nconst onOptionKeydown = (event: KeyboardEvent, opt: TSelectOption, _index: number) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeDropdown(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectOption(opt);\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(-1);\n break;\n case 'Home':\n event.preventDefault();\n focusedIndex.value = enabledOptions.value.length > 0\n ? props.options.indexOf(enabledOptions.value[0])\n : 0;\n focusOption(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledOptions.value.length > 0\n ? props.options.indexOf(enabledOptions.value[enabledOptions.value.length - 1])\n : props.options.length - 1;\n focusOption(focusedIndex.value);\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) return;\n const target = event.target;\n if (!(target instanceof Node)) return;\n if (rootRef.value?.contains(target)) return;\n closeDropdown();\n};\n\nconst hasSelection = computed(() =>\n props.modelValue !== '' && props.modelValue !== null && props.modelValue !== undefined,\n);\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n } else {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-select__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? listboxId : undefined\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"isOpen\"\n :aria-invalid=\"invalid || undefined\"\n :aria-busy=\"loading || undefined\"\n @click=\"toggleDropdown\"\n @keydown=\"onTriggerKeydown\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-select__slot t-select__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <span\n class=\"t-select__value\"\n :data-placeholder=\"!hasSelection ? true : undefined\"\n >\n {{ selectedLabel || placeholder }}\n </span>\n <TSpinner\n v-if=\"loading\"\n size=\"sm\"\n label=\"Loading\"\n />\n <svg\n v-else\n class=\"t-select__chevron\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"4 6 8 10 12 6\" />\n </svg>\n </button>\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"listboxId\"\n ref=\"listboxRef\"\n role=\"listbox\"\n class=\"t-select__listbox\"\n :aria-label=\"typeof triggerAttrs['aria-label'] === 'string' ? triggerAttrs['aria-label'] : undefined\"\n >\n <li\n v-for=\"(opt, index) in options\"\n :key=\"opt.value\"\n :ref=\"(el) => setOptionRef(el as Element | null, opt.value)\"\n role=\"option\"\n class=\"t-select__option\"\n :class=\"{\n 'is-selected': opt.value === modelValue,\n 'is-disabled': opt.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-selected=\"opt.value === modelValue\"\n :aria-disabled=\"opt.disabled || undefined\"\n :tabindex=\"opt.disabled ? -1 : 0\"\n @click=\"selectOption(opt)\"\n @keydown=\"onOptionKeydown($event, opt, index)\"\n >\n {{ opt.label }}\n <svg\n v-if=\"opt.value === modelValue\"\n class=\"t-select__check\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"3.5 8.5 6.5 11.5 12.5 4.5\" />\n </svg>\n </li>\n </ul>\n </transition>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiBA,IAAM,IAAQ,GAyBR,IAAO,GAMP,IAAQ,EAAS,GACjB,IAAY,EAAS,UAAU,GAC/B,IAAU,EAAwB,IAAI,GACtC,IAAa,EAA8B,IAAI,GAC/C,IAAa,EAAwB,IAAI,GACzC,IAAa,kBAAuC,IAAI,IAAI,CAAC,GAC7D,IAAe,EAAI,EAAE,GACrB,IAAS,EAAI,EAAK,GAElB,IAAe,QAAe;GAClC,IAAM,EAAE,OAAO,GAAQ,OAAO,GAAQ,GAAG,MAAS;GAClD,OAAO;EACT,CAAC,GAEK,EAAE,OAAO,GAAQ,gBAAa,EAClC,EAAM,GAAO,MAAM,GACnB,EAAM,cACL,MAAU;GAET,AADA,EAAK,eAAe,CAAK,GACzB,EAAK,eAAe,CAAK;EAC3B,CACF,GAEM,IAAc,QAAe;GACjC;GACA,aAAa,EAAM;GACnB;IACE,qBAAqB,EAAO;IAC5B,eAAe,EAAM;IACrB,cAAc,EAAM;IACpB,cAAc,EAAM;IACpB,WAAW,EAAO;GACpB;GACA,EAAM;EACR,CAAC,GAGK,KAAwB,MAA6C;GACzE,IAAI,IAAS,EAAQ;GACrB,OAAO,KAAU,MAAW,SAAS,OAAM;IACzC,IAAM,EAAE,iBAAc,OAAO,iBAAiB,CAAM;IACpD,IAAI,MAAc,UAAU,MAAc,YAAY,MAAc,UAClE,OAAO;IAET,IAAS,EAAO;GAClB;GACA,OAAO;EACT,GAMM,WAA4B;GAChC,IAAM,IAAU,EAAW,OACrB,IAAU,EAAW;GAC3B,IAAI,CAAC,KAAW,CAAC,GAAS;IACxB,EAAO,QAAQ;IACf;GACF;GACA,IAAM,IAAc,EAAQ,sBAAsB,GAC5C,IAAc,EAAQ,sBAAsB,GAC5C,IAAW,EAAqB,CAAO,CAAC,EAAE,sBAAsB,GAChE,IAAc,KAAK,IAAI,GAAU,UAAU,UAAU,OAAO,WAAW,GACvE,IAAW,KAAK,IAAI,GAAU,OAAO,GAAG,CAAC,GACzC,IAAa,IAAc,EAAY,QACvC,IAAa,EAAY,MAAM;GACrC,EAAO,QAAQ,EAAY,SAAS,KAAe,IAAa;EAClE,GAEM,KAAY,QAAe,EAAM,KAAK,GAEtC,KAAgB,QACR,EAAM,QAAQ,MAAM,MAAM,EAAE,UAAU,EAAM,UACjD,CAAA,EAAK,SAAS,EACtB,GAEK,IAAiB,QACrB,EAAM,QAAQ,QAAQ,MAAM,CAAC,EAAE,QAAQ,CACzC,GAEM,UAAqB;GACzB,IAAI,EAAM,UAAU;GACpB,IAAM,IAAc,EAAM,QAAQ,WAAW,MAAM,EAAE,UAAU,EAAM,UAAU;GAK/E,AAJA,EAAa,QAAQ,KAAe,IAAI,IAAc,GAEtD,EAAO,QAAQ,IACf,EAAS,EAAI,GACb,QAAe;IAEb,AADA,GAAoB,GACpB,EAAY,EAAa,KAAK;GAChC,CAAC;EACH,GAEM,KAAiB,IAAe,OAAU;GAG9C,AAFA,EAAS,EAAK,GACd,EAAa,QAAQ,IACjB,KACF,QAAe,EAAW,OAAO,MAAM,CAAC;EAE5C,GAEM,UAAuB;GAC3B,AAAI,EAAO,QACT,EAAc,IAEd,EAAa;EAEjB,GAEM,KAAgB,MAAuB;GACvC,EAAI,aACR,EAAK,qBAAqB,EAAI,KAAK,GACnC,EAAc,EAAI;EACpB,GAEM,KAAe,MAAkB;GACrC,IAAM,IAAM,EAAM,QAAQ;GACrB,KAEL,EADsB,MAAM,IAAI,EAAI,KACpC,CAAA,EAAI,MAAM;EACZ,GAEM,MAAgB,GAAoB,MAA2B;GACnE,AAAI,aAAc,cAChB,EAAW,MAAM,IAAI,GAAO,CAAE,IAE9B,EAAW,MAAM,OAAO,CAAK;EAEjC,GAEM,KAAa,MAAsB;GACvC,IAAI,IAAY,EAAa,QAAQ;GACrC,OAAO,KAAa,KAAK,IAAY,EAAM,QAAQ,SAAQ;IACzD,IAAI,CAAC,EAAM,QAAQ,EAAU,CAAC,UAAU;KAEtC,AADA,EAAa,QAAQ,GACrB,EAAY,CAAS;KACrB;IACF;IACA,KAAa;GACf;EACF,GAEM,MAAoB,MAAyB;GAC7C,OAAM,UAEV;QAAI,EAAY,CAAK,KAAK,EAAO,OAAO;KAEtC,AADA,EAAM,eAAe,GACrB,EAAc;KACd;IACF;IAEA,CAAI,EAAgB,CAAK,KAAK,EAAM,QAAQ,eAAe,EAAM,QAAQ,eACvE,EAAM,eAAe,GACrB,EAAa;GAJf;EAMF,GAEM,MAAmB,GAAsB,GAAoB,MAAmB;GACpF,IAAI,EAAY,CAAK,GAAG;IAEtB,AADA,EAAM,eAAe,GACrB,EAAc,EAAI;IAClB;GACF;GAEA,IAAI,EAAgB,CAAK,GAAG;IAE1B,AADA,EAAM,eAAe,GACrB,EAAa,CAAG;IAChB;GACF;GAEA,QAAQ,EAAM,KAAd;IACE,KAAK;KAEH,AADA,EAAM,eAAe,GACrB,EAAU,CAAC;KACX;IACF,KAAK;KAEH,AADA,EAAM,eAAe,GACrB,EAAU,EAAE;KACZ;IACF,KAAK;KAKH,AAJA,EAAM,eAAe,GACrB,EAAa,QAAQ,EAAe,MAAM,SAAS,IAC/C,EAAM,QAAQ,QAAQ,EAAe,MAAM,EAAE,IAC7C,GACJ,EAAY,EAAa,KAAK;KAC9B;IACF,KAAK;KAKH,AAJA,EAAM,eAAe,GACrB,EAAa,QAAQ,EAAe,MAAM,SAAS,IAC/C,EAAM,QAAQ,QAAQ,EAAe,MAAM,EAAe,MAAM,SAAS,EAAE,IAC3E,EAAM,QAAQ,SAAS,GAC3B,EAAY,EAAa,KAAK;KAC9B;IACF,SACE;GACJ;EACF,GAEM,KAAyB,MAAwB;GACrD,IAAI,CAAC,EAAO,OAAO;GACnB,IAAM,IAAS,EAAM;GACf,aAAkB,SACpB,EAAQ,OAAO,SAAS,CAAM,KAClC,EAAc;EAChB,GAEM,KAAe,QACnB,EAAM,eAAe,MAAM,EAAM,eAAe,QAAQ,EAAM,eAAe,KAAA,CAC/E;SAEA,EAAM,IAAS,MAAU;GACvB,AAAI,IACF,SAAS,iBAAiB,eAAe,CAAqB,IAE9D,SAAS,oBAAoB,eAAe,CAAqB;EAErE,CAAC,GAED,QAAsB;GACpB,SAAS,oBAAoB,eAAe,CAAqB;EACnE,CAAC,mBAIC,EA8FM,OAAA;YA7FA;GAAJ,KAAI;GACH,OAAK,EAAE,EAAA,KAAW;GAClB,OAAK,EAAE,GAAA,KAAS;GAChB,cAAY,EAAA,CAAA,IAAM,SAAA;MAEnB,EA4CS,UA5CT,EA4CS;YA3CH;GAAJ,KAAI;KACI,EAAA,OAAY;GACpB,MAAK;GACL,OAAM;GACL,UAAU,EAAA;GACV,iBAAe,EAAA,CAAA,IAAS,EAAA,CAAA,IAAY,KAAA;GACrC,iBAAc;GACb,iBAAe,EAAA,CAAA;GACf,gBAAc,EAAA,WAAW,KAAA;GACzB,aAAW,EAAA,WAAW,KAAA;GACtB,SAAO;GACP,WAAS;;GAGFA,EAAAA,OAAO,UAAA,EAAA,GADf,EAKO,QALP,IAKO,CADL,EAAsB,EAAA,QAAA,QAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA;GAExB,EAKO,QAAA;IAJL,OAAM;IACL,oBAAgB,CAAG,GAAA,SAAsB,KAAA;QAEvC,GAAA,SAAiB,EAAA,WAAW,GAAA,GAAA,EAAA;GAGzB,EAAA,WAAA,EAAA,GADR,EAIE,GAAA;;IAFA,MAAK;IACL,OAAM;eAER,EAYM,OAZN,IAYM,CAAA,GAAA,AAAA,EAAA,OAAA,CADJ,EAAmC,YAAA,EAAzB,QAAO,gBAAe,GAAA,MAAA,EAAA,CAAA,CAAA,CAAA;aAGpC,GA0Ca,GAAA,EA1CD,MAAK,SAAQ,GAAA;oBAyClB,CAvCG,EAAA,CAAA,KAAM,CAAK,EAAA,YAAA,EAAA,GADnB,EAwCK,MAAA;;IAtCF,IAAI,EAAA,CAAA;aACD;IAAJ,KAAI;IACJ,MAAK;IACL,OAAM;IACL,cAAU,OAAS,EAAA,MAAY,iBAAA,WAA8B,EAAA,MAAY,gBAAiB,KAAA;eAE3F,EA+BK,GAAA,MAAA,GA9BoB,EAAA,UAAf,GAAK,YADf,EA+BK,MAAA;IA7BF,KAAK,EAAI;;IACT,MAAM,MAAO,GAAa,GAAsB,EAAI,KAAK;IAC1D,MAAK;IACL,OAAK,EAAA,CAAC,oBAAkB;oBACa,EAAI,UAAU,EAAA;oBAAuC,EAAI;mBAAoC,MAAU,EAAA;;IAK3I,iBAAe,EAAI,UAAU,EAAA;IAC7B,iBAAe,EAAI,YAAY,KAAA;IAC/B,UAAU,EAAI,WAAQ,KAAA;IACtB,UAAK,MAAE,EAAa,CAAG;IACvB,YAAO,MAAE,GAAgB,GAAQ,GAAK,CAAK;WAEzC,EAAI,KAAK,IAAG,KACf,CAAA,GACQ,EAAI,UAAU,EAAA,cAAA,EAAA,GADtB,EAYM,OAZN,IAYM,CAAA,GAAA,AAAA,EAAA,OAAA,CADJ,EAA+C,YAAA,EAArC,QAAO,4BAA2B,GAAA,MAAA,EAAA,CAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,GAAA,IAAA,EAAA"}
|
|
1
|
+
{"version":3,"file":"TSelect.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../src/components/TSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { createId, isActivationKey, isEscapeKey } from '@treeui/utils';\nimport { computed, nextTick, onBeforeUnmount, ref, toRef, useAttrs, watch } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TFieldWidth, TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TSelectOption {\n label: string;\n value: string | number;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string | number;\n options?: TSelectOption[];\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n /** Inline-size cap. Fluid (`full`) by default. */\n width?: TFieldWidth;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n placeholder?: string;\n }>(),\n {\n modelValue: '',\n options: () => [],\n open: undefined,\n defaultOpen: false,\n size: 'md',\n width: 'full',\n disabled: false,\n loading: false,\n invalid: false,\n placeholder: '',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\nconst listboxId = createId('t-select');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst listboxRef = ref<HTMLElement | null>(null);\nconst optionRefs = ref<Map<string | number, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\nconst dropUp = ref(false);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-select',\n `t-select--${props.size}`,\n props.width !== 'full' ? `t-field-width--${props.width}` : null,\n {\n 't-select--drop-up': dropUp.value,\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\n// Nearest ancestor that can clip the listbox (scroll container or hidden overflow).\nconst findClippingAncestor = (element: HTMLElement): HTMLElement | null => {\n let parent = element.parentElement;\n while (parent && parent !== document.body) {\n const { overflowY } = window.getComputedStyle(parent);\n if (overflowY === 'auto' || overflowY === 'scroll' || overflowY === 'hidden') {\n return parent;\n }\n parent = parent.parentElement;\n }\n return null;\n};\n\n// Flip the listbox above the trigger when its rendered position overflows the\n// nearest clipping ancestor (e.g. a modal body) or the viewport, and there is\n// more room above the trigger than below it. Measuring the rendered rect keeps\n// the decision in sync with the CSS offset (--tree-space-2) automatically.\nconst updateDropDirection = () => {\n const trigger = triggerRef.value;\n const listbox = listboxRef.value;\n if (!trigger || !listbox) {\n dropUp.value = false;\n return;\n }\n const triggerRect = trigger.getBoundingClientRect();\n const listboxRect = listbox.getBoundingClientRect();\n const boundary = findClippingAncestor(trigger)?.getBoundingClientRect();\n const bottomLimit = Math.min(boundary?.bottom ?? Infinity, window.innerHeight);\n const topLimit = Math.max(boundary?.top ?? 0, 0);\n const spaceBelow = bottomLimit - triggerRect.bottom;\n const spaceAbove = triggerRect.top - topLimit;\n dropUp.value = listboxRect.bottom > bottomLimit && spaceAbove > spaceBelow;\n};\n\nconst rootStyle = computed(() => attrs.style);\n\nconst selectedLabel = computed(() => {\n const opt = props.options.find((o) => o.value === props.modelValue);\n return opt?.label ?? '';\n});\n\nconst enabledOptions = computed(() =>\n props.options.filter((o) => !o.disabled),\n);\n\nconst openDropdown = () => {\n if (props.disabled) return;\n const selectedIdx = props.options.findIndex((o) => o.value === props.modelValue);\n focusedIndex.value = selectedIdx >= 0 ? selectedIdx : 0;\n // Render downward first so the measurement always starts from the default position.\n dropUp.value = false;\n setValue(true);\n nextTick(() => {\n updateDropDirection();\n focusOption(focusedIndex.value);\n });\n};\n\nconst closeDropdown = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => triggerRef.value?.focus());\n }\n};\n\nconst toggleDropdown = () => {\n if (isOpen.value) {\n closeDropdown();\n } else {\n openDropdown();\n }\n};\n\nconst selectOption = (opt: TSelectOption) => {\n if (opt.disabled) return;\n emit('update:modelValue', opt.value);\n closeDropdown(true);\n};\n\nconst focusOption = (index: number) => {\n const opt = props.options[index];\n if (!opt) return;\n const el = optionRefs.value.get(opt.value);\n el?.focus();\n};\n\nconst setOptionRef = (el: Element | null, value: string | number) => {\n if (el instanceof HTMLElement) {\n optionRefs.value.set(value, el);\n } else {\n optionRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.options.length) {\n if (!props.options[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusOption(nextIndex);\n return;\n }\n nextIndex += direction;\n }\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) return;\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeDropdown();\n return;\n }\n\n if (isActivationKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n openDropdown();\n }\n};\n\nconst onOptionKeydown = (event: KeyboardEvent, opt: TSelectOption, _index: number) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeDropdown(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectOption(opt);\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(-1);\n break;\n case 'Home':\n event.preventDefault();\n focusedIndex.value = enabledOptions.value.length > 0\n ? props.options.indexOf(enabledOptions.value[0])\n : 0;\n focusOption(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledOptions.value.length > 0\n ? props.options.indexOf(enabledOptions.value[enabledOptions.value.length - 1])\n : props.options.length - 1;\n focusOption(focusedIndex.value);\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) return;\n const target = event.target;\n if (!(target instanceof Node)) return;\n if (rootRef.value?.contains(target)) return;\n closeDropdown();\n};\n\nconst hasSelection = computed(() =>\n props.modelValue !== '' && props.modelValue !== null && props.modelValue !== undefined,\n);\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n } else {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-select__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? listboxId : undefined\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"isOpen\"\n :aria-invalid=\"invalid || undefined\"\n :aria-busy=\"loading || undefined\"\n @click=\"toggleDropdown\"\n @keydown=\"onTriggerKeydown\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-select__slot t-select__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <span\n class=\"t-select__value\"\n :data-placeholder=\"!hasSelection ? true : undefined\"\n >\n {{ selectedLabel || placeholder }}\n </span>\n <TSpinner\n v-if=\"loading\"\n size=\"sm\"\n label=\"Loading\"\n />\n <svg\n v-else\n class=\"t-select__chevron\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"4 6 8 10 12 6\" />\n </svg>\n </button>\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"listboxId\"\n ref=\"listboxRef\"\n role=\"listbox\"\n class=\"t-select__listbox\"\n :aria-label=\"typeof triggerAttrs['aria-label'] === 'string' ? triggerAttrs['aria-label'] : undefined\"\n >\n <li\n v-for=\"(opt, index) in options\"\n :key=\"opt.value\"\n :ref=\"(el) => setOptionRef(el as Element | null, opt.value)\"\n role=\"option\"\n class=\"t-select__option\"\n :class=\"{\n 'is-selected': opt.value === modelValue,\n 'is-disabled': opt.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-selected=\"opt.value === modelValue\"\n :aria-disabled=\"opt.disabled || undefined\"\n :tabindex=\"opt.disabled ? -1 : 0\"\n @click=\"selectOption(opt)\"\n @keydown=\"onOptionKeydown($event, opt, index)\"\n >\n {{ opt.label }}\n <svg\n v-if=\"opt.value === modelValue\"\n class=\"t-select__check\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"3.5 8.5 6.5 11.5 12.5 4.5\" />\n </svg>\n </li>\n </ul>\n </transition>\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../composables/useControllableOpen.cjs"),t=require("./sidebar.cjs");let n=require("vue"),r=require("@treeui/icons");var i={key:0,class:`t-sidebar__header`},a={class:`t-sidebar__body`},o={key:1,class:`t-sidebar__footer`},s=[`aria-label`,`aria-expanded`],c={key:0},l=(0,n.defineComponent)({inheritAttrs:!1,__name:`TSidebar`,props:{as:{default:`aside`},collapsed:{type:Boolean,default:void 0},defaultCollapsed:{type:Boolean,default:!1},collapsible:{type:Boolean,default:!0},size:{default:`md`},side:{default:`left`},sticky:{type:Boolean,default:!1},bordered:{type:Boolean,default:!0},width:{default:`17.5rem`},collapsedWidth:{default:`4.75rem`},collapseLabel:{default:`Collapse sidebar`},expandLabel:{default:`Expand sidebar`}},emits:[`update:collapsed`,`collapse-change`],setup(l,{emit:u}){let d=(0,r.getTreeIcon)(`chevron-left`),f=(0,r.getTreeIcon)(`chevron-right`),p=l,m=u,h=(0,n.useAttrs)(),{value:g,setValue:_}=e.useControllableOpen((0,n.toRef)(p,`collapsed`),p.defaultCollapsed,e=>{m(`update:collapsed`,e),m(`collapse-change`,e)}),v=(0,n.computed)(()=>[`t-sidebar`,`t-sidebar--${p.size}`,`t-sidebar--${p.side}`,{"is-collapsed":g.value,"is-sticky":p.sticky,"is-bordered":p.bordered},h.class]),y=(0,n.computed)(()=>[{"--tree-sidebar-width":p.width,"--tree-sidebar-collapsed-width":p.collapsedWidth},h.style]),b=(0,n.computed)(()=>{let{class:e,style:t,...n}=h;return n}),x=()=>{p.collapsible&&_(!g.value)},S=(0,n.computed)(()=>p.side===`right`?g.value?d:f:g.value?f:d),C=(0,n.computed)(()=>g.value?p.expandLabel:p.collapseLabel);return(0,n.provide)(t.treeSidebarInjectionKey,{collapsed:(0,n.computed)(()=>g.value)}),(e,t)=>((0,n.openBlock)(),(0,n.createBlock)((0,n.resolveDynamicComponent)(l.as),(0,n.mergeProps)(b.value,{class:v.value,style:y.value,"data-state":(0,n.unref)(g)?`collapsed`:`expanded`}),{default:(0,n.withCtx)(()=>[e.$slots.header?((0,n.openBlock)(),(0,n.createElementBlock)(`div`,i,[(0,n.renderSlot)(e.$slots,`header`,{collapsed:(0,n.unref)(g)})])):(0,n.createCommentVNode)(``,!0),(0,n.createElementVNode)(`div`,a,[(0,n.renderSlot)(e.$slots,`default`,{collapsed:(0,n.unref)(g)})]),e.$slots.footer||l.collapsible?((0,n.openBlock)(),(0,n.createElementBlock)(`div`,o,[e.$slots.footer?(0,n.renderSlot)(e.$slots,`footer`,{
|
|
1
|
+
const e=require("../composables/useControllableOpen.cjs"),t=require("./sidebar.cjs");let n=require("vue"),r=require("@treeui/icons");var i={key:0,class:`t-sidebar__header`},a={class:`t-sidebar__body`},o={key:1,class:`t-sidebar__footer`},s=[`aria-label`,`aria-expanded`],c={key:0},l=(0,n.defineComponent)({inheritAttrs:!1,__name:`TSidebar`,props:{as:{default:`aside`},collapsed:{type:Boolean,default:void 0},defaultCollapsed:{type:Boolean,default:!1},collapsible:{type:Boolean,default:!0},size:{default:`md`},side:{default:`left`},sticky:{type:Boolean,default:!1},bordered:{type:Boolean,default:!0},width:{default:`17.5rem`},collapsedWidth:{default:`4.75rem`},collapseLabel:{default:`Collapse sidebar`},expandLabel:{default:`Expand sidebar`}},emits:[`update:collapsed`,`collapse-change`],setup(l,{emit:u}){let d=(0,r.getTreeIcon)(`chevron-left`),f=(0,r.getTreeIcon)(`chevron-right`),p=l,m=u,h=(0,n.useAttrs)(),{value:g,setValue:_}=e.useControllableOpen((0,n.toRef)(p,`collapsed`),p.defaultCollapsed,e=>{m(`update:collapsed`,e),m(`collapse-change`,e)}),v=(0,n.computed)(()=>[`t-sidebar`,`t-sidebar--${p.size}`,`t-sidebar--${p.side}`,{"is-collapsed":g.value,"is-sticky":p.sticky,"is-bordered":p.bordered},h.class]),y=(0,n.computed)(()=>[{"--tree-sidebar-width":p.width,"--tree-sidebar-collapsed-width":p.collapsedWidth},h.style]),b=(0,n.computed)(()=>{let{class:e,style:t,...n}=h;return n}),x=()=>{p.collapsible&&_(!g.value)},S=(0,n.computed)(()=>p.side===`right`?g.value?d:f:g.value?f:d),C=(0,n.computed)(()=>g.value?p.expandLabel:p.collapseLabel);return(0,n.provide)(t.treeSidebarInjectionKey,{collapsed:(0,n.computed)(()=>g.value)}),(e,t)=>((0,n.openBlock)(),(0,n.createBlock)((0,n.resolveDynamicComponent)(l.as),(0,n.mergeProps)(b.value,{class:v.value,style:y.value,"data-state":(0,n.unref)(g)?`collapsed`:`expanded`}),{default:(0,n.withCtx)(()=>[e.$slots.header?((0,n.openBlock)(),(0,n.createElementBlock)(`div`,i,[(0,n.renderSlot)(e.$slots,`header`,{collapsed:(0,n.unref)(g)})])):(0,n.createCommentVNode)(``,!0),(0,n.createElementVNode)(`div`,a,[(0,n.renderSlot)(e.$slots,`default`,{collapsed:(0,n.unref)(g)})]),e.$slots.footer||l.collapsible?((0,n.openBlock)(),(0,n.createElementBlock)(`div`,o,[e.$slots.footer?(0,n.renderSlot)(e.$slots,`footer`,{collapsed:(0,n.unref)(g)},void 0,void 0,0):(0,n.createCommentVNode)(``,!0),l.collapsible?((0,n.openBlock)(),(0,n.createElementBlock)(`button`,{key:1,type:`button`,class:`t-sidebar__toggle`,"aria-label":C.value,"aria-expanded":!(0,n.unref)(g),onClick:x},[(0,n.renderSlot)(e.$slots,`toggle`,{collapsed:(0,n.unref)(g)},()=>[((0,n.openBlock)(),(0,n.createBlock)((0,n.resolveDynamicComponent)(S.value),{size:16})),(0,n.unref)(g)?(0,n.createCommentVNode)(``,!0):((0,n.openBlock)(),(0,n.createElementBlock)(`span`,c,(0,n.toDisplayString)(C.value),1))])],8,s)):(0,n.createCommentVNode)(``,!0)])):(0,n.createCommentVNode)(``,!0)]),_:3},16,[`class`,`style`,`data-state`]))}});exports.default=l;
|
|
2
2
|
//# sourceMappingURL=TSidebar.vue_vue_type_script_setup_true_lang.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TSidebar.vue_vue_type_script_setup_true_lang.cjs","names":["$slots"],"sources":["../../src/components/TSidebar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { getTreeIcon } from '@treeui/icons';\nimport { computed, provide, toRef, useAttrs } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\nimport { treeSidebarInjectionKey } from './sidebar';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst _treeSidebarSides = ['left', 'right'] as const;\n\nexport type TSidebarSide = (typeof _treeSidebarSides)[number];\n\nconst ChevronLeftIcon = getTreeIcon('chevron-left');\nconst ChevronRightIcon = getTreeIcon('chevron-right');\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n collapsed?: boolean;\n defaultCollapsed?: boolean;\n collapsible?: boolean;\n size?: TSize;\n side?: TSidebarSide;\n sticky?: boolean;\n bordered?: boolean;\n width?: string;\n collapsedWidth?: string;\n collapseLabel?: string;\n expandLabel?: string;\n }>(),\n {\n as: 'aside',\n collapsed: undefined,\n defaultCollapsed: false,\n collapsible: true,\n size: 'md',\n side: 'left',\n sticky: false,\n bordered: true,\n width: '17.5rem',\n collapsedWidth: '4.75rem',\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}>();\n\ndefineSlots<{\n header?: (props: { collapsed: boolean }) => unknown;\n default?: (props: { collapsed: boolean }) => unknown;\n footer?: (props: { collapsed: boolean }) => unknown;\n toggle?: (props: { collapsed: boolean }) => unknown;\n}>();\n\nconst attrs = useAttrs();\n\nconst { value: isCollapsed, setValue } = useControllableOpen(\n toRef(props, 'collapsed'),\n props.defaultCollapsed,\n (value) => {\n emit('update:collapsed', value);\n emit('collapse-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-sidebar',\n `t-sidebar--${props.size}`,\n `t-sidebar--${props.side}`,\n {\n 'is-collapsed': isCollapsed.value,\n 'is-sticky': props.sticky,\n 'is-bordered': props.bordered,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => [\n {\n '--tree-sidebar-width': props.width,\n '--tree-sidebar-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 toggleCollapsed = () => {\n if (!props.collapsible) {\n return;\n }\n\n setValue(!isCollapsed.value);\n};\n\nconst ToggleIcon = computed(() => {\n if (props.side === 'right') {\n return isCollapsed.value ? ChevronLeftIcon : ChevronRightIcon;\n }\n\n return isCollapsed.value ? ChevronRightIcon : ChevronLeftIcon;\n});\n\nconst toggleLabel = computed(() =>\n isCollapsed.value ? props.expandLabel : props.collapseLabel,\n);\n\nprovide(treeSidebarInjectionKey, {\n collapsed: computed(() => isCollapsed.value),\n});\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isCollapsed ? 'collapsed' : 'expanded'\"\n >\n <div\n v-if=\"$slots.header\"\n class=\"t-sidebar__header\"\n >\n <slot\n name=\"header\"\n :collapsed=\"isCollapsed\"\n />\n </div>\n\n <div class=\"t-sidebar__body\">\n <slot :collapsed=\"isCollapsed\" />\n </div>\n\n <div\n v-if=\"$slots.footer || collapsible\"\n class=\"t-sidebar__footer\"\n >\n <slot\n v-if=\"$slots.footer\"\n name=\"footer\"\n :collapsed=\"isCollapsed\"\n />\n\n <button\n v-if=\"collapsible\"\n type=\"button\"\n class=\"t-sidebar__toggle\"\n :aria-label=\"toggleLabel\"\n :aria-expanded=\"!isCollapsed\"\n @click=\"toggleCollapsed\"\n >\n <slot\n name=\"toggle\"\n :collapsed=\"isCollapsed\"\n >\n <component\n :is=\"ToggleIcon\"\n :size=\"16\"\n />\n <span v-if=\"!isCollapsed\">{{ toggleLabel }}</span>\n </slot>\n </button>\n </div>\n </component>\n</template>\n"],"mappings":"qyBAeA,IAAM,GAAA,EAAA,EAAA,YAAA,CAA8B,cAAc,EAC5C,GAAA,EAAA,EAAA,YAAA,CAA+B,eAAe,EAE9C,EAAQ,EA+BR,EAAO,EAYP,GAAA,EAAA,EAAA,SAAA,CAAiB,EAEjB,CAAE,MAAO,EAAa,YAAa,EAAA,qBAAA,EAAA,EAAA,MAAA,CACjC,EAAO,WAAW,EACxB,EAAM,iBACL,GAAU,CACT,EAAK,mBAAoB,CAAK,EAC9B,EAAK,kBAAmB,CAAK,CAC/B,CACF,EAEM,GAAA,EAAA,EAAA,SAAA,KAA6B,CACjC,YACA,cAAc,EAAM,OACpB,cAAc,EAAM,OACpB,CACE,eAAgB,EAAY,MAC5B,YAAa,EAAM,OACnB,cAAe,EAAM,QACvB,EACA,EAAM,KACR,CAAC,EAEK,GAAA,EAAA,EAAA,SAAA,KAA2B,CAC/B,CACE,uBAAwB,EAAM,MAC9B,iCAAkC,EAAM,cAC1C,EACA,EAAM,KACR,CAAC,EAEK,GAAA,EAAA,EAAA,SAAA,KAA2B,CAC/B,GAAM,CAAE,MAAO,EAAQ,MAAO,EAAQ,GAAG,GAAS,EAClD,OAAO,CACT,CAAC,EAEK,MAAwB,CACvB,EAAM,aAIX,EAAS,CAAC,EAAY,KAAK,CAC7B,EAEM,GAAA,EAAA,EAAA,SAAA,KACA,EAAM,OAAS,QACV,EAAY,MAAQ,EAAkB,EAGxC,EAAY,MAAQ,EAAmB,CAC/C,EAEK,GAAA,EAAA,EAAA,SAAA,KACJ,EAAY,MAAQ,EAAM,YAAc,EAAM,aAChD,SAEA,EAAA,EAAA,QAAA,CAAQ,EAAA,wBAAyB,CAC/B,WAAA,EAAA,EAAA,SAAA,KAA0B,EAAY,KAAK,CAC7C,CAAC,4EAKQ,EAAA,EAAE,GAAA,EAAA,EAAA,WAAA,CACC,EAiDE,MAjDO,CAChB,MAAO,EAAA,MACP,MAAO,EAAA,MACP,cAAA,EAAA,EAAA,MAAA,CAAY,CAAA,EAAW,YAAA,wCAUlB,CAPEA,EAAAA,OAAO,SAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAOT,MARN,EAQM,EAAA,EAAA,EAAA,WAAA,CADF,EAAA,OAAA,SAAA,CADC,WAAA,EAAA,EAAA,MAAA,CAAW,CAAA,CAAW,CAAA,CAAA,CAAA,IAAA,EAAA,EAAA,mBAAA,CAAA,GAAA,EAAA,2BAMrB,MAFN,EAEM,EAAA,EAAA,EAAA,WAAA,CAD6B,EAAA,OAAA,UAAA,CAA1B,WAAA,EAAA,EAAA,MAAA,CAAW,CAAA,CAAW,CAAA,CAAA,CAAA,EAIvBA,EAAAA,OAAO,QAAU,EAAA,cAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CA4BnB,MA7BN,EA6BM,CAxBIA,EAAAA,OAAO,QAAA,EAAA,EAAA,WAAA,CAGb,EAAA,OAAA,SAAA,
|
|
1
|
+
{"version":3,"file":"TSidebar.vue_vue_type_script_setup_true_lang.cjs","names":["$slots"],"sources":["../../src/components/TSidebar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { getTreeIcon } from '@treeui/icons';\nimport { computed, provide, toRef, useAttrs } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\nimport { treeSidebarInjectionKey } from './sidebar';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst _treeSidebarSides = ['left', 'right'] as const;\n\nexport type TSidebarSide = (typeof _treeSidebarSides)[number];\n\nconst ChevronLeftIcon = getTreeIcon('chevron-left');\nconst ChevronRightIcon = getTreeIcon('chevron-right');\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n collapsed?: boolean;\n defaultCollapsed?: boolean;\n collapsible?: boolean;\n size?: TSize;\n side?: TSidebarSide;\n sticky?: boolean;\n bordered?: boolean;\n width?: string;\n collapsedWidth?: string;\n collapseLabel?: string;\n expandLabel?: string;\n }>(),\n {\n as: 'aside',\n collapsed: undefined,\n defaultCollapsed: false,\n collapsible: true,\n size: 'md',\n side: 'left',\n sticky: false,\n bordered: true,\n width: '17.5rem',\n collapsedWidth: '4.75rem',\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}>();\n\ndefineSlots<{\n header?: (props: { collapsed: boolean }) => unknown;\n default?: (props: { collapsed: boolean }) => unknown;\n footer?: (props: { collapsed: boolean }) => unknown;\n toggle?: (props: { collapsed: boolean }) => unknown;\n}>();\n\nconst attrs = useAttrs();\n\nconst { value: isCollapsed, setValue } = useControllableOpen(\n toRef(props, 'collapsed'),\n props.defaultCollapsed,\n (value) => {\n emit('update:collapsed', value);\n emit('collapse-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-sidebar',\n `t-sidebar--${props.size}`,\n `t-sidebar--${props.side}`,\n {\n 'is-collapsed': isCollapsed.value,\n 'is-sticky': props.sticky,\n 'is-bordered': props.bordered,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => [\n {\n '--tree-sidebar-width': props.width,\n '--tree-sidebar-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 toggleCollapsed = () => {\n if (!props.collapsible) {\n return;\n }\n\n setValue(!isCollapsed.value);\n};\n\nconst ToggleIcon = computed(() => {\n if (props.side === 'right') {\n return isCollapsed.value ? ChevronLeftIcon : ChevronRightIcon;\n }\n\n return isCollapsed.value ? ChevronRightIcon : ChevronLeftIcon;\n});\n\nconst toggleLabel = computed(() =>\n isCollapsed.value ? props.expandLabel : props.collapseLabel,\n);\n\nprovide(treeSidebarInjectionKey, {\n collapsed: computed(() => isCollapsed.value),\n});\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isCollapsed ? 'collapsed' : 'expanded'\"\n >\n <div\n v-if=\"$slots.header\"\n class=\"t-sidebar__header\"\n >\n <slot\n name=\"header\"\n :collapsed=\"isCollapsed\"\n />\n </div>\n\n <div class=\"t-sidebar__body\">\n <slot :collapsed=\"isCollapsed\" />\n </div>\n\n <div\n v-if=\"$slots.footer || collapsible\"\n class=\"t-sidebar__footer\"\n >\n <slot\n v-if=\"$slots.footer\"\n name=\"footer\"\n :collapsed=\"isCollapsed\"\n />\n\n <button\n v-if=\"collapsible\"\n type=\"button\"\n class=\"t-sidebar__toggle\"\n :aria-label=\"toggleLabel\"\n :aria-expanded=\"!isCollapsed\"\n @click=\"toggleCollapsed\"\n >\n <slot\n name=\"toggle\"\n :collapsed=\"isCollapsed\"\n >\n <component\n :is=\"ToggleIcon\"\n :size=\"16\"\n />\n <span v-if=\"!isCollapsed\">{{ toggleLabel }}</span>\n </slot>\n </button>\n </div>\n </component>\n</template>\n"],"mappings":"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"}
|
|
@@ -72,10 +72,7 @@ var y = {
|
|
|
72
72
|
default: _(() => [
|
|
73
73
|
e.$slots.header ? (l(), a("div", y, [d(e.$slots, "header", { collapsed: h(A) })])) : i("", !0),
|
|
74
74
|
o("div", b, [d(e.$slots, "default", { collapsed: h(A) })]),
|
|
75
|
-
e.$slots.footer || s.collapsible ? (l(), a("div", x, [e.$slots.footer ? d(e.$slots, "footer", {
|
|
76
|
-
key: 0,
|
|
77
|
-
collapsed: h(A)
|
|
78
|
-
}) : i("", !0), s.collapsible ? (l(), a("button", {
|
|
75
|
+
e.$slots.footer || s.collapsible ? (l(), a("div", x, [e.$slots.footer ? d(e.$slots, "footer", { collapsed: h(A) }, void 0, void 0, 0) : i("", !0), s.collapsible ? (l(), a("button", {
|
|
79
76
|
key: 1,
|
|
80
77
|
type: "button",
|
|
81
78
|
class: "t-sidebar__toggle",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TSidebar.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../src/components/TSidebar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { getTreeIcon } from '@treeui/icons';\nimport { computed, provide, toRef, useAttrs } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\nimport { treeSidebarInjectionKey } from './sidebar';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst _treeSidebarSides = ['left', 'right'] as const;\n\nexport type TSidebarSide = (typeof _treeSidebarSides)[number];\n\nconst ChevronLeftIcon = getTreeIcon('chevron-left');\nconst ChevronRightIcon = getTreeIcon('chevron-right');\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n collapsed?: boolean;\n defaultCollapsed?: boolean;\n collapsible?: boolean;\n size?: TSize;\n side?: TSidebarSide;\n sticky?: boolean;\n bordered?: boolean;\n width?: string;\n collapsedWidth?: string;\n collapseLabel?: string;\n expandLabel?: string;\n }>(),\n {\n as: 'aside',\n collapsed: undefined,\n defaultCollapsed: false,\n collapsible: true,\n size: 'md',\n side: 'left',\n sticky: false,\n bordered: true,\n width: '17.5rem',\n collapsedWidth: '4.75rem',\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}>();\n\ndefineSlots<{\n header?: (props: { collapsed: boolean }) => unknown;\n default?: (props: { collapsed: boolean }) => unknown;\n footer?: (props: { collapsed: boolean }) => unknown;\n toggle?: (props: { collapsed: boolean }) => unknown;\n}>();\n\nconst attrs = useAttrs();\n\nconst { value: isCollapsed, setValue } = useControllableOpen(\n toRef(props, 'collapsed'),\n props.defaultCollapsed,\n (value) => {\n emit('update:collapsed', value);\n emit('collapse-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-sidebar',\n `t-sidebar--${props.size}`,\n `t-sidebar--${props.side}`,\n {\n 'is-collapsed': isCollapsed.value,\n 'is-sticky': props.sticky,\n 'is-bordered': props.bordered,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => [\n {\n '--tree-sidebar-width': props.width,\n '--tree-sidebar-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 toggleCollapsed = () => {\n if (!props.collapsible) {\n return;\n }\n\n setValue(!isCollapsed.value);\n};\n\nconst ToggleIcon = computed(() => {\n if (props.side === 'right') {\n return isCollapsed.value ? ChevronLeftIcon : ChevronRightIcon;\n }\n\n return isCollapsed.value ? ChevronRightIcon : ChevronLeftIcon;\n});\n\nconst toggleLabel = computed(() =>\n isCollapsed.value ? props.expandLabel : props.collapseLabel,\n);\n\nprovide(treeSidebarInjectionKey, {\n collapsed: computed(() => isCollapsed.value),\n});\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isCollapsed ? 'collapsed' : 'expanded'\"\n >\n <div\n v-if=\"$slots.header\"\n class=\"t-sidebar__header\"\n >\n <slot\n name=\"header\"\n :collapsed=\"isCollapsed\"\n />\n </div>\n\n <div class=\"t-sidebar__body\">\n <slot :collapsed=\"isCollapsed\" />\n </div>\n\n <div\n v-if=\"$slots.footer || collapsible\"\n class=\"t-sidebar__footer\"\n >\n <slot\n v-if=\"$slots.footer\"\n name=\"footer\"\n :collapsed=\"isCollapsed\"\n />\n\n <button\n v-if=\"collapsible\"\n type=\"button\"\n class=\"t-sidebar__toggle\"\n :aria-label=\"toggleLabel\"\n :aria-expanded=\"!isCollapsed\"\n @click=\"toggleCollapsed\"\n >\n <slot\n name=\"toggle\"\n :collapsed=\"isCollapsed\"\n >\n <component\n :is=\"ToggleIcon\"\n :size=\"16\"\n />\n <span v-if=\"!isCollapsed\">{{ toggleLabel }}</span>\n </slot>\n </button>\n </div>\n </component>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAeA,IAAM,IAAkB,EAAY,cAAc,GAC5C,IAAmB,EAAY,eAAe,GAE9C,IAAQ,GA+BR,IAAO,GAYP,IAAQ,EAAS,GAEjB,EAAE,OAAO,GAAa,gBAAa,EACvC,EAAM,GAAO,WAAW,GACxB,EAAM,mBACL,MAAU;GAET,AADA,EAAK,oBAAoB,CAAK,GAC9B,EAAK,mBAAmB,CAAK;EAC/B,CACF,GAEM,IAAc,QAAe;GACjC;GACA,cAAc,EAAM;GACpB,cAAc,EAAM;GACpB;IACE,gBAAgB,EAAY;IAC5B,aAAa,EAAM;IACnB,eAAe,EAAM;GACvB;GACA,EAAM;EACR,CAAC,GAEK,IAAY,QAAe,CAC/B;GACE,wBAAwB,EAAM;GAC9B,kCAAkC,EAAM;EAC1C,GACA,EAAM,KACR,CAAC,GAEK,IAAY,QAAe;GAC/B,IAAM,EAAE,OAAO,GAAQ,OAAO,GAAQ,GAAG,MAAS;GAClD,OAAO;EACT,CAAC,GAEK,UAAwB;GACvB,EAAM,eAIX,EAAS,CAAC,EAAY,KAAK;EAC7B,GAEM,IAAa,QACb,EAAM,SAAS,UACV,EAAY,QAAQ,IAAkB,IAGxC,EAAY,QAAQ,IAAmB,CAC/C,GAEK,IAAc,QAClB,EAAY,QAAQ,EAAM,cAAc,EAAM,aAChD;SAEA,EAAQ,GAAyB,EAC/B,WAAW,QAAe,EAAY,KAAK,EAC7C,CAAC,mBAIC,EAmDY,EAlDL,EAAA,EAAE,GADT,EAEU,EAiDE,OAjDO;GAChB,OAAO,EAAA;GACP,OAAO,EAAA;GACP,cAAY,EAAA,CAAA,IAAW,cAAA;;oBAUlB;IAPEA,EAAAA,OAAO,UAAA,EAAA,GADf,EAQM,OARN,GAQM,CAJJ,EAGE,EAAA,QAAA,UAAA,EADC,WAAW,EAAA,CAAA,EAAW,CAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA;IAI3B,EAEM,OAFN,GAEM,CADJ,EAAiC,EAAA,QAAA,WAAA,EAA1B,WAAW,EAAA,CAAA,EAAW,CAAA,CAAA,CAAA;IAIvBA,EAAAA,OAAO,UAAU,EAAA,eAAA,EAAA,GADzB,EA6BM,OA7BN,GA6BM,CAxBIA,EAAAA,OAAO,SADf,EAIE,EAAA,QAAA,UAAA
|
|
1
|
+
{"version":3,"file":"TSidebar.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../src/components/TSidebar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { getTreeIcon } from '@treeui/icons';\nimport { computed, provide, toRef, useAttrs } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\nimport { treeSidebarInjectionKey } from './sidebar';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst _treeSidebarSides = ['left', 'right'] as const;\n\nexport type TSidebarSide = (typeof _treeSidebarSides)[number];\n\nconst ChevronLeftIcon = getTreeIcon('chevron-left');\nconst ChevronRightIcon = getTreeIcon('chevron-right');\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n collapsed?: boolean;\n defaultCollapsed?: boolean;\n collapsible?: boolean;\n size?: TSize;\n side?: TSidebarSide;\n sticky?: boolean;\n bordered?: boolean;\n width?: string;\n collapsedWidth?: string;\n collapseLabel?: string;\n expandLabel?: string;\n }>(),\n {\n as: 'aside',\n collapsed: undefined,\n defaultCollapsed: false,\n collapsible: true,\n size: 'md',\n side: 'left',\n sticky: false,\n bordered: true,\n width: '17.5rem',\n collapsedWidth: '4.75rem',\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}>();\n\ndefineSlots<{\n header?: (props: { collapsed: boolean }) => unknown;\n default?: (props: { collapsed: boolean }) => unknown;\n footer?: (props: { collapsed: boolean }) => unknown;\n toggle?: (props: { collapsed: boolean }) => unknown;\n}>();\n\nconst attrs = useAttrs();\n\nconst { value: isCollapsed, setValue } = useControllableOpen(\n toRef(props, 'collapsed'),\n props.defaultCollapsed,\n (value) => {\n emit('update:collapsed', value);\n emit('collapse-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-sidebar',\n `t-sidebar--${props.size}`,\n `t-sidebar--${props.side}`,\n {\n 'is-collapsed': isCollapsed.value,\n 'is-sticky': props.sticky,\n 'is-bordered': props.bordered,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => [\n {\n '--tree-sidebar-width': props.width,\n '--tree-sidebar-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 toggleCollapsed = () => {\n if (!props.collapsible) {\n return;\n }\n\n setValue(!isCollapsed.value);\n};\n\nconst ToggleIcon = computed(() => {\n if (props.side === 'right') {\n return isCollapsed.value ? ChevronLeftIcon : ChevronRightIcon;\n }\n\n return isCollapsed.value ? ChevronRightIcon : ChevronLeftIcon;\n});\n\nconst toggleLabel = computed(() =>\n isCollapsed.value ? props.expandLabel : props.collapseLabel,\n);\n\nprovide(treeSidebarInjectionKey, {\n collapsed: computed(() => isCollapsed.value),\n});\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isCollapsed ? 'collapsed' : 'expanded'\"\n >\n <div\n v-if=\"$slots.header\"\n class=\"t-sidebar__header\"\n >\n <slot\n name=\"header\"\n :collapsed=\"isCollapsed\"\n />\n </div>\n\n <div class=\"t-sidebar__body\">\n <slot :collapsed=\"isCollapsed\" />\n </div>\n\n <div\n v-if=\"$slots.footer || collapsible\"\n class=\"t-sidebar__footer\"\n >\n <slot\n v-if=\"$slots.footer\"\n name=\"footer\"\n :collapsed=\"isCollapsed\"\n />\n\n <button\n v-if=\"collapsible\"\n type=\"button\"\n class=\"t-sidebar__toggle\"\n :aria-label=\"toggleLabel\"\n :aria-expanded=\"!isCollapsed\"\n @click=\"toggleCollapsed\"\n >\n <slot\n name=\"toggle\"\n :collapsed=\"isCollapsed\"\n >\n <component\n :is=\"ToggleIcon\"\n :size=\"16\"\n />\n <span v-if=\"!isCollapsed\">{{ toggleLabel }}</span>\n </slot>\n </button>\n </div>\n </component>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAeA,IAAM,IAAkB,EAAY,cAAc,GAC5C,IAAmB,EAAY,eAAe,GAE9C,IAAQ,GA+BR,IAAO,GAYP,IAAQ,EAAS,GAEjB,EAAE,OAAO,GAAa,gBAAa,EACvC,EAAM,GAAO,WAAW,GACxB,EAAM,mBACL,MAAU;GAET,AADA,EAAK,oBAAoB,CAAK,GAC9B,EAAK,mBAAmB,CAAK;EAC/B,CACF,GAEM,IAAc,QAAe;GACjC;GACA,cAAc,EAAM;GACpB,cAAc,EAAM;GACpB;IACE,gBAAgB,EAAY;IAC5B,aAAa,EAAM;IACnB,eAAe,EAAM;GACvB;GACA,EAAM;EACR,CAAC,GAEK,IAAY,QAAe,CAC/B;GACE,wBAAwB,EAAM;GAC9B,kCAAkC,EAAM;EAC1C,GACA,EAAM,KACR,CAAC,GAEK,IAAY,QAAe;GAC/B,IAAM,EAAE,OAAO,GAAQ,OAAO,GAAQ,GAAG,MAAS;GAClD,OAAO;EACT,CAAC,GAEK,UAAwB;GACvB,EAAM,eAIX,EAAS,CAAC,EAAY,KAAK;EAC7B,GAEM,IAAa,QACb,EAAM,SAAS,UACV,EAAY,QAAQ,IAAkB,IAGxC,EAAY,QAAQ,IAAmB,CAC/C,GAEK,IAAc,QAClB,EAAY,QAAQ,EAAM,cAAc,EAAM,aAChD;SAEA,EAAQ,GAAyB,EAC/B,WAAW,QAAe,EAAY,KAAK,EAC7C,CAAC,mBAIC,EAmDY,EAlDL,EAAA,EAAE,GADT,EAEU,EAiDE,OAjDO;GAChB,OAAO,EAAA;GACP,OAAO,EAAA;GACP,cAAY,EAAA,CAAA,IAAW,cAAA;;oBAUlB;IAPEA,EAAAA,OAAO,UAAA,EAAA,GADf,EAQM,OARN,GAQM,CAJJ,EAGE,EAAA,QAAA,UAAA,EADC,WAAW,EAAA,CAAA,EAAW,CAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA;IAI3B,EAEM,OAFN,GAEM,CADJ,EAAiC,EAAA,QAAA,WAAA,EAA1B,WAAW,EAAA,CAAA,EAAW,CAAA,CAAA,CAAA;IAIvBA,EAAAA,OAAO,UAAU,EAAA,eAAA,EAAA,GADzB,EA6BM,OA7BN,GA6BM,CAxBIA,EAAAA,OAAO,SADf,EAIE,EAAA,QAAA,UAAA,EADC,WAAW,EAAA,CAAA,EAAW,GAAA,KAAA,GAAA,KAAA,GAAA,CAAA,IAAA,EAAA,IAAA,EAAA,GAIjB,EAAA,eAAA,EAAA,GADR,EAkBS,UAAA;;KAhBP,MAAK;KACL,OAAM;KACL,cAAY,EAAA;KACZ,iBAAa,CAAG,EAAA,CAAA;KAChB,SAAO;QAER,EASO,EAAA,QAAA,UAAA,EAPJ,WAAW,EAAA,CAAA,EAAW,SAOlB,EAAA,EAAA,GALL,EAGE,EAFK,EAAA,KAAU,GAAA,EACd,MAAM,GAAE,CAAA,IAEE,EAAA,CAAA,IAA2B,EAAA,IAAA,EAAA,KAA3B,EAAA,GAAb,EAAkD,QAAA,GAAA,EAArB,EAAA,KAAW,GAAA,CAAA,EAAA,CAAA,CAAA,GAAA,GAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TSpacer.cjs","names":[],"sources":["../../src/components/TSpacer.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// A flexible spacer that absorbs free space between siblings in a flex layout\n// (e.g. a TStack). Use it to push items apart or pin a trailing item to the end\n// without hand-writing `margin-*: auto` or `flex: 1`.\nwithDefaults(\n defineProps<{\n as?: string;\n }>(),\n {\n as: 'div',\n },\n);\n</script>\n\n<template>\n <component\n :is=\"as\"\n class=\"t-spacer\"\n aria-hidden=\"true\"\n />\n</template>\n"],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TSpacer.js","names":[],"sources":["../../src/components/TSpacer.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// A flexible spacer that absorbs free space between siblings in a flex layout\n// (e.g. a TStack). Use it to push items apart or pin a trailing item to the end\n// without hand-writing `margin-*: auto` or `flex: 1`.\nwithDefaults(\n defineProps<{\n as?: string;\n }>(),\n {\n as: 'div',\n },\n);\n</script>\n\n<template>\n <component\n :is=\"as\"\n class=\"t-spacer\"\n aria-hidden=\"true\"\n />\n</template>\n"],"mappings":""}
|