@treeui/vue 0.15.0 → 0.16.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.
Files changed (26) hide show
  1. package/dist/components/TCard.cjs.map +1 -1
  2. package/dist/components/TCard.js.map +1 -1
  3. package/dist/components/TCard.vue_vue_type_script_setup_true_lang.cjs +1 -1
  4. package/dist/components/TCard.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
  5. package/dist/components/TCard.vue_vue_type_script_setup_true_lang.js +2 -2
  6. package/dist/components/TCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  7. package/dist/components/TDropdown.cjs.map +1 -1
  8. package/dist/components/TDropdown.js.map +1 -1
  9. package/dist/components/TDropdown.vue.d.ts +2 -2
  10. package/dist/components/TDropdown.vue.d.ts.map +1 -1
  11. package/dist/components/TDropdown.vue_vue_type_script_setup_true_lang.cjs +1 -1
  12. package/dist/components/TDropdown.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
  13. package/dist/components/TDropdown.vue_vue_type_script_setup_true_lang.js +35 -32
  14. package/dist/components/TDropdown.vue_vue_type_script_setup_true_lang.js.map +1 -1
  15. package/dist/components/TMarkdownEditor.cjs.map +1 -1
  16. package/dist/components/TMarkdownEditor.js.map +1 -1
  17. package/dist/components/TMarkdownEditor.vue.d.ts +2 -0
  18. package/dist/components/TMarkdownEditor.vue.d.ts.map +1 -1
  19. package/dist/components/TMarkdownEditor.vue_vue_type_script_setup_true_lang.cjs +9 -9
  20. package/dist/components/TMarkdownEditor.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
  21. package/dist/components/TMarkdownEditor.vue_vue_type_script_setup_true_lang.js +117 -96
  22. package/dist/components/TMarkdownEditor.vue_vue_type_script_setup_true_lang.js.map +1 -1
  23. package/dist/components/index.d.ts +9 -0
  24. package/dist/components/index.d.ts.map +1 -1
  25. package/dist/style.css +1 -1
  26. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"TCard.cjs","names":[],"sources":["../../src/components/TCard.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TCardVariant, TSize } from '../types/contracts';\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n variant?: TCardVariant;\n size?: TSize;\n title?: string;\n }>(),\n {\n as: 'section',\n variant: 'outline',\n size: 'md',\n title: undefined,\n },\n);\n\nconst classes = computed(() => [\n 't-card',\n `t-card--${props.variant}`,\n `t-card--${props.size}`,\n]);\n\nconst hasHeader = computed(() => !!props.title);\n</script>\n\n<template>\n <component\n :is=\"as\"\n :class=\"classes\"\n >\n <header\n v-if=\"$slots.header || hasHeader || $slots.actions\"\n class=\"t-card__header\"\n >\n <slot name=\"header\">\n <span\n v-if=\"title\"\n class=\"t-card__title\"\n >\n {{ title }}\n </span>\n <span\n v-if=\"$slots.actions\"\n class=\"t-card__actions\"\n >\n <slot name=\"actions\" />\n </span>\n </slot>\n </header>\n <div class=\"t-card__body\">\n <slot />\n </div>\n <footer\n v-if=\"$slots.footer\"\n class=\"t-card__footer\"\n >\n <slot name=\"footer\" />\n </footer>\n </component>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"TCard.cjs","names":[],"sources":["../../src/components/TCard.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TCardVariant, TSize } from '../types/contracts';\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n variant?: TCardVariant;\n size?: TSize;\n title?: string;\n }>(),\n {\n as: 'section',\n variant: 'outline',\n size: 'md',\n title: undefined,\n },\n);\n\nconst classes = computed(() => [\n 't-card',\n `t-card--${props.variant}`,\n `t-card--${props.size}`,\n]);\n\nconst hasHeader = computed(() => !!props.title);\n</script>\n\n<template>\n <component\n :is=\"as\"\n :class=\"classes\"\n >\n <header\n v-if=\"$slots.header || hasHeader || $slots.actions\"\n class=\"t-card__header\"\n >\n <slot name=\"header\">\n <span\n v-if=\"title\"\n class=\"t-card__title\"\n >\n {{ title }}\n </span>\n </slot>\n <span\n v-if=\"$slots.actions\"\n class=\"t-card__actions\"\n >\n <slot name=\"actions\" />\n </span>\n </header>\n <div class=\"t-card__body\">\n <slot />\n </div>\n <footer\n v-if=\"$slots.footer\"\n class=\"t-card__footer\"\n >\n <slot name=\"footer\" />\n </footer>\n </component>\n</template>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"TCard.js","names":[],"sources":["../../src/components/TCard.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TCardVariant, TSize } from '../types/contracts';\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n variant?: TCardVariant;\n size?: TSize;\n title?: string;\n }>(),\n {\n as: 'section',\n variant: 'outline',\n size: 'md',\n title: undefined,\n },\n);\n\nconst classes = computed(() => [\n 't-card',\n `t-card--${props.variant}`,\n `t-card--${props.size}`,\n]);\n\nconst hasHeader = computed(() => !!props.title);\n</script>\n\n<template>\n <component\n :is=\"as\"\n :class=\"classes\"\n >\n <header\n v-if=\"$slots.header || hasHeader || $slots.actions\"\n class=\"t-card__header\"\n >\n <slot name=\"header\">\n <span\n v-if=\"title\"\n class=\"t-card__title\"\n >\n {{ title }}\n </span>\n <span\n v-if=\"$slots.actions\"\n class=\"t-card__actions\"\n >\n <slot name=\"actions\" />\n </span>\n </slot>\n </header>\n <div class=\"t-card__body\">\n <slot />\n </div>\n <footer\n v-if=\"$slots.footer\"\n class=\"t-card__footer\"\n >\n <slot name=\"footer\" />\n </footer>\n </component>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"TCard.js","names":[],"sources":["../../src/components/TCard.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TCardVariant, TSize } from '../types/contracts';\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n variant?: TCardVariant;\n size?: TSize;\n title?: string;\n }>(),\n {\n as: 'section',\n variant: 'outline',\n size: 'md',\n title: undefined,\n },\n);\n\nconst classes = computed(() => [\n 't-card',\n `t-card--${props.variant}`,\n `t-card--${props.size}`,\n]);\n\nconst hasHeader = computed(() => !!props.title);\n</script>\n\n<template>\n <component\n :is=\"as\"\n :class=\"classes\"\n >\n <header\n v-if=\"$slots.header || hasHeader || $slots.actions\"\n class=\"t-card__header\"\n >\n <slot name=\"header\">\n <span\n v-if=\"title\"\n class=\"t-card__title\"\n >\n {{ title }}\n </span>\n </slot>\n <span\n v-if=\"$slots.actions\"\n class=\"t-card__actions\"\n >\n <slot name=\"actions\" />\n </span>\n </header>\n <div class=\"t-card__body\">\n <slot />\n </div>\n <footer\n v-if=\"$slots.footer\"\n class=\"t-card__footer\"\n >\n <slot name=\"footer\" />\n </footer>\n </component>\n</template>\n"],"mappings":""}
@@ -1,2 +1,2 @@
1
- let e=require("vue");var t={key:0,class:`t-card__header`},n={key:0,class:`t-card__title`},r={key:1,class:`t-card__actions`},i={class:`t-card__body`},a={key:1,class:`t-card__footer`},o=(0,e.defineComponent)({__name:`TCard`,props:{as:{default:`section`},variant:{default:`outline`},size:{default:`md`},title:{default:void 0}},setup(o){let s=o,c=(0,e.computed)(()=>[`t-card`,`t-card--${s.variant}`,`t-card--${s.size}`]),l=(0,e.computed)(()=>!!s.title);return(s,u)=>((0,e.openBlock)(),(0,e.createBlock)((0,e.resolveDynamicComponent)(o.as),{class:(0,e.normalizeClass)(c.value)},{default:(0,e.withCtx)(()=>[s.$slots.header||l.value||s.$slots.actions?((0,e.openBlock)(),(0,e.createElementBlock)(`header`,t,[(0,e.renderSlot)(s.$slots,`header`,{},()=>[o.title?((0,e.openBlock)(),(0,e.createElementBlock)(`span`,n,(0,e.toDisplayString)(o.title),1)):(0,e.createCommentVNode)(``,!0),s.$slots.actions?((0,e.openBlock)(),(0,e.createElementBlock)(`span`,r,[(0,e.renderSlot)(s.$slots,`actions`)])):(0,e.createCommentVNode)(``,!0)])])):(0,e.createCommentVNode)(``,!0),(0,e.createElementVNode)(`div`,i,[(0,e.renderSlot)(s.$slots,`default`)]),s.$slots.footer?((0,e.openBlock)(),(0,e.createElementBlock)(`footer`,a,[(0,e.renderSlot)(s.$slots,`footer`)])):(0,e.createCommentVNode)(``,!0)]),_:3},8,[`class`]))}});exports.default=o;
1
+ let e=require("vue");var t={key:0,class:`t-card__header`},n={key:0,class:`t-card__title`},r={key:0,class:`t-card__actions`},i={class:`t-card__body`},a={key:1,class:`t-card__footer`},o=(0,e.defineComponent)({__name:`TCard`,props:{as:{default:`section`},variant:{default:`outline`},size:{default:`md`},title:{default:void 0}},setup(o){let s=o,c=(0,e.computed)(()=>[`t-card`,`t-card--${s.variant}`,`t-card--${s.size}`]),l=(0,e.computed)(()=>!!s.title);return(s,u)=>((0,e.openBlock)(),(0,e.createBlock)((0,e.resolveDynamicComponent)(o.as),{class:(0,e.normalizeClass)(c.value)},{default:(0,e.withCtx)(()=>[s.$slots.header||l.value||s.$slots.actions?((0,e.openBlock)(),(0,e.createElementBlock)(`header`,t,[(0,e.renderSlot)(s.$slots,`header`,{},()=>[o.title?((0,e.openBlock)(),(0,e.createElementBlock)(`span`,n,(0,e.toDisplayString)(o.title),1)):(0,e.createCommentVNode)(``,!0)]),s.$slots.actions?((0,e.openBlock)(),(0,e.createElementBlock)(`span`,r,[(0,e.renderSlot)(s.$slots,`actions`)])):(0,e.createCommentVNode)(``,!0)])):(0,e.createCommentVNode)(``,!0),(0,e.createElementVNode)(`div`,i,[(0,e.renderSlot)(s.$slots,`default`)]),s.$slots.footer?((0,e.openBlock)(),(0,e.createElementBlock)(`footer`,a,[(0,e.renderSlot)(s.$slots,`footer`)])):(0,e.createCommentVNode)(``,!0)]),_:3},8,[`class`]))}});exports.default=o;
2
2
  //# sourceMappingURL=TCard.vue_vue_type_script_setup_true_lang.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"TCard.vue_vue_type_script_setup_true_lang.cjs","names":["$slots"],"sources":["../../src/components/TCard.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TCardVariant, TSize } from '../types/contracts';\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n variant?: TCardVariant;\n size?: TSize;\n title?: string;\n }>(),\n {\n as: 'section',\n variant: 'outline',\n size: 'md',\n title: undefined,\n },\n);\n\nconst classes = computed(() => [\n 't-card',\n `t-card--${props.variant}`,\n `t-card--${props.size}`,\n]);\n\nconst hasHeader = computed(() => !!props.title);\n</script>\n\n<template>\n <component\n :is=\"as\"\n :class=\"classes\"\n >\n <header\n v-if=\"$slots.header || hasHeader || $slots.actions\"\n class=\"t-card__header\"\n >\n <slot name=\"header\">\n <span\n v-if=\"title\"\n class=\"t-card__title\"\n >\n {{ title }}\n </span>\n <span\n v-if=\"$slots.actions\"\n class=\"t-card__actions\"\n >\n <slot name=\"actions\" />\n </span>\n </slot>\n </header>\n <div class=\"t-card__body\">\n <slot />\n </div>\n <footer\n v-if=\"$slots.footer\"\n class=\"t-card__footer\"\n >\n <slot name=\"footer\" />\n </footer>\n </component>\n</template>\n"],"mappings":"6UAIA,IAAM,EAAQ,EAeR,GAAA,EAAA,EAAA,SAAA,KAAyB,CAC7B,SACA,WAAW,EAAM,UACjB,WAAW,EAAM,MACnB,CAAC,EAEK,GAAA,EAAA,EAAA,SAAA,KAA2B,CAAC,CAAC,EAAM,KAAK,kFAKrC,EAAA,EAAE,EAAA,CACN,OAAA,EAAA,EAAA,eAAA,CAAO,EAAA,KAAO,CAAA,EAAA,2BAoBN,CAjBDA,EAAAA,OAAO,QAAU,EAAA,OAAaA,EAAAA,OAAO,UAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAiBpC,SAlBT,EAkBS,EAAA,EAAA,EAAA,WAAA,CADA,EAAA,OAAA,SAAA,CAAA,MAAA,CAXG,EAAA,QAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAID,OALP,GAAA,EAAA,EAAA,gBAAA,CAIK,EAAA,KAAK,EAAA,CAAA,IAAA,EAAA,EAAA,mBAAA,CAAA,GAAA,EAAA,EAGFA,EAAAA,OAAO,UAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAIR,OALP,EAKO,EAAA,EAAA,EAAA,WAAA,CADkB,EAAA,OAAA,SAAA,CAAA,CAAA,IAAA,EAAA,EAAA,mBAAA,CAAA,GAAA,EAAA,CAAA,CAAA,CAAA,CAAA,IAAA,EAAA,EAAA,mBAAA,CAAA,GAAA,EAAA,2BAMvB,MAFN,EAEM,EAAA,EAAA,EAAA,WAAA,CADI,EAAA,OAAA,SAAA,CAAA,CAAA,EAGFA,EAAAA,OAAO,SAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAIN,SALT,EAKS,EAAA,EAAA,EAAA,WAAA,CADe,EAAA,OAAA,QAAA,CAAA,CAAA,IAAA,EAAA,EAAA,mBAAA,CAAA,GAAA,EAAA"}
