maz-ui
Version:
A standalone components library for Vue.Js 3 & Nuxt.Js 3
139 lines (138 loc) • 6.46 kB
JavaScript
import { defineComponent, defineAsyncComponent, ref, computed, onBeforeMount, onMounted, watch, createElementBlock, openBlock, normalizeClass, createElementVNode, normalizeStyle, Fragment, renderList, renderSlot, createTextVNode, createBlock, createCommentVNode, toDisplayString, unref, mergeProps, withCtx } from "vue";
import { s as sleep } from "../chunks/sleep.BLRH1qZG.js";
import { useInjectStrict } from "../composables/useInjectStrict.js";
import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper.B--vMWp3.js";
import '../assets/MazTabsBar.BRr1XiYu.css';const _hoisted_1 = ["disabled", "onClick"], _sfc_main = /* @__PURE__ */ defineComponent({
__name: "MazTabsBar",
props: {
items: {},
persistent: { type: Boolean, default: !1 },
queryParam: { default: "tab" },
block: { type: Boolean, default: !1 },
elevation: { type: Boolean, default: !1 },
autoScroll: { type: Boolean, default: !0 },
bordered: { type: Boolean, default: !0 }
},
setup(__props) {
const MazBadge = defineAsyncComponent(() => import("./MazBadge.js")), { currentTab, updateCurrentTab } = useInjectStrict("maz-tabs");
function selectTab(tabIndex) {
updateCurrentTab(tabIndex + 1), __props.persistent && addOrUpdateQueryParamTab(tabIndex + 1);
}
const tabsBarRef = ref(), itemRefs = ref([]);
function isActiveTab(index) {
return currentTab.value === index + 1;
}
function addElementToItemRefs({
mazBtn,
index
}) {
itemRefs.value[index] = mazBtn && "$el" in mazBtn ? mazBtn.$el : mazBtn;
}
const normalizedItems = computed(
() => __props.items.map((item) => ({
label: typeof item == "string" ? item : item.label,
disabled: typeof item == "string" ? !1 : item.disabled ?? !1,
badge: typeof item == "string" ? void 0 : item.badge
}))
), tabsIndicatorState = ref(), tabsBarHasScrollAnimation = ref(!1);
async function setIndicatorAndScroll() {
if (!__props.autoScroll)
return;
await sleep(150);
const tabsBar = tabsBarRef.value, activeTab = itemRefs.value[currentTab.value - 1];
if (!tabsBar || !activeTab)
return;
const scrollOffset = 50;
if (activeTab.offsetLeft - scrollOffset < tabsBar.scrollLeft || activeTab.offsetLeft + activeTab.offsetWidth > tabsBar.scrollLeft + tabsBar.clientWidth) {
const tabBarPaddingLeft = globalThis.getComputedStyle(tabsBar, "padding-left").paddingLeft, tabsBarPaddingOffset = Number(tabBarPaddingLeft.slice(0, -2));
tabsBar.scrollTo({
left: activeTab.offsetLeft - tabsBarPaddingOffset - scrollOffset,
behavior: tabsBarHasScrollAnimation.value ? "smooth" : "instant"
});
}
if (typeof currentTab.value != "number")
return;
const indicatorWidth = activeTab?.offsetWidth ?? 0, indicatorHeight = activeTab?.offsetHeight ?? 0, translateXValue = activeTab?.offsetLeft ?? 0;
tabsIndicatorState.value = {
transform: `translateX(${translateXValue}px)`,
width: `${indicatorWidth}px`,
height: `${indicatorHeight}px`
}, tabsBarHasScrollAnimation.value = !0;
}
function getTabStyle(index, disabled) {
return disabled ? {} : currentTab.value === index + 1 ? "color: hsl(var(--maz-foreground))" : "color: hsl(var(--maz-muted))";
}
onBeforeMount(() => {
(currentTab.value < 1 || currentTab.value > normalizedItems.value.length) && console.error(
`[maz-ui](MazTabsBar) The model-value should be between 1 and ${normalizedItems.value.length}`
);
}), onMounted(() => {
(__props.persistent || currentTab.value) && setIndicatorAndScroll();
}), watch(
() => [currentTab.value, normalizedItems.value],
() => {
setIndicatorAndScroll();
}
);
function getQueryParamTab() {
const urlActuelle = new URL(globalThis.location.href);
return Number(urlActuelle.searchParams.get(__props.queryParam));
}
function addOrUpdateQueryParamTab(tab) {
const urlActuelle = new URL(globalThis.location.href);
urlActuelle.searchParams.set(__props.queryParam, String(tab)), globalThis.history.replaceState({}, document.title, urlActuelle.toString());
}
return onMounted(() => {
__props.persistent && updateCurrentTab(getQueryParamTab() || currentTab.value || 1);
}), (_ctx, _cache) => (openBlock(), createElementBlock("div", {
ref_key: "tabsBarRef",
ref: tabsBarRef,
class: normalizeClass(["m-tabs-bar m-reset-css", {
"--block": __props.block,
"--elevation": __props.elevation,
"--bordered": __props.bordered
}])
}, [
createElementVNode("div", {
class: normalizeClass(["m-tabs-bar__indicator", { "--animated": tabsBarHasScrollAnimation.value }]),
style: normalizeStyle([tabsIndicatorState.value])
}, null, 6),
(openBlock(!0), createElementBlock(Fragment, null, renderList(normalizedItems.value, (item, index) => (openBlock(), createElementBlock("button", {
key: index,
ref_for: !0,
ref: (mazBtn) => addElementToItemRefs({ mazBtn, index }),
class: normalizeClass([{ "--active": isActiveTab(index), "--disabled": item.disabled }, "m-tabs-bar__item"]),
disabled: item.disabled,
style: normalizeStyle(getTabStyle(index, item.disabled)),
onClick: ($event) => item.disabled ? void 0 : selectTab(index)
}, [
renderSlot(_ctx.$slots, "item", {
item,
active: isActiveTab(index),
index
}, () => [
createTextVNode(toDisplayString(item.label) + " ", 1),
item.badge ? (openBlock(), createBlock(unref(MazBadge), mergeProps({
key: 0,
ref_for: !0
}, item.badge, {
size: item.badge.size ?? "0.7rem",
class: "m-tabs-bar__item__badge"
}), {
default: withCtx(() => [
renderSlot(_ctx.$slots, "badge-content", {
content: item.badge.content
}, () => [
createTextVNode(toDisplayString(item.badge.content), 1)
], !0)
]),
_: 2
}, 1040, ["size"])) : createCommentVNode("", !0)
], !0)
], 14, _hoisted_1))), 128))
], 2));
}
}), MazTabsBar = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-a10056dd"]]);
export {
MazTabsBar as default
};