UNPKG

@primer/react-brand

Version:

Primer Brand is a GitHub's design system for creating React-based marketing websites and digital experiences.

304 lines (303 loc) • 9.13 kB
import e from "../node_modules/clsx/dist/clsx.js"; import { useId as t } from "../hooks/useId.js"; import { Text as n } from "../Text/Text.js"; import { Button as r } from "../Button/Button.js"; import { ThemeProvider as i } from "../ThemeProvider/ThemeProvider.js"; import { useTheme as a } from "../ThemeProvider/useTheme.js"; import { useAnchoredPosition as o } from "../hooks/useAnchoredPosition.js"; import { useOnClickOutside as s } from "../hooks/useOnClickOutside.js"; import { useKeyboardEscape as c } from "../hooks/useKeyboardEscape.js"; import { CheckIcon as l, ChevronDownIcon as u } from "../node_modules/@primer/octicons-react/dist/index.esm.js"; import '../packages/design-tokens/lib/design-tokens/css/tokens/functional/components/action-menu/colors-with-modes-B69RzUbe.css';/* empty css */ import d from "./ActionMenu.module.js"; import f, { Children as p, cloneElement as m, forwardRef as h, isValidElement as g, memo as _, useCallback as v, useEffect as y, useMemo as b, useRef as x, useState as S } from "react"; import { Fragment as C, jsx as w, jsxs as T } from "react/jsx-runtime"; import { FocusKeys as E, focusZone as D } from "@primer/behaviors"; //#region src/ActionMenu/ActionMenu.tsx var O = { root: "ActionMenu", get button() { return `${this.root}-button`; }, get overlay() { return `${this.root}-overlay`; }, get list() { return `${this.root}-list`; }, get item() { return `${this.root}-list-item`; } }, k = [ "inside-top", "inside-bottom", "inside-left", "inside-right", "inside-center", "outside-top", "outside-bottom", "outside-left", "outside-right" ], A = ["small", "medium"], j = ["default", "split-button"], M = f.createContext({}), N = () => f.useContext(M), P = ({ size: e, children: t, onMenuToggle: n }) => { let [r, i] = S(e); return /* @__PURE__ */ w(M.Provider, { value: { size: r, setSize: i, onMenuToggle: n }, children: t }); }, F = _(({ id: n, children: r, "data-testid": i, disabled: a, open: l = !1, selectionVariant: u = "none", menuAlignment: f = "end", size: h = "medium", menuSide: _, onSelect: b, mode: C = "default" }) => { let [k, A] = S(l), j = x(null), M = x(null), N = t(n); s(j, () => A(!1), M), c(v(() => { A(!1); }, [])); let F = v(() => { A(!k); }, [k]), L = v((e) => { b && b(e), F(); }, [b, F]), R = v((e) => { L(e), F(), M.current?.focus(); }, [ L, F, M ]); y(() => { if (k && j.current) { let e = j.current, t = C === "split-button", n = t ? (e) => e.tagName === "A" : void 0; D(j.current, { bindKeys: E.ArrowVertical, focusableElementFilter: n, focusInStrategy: t ? "first" : void 0 }), e.addEventListener("keydown", (e) => { if (e.key === "Enter") { let t = e.target, n = t.tagName === "A" ? t.closest("li") : t; if (!n || n.getAttribute("aria-disabled") === "true") return; let r = n.getAttribute("data-value"); r && (L(r), A(!1), setTimeout(() => { M.current?.focus(); }, 10)); } }); let r = t ? "a" : "li", i = j.current.querySelector(r); i && setTimeout(() => { i.focus(); }, 10); let a = e.querySelectorAll(r)[e.querySelectorAll(r).length - 1]; a.addEventListener("keydown", (e) => { let t = e; t.key === "ArrowDown" && (t.preventDefault(), i?.focus()); }), i?.addEventListener("keydown", (e) => { let t = e; t.key === "ArrowUp" && (t.preventDefault(), a.focus()); }), e.addEventListener("keydown", (e) => { e.key === "Escape" && M.current?.focus(); }); } }, [ k, j, C, R, F, L ]); let { position: B } = o({ floatingElementRef: j, anchorElementRef: M, align: f, allowOutOfBounds: !0, side: _ }, [k]), { Button: V, Overlay: H } = p.toArray(r).reduce((t, n) => (g(n) && n.type === I ? t.Button = m(n, { ref: M, className: e(n.props.className, d[`ActionMenu__button--${C}`], k), menuOpen: k, disabled: a, id: `${N}-button`, size: h, _mode: C }) : g(n) && n.type === z && (t.Overlay = m(n, { ref: j, className: e(d.ActionMenu__menu, B && d["ActionMenu__menu--visible"], B && d[`ActionMenu__menu--pos-${B.anchorSide}`], d[`ActionMenu__menu--${h}`], C === "split-button" && "ActionMenu__menu--split"), style: { top: `${B?.top ?? 0}px`, left: `${B?.left ?? 0}px` }, id: `${N}-menu`, children: p.map(n.props.children, (e) => g(e) ? m(e, { handler: R, type: C === "split-button" ? "link" : u }) : e) })), t), {}); return /* @__PURE__ */ w(P, { size: h, onMenuToggle: F, children: /* @__PURE__ */ T("div", { id: N, className: e(d.ActionMenu, a && d["ActionMenu--disabled"]), "data-testid": i || O.root, children: [V, k ? H : null] }) }); }), I = h(({ as: t, href: n, id: i, children: a, className: o, "data-testid": s, disabled: c, menuOpen: l, size: f, _mode: p = "default", onClick: m, leadingVisual: h, variant: g, ..._ }, y) => { let { onMenuToggle: b } = N(), x = v((e) => { m?.(e), e.defaultPrevented || b?.(); }, [m, b]); if (p === "split-button") { let p = g ?? "primary"; return /* @__PURE__ */ T("div", { className: e(d.ActionMenu__button, d[`ActionMenu__button--${f}`], o), children: [/* @__PURE__ */ w(r, { as: t, href: n, className: e(d["ActionMenu__innerButton--split-button"], d[`ActionMenu__innerButton--${p}`], d[`ActionMenu__innerButton--${f}`], c && d["ActionMenu__innerButton--disabled"]), variant: p, "aria-disabled": c, "data-testid": s || O.button, size: f, leadingVisual: h, onClick: m, ..._, children: /* @__PURE__ */ w("span", { className: d["ActionMenu__button-text"], children: a }) }), /* @__PURE__ */ w(r, { ref: y, id: i, as: "button", className: d["ActionMenu__innerButton--split-button"], variant: p, "aria-haspopup": "true", "aria-label": "Menu", size: f, "aria-expanded": l ? "true" : "false", onClick: b, disabled: c, children: /* @__PURE__ */ w(u, { className: d["ActionMenu__inner-button-dropdown-icon"] }) })] }); } return /* @__PURE__ */ w(r, { ref: y, id: i, className: e(d.ActionMenu__button, d[`ActionMenu__button--${f}`], o), "aria-haspopup": "true", "aria-expanded": l ? "true" : "false", disabled: c, "data-testid": s || O.button, size: f, variant: g, leadingVisual: h, trailingVisual: /* @__PURE__ */ w(u, {}), onClick: x, ..._, children: /* @__PURE__ */ w("span", { className: d["ActionMenu__button-text"], children: a }) }); }), L = { none: "menuitem", single: "menuitemradio", link: "menuitem" }, R = ({ as: t, children: r, className: i, disabled: a, handler: o, selected: s, type: c, value: u, onClick: p, onKeyDown: m, leadingVisual: h, ...g }) => { let { size: _ } = N(), y = v((e) => { p?.(e), a || o?.(String(u)); }, [ o, u, a, p ]), x = v((e) => { m?.(e), !a && e.key === "Enter" && o?.(String(u)); }, [ o, u, a, m ]), S = b(() => ({ className: e(d.ActionMenu__item, c === "single" && d[`ActionMenu__item--selection-type-${c}`], _ && d[`ActionMenu__item--${_}`], i), role: L[c || "single"], "aria-disabled": a, tabIndex: -1, "data-value": u, ...g }), [ g, c, _, i, a, u ]), E = b(() => /* @__PURE__ */ T(C, { children: [ f.isValidElement(h) ? f.cloneElement(h, { width: h.props.width || 20, height: h.props.width || 20 }) : null, c === "single" && /* @__PURE__ */ w("span", { className: d["ActionMenu__item-leadingVisual"], children: s && /* @__PURE__ */ w(l, { className: e(d["ActionMenu__item-icon"], a && d["ActionMenu__item-icon--disabled"]), size: 16 }) }), /* @__PURE__ */ w("span", { className: d["ActionMenu__item-text"], children: /* @__PURE__ */ w(n, { variant: a ? "muted" : "default", size: _ === "medium" ? "200" : "100", className: e(a && d["ActionMenu__item-content--disabled"]), children: r }) }) ] }), [ h, r, s, a, _, c ]); return t === "a" ? /* @__PURE__ */ w("li", { role: "menuitem", ...S, onClick: p, onKeyDown: m, children: /* @__PURE__ */ w("a", { className: e(d["ActionMenu__item-anchor"], a && d["ActionMenu__item--disabled"]), href: g.href, children: E }) }) : /* @__PURE__ */ w("li", { role: "menuitem", ...S, "aria-checked": c === "none" ? void 0 : s ? "true" : "false", onClick: y, onKeyDown: x, children: E }); }, z = h(({ children: t, className: n, "data-testid": r, menuOpen: o, ...s }, c) => { let { colorMode: l } = a(); return /* @__PURE__ */ w(i, { colorMode: n?.includes("ActionMenu__menu--split") ? "light" : l, children: /* @__PURE__ */ w("ul", { ref: c, className: e(n), role: "menu", "data-testid": r || O.list, ...s, children: t }) }); }), B = Object.assign(F, { Button: I, Item: R, Overlay: z, testIds: O }); //#endregion export { B as ActionMenu, j as ActionMenuButtonModes, P as ActionMenuProvider, A as ActionMenuSizes, k as actionMenuOverlaySides, N as useActionMenuContext }; //# sourceMappingURL=ActionMenu.js.map