1
+ {"version":3,"file":"TCard.vue_vue_type_script_setup_true_lang.cjs","names":["$slots"],"sources":["../../src/components/TCard.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TCardVariant, TSize } from '../types/contracts';\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n variant?: TCardVariant;\n size?: TSize;\n title?: string;\n }>(),\n {\n as: 'section',\n variant: 'outline',\n size: 'md',\n title: undefined,\n },\n);\n\nconst classes = computed(() => [\n 't-card',\n `t-card--${props.variant}`,\n `t-card--${props.size}`,\n]);\n\nconst hasHeader = computed(() => !!props.title);\n</script>\n\n<template>\n <component\n :is=\"as\"\n :class=\"classes\"\n >\n <header\n v-if=\"$slots.header || hasHeader || $slots.actions\"\n class=\"t-card__header\"\n >\n <slot name=\"header\">\n <span\n v-if=\"title\"\n class=\"t-card__title\"\n >\n {{ title }}\n </span>\n </slot>\n <span\n v-if=\"$slots.actions\"\n class=\"t-card__actions\"\n >\n <slot name=\"actions\" />\n </span>\n </header>\n <div class=\"t-card__body\">\n <slot />\n </div>\n <footer\n v-if=\"$slots.footer\"\n class=\"t-card__footer\"\n >\n <slot name=\"footer\" />\n </footer>\n </component>\n</template>\n"],"mappings":"6UAIA,IAAM,EAAQ,EAeR,GAAA,EAAA,EAAA,SAAA,KAAyB,CAC7B,SACA,WAAW,EAAM,UACjB,WAAW,EAAM,MACnB,CAAC,EAEK,GAAA,EAAA,EAAA,SAAA,KAA2B,CAAC,CAAC,EAAM,KAAK,kFAKrC,EAAA,EAAE,EAAA,CACN,OAAA,EAAA,EAAA,eAAA,CAAO,EAAA,KAAO,CAAA,EAAA,2BAoBN,CAjBDA,EAAAA,OAAO,QAAU,EAAA,OAAaA,EAAAA,OAAO,UAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAiBpC,SAlBT,EAkBS,EAAA,EAAA,EAAA,WAAA,CAPA,EAAA,OAAA,SAAA,CAAA,MAAA,CALG,EAAA,QAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAID,OALP,GAAA,EAAA,EAAA,gBAAA,CAIK,EAAA,KAAK,EAAA,CAAA,IAAA,EAAA,EAAA,mBAAA,CAAA,GAAA,EAAA,CAAA,CAAA,EAIJA,EAAAA,OAAO,UAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAIR,OALP,EAKO,EAAA,EAAA,EAAA,WAAA,CADkB,EAAA,OAAA,SAAA,CAAA,CAAA,IAAA,EAAA,EAAA,mBAAA,CAAA,GAAA,EAAA,CAAA,CAAA,IAAA,EAAA,EAAA,mBAAA,CAAA,GAAA,EAAA,2BAKrB,MAFN,EAEM,EAAA,EAAA,EAAA,WAAA,CADI,EAAA,OAAA,SAAA,CAAA,CAAA,EAGFA,EAAAA,OAAO,SAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAIN,SALT,EAKS,EAAA,EAAA,EAAA,WAAA,CADe,EAAA,OAAA,QAAA,CAAA,CAAA,IAAA,EAAA,EAAA,mBAAA,CAAA,GAAA,EAAA"}
@@ -7,7 +7,7 @@ var f = {
7
7
  key: 0,
8
8
  class: "t-card__title"
9
9
  }, m = {
10
- key: 1,
10
+ key: 0,
11
11
  class: "t-card__actions"
12
12
  }, h = { class: "t-card__body" }, g = {
13
13
  key: 1,
@@ -28,7 +28,7 @@ var f = {
28
28
  ]), y = e(() => !!_.title);
