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

313 lines (312 loc) 8.86 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 o from "prop-types"; import { useZIndexContext as ye, useId as Y, useDir as Ie, dispatchEvent as b, getActiveElement as ve, Keys as c, classNames as N, kendoThemeMaps as Ee, ZIndexContext as xe, getTabIndex as De, svgIconPropType as Ne, IconWrap as we } from "@progress/kendo-react-common"; import { FloatingActionButtonItem as Re } from "./FloatingActionButtonItem.mjs"; import { position as Ae, getTextDirectionClass as Fe, getAnchorAlign as Oe, getPopupAlign as ze } from "./utils.mjs"; import { Popup as Te } from "@progress/kendo-react-popup"; const Be = 2, Me = 100, ee = t.forwardRef( (P, te) => { const { align: u = h.align, alignOffset: $, className: K, disabled: d, icon: w, svgIcon: R, iconClass: S, id: W, items: n, item: oe, text: C, positionMode: A = h.positionMode, size: y = h.size, style: ae, rounded: I = h.rounded, themeColor: F = h.themeColor, overlayStyle: ne, tabIndex: se, accessKey: le, popupSettings: v = {}, modal: ie, onClick: O, onItemClick: Z, onFocus: z, onBlur: q, onKeyDown: _, onOpen: H, onClose: j, ...re } = P, L = ye(), X = L ? L + Be : Me, U = t.useRef(null), l = t.useRef(null), ce = t.useRef(null), ue = t.useRef(null), G = t.useCallback(() => { l.current && l.current.focus(); }, []), f = t.useCallback( () => ({ element: l.current, focus: G }), [G] ); t.useImperativeHandle(U, f), t.useImperativeHandle( te, () => U.current ); const [i, r] = t.useState(!1), [E, p] = t.useState(!1), [g, s] = t.useState(-1), de = Y() + "-button-id", T = Ie(l, P.dir), k = T === "rtl", x = Y() + "-list-id"; t.useEffect(() => { Ae(l, u, $, k); }, [l, u, $, k]), t.useEffect(() => { E && l && l.current && l.current.focus(); }, [E, l]); const m = t.useCallback( (e, a) => { n && b(a ? H : j, e, f(), void 0); }, [H, j, n] ), J = t.useCallback( (e) => { !e.target || d || (!n && O ? b( O, e, f(), void 0 ) : (r(!i), p(!0), s(i ? -1 : 0), m(e, !i))); }, [r, p, s, O, m, i, n, d] ), fe = t.useCallback( (e) => { p(!0), s(i ? 0 : -1), z && b( z, e, f(), void 0 ); }, [z, p, s] ), pe = t.useCallback( (e) => { p(!1), r(!1), s(-1), b( q, e, f(), void 0 ), i && m(e, !1); }, [q, p, r, s, m] ), me = t.useCallback((e) => { e.preventDefault(); }, []), B = t.useCallback( (e, a) => { n && (n[a].disabled || b(Z, e, f(), { itemProps: n[a], itemIndex: a })); }, [Z] ), be = t.useCallback( (e, a) => { !e.target || !n || (s(a), r(!1), B(e, a), m(e, !1)); }, [s, r, B, m] ), ge = t.useCallback( (e) => { ve(document) === l.current && e.preventDefault(); }, [l] ), ke = t.useCallback( (e) => { const a = g, M = n ? n.length : -1; if (e.altKey) { !i && e.keyCode === c.down && (e.preventDefault(), r(!0), s(0)), i && e.keyCode === c.up && (e.preventDefault(), r(!1), s(-1)); return; } switch (e.keyCode) { case c.enter: case c.space: a >= 0 && B(e, a), n || J(e), e.preventDefault(), r(!i), s(i ? -1 : 0); break; case c.esc: e.preventDefault(), r(!1), s(-1); break; case c.home: e.preventDefault(), s(0); break; case c.end: e.preventDefault(), s(M - 1); break; case c.down: case c.right: e.preventDefault(), s(a + 1 >= M ? 0 : a + 1); break; case c.up: case c.left: e.preventDefault(), s(a - 1 < 0 ? M - 1 : a - 1); break; } b( _, e, f(), void 0 ); }, [_, g, s, k, r] ), he = t.useMemo( () => N( "k-fab k-fab-solid", { "k-fab-sm": y === "small", "k-fab-md": y === "medium", "k-fab-lg": y === "large", "k-disabled": d, "k-pos-absolute": A === "absolute", "k-pos-fixed": A === "fixed", "k-focus": E, [`k-rounded-${Ee.roundedMap[I] || I}`]: I, [`k-fab-solid-${F}`]: F }, `k-${u.vertical}-${u.horizontal}`, K ), [F, y, I, d, A, u, E, K] ), Ce = n && n.map((e, a) => /* @__PURE__ */ t.createElement( Re, { ...e, key: a, index: a, id: `${x}-${a}`, disabled: d || e.disabled, focused: g === a, dataItem: e, item: oe, className: N(e.className, Fe(T || "ltr", u.horizontal)), onClick: be, onDown: ge } )), Q = !!((w || R) && !C), V = (l.current ? l.current.offsetWidth : 0) / 2 - 32 / 2; let D; return w || R ? D = /* @__PURE__ */ t.createElement(we, { className: "k-fab-icon", name: w, icon: R }) : S ? D = /* @__PURE__ */ t.createElement("span", { role: "presentation", className: S }) : D = null, /* @__PURE__ */ t.createElement(xe.Provider, { value: X }, /* @__PURE__ */ t.createElement(t.Fragment, null, /* @__PURE__ */ t.createElement( "button", { ref: l, id: W || de, role: "button", type: "button", "aria-disabled": d, "aria-expanded": n ? i : void 0, "aria-haspopup": !!n, "aria-label": `${C || ""} floatingactionbutton`, "aria-owns": n ? x : void 0, "aria-activedescendant": g >= 0 && n ? `${x}-${g}` : void 0, tabIndex: De(se, d), accessKey: le, dir: T, disabled: d, className: he, style: ae, onClick: J, onMouseDown: me, onFocus: fe, onBlur: pe, onKeyDown: ke, ...re }, D, C && /* @__PURE__ */ t.createElement("span", { className: "k-fab-text" }, C) ), ie && i && /* @__PURE__ */ t.createElement( "div", { className: "k-overlay", style: { zIndex: X, ...ne } } ), /* @__PURE__ */ t.createElement( Te, { ref: ue, anchor: l.current, show: i, animate: v.animate, popupClass: N("k-popup-transparent k-fab-popup", v.popupClass), anchorAlign: v.anchorAlign || Oe(u, k), popupAlign: v.popupAlign || ze(u, k), style: { boxShadow: "none" } }, /* @__PURE__ */ t.createElement( "ul", { ref: ce, role: "menu", "aria-labelledby": W, id: x, className: N("k-fab-items", { "k-fab-items-bottom": u.vertical !== "bottom", "k-fab-items-top": u.vertical === "bottom" }), style: { paddingLeft: Q ? V : void 0, paddingRight: Q ? V : void 0 } }, Ce ) ))); } ); ee.propTypes = { className: o.string, style: o.object, id: o.string, dir: o.string, tabIndex: o.number, accessKey: o.string, disabled: o.bool, icon: o.string, svgIcon: Ne, iconClass: o.string, text: o.string, alignOffset: o.shape({ x: o.oneOfType([o.number, o.string]).isRequired, y: o.oneOfType([o.number, o.string]).isRequired }), align: o.shape({ vertical: o.oneOf(["top", "middle", "bottom"]).isRequired, horizontal: o.oneOf(["start", "center", "end"]).isRequired }), positionMode: o.oneOf(["absolute", "fixed"]), size: o.oneOf([null, "small", "medium", "large"]), rounded: o.oneOf([null, "small", "medium", "large", "full"]), themeColor: o.oneOf([ null, "primary", "secondary", "tertiary", "info", "success", "warning", "error", "dark", "light", "inverse" ]), modal: o.bool, overlayStyle: o.object }; const h = { align: { vertical: "bottom", horizontal: "end" }, size: "medium", rounded: "full", themeColor: "primary", positionMode: "fixed" }; ee.displayName = "KendoFloatingActionButton"; export { ee as FloatingActionButton };