UNPKG

@opensig/opendesign

Version:

<p align="center"><img src="../docs/public/opendesign-logo-light.png"/></p> <h1 align="center">opendesign</h1> <p align="center">一个 Vue 3 组件库</p> <p align="center"><b>皮肤可定制,使用 TypeScript</b></p>

302 lines (301 loc) 10.7 kB
"use strict"; const vue = require("vue"); const provide = require("./provide.js"); const icons = require("../_utils/icons.js"); const types = require("./types.js"); const useScreen = require("../hooks/use-screen.js"); const onResize = require("../directives/on-resize.js"); const helper = require("../_utils/helper.js"); const global = require("../_utils/global.js"); const _hoisted_1 = { key: 0, class: "o-tab-head-prefix" }; const _hoisted_2 = { class: "o-tab-navs" }; const _hoisted_3 = { key: 1, class: "o-tab-head-suffix" }; const _sfc_main = /* @__PURE__ */ vue.defineComponent({ __name: "OTab", props: types.tabProps, emits: ["update:modelValue", "change", "delete", "add"], setup(__props, { emit: __emit }) { const props = __props; const emits = __emit; const { isPhonePad } = useScreen.useScreen(); const activeKey = vue.ref(props.modelValue); const anchorStyle = vue.ref({}); const navWrapRef = vue.ref(null); const navsRef = vue.ref(null); const bodyRef = vue.ref(null); const valueSet = []; let activeNavEl = null; const isScroll = vue.ref(false); const prevDisabled = vue.ref(true); const nextDisabled = vue.ref(true); const showArrow = vue.computed(() => { return !isPhonePad.value && isScroll.value; }); const scrollActiveNavIntoView = () => { var _a; if (isScroll.value && activeNavEl && navWrapRef.value) { const { offsetLeft } = activeNavEl; const { scrollLeft, clientWidth } = navWrapRef.value; const center = scrollLeft + clientWidth / 2; if (offsetLeft > center || offsetLeft < center) { (_a = navWrapRef.value) == null ? void 0 : _a.scrollTo({ left: offsetLeft - clientWidth / 2, behavior: "smooth" }); } } }; const onWrapScroll = helper.debounceRAF(() => { if (navWrapRef.value) { const { scrollLeft, scrollWidth, clientWidth } = navWrapRef.value; prevDisabled.value = scrollLeft === 0; nextDisabled.value = scrollLeft + 1 >= scrollWidth - clientWidth; } }); const updateNavScroll = () => { if (navWrapRef.value && navsRef.value) { const { clientWidth: wrapWidth } = navWrapRef.value; const { clientWidth: width } = navsRef.value; isScroll.value = wrapWidth < width; if (isScroll.value) { vue.nextTick(() => { onWrapScroll(); scrollActiveNavIntoView(); }); } } }; vue.watch( () => props.modelValue, (v) => { activeKey.value = v; } ); const updateAnchor = () => { if (!activeNavEl) { return; } const { clientWidth, offsetLeft } = activeNavEl; anchorStyle.value = { transform: `translate3d(${offsetLeft}px, 0px, 0px)`, width: `${clientWidth}px` }; }; vue.watch(() => isScroll.value, updateAnchor); const updateValue = (value, navEl) => { emits("update:modelValue", value); activeNavEl = navEl; if (activeKey.value !== value) { emits("change", value, activeKey.value); activeKey.value = value; } if (navEl) { activeNavEl = navEl; updateAnchor(); scrollActiveNavIntoView(); } }; const isAdding = vue.ref(false); const initValue = (value, navEl) => { if (!valueSet.includes(value)) { valueSet.push(value); } if (activeKey.value === void 0 || isAdding.value) { updateValue(value, navEl); isAdding.value = false; } if (activeKey.value === value && navEl) { activeNavEl = navEl; updateAnchor(); } }; const onDeletePane = (value) => { emits("delete", value); const idx = valueSet.indexOf(value); if (activeKey.value === value) { activeKey.value = valueSet[idx > 0 ? idx - 1 : 0]; emits("change", activeKey.value, value); } valueSet.splice(idx, 1); }; const onAddNav = (e) => { emits("add", e); if (!props.addInactive) { isAdding.value = true; } }; vue.provide(provide.tabInjectKey, { lazy: props.lazy, navsRef, bodyRef, activeValue: activeKey, updateValue, onDeletePane, initValue }); const onHeadResize = helper.debounceRAF(() => { updateAnchor(); updateNavScroll(); scrollActiveNavIntoView(); }); const navScroll = (to) => { if (!navWrapRef.value) { return; } const { clientWidth } = navWrapRef.value; const i = to === "prev" ? -1 : to === "next" ? 1 : 0; navWrapRef.value.scrollBy({ left: i * clientWidth, behavior: "smooth" }); }; return (_ctx, _cache) => { return vue.openBlock(), vue.createElementBlock( "div", { class: vue.normalizeClass(["o-tab", [`o-tab-${props.variant}`, `o-tab-${props.size || vue.unref(global.defaultSize)}`]]) }, [ vue.createElementVNode( "div", { class: vue.normalizeClass(["o-tab-head", [ { "with-act": _ctx.$slots.suffix || _ctx.$slots.prefix, "show-line": props.line }, props.headerClass ]]) }, [ _ctx.$slots.prefix ? vue.withDirectives((vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [ vue.renderSlot(_ctx.$slots, "prefix") ])), [ [vue.unref(onResize.vOnResize), vue.unref(onHeadResize)] ]) : vue.createCommentVNode("v-if", true), vue.createElementVNode("div", _hoisted_2, [ vue.createElementVNode( "div", { class: vue.normalizeClass([{ "o-tab-navs-scrollable": isScroll.value }, "o-tab-navs-container"]) }, [ showArrow.value ? (vue.openBlock(), vue.createElementBlock( "div", { key: 0, class: vue.normalizeClass(["o-tab-nav-btn prev", { "o-tab-nav-btn-disabled": prevDisabled.value }]), onClick: _cache[0] || (_cache[0] = ($event) => navScroll("prev")) }, [ vue.createVNode(vue.unref(icons.IconChevronLeft)) ], 2 /* CLASS */ )) : vue.createCommentVNode("v-if", true), vue.createElementVNode( "div", { ref_key: "navWrapRef", ref: navWrapRef, class: "o-tab-navs-wrap o-hide-scrollbar", onScrollPassive: _cache[1] || (_cache[1] = //@ts-ignore (...args) => vue.unref(onWrapScroll) && vue.unref(onWrapScroll)(...args)) }, [ vue.withDirectives(vue.createElementVNode( "div", { class: "o-tab-nav-list", ref_key: "navsRef", ref: navsRef }, null, 512 /* NEED_PATCH */ ), [ [vue.unref(onResize.vOnResize), vue.unref(onHeadResize)] ]), props.variant === "text" ? (vue.openBlock(), vue.createElementBlock( "div", { key: 0, class: "o-tab-nav-anchor", style: vue.normalizeStyle(anchorStyle.value) }, [ vue.renderSlot(_ctx.$slots, "anchor", {}, () => [ _cache[3] || (_cache[3] = vue.createElementVNode( "div", { class: "o-tab-nav-anchor-line" }, null, -1 /* HOISTED */ )) ]) ], 4 /* STYLE */ )) : vue.createCommentVNode("v-if", true) ], 544 /* NEED_HYDRATION, NEED_PATCH */ ), showArrow.value ? (vue.openBlock(), vue.createElementBlock( "div", { key: 1, class: vue.normalizeClass(["o-tab-nav-btn next", { "o-tab-nav-btn-disabled": nextDisabled.value }]), onClick: _cache[2] || (_cache[2] = ($event) => navScroll("next")) }, [ vue.createVNode(vue.unref(icons.IconChevronRight)) ], 2 /* CLASS */ )) : vue.createCommentVNode("v-if", true) ], 2 /* CLASS */ ), props.addable ? (vue.openBlock(), vue.createElementBlock("div", { key: 0, class: "o-tab-nav-add", onClick: onAddNav }, [ vue.createVNode(vue.unref(icons.IconAdd)) ])) : vue.createCommentVNode("v-if", true) ]), _ctx.$slots.suffix ? vue.withDirectives((vue.openBlock(), vue.createElementBlock("div", _hoisted_3, [ vue.renderSlot(_ctx.$slots, "suffix") ])), [ [vue.unref(onResize.vOnResize), vue.unref(onHeadResize)] ]) : vue.createCommentVNode("v-if", true) ], 2 /* CLASS */ ), vue.createElementVNode( "div", { ref_key: "bodyRef", ref: bodyRef, class: "o-tab-body" }, [ vue.renderSlot(_ctx.$slots, "default") ], 512 /* NEED_PATCH */ ) ], 2 /* CLASS */ ); }; } }); module.exports = _sfc_main;