29
29
  return (e, _) => (s(), t(l(a.as), { class: o(v.value) }, {
30
30
  default: d(() => [
31
- e.$slots.header || y.value || e.$slots.actions ? (s(), r("header", f, [c(e.$slots, "header", {}, () => [a.title ? (s(), r("span", p, u(a.title), 1)) : n("", !0), e.$slots.actions ? (s(), r("span", m, [c(e.$slots, "actions")])) : n("", !0)])])) : n("", !0),
31
+ e.$slots.header || y.value || e.$slots.actions ? (s(), r("header", f, [c(e.$slots, "header", {}, () => [a.title ? (s(), r("span", p, u(a.title), 1)) : n("", !0)]), e.$slots.actions ? (s(), r("span", m, [c(e.$slots, "actions")])) : n("", !0)])) : n("", !0),
32
32
  i("div", h, [c(e.$slots, "default")]),
33
33
  e.$slots.footer ? (s(), r("footer", g, [c(e.$slots, "footer")])) : n("", !0)
34
34
  ]),
@@ -1 +1 @@
1
- {"version":3,"file":"TCard.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../src/components/TCard.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TCardVariant, TSize } from '../types/contracts';\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n variant?: TCardVariant;\n size?: TSize;\n title?: string;\n }>(),\n {\n as: 'section',\n variant: 'outline',\n size: 'md',\n title: undefined,\n },\n);\n\nconst classes = computed(() => [\n 't-card',\n `t-card--${props.variant}`,\n `t-card--${props.size}`,\n]);\n\nconst hasHeader = computed(() => !!props.title);\n</script>\n\n<template>\n <component\n :is=\"as\"\n :class=\"classes\"\n >\n <header\n v-if=\"$slots.header || hasHeader || $slots.actions\"\n class=\"t-card__header\"\n >\n <slot name=\"header\">\n <span\n v-if=\"title\"\n class=\"t-card__title\"\n >\n {{ title }}\n </span>\n <span\n v-if=\"$slots.actions\"\n class=\"t-card__actions\"\n >\n <slot name=\"actions\" />\n </span>\n </slot>\n </header>\n <div class=\"t-card__body\">\n <slot />\n </div>\n <footer\n v-if=\"$slots.footer\"\n class=\"t-card__footer\"\n >\n <slot name=\"footer\" />\n </footer>\n </component>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;EAIA,IAAM,IAAQ,GAeR,IAAU,QAAe;GAC7B;GACA,WAAW,EAAM;GACjB,WAAW,EAAM;EACnB,CAAC,GAEK,IAAY,QAAe,CAAC,CAAC,EAAM,KAAK;yBAI5C,EAgCY,EA/BL,EAAA,EAAE,GAAA,EACN,OAAK,EAAE,EAAA,KAAO,EAAA,GAAA;oBAoBN;IAjBDA,EAAAA,OAAO,UAAU,EAAA,SAAaA,EAAAA,OAAO,WAAA,EAAA,GAD7C,EAkBS,UAlBT,GAkBS,CAdP,EAaO,EAAA,QAAA,UAAA,CAAA,SAAA,CAXG,EAAA,SAAA,EAAA,GADR,EAKO,QALP,GAKO,EADF,EAAA,KAAK,GAAA,CAAA,KAAA,EAAA,IAAA,EAAA,GAGFA,EAAAA,OAAO,WAAA,EAAA,GADf,EAKO,QALP,GAKO,CADL,EAAuB,EAAA,QAAA,SAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA;IAI7B,EAEM,OAFN,GAEM,CADJ,EAAQ,EAAA,QAAA,SAAA,CAAA,CAAA;IAGFA,EAAAA,OAAO,UAAA,EAAA,GADf,EAKS,UALT,GAKS,CADP,EAAsB,EAAA,QAAA,QAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA"}
1
+ {"version":3,"file":"TCard.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../src/components/TCard.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TCardVariant, TSize } from '../types/contracts';\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n variant?: TCardVariant;\n size?: TSize;\n title?: string;\n }>(),\n {\n as: 'section',\n variant: 'outline',\n size: 'md',\n title: undefined,\n },\n);\n\nconst classes = computed(() => [\n 't-card',\n `t-card--${props.variant}`,\n `t-card--${props.size}`,\n]);\n\nconst hasHeader = computed(() => !!props.title);\n</script>\n\n<template>\n <component\n :is=\"as\"\n :class=\"classes\"\n >\n <header\n v-if=\"$slots.header || hasHeader || $slots.actions\"\n class=\"t-card__header\"\n >\n <slot name=\"header\">\n <span\n v-if=\"title\"\n class=\"t-card__title\"\n >\n {{ title }}\n </span>\n </slot>\n <span\n v-if=\"$slots.actions\"\n class=\"t-card__actions\"\n >\n <slot name=\"actions\" />\n </span>\n </header>\n <div class=\"t-card__body\">\n <slot />\n </div>\n <footer\n v-if=\"$slots.footer\"\n class=\"t-card__footer\"\n >\n <slot name=\"footer\" />\n </footer>\n </component>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;EAIA,IAAM,IAAQ,GAeR,IAAU,QAAe;GAC7B;GACA,WAAW,EAAM;GACjB,WAAW,EAAM;EACnB,CAAC,GAEK,IAAY,QAAe,CAAC,CAAC,EAAM,KAAK;yBAI5C,EAgCY,EA/BL,EAAA,EAAE,GAAA,EACN,OAAK,EAAE,EAAA,KAAO,EAAA,GAAA;oBAoBN;IAjBDA,EAAAA,OAAO,UAAU,EAAA,SAAaA,EAAAA,OAAO,WAAA,EAAA,GAD7C,EAkBS,UAlBT,GAkBS,CAdP,EAOO,EAAA,QAAA,UAAA,CAAA,SAAA,CALG,EAAA,SAAA,EAAA,GADR,EAKO,QALP,GAKO,EADF,EAAA,KAAK,GAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA,GAIJA,EAAAA,OAAO,WAAA,EAAA,GADf,EAKO,QALP,GAKO,CADL,EAAuB,EAAA,QAAA,SAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA;IAG3B,EAEM,OAFN,GAEM,CADJ,EAAQ,EAAA,QAAA,SAAA,CAAA,CAAA;IAGFA,EAAAA,OAAO,UAAA,EAAA,GADf,EAKS,UALT,GAKS,CADP,EAAsB,EAAA,QAAA,QAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"TDropdown.cjs","names":[],"sources":["../../src/components/TDropdown.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';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TDropdownItem {\n label: string;\n value: string;\n disabled?: boolean;\n}\n\nexport type TDropdownAlign = 'start' | 'end';\n\nconst props = withDefaults(\n defineProps<{\n items?: TDropdownItem[];\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n size?: TSize;\n label?: string;\n align?: TDropdownAlign;\n }>(),\n {\n items: () => [],\n open: undefined,\n defaultOpen: false,\n disabled: false,\n size: 'md',\n label: '',\n align: 'start',\n },\n);\n\nconst emit = defineEmits<{\n select: [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\ndefineSlots<{\n trigger(props: { isOpen: boolean }): unknown;\n item(props: { item: TDropdownItem; index: number }): unknown;\n}>();\n\nconst attrs = useAttrs();\nconst menuId = createId('t-dropdown');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst itemRefs = ref<Map<string, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\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-dropdown',\n `t-dropdown--${props.size}`,\n {\n 't-dropdown--align-end': props.align === 'end',\n 'is-disabled': props.disabled,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst enabledItems = computed(() => props.items.filter((i) => !i.disabled));\n\nconst openMenu = () => {\n if (props.disabled) return;\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n setValue(true);\n nextTick(() => focusItem(focusedIndex.value));\n};\n\nconst closeMenu = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => triggerRef.value?.focus());\n }\n};\n\nconst toggleMenu = () => {\n if (isOpen.value) {\n closeMenu();\n } else {\n openMenu();\n }\n};\n\nconst selectItem = (item: TDropdownItem) => {\n if (item.disabled) return;\n emit('select', item.value);\n closeMenu(true);\n};\n\nconst focusItem = (index: number) => {\n const item = props.items[index];\n if (!item) return;\n const el = itemRefs.value.get(item.value);\n el?.focus();\n};\n\nconst setItemRef = (el: Element | null, value: string) => {\n if (el instanceof HTMLElement) {\n itemRefs.value.set(value, el);\n } else {\n itemRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.items.length) {\n if (!props.items[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusItem(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 closeMenu();\n return;\n }\n\n if (isActivationKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n openMenu();\n }\n};\n\nconst onItemKeydown = (event: KeyboardEvent, item: TDropdownItem) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeMenu(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectItem(item);\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 = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n focusItem(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[enabledItems.value.length - 1])\n : props.items.length - 1;\n focusItem(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 closeMenu();\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 <span class=\"t-dropdown__trigger-wrapper\">\n <slot\n name=\"trigger\"\n :is-open=\"isOpen\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-dropdown__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? menuId : undefined\"\n aria-haspopup=\"menu\"\n :aria-expanded=\"isOpen\"\n @click=\"toggleMenu\"\n @keydown=\"onTriggerKeydown\"\n >\n <span class=\"t-dropdown__label\">{{ label }}</span>\n <svg\n class=\"t-dropdown__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 </slot>\n </span>\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"menuId\"\n role=\"menu\"\n class=\"t-dropdown__menu\"\n :aria-label=\"label || undefined\"\n >\n <li\n v-for=\"(item, index) in items\"\n :key=\"item.value\"\n :ref=\"(el) => setItemRef(el as Element | null, item.value)\"\n role=\"menuitem\"\n class=\"t-dropdown__item\"\n :class=\"{\n 'is-disabled': item.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-disabled=\"item.disabled || undefined\"\n :tabindex=\"item.disabled ? -1 : 0\"\n @click=\"selectItem(item)\"\n @keydown=\"onItemKeydown($event, item)\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :index=\"index\"\n >\n {{ item.label }}\n </slot>\n </li>\n </ul>\n </transition>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"TDropdown.cjs","names":[],"sources":["../../src/components/TDropdown.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { createId, focusFirst, 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';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TDropdownItem {\n label: string;\n value: string;\n disabled?: boolean;\n}\n\nexport type TDropdownAlign = 'start' | 'end';\n\nconst props = withDefaults(\n defineProps<{\n items?: TDropdownItem[];\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n size?: TSize;\n label?: string;\n align?: TDropdownAlign;\n }>(),\n {\n items: () => [],\n open: undefined,\n defaultOpen: false,\n disabled: false,\n size: 'md',\n label: '',\n align: 'start',\n },\n);\n\nconst emit = defineEmits<{\n select: [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\ndefineSlots<{\n trigger(props: { isOpen: boolean }): unknown;\n item(props: { item: TDropdownItem; index: number }): unknown;\n}>();\n\nconst attrs = useAttrs();\nconst menuId = createId('t-dropdown');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLElement | null>(null);\nconst itemRefs = ref<Map<string, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\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-dropdown',\n `t-dropdown--${props.size}`,\n {\n 't-dropdown--align-end': props.align === 'end',\n 'is-disabled': props.disabled,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst enabledItems = computed(() => props.items.filter((i) => !i.disabled));\n\nconst openMenu = () => {\n if (props.disabled) return;\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n setValue(true);\n nextTick(() => focusItem(focusedIndex.value));\n};\n\nconst closeMenu = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => {\n if (triggerRef.value) focusFirst(triggerRef.value);\n });\n }\n};\n\nconst toggleMenu = () => {\n if (props.disabled) return;\n if (isOpen.value) {\n closeMenu();\n } else {\n openMenu();\n }\n};\n\nconst selectItem = (item: TDropdownItem) => {\n if (item.disabled) return;\n emit('select', item.value);\n closeMenu(true);\n};\n\nconst focusItem = (index: number) => {\n const item = props.items[index];\n if (!item) return;\n const el = itemRefs.value.get(item.value);\n el?.focus();\n};\n\nconst setItemRef = (el: Element | null, value: string) => {\n if (el instanceof HTMLElement) {\n itemRefs.value.set(value, el);\n } else {\n itemRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.items.length) {\n if (!props.items[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusItem(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 closeMenu();\n return;\n }\n\n if (isActivationKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n openMenu();\n }\n};\n\nconst onItemKeydown = (event: KeyboardEvent, item: TDropdownItem) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeMenu(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectItem(item);\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 = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n focusItem(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[enabledItems.value.length - 1])\n : props.items.length - 1;\n focusItem(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 closeMenu();\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 <span\n ref=\"triggerRef\"\n class=\"t-dropdown__trigger-wrapper\"\n @click=\"toggleMenu\"\n @keydown=\"onTriggerKeydown\"\n >\n <slot\n name=\"trigger\"\n :is-open=\"isOpen\"\n >\n <button\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-dropdown__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? menuId : undefined\"\n aria-haspopup=\"menu\"\n :aria-expanded=\"isOpen\"\n >\n <span class=\"t-dropdown__label\">{{ label }}</span>\n <svg\n class=\"t-dropdown__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 </slot>\n </span>\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"menuId\"\n role=\"menu\"\n class=\"t-dropdown__menu\"\n :aria-label=\"label || undefined\"\n >\n <li\n v-for=\"(item, index) in items\"\n :key=\"item.value\"\n :ref=\"(el) => setItemRef(el as Element | null, item.value)\"\n role=\"menuitem\"\n class=\"t-dropdown__item\"\n :class=\"{\n 'is-disabled': item.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-disabled=\"item.disabled || undefined\"\n :tabindex=\"item.disabled ? -1 : 0\"\n @click=\"selectItem(item)\"\n @keydown=\"onItemKeydown($event, item)\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :index=\"index\"\n >\n {{ item.label }}\n </slot>\n </li>\n </ul>\n </transition>\n </div>\n</template>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"TDropdown.js","names":[],"sources":["../../src/components/TDropdown.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';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TDropdownItem {\n label: string;\n value: string;\n disabled?: boolean;\n}\n\nexport type TDropdownAlign = 'start' | 'end';\n\nconst props = withDefaults(\n defineProps<{\n items?: TDropdownItem[];\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n size?: TSize;\n label?: string;\n align?: TDropdownAlign;\n }>(),\n {\n items: () => [],\n open: undefined,\n defaultOpen: false,\n disabled: false,\n size: 'md',\n label: '',\n align: 'start',\n },\n);\n\nconst emit = defineEmits<{\n select: [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\ndefineSlots<{\n trigger(props: { isOpen: boolean }): unknown;\n item(props: { item: TDropdownItem; index: number }): unknown;\n}>();\n\nconst attrs = useAttrs();\nconst menuId = createId('t-dropdown');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst itemRefs = ref<Map<string, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\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-dropdown',\n `t-dropdown--${props.size}`,\n {\n 't-dropdown--align-end': props.align === 'end',\n 'is-disabled': props.disabled,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst enabledItems = computed(() => props.items.filter((i) => !i.disabled));\n\nconst openMenu = () => {\n if (props.disabled) return;\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n setValue(true);\n nextTick(() => focusItem(focusedIndex.value));\n};\n\nconst closeMenu = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => triggerRef.value?.focus());\n }\n};\n\nconst toggleMenu = () => {\n if (isOpen.value) {\n closeMenu();\n } else {\n openMenu();\n }\n};\n\nconst selectItem = (item: TDropdownItem) => {\n if (item.disabled) return;\n emit('select', item.value);\n closeMenu(true);\n};\n\nconst focusItem = (index: number) => {\n const item = props.items[index];\n if (!item) return;\n const el = itemRefs.value.get(item.value);\n el?.focus();\n};\n\nconst setItemRef = (el: Element | null, value: string) => {\n if (el instanceof HTMLElement) {\n itemRefs.value.set(value, el);\n } else {\n itemRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.items.length) {\n if (!props.items[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusItem(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 closeMenu();\n return;\n }\n\n if (isActivationKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n openMenu();\n }\n};\n\nconst onItemKeydown = (event: KeyboardEvent, item: TDropdownItem) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeMenu(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectItem(item);\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 = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n focusItem(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[enabledItems.value.length - 1])\n : props.items.length - 1;\n focusItem(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 closeMenu();\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 <span class=\"t-dropdown__trigger-wrapper\">\n <slot\n name=\"trigger\"\n :is-open=\"isOpen\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-dropdown__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? menuId : undefined\"\n aria-haspopup=\"menu\"\n :aria-expanded=\"isOpen\"\n @click=\"toggleMenu\"\n @keydown=\"onTriggerKeydown\"\n >\n <span class=\"t-dropdown__label\">{{ label }}</span>\n <svg\n class=\"t-dropdown__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 </slot>\n </span>\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"menuId\"\n role=\"menu\"\n class=\"t-dropdown__menu\"\n :aria-label=\"label || undefined\"\n >\n <li\n v-for=\"(item, index) in items\"\n :key=\"item.value\"\n :ref=\"(el) => setItemRef(el as Element | null, item.value)\"\n role=\"menuitem\"\n class=\"t-dropdown__item\"\n :class=\"{\n 'is-disabled': item.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-disabled=\"item.disabled || undefined\"\n :tabindex=\"item.disabled ? -1 : 0\"\n @click=\"selectItem(item)\"\n @keydown=\"onItemKeydown($event, item)\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :index=\"index\"\n >\n {{ item.label }}\n </slot>\n </li>\n </ul>\n </transition>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"TDropdown.js","names":[],"sources":["../../src/components/TDropdown.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { createId, focusFirst, 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';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TDropdownItem {\n label: string;\n value: string;\n disabled?: boolean;\n}\n\nexport type TDropdownAlign = 'start' | 'end';\n\nconst props = withDefaults(\n defineProps<{\n items?: TDropdownItem[];\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n size?: TSize;\n label?: string;\n align?: TDropdownAlign;\n }>(),\n {\n items: () => [],\n open: undefined,\n defaultOpen: false,\n disabled: false,\n size: 'md',\n label: '',\n align: 'start',\n },\n);\n\nconst emit = defineEmits<{\n select: [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\ndefineSlots<{\n trigger(props: { isOpen: boolean }): unknown;\n item(props: { item: TDropdownItem; index: number }): unknown;\n}>();\n\nconst attrs = useAttrs();\nconst menuId = createId('t-dropdown');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLElement | null>(null);\nconst itemRefs = ref<Map<string, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\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-dropdown',\n `t-dropdown--${props.size}`,\n {\n 't-dropdown--align-end': props.align === 'end',\n 'is-disabled': props.disabled,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst enabledItems = computed(() => props.items.filter((i) => !i.disabled));\n\nconst openMenu = () => {\n if (props.disabled) return;\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n setValue(true);\n nextTick(() => focusItem(focusedIndex.value));\n};\n\nconst closeMenu = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => {\n if (triggerRef.value) focusFirst(triggerRef.value);\n });\n }\n};\n\nconst toggleMenu = () => {\n if (props.disabled) return;\n if (isOpen.value) {\n closeMenu();\n } else {\n openMenu();\n }\n};\n\nconst selectItem = (item: TDropdownItem) => {\n if (item.disabled) return;\n emit('select', item.value);\n closeMenu(true);\n};\n\nconst focusItem = (index: number) => {\n const item = props.items[index];\n if (!item) return;\n const el = itemRefs.value.get(item.value);\n el?.focus();\n};\n\nconst setItemRef = (el: Element | null, value: string) => {\n if (el instanceof HTMLElement) {\n itemRefs.value.set(value, el);\n } else {\n itemRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.items.length) {\n if (!props.items[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusItem(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 closeMenu();\n return;\n }\n\n if (isActivationKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n openMenu();\n }\n};\n\nconst onItemKeydown = (event: KeyboardEvent, item: TDropdownItem) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeMenu(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectItem(item);\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 = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n focusItem(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[enabledItems.value.length - 1])\n : props.items.length - 1;\n focusItem(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 closeMenu();\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 <span\n ref=\"triggerRef\"\n class=\"t-dropdown__trigger-wrapper\"\n @click=\"toggleMenu\"\n @keydown=\"onTriggerKeydown\"\n >\n <slot\n name=\"trigger\"\n :is-open=\"isOpen\"\n >\n <button\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-dropdown__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? menuId : undefined\"\n aria-haspopup=\"menu\"\n :aria-expanded=\"isOpen\"\n >\n <span class=\"t-dropdown__label\">{{ label }}</span>\n <svg\n class=\"t-dropdown__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 </slot>\n </span>\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"menuId\"\n role=\"menu\"\n class=\"t-dropdown__menu\"\n :aria-label=\"label || undefined\"\n >\n <li\n v-for=\"(item, index) in items\"\n :key=\"item.value\"\n :ref=\"(el) => setItemRef(el as Element | null, item.value)\"\n role=\"menuitem\"\n class=\"t-dropdown__item\"\n :class=\"{\n 'is-disabled': item.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-disabled=\"item.disabled || undefined\"\n :tabindex=\"item.disabled ? -1 : 0\"\n @click=\"selectItem(item)\"\n @keydown=\"onItemKeydown($event, item)\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :index=\"index\"\n >\n {{ item.label }}\n </slot>\n </li>\n </ul>\n </transition>\n </div>\n</template>\n"],"mappings":""}
@@ -35,7 +35,7 @@ declare function __VLS_template(): {
35
35
  };
36
36
  refs: {
37
37
  rootRef: HTMLDivElement;
38
- triggerRef: HTMLButtonElement;
38
+ triggerRef: HTMLSpanElement;
39
39
  };
40
40
  rootEl: any;
41
41
  };
@@ -58,7 +58,7 @@ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}
58
58
  items: TDropdownItem[];
59
59
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
60
60
  rootRef: HTMLDivElement;
61
- triggerRef: HTMLButtonElement;
61
+ triggerRef: HTMLSpanElement;
62
62
  }, any>;
63
63
  declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
64
64
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"TDropdown.vue.d.ts","sourceRoot":"","sources":["../../src/components/TDropdown.vue"],"names":[],"mappings":"AA6SA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAMhD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,KAAK,CAAC;AAE7C,KAAK,WAAW,GAAG;IACf,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB,CAAC;AA+MJ,iBAAS,cAAc;WA8GT,OAAO,IAA6B;;uBAvSjC;YAAE,MAAM,EAAE,OAAO,CAAA;SAAE,GAAG,OAAO;oBAChC;YAAE,IAAI,EAAE,aAAa,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO;;uBAD7C;YAAE,MAAM,EAAE,OAAO,CAAA;SAAE,GAAG,OAAO;oBAChC;YAAE,IAAI,EAAE,aAAa,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO;;;;;;;EA2S7D;AAuBD,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAC9D,QAAA,MAAM,eAAe;;;;;;;;;cA9VN,OAAO;UACX,KAAK;WACJ,MAAM;WACN,cAAc;UALf,OAAO;iBACA,OAAO;WAFb,aAAa,EAAE;;;;OA0WzB,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
+ {"version":3,"file":"TDropdown.vue.d.ts","sourceRoot":"","sources":["../../src/components/TDropdown.vue"],"names":[],"mappings":"AAkTA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAMhD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,KAAK,CAAC;AAE7C,KAAK,WAAW,GAAG;IACf,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB,CAAC;AAkNJ,iBAAS,cAAc;WA8GT,OAAO,IAA6B;;uBA1SjC;YAAE,MAAM,EAAE,OAAO,CAAA;SAAE,GAAG,OAAO;oBAChC;YAAE,IAAI,EAAE,aAAa,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO;;uBAD7C;YAAE,MAAM,EAAE,OAAO,CAAA;SAAE,GAAG,OAAO;oBAChC;YAAE,IAAI,EAAE,aAAa,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO;;;;;;;EA8S7D;AAuBD,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAC9D,QAAA,MAAM,eAAe;;;;;;;;;cAjWN,OAAO;UACX,KAAK;WACJ,MAAM;WACN,cAAc;UALf,OAAO;iBACA,OAAO;WAFb,aAAa,EAAE;;;;OA6WzB,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("../composables/useControllableOpen.cjs");let t=require("vue"),n=require("@treeui/utils");var r=[`data-state`],i={class:`t-dropdown__trigger-wrapper`},a=[`disabled`,`aria-controls`,`aria-expanded`],o={class:`t-dropdown__label`},s=[`id`,`aria-label`],c=[`aria-disabled`,`tabindex`,`onClick`,`onKeydown`],l=(0,t.defineComponent)({inheritAttrs:!1,__name:`TDropdown`,props:{items:{default:()=>[]},open:{type:Boolean,default:void 0},defaultOpen:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},size:{default:`md`},label:{default:``},align:{default:`start`}},emits:[`select`,`update:open`,`open-change`],setup(l,{emit:u}){let d=l,f=u,p=(0,t.useAttrs)(),m=(0,n.createId)(`t-dropdown`),h=(0,t.ref)(null),g=(0,t.ref)(null),_=(0,t.ref)(new Map),v=(0,t.ref)(-1),y=(0,t.computed)(()=>{let{class:e,style:t,...n}=p;return n}),{value:b,setValue:x}=e.useControllableOpen((0,t.toRef)(d,`open`),d.defaultOpen,e=>{f(`update:open`,e),f(`open-change`,e)}),S=(0,t.computed)(()=>[`t-dropdown`,`t-dropdown--${d.size}`,{"t-dropdown--align-end":d.align===`end`,"is-disabled":d.disabled,"is-open":b.value},p.class]),C=(0,t.computed)(()=>p.style),w=(0,t.computed)(()=>d.items.filter(e=>!e.disabled)),T=()=>{d.disabled||(v.value=w.value.length>0?d.items.indexOf(w.value[0]):0,x(!0),(0,t.nextTick)(()=>k(v.value)))},E=(e=!1)=>{x(!1),v.value=-1,e&&(0,t.nextTick)(()=>g.value?.focus())},D=()=>{b.value?E():T()},O=e=>{e.disabled||(f(`select`,e.value),E(!0))},k=e=>{let t=d.items[e];t&&_.value.get(t.value)?.focus()},A=(e,t)=>{e instanceof HTMLElement?_.value.set(t,e):_.value.delete(t)},j=e=>{let t=v.value+e;for(;t>=0&&t<d.items.length;){if(!d.items[t].disabled){v.value=t,k(t);return}t+=e}},M=e=>{if(!d.disabled){if((0,n.isEscapeKey)(e)&&b.value){e.preventDefault(),E();return}((0,n.isActivationKey)(e)||e.key===`ArrowDown`||e.key===`ArrowUp`)&&(e.preventDefault(),T())}},N=(e,t)=>{if((0,n.isEscapeKey)(e)){e.preventDefault(),E(!0);return}if((0,n.isActivationKey)(e)){e.preventDefault(),O(t);return}switch(e.key){case`ArrowDown`:e.preventDefault(),j(1);break;case`ArrowUp`:e.preventDefault(),j(-1);break;case`Home`:e.preventDefault(),v.value=w.value.length>0?d.items.indexOf(w.value[0]):0,k(v.value);break;case`End`:e.preventDefault(),v.value=w.value.length>0?d.items.indexOf(w.value[w.value.length-1]):d.items.length-1,k(v.value);break;default:break}},P=e=>{if(!b.value)return;let t=e.target;t instanceof Node&&(h.value?.contains(t)||E())};return(0,t.watch)(b,e=>{e?document.addEventListener(`pointerdown`,P):document.removeEventListener(`pointerdown`,P)}),(0,t.onBeforeUnmount)(()=>{document.removeEventListener(`pointerdown`,P)}),(e,n)=>((0,t.openBlock)(),(0,t.createElementBlock)(`div`,{ref_key:`rootRef`,ref:h,class:(0,t.normalizeClass)(S.value),style:(0,t.normalizeStyle)(C.value),"data-state":(0,t.unref)(b)?`open`:`closed`},[(0,t.createElementVNode)(`span`,i,[(0,t.renderSlot)(e.$slots,`trigger`,{isOpen:(0,t.unref)(b)},()=>[(0,t.createElementVNode)(`button`,(0,t.mergeProps)({ref_key:`triggerRef`,ref:g},y.value,{type:`button`,class:`t-dropdown__trigger`,disabled:l.disabled,"aria-controls":(0,t.unref)(b)?(0,t.unref)(m):void 0,"aria-haspopup":`menu`,"aria-expanded":(0,t.unref)(b),onClick:D,onKeydown:M}),[(0,t.createElementVNode)(`span`,o,(0,t.toDisplayString)(l.label),1),n[0]||=(0,t.createElementVNode)(`svg`,{class:`t-dropdown__chevron`,viewBox:`0 0 16 16`,fill:`none`,stroke:`currentColor`,"stroke-width":`2`,"stroke-linecap":`round`,"stroke-linejoin":`round`,"aria-hidden":`true`},[(0,t.createElementVNode)(`polyline`,{points:`4 6 8 10 12 6`})],-1)],16,a)])]),(0,t.createVNode)(t.Transition,{name:`t-fade`},{default:(0,t.withCtx)(()=>[(0,t.unref)(b)&&!l.disabled?((0,t.openBlock)(),(0,t.createElementBlock)(`ul`,{key:0,id:(0,t.unref)(m),role:`menu`,class:`t-dropdown__menu`,"aria-label":l.label||void 0},[((0,t.openBlock)(!0),(0,t.createElementBlock)(t.Fragment,null,(0,t.renderList)(l.items,(n,r)=>((0,t.openBlock)(),(0,t.createElementBlock)(`li`,{key:n.value,ref_for:!0,ref:e=>A(e,n.value),role:`menuitem`,class:(0,t.normalizeClass)([`t-dropdown__item`,{"is-disabled":n.disabled,"is-focused":r===v.value}]),"aria-disabled":n.disabled||void 0,tabindex:n.disabled?-1:0,onClick:e=>O(n),onKeydown:e=>N(e,n)},[(0,t.renderSlot)(e.$slots,`item`,{item:n,index:r},()=>[(0,t.createTextVNode)((0,t.toDisplayString)(n.label),1)])],42,c))),128))],8,s)):(0,t.createCommentVNode)(``,!0)]),_:3})],14,r))}});exports.default=l;
1
+ const e=require("../composables/useControllableOpen.cjs");let t=require("vue"),n=require("@treeui/utils");var r=[`data-state`],i=[`disabled`,`aria-controls`,`aria-expanded`],a={class:`t-dropdown__label`},o=[`id`,`aria-label`],s=[`aria-disabled`,`tabindex`,`onClick`,`onKeydown`],c=(0,t.defineComponent)({inheritAttrs:!1,__name:`TDropdown`,props:{items:{default:()=>[]},open:{type:Boolean,default:void 0},defaultOpen:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},size:{default:`md`},label:{default:``},align:{default:`start`}},emits:[`select`,`update:open`,`open-change`],setup(c,{emit:l}){let u=c,d=l,f=(0,t.useAttrs)(),p=(0,n.createId)(`t-dropdown`),m=(0,t.ref)(null),h=(0,t.ref)(null),g=(0,t.ref)(new Map),_=(0,t.ref)(-1),v=(0,t.computed)(()=>{let{class:e,style:t,...n}=f;return n}),{value:y,setValue:b}=e.useControllableOpen((0,t.toRef)(u,`open`),u.defaultOpen,e=>{d(`update:open`,e),d(`open-change`,e)}),x=(0,t.computed)(()=>[`t-dropdown`,`t-dropdown--${u.size}`,{"t-dropdown--align-end":u.align===`end`,"is-disabled":u.disabled,"is-open":y.value},f.class]),S=(0,t.computed)(()=>f.style),C=(0,t.computed)(()=>u.items.filter(e=>!e.disabled)),w=()=>{u.disabled||(_.value=C.value.length>0?u.items.indexOf(C.value[0]):0,b(!0),(0,t.nextTick)(()=>O(_.value)))},T=(e=!1)=>{b(!1),_.value=-1,e&&(0,t.nextTick)(()=>{h.value&&(0,n.focusFirst)(h.value)})},E=()=>{u.disabled||(y.value?T():w())},D=e=>{e.disabled||(d(`select`,e.value),T(!0))},O=e=>{let t=u.items[e];t&&g.value.get(t.value)?.focus()},k=(e,t)=>{e instanceof HTMLElement?g.value.set(t,e):g.value.delete(t)},A=e=>{let t=_.value+e;for(;t>=0&&t<u.items.length;){if(!u.items[t].disabled){_.value=t,O(t);return}t+=e}},j=e=>{if(!u.disabled){if((0,n.isEscapeKey)(e)&&y.value){e.preventDefault(),T();return}((0,n.isActivationKey)(e)||e.key===`ArrowDown`||e.key===`ArrowUp`)&&(e.preventDefault(),w())}},M=(e,t)=>{if((0,n.isEscapeKey)(e)){e.preventDefault(),T(!0);return}if((0,n.isActivationKey)(e)){e.preventDefault(),D(t);return}switch(e.key){case`ArrowDown`:e.preventDefault(),A(1);break;case`ArrowUp`:e.preventDefault(),A(-1);break;case`Home`:e.preventDefault(),_.value=C.value.length>0?u.items.indexOf(C.value[0]):0,O(_.value);break;case`End`:e.preventDefault(),_.value=C.value.length>0?u.items.indexOf(C.value[C.value.length-1]):u.items.length-1,O(_.value);break;default:break}},N=e=>{if(!y.value)return;let t=e.target;t instanceof Node&&(m.value?.contains(t)||T())};return(0,t.watch)(y,e=>{e?document.addEventListener(`pointerdown`,N):document.removeEventListener(`pointerdown`,N)}),(0,t.onBeforeUnmount)(()=>{document.removeEventListener(`pointerdown`,N)}),(e,n)=>((0,t.openBlock)(),(0,t.createElementBlock)(`div`,{ref_key:`rootRef`,ref:m,class:(0,t.normalizeClass)(x.value),style:(0,t.normalizeStyle)(S.value),"data-state":(0,t.unref)(y)?`open`:`closed`},[(0,t.createElementVNode)(`span`,{ref_key:`triggerRef`,ref:h,class:`t-dropdown__trigger-wrapper`,onClick:E,onKeydown:j},[(0,t.renderSlot)(e.$slots,`trigger`,{isOpen:(0,t.unref)(y)},()=>[(0,t.createElementVNode)(`button`,(0,t.mergeProps)(v.value,{type:`button`,class:`t-dropdown__trigger`,disabled:c.disabled,"aria-controls":(0,t.unref)(y)?(0,t.unref)(p):void 0,"aria-haspopup":`menu`,"aria-expanded":(0,t.unref)(y)}),[(0,t.createElementVNode)(`span`,a,(0,t.toDisplayString)(c.label),1),n[0]||=(0,t.createElementVNode)(`svg`,{class:`t-dropdown__chevron`,viewBox:`0 0 16 16`,fill:`none`,stroke:`currentColor`,"stroke-width":`2`,"stroke-linecap":`round`,"stroke-linejoin":`round`,"aria-hidden":`true`},[(0,t.createElementVNode)(`polyline`,{points:`4 6 8 10 12 6`})],-1)],16,i)])],544),(0,t.createVNode)(t.Transition,{name:`t-fade`},{default:(0,t.withCtx)(()=>[(0,t.unref)(y)&&!c.disabled?((0,t.openBlock)(),(0,t.createElementBlock)(`ul`,{key:0,id:(0,t.unref)(p),role:`menu`,class:`t-dropdown__menu`,"aria-label":c.label||void 0},[((0,t.openBlock)(!0),(0,t.createElementBlock)(t.Fragment,null,(0,t.renderList)(c.items,(n,r)=>((0,t.openBlock)(),(0,t.createElementBlock)(`li`,{key:n.value,ref_for:!0,ref:e=>k(e,n.value),role:`menuitem`,class:(0,t.normalizeClass)([`t-dropdown__item`,{"is-disabled":n.disabled,"is-focused":r===_.value}]),"aria-disabled":n.disabled||void 0,tabindex:n.disabled?-1:0,onClick:e=>D(n),onKeydown:e=>M(e,n)},[(0,t.renderSlot)(e.$slots,`item`,{item:n,index:r},()=>[(0,t.createTextVNode)((0,t.toDisplayString)(n.label),1)])],42,s))),128))],8,o)):(0,t.createCommentVNode)(``,!0)]),_:3})],14,r))}});exports.default=c;
2
2
  //# sourceMappingURL=TDropdown.vue_vue_type_script_setup_true_lang.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"TDropdown.vue_vue_type_script_setup_true_lang.cjs","names":[],"sources":["../../src/components/TDropdown.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';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TDropdownItem {\n label: string;\n value: string;\n disabled?: boolean;\n}\n\nexport type TDropdownAlign = 'start' | 'end';\n\nconst props = withDefaults(\n defineProps<{\n items?: TDropdownItem[];\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n size?: TSize;\n label?: string;\n align?: TDropdownAlign;\n }>(),\n {\n items: () => [],\n open: undefined,\n defaultOpen: false,\n disabled: false,\n size: 'md',\n label: '',\n align: 'start',\n },\n);\n\nconst emit = defineEmits<{\n select: [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\ndefineSlots<{\n trigger(props: { isOpen: boolean }): unknown;\n item(props: { item: TDropdownItem; index: number }): unknown;\n}>();\n\nconst attrs = useAttrs();\nconst menuId = createId('t-dropdown');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst itemRefs = ref<Map<string, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\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-dropdown',\n `t-dropdown--${props.size}`,\n {\n 't-dropdown--align-end': props.align === 'end',\n 'is-disabled': props.disabled,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst enabledItems = computed(() => props.items.filter((i) => !i.disabled));\n\nconst openMenu = () => {\n if (props.disabled) return;\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n setValue(true);\n nextTick(() => focusItem(focusedIndex.value));\n};\n\nconst closeMenu = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => triggerRef.value?.focus());\n }\n};\n\nconst toggleMenu = () => {\n if (isOpen.value) {\n closeMenu();\n } else {\n openMenu();\n }\n};\n\nconst selectItem = (item: TDropdownItem) => {\n if (item.disabled) return;\n emit('select', item.value);\n closeMenu(true);\n};\n\nconst focusItem = (index: number) => {\n const item = props.items[index];\n if (!item) return;\n const el = itemRefs.value.get(item.value);\n el?.focus();\n};\n\nconst setItemRef = (el: Element | null, value: string) => {\n if (el instanceof HTMLElement) {\n itemRefs.value.set(value, el);\n } else {\n itemRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.items.length) {\n if (!props.items[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusItem(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 closeMenu();\n return;\n }\n\n if (isActivationKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n openMenu();\n }\n};\n\nconst onItemKeydown = (event: KeyboardEvent, item: TDropdownItem) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeMenu(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectItem(item);\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 = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n focusItem(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[enabledItems.value.length - 1])\n : props.items.length - 1;\n focusItem(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 closeMenu();\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 <span class=\"t-dropdown__trigger-wrapper\">\n <slot\n name=\"trigger\"\n :is-open=\"isOpen\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-dropdown__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? menuId : undefined\"\n aria-haspopup=\"menu\"\n :aria-expanded=\"isOpen\"\n @click=\"toggleMenu\"\n @keydown=\"onTriggerKeydown\"\n >\n <span class=\"t-dropdown__label\">{{ label }}</span>\n <svg\n class=\"t-dropdown__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 </slot>\n </span>\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"menuId\"\n role=\"menu\"\n class=\"t-dropdown__menu\"\n :aria-label=\"label || undefined\"\n >\n <li\n v-for=\"(item, index) in items\"\n :key=\"item.value\"\n :ref=\"(el) => setItemRef(el as Element | null, item.value)\"\n role=\"menuitem\"\n class=\"t-dropdown__item\"\n :class=\"{\n 'is-disabled': item.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-disabled=\"item.disabled || undefined\"\n :tabindex=\"item.disabled ? -1 : 0\"\n @click=\"selectItem(item)\"\n @keydown=\"onItemKeydown($event, item)\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :index=\"index\"\n >\n {{ item.label }}\n </slot>\n </li>\n </ul>\n </transition>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"TDropdown.vue_vue_type_script_setup_true_lang.cjs","names":[],"sources":["../../src/components/TDropdown.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { createId, focusFirst, 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';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TDropdownItem {\n label: string;\n value: string;\n disabled?: boolean;\n}\n\nexport type TDropdownAlign = 'start' | 'end';\n\nconst props = withDefaults(\n defineProps<{\n items?: TDropdownItem[];\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n size?: TSize;\n label?: string;\n align?: TDropdownAlign;\n }>(),\n {\n items: () => [],\n open: undefined,\n defaultOpen: false,\n disabled: false,\n size: 'md',\n label: '',\n align: 'start',\n },\n);\n\nconst emit = defineEmits<{\n select: [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\ndefineSlots<{\n trigger(props: { isOpen: boolean }): unknown;\n item(props: { item: TDropdownItem; index: number }): unknown;\n}>();\n\nconst attrs = useAttrs();\nconst menuId = createId('t-dropdown');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLElement | null>(null);\nconst itemRefs = ref<Map<string, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\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-dropdown',\n `t-dropdown--${props.size}`,\n {\n 't-dropdown--align-end': props.align === 'end',\n 'is-disabled': props.disabled,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst enabledItems = computed(() => props.items.filter((i) => !i.disabled));\n\nconst openMenu = () => {\n if (props.disabled) return;\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n setValue(true);\n nextTick(() => focusItem(focusedIndex.value));\n};\n\nconst closeMenu = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => {\n if (triggerRef.value) focusFirst(triggerRef.value);\n });\n }\n};\n\nconst toggleMenu = () => {\n if (props.disabled) return;\n if (isOpen.value) {\n closeMenu();\n } else {\n openMenu();\n }\n};\n\nconst selectItem = (item: TDropdownItem) => {\n if (item.disabled) return;\n emit('select', item.value);\n closeMenu(true);\n};\n\nconst focusItem = (index: number) => {\n const item = props.items[index];\n if (!item) return;\n const el = itemRefs.value.get(item.value);\n el?.focus();\n};\n\nconst setItemRef = (el: Element | null, value: string) => {\n if (el instanceof HTMLElement) {\n itemRefs.value.set(value, el);\n } else {\n itemRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.items.length) {\n if (!props.items[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusItem(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 closeMenu();\n return;\n }\n\n if (isActivationKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n openMenu();\n }\n};\n\nconst onItemKeydown = (event: KeyboardEvent, item: TDropdownItem) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeMenu(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectItem(item);\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 = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n focusItem(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[enabledItems.value.length - 1])\n : props.items.length - 1;\n focusItem(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 closeMenu();\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 <span\n ref=\"triggerRef\"\n class=\"t-dropdown__trigger-wrapper\"\n @click=\"toggleMenu\"\n @keydown=\"onTriggerKeydown\"\n >\n <slot\n name=\"trigger\"\n :is-open=\"isOpen\"\n >\n <button\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-dropdown__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? menuId : undefined\"\n aria-haspopup=\"menu\"\n :aria-expanded=\"isOpen\"\n >\n <span class=\"t-dropdown__label\">{{ label }}</span>\n <svg\n class=\"t-dropdown__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 </slot>\n </span>\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"menuId\"\n role=\"menu\"\n class=\"t-dropdown__menu\"\n :aria-label=\"label || undefined\"\n >\n <li\n v-for=\"(item, index) in items\"\n :key=\"item.value\"\n :ref=\"(el) => setItemRef(el as Element | null, item.value)\"\n role=\"menuitem\"\n class=\"t-dropdown__item\"\n :class=\"{\n 'is-disabled': item.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-disabled=\"item.disabled || undefined\"\n :tabindex=\"item.disabled ? -1 : 0\"\n @click=\"selectItem(item)\"\n @keydown=\"onItemKeydown($event, item)\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :index=\"index\"\n >\n {{ item.label }}\n </slot>\n </li>\n </ul>\n </transition>\n </div>\n</template>\n"],"mappings":"4lBAkBA,IAAM,EAAQ,EAqBR,EAAO,EAWP,GAAA,EAAA,EAAA,SAAA,CAAiB,EACjB,GAAA,EAAA,EAAA,SAAA,CAAkB,YAAY,EAC9B,GAAA,EAAA,EAAA,IAAA,CAAkC,IAAI,EACtC,GAAA,EAAA,EAAA,IAAA,CAAqC,IAAI,EACzC,GAAA,EAAA,EAAA,IAAA,CAAyC,IAAI,GAAK,EAClD,GAAA,EAAA,EAAA,IAAA,CAAmB,EAAE,EAErB,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,aACA,eAAe,EAAM,OACrB,CACE,wBAAyB,EAAM,QAAU,MACzC,cAAe,EAAM,SACrB,UAAW,EAAO,KACpB,EACA,EAAM,KACR,CAAC,EAEK,GAAA,EAAA,EAAA,SAAA,KAA2B,EAAM,KAAK,EAEtC,GAAA,EAAA,EAAA,SAAA,KAA8B,EAAM,MAAM,OAAQ,GAAM,CAAC,EAAE,QAAQ,CAAC,EAEpE,MAAiB,CACjB,EAAM,WACV,EAAa,MAAQ,EAAa,MAAM,OAAS,EAC7C,EAAM,MAAM,QAAQ,EAAa,MAAM,EAAE,EACzC,EACJ,EAAS,EAAI,GACb,EAAA,EAAA,SAAA,KAAe,EAAU,EAAa,KAAK,CAAC,EAC9C,EAEM,GAAa,EAAe,KAAU,CAC1C,EAAS,EAAK,EACd,EAAa,MAAQ,GACjB,IACF,EAAA,EAAA,SAAA,KAAe,CACT,EAAW,QAAO,EAAA,EAAA,WAAA,CAAW,EAAW,KAAK,CACnD,CAAC,CAEL,EAEM,MAAmB,CACnB,EAAM,WACN,EAAO,MACT,EAAU,EAEV,EAAS,EAEb,EAEM,EAAc,GAAwB,CACtC,EAAK,WACT,EAAK,SAAU,EAAK,KAAK,EACzB,EAAU,EAAI,EAChB,EAEM,EAAa,GAAkB,CACnC,IAAM,EAAO,EAAM,MAAM,GACpB,GAEL,EADoB,MAAM,IAAI,EAAK,KACnC,CAAA,EAAI,MAAM,CACZ,EAEM,GAAc,EAAoB,IAAkB,CACpD,aAAc,YAChB,EAAS,MAAM,IAAI,EAAO,CAAE,EAE5B,EAAS,MAAM,OAAO,CAAK,CAE/B,EAEM,EAAa,GAAsB,CACvC,IAAI,EAAY,EAAa,MAAQ,EACrC,KAAO,GAAa,GAAK,EAAY,EAAM,MAAM,QAAQ,CACvD,GAAI,CAAC,EAAM,MAAM,EAAU,CAAC,SAAU,CACpC,EAAa,MAAQ,EACrB,EAAU,CAAS,EACnB,MACF,CACA,GAAa,CACf,CACF,EAEM,EAAoB,GAAyB,CAC7C,MAAM,SAEV,KAAA,EAAA,EAAA,YAAA,CAAgB,CAAK,GAAK,EAAO,MAAO,CACtC,EAAM,eAAe,EACrB,EAAU,EACV,MACF,GAEA,EAAA,EAAA,gBAAA,CAAoB,CAAK,GAAK,EAAM,MAAQ,aAAe,EAAM,MAAQ,aACvE,EAAM,eAAe,EACrB,EAAS,EAJX,CAMF,EAEM,GAAiB,EAAsB,IAAwB,CACnE,IAAA,EAAA,EAAA,YAAA,CAAgB,CAAK,EAAG,CACtB,EAAM,eAAe,EACrB,EAAU,EAAI,EACd,MACF,CAEA,IAAA,EAAA,EAAA,gBAAA,CAAoB,CAAK,EAAG,CAC1B,EAAM,eAAe,EACrB,EAAW,CAAI,EACf,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,EAAa,MAAM,OAAS,EAC7C,EAAM,MAAM,QAAQ,EAAa,MAAM,EAAE,EACzC,EACJ,EAAU,EAAa,KAAK,EAC5B,MACF,IAAK,MACH,EAAM,eAAe,EACrB,EAAa,MAAQ,EAAa,MAAM,OAAS,EAC7C,EAAM,MAAM,QAAQ,EAAa,MAAM,EAAa,MAAM,OAAS,EAAE,EACrE,EAAM,MAAM,OAAS,EACzB,EAAU,EAAa,KAAK,EAC5B,MACF,QACE,KACJ,CACF,EAEM,EAAyB,GAAwB,CACrD,GAAI,CAAC,EAAO,MAAO,OACnB,IAAM,EAAS,EAAM,OACf,aAAkB,OACpB,EAAQ,OAAO,SAAS,CAAM,GAClC,EAAU,EACZ,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,qDA8EO,MAAA,SAzEA,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,oCAoCZ,OAAA,SAjCD,aAAJ,IAAI,EACJ,MAAM,8BACL,QAAO,EACP,UAAS,qBA6BH,EAAA,OAAA,UAAA,CAzBJ,QAAA,EAAA,EAAA,MAAA,CAAS,CAAA,CAAM,MAyBX,EAAA,EAAA,EAAA,mBAAA,CADI,UAAA,EAAA,EAAA,WAAA,CArBC,EAqBD,MArBa,CACpB,KAAK,SACL,MAAM,sBACL,SAAU,EAAA,SACV,iBAAA,EAAA,EAAA,MAAA,CAAe,CAAA,GAAA,EAAA,EAAA,MAAA,CAAS,CAAA,EAAS,IAAA,GAClC,gBAAc,OACb,iBAAA,EAAA,EAAA,MAAA,CAAe,CAAA,8BAEkC,OAAlD,GAAA,EAAA,EAAA,gBAAA,CAAmC,EAAA,KAAK,EAAA,CAAA,EAAA,AAAA,EAAA,MAAA,EAAA,EAAA,mBAAA,CAYlC,MAAA,CAVJ,MAAM,sBACN,QAAQ,YACR,KAAK,OACL,OAAO,eACP,eAAa,IACb,iBAAe,QACf,kBAAgB,QAChB,cAAY,kCAEuB,WAAA,CAAzB,OAAO,eAAe,CAAA,CAAA,EAAA,EAAA,CAAA,EAAA,GAAA,CAAA,CAAA,CAAA,CAAA,EAAA,GAAA,GAAA,EAAA,EAAA,YAAA,CAqC3B,EAAA,WAAA,CAhCD,KAAK,QAAQ,EAAA,2BA+BlB,EAAA,EAAA,EAAA,MAAA,CA7BG,CAAA,GAAM,CAAK,EAAA,WAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CA6Bd,KAAA,OA5BF,IAAA,EAAA,EAAA,MAAA,CAAI,CAAA,EACL,KAAK,OACL,MAAM,mBACL,aAAY,EAAA,OAAS,IAAA,mDAwBjB,EAAA,SAAA,MAAA,EAAA,EAAA,WAAA,CArBqB,EAAA,OAAhB,EAAM,gDAqBX,KAAA,CApBF,IAAK,EAAK,iBACV,IAAM,GAAO,EAAW,EAAsB,EAAK,KAAK,EACzD,KAAK,WACL,OAAA,EAAA,EAAA,eAAA,CAAK,CAAC,mBAAkB,eACa,EAAK,sBAAoC,IAAU,EAAA,SAIvF,gBAAe,EAAK,UAAY,IAAA,GAChC,SAAU,EAAK,SAAQ,GAAA,EACvB,QAAK,GAAE,EAAW,CAAI,EACtB,UAAO,GAAE,EAAc,EAAQ,CAAI,qBAQ7B,EAAA,OAAA,OAAA,CAJE,OACC,aAGH,EAAA,EAAA,EAAA,gBAAA,EAAA,EAAA,EAAA,gBAAA,CADF,EAAK,KAAK,EAAA,CAAA,CAAA,CAAA,CAAA,EAAA,GAAA,CAAA"}
@@ -1,8 +1,8 @@
1
1
  import { useControllableOpen as e } from "../composables/useControllableOpen.js";
2
- import { Fragment as t, Transition as n, computed as r, createCommentVNode as i, createElementBlock as a, createElementVNode as o, createTextVNode as s, createVNode as c, defineComponent as l, mergeProps as ee, nextTick as u, normalizeClass as d, normalizeStyle as f, onBeforeUnmount as p, openBlock as m, ref as h, renderList as g, renderSlot as _, toDisplayString as v, toRef as te, unref as y, useAttrs as b, watch as x, withCtx as S } from "vue";
3
- import { createId as C, isActivationKey as w, isEscapeKey as T } from "@treeui/utils";
2
+ import { Fragment as t, Transition as n, computed as r, createCommentVNode as ee, createElementBlock as i, createElementVNode as a, createTextVNode as o, createVNode as s, defineComponent as c, mergeProps as l, nextTick as u, normalizeClass as d, normalizeStyle as f, onBeforeUnmount as p, openBlock as m, ref as h, renderList as g, renderSlot as _, toDisplayString as v, toRef as y, unref as b, useAttrs as x, watch as S, withCtx as C } from "vue";
3
+ import { createId as w, focusFirst as te, isActivationKey as T, isEscapeKey as E } from "@treeui/utils";
4
4
  //#region src/components/TDropdown.vue?vue&type=script&setup=true&lang.ts
5
- var E = ["data-state"], D = { class: "t-dropdown__trigger-wrapper" }, O = [
5
+ var D = ["data-state"], O = [
6
6
  "disabled",
7
7
  "aria-controls",
8
8
  "aria-expanded"
@@ -11,7 +11,7 @@ var E = ["data-state"], D = { class: "t-dropdown__trigger-wrapper" }, O = [
11
11
  "tabindex",
12
12
  "onClick",
13
13
  "onKeydown"
14
- ], M = /*@__PURE__*/ l({
14
+ ], M = /*@__PURE__*/ c({
15
15
  inheritAttrs: !1,
16
16
  __name: "TDropdown",
17
17
  props: {
@@ -37,11 +37,11 @@ var E = ["data-state"], D = { class: "t-dropdown__trigger-wrapper" }, O = [
37
37
  "update:open",
38
38
  "open-change"
39
39
  ],
40
- setup(l, { emit: M }) {
41
- let N = l, P = M, F = b(), I = C("t-dropdown"), L = h(null), R = h(null), z = h(/* @__PURE__ */ new Map()), B = h(-1), V = r(() => {
40
+ setup(c, { emit: M }) {
41
+ let N = c, P = M, F = x(), I = w("t-dropdown"), L = h(null), R = h(null), z = h(/* @__PURE__ */ new Map()), B = h(-1), V = r(() => {
42
42
  let { class: e, style: t, ...n } = F;
43
43
  return n;
44
- }), { value: H, setValue: U } = e(te(N, "open"), N.defaultOpen, (e) => {
44
+ }), { value: H, setValue: U } = e(y(N, "open"), N.defaultOpen, (e) => {
45
45
  P("update:open", e), P("open-change", e);
46
46
  }), W = r(() => [
47
47
  "t-dropdown",
@@ -55,9 +55,11 @@ var E = ["data-state"], D = { class: "t-dropdown__trigger-wrapper" }, O = [
55
55
  ]), G = r(() => F.style), K = r(() => N.items.filter((e) => !e.disabled)), q = () => {
56
56
  N.disabled || (B.value = K.value.length > 0 ? N.items.indexOf(K.value[0]) : 0, U(!0), u(() => Z(B.value)));
57
57
  }, J = (e = !1) => {
58
- U(!1), B.value = -1, e && u(() => R.value?.focus());
58
+ U(!1), B.value = -1, e && u(() => {
59
+ R.value && te(R.value);
60
+ });
59
61
  }, Y = () => {
60
- H.value ? J() : q();
62
+ N.disabled || (H.value ? J() : q());
61
63
  }, X = (e) => {
62
64
  e.disabled || (P("select", e.value), J(!0));
63
65
  }, Z = (e) => {
@@ -76,18 +78,18 @@ var E = ["data-state"], D = { class: "t-dropdown__trigger-wrapper" }, O = [
76
78
  }
77
79
  }, re = (e) => {
78
80
  if (!N.disabled) {
79
- if (T(e) && H.value) {
81
+ if (E(e) && H.value) {
80
82
  e.preventDefault(), J();
81
83
  return;
82
84
  }
83
- (w(e) || e.key === "ArrowDown" || e.key === "ArrowUp") && (e.preventDefault(), q());
85
+ (T(e) || e.key === "ArrowDown" || e.key === "ArrowUp") && (e.preventDefault(), q());
84
86
  }
85
87
  }, ie = (e, t) => {
86
- if (T(e)) {
88
+ if (E(e)) {
87
89
  e.preventDefault(), J(!0);
88
90
  return;
89
91
  }
90
- if (w(e)) {
92
+ if (T(e)) {
91
93
  e.preventDefault(), X(t);
92
94
  return;
93
95
  }
@@ -111,29 +113,30 @@ var E = ["data-state"], D = { class: "t-dropdown__trigger-wrapper" }, O = [
111
113
  let t = e.target;
112
114
  t instanceof Node && (L.value?.contains(t) || J());
113
115
  };
114
- return x(H, (e) => {
116
+ return S(H, (e) => {
115
117
  e ? document.addEventListener("pointerdown", $) : document.removeEventListener("pointerdown", $);
116
118
  }), p(() => {
117
119
  document.removeEventListener("pointerdown", $);
118
- }), (e, r) => (m(), a("div", {
120
+ }), (e, r) => (m(), i("div", {
119
121
  ref_key: "rootRef",
120
122
  ref: L,
121
123
  class: d(W.value),
122
124
  style: f(G.value),
123
- "data-state": y(H) ? "open" : "closed"
124
- }, [o("span", D, [_(e.$slots, "trigger", { isOpen: y(H) }, () => [o("button", ee({
125
+ "data-state": b(H) ? "open" : "closed"
126
+ }, [a("span", {
125
127
  ref_key: "triggerRef",
126
- ref: R
127
- }, V.value, {
128
+ ref: R,
129
+ class: "t-dropdown__trigger-wrapper",
130
+ onClick: Y,
131
+ onKeydown: re
132
+ }, [_(e.$slots, "trigger", { isOpen: b(H) }, () => [a("button", l(V.value, {
128
133
  type: "button",
129
134
  class: "t-dropdown__trigger",
130
- disabled: l.disabled,
131
- "aria-controls": y(H) ? y(I) : void 0,
135
+ disabled: c.disabled,
136
+ "aria-controls": b(H) ? b(I) : void 0,
132
137
  "aria-haspopup": "menu",
133
- "aria-expanded": y(H),
134
- onClick: Y,
135
- onKeydown: re
136
- }), [o("span", k, v(l.label), 1), r[0] ||= o("svg", {
138
+ "aria-expanded": b(H)
139
+ }), [a("span", k, v(c.label), 1), r[0] ||= a("svg", {
137
140
  class: "t-dropdown__chevron",
138
141
  viewBox: "0 0 16 16",
139
142
  fill: "none",
@@ -142,14 +145,14 @@ var E = ["data-state"], D = { class: "t-dropdown__trigger-wrapper" }, O = [
142
145
  "stroke-linecap": "round",
143
146
  "stroke-linejoin": "round",
144
147
  "aria-hidden": "true"
145
- }, [o("polyline", { points: "4 6 8 10 12 6" })], -1)], 16, O)])]), c(n, { name: "t-fade" }, {
146
- default: S(() => [y(H) && !l.disabled ? (m(), a("ul", {
148
+ }, [a("polyline", { points: "4 6 8 10 12 6" })], -1)], 16, O)])], 544), s(n, { name: "t-fade" }, {
149
+ default: C(() => [b(H) && !c.disabled ? (m(), i("ul", {
147
150
  key: 0,
148
- id: y(I),
151
+ id: b(I),
149
152
  role: "menu",
150
153
  class: "t-dropdown__menu",
151
- "aria-label": l.label || void 0
152
- }, [(m(!0), a(t, null, g(l.items, (t, n) => (m(), a("li", {
154
+ "aria-label": c.label || void 0
155
+ }, [(m(!0), i(t, null, g(c.items, (t, n) => (m(), i("li", {
153
156
  key: t.value,
154
157
  ref_for: !0,
155
158
  ref: (e) => ne(e, t.value),
@@ -165,9 +168,9 @@ var E = ["data-state"], D = { class: "t-dropdown__trigger-wrapper" }, O = [
165
168
  }, [_(e.$slots, "item", {
166
169
  item: t,
167
170
  index: n
168
- }, () => [s(v(t.label), 1)])], 42, j))), 128))], 8, A)) : i("", !0)]),
171
+ }, () => [o(v(t.label), 1)])], 42, j))), 128))], 8, A)) : ee("", !0)]),
169
172
  _: 3
170
- })], 14, E));
173
+ })], 14, D));
171
174
  }
172
175
  });
173
176
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"TDropdown.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../src/components/TDropdown.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';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TDropdownItem {\n label: string;\n value: string;\n disabled?: boolean;\n}\n\nexport type TDropdownAlign = 'start' | 'end';\n\nconst props = withDefaults(\n defineProps<{\n items?: TDropdownItem[];\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n size?: TSize;\n label?: string;\n align?: TDropdownAlign;\n }>(),\n {\n items: () => [],\n open: undefined,\n defaultOpen: false,\n disabled: false,\n size: 'md',\n label: '',\n align: 'start',\n },\n);\n\nconst emit = defineEmits<{\n select: [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\ndefineSlots<{\n trigger(props: { isOpen: boolean }): unknown;\n item(props: { item: TDropdownItem; index: number }): unknown;\n}>();\n\nconst attrs = useAttrs();\nconst menuId = createId('t-dropdown');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst itemRefs = ref<Map<string, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\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-dropdown',\n `t-dropdown--${props.size}`,\n {\n 't-dropdown--align-end': props.align === 'end',\n 'is-disabled': props.disabled,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst enabledItems = computed(() => props.items.filter((i) => !i.disabled));\n\nconst openMenu = () => {\n if (props.disabled) return;\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n setValue(true);\n nextTick(() => focusItem(focusedIndex.value));\n};\n\nconst closeMenu = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => triggerRef.value?.focus());\n }\n};\n\nconst toggleMenu = () => {\n if (isOpen.value) {\n closeMenu();\n } else {\n openMenu();\n }\n};\n\nconst selectItem = (item: TDropdownItem) => {\n if (item.disabled) return;\n emit('select', item.value);\n closeMenu(true);\n};\n\nconst focusItem = (index: number) => {\n const item = props.items[index];\n if (!item) return;\n const el = itemRefs.value.get(item.value);\n el?.focus();\n};\n\nconst setItemRef = (el: Element | null, value: string) => {\n if (el instanceof HTMLElement) {\n itemRefs.value.set(value, el);\n } else {\n itemRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.items.length) {\n if (!props.items[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusItem(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 closeMenu();\n return;\n }\n\n if (isActivationKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n openMenu();\n }\n};\n\nconst onItemKeydown = (event: KeyboardEvent, item: TDropdownItem) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeMenu(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectItem(item);\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 = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n focusItem(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[enabledItems.value.length - 1])\n : props.items.length - 1;\n focusItem(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 closeMenu();\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 <span class=\"t-dropdown__trigger-wrapper\">\n <slot\n name=\"trigger\"\n :is-open=\"isOpen\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-dropdown__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? menuId : undefined\"\n aria-haspopup=\"menu\"\n :aria-expanded=\"isOpen\"\n @click=\"toggleMenu\"\n @keydown=\"onTriggerKeydown\"\n >\n <span class=\"t-dropdown__label\">{{ label }}</span>\n <svg\n class=\"t-dropdown__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 </slot>\n </span>\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"menuId\"\n role=\"menu\"\n class=\"t-dropdown__menu\"\n :aria-label=\"label || undefined\"\n >\n <li\n v-for=\"(item, index) in items\"\n :key=\"item.value\"\n :ref=\"(el) => setItemRef(el as Element | null, item.value)\"\n role=\"menuitem\"\n class=\"t-dropdown__item\"\n :class=\"{\n 'is-disabled': item.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-disabled=\"item.disabled || undefined\"\n :tabindex=\"item.disabled ? -1 : 0\"\n @click=\"selectItem(item)\"\n @keydown=\"onItemKeydown($event, item)\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :index=\"index\"\n >\n {{ item.label }}\n </slot>\n </li>\n </ul>\n </transition>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"TDropdown.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../src/components/TDropdown.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { createId, focusFirst, 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';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TDropdownItem {\n label: string;\n value: string;\n disabled?: boolean;\n}\n\nexport type TDropdownAlign = 'start' | 'end';\n\nconst props = withDefaults(\n defineProps<{\n items?: TDropdownItem[];\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n size?: TSize;\n label?: string;\n align?: TDropdownAlign;\n }>(),\n {\n items: () => [],\n open: undefined,\n defaultOpen: false,\n disabled: false,\n size: 'md',\n label: '',\n align: 'start',\n },\n);\n\nconst emit = defineEmits<{\n select: [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\ndefineSlots<{\n trigger(props: { isOpen: boolean }): unknown;\n item(props: { item: TDropdownItem; index: number }): unknown;\n}>();\n\nconst attrs = useAttrs();\nconst menuId = createId('t-dropdown');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLElement | null>(null);\nconst itemRefs = ref<Map<string, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\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-dropdown',\n `t-dropdown--${props.size}`,\n {\n 't-dropdown--align-end': props.align === 'end',\n 'is-disabled': props.disabled,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst enabledItems = computed(() => props.items.filter((i) => !i.disabled));\n\nconst openMenu = () => {\n if (props.disabled) return;\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n setValue(true);\n nextTick(() => focusItem(focusedIndex.value));\n};\n\nconst closeMenu = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => {\n if (triggerRef.value) focusFirst(triggerRef.value);\n });\n }\n};\n\nconst toggleMenu = () => {\n if (props.disabled) return;\n if (isOpen.value) {\n closeMenu();\n } else {\n openMenu();\n }\n};\n\nconst selectItem = (item: TDropdownItem) => {\n if (item.disabled) return;\n emit('select', item.value);\n closeMenu(true);\n};\n\nconst focusItem = (index: number) => {\n const item = props.items[index];\n if (!item) return;\n const el = itemRefs.value.get(item.value);\n el?.focus();\n};\n\nconst setItemRef = (el: Element | null, value: string) => {\n if (el instanceof HTMLElement) {\n itemRefs.value.set(value, el);\n } else {\n itemRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.items.length) {\n if (!props.items[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusItem(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 closeMenu();\n return;\n }\n\n if (isActivationKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n openMenu();\n }\n};\n\nconst onItemKeydown = (event: KeyboardEvent, item: TDropdownItem) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeMenu(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectItem(item);\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 = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n focusItem(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[enabledItems.value.length - 1])\n : props.items.length - 1;\n focusItem(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 closeMenu();\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 <span\n ref=\"triggerRef\"\n class=\"t-dropdown__trigger-wrapper\"\n @click=\"toggleMenu\"\n @keydown=\"onTriggerKeydown\"\n >\n <slot\n name=\"trigger\"\n :is-open=\"isOpen\"\n >\n <button\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-dropdown__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? menuId : undefined\"\n aria-haspopup=\"menu\"\n :aria-expanded=\"isOpen\"\n >\n <span class=\"t-dropdown__label\">{{ label }}</span>\n <svg\n class=\"t-dropdown__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 </slot>\n </span>\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"menuId\"\n role=\"menu\"\n class=\"t-dropdown__menu\"\n :aria-label=\"label || undefined\"\n >\n <li\n v-for=\"(item, index) in items\"\n :key=\"item.value\"\n :ref=\"(el) => setItemRef(el as Element | null, item.value)\"\n role=\"menuitem\"\n class=\"t-dropdown__item\"\n :class=\"{\n 'is-disabled': item.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-disabled=\"item.disabled || undefined\"\n :tabindex=\"item.disabled ? -1 : 0\"\n @click=\"selectItem(item)\"\n @keydown=\"onItemKeydown($event, item)\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :index=\"index\"\n >\n {{ item.label }}\n </slot>\n </li>\n </ul>\n </transition>\n </div>\n</template>\n"],"mappings":"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"}