UNPKG

@varlet/ui

Version:

A Vue3 component library based on Material Design 2 and 3, supporting mobile and desktop.

248 lines (247 loc) • 8.55 kB
var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; import { computed, defineComponent, onActivated, ref, Transition, watch } from "vue"; import { call, clamp, doubleRaf, isNumber } from "@varlet/shared"; import { onWindowResize } from "@varlet/use"; import VarSticky from "../sticky/index.mjs"; import { createNamespace, formatElevation } from "../utils/components.mjs"; import { scrollTo, toSizeUnit } from "../utils/elements.mjs"; import { linear } from "../utils/shared.mjs"; import { props } from "./props.mjs"; import { useTabList } from "./provide.mjs"; const { name, n, classes } = createNamespace("tabs"); import { renderSlot as _renderSlot, normalizeClass as _normalizeClass, normalizeStyle as _normalizeStyle, createElementVNode as _createElementVNode, mergeProps as _mergeProps, resolveDynamicComponent as _resolveDynamicComponent, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock } from "vue"; function __render__(_ctx, _cache) { return _openBlock(), _createBlock(_resolveDynamicComponent(_ctx.sticky ? _ctx.n("$-sticky") : _ctx.Transition), { ref: _ctx.sticky ? "stickyComponent" : void 0, "css-mode": _ctx.sticky ? _ctx.stickyCssMode : void 0, "offset-top": _ctx.sticky ? _ctx.offsetTop : void 0, "z-index": _ctx.sticky ? _ctx.stickyZIndex : void 0 }, { default: _withCtx(() => [ _createElementVNode( "div", _mergeProps({ class: _ctx.classes( _ctx.n(), _ctx.n("$--box"), _ctx.n(`--item-${_ctx.itemDirection}`), _ctx.n(`--layout-${_ctx.layoutDirection}-padding`), _ctx.formatElevation(_ctx.elevation, 4), [_ctx.fixedBottom, _ctx.n("--fixed-bottom")], [_ctx.safeArea, _ctx.n("--safe-area")] ), style: { background: _ctx.color } }, _ctx.$attrs), [ _createElementVNode( "div", { ref: "scrollerEl", class: _normalizeClass( _ctx.classes( _ctx.n("tab-wrap"), [_ctx.localScrollable, _ctx.n(`--layout-${_ctx.layoutDirection}-scrollable`)], _ctx.n(`--layout-${_ctx.layoutDirection}`) ) ) }, [ _renderSlot(_ctx.$slots, "default"), _createElementVNode( "div", { class: _normalizeClass(_ctx.classes(_ctx.n("indicator"), _ctx.n(`--layout-${_ctx.layoutDirection}${_ctx.indicatorPosition}-indicator`))), style: _normalizeStyle({ width: _ctx.layoutDirection === "horizontal" ? _ctx.indicatorWidth : _ctx.toSizeUnit(_ctx.indicatorSize), height: _ctx.layoutDirection === "horizontal" ? _ctx.toSizeUnit(_ctx.indicatorSize) : _ctx.indicatorHeight, transform: _ctx.layoutDirection === "horizontal" ? `translateX(${_ctx.indicatorX})` : `translateY(${_ctx.indicatorY})` }) }, [ _createElementVNode( "div", { class: _normalizeClass(_ctx.classes(_ctx.n("indicator-inner"), _ctx.n(`--layout-${_ctx.layoutDirection}-indicator-inner`))), style: _normalizeStyle({ background: _ctx.indicatorColor || _ctx.activeColor }) }, null, 6 /* CLASS, STYLE */ ) ], 6 /* CLASS, STYLE */ ) ], 2 /* CLASS */ ) ], 16 /* FULL_PROPS */ ) ]), _: 3 /* FORWARDED */ }, 8, ["css-mode", "offset-top", "z-index"]); } const __sfc__ = defineComponent({ name, components: { VarSticky }, inheritAttrs: false, props, setup(props2) { const indicatorWidth = ref("0px"); const indicatorHeight = ref("0px"); const indicatorX = ref("0px"); const indicatorY = ref("0px"); const localScrollable = ref(false); const scrollerEl = ref(null); const active = computed(() => props2.active); const activeColor = computed(() => props2.activeColor); const inactiveColor = computed(() => props2.inactiveColor); const disabledColor = computed(() => props2.disabledColor); const itemDirection = computed(() => props2.itemDirection); const stickyComponent = ref(null); const indicatorPosition = computed(() => props2.indicatorPosition === "reverse" ? "-reverse" : ""); const { tabList, bindTabList, length } = useTabList(); const tabsProvider = { active, activeColor, inactiveColor, disabledColor, itemDirection, resize, onTabClick }; bindTabList(tabsProvider); watch( () => length.value, () => __async(this, null, function* () { yield doubleRaf(); resize(); }) ); watch(() => [props2.active, props2.scrollable], resize); onActivated(resize); onWindowResize(resize); function onTabClick(tab) { var _a; const currentActive = (_a = tab.name.value) != null ? _a : tab.index.value; const { active: active2, onChange, onClick } = props2; call(props2["onUpdate:active"], currentActive); call(onClick, currentActive); currentActive !== active2 && call(onChange, currentActive); } function matchName() { return tabList.find(({ name: name2 }) => props2.active === name2.value); } function matchIndex(activeIndex) { return tabList.find(({ index }) => (activeIndex != null ? activeIndex : props2.active) === index.value); } function matchBoundary() { if (length.value === 0) { return; } const { active: active2 } = props2; if (isNumber(active2)) { const activeIndex = clamp(active2, 0, length.value - 1); call(props2["onUpdate:active"], activeIndex); return matchIndex(activeIndex); } } function watchScrollable() { localScrollable.value = props2.scrollable === "always" || tabList.length >= 5; } function moveIndicator({ element }) { const el = element.value; if (!el) { return; } if (props2.layoutDirection === "horizontal") { indicatorWidth.value = `${el.offsetWidth}px`; indicatorX.value = `${el.offsetLeft}px`; } else { indicatorHeight.value = `${el.offsetHeight}px`; indicatorY.value = `${el.offsetTop}px`; } } function scrollToCenter({ element }) { if (!localScrollable.value) { return; } const scroller = scrollerEl.value; const el = element.value; if (props2.layoutDirection === "horizontal") { const left = el.offsetLeft + el.offsetWidth / 2 - scroller.offsetWidth / 2; scrollTo(scroller, { left, animation: linear }); } else { const top = el.offsetTop + el.offsetHeight / 2 - scroller.offsetHeight / 2; scrollTo(scroller, { top, animation: linear }); } } function resize() { const tab = matchName() || matchIndex() || matchBoundary(); if (!tab || tab.disabled.value) { return; } watchScrollable(); moveIndicator(tab); scrollToCenter(tab); } function resizeSticky() { return __async(this, null, function* () { if (props2.sticky && stickyComponent.value) { yield stickyComponent.value.resize(); } }); } return { stickyComponent, indicatorWidth, indicatorHeight, indicatorX, indicatorY, indicatorPosition, localScrollable, scrollerEl, Transition, toSizeUnit, n, classes, resize, resizeSticky, formatElevation }; } }); __sfc__.render = __render__; var stdin_default = __sfc__; export { stdin_default as default };