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

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