UNPKG

@stratakit/structures

Version:

Medium-sized component structures for the Strata design system

239 lines (238 loc) 7.03 kB
import { jsx, jsxs } from "react/jsx-runtime"; import * as React from "react"; import { Button as ButtonAk } from "@ariakit/react/button"; import { Menu, MenuButton, MenuItem, MenuItemCheckbox, MenuProvider, useMenuContext } from "@ariakit/react/menu"; import { usePopoverContext } from "@ariakit/react/popover"; import { useStoreState } from "@ariakit/react/store"; import { Button, Kbd } from "@stratakit/bricks"; import { DisclosureArrow, Dot, predefinedSymbols } from "@stratakit/bricks/secret-internals"; import { Icon } from "@stratakit/foundations"; import { forwardRef, usePopoverApi } from "@stratakit/foundations/secret-internals"; import cx from "classnames"; import { Checkmark } from "./~utils.icons.js"; import * as ListItem from "./~utils.ListItem.js"; function DropdownMenuRoot(props) { const { children, placement, open: openProp, setOpen: setOpenProp, defaultOpen: defaultOpenProp } = props; return /* @__PURE__ */ jsx( MenuProvider, { placement, defaultOpen: defaultOpenProp, open: openProp, setOpen: setOpenProp, popover: usePopoverContext(), children } ); } DEV: DropdownMenuRoot.displayName = "DropdownMenu.Root"; const DropdownMenuContent = forwardRef( (props, forwardedRef) => { const context = useMenuContext(); const open = useStoreState(context, "open"); const popoverElement = useStoreState(context, "popoverElement"); const popoverProps = usePopoverApi({ element: popoverElement, open }); return /* @__PURE__ */ jsx( Menu, { portal: true, unmountOnHide: true, ...props, gutter: 4, style: { ...popoverProps.style, ...props.style }, wrapperProps: { popover: popoverProps.popover }, className: cx("\u{1F95D}-dropdown-menu", props.className), ref: forwardedRef } ); } ); DEV: DropdownMenuContent.displayName = "DropdownMenu.Content"; const DropdownMenuButton = forwardRef( (props, forwardedRef) => { const { accessibleWhenDisabled = true, children, ...rest } = props; const open = useStoreState(useMenuContext(), (state) => state?.open); return /* @__PURE__ */ jsx( MenuButton, { accessibleWhenDisabled: true, ...rest, render: props.render ?? /* @__PURE__ */ jsxs(Button, { accessibleWhenDisabled, children: [ children, /* @__PURE__ */ jsx(DisclosureArrow, {}) ] }), className: cx("\u{1F95D}-dropdown-menu-button", props.className), "data-has-popover-open": open || void 0, ref: forwardedRef } ); } ); DEV: DropdownMenuButton.displayName = "DropdownMenu.Button"; const DropdownMenuItem = forwardRef( (props, forwardedRef) => { const { label, shortcuts, icon, unstable_dot, ...rest } = props; const dotId = React.useId(); return /* @__PURE__ */ jsxs( MenuItem, { accessibleWhenDisabled: true, render: /* @__PURE__ */ jsx( ListItem.Root, { render: /* @__PURE__ */ jsx( ButtonAk, { accessibleWhenDisabled: true, "aria-describedby": dotId, ...rest, className: cx("\u{1F95D}-dropdown-menu-item", props.className), ref: forwardedRef } ) } ), children: [ icon ? /* @__PURE__ */ jsx(DropdownMenuIcon, { icon }) : null, /* @__PURE__ */ jsx(ListItem.Content, { render: /* @__PURE__ */ jsx("span", {}), children: label }), shortcuts ? /* @__PURE__ */ jsx(DropdownMenuItemShortcuts, { shortcuts }) : null, unstable_dot ? /* @__PURE__ */ jsx( ListItem.Decoration, { render: /* @__PURE__ */ jsx(Dot, { id: dotId, className: "\u{1F95D}-dropdown-menu-item-dot", children: unstable_dot }) } ) : null ] } ); } ); DEV: DropdownMenuItem.displayName = "DropdownMenu.Item"; const DropdownMenuItemShortcuts = forwardRef((props, forwardedRef) => { const { shortcuts, ...rest } = props; const shortcutKeys = React.useMemo(() => { return shortcuts.split("+").map((key) => ({ key: key.trim(), isSymbol: key in predefinedSymbols })); }, [shortcuts]); return /* @__PURE__ */ jsx( ListItem.Decoration, { render: /* @__PURE__ */ jsx("span", {}), ...rest, className: cx("\u{1F95D}-dropdown-menu-item-shortcuts", props.className), ref: forwardedRef, children: shortcutKeys.map(({ key, isSymbol }, index) => { if (isSymbol) { return /* @__PURE__ */ jsx( Kbd, { variant: "ghost", symbol: key }, `${key + index}` ); } return /* @__PURE__ */ jsx(Kbd, { variant: "ghost", children: key }, `${key + index}`); }) } ); }); DEV: DropdownMenuItemShortcuts.displayName = "DropdownMenuItemShortcuts"; const DropdownMenuIcon = forwardRef( (props, forwardedRef) => { const { icon, ...rest } = props; return /* @__PURE__ */ jsx( ListItem.Decoration, { render: /* @__PURE__ */ jsx( Icon, { href: typeof icon === "string" ? icon : void 0, render: React.isValidElement(icon) ? icon : void 0, ...rest, ref: forwardedRef } ) } ); } ); DEV: DropdownMenuIcon.displayName = "DropdownMenuIcon"; const DropdownMenuCheckboxItem = forwardRef((props, forwardedRef) => { const { label, icon, defaultChecked, checked, onChange, name, value = defaultChecked ? "on" : void 0, // For defaultChecked to work ...rest } = props; return /* @__PURE__ */ jsxs( MenuItemCheckbox, { accessibleWhenDisabled: true, defaultChecked, checked, name, value, onChange, render: /* @__PURE__ */ jsx( ListItem.Root, { render: /* @__PURE__ */ jsx( ButtonAk, { accessibleWhenDisabled: true, ...rest, className: cx("\u{1F95D}-dropdown-menu-item", props.className), ref: forwardedRef } ) } ), children: [ icon ? /* @__PURE__ */ jsx(DropdownMenuIcon, { icon }) : null, /* @__PURE__ */ jsx(ListItem.Content, { render: /* @__PURE__ */ jsx("span", {}), children: label }), /* @__PURE__ */ jsx( ListItem.Decoration, { render: /* @__PURE__ */ jsx(Checkmark, { className: "\u{1F95D}-dropdown-menu-checkmark" }) } ) ] } ); }); DEV: DropdownMenuCheckboxItem.displayName = "DropdownMenu.CheckboxItem"; export { DropdownMenuButton as Button, DropdownMenuCheckboxItem as CheckboxItem, DropdownMenuContent as Content, DropdownMenuItem as Item, DropdownMenuRoot as Root };