@progress/kendo-react-layout
Version:
React Layout components enable you to create a perceptive and intuitive layout of web projects. KendoReact Layout package
226 lines (225 loc) • 7.57 kB
JavaScript
/**
* @license
*-------------------------------------------------------------------------------------------
* Copyright © 2026 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the package root for more information
*-------------------------------------------------------------------------------------------
*/
import * as n from "react";
import l from "prop-types";
import { TabStripNavigation as ee } from "./TabStripNavigation.mjs";
import { TabStripContent as ie } from "./TabStripContent.mjs";
import { useWebMcpRegister as ce, Navigation as ae, classNames as ue, kendoThemeMaps as de } from "@progress/kendo-react-common";
const be = {
animation: !0,
tabPosition: "top",
tabAlignment: "start",
keepTabsMounted: !1,
buttonScrollSpeed: 100,
mouseScrollSpeed: 10,
scrollButtons: "auto",
scrollButtonsPosition: "split",
renderAllContent: !1
}, D = n.forwardRef((E, te) => {
const h = n.useMemo(() => ({ ...be, ...E }), [E]), {
id: m,
animation: H,
children: O,
selected: u,
onSelect: N,
style: ne,
tabContentStyle: z,
tabPosition: b,
tabAlignment: W,
tabIndex: L,
className: K,
dir: x,
renderAllContent: P,
keepTabsMounted: j,
size: k,
scrollable: g,
scrollButtons: C,
scrollButtonsPosition: F,
buttonScrollSpeed: U,
mouseScrollSpeed: $,
prevButton: q,
nextButton: G
} = h, [f, oe] = n.useState(null), J = n.useRef({ props: h }), T = n.useRef(null), A = n.useRef(null), I = n.useRef(void 0), R = n.useRef(void 0), Q = n.useCallback(() => ({ props: h }), [h]);
n.useImperativeHandle(J, Q), n.useImperativeHandle(te, Q), ce("tabstrip", J, h, h.webMcp);
const w = n.useMemo(() => m ? m + "-content-panel-id" : void 0, [m]), y = n.useMemo(() => m ? m + "-nav-item-id" : void 0, [m]), S = n.useMemo(() => n.Children.toArray(O).filter(Boolean), [O]), V = n.useCallback(() => /top|bottom/.test(b || "top"), [b]), v = n.useCallback(() => {
const s = V(), i = A.current;
if (!i)
return;
const a = i.scrollLeft, t = i.clientWidth, e = i.scrollWidth, r = i.scrollTop, o = i.scrollHeight, d = i.clientHeight;
let c = null;
const le = s ? e > t : o > d, _ = x === "rtl";
le ? s ? a + t === e || (_ && t - a) === e ? c = "end" : a === 0 || _ && -a === 0 ? c = "start" : a > 0 && a + t < e || -a > 0 && t - a < e ? c = "middle" : c = null : o - (r + d) === 0 ? c = "bottom" : r === 0 ? c = "top" : r > 0 && o - (r + d) > 0 ? c = "middle" : c = null : c = null, oe(c);
}, [V, x]), M = n.useCallback(
(s) => {
u !== s && N && N({
selected: s
});
},
[u, N]
), p = n.useCallback(
(s) => {
var t, e;
const i = S;
((e = (t = i == null ? void 0 : i[s]) == null ? void 0 : t.props) == null ? void 0 : e.disabled) || M(s);
},
[S, M]
), X = n.useCallback((s) => {
R.current && R.current.triggerKeyboardEvent(s);
}, []);
n.useEffect(() => {
var a;
const s = T.current, i = s && getComputedStyle(s).direction === "rtl" || !1;
return s && (R.current = new ae({
tabIndex: 0,
root: T,
rovingTabIndex: !0,
focusClass: "k-focus",
selectors: [".k-tabstrip .k-tabstrip-item"],
keyboardEvents: {
keydown: {
ArrowLeft: (t, e, r) => {
r.preventDefault();
const o = e.elements.indexOf(t), d = o !== 0 ? o - 1 : e.elements.length - 1, c = o !== e.elements.length - 1 ? o + 1 : 0;
i ? (e.focusNext(t), p(c)) : (e.focusPrevious(t), p(d));
},
ArrowRight: (t, e, r) => {
r.preventDefault();
const o = e.elements.indexOf(t), d = o !== 0 ? o - 1 : e.elements.length - 1, c = o !== e.elements.length - 1 ? o + 1 : 0;
i ? (e.focusPrevious(t), p(d)) : (e.focusNext(t), p(c));
},
ArrowDown: (t, e, r) => {
r.preventDefault();
const o = e.elements.indexOf(t), d = o !== e.elements.length - 1 ? o + 1 : 0;
e.focusNext(t), p(d);
},
ArrowUp: (t, e, r) => {
r.preventDefault();
const o = e.elements.indexOf(t), d = o !== 0 ? o - 1 : e.elements.length - 1;
e.focusPrevious(t), p(d);
},
Home: (t, e, r) => {
r.preventDefault(), e.focusElement(e.first, t), p(0);
},
End: (t, e, r) => {
r.preventDefault(), e.focusElement(e.last, t), p(e.elements.length - 1);
}
}
}
}), (a = R.current) == null || a.initializeRovingTab(u), v(), I.current = window.ResizeObserver && new ResizeObserver(() => v()), T.current && I.current && I.current.observe(T.current)), () => {
var t;
(t = R.current) == null || t.removeFocusListener(), I.current && I.current.disconnect();
};
}, [u, p, v]);
const se = n.useMemo(() => {
const s = n.Children.count(S);
return u < s && u > -1 ? /* @__PURE__ */ n.createElement(
ie,
{
index: u,
selected: u,
contentPanelId: w,
navItemId: y,
animation: H,
keepTabsMounted: j,
renderAllContent: P,
style: z
},
S
) : null;
}, [u, S, w, y, H, j, P, z]), B = C === "hidden" || f === null && C === "auto" ? "hidden" : "visible", Y = n.useMemo(
() => ({
itemsNavRef: A,
children: S,
selected: u,
tabIndex: L,
tabPosition: b,
tabAlignment: W,
size: k,
scrollable: g,
scrollButtons: B,
scrollButtonsPosition: F,
buttonScrollSpeed: U,
mouseScrollSpeed: $,
prevButton: q,
nextButton: G,
dir: x,
contentPanelId: w,
renderAllContent: P,
navItemId: y,
onKeyDown: X,
onSelect: M,
onScroll: v,
containerScrollPosition: f
}),
[
A,
S,
u,
L,
b,
W,
k,
g,
B,
F,
U,
$,
q,
G,
x,
w,
P,
y,
X,
M,
v,
f
]
), Z = b === "bottom", re = n.useMemo(
() => ue(
"k-tabstrip k-pos-relative",
{
[`k-tabstrip-${de.sizeMap[k || "medium"] || k}`]: k,
"k-tabstrip-left": b === "left",
"k-tabstrip-right": b === "right",
"k-tabstrip-bottom": b === "bottom",
"k-tabstrip-top": b === "top",
"k-tabstrip-scrollable": g,
"k-tabstrip-scrollable-start k-tabstrip-scrollable-end": g && B === "visible",
"k-tabstrip-scrollable-start": g && C === "auto" && (f === "end" || f === "middle"),
"k-tabstrip-scrollable-end": g && C === "auto" && (f === "start" || f === "middle")
},
K
),
[k, b, g, C, B, f, K]
);
return /* @__PURE__ */ n.createElement("div", { id: m, ref: T, dir: x, className: re, style: ne, onScroll: v }, !Z && /* @__PURE__ */ n.createElement(ee, { ...Y }), se, Z && /* @__PURE__ */ n.createElement(ee, { ...Y }));
});
D.displayName = "TabStrip";
D.propTypes = {
id: l.string,
animation: l.bool,
children: l.node,
onSelect: l.func,
selected: l.number,
style: l.object,
tabContentStyle: l.object,
tabPosition: l.string,
tabAlignment: l.string,
tabIndex: l.number,
className: l.string,
dir: l.string,
renderAllContent: l.bool,
size: l.oneOf(["small", "medium", "large"]),
scrollButtons: l.oneOf(["auto", "visible", "hidden"]),
scrollButtonsPosition: l.oneOf(["split", "start", "end", "around", "before", "after"])
};
const Se = D;
export {
Se as TabStrip
};