UNPKG

@progress/kendo-react-layout

Version:

React Layout components enable you to create a perceptive and intuitive layout of web projects. KendoReact Layout package

241 lines (240 loc) 7.76 kB
/** * @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 a from "react"; import y from "prop-types"; import { PanelBarItem as L } from "./PanelBarItem.mjs"; import { getInitialState as Q, getFirstId as X, flatChildren as Y, isArrayEqual as Z, flatVisibleChildren as _, getFocusedChild as ee, renderChildren as te } from "./util.mjs"; import { useWebMcpRegister as re, Keys as m, classNames as ne } from "@progress/kendo-react-common"; import { NavigationAction as n } from "./interfaces/NavigationAction.mjs"; const U = (c) => { const { animation: u = !0, children: o, dir: N, selected: w, expanded: O, expandMode: I = "multiple", className: A, keepItemsMounted: R = !1, onSelect: C, style: D, isControlled: W } = c, v = a.useRef(null), $ = a.useRef(null), T = a.useRef(void 0), x = a.useRef(null); re("panelbar", $, c, c.webMcp); const [p, f] = a.useState(() => { const i = Q(c, I || "multiple"); return i.focused || (i.focused = X(c)), i; }), E = I || "multiple", F = w !== void 0 ? w : p.selected, h = W ? O || [] : p.expanded, M = a.useCallback((t) => { x.current = window.setTimeout(() => t()); }, []), g = a.useCallback( (t) => { const i = K, s = Y(a.Children.toArray(i)); let r, l; switch (s.forEach((e) => { e.props.uniquePrivateKey === (t.uniquePrivateKey || p.focused) && (r = e); }), E) { case "single": l = [...r.props.parentUniquePrivateKey, r.props.uniquePrivateKey], Z(h, l) && (r.props.parentUniquePrivateKey ? l = [...r.props.parentUniquePrivateKey] : l = []); break; case "multiple": { l = h.slice(); const e = l.indexOf(r.props.uniquePrivateKey); e === -1 ? l.push(r.props.uniquePrivateKey) : l.splice(e, 1); break; } default: l = h.slice(); break; } f((e) => ({ ...e, selected: r.props.uniquePrivateKey, expanded: l })), C && C({ target: r, expandedItems: l }); }, [o, p.focused, E, h, C] ), d = a.useCallback( (t, i = 0, s) => { const r = K, l = _(a.Children.toArray(r)), e = ee(l, i, t, p.focused, s); if (e) { const k = h.slice(); if (s === n.Right && e && e.props && e.props.children && e.props.children.length > 0) { if (k.push(e.props.uniquePrivateKey), f((b) => ({ ...b, expanded: [...new Set(k)] })), e.props.expanded) { const b = e.props.children[0]; f((P) => ({ ...P, focused: b.props.uniquePrivateKey })); } } else if (s === n.Left && (e && e.props && e.props.parentUniquePrivateKey && e.props.parentUniquePrivateKey.length > 0 || e && e.props && !e.props.disabled && e.props.children && e.props.children.length > 0)) { const b = e.props.parentUniquePrivateKey; if (e.props.expanded) { const P = e.props.uniquePrivateKey, q = k.indexOf(P); k.splice(q, 1), f((J) => ({ ...J, expanded: k })); } else if (e.props.level > 0) { const P = e.props.parentUniquePrivateKey[b.length - 1]; f((q) => ({ ...q, focused: P })); } } else f((b) => ({ ...b, focused: e.props.uniquePrivateKey })); } }, [o, p.focused, h] ), B = a.useCallback( (t) => { g(t), d(t); }, [g, d] ), K = a.useMemo(() => te({ animation: u, keepItemsMounted: R, state: { ...p, selected: F }, expanded: h, handleSelect: B, children: o, activeDescendantRef: T }), [u, R, p, F, h, o, B]), S = a.useCallback( (t, i) => { let s; switch (i) { case n.First: d(t, s, n.First); break; case n.Last: d(t, s, n.Last); break; case n.Left: d(t, s, n.Left); break; case n.Right: d(t, s, n.Right); break; case n.Previous: s = -1, d(t, s); break; case n.Next: s = 1, d(t, s); break; case n.Toggle: g(t); break; } }, [d, g] ), H = a.useCallback(() => { clearTimeout(x.current), p.wrapperFocused || f((t) => ({ ...t, wrapperFocused: !0 })); }, [p.wrapperFocused]), V = a.useCallback(() => { M(() => { f((t) => ({ ...t, wrapperFocused: !1 })); }); }, [M]), j = a.useCallback( (t) => { const i = v.current && getComputedStyle(v.current).direction === "rtl" || !1; if (t.target === t.currentTarget) { const s = t.keyCode; let r; switch (s) { case m.left: r = i ? n.Right : n.Left; break; case m.up: r = n.Previous; break; case m.right: r = i ? n.Left : n.Right; break; case m.down: r = n.Next; break; case m.home: r = n.First; break; case m.end: r = n.Last; break; case m.space: case m.enter: r = n.Toggle; break; default: r = null; break; } r !== null && (t.preventDefault(), S(t, r)); } }, [S] ); a.useEffect(() => () => { x.current && clearTimeout(x.current); }, []); const z = { "aria-activedescendant": T.current }, G = ne("k-panelbar", A); return /* @__PURE__ */ a.createElement( "ul", { ref: v, dir: N, role: "tree", tabIndex: 0, onKeyDown: j, onFocus: H, onBlur: V, className: G, style: D, ...z }, K ); }; U.propTypes = { /** * A collection of `PanelBarItem` components. */ children: y.oneOfType([ y.arrayOf(function(c, u) { return c[u].type !== L ? new Error("PanelBar children should be either PanelBarItem or an array of PanelBarItem.") : null; }), function(c, u) { const o = c[u]; return o && o.type !== L ? new Error("PanelBar children should be either PanelBarItem or an array of PanelBarItem.") : null; } ]), /** * Expands the item or items that match the `selected` property while respecting the `expandMode` property (see [example]({% slug expandModes_panelbar %}#toc-single-expandMode)). * To expand the item on the initial load of the PanelBar, define the `expanded` property of each PanelBarItem. */ selected: y.string, /** * Sets the expand mode of the PanelBar through the `single`, `multiple`, or `default` keywords (see [example]({% slug expandModes_panelbar %})). */ expandMode(c, u) { const o = c[u]; return o !== "single" && o !== "multiple" && o !== "default" ? new Error( `Invalid value '${o}' given to '${u}'. It must be either 'single', 'multiple' or 'default'.` ) : null; }, /** * Enables or disables the animation of the PanelBar items. */ animation: y.bool, /** * When enabled, keeps PanelBarItem content mounted in the DOM even when collapsed. */ keepItemsMounted: y.bool, /** * Fires when the expand mode of the PanelBar is set to `single` or `multiple` * and an item is toggled (see [example]({% slug overview_panelbar %}#toc-expanded-state-management)). */ onSelect: y.func }; U.defaultProps = { expandMode: "multiple", animation: !0, keepItemsMounted: !1 }; export { U as PanelBar };