UNPKG

@progress/kendo-react-buttons

Version:

All you need in React Button in one package: disabled/enabled states, built-in styles and more. KendoReact Buttons package

179 lines (178 loc) 6.14 kB
/** * @license *------------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the package root for more information *------------------------------------------------------------------------------------------- */ import * as t from "react"; import n from "prop-types"; import { useDir as Y, classNames as Z, kendoThemeMaps as _, Keys as u } from "@progress/kendo-react-common"; import { toolbarButtons as ee } from "../util.mjs"; import { ToolbarScrollable as te } from "./tools/ToolbarScrollable.mjs"; import { ToolbarOverflowSection as oe } from "./tools/ToolbarOverflowSection.mjs"; const N = t.forwardRef((i, A) => { const { children: k, className: K, id: j, ariaLabel: q, keyboardNavigation: w, role: x, onResize: E, style: D, tabIndex: B = a.tabIndex, size: b = a.size, fillMode: I = a.fillMode, overflow: c, scrollButtons: d = a.scrollButtons, scrollButtonsPosition: $ = a.scrollButtonsPosition, buttonScrollSpeed: F = a.buttonScrollSpeed, prevButton: G, nextButton: J } = i, C = t.useRef(!1), r = t.useRef(null), m = t.useRef(null), h = t.useRef(0), S = t.useRef(0), s = t.useRef([]), R = t.useRef({ element: null, props: i }), [Q, U] = t.useState(!1), [O, W] = t.useState(!0), [z, P] = t.useState(!1), y = Y(r, i.dir), g = t.useMemo(() => i.buttons || ee, [i.buttons]), V = t.useMemo(() => g.map((e) => e + ":focus").join(","), [g]), M = () => { const e = r.current && r.current.querySelector(V); return Math.max( 0, s.current.findIndex((l) => l === e) ); }; t.useImperativeHandle( R, () => ({ element: r.current, props: i }) ), t.useImperativeHandle(A, () => R.current), t.useEffect(() => (window.addEventListener("resize", L), r.current && (S.current = r.current.offsetWidth, h.current = r.current.offsetHeight, w !== !1 && (s.current = Array.from( r.current.querySelectorAll(g.join(",")) ), H(0))), () => { window.removeEventListener("resize", L), s.current.length = 0; }), []), t.useEffect(() => { if (C.current) { if (!r.current || w === !1) return; s.current = Array.from( r.current.querySelectorAll(g.join(",")) ), H(M()), T(); } else C.current = !0; }); const H = (e) => { s.current.forEach((l, o) => { l.tabIndex = o === e ? B : -1; }); }, X = (e) => { const l = e.keyCode === u.left || e.keyCode === u.right || e.keyCode === u.home || e.keyCode === u.end, o = M(); !l || e.defaultPrevented || s.current.findIndex((f) => f === e.target) === -1 || (e.keyCode === u.left ? v( o, o === 0 ? s.current.length - 1 : o - 1 ) : v( o, o === s.current.length - 1 ? 0 : o + 1 ), e.keyCode === u.home && v(o, 0), e.keyCode === u.end && v(o, s.current.length - 1)); }, v = (e, l) => { const o = s.current[l]; if (o) { o.tabIndex = B, o.focus(); const f = s.current[e]; f && (f.tabIndex = -1); } }, L = (e) => { if (!r.current) return; const l = r.current.offsetWidth, o = r.current.offsetHeight; if (S.current !== l || h.current !== o) { S.current = l, h.current = o; const f = { offsetWidth: S.current, offsetHeight: h.current }; E && E.call(void 0, { target: R.current, ...f, nativeEvent: e }); } T(); }, T = t.useCallback(() => { const e = m.current; e && U( e.scrollWidth > e.clientWidth || e.scrollHeight > e.clientHeight ); }, []), p = t.useCallback(() => { const e = m.current; if (e) { const l = e.scrollLeft === 0, o = y !== "rtl" ? e.scrollLeft + e.clientWidth === e.scrollWidth : e.clientWidth - e.scrollLeft === e.scrollWidth; l && W(!0), o && P(!0), !l && !o && (W(!1), P(!1)); } }, [y]); return t.useEffect(() => { const e = m.current; if (e) return e.addEventListener("scroll", p), () => { e.removeEventListener("scroll", p); }; }, [p]), /* @__PURE__ */ t.createElement( "div", { id: j, "aria-label": q, className: Z( "k-toolbar", { [`k-toolbar-${_.sizeMap[b] || b}`]: b, [`k-toolbar-${I}`]: I, "k-toolbar-scrollable": c === "scroll", "k-toolbar-scrollable-overlay": c === "scroll" && (d === "hidden" || d === void 0), "k-toolbar-scrollable-start": c === "scroll" && d === "hidden" && O, "k-toolbar-scrollable-end": c === "scroll" && d === "hidden" && z, "k-toolbar-section": i.overflow && c === "section" }, K ), style: D, role: x !== void 0 ? x || void 0 : "toolbar", dir: y, ref: r, onKeyDown: w !== !1 ? X : void 0 }, c === "scroll" && /* @__PURE__ */ t.createElement( te, { scrollButtons: d, scrollButtonsPosition: $, prevButton: G, nextButton: J, isOverflowing: Q, scrollContentRef: m, buttonScrollSpeed: F, dir: y, isScrollStartPosition: O, isScrollEndPosition: z, children: k } ), c === "section" && /* @__PURE__ */ t.createElement(oe, { toolbarRef: r, fillMode: I, size: b }, k), (c === "none" || c === void 0) && k ); }), a = { tabIndex: 0, size: "medium", fillMode: "solid", scrollButtons: "auto", scrollButtonsPosition: "split", buttonScrollSpeed: 100 }; N.displayName = "KendoReactToolbar"; N.propTypes = { tabIndex: n.number, dir: n.string, keyboardNavigation: n.bool, style: n.object, className: n.string, role: n.string, onResize: n.func, buttons: n.arrayOf(n.string.isRequired), size: n.oneOf([null, "small", "medium", "large"]), fillMode: n.oneOf([null, "solid", "flat", "outline"]), overflow: n.oneOf(["none", "section", "scroll"]), scrollButtons: n.oneOf(["hidden", "visible", "auto"]), scrollButtonsPosition: n.oneOf(["start", "end", "split"]), buttonScrollSpeed: n.number }; export { N as Toolbar };