@auronui/vue 1.0.13 → 1.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +15 -14
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/components/tabs/TabList.js.map +1 -1
- package/dist/components/tabs/TabList.vue_vue_type_script_setup_true_lang.js +15 -14
- package/dist/components/tabs/TabList.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/index.d.ts +0 -192
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabList.js","names":[],"sources":["../../../src/components/tabs/TabList.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, nextTick, onMounted, watch } from 'vue'\nimport { useTemplateRef } from 'vue'\nimport { TabsList } from 'reka-ui'\nimport { useResizeObserver, onClickOutside } from '@vueuse/core'\nimport { composeClassName } from '../../utils/composeClassName'\nimport { useTabsInject } from './tabs.context'\nimport Button from '../button/Button.vue'\n\nconst props = defineProps<{\n loop?: boolean\n overflow?: 'arrows' | 'dropdown'\n class?: string\n}>()\n\nconst ctx = useTabsInject()\n\n// ── Arrows mode ─────────────────────────────────────────────────────────────\nconst scrollWrapperEl = useTemplateRef<HTMLElement>('scrollWrapperEl')\nconst canScrollLeft = ref(false)\nconst canScrollRight = ref(false)\n\nfunction updateScrollButtons() {\n const el = scrollWrapperEl.value\n if (!el) { canScrollLeft.value = false; canScrollRight.value = false; return }\n canScrollLeft.value = el.scrollLeft > 1\n canScrollRight.value = el.scrollLeft + el.clientWidth < el.scrollWidth - 1\n}\n\nfunction scrollTabs(dir: 'left' | 'right') {\n const el = scrollWrapperEl.value\n if (!el) return\n el.scrollBy({ left: dir === 'left' ? -200 : 200, behavior: 'smooth' })\n // Poll briefly after smooth scroll starts so button states update\n setTimeout(updateScrollButtons, 150)\n setTimeout(updateScrollButtons, 350)\n}\n\nwatch(scrollWrapperEl, (el, oldEl) => {\n if (oldEl) oldEl.removeEventListener('scroll', updateScrollButtons)\n if (el) {\n el.addEventListener('scroll', updateScrollButtons, { passive: true })\n nextTick(updateScrollButtons)\n }\n}, { immediate: true })\n\nuseResizeObserver(scrollWrapperEl, () => nextTick(updateScrollButtons))\n\n// ── Dropdown mode ────────────────────────────────────────────────────────────\ninterface OverflowTab {\n value: string\n label: string\n disabled: boolean\n}\n\nconst containerEl = useTemplateRef<HTMLElement>('containerEl')\n// Button component ref — use .$el to reach the underlying DOM element for offsetWidth\nconst moreBtnEl = useTemplateRef<InstanceType<typeof Button>>('moreBtnEl')\nconst dropdownEl = useTemplateRef<HTMLElement>('dropdownEl')\n\nconst hiddenTabs = ref<OverflowTab[]>([])\nconst dropdownOpen = ref(false)\nconst hasOverflow = computed(() => hiddenTabs.value.length > 0)\n// Pre-measured natural width of the more button (measured once on mount before it's visible)\nlet moreBtnNaturalWidth = 48\n\nonClickOutside(dropdownEl, () => { dropdownOpen.value = false })\n\nfunction computeOverflow() {\n if (!containerEl.value) return\n\n const allTabs = Array.from(\n containerEl.value.querySelectorAll('[data-tab-value]'),\n ) as HTMLElement[]\n\n // Reveal all tabs first\n allTabs.forEach(t => t.removeAttribute('data-overflow-hidden'))\n\n // Tabs use w-full and shrink to share the container width, so offsetWidth after\n // a normal render would be containerWidth/n — useless for overflow detection.\n // Force each tab to its natural content width for measurement only (no paint flash:\n // all DOM reads/writes happen synchronously within this JS task before the next frame).\n const listEl = containerEl.value.querySelector('[role=\"tablist\"]') as HTMLElement | null\n if (listEl) {\n listEl.style.overflow = 'visible'\n allTabs.forEach(t => { t.style.flexShrink = '0'; t.style.width = 'auto' })\n void listEl.offsetWidth // force reflow so offsetWidth reads below are accurate\n }\n\n const containerWidth = containerEl.value.clientWidth\n const tabWidths = allTabs.map(t => t.offsetWidth)\n const totalWidth = tabWidths.reduce((sum, w) => sum + w, 0)\n\n // Restore layout before any early-return so tabs always look correct\n if (listEl) {\n listEl.style.overflow = ''\n allTabs.forEach(t => { t.style.flexShrink = ''; t.style.width = '' })\n }\n\n if (totalWidth <= containerWidth) {\n hiddenTabs.value = []\n return\n }\n\n // More button is in-flow (display:none when no overflow, display:flex when visible).\n // Use the pre-measured natural width so the calculation is accurate on the first run\n // before the button becomes visible.\n const available = containerWidth - moreBtnNaturalWidth\n\n let accumulated = 0\n const newHidden: OverflowTab[] = []\n const visibleEls: HTMLElement[] = []\n\n for (let i = 0; i < allTabs.length; i++) {\n const tab = allTabs[i]\n const w = tabWidths[i]\n if (accumulated + w <= available) {\n accumulated += w\n visibleEls.push(tab)\n } else {\n newHidden.push({\n value: tab.getAttribute('data-tab-value') ?? '',\n label: tab.textContent?.trim() ?? '',\n disabled: tab.hasAttribute('data-disabled') || tab.getAttribute('aria-disabled') === 'true',\n })\n tab.setAttribute('data-overflow-hidden', '')\n }\n }\n\n // If the active tab ended up hidden, swap it with the last visible tab\n const activeValue = ctx.currentValue.value\n if (activeValue) {\n const hiddenActiveIdx = newHidden.findIndex(t => t.value === activeValue)\n if (hiddenActiveIdx !== -1 && visibleEls.length > 0) {\n const displacedEl = visibleEls[visibleEls.length - 1]\n const activeEl = allTabs.find(t => t.getAttribute('data-tab-value') === activeValue)\n\n if (displacedEl && activeEl) {\n // Swap: make displaced tab hidden, active tab visible\n displacedEl.setAttribute('data-overflow-hidden', '')\n activeEl.removeAttribute('data-overflow-hidden')\n\n const displaced: OverflowTab = {\n value: displacedEl.getAttribute('data-tab-value') ?? '',\n label: displacedEl.textContent?.trim() ?? '',\n disabled: displacedEl.hasAttribute('data-disabled') || displacedEl.getAttribute('aria-disabled') === 'true',\n }\n newHidden.splice(hiddenActiveIdx, 1)\n newHidden.unshift(displaced)\n }\n }\n }\n\n hiddenTabs.value = newHidden\n}\n\nuseResizeObserver(containerEl, () => nextTick(computeOverflow))\nonMounted(() => {\n // Pre-measure the more button's natural width before it becomes visible (display:none).\n // Temporarily show it, read offsetWidth, then hide again — happens before first paint.\n const btnEl = (moreBtnEl.value as InstanceType<typeof Button> | null)?.$el as HTMLElement | null\n if (btnEl) {\n btnEl.style.display = 'flex'\n void btnEl.offsetWidth\n moreBtnNaturalWidth = btnEl.offsetWidth\n btnEl.style.display = ''\n }\n nextTick(computeOverflow)\n})\n\n// Recompute when the active tab changes so the active tab is always visible\nwatch(() => ctx.currentValue.value, () => {\n if (props.overflow === 'dropdown') nextTick(computeOverflow)\n})\n\n// When overflow state first transitions false→true the more button enters the flex flow,\n// narrowing the container. Re-run once so the tab count reflects the reduced available space.\nwatch(hasOverflow, () => {\n if (props.overflow === 'dropdown') nextTick(computeOverflow)\n})\n\nfunction selectOverflowTab(value: string) {\n ctx.changeTab(value)\n dropdownOpen.value = false\n}\n</script>\n\n<template>\n <!-- ── Default (no overflow behaviour) ───────────────────────────────────── -->\n <TabsList\n v-if=\"!props.overflow\"\n :loop=\"props.loop ?? true\"\n :class=\"composeClassName(ctx.slotFns.value.tabList(), props.class)\"\n >\n <slot />\n </TabsList>\n\n <!-- ── Arrows mode ────────────────────────────────────────────────────────── -->\n <div\n v-else-if=\"props.overflow === 'arrows'\"\n class=\"tabs__list-container tabs__list-container--arrows\"\n :class=\"{ 'has-left': canScrollLeft, 'has-right': canScrollRight }\"\n >\n <Button\n variant=\"secondary\"\n size=\"sm\"\n radius=\"full\"\n :is-icon-only=\"true\"\n :class=\"composeClassName('tabs__arrow tabs__arrow--left', canScrollLeft && 'is-visible')\"\n aria-label=\"Scroll tabs left\"\n tabindex=\"-1\"\n @click=\"scrollTabs('left')\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M9 11L5 7L9 3\" stroke=\"currentColor\" stroke-width=\"1.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </Button>\n\n <div ref=\"scrollWrapperEl\" class=\"tabs__scroll-wrapper\">\n <TabsList\n :loop=\"props.loop ?? true\"\n :class=\"composeClassName(ctx.slotFns.value.tabList(), 'tabs__list--scroll', props.class)\"\n >\n <slot />\n </TabsList>\n </div>\n\n <Button\n variant=\"secondary\"\n size=\"sm\"\n radius=\"full\"\n :is-icon-only=\"true\"\n :class=\"composeClassName('tabs__arrow tabs__arrow--right', canScrollRight && 'is-visible')\"\n aria-label=\"Scroll tabs right\"\n tabindex=\"-1\"\n @click=\"scrollTabs('right')\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M5 3L9 7L5 11\" stroke=\"currentColor\" stroke-width=\"1.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </Button>\n </div>\n\n <!-- ── Dropdown mode ──────────────────────────────────────────────────────── -->\n <div\n v-else-if=\"props.overflow === 'dropdown'\"\n ref=\"containerEl\"\n class=\"tabs__list-container tabs__list-container--dropdown\"\n >\n <TabsList\n :loop=\"props.loop ?? true\"\n :class=\"composeClassName(ctx.slotFns.value.tabList(), 'tabs__list--clipped', props.class)\"\n >\n <slot />\n </TabsList>\n\n <!-- Always rendered so offsetWidth is measurable; visibility toggled via CSS -->\n <div\n ref=\"dropdownEl\"\n class=\"tabs__more\"\n :class=\"{ 'tabs__more--visible': hasOverflow }\"\n >\n <Button\n ref=\"moreBtnEl\"\n variant=\"secondary\"\n size=\"sm\"\n radius=\"full\"\n class=\"tabs__more-btn\"\n :aria-expanded=\"dropdownOpen\"\n aria-haspopup=\"menu\"\n @click=\"dropdownOpen = !dropdownOpen\"\n >\n +{{ hiddenTabs.length }}\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M2 4L6 8L10 4\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </Button>\n\n <div v-if=\"dropdownOpen\" class=\"tabs__overflow-menu\" role=\"menu\">\n <Button\n v-for=\"tab in hiddenTabs\"\n :key=\"tab.value\"\n variant=\"ghost\"\n radius=\"lg\"\n class=\"tabs__overflow-item\"\n role=\"menuitem\"\n :disabled=\"tab.disabled\"\n @click=\"selectOverflowTab(tab.value)\"\n >\n {{ tab.label }}\n </Button>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"TabList.js","names":[],"sources":["../../../src/components/tabs/TabList.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, nextTick, onMounted, watch } from 'vue'\nimport { useTemplateRef } from 'vue'\nimport { TabsList } from 'reka-ui'\nimport { useResizeObserver, onClickOutside } from '@vueuse/core'\nimport { composeClassName } from '../../utils/composeClassName'\nimport { useTabsInject } from './tabs.context'\nimport Button from '../button/Button.vue'\n\nconst props = defineProps<{\n loop?: boolean\n overflow?: 'arrows' | 'dropdown'\n class?: string\n}>()\n\nconst ctx = useTabsInject()\n\n// ── Arrows mode ─────────────────────────────────────────────────────────────\nconst scrollWrapperEl = useTemplateRef<HTMLElement>('scrollWrapperEl')\nconst canScrollLeft = ref(false)\nconst canScrollRight = ref(false)\n\nfunction updateScrollButtons() {\n const el = scrollWrapperEl.value\n if (!el) { canScrollLeft.value = false; canScrollRight.value = false; return }\n canScrollLeft.value = el.scrollLeft > 1\n canScrollRight.value = el.scrollLeft + el.clientWidth < el.scrollWidth - 1\n}\n\nfunction scrollTabs(dir: 'left' | 'right') {\n const el = scrollWrapperEl.value\n if (!el) return\n el.scrollBy({ left: dir === 'left' ? -200 : 200, behavior: 'smooth' })\n // Poll briefly after smooth scroll starts so button states update\n setTimeout(updateScrollButtons, 150)\n setTimeout(updateScrollButtons, 350)\n}\n\nwatch(scrollWrapperEl, (el, oldEl) => {\n if (oldEl) oldEl.removeEventListener('scroll', updateScrollButtons)\n if (el) {\n el.addEventListener('scroll', updateScrollButtons, { passive: true })\n nextTick(updateScrollButtons)\n }\n}, { immediate: true })\n\nuseResizeObserver(scrollWrapperEl, () => nextTick(updateScrollButtons))\n\n// ── Dropdown mode ────────────────────────────────────────────────────────────\ninterface OverflowTab {\n value: string\n label: string\n disabled: boolean\n}\n\nconst containerEl = useTemplateRef<HTMLElement>('containerEl')\nconst dropdownEl = useTemplateRef<HTMLElement>('dropdownEl')\n\nconst hiddenTabs = ref<OverflowTab[]>([])\nconst dropdownOpen = ref(false)\nconst hasOverflow = computed(() => hiddenTabs.value.length > 0)\n\nonClickOutside(dropdownEl, () => { dropdownOpen.value = false })\n\nfunction computeOverflow() {\n if (!containerEl.value) return\n\n const allTabs = Array.from(\n containerEl.value.querySelectorAll('[data-tab-value]'),\n ) as HTMLElement[]\n\n // Reveal all tabs first\n allTabs.forEach(t => t.removeAttribute('data-overflow-hidden'))\n\n // Tabs use w-full and shrink to share the container width, so offsetWidth after\n // a normal render would be containerWidth/n — useless for overflow detection.\n // Force each tab to its natural content width for measurement only (no paint flash:\n // all DOM reads/writes happen synchronously within this JS task before the next frame).\n const listEl = containerEl.value.querySelector('[role=\"tablist\"]') as HTMLElement | null\n if (listEl) {\n listEl.style.overflow = 'visible'\n allTabs.forEach(t => { t.style.flexShrink = '0'; t.style.width = 'auto' })\n void listEl.offsetWidth // force reflow so offsetWidth reads below are accurate\n }\n\n // Measure the more button's real width by temporarily revealing its wrapper.\n // The wrapper is display:none when there's no overflow, so we can't rely on a\n // pre-measured value — measure it here while the (always-visible) container holds it.\n let moreWidth = 0\n const moreEl = dropdownEl.value\n if (moreEl) {\n const prevDisplay = moreEl.style.display\n moreEl.style.display = 'flex'\n void moreEl.offsetWidth\n moreWidth = moreEl.offsetWidth\n moreEl.style.display = prevDisplay\n }\n\n // clientWidth includes the container's horizontal padding; the flex children only\n // get the content box. Subtract padding so measurements compare against real space.\n const cs = getComputedStyle(containerEl.value)\n const padX = parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight)\n const gap = parseFloat(cs.columnGap) || 0\n const contentWidth = containerEl.value.clientWidth - padX\n\n const tabWidths = allTabs.map(t => t.offsetWidth)\n const totalWidth = tabWidths.reduce((sum, w) => sum + w, 0)\n\n // Restore layout before any early-return so tabs always look correct\n if (listEl) {\n listEl.style.overflow = ''\n allTabs.forEach(t => { t.style.flexShrink = ''; t.style.width = '' })\n }\n\n if (totalWidth <= contentWidth) {\n hiddenTabs.value = []\n return\n }\n\n // When the more button is shown it sits beside the clipped list, separated by `gap`.\n // Reserve its width + the gap (+1px sub-pixel safety) so the last visible tab can\n // never extend under the button.\n const available = contentWidth - moreWidth - gap - 1\n\n let accumulated = 0\n const newHidden: OverflowTab[] = []\n const visibleEls: HTMLElement[] = []\n\n for (let i = 0; i < allTabs.length; i++) {\n const tab = allTabs[i]\n const w = tabWidths[i]\n if (accumulated + w <= available) {\n accumulated += w\n visibleEls.push(tab)\n } else {\n newHidden.push({\n value: tab.getAttribute('data-tab-value') ?? '',\n label: tab.textContent?.trim() ?? '',\n disabled: tab.hasAttribute('data-disabled') || tab.getAttribute('aria-disabled') === 'true',\n })\n tab.setAttribute('data-overflow-hidden', '')\n }\n }\n\n // If the active tab ended up hidden, swap it with the last visible tab\n const activeValue = ctx.currentValue.value\n if (activeValue) {\n const hiddenActiveIdx = newHidden.findIndex(t => t.value === activeValue)\n if (hiddenActiveIdx !== -1 && visibleEls.length > 0) {\n const displacedEl = visibleEls[visibleEls.length - 1]\n const activeEl = allTabs.find(t => t.getAttribute('data-tab-value') === activeValue)\n\n if (displacedEl && activeEl) {\n // Swap: make displaced tab hidden, active tab visible\n displacedEl.setAttribute('data-overflow-hidden', '')\n activeEl.removeAttribute('data-overflow-hidden')\n\n const displaced: OverflowTab = {\n value: displacedEl.getAttribute('data-tab-value') ?? '',\n label: displacedEl.textContent?.trim() ?? '',\n disabled: displacedEl.hasAttribute('data-disabled') || displacedEl.getAttribute('aria-disabled') === 'true',\n }\n newHidden.splice(hiddenActiveIdx, 1)\n newHidden.unshift(displaced)\n }\n }\n }\n\n hiddenTabs.value = newHidden\n}\n\nuseResizeObserver(containerEl, () => nextTick(computeOverflow))\nonMounted(() => {\n nextTick(computeOverflow)\n})\n\n// Recompute when the active tab changes so the active tab is always visible\nwatch(() => ctx.currentValue.value, () => {\n if (props.overflow === 'dropdown') nextTick(computeOverflow)\n})\n\n// Safety re-check when overflow toggles. computeOverflow already reserves the more\n// button's width up front, so this is idempotent — it just guards against layout\n// settling (e.g. a scrollbar appearing) on the false→true transition.\nwatch(hasOverflow, () => {\n if (props.overflow === 'dropdown') nextTick(computeOverflow)\n})\n\nfunction selectOverflowTab(value: string) {\n ctx.changeTab(value)\n dropdownOpen.value = false\n}\n</script>\n\n<template>\n <!-- ── Default (no overflow behaviour) ───────────────────────────────────── -->\n <TabsList\n v-if=\"!props.overflow\"\n :loop=\"props.loop ?? true\"\n :class=\"composeClassName(ctx.slotFns.value.tabList(), props.class)\"\n >\n <slot />\n </TabsList>\n\n <!-- ── Arrows mode ────────────────────────────────────────────────────────── -->\n <div\n v-else-if=\"props.overflow === 'arrows'\"\n class=\"tabs__list-container tabs__list-container--arrows\"\n :class=\"{ 'has-left': canScrollLeft, 'has-right': canScrollRight }\"\n >\n <Button\n variant=\"secondary\"\n size=\"sm\"\n radius=\"full\"\n :is-icon-only=\"true\"\n :class=\"composeClassName('tabs__arrow tabs__arrow--left', canScrollLeft && 'is-visible')\"\n aria-label=\"Scroll tabs left\"\n tabindex=\"-1\"\n @click=\"scrollTabs('left')\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M9 11L5 7L9 3\" stroke=\"currentColor\" stroke-width=\"1.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </Button>\n\n <div ref=\"scrollWrapperEl\" class=\"tabs__scroll-wrapper\">\n <TabsList\n :loop=\"props.loop ?? true\"\n :class=\"composeClassName(ctx.slotFns.value.tabList(), 'tabs__list--scroll', props.class)\"\n >\n <slot />\n </TabsList>\n </div>\n\n <Button\n variant=\"secondary\"\n size=\"sm\"\n radius=\"full\"\n :is-icon-only=\"true\"\n :class=\"composeClassName('tabs__arrow tabs__arrow--right', canScrollRight && 'is-visible')\"\n aria-label=\"Scroll tabs right\"\n tabindex=\"-1\"\n @click=\"scrollTabs('right')\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M5 3L9 7L5 11\" stroke=\"currentColor\" stroke-width=\"1.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </Button>\n </div>\n\n <!-- ── Dropdown mode ──────────────────────────────────────────────────────── -->\n <div\n v-else-if=\"props.overflow === 'dropdown'\"\n ref=\"containerEl\"\n class=\"tabs__list-container tabs__list-container--dropdown\"\n >\n <TabsList\n :loop=\"props.loop ?? true\"\n :class=\"composeClassName(ctx.slotFns.value.tabList(), 'tabs__list--clipped', props.class)\"\n >\n <slot />\n </TabsList>\n\n <!-- Always rendered so offsetWidth is measurable; visibility toggled via CSS -->\n <div\n ref=\"dropdownEl\"\n class=\"tabs__more\"\n :class=\"{ 'tabs__more--visible': hasOverflow }\"\n >\n <Button\n variant=\"secondary\"\n size=\"sm\"\n radius=\"full\"\n class=\"tabs__more-btn\"\n :aria-expanded=\"dropdownOpen\"\n aria-haspopup=\"menu\"\n @click=\"dropdownOpen = !dropdownOpen\"\n >\n +{{ hiddenTabs.length }}\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M2 4L6 8L10 4\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </Button>\n\n <div v-if=\"dropdownOpen\" class=\"tabs__overflow-menu\" role=\"menu\">\n <Button\n v-for=\"tab in hiddenTabs\"\n :key=\"tab.value\"\n variant=\"ghost\"\n radius=\"lg\"\n class=\"tabs__overflow-item\"\n role=\"menuitem\"\n :disabled=\"tab.disabled\"\n @click=\"selectOverflowTab(tab.value)\"\n >\n {{ tab.label }}\n </Button>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -52,12 +52,10 @@ var TabList_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
|
|
|
52
52
|
}, { immediate: true });
|
|
53
53
|
useResizeObserver(scrollWrapperEl, () => nextTick(updateScrollButtons));
|
|
54
54
|
const containerEl = useTemplateRef("containerEl");
|
|
55
|
-
const moreBtnEl = useTemplateRef("moreBtnEl");
|
|
56
55
|
const dropdownEl = useTemplateRef("dropdownEl");
|
|
57
56
|
const hiddenTabs = ref([]);
|
|
58
57
|
const dropdownOpen = ref(false);
|
|
59
58
|
const hasOverflow = computed(() => hiddenTabs.value.length > 0);
|
|
60
|
-
let moreBtnNaturalWidth = 48;
|
|
61
59
|
onClickOutside(dropdownEl, () => {
|
|
62
60
|
dropdownOpen.value = false;
|
|
63
61
|
});
|
|
@@ -74,7 +72,19 @@ var TabList_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
|
|
|
74
72
|
});
|
|
75
73
|
listEl.offsetWidth;
|
|
76
74
|
}
|
|
77
|
-
|
|
75
|
+
let moreWidth = 0;
|
|
76
|
+
const moreEl = dropdownEl.value;
|
|
77
|
+
if (moreEl) {
|
|
78
|
+
const prevDisplay = moreEl.style.display;
|
|
79
|
+
moreEl.style.display = "flex";
|
|
80
|
+
moreEl.offsetWidth;
|
|
81
|
+
moreWidth = moreEl.offsetWidth;
|
|
82
|
+
moreEl.style.display = prevDisplay;
|
|
83
|
+
}
|
|
84
|
+
const cs = getComputedStyle(containerEl.value);
|
|
85
|
+
const padX = parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight);
|
|
86
|
+
const gap = parseFloat(cs.columnGap) || 0;
|
|
87
|
+
const contentWidth = containerEl.value.clientWidth - padX;
|
|
78
88
|
const tabWidths = allTabs.map((t) => t.offsetWidth);
|
|
79
89
|
const totalWidth = tabWidths.reduce((sum, w) => sum + w, 0);
|
|
80
90
|
if (listEl) {
|
|
@@ -84,11 +94,11 @@ var TabList_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
|
|
|
84
94
|
t.style.width = "";
|
|
85
95
|
});
|
|
86
96
|
}
|
|
87
|
-
if (totalWidth <=
|
|
97
|
+
if (totalWidth <= contentWidth) {
|
|
88
98
|
hiddenTabs.value = [];
|
|
89
99
|
return;
|
|
90
100
|
}
|
|
91
|
-
const available =
|
|
101
|
+
const available = contentWidth - moreWidth - gap - 1;
|
|
92
102
|
let accumulated = 0;
|
|
93
103
|
const newHidden = [];
|
|
94
104
|
const visibleEls = [];
|
|
@@ -130,13 +140,6 @@ var TabList_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
|
|
|
130
140
|
}
|
|
131
141
|
useResizeObserver(containerEl, () => nextTick(computeOverflow));
|
|
132
142
|
onMounted(() => {
|
|
133
|
-
const btnEl = moreBtnEl.value?.$el;
|
|
134
|
-
if (btnEl) {
|
|
135
|
-
btnEl.style.display = "flex";
|
|
136
|
-
btnEl.offsetWidth;
|
|
137
|
-
moreBtnNaturalWidth = btnEl.offsetWidth;
|
|
138
|
-
btnEl.style.display = "";
|
|
139
|
-
}
|
|
140
143
|
nextTick(computeOverflow);
|
|
141
144
|
});
|
|
142
145
|
watch(() => ctx.currentValue.value, () => {
|
|
@@ -241,8 +244,6 @@ var TabList_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
|
|
|
241
244
|
ref: dropdownEl,
|
|
242
245
|
class: normalizeClass(["tabs__more", { "tabs__more--visible": hasOverflow.value }])
|
|
243
246
|
}, [createVNode(Button_default, {
|
|
244
|
-
ref_key: "moreBtnEl",
|
|
245
|
-
ref: moreBtnEl,
|
|
246
247
|
variant: "secondary",
|
|
247
248
|
size: "sm",
|
|
248
249
|
radius: "full",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabList.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/tabs/TabList.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, nextTick, onMounted, watch } from 'vue'\nimport { useTemplateRef } from 'vue'\nimport { TabsList } from 'reka-ui'\nimport { useResizeObserver, onClickOutside } from '@vueuse/core'\nimport { composeClassName } from '../../utils/composeClassName'\nimport { useTabsInject } from './tabs.context'\nimport Button from '../button/Button.vue'\n\nconst props = defineProps<{\n loop?: boolean\n overflow?: 'arrows' | 'dropdown'\n class?: string\n}>()\n\nconst ctx = useTabsInject()\n\n// ── Arrows mode ─────────────────────────────────────────────────────────────\nconst scrollWrapperEl = useTemplateRef<HTMLElement>('scrollWrapperEl')\nconst canScrollLeft = ref(false)\nconst canScrollRight = ref(false)\n\nfunction updateScrollButtons() {\n const el = scrollWrapperEl.value\n if (!el) { canScrollLeft.value = false; canScrollRight.value = false; return }\n canScrollLeft.value = el.scrollLeft > 1\n canScrollRight.value = el.scrollLeft + el.clientWidth < el.scrollWidth - 1\n}\n\nfunction scrollTabs(dir: 'left' | 'right') {\n const el = scrollWrapperEl.value\n if (!el) return\n el.scrollBy({ left: dir === 'left' ? -200 : 200, behavior: 'smooth' })\n // Poll briefly after smooth scroll starts so button states update\n setTimeout(updateScrollButtons, 150)\n setTimeout(updateScrollButtons, 350)\n}\n\nwatch(scrollWrapperEl, (el, oldEl) => {\n if (oldEl) oldEl.removeEventListener('scroll', updateScrollButtons)\n if (el) {\n el.addEventListener('scroll', updateScrollButtons, { passive: true })\n nextTick(updateScrollButtons)\n }\n}, { immediate: true })\n\nuseResizeObserver(scrollWrapperEl, () => nextTick(updateScrollButtons))\n\n// ── Dropdown mode ────────────────────────────────────────────────────────────\ninterface OverflowTab {\n value: string\n label: string\n disabled: boolean\n}\n\nconst containerEl = useTemplateRef<HTMLElement>('containerEl')\n// Button component ref — use .$el to reach the underlying DOM element for offsetWidth\nconst moreBtnEl = useTemplateRef<InstanceType<typeof Button>>('moreBtnEl')\nconst dropdownEl = useTemplateRef<HTMLElement>('dropdownEl')\n\nconst hiddenTabs = ref<OverflowTab[]>([])\nconst dropdownOpen = ref(false)\nconst hasOverflow = computed(() => hiddenTabs.value.length > 0)\n// Pre-measured natural width of the more button (measured once on mount before it's visible)\nlet moreBtnNaturalWidth = 48\n\nonClickOutside(dropdownEl, () => { dropdownOpen.value = false })\n\nfunction computeOverflow() {\n if (!containerEl.value) return\n\n const allTabs = Array.from(\n containerEl.value.querySelectorAll('[data-tab-value]'),\n ) as HTMLElement[]\n\n // Reveal all tabs first\n allTabs.forEach(t => t.removeAttribute('data-overflow-hidden'))\n\n // Tabs use w-full and shrink to share the container width, so offsetWidth after\n // a normal render would be containerWidth/n — useless for overflow detection.\n // Force each tab to its natural content width for measurement only (no paint flash:\n // all DOM reads/writes happen synchronously within this JS task before the next frame).\n const listEl = containerEl.value.querySelector('[role=\"tablist\"]') as HTMLElement | null\n if (listEl) {\n listEl.style.overflow = 'visible'\n allTabs.forEach(t => { t.style.flexShrink = '0'; t.style.width = 'auto' })\n void listEl.offsetWidth // force reflow so offsetWidth reads below are accurate\n }\n\n const containerWidth = containerEl.value.clientWidth\n const tabWidths = allTabs.map(t => t.offsetWidth)\n const totalWidth = tabWidths.reduce((sum, w) => sum + w, 0)\n\n // Restore layout before any early-return so tabs always look correct\n if (listEl) {\n listEl.style.overflow = ''\n allTabs.forEach(t => { t.style.flexShrink = ''; t.style.width = '' })\n }\n\n if (totalWidth <= containerWidth) {\n hiddenTabs.value = []\n return\n }\n\n // More button is in-flow (display:none when no overflow, display:flex when visible).\n // Use the pre-measured natural width so the calculation is accurate on the first run\n // before the button becomes visible.\n const available = containerWidth - moreBtnNaturalWidth\n\n let accumulated = 0\n const newHidden: OverflowTab[] = []\n const visibleEls: HTMLElement[] = []\n\n for (let i = 0; i < allTabs.length; i++) {\n const tab = allTabs[i]\n const w = tabWidths[i]\n if (accumulated + w <= available) {\n accumulated += w\n visibleEls.push(tab)\n } else {\n newHidden.push({\n value: tab.getAttribute('data-tab-value') ?? '',\n label: tab.textContent?.trim() ?? '',\n disabled: tab.hasAttribute('data-disabled') || tab.getAttribute('aria-disabled') === 'true',\n })\n tab.setAttribute('data-overflow-hidden', '')\n }\n }\n\n // If the active tab ended up hidden, swap it with the last visible tab\n const activeValue = ctx.currentValue.value\n if (activeValue) {\n const hiddenActiveIdx = newHidden.findIndex(t => t.value === activeValue)\n if (hiddenActiveIdx !== -1 && visibleEls.length > 0) {\n const displacedEl = visibleEls[visibleEls.length - 1]\n const activeEl = allTabs.find(t => t.getAttribute('data-tab-value') === activeValue)\n\n if (displacedEl && activeEl) {\n // Swap: make displaced tab hidden, active tab visible\n displacedEl.setAttribute('data-overflow-hidden', '')\n activeEl.removeAttribute('data-overflow-hidden')\n\n const displaced: OverflowTab = {\n value: displacedEl.getAttribute('data-tab-value') ?? '',\n label: displacedEl.textContent?.trim() ?? '',\n disabled: displacedEl.hasAttribute('data-disabled') || displacedEl.getAttribute('aria-disabled') === 'true',\n }\n newHidden.splice(hiddenActiveIdx, 1)\n newHidden.unshift(displaced)\n }\n }\n }\n\n hiddenTabs.value = newHidden\n}\n\nuseResizeObserver(containerEl, () => nextTick(computeOverflow))\nonMounted(() => {\n // Pre-measure the more button's natural width before it becomes visible (display:none).\n // Temporarily show it, read offsetWidth, then hide again — happens before first paint.\n const btnEl = (moreBtnEl.value as InstanceType<typeof Button> | null)?.$el as HTMLElement | null\n if (btnEl) {\n btnEl.style.display = 'flex'\n void btnEl.offsetWidth\n moreBtnNaturalWidth = btnEl.offsetWidth\n btnEl.style.display = ''\n }\n nextTick(computeOverflow)\n})\n\n// Recompute when the active tab changes so the active tab is always visible\nwatch(() => ctx.currentValue.value, () => {\n if (props.overflow === 'dropdown') nextTick(computeOverflow)\n})\n\n// When overflow state first transitions false→true the more button enters the flex flow,\n// narrowing the container. Re-run once so the tab count reflects the reduced available space.\nwatch(hasOverflow, () => {\n if (props.overflow === 'dropdown') nextTick(computeOverflow)\n})\n\nfunction selectOverflowTab(value: string) {\n ctx.changeTab(value)\n dropdownOpen.value = false\n}\n</script>\n\n<template>\n <!-- ── Default (no overflow behaviour) ───────────────────────────────────── -->\n <TabsList\n v-if=\"!props.overflow\"\n :loop=\"props.loop ?? true\"\n :class=\"composeClassName(ctx.slotFns.value.tabList(), props.class)\"\n >\n <slot />\n </TabsList>\n\n <!-- ── Arrows mode ────────────────────────────────────────────────────────── -->\n <div\n v-else-if=\"props.overflow === 'arrows'\"\n class=\"tabs__list-container tabs__list-container--arrows\"\n :class=\"{ 'has-left': canScrollLeft, 'has-right': canScrollRight }\"\n >\n <Button\n variant=\"secondary\"\n size=\"sm\"\n radius=\"full\"\n :is-icon-only=\"true\"\n :class=\"composeClassName('tabs__arrow tabs__arrow--left', canScrollLeft && 'is-visible')\"\n aria-label=\"Scroll tabs left\"\n tabindex=\"-1\"\n @click=\"scrollTabs('left')\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M9 11L5 7L9 3\" stroke=\"currentColor\" stroke-width=\"1.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </Button>\n\n <div ref=\"scrollWrapperEl\" class=\"tabs__scroll-wrapper\">\n <TabsList\n :loop=\"props.loop ?? true\"\n :class=\"composeClassName(ctx.slotFns.value.tabList(), 'tabs__list--scroll', props.class)\"\n >\n <slot />\n </TabsList>\n </div>\n\n <Button\n variant=\"secondary\"\n size=\"sm\"\n radius=\"full\"\n :is-icon-only=\"true\"\n :class=\"composeClassName('tabs__arrow tabs__arrow--right', canScrollRight && 'is-visible')\"\n aria-label=\"Scroll tabs right\"\n tabindex=\"-1\"\n @click=\"scrollTabs('right')\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M5 3L9 7L5 11\" stroke=\"currentColor\" stroke-width=\"1.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </Button>\n </div>\n\n <!-- ── Dropdown mode ──────────────────────────────────────────────────────── -->\n <div\n v-else-if=\"props.overflow === 'dropdown'\"\n ref=\"containerEl\"\n class=\"tabs__list-container tabs__list-container--dropdown\"\n >\n <TabsList\n :loop=\"props.loop ?? true\"\n :class=\"composeClassName(ctx.slotFns.value.tabList(), 'tabs__list--clipped', props.class)\"\n >\n <slot />\n </TabsList>\n\n <!-- Always rendered so offsetWidth is measurable; visibility toggled via CSS -->\n <div\n ref=\"dropdownEl\"\n class=\"tabs__more\"\n :class=\"{ 'tabs__more--visible': hasOverflow }\"\n >\n <Button\n ref=\"moreBtnEl\"\n variant=\"secondary\"\n size=\"sm\"\n radius=\"full\"\n class=\"tabs__more-btn\"\n :aria-expanded=\"dropdownOpen\"\n aria-haspopup=\"menu\"\n @click=\"dropdownOpen = !dropdownOpen\"\n >\n +{{ hiddenTabs.length }}\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M2 4L6 8L10 4\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </Button>\n\n <div v-if=\"dropdownOpen\" class=\"tabs__overflow-menu\" role=\"menu\">\n <Button\n v-for=\"tab in hiddenTabs\"\n :key=\"tab.value\"\n variant=\"ghost\"\n radius=\"lg\"\n class=\"tabs__overflow-item\"\n role=\"menuitem\"\n :disabled=\"tab.disabled\"\n @click=\"selectOverflowTab(tab.value)\"\n >\n {{ tab.label }}\n </Button>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;EASA,MAAM,QAAQ;EAMd,MAAM,MAAM,eAAc;EAG1B,MAAM,kBAAkB,eAA4B,kBAAiB;EACrE,MAAM,gBAAgB,IAAI,MAAK;EAC/B,MAAM,iBAAiB,IAAI,MAAK;EAEhC,SAAS,sBAAsB;GAC7B,MAAM,KAAK,gBAAgB;AAC3B,OAAI,CAAC,IAAI;AAAE,kBAAc,QAAQ;AAAO,mBAAe,QAAQ;AAAO;;AACtE,iBAAc,QAAQ,GAAG,aAAa;AACtC,kBAAe,QAAQ,GAAG,aAAa,GAAG,cAAc,GAAG,cAAc;;EAG3E,SAAS,WAAW,KAAuB;GACzC,MAAM,KAAK,gBAAgB;AAC3B,OAAI,CAAC,GAAI;AACT,MAAG,SAAS;IAAE,MAAM,QAAQ,SAAS,OAAO;IAAK,UAAU;IAAU,CAAA;AAErE,cAAW,qBAAqB,IAAG;AACnC,cAAW,qBAAqB,IAAG;;AAGrC,QAAM,kBAAkB,IAAI,UAAU;AACpC,OAAI,MAAO,OAAM,oBAAoB,UAAU,oBAAmB;AAClE,OAAI,IAAI;AACN,OAAG,iBAAiB,UAAU,qBAAqB,EAAE,SAAS,MAAM,CAAA;AACpE,aAAS,oBAAmB;;KAE7B,EAAE,WAAW,MAAM,CAAA;AAEtB,oBAAkB,uBAAuB,SAAS,oBAAoB,CAAA;EAStE,MAAM,cAAc,eAA4B,cAAa;EAE7D,MAAM,YAAY,eAA4C,YAAW;EACzE,MAAM,aAAa,eAA4B,aAAY;EAE3D,MAAM,aAAa,IAAmB,EAAE,CAAA;EACxC,MAAM,eAAe,IAAI,MAAK;EAC9B,MAAM,cAAc,eAAe,WAAW,MAAM,SAAS,EAAC;EAE9D,IAAI,sBAAsB;AAE1B,iBAAe,kBAAkB;AAAE,gBAAa,QAAQ;IAAO;EAE/D,SAAS,kBAAkB;AACzB,OAAI,CAAC,YAAY,MAAO;GAExB,MAAM,UAAU,MAAM,KACpB,YAAY,MAAM,iBAAiB,mBAAmB,CACvD;AAGD,WAAQ,SAAQ,MAAK,EAAE,gBAAgB,uBAAuB,CAAA;GAM9D,MAAM,SAAS,YAAY,MAAM,cAAc,qBAAmB;AAClE,OAAI,QAAQ;AACV,WAAO,MAAM,WAAW;AACxB,YAAQ,SAAQ,MAAK;AAAE,OAAE,MAAM,aAAa;AAAK,OAAE,MAAM,QAAQ;MAAQ;AACpE,WAAO;;GAGd,MAAM,iBAAiB,YAAY,MAAM;GACzC,MAAM,YAAY,QAAQ,KAAI,MAAK,EAAE,YAAW;GAChD,MAAM,aAAa,UAAU,QAAQ,KAAK,MAAM,MAAM,GAAG,EAAC;AAG1D,OAAI,QAAQ;AACV,WAAO,MAAM,WAAW;AACxB,YAAQ,SAAQ,MAAK;AAAE,OAAE,MAAM,aAAa;AAAI,OAAE,MAAM,QAAQ;MAAI;;AAGtE,OAAI,cAAc,gBAAgB;AAChC,eAAW,QAAQ,EAAC;AACpB;;GAMF,MAAM,YAAY,iBAAiB;GAEnC,IAAI,cAAc;GAClB,MAAM,YAA2B,EAAC;GAClC,MAAM,aAA4B,EAAC;AAEnC,QAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;IACvC,MAAM,MAAM,QAAQ;IACpB,MAAM,IAAI,UAAU;AACpB,QAAI,cAAc,KAAK,WAAW;AAChC,oBAAe;AACf,gBAAW,KAAK,IAAG;WACd;AACL,eAAU,KAAK;MACb,OAAO,IAAI,aAAa,iBAAiB,IAAI;MAC7C,OAAO,IAAI,aAAa,MAAM,IAAI;MAClC,UAAU,IAAI,aAAa,gBAAgB,IAAI,IAAI,aAAa,gBAAgB,KAAK;MACtF,CAAA;AACD,SAAI,aAAa,wBAAwB,GAAE;;;GAK/C,MAAM,cAAc,IAAI,aAAa;AACrC,OAAI,aAAa;IACf,MAAM,kBAAkB,UAAU,WAAU,MAAK,EAAE,UAAU,YAAW;AACxE,QAAI,oBAAoB,MAAM,WAAW,SAAS,GAAG;KACnD,MAAM,cAAc,WAAW,WAAW,SAAS;KACnD,MAAM,WAAW,QAAQ,MAAK,MAAK,EAAE,aAAa,iBAAiB,KAAK,YAAW;AAEnF,SAAI,eAAe,UAAU;AAE3B,kBAAY,aAAa,wBAAwB,GAAE;AACnD,eAAS,gBAAgB,uBAAsB;MAE/C,MAAM,YAAyB;OAC7B,OAAO,YAAY,aAAa,iBAAiB,IAAI;OACrD,OAAO,YAAY,aAAa,MAAM,IAAI;OAC1C,UAAU,YAAY,aAAa,gBAAgB,IAAI,YAAY,aAAa,gBAAgB,KAAK;OACvG;AACA,gBAAU,OAAO,iBAAiB,EAAC;AACnC,gBAAU,QAAQ,UAAS;;;;AAKjC,cAAW,QAAQ;;AAGrB,oBAAkB,mBAAmB,SAAS,gBAAgB,CAAA;AAC9D,kBAAgB;GAGd,MAAM,QAAS,UAAU,OAA8C;AACvE,OAAI,OAAO;AACT,UAAM,MAAM,UAAU;AACjB,UAAM;AACX,0BAAsB,MAAM;AAC5B,UAAM,MAAM,UAAU;;AAExB,YAAS,gBAAe;IACzB;AAGD,cAAY,IAAI,aAAa,aAAa;AACxC,OAAI,MAAM,aAAa,WAAY,UAAS,gBAAe;IAC5D;AAID,QAAM,mBAAmB;AACvB,OAAI,MAAM,aAAa,WAAY,UAAS,gBAAe;IAC5D;EAED,SAAS,kBAAkB,OAAe;AACxC,OAAI,UAAU,MAAK;AACnB,gBAAa,QAAQ;;;WAOZ,MAAM,YAAA,WAAA,EADf,YAMW,MAAA,SAAA,EAAA;;IAJR,MAAM,MAAM,QAAI;IAChB,OAAK,eAAE,MAAA,iBAAgB,CAAC,MAAA,IAAG,CAAC,QAAQ,MAAM,SAAO,EAAI,MAAM,MAAK,CAAA;;2BAEzD,CAAR,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA;;+BAKG,MAAM,aAAQ,YAAA,WAAA,EAD3B,mBA2CM,OAAA;;IAzCJ,OAAK,eAAA,CAAC,qDAAmD;KAAA,YACnC,cAAA;KAAa,aAAe,eAAA;KAAc,CAAA,CAAA;;IAEhE,YAaS,gBAAA;KAZP,SAAQ;KACR,MAAK;KACL,QAAO;KACN,gBAAc;KACd,OAAK,eAAE,MAAA,iBAAgB,CAAA,iCAAkC,cAAA,SAAa,aAAA,CAAA;KACvE,cAAW;KACX,UAAS;KACR,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,WAAU,OAAA;;4BAIZ,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAFN,mBAEM,OAAA;MAFD,OAAM;MAAK,QAAO;MAAK,SAAQ;MAAY,MAAK;MAAO,eAAY;SACtE,mBAAmH,QAAA;MAA7G,GAAE;MAAgB,QAAO;MAAe,gBAAa;MAAO,kBAAe;MAAQ,mBAAgB;;;;IAI7G,mBAOM,OAAA;cAPG;KAAJ,KAAI;KAAkB,OAAM;QAC/B,YAKW,MAAA,SAAA,EAAA;KAJR,MAAM,MAAM,QAAI;KAChB,OAAK,eAAE,MAAA,iBAAgB,CAAC,MAAA,IAAG,CAAC,QAAQ,MAAM,SAAO,EAAA,sBAA0B,MAAM,MAAK,CAAA;;4BAE/E,CAAR,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA;;;IAIZ,YAaS,gBAAA;KAZP,SAAQ;KACR,MAAK;KACL,QAAO;KACN,gBAAc;KACd,OAAK,eAAE,MAAA,iBAAgB,CAAA,kCAAmC,eAAA,SAAc,aAAA,CAAA;KACzE,cAAW;KACX,UAAS;KACR,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,WAAU,QAAA;;4BAIZ,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAFN,mBAEM,OAAA;MAFD,OAAM;MAAK,QAAO;MAAK,SAAQ;MAAY,MAAK;MAAO,eAAY;SACtE,mBAAmH,QAAA;MAA7G,GAAE;MAAgB,QAAO;MAAe,gBAAa;MAAO,kBAAe;MAAQ,mBAAgB;;;;YAOlG,MAAM,aAAQ,cAAA,WAAA,EAD3B,mBAiDM,OAAA;;aA/CA;IAAJ,KAAI;IACJ,OAAM;OAEN,YAKW,MAAA,SAAA,EAAA;IAJR,MAAM,MAAM,QAAI;IAChB,OAAK,eAAE,MAAA,iBAAgB,CAAC,MAAA,IAAG,CAAC,QAAQ,MAAM,SAAO,EAAA,uBAA2B,MAAM,MAAK,CAAA;;2BAEhF,CAAR,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA;;6BAIV,mBAmCM,OAAA;aAlCA;IAAJ,KAAI;IACJ,OAAK,eAAA,CAAC,cAAY,EAAA,uBACe,YAAA,OAAW,CAAA,CAAA;OAE5C,YAcS,gBAAA;aAbH;IAAJ,KAAI;IACJ,SAAQ;IACR,MAAK;IACL,QAAO;IACP,OAAM;IACL,iBAAe,aAAA;IAChB,iBAAc;IACb,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,aAAA,QAAY,CAAI,aAAA;;2BAEvB,CAAA,gBADF,OACE,gBAAG,WAAA,MAAW,OAAM,GAAG,KACxB,EAAA,EAAA,OAAA,OAAA,OAAA,KAAA,mBAEM,OAAA;KAFD,OAAM;KAAK,QAAO;KAAK,SAAQ;KAAY,MAAK;KAAO,eAAY;QACtE,mBAAkH,QAAA;KAA5G,GAAE;KAAgB,QAAO;KAAe,gBAAa;KAAM,kBAAe;KAAQ,mBAAgB;;;6BAIjG,aAAA,SAAA,WAAA,EAAX,mBAaM,OAbN,YAaM,EAAA,UAAA,KAAA,EAZJ,mBAWS,UAAA,MAAA,WAVO,WAAA,QAAP,QAAG;wBADZ,YAWS,gBAAA;KATN,KAAK,IAAI;KACV,SAAQ;KACR,QAAO;KACP,OAAM;KACN,MAAK;KACJ,UAAU,IAAI;KACd,UAAK,WAAE,kBAAkB,IAAI,MAAK;;4BAEpB,CAAA,gBAAA,gBAAZ,IAAI,MAAK,EAAA,EAAA,CAAA,CAAA"}
|
|
1
|
+
{"version":3,"file":"TabList.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/tabs/TabList.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, nextTick, onMounted, watch } from 'vue'\nimport { useTemplateRef } from 'vue'\nimport { TabsList } from 'reka-ui'\nimport { useResizeObserver, onClickOutside } from '@vueuse/core'\nimport { composeClassName } from '../../utils/composeClassName'\nimport { useTabsInject } from './tabs.context'\nimport Button from '../button/Button.vue'\n\nconst props = defineProps<{\n loop?: boolean\n overflow?: 'arrows' | 'dropdown'\n class?: string\n}>()\n\nconst ctx = useTabsInject()\n\n// ── Arrows mode ─────────────────────────────────────────────────────────────\nconst scrollWrapperEl = useTemplateRef<HTMLElement>('scrollWrapperEl')\nconst canScrollLeft = ref(false)\nconst canScrollRight = ref(false)\n\nfunction updateScrollButtons() {\n const el = scrollWrapperEl.value\n if (!el) { canScrollLeft.value = false; canScrollRight.value = false; return }\n canScrollLeft.value = el.scrollLeft > 1\n canScrollRight.value = el.scrollLeft + el.clientWidth < el.scrollWidth - 1\n}\n\nfunction scrollTabs(dir: 'left' | 'right') {\n const el = scrollWrapperEl.value\n if (!el) return\n el.scrollBy({ left: dir === 'left' ? -200 : 200, behavior: 'smooth' })\n // Poll briefly after smooth scroll starts so button states update\n setTimeout(updateScrollButtons, 150)\n setTimeout(updateScrollButtons, 350)\n}\n\nwatch(scrollWrapperEl, (el, oldEl) => {\n if (oldEl) oldEl.removeEventListener('scroll', updateScrollButtons)\n if (el) {\n el.addEventListener('scroll', updateScrollButtons, { passive: true })\n nextTick(updateScrollButtons)\n }\n}, { immediate: true })\n\nuseResizeObserver(scrollWrapperEl, () => nextTick(updateScrollButtons))\n\n// ── Dropdown mode ────────────────────────────────────────────────────────────\ninterface OverflowTab {\n value: string\n label: string\n disabled: boolean\n}\n\nconst containerEl = useTemplateRef<HTMLElement>('containerEl')\nconst dropdownEl = useTemplateRef<HTMLElement>('dropdownEl')\n\nconst hiddenTabs = ref<OverflowTab[]>([])\nconst dropdownOpen = ref(false)\nconst hasOverflow = computed(() => hiddenTabs.value.length > 0)\n\nonClickOutside(dropdownEl, () => { dropdownOpen.value = false })\n\nfunction computeOverflow() {\n if (!containerEl.value) return\n\n const allTabs = Array.from(\n containerEl.value.querySelectorAll('[data-tab-value]'),\n ) as HTMLElement[]\n\n // Reveal all tabs first\n allTabs.forEach(t => t.removeAttribute('data-overflow-hidden'))\n\n // Tabs use w-full and shrink to share the container width, so offsetWidth after\n // a normal render would be containerWidth/n — useless for overflow detection.\n // Force each tab to its natural content width for measurement only (no paint flash:\n // all DOM reads/writes happen synchronously within this JS task before the next frame).\n const listEl = containerEl.value.querySelector('[role=\"tablist\"]') as HTMLElement | null\n if (listEl) {\n listEl.style.overflow = 'visible'\n allTabs.forEach(t => { t.style.flexShrink = '0'; t.style.width = 'auto' })\n void listEl.offsetWidth // force reflow so offsetWidth reads below are accurate\n }\n\n // Measure the more button's real width by temporarily revealing its wrapper.\n // The wrapper is display:none when there's no overflow, so we can't rely on a\n // pre-measured value — measure it here while the (always-visible) container holds it.\n let moreWidth = 0\n const moreEl = dropdownEl.value\n if (moreEl) {\n const prevDisplay = moreEl.style.display\n moreEl.style.display = 'flex'\n void moreEl.offsetWidth\n moreWidth = moreEl.offsetWidth\n moreEl.style.display = prevDisplay\n }\n\n // clientWidth includes the container's horizontal padding; the flex children only\n // get the content box. Subtract padding so measurements compare against real space.\n const cs = getComputedStyle(containerEl.value)\n const padX = parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight)\n const gap = parseFloat(cs.columnGap) || 0\n const contentWidth = containerEl.value.clientWidth - padX\n\n const tabWidths = allTabs.map(t => t.offsetWidth)\n const totalWidth = tabWidths.reduce((sum, w) => sum + w, 0)\n\n // Restore layout before any early-return so tabs always look correct\n if (listEl) {\n listEl.style.overflow = ''\n allTabs.forEach(t => { t.style.flexShrink = ''; t.style.width = '' })\n }\n\n if (totalWidth <= contentWidth) {\n hiddenTabs.value = []\n return\n }\n\n // When the more button is shown it sits beside the clipped list, separated by `gap`.\n // Reserve its width + the gap (+1px sub-pixel safety) so the last visible tab can\n // never extend under the button.\n const available = contentWidth - moreWidth - gap - 1\n\n let accumulated = 0\n const newHidden: OverflowTab[] = []\n const visibleEls: HTMLElement[] = []\n\n for (let i = 0; i < allTabs.length; i++) {\n const tab = allTabs[i]\n const w = tabWidths[i]\n if (accumulated + w <= available) {\n accumulated += w\n visibleEls.push(tab)\n } else {\n newHidden.push({\n value: tab.getAttribute('data-tab-value') ?? '',\n label: tab.textContent?.trim() ?? '',\n disabled: tab.hasAttribute('data-disabled') || tab.getAttribute('aria-disabled') === 'true',\n })\n tab.setAttribute('data-overflow-hidden', '')\n }\n }\n\n // If the active tab ended up hidden, swap it with the last visible tab\n const activeValue = ctx.currentValue.value\n if (activeValue) {\n const hiddenActiveIdx = newHidden.findIndex(t => t.value === activeValue)\n if (hiddenActiveIdx !== -1 && visibleEls.length > 0) {\n const displacedEl = visibleEls[visibleEls.length - 1]\n const activeEl = allTabs.find(t => t.getAttribute('data-tab-value') === activeValue)\n\n if (displacedEl && activeEl) {\n // Swap: make displaced tab hidden, active tab visible\n displacedEl.setAttribute('data-overflow-hidden', '')\n activeEl.removeAttribute('data-overflow-hidden')\n\n const displaced: OverflowTab = {\n value: displacedEl.getAttribute('data-tab-value') ?? '',\n label: displacedEl.textContent?.trim() ?? '',\n disabled: displacedEl.hasAttribute('data-disabled') || displacedEl.getAttribute('aria-disabled') === 'true',\n }\n newHidden.splice(hiddenActiveIdx, 1)\n newHidden.unshift(displaced)\n }\n }\n }\n\n hiddenTabs.value = newHidden\n}\n\nuseResizeObserver(containerEl, () => nextTick(computeOverflow))\nonMounted(() => {\n nextTick(computeOverflow)\n})\n\n// Recompute when the active tab changes so the active tab is always visible\nwatch(() => ctx.currentValue.value, () => {\n if (props.overflow === 'dropdown') nextTick(computeOverflow)\n})\n\n// Safety re-check when overflow toggles. computeOverflow already reserves the more\n// button's width up front, so this is idempotent — it just guards against layout\n// settling (e.g. a scrollbar appearing) on the false→true transition.\nwatch(hasOverflow, () => {\n if (props.overflow === 'dropdown') nextTick(computeOverflow)\n})\n\nfunction selectOverflowTab(value: string) {\n ctx.changeTab(value)\n dropdownOpen.value = false\n}\n</script>\n\n<template>\n <!-- ── Default (no overflow behaviour) ───────────────────────────────────── -->\n <TabsList\n v-if=\"!props.overflow\"\n :loop=\"props.loop ?? true\"\n :class=\"composeClassName(ctx.slotFns.value.tabList(), props.class)\"\n >\n <slot />\n </TabsList>\n\n <!-- ── Arrows mode ────────────────────────────────────────────────────────── -->\n <div\n v-else-if=\"props.overflow === 'arrows'\"\n class=\"tabs__list-container tabs__list-container--arrows\"\n :class=\"{ 'has-left': canScrollLeft, 'has-right': canScrollRight }\"\n >\n <Button\n variant=\"secondary\"\n size=\"sm\"\n radius=\"full\"\n :is-icon-only=\"true\"\n :class=\"composeClassName('tabs__arrow tabs__arrow--left', canScrollLeft && 'is-visible')\"\n aria-label=\"Scroll tabs left\"\n tabindex=\"-1\"\n @click=\"scrollTabs('left')\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M9 11L5 7L9 3\" stroke=\"currentColor\" stroke-width=\"1.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </Button>\n\n <div ref=\"scrollWrapperEl\" class=\"tabs__scroll-wrapper\">\n <TabsList\n :loop=\"props.loop ?? true\"\n :class=\"composeClassName(ctx.slotFns.value.tabList(), 'tabs__list--scroll', props.class)\"\n >\n <slot />\n </TabsList>\n </div>\n\n <Button\n variant=\"secondary\"\n size=\"sm\"\n radius=\"full\"\n :is-icon-only=\"true\"\n :class=\"composeClassName('tabs__arrow tabs__arrow--right', canScrollRight && 'is-visible')\"\n aria-label=\"Scroll tabs right\"\n tabindex=\"-1\"\n @click=\"scrollTabs('right')\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M5 3L9 7L5 11\" stroke=\"currentColor\" stroke-width=\"1.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </Button>\n </div>\n\n <!-- ── Dropdown mode ──────────────────────────────────────────────────────── -->\n <div\n v-else-if=\"props.overflow === 'dropdown'\"\n ref=\"containerEl\"\n class=\"tabs__list-container tabs__list-container--dropdown\"\n >\n <TabsList\n :loop=\"props.loop ?? true\"\n :class=\"composeClassName(ctx.slotFns.value.tabList(), 'tabs__list--clipped', props.class)\"\n >\n <slot />\n </TabsList>\n\n <!-- Always rendered so offsetWidth is measurable; visibility toggled via CSS -->\n <div\n ref=\"dropdownEl\"\n class=\"tabs__more\"\n :class=\"{ 'tabs__more--visible': hasOverflow }\"\n >\n <Button\n variant=\"secondary\"\n size=\"sm\"\n radius=\"full\"\n class=\"tabs__more-btn\"\n :aria-expanded=\"dropdownOpen\"\n aria-haspopup=\"menu\"\n @click=\"dropdownOpen = !dropdownOpen\"\n >\n +{{ hiddenTabs.length }}\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M2 4L6 8L10 4\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </Button>\n\n <div v-if=\"dropdownOpen\" class=\"tabs__overflow-menu\" role=\"menu\">\n <Button\n v-for=\"tab in hiddenTabs\"\n :key=\"tab.value\"\n variant=\"ghost\"\n radius=\"lg\"\n class=\"tabs__overflow-item\"\n role=\"menuitem\"\n :disabled=\"tab.disabled\"\n @click=\"selectOverflowTab(tab.value)\"\n >\n {{ tab.label }}\n </Button>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1523,102 +1523,6 @@ declare const __VLS_component_66: DefineComponent<__VLS_Props_74, {}, {}, {}, {}
|
|
|
1523
1523
|
scrollWrapperEl: HTMLDivElement;
|
|
1524
1524
|
containerEl: HTMLDivElement;
|
|
1525
1525
|
dropdownEl: HTMLDivElement;
|
|
1526
|
-
moreBtnEl: ({
|
|
1527
|
-
$: ComponentInternalInstance;
|
|
1528
|
-
$data: {};
|
|
1529
|
-
$props: {
|
|
1530
|
-
readonly variant?: "danger" | "success" | "warning" | "primary" | "secondary" | "danger-soft" | "ghost" | "outline" | "success-soft" | "tertiary" | "warning-soft" | undefined;
|
|
1531
|
-
readonly size?: "md" | "sm" | "lg" | "xs" | "xl" | undefined;
|
|
1532
|
-
readonly radius?: "md" | "sm" | "lg" | "none" | "full" | undefined;
|
|
1533
|
-
readonly isIconOnly?: boolean | undefined;
|
|
1534
|
-
readonly fullWidth?: boolean | undefined;
|
|
1535
|
-
readonly disabled?: boolean | undefined;
|
|
1536
|
-
readonly isLoading?: boolean | undefined;
|
|
1537
|
-
readonly as?: string | object | undefined;
|
|
1538
|
-
readonly class?: string | undefined;
|
|
1539
|
-
readonly value?: string | number | undefined;
|
|
1540
|
-
} & VNodeProps & AllowedComponentProps & ComponentCustomProps;
|
|
1541
|
-
$attrs: Attrs;
|
|
1542
|
-
$refs: {
|
|
1543
|
-
[x: string]: unknown;
|
|
1544
|
-
};
|
|
1545
|
-
$slots: Readonly<{
|
|
1546
|
-
[name: string]: Slot<any> | undefined;
|
|
1547
|
-
}>;
|
|
1548
|
-
$root: ComponentPublicInstance | null;
|
|
1549
|
-
$parent: ComponentPublicInstance | null;
|
|
1550
|
-
$host: Element | null;
|
|
1551
|
-
$emit: (event: string, ...args: any[]) => void;
|
|
1552
|
-
$el: any;
|
|
1553
|
-
$options: ComponentOptionsBase<Readonly<{
|
|
1554
|
-
variant?: ButtonVariants["variant"];
|
|
1555
|
-
size?: ButtonVariants["size"];
|
|
1556
|
-
radius?: ButtonVariants["radius"];
|
|
1557
|
-
isIconOnly?: boolean;
|
|
1558
|
-
fullWidth?: boolean;
|
|
1559
|
-
disabled?: boolean;
|
|
1560
|
-
isLoading?: boolean;
|
|
1561
|
-
as?: string | object;
|
|
1562
|
-
class?: string;
|
|
1563
|
-
value?: string | number;
|
|
1564
|
-
}> & Readonly<{}>, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, {
|
|
1565
|
-
size: "md" | "sm" | "lg" | "xs" | "xl";
|
|
1566
|
-
variant: "danger" | "success" | "warning" | "primary" | "secondary" | "danger-soft" | "ghost" | "outline" | "success-soft" | "tertiary" | "warning-soft";
|
|
1567
|
-
fullWidth: boolean;
|
|
1568
|
-
isIconOnly: boolean;
|
|
1569
|
-
isLoading: boolean;
|
|
1570
|
-
radius: "md" | "sm" | "lg" | "none" | "full";
|
|
1571
|
-
value: string | number;
|
|
1572
|
-
as: string | object;
|
|
1573
|
-
disabled: boolean;
|
|
1574
|
-
}, {}, string, {}, GlobalComponents, GlobalDirectives, string, ComponentProvideOptions> & {
|
|
1575
|
-
beforeCreate?: (() => void) | (() => void)[];
|
|
1576
|
-
created?: (() => void) | (() => void)[];
|
|
1577
|
-
beforeMount?: (() => void) | (() => void)[];
|
|
1578
|
-
mounted?: (() => void) | (() => void)[];
|
|
1579
|
-
beforeUpdate?: (() => void) | (() => void)[];
|
|
1580
|
-
updated?: (() => void) | (() => void)[];
|
|
1581
|
-
activated?: (() => void) | (() => void)[];
|
|
1582
|
-
deactivated?: (() => void) | (() => void)[];
|
|
1583
|
-
beforeDestroy?: (() => void) | (() => void)[];
|
|
1584
|
-
beforeUnmount?: (() => void) | (() => void)[];
|
|
1585
|
-
destroyed?: (() => void) | (() => void)[];
|
|
1586
|
-
unmounted?: (() => void) | (() => void)[];
|
|
1587
|
-
renderTracked?: ((e: DebuggerEvent) => void) | ((e: DebuggerEvent) => void)[];
|
|
1588
|
-
renderTriggered?: ((e: DebuggerEvent) => void) | ((e: DebuggerEvent) => void)[];
|
|
1589
|
-
errorCaptured?: ((err: unknown, instance: ComponentPublicInstance | null, info: string) => boolean | void) | ((err: unknown, instance: ComponentPublicInstance | null, info: string) => boolean | void)[];
|
|
1590
|
-
};
|
|
1591
|
-
$forceUpdate: () => void;
|
|
1592
|
-
$nextTick: typeof nextTick;
|
|
1593
|
-
$watch<T extends string | ((...args: any) => any)>(source: T, cb: T extends (...args: any) => infer R ? (...args: [R, R, OnCleanup]) => any : (...args: [any, any, OnCleanup]) => any, options?: WatchOptions): WatchStopHandle;
|
|
1594
|
-
} & Readonly<{
|
|
1595
|
-
size: "md" | "sm" | "lg" | "xs" | "xl";
|
|
1596
|
-
variant: "danger" | "success" | "warning" | "primary" | "secondary" | "danger-soft" | "ghost" | "outline" | "success-soft" | "tertiary" | "warning-soft";
|
|
1597
|
-
fullWidth: boolean;
|
|
1598
|
-
isIconOnly: boolean;
|
|
1599
|
-
isLoading: boolean;
|
|
1600
|
-
radius: "md" | "sm" | "lg" | "none" | "full";
|
|
1601
|
-
value: string | number;
|
|
1602
|
-
as: string | object;
|
|
1603
|
-
disabled: boolean;
|
|
1604
|
-
}> & Omit<Readonly<{
|
|
1605
|
-
variant?: ButtonVariants["variant"];
|
|
1606
|
-
size?: ButtonVariants["size"];
|
|
1607
|
-
radius?: ButtonVariants["radius"];
|
|
1608
|
-
isIconOnly?: boolean;
|
|
1609
|
-
fullWidth?: boolean;
|
|
1610
|
-
disabled?: boolean;
|
|
1611
|
-
isLoading?: boolean;
|
|
1612
|
-
as?: string | object;
|
|
1613
|
-
class?: string;
|
|
1614
|
-
value?: string | number;
|
|
1615
|
-
}> & Readonly<{}>, "size" | "variant" | "fullWidth" | "isIconOnly" | "isLoading" | "radius" | "value" | "as" | "disabled"> & {} & ComponentCustomProperties & {} & {
|
|
1616
|
-
$slots: {
|
|
1617
|
-
startContent?(_: {}): any;
|
|
1618
|
-
default?(_: {}): any;
|
|
1619
|
-
endContent?(_: {}): any;
|
|
1620
|
-
};
|
|
1621
|
-
}) | null;
|
|
1622
1526
|
}, any>;
|
|
1623
1527
|
|
|
1624
1528
|
declare const __VLS_component_67: DefineComponent<__VLS_Props_75, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<__VLS_Props_75> & Readonly<{}>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, any>;
|
|
@@ -5004,102 +4908,6 @@ declare function __VLS_template_66(): {
|
|
|
5004
4908
|
scrollWrapperEl: HTMLDivElement;
|
|
5005
4909
|
containerEl: HTMLDivElement;
|
|
5006
4910
|
dropdownEl: HTMLDivElement;
|
|
5007
|
-
moreBtnEl: ({
|
|
5008
|
-
$: ComponentInternalInstance;
|
|
5009
|
-
$data: {};
|
|
5010
|
-
$props: {
|
|
5011
|
-
readonly variant?: "danger" | "success" | "warning" | "primary" | "secondary" | "danger-soft" | "ghost" | "outline" | "success-soft" | "tertiary" | "warning-soft" | undefined;
|
|
5012
|
-
readonly size?: "md" | "sm" | "lg" | "xs" | "xl" | undefined;
|
|
5013
|
-
readonly radius?: "md" | "sm" | "lg" | "none" | "full" | undefined;
|
|
5014
|
-
readonly isIconOnly?: boolean | undefined;
|
|
5015
|
-
readonly fullWidth?: boolean | undefined;
|
|
5016
|
-
readonly disabled?: boolean | undefined;
|
|
5017
|
-
readonly isLoading?: boolean | undefined;
|
|
5018
|
-
readonly as?: string | object | undefined;
|
|
5019
|
-
readonly class?: string | undefined;
|
|
5020
|
-
readonly value?: string | number | undefined;
|
|
5021
|
-
} & VNodeProps & AllowedComponentProps & ComponentCustomProps;
|
|
5022
|
-
$attrs: Attrs;
|
|
5023
|
-
$refs: {
|
|
5024
|
-
[x: string]: unknown;
|
|
5025
|
-
};
|
|
5026
|
-
$slots: Readonly<{
|
|
5027
|
-
[name: string]: Slot<any> | undefined;
|
|
5028
|
-
}>;
|
|
5029
|
-
$root: ComponentPublicInstance | null;
|
|
5030
|
-
$parent: ComponentPublicInstance | null;
|
|
5031
|
-
$host: Element | null;
|
|
5032
|
-
$emit: (event: string, ...args: any[]) => void;
|
|
5033
|
-
$el: any;
|
|
5034
|
-
$options: ComponentOptionsBase<Readonly<{
|
|
5035
|
-
variant?: ButtonVariants["variant"];
|
|
5036
|
-
size?: ButtonVariants["size"];
|
|
5037
|
-
radius?: ButtonVariants["radius"];
|
|
5038
|
-
isIconOnly?: boolean;
|
|
5039
|
-
fullWidth?: boolean;
|
|
5040
|
-
disabled?: boolean;
|
|
5041
|
-
isLoading?: boolean;
|
|
5042
|
-
as?: string | object;
|
|
5043
|
-
class?: string;
|
|
5044
|
-
value?: string | number;
|
|
5045
|
-
}> & Readonly<{}>, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, {
|
|
5046
|
-
size: "md" | "sm" | "lg" | "xs" | "xl";
|
|
5047
|
-
variant: "danger" | "success" | "warning" | "primary" | "secondary" | "danger-soft" | "ghost" | "outline" | "success-soft" | "tertiary" | "warning-soft";
|
|
5048
|
-
fullWidth: boolean;
|
|
5049
|
-
isIconOnly: boolean;
|
|
5050
|
-
isLoading: boolean;
|
|
5051
|
-
radius: "md" | "sm" | "lg" | "none" | "full";
|
|
5052
|
-
value: string | number;
|
|
5053
|
-
as: string | object;
|
|
5054
|
-
disabled: boolean;
|
|
5055
|
-
}, {}, string, {}, GlobalComponents, GlobalDirectives, string, ComponentProvideOptions> & {
|
|
5056
|
-
beforeCreate?: (() => void) | (() => void)[];
|
|
5057
|
-
created?: (() => void) | (() => void)[];
|
|
5058
|
-
beforeMount?: (() => void) | (() => void)[];
|
|
5059
|
-
mounted?: (() => void) | (() => void)[];
|
|
5060
|
-
beforeUpdate?: (() => void) | (() => void)[];
|
|
5061
|
-
updated?: (() => void) | (() => void)[];
|
|
5062
|
-
activated?: (() => void) | (() => void)[];
|
|
5063
|
-
deactivated?: (() => void) | (() => void)[];
|
|
5064
|
-
beforeDestroy?: (() => void) | (() => void)[];
|
|
5065
|
-
beforeUnmount?: (() => void) | (() => void)[];
|
|
5066
|
-
destroyed?: (() => void) | (() => void)[];
|
|
5067
|
-
unmounted?: (() => void) | (() => void)[];
|
|
5068
|
-
renderTracked?: ((e: DebuggerEvent) => void) | ((e: DebuggerEvent) => void)[];
|
|
5069
|
-
renderTriggered?: ((e: DebuggerEvent) => void) | ((e: DebuggerEvent) => void)[];
|
|
5070
|
-
errorCaptured?: ((err: unknown, instance: ComponentPublicInstance | null, info: string) => boolean | void) | ((err: unknown, instance: ComponentPublicInstance | null, info: string) => boolean | void)[];
|
|
5071
|
-
};
|
|
5072
|
-
$forceUpdate: () => void;
|
|
5073
|
-
$nextTick: typeof nextTick;
|
|
5074
|
-
$watch<T extends string | ((...args: any) => any)>(source: T, cb: T extends (...args: any) => infer R ? (...args: [R, R, OnCleanup]) => any : (...args: [any, any, OnCleanup]) => any, options?: WatchOptions): WatchStopHandle;
|
|
5075
|
-
} & Readonly<{
|
|
5076
|
-
size: "md" | "sm" | "lg" | "xs" | "xl";
|
|
5077
|
-
variant: "danger" | "success" | "warning" | "primary" | "secondary" | "danger-soft" | "ghost" | "outline" | "success-soft" | "tertiary" | "warning-soft";
|
|
5078
|
-
fullWidth: boolean;
|
|
5079
|
-
isIconOnly: boolean;
|
|
5080
|
-
isLoading: boolean;
|
|
5081
|
-
radius: "md" | "sm" | "lg" | "none" | "full";
|
|
5082
|
-
value: string | number;
|
|
5083
|
-
as: string | object;
|
|
5084
|
-
disabled: boolean;
|
|
5085
|
-
}> & Omit<Readonly<{
|
|
5086
|
-
variant?: ButtonVariants["variant"];
|
|
5087
|
-
size?: ButtonVariants["size"];
|
|
5088
|
-
radius?: ButtonVariants["radius"];
|
|
5089
|
-
isIconOnly?: boolean;
|
|
5090
|
-
fullWidth?: boolean;
|
|
5091
|
-
disabled?: boolean;
|
|
5092
|
-
isLoading?: boolean;
|
|
5093
|
-
as?: string | object;
|
|
5094
|
-
class?: string;
|
|
5095
|
-
value?: string | number;
|
|
5096
|
-
}> & Readonly<{}>, "size" | "variant" | "fullWidth" | "isIconOnly" | "isLoading" | "radius" | "value" | "as" | "disabled"> & {} & ComponentCustomProperties & {} & {
|
|
5097
|
-
$slots: {
|
|
5098
|
-
startContent?(_: {}): any;
|
|
5099
|
-
default?(_: {}): any;
|
|
5100
|
-
endContent?(_: {}): any;
|
|
5101
|
-
};
|
|
5102
|
-
}) | null;
|
|
5103
4911
|
};
|
|
5104
4912
|
rootEl: any;
|
|
5105
4913
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@auronui/vue",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.14",
|
|
4
4
|
"description": "Vue 3 85 components with full visual and functional parity",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"tailwind-merge": "3.5.0",
|
|
70
70
|
"tailwind-variants": "3.2.2",
|
|
71
71
|
"vee-validate": "^4.15.1",
|
|
72
|
-
"@auronui/styles": "1.0.
|
|
72
|
+
"@auronui/styles": "1.0.14"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
75
|
"@chialab/vitest-axe": "0.19.1",
|