vexip-ui
Version:
A Vue 3 UI library, Highly customizability, full TypeScript, performance pretty good
1 lines • 12.9 kB
Source Map (JSON)
{"version":3,"file":"tab-nav.vue2.cjs","sources":["../../../components/tab-nav/tab-nav.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { Icon } from '@/components/icon'\nimport { Renderer } from '@/components/renderer'\nimport { ResizeObserver } from '@/components/resize-observer'\nimport { Scroll } from '@/components/scroll'\nimport { TabNavItem } from '@/components/tab-nav-item'\n\nimport { computed, onMounted, provide, reactive, ref, toRef, watch } from 'vue'\n\nimport { emitEvent, useIcons, useNameHelper, useProps } from '@vexip-ui/config'\nimport { useDisplay } from '@vexip-ui/hooks'\nimport { debounceMinor, isNull } from '@vexip-ui/utils'\nimport { tabNavProps } from './props'\nimport { TAB_NAV_STATE, trackStyleMap } from './symbol'\n\nimport type { ChangeEvent, ItemState, TabNavSlots } from './symbol'\n\ndefineOptions({ name: 'TabNav' })\n\nconst _props = defineProps(tabNavProps)\nconst props = useProps('tabNav', _props, {\n active: {\n default: null,\n static: true,\n },\n card: false,\n options: {\n default: () => [],\n static: true,\n },\n align: 'left',\n placement: 'top',\n closable: false,\n showAdd: false,\n slots: () => ({}),\n})\n\nconst emit = defineEmits(['update:active'])\n\nconst slots = defineSlots<TabNavSlots>()\n\nconst nh = useNameHelper('tab-nav')\nconst icons = useIcons()\nconst currentActive = ref(props.active)\nconst markerPosition = ref(0)\nconst markerSize = ref(0)\nconst itemStates = new Set<ItemState>()\n\nconst wrapper = useDisplay(updateMarkerPosition)\nconst scroll = ref<InstanceType<typeof Scroll>>()\n\nconst className = computed(() => {\n return {\n [nh.b()]: true,\n [nh.bs('vars')]: true,\n [nh.bm('inherit')]: props.inherit,\n [nh.bm(`align-${props.align}`)]: true,\n [nh.bm(props.placement)]: true,\n [nh.bm('card')]: props.card,\n }\n})\nconst markerStyle = computed(() => {\n const [position, length] = trackStyleMap[props.placement]\n\n return {\n [position]: `${markerPosition.value}px`,\n [length]: `${markerSize.value}px`,\n }\n})\nconst items = computed(() => {\n return props.options.map(item => {\n if (typeof item === 'string' || typeof item === 'number') {\n return { label: item }\n }\n\n return item\n })\n})\nconst scrollMode = computed(() => {\n return props.placement === 'top' || props.placement === 'bottom' ? 'horizontal-exact' : 'vertical'\n})\n\nconst refreshLabels = debounceMinor(() => {\n const total = itemStates.size\n\n Array.from(itemStates).forEach((item, index) => {\n item.index = index + 1\n item.total = total\n\n if (isNull(item.label)) {\n item.label = index + 1\n }\n })\n\n if (itemStates.size >= 1 && isActiveEmpty()) {\n currentActive.value = Array.from(itemStates)[0].label\n }\n})\n\nprovide(\n TAB_NAV_STATE,\n reactive({\n currentActive,\n closable: toRef(props, 'closable'),\n increaseItem,\n decreaseItem,\n handleActive,\n handleClose,\n refreshLabels,\n }),\n)\n\nwatch(\n () => props.active,\n value => {\n currentActive.value = value\n updateMarkerPosition()\n },\n)\nwatch(\n () => props.placement,\n () => {\n requestAnimationFrame(updateMarkerPosition)\n },\n)\n\nonMounted(updateMarkerPosition)\n\ndefineExpose({\n items,\n wrapper,\n scroll,\n updateMarkerPosition,\n handleAdd,\n})\n\nfunction isActiveEmpty() {\n return isNull(currentActive.value) || currentActive.value === ''\n}\n\nfunction increaseItem(item: ItemState) {\n itemStates.add(item)\n refreshLabels()\n}\n\nfunction decreaseItem(item: ItemState) {\n itemStates.delete(item)\n refreshLabels()\n}\n\nfunction handleActive(label: string | number) {\n currentActive.value = label\n\n updateMarkerPosition()\n emit('update:active', label)\n emitEvent(props.onChange as ChangeEvent, label)\n}\n\nfunction handleAdd() {\n emitEvent(props.onAdd)\n}\n\nfunction handleClose(label: string | number) {\n emitEvent(props.onClose as ChangeEvent, label)\n\n requestAnimationFrame(updateMarkerPosition)\n}\n\nfunction updateMarkerPosition() {\n const activeItem = Array.from(itemStates).find(item => item.label === currentActive.value)\n\n if (activeItem?.el) {\n if (props.placement === 'top' || props.placement === 'bottom') {\n markerPosition.value = activeItem.el.offsetLeft\n markerSize.value = activeItem.el.offsetWidth\n } else {\n markerPosition.value = activeItem.el.offsetTop\n markerSize.value = activeItem.el.offsetHeight\n }\n } else {\n markerPosition.value = 0\n markerSize.value = 0\n }\n}\n</script>\n\n<template>\n <div ref=\"wrapper\" :class=\"className\" tabindex=\"-1\">\n <ResizeObserver :on-resize=\"updateMarkerPosition\">\n <div :class=\"[nh.be('extra'), nh.bem('extra', 'prefix')]\">\n <div v-if=\"slots.prefix || props.slots.prefix\" :class=\"nh.be('prefix')\">\n <slot name=\"prefix\">\n <Renderer :renderer=\"props.slots.prefix\"></Renderer>\n </slot>\n </div>\n </div>\n </ResizeObserver>\n <Scroll\n ref=\"scroll\"\n :class=\"nh.be('scroll')\"\n :mode=\"scrollMode\"\n :delta-x=\"40\"\n :delta-y=\"40\"\n scroll-tag=\"ul\"\n :scroll-class=\"nh.be('list')\"\n :scroll-attrs=\"{ role: 'tablist' }\"\n >\n <slot>\n <TabNavItem\n v-for=\"item in items\"\n :key=\"item.label\"\n :label=\"item.label\"\n :icon=\"item.icon\"\n :disabled=\"item.disabled\"\n :closable=\"item.closable\"\n @toggle=\"item.onToggle\"\n >\n {{ item.content || item.label }}\n </TabNavItem>\n </slot>\n <li v-if=\"props.showAdd || slots.add || props.slots.add\" :class=\"nh.be('item')\" role=\"none\">\n <div :class=\"nh.be('pad')\"></div>\n <button type=\"button\" :class=\"nh.be('add')\" @click=\"handleAdd\">\n <slot name=\"add\">\n <Renderer :renderer=\"props.slots.add\">\n <Icon v-bind=\"icons.plus\" :scale=\"+(icons.plus.scale || 1) * 1.2\"></Icon>\n </Renderer>\n </slot>\n </button>\n </li>\n <div\n v-if=\"!props.card\"\n :class=\"nh.be('track')\"\n role=\"none\"\n :style=\"markerStyle\"\n >\n <slot name=\"marker\">\n <Renderer :renderer=\"props.slots.marker\">\n <div :class=\"nh.be('marker')\"></div>\n </Renderer>\n </slot>\n </div>\n </Scroll>\n <ResizeObserver :on-resize=\"updateMarkerPosition\">\n <div :class=\"[nh.be('extra'), nh.bem('extra', 'suffix')]\">\n <div v-if=\"slots.suffix || props.slots.suffix\" :class=\"nh.be('suffix')\">\n <slot name=\"suffix\">\n <Renderer :renderer=\"props.slots.suffix\"></Renderer>\n </slot>\n </div>\n </div>\n </ResizeObserver>\n </div>\n</template>\n"],"names":["_props","__props","props","useProps","emit","__emit","slots","_useSlots","nh","useNameHelper","icons","useIcons","currentActive","ref","markerPosition","markerSize","itemStates","wrapper","useDisplay","updateMarkerPosition","scroll","className","computed","markerStyle","position","length","trackStyleMap","items","item","scrollMode","refreshLabels","debounceMinor","total","index","isNull","isActiveEmpty","provide","TAB_NAV_STATE","reactive","toRef","increaseItem","decreaseItem","handleActive","handleClose","watch","value","onMounted","__expose","handleAdd","label","emitEvent","activeItem","_createElementBlock","_createVNode","_unref","ResizeObserver","_createElementVNode","_normalizeClass","_renderSlot","_ctx","Renderer","Scroll","_Fragment","_renderList","_createBlock","TabNavItem","_createTextVNode","_toDisplayString","Icon","_mergeProps"],"mappings":"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"}