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