@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
JavaScript
/**
* @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
};