@frontify/fondue
Version:
Design system of Frontify
198 lines (197 loc) • 8.55 kB
JavaScript
import { jsxs as m, Fragment as U, jsx as l } from "react/jsx-runtime";
import { useFocusRing as V } from "@react-aria/focus";
import { motion as K } from "framer-motion";
import { useRef as z, useState as y, Children as A, isValidElement as O, useCallback as Y, useEffect as T, cloneElement as W } from "react";
import H from "../../foundation/Icon/Generated/IconDotsHorizontal.es.js";
import { useMemoizedId as q } from "../../hooks/useMemoizedId.es.js";
import { FOCUS_VISIBLE_STYLE_INSET as G, FOCUS_STYLE as J, FOCUS_VISIBLE_STYLE as P } from "../../utilities/focusStyle.es.js";
import { merge as g } from "../../utilities/merge.es.js";
import { Badge as B } from "../Badge/Badge.es.js";
var Q = /* @__PURE__ */ ((n) => (n.None = "None", n.XSmall = "XSmall", n.Small = "Small", n.Medium = "Medium", n.Large = "Large", n))(Q || {}), Z = /* @__PURE__ */ ((n) => (n.Small = "Small", n.Large = "Large", n))(Z || {});
const X = {
None: "tw-pl-0",
XSmall: "tw-pl-xs",
Small: "tw-pl-s",
Medium: "tw-pl-m",
Large: "tw-pl-l"
}, tt = (n, p) => n.disabled ? "tw-text-text-disabled" : n.id === p ? "tw-font-medium tw-text-text" : "tw-text-text-weak hover:tw-text-text", et = ({
paddingX: n,
size: p,
activeItemId: i,
children: v,
onChange: S,
maxHeight: C,
minHeight: I
}) => {
const F = q(), E = z(null), [N, $] = y(!1), [w, c] = y(!1), x = A.map(v, (t) => O(t) ? t == null ? void 0 : t.props : null) ?? [], [D, M] = y([0]), a = Y(() => {
const t = E.current;
$((t && t.scrollWidth > t.clientWidth) ?? !1);
const r = [];
if (t) {
for (const e of t.children) {
const s = [...t.children].indexOf(e), f = t.getBoundingClientRect(), u = e.getBoundingClientRect();
(u.right > f.right || u.left < f.left) && r.push(s);
}
const o = [...r].sort((e, s) => e - s);
M(o);
}
}, []), b = () => D.map((t) => x[t]), k = (t, r) => {
const o = t.findIndex((e) => e.id === i);
return t.filter((e, s) => r === "next" && s > o && !e.disabled || r === "previous" && s < o && !e.disabled ? e : !1);
}, L = (t) => {
["ArrowRight", "ArrowDown", "ArrowLeft", "ArrowUp"].includes(t.key) && t.stopPropagation();
const r = b(), o = t.target, e = o.id.includes("-m"), s = o.id.replace("-btn-m", ""), f = e ? r : x, u = k(f, "next"), h = k(f, "previous");
(t.key === "ArrowRight" || t.key === "ArrowDown") && u.length > 0 && d(u[0].id, e), (t.key === "ArrowLeft" || t.key === "ArrowUp") && h.length > 0 && d(h[h.length - 1].id, e), t.key === "Enter" && e && (d(s, !0), c(!1), document.getElementById(`${s}-content`).focus()), o.id.includes("-m") || c(!1);
}, d = (t, r) => {
try {
const o = document.getElementById(`${t}-btn`), e = document.getElementById(
r ? `${t}-btn-m` : `${t}-btn`
);
S && S(t), N && o.scrollIntoView({ behavior: "smooth", block: "end", inline: "end" }), e.focus();
} catch (o) {
throw o.message;
}
}, R = (t) => {
a();
const r = b();
if (t.key === "Enter" && !w && r.length > 0) {
const o = document.getElementById(`${r[0].id}-btn-m`);
o && o.focus();
}
w && (t.key === "ArrowRight" || t.key === "ArrowDown") && d(r[0].id, !0);
};
T(() => {
a();
}, [a]), T(() => (window.addEventListener("resize", a), () => {
window.removeEventListener("resize", a);
}), [a]);
const { isFocusVisible: j, focusProps: _ } = V();
return /* @__PURE__ */ m(U, { children: [
/* @__PURE__ */ m("div", { "data-test-id": "tabs", className: "tw-flex tw-relative tw-border-b tw-border-line", children: [
/* @__PURE__ */ l(
"div",
{
ref: E,
role: "tablist",
className: g([
"tw-overflow-x-hidden tw-h-full tw-w-full tw-flex tw-justify-start",
X[
n ?? "Small"
/* Small */
],
p === "Small" ? "tw-gap-xxs" : "tw-gap-xs "
]),
children: x.map((t) => /* @__PURE__ */ m(
"button",
{
"data-test-id": "tab-item",
role: "tab",
type: "button",
"aria-selected": t.id === i,
"aria-controls": `${t.id}-content`,
"aria-hidden": t.disabled,
tabIndex: t.id === i ? 0 : -1,
id: `${t.id}-btn`,
className: g([
"tw-group tw-relative tw-mx-0 tw-px-2 tw-w-max tw-cursor-pointer tw-flex tw-items-center tw-justify-center tw-whitespace-nowrap",
tt(t, i),
G,
p === "Small" ? "tw-h-12 tw-text-body-medium" : "tw-h-14 tw-text-body-large"
]),
onClick: () => {
t.disabled || (d(t.id, !1), c(!1));
},
onKeyDown: (r) => L(r),
children: [
t.decorator && /* @__PURE__ */ l("span", { className: "tw-mr-1.5", children: t.decorator }),
/* @__PURE__ */ l("span", { children: t.label }),
t.badge && /* @__PURE__ */ l("span", { className: "tw-ml-1.5", children: /* @__PURE__ */ l(B, { disabled: t.disabled, style: t.badge.style, children: t.badge.children }) }),
t.id === i && /* @__PURE__ */ l(
K.div,
{
initial: !1,
layoutDependency: i,
"data-test-id": "tab-active-highlight",
layoutId: F,
className: "tw-absolute tw-h-[3px] tw-bg-box-selected-strong tw-rounded-t-x-large tw-w-full tw-bottom-0"
}
)
]
},
t.id
))
}
),
N && /* @__PURE__ */ m(
"div",
{
"data-test-id": "tab-overflow",
className: "tw-z-50 tw-flex-grow tw-pl-3 tw-flex tw-justify-center tw-items-center",
children: [
/* @__PURE__ */ l(
"button",
{
className: g([
"tw-w-6 tw-h-6 tw-bg-box-neutral tw-rounded tw-flex tw-justify-center tw-items-center",
j ? J : ""
]),
type: "button",
onClick: () => {
a(), c(!w);
},
onKeyDown: (t) => R(t),
..._,
children: /* @__PURE__ */ l(H, {})
}
),
w && /* @__PURE__ */ l(
"div",
{
className: "tw-absolute tw-right-0 tw-top-11 tw-px-3 tw-pt-3 tw-bg-base tw-shadow tw-w-max",
role: "dialog",
children: b().map((t) => {
var r, o;
return /* @__PURE__ */ m(
"button",
{
className: g([
"tw-flex tw-items-center tw-w-full tw-mb-3 tw-text-left tw-text-text-weak",
t.disabled && "tw-text-text-disabled",
P
]),
onClick: () => {
t.disabled || (d(t.id, !0), c(!1));
},
role: "tab",
type: "button",
"aria-selected": t.id === i,
"aria-controls": `${t.id}-content`,
"aria-hidden": t.disabled,
tabIndex: !t.disabled && w ? 0 : -1,
id: `${t.id}-btn-m`,
onKeyDown: (e) => L(e),
children: [
t.decorator,
/* @__PURE__ */ l("span", { className: "tw-mr-1 tw-ml-1.5", children: t.label }),
t.badge && /* @__PURE__ */ l(B, { disabled: t.disabled, style: (r = t.badge) == null ? void 0 : r.style, children: (o = t.badge) == null ? void 0 : o.children })
]
},
t.id
);
})
}
)
]
}
)
] }),
/* @__PURE__ */ l("div", { "data-test-id": "tab-content", className: "tw-flex tw-flex-col tw-overflow-y-auto", children: /* @__PURE__ */ l("div", { className: "tw-mr-0", style: { maxHeight: C, minHeight: I }, children: A.map(v, (t) => O(t) ? W(t, { ...t.props, active: t.props.id === i }) : null) }) })
] });
};
et.displayName = "FondueTabs";
export {
Z as TabSize,
et as Tabs,
Q as TabsPaddingX
};
//# sourceMappingURL=Tabs.es.js.map