@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
JavaScript
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
};