@stihl-design-system/components
Version:
Welcome to the STIHL Design System react component library.
210 lines (209 loc) • 7.2 kB
JavaScript
"use client";
import { jsxs as k, jsx as h } from "react/jsx-runtime";
import { c as D } from "./chunks/index.DL9mof6u.js";
import { useState as E, useRef as v, useEffect as ot } from "react";
import { g as f, i as C } from "./chunks/is-animation-disabled.B-V_68K-.js";
import { h as nt } from "./chunks/has-window.ut_-aShB.js";
import { g as st } from "./chunks/helpers.CexwVao7.js";
import { u as W } from "./chunks/useIsomorphicLayoutEffect.CnJ9AMFS.js";
import "./chunks/index.D-sRdssb.js";
import { D as X } from "./chunks/Button.Cn5yg7dG.js";
import { D as ct } from "./chunks/Icon.CDLyB7Pv.js";
import { NumberIndicator as it } from "./numberindicator.BdnPMogE.js";
import { g as at, a as j } from "./chunks/TabPane.utils.DG16Y2uD.js";
import { s as i, N as lt } from "./chunks/NavigationTabList.G_l0GiUa.js";
const g = 48, yt = ({
aria: q,
id: L,
selectedTabIndex: n,
setSelectedTabIndex: F,
tabs: l,
alignment: I = "left",
className: G,
defaultSelectedTabIndex: Q = 0,
isNavigation: y,
onTabChange: z,
...J
}) => {
const [A, u] = E(Q), [U, V] = E(!1), [Y, Z] = E(!1), m = v([]), p = v(null), c = v(null), a = v(null), w = v(!1), H = v(n), T = () => {
P(), x();
};
W(() => {
const e = new ResizeObserver(T);
return c.current && e.observe(c.current), () => {
e.disconnect();
};
}, []), W(() => {
const e = [
"18px 'STIHL Contraface Digital Text Regular'",
// utility large - Tab
"18px 'STIHL Contraface Digital Text Bold'",
// utility large bold - Tab active
"14px 'STIHL Contraface Digital Text Demi'"
// utility small demi - Number indicator
];
Promise.all(e.map((o) => document.fonts.load(o))).then(() => {
N(n), R("next", n, "instant"), P(), w.current = !0;
}).catch((o) => {
throw new Error(st("DSTabs", `The component requires the fonts to be loaded: ${o}`));
});
const t = () => {
!w.current || !a.current || (r.matches ? a.current.style.transitionDuration = "0s" : a.current.style.transitionDuration = "");
}, r = window.matchMedia("(prefers-reduced-motion: reduce)");
return r.addEventListener("change", t), c.current?.addEventListener("scroll", T), () => {
r.removeEventListener("change", t), c.current?.removeEventListener("scroll", T);
};
}, [l, I]), W(() => {
if (w.current && (N(n), y)) {
const e = M(n);
u(n), R(e, n);
}
H.current = n;
}, [n]), ot(() => {
w.current && m.current[A]?.focus();
}, [A]);
const b = (e) => {
const t = M(e);
F(e), u(e), R(t, e), z && z(e);
}, M = (e) => {
const t = f(c.current), r = f(m.current[e]);
let o = "next";
return r.left - g < t.left ? o = "prev" : r.right + g > t.right ? o = "next" : o = n < e ? "next" : "prev", o;
}, P = () => {
if (c.current && p.current) {
const e = f(c.current), t = f(p.current);
V(t.left < e.left), Z(t.right > e.right + 4);
}
}, O = (e = 0) => {
nt && a.current && !C() && setTimeout(() => {
a.current && (a.current.style.transitionDuration = "250ms");
}, e);
}, x = () => {
a.current && (a.current.style.transitionDuration = "0s", N(H.current), O());
}, N = (e) => {
const t = a.current, r = f(m.current[e]), o = f(p.current), s = r.left - o.left;
t && (w.current ? (t.style.width = `${r.width}px`, t.style.transform = `translateX(${s}px)`) : (t.style.transitionDuration = "0s", t.style.transform = `translateX(${s}px)`, t.style.width = `${r.width}px`, O(50)));
}, _ = (e, t) => {
let r;
switch (e.key) {
case "ArrowLeft":
r = (t > 0 ? t : l.length) - 1, u(r);
break;
case "ArrowRight":
r = (t + 1) % l.length, u(r);
break;
case "Home":
r = 0, u(r);
break;
case "End":
r = l.length - 1, u(r);
break;
case "Enter":
case " ":
b(t);
return;
default:
return;
}
if (r !== void 0) {
const o = r > t ? "next" : "prev";
setTimeout(() => R(o, r), 0);
}
e.preventDefault();
}, tt = (e, t) => {
let r;
switch (e.key) {
case "Tab":
if (e.shiftKey) {
r = t - 1 < 0 ? 0 : t - 1, u(r), t !== 0 && e.preventDefault();
break;
} else
r = t + 1 > l.length - 1 ? t : t + 1, u(r), t !== l.length - 1 && e.preventDefault();
break;
case "Enter":
b(t);
return;
default:
return;
}
if (r !== void 0) {
const o = r > t ? "next" : "prev";
setTimeout(() => R(o, r), 0);
}
}, R = (e, t, r = "smooth") => {
const o = m.current[t], s = c.current, d = f(o), S = f(s);
let B;
if (!(!o || !s)) {
if (e === "prev") {
if (d.left - g > S.left)
return;
B = o.offsetLeft - g;
} else {
if (d.right + g < S.right)
return;
B = o.offsetLeft + o.offsetWidth - S.width + g;
}
s.scrollTo({
left: B,
behavior: C() ? "instant" : r
});
}
}, $ = (e) => {
const t = et(e);
c.current?.scrollTo({
left: t,
behavior: C() ? "instant" : "smooth"
});
}, et = (e) => {
if (!p.current || !c.current)
return 0;
const {
scrollLeft: t,
offsetWidth: r
} = c.current, o = Math.round(r * 0.2);
return e === "next" ? t + o : t - o;
}, K = D(i.scroller, {
[i.scrollerCentered]: I === "center"
}), rt = y ? "nav" : "div";
return /* @__PURE__ */ k("div", { className: D(i.tabsWrapper, G), ...J, children: [
/* @__PURE__ */ k(rt, { className: i.scrollWrapper, ref: c, ...q, children: [
y ? /* @__PURE__ */ h(lt, { tabs: l, tabRefs: m, scrollerRef: p, handleNavigationKeydown: tt, scrollerClass: K, selectedTabIndex: n, setSelectedTab: b }) : /* @__PURE__ */ h("div", { role: "tablist", className: K, ref: p, children: l.map(({
id: e,
label: t,
iconName: r,
numberIndicatorValue: o
}, s) => /* @__PURE__ */ k(
"button",
{
id: j(L, e),
role: "tab",
"aria-selected": n === s,
"aria-controls": at(L, e, s),
tabIndex: n === s ? 0 : -1,
className: i.tab,
ref: (d) => {
m.current[s] = d;
},
onClick: () => b(s),
onKeyDown: (d) => _(d, s),
children: [
r && /* @__PURE__ */ h(ct, { name: r, "aria-hidden": "true" }),
t,
o && /* @__PURE__ */ h(it, { label: o })
]
},
j(L, e)
)) }),
/* @__PURE__ */ h("span", { className: i.indicator, ref: a })
] }),
/* @__PURE__ */ h(X, { variant: "filled", className: D(i.scrollButton, {
[i.scrollButtonHidden]: !U
}), hideLabel: !0, iconName: "chevron-left", tabIndex: -1, size: "small", onClick: () => $("prev"), children: "Left" }),
/* @__PURE__ */ h(X, { variant: "filled", className: D(i.scrollButton, i.scrollButtonRight, {
[i.scrollButtonHidden]: !Y
}), hideLabel: !0, iconName: "chevron-right", tabIndex: -1, size: "small", onClick: () => $("next"), children: "Right" })
] });
};
export {
yt as TabList
};