DropdownMenu
Allows user to select between multiple actions.
version
5.2.1
install
yarn add @welcome-ui/dropdown-menu
usage
import { DropdownMenu, useDropdownMenu } from '@welcome-ui/dropdown-menu'
About #
Menu from Ariakit menu with a really nice theme 👀
Usage #
...or with more complexity
Arrow #
Use DropdownMenu.Arrow
to add an arrow to the dropdown menu
Stay open on item menu click #
Use hideOnClick={false}
on DropdownMenu.Item
to not closing menu on item click.
useDropdownMenu #
We use useMenuStore
from Ariakit Menu for the state of the dropdown menu with the animated
flag set to true
by default.
Pass options to useDropdownMenu
:
defaultOpen
: e.g.const dropdownMenu = useDropdownMenu({ defaultOpen: true })
And the hook returns (among other things):
useState('open')
: whether the dropdown menu is currently openhide
: a function to hide the dropdown menu
Properties #
Name | Type(s) | Default | Required |
---|---|---|---|
innerProps | WuiProps add custom props from styled system on DropdownMenu inner | {} | |
gutter | string number default 4px (space.xs) | xs | |
store | MenuStoreFunctions<...> & MenuStoreFunctions<...> & Store<MenuStoreState<MenuStoreValues>> & { ...; } Object returned by the `useMenuStore` hook. | ||
autoFocus | Boolean Automatically focuses the element upon mounting, similar to the native `autoFocus` prop. This addresses an issue where the element with the native `autoFocus` attribute might receive focus before React effects are executed. The `autoFocus` prop can also be used with [Focusable](https://ariakit.org/components/focusable) elements within a [Dialog](https://ariakit.org/components/dialog) component, establishing the initial focus as the dialog opens. Live examples: - [Dialog with React Router](https://ariakit.org/examples/dialog-react-router) - [Nested Dialog](https://ariakit.org/examples/dialog-nested) | false | |
disabled | Boolean Determines if the element is disabled. This sets the `aria-disabled` attribute accordingly, enabling support for all elements, including those that don't support the native `disabled` attribute. This feature can be combined with the [`accessibleWhenDisabled`](https://ariakit.org/reference/focusable#accessiblewhendisabled) prop to make disabled elements still accessible via keyboard. Live examples: - [Submenu](https://ariakit.org/examples/menu-nested) | false | |
fixed | Boolean Whether the popover has `position: fixed` or not. | false | |
alwaysVisible | Boolean Determines whether the content element should remain visible even when the `open` state is `false`. If this prop is set to `true`, the `hidden` prop and the `display: none` style will not be applied, unless explicitly set otherwise. This prop is particularly useful when using third-party animation libraries such as Framer Motion or React Spring, where the element needs to be visible for exit animations to work. Live examples: - [Dialog with Framer Motion](https://ariakit.org/examples/dialog-framer-motion) - [Menu with Framer Motion](https://ariakit.org/examples/menu-framer-motion) - [Tooltip with Framer Motion](https://ariakit.org/examples/tooltip-framer-motion) - [Dialog with details & summary](https://ariakit.org/examples/dialog-details) | false | |
hideOnHoverOutside | false true (arg: MouseEvent) => boolean Whether to hide the popover when the mouse cursor leaves any hovercard element, including the hovercard popover itself, but also the anchor element. | true | |
disablePointerEventsOnApproach | false true (arg: MouseEvent) => boolean Whether to disable the pointer events outside of the hovercard while the mouse is moving toward the hovercard. This is necessary because these events may trigger focus on other elements and close the hovercard while the user is moving the mouse toward it. | true | |
modal | Boolean Determines whether the dialog is modal. Modal dialogs have distinct states and behaviors: - The `portal` and `preventBodyScroll` props are set to `true`. They can still be manually set to `false`. - A visually hidden dismiss button will be rendered if the `DialogDismiss` component hasn't been used. This allows screen reader users to close the dialog. - When the dialog is open, element tree outside it will be disabled. - When using the `Heading` or `DialogHeading` components within the dialog, their level will be reset so they start with `h1`. | false | |
wrapperProps | HTMLAttributes<HTMLDivElement> Props that will be passed to the popover wrapper element. This element will be used to position the popover. | ||
shift | number The skidding of the popover along the anchor element. Can be set to negative values to make the popover shift to the opposite side. | 0 | |
flip | string false true Controls the behavior of the popover when it overflows the viewport: - If a `boolean`, specifies whether the popover should flip to the opposite side when it overflows. - If a `string`, indicates the preferred fallback placements when it overflows. The placements must be spaced-delimited, e.g. "top left". | true | |
slide | Boolean Whether the popover should slide when it overflows. | true | |
overlap | Boolean Whether the popover can overlap the anchor element when it overflows. | false | |
sameWidth | Boolean Whether the popover should have the same width as the anchor element. This will be exposed to CSS as [`--popover-anchor-width`](https://ariakit.org/guide/styling#--popover-anchor-width). | false | |
fitViewport | Boolean Whether the popover should fit the viewport. If this is set to true, the popover wrapper will have `maxWidth` and `maxHeight` set to the viewport size. This will be exposed to CSS as [`--popover-available-width`](https://ariakit.org/guide/styling#--popover-available-width) and [`--popover-available-height`](https://ariakit.org/guide/styling#--popover-available-height). | false | |
arrowPadding | number The minimum padding between the arrow and the popover corner. | 4 | |
overflowPadding | number The minimum padding between the popover and the viewport edge. This will be exposed to CSS as [`--popover-overflow-padding`](https://ariakit.org/guide/styling#--popover-overflow-padding). | 8 | |
getAnchorRect | (anchor: HTMLElement) => AnchorRect Function that returns the anchor element's DOMRect. If this is explicitly passed, it will override the anchor `getBoundingClientRect` method. Live examples: - [Textarea with inline combobox](https://ariakit.org/examples/combobox-textarea) - [Standalone Popover](https://ariakit.org/examples/popover-standalone) - [Context menu](https://ariakit.org/examples/menu-context-menu) - [Selection Popover](https://ariakit.org/examples/popover-selection) @param anchor The anchor element. | ||
updatePosition | (props: { updatePosition: () => Promise<void>; }) => void | Promise<void> A callback that will be called when the popover needs to calculate its position. This will override the internal `updatePosition` function. The original `updatePosition` function will be passed as an argument, so it can be called inside the callback to apply the default behavior. Live examples: - [Responsive Popover](https://ariakit.org/examples/popover-responsive) | ||
backdrop | false true "p" "abbr" "address" "article" "aside" "b" "bdi" "bdo" "big" "caption" "cite" "code" "dd" "dfn" "div" "dt" "em" "figcaption" "figure" "footer" "h1" "h2" "h3" "h4" "h5" "h6" "head" "header" "hgroup" "i" "kbd" "keygen" "main" "mark" "menu" "menuitem" "nav" "noindex" "noscript" "picture" "rp" "rt" "ruby" "s" "samp" "section" "small" "span" "strong" "sub" "summary" "sup" "u" "var" "wbr" "webview" "center" ReactElement<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & { ...; }, string | JSXElementConstructor<...>> ComponentClass<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & { ...; }, any> FunctionComponent<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & { ...; }> Determines whether there will be a backdrop behind the dialog. On modal dialogs, this is `true` by default. Besides a `boolean`, this prop can also be a React component or JSX element that will be rendered as the backdrop. **If a custom component is used, it must accept ref and spread all props to its underlying DOM element**, the same way a native element would. Live examples: - [Animated Dialog](https://ariakit.org/examples/dialog-animated) - [Dialog with scrollable backdrop](https://ariakit.org/examples/dialog-backdrop-scrollable) - [Dialog with Framer Motion](https://ariakit.org/examples/dialog-framer-motion) - [Dialog with Menu](https://ariakit.org/examples/dialog-menu) - [Nested Dialog](https://ariakit.org/examples/dialog-nested) - [Dialog with Next.js App Router](https://ariakit.org/examples/dialog-next-router) @example ```jsx <Dialog backdrop={<div className="backdrop" />} /> ``` | ||
backdropProps | Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & { ...; } Props that will be passed to the backdrop element if [`backdrop`](https://ariakit.org/reference/dialog#backdrop) is `true`. @deprecated Use the [`backdrop`](https://ariakit.org/reference/dialog#backdrop) prop instead. | ||
hideOnEscape | false true (arg: KeyboardEvent | React.KeyboardEvent<Element>) => boolean Determines whether the dialog will be hidden when the user presses the Escape key. | true | |
hideOnInteractOutside | false true (arg: Event | SyntheticEvent<Element, Event>) => boolean Determines whether the dialog will be hidden when the user clicks or focus on an element outside of the dialog. | true | |
getPersistentElements | () => Iterable<Element> When a dialog is open, the elements outside of it will be disabled so they can't be interacted with if the dialog is modal. For non-modal dialogs, interacting with elements outside of the dialog will close it. With this function, you can return a collection of elements that will be considered part of the dialog and therefore will be excluded from this behavior. Live examples: - [Dialog with React-Toastify](https://ariakit.org/examples/dialog-react-toastify) | ||
preventBodyScroll | Boolean Determines whether the body scrolling will be prevented when the dialog is shown. | ||
autoFocusOnShow | false true (arg: HTMLElement) => boolean Determines whether an element inside the dialog will receive focus when the dialog is shown. By default, this is usually the first tabbable element in the dialog or the dialog itself. The `initialFocus` prop can be used to set a different element to receive focus. | true | |
autoFocusOnHide | false true (arg: HTMLElement) => boolean Determines whether an element outside of the dialog will be focused when the dialog is hidden if another element hasn't been focused in the action of hiding the dialog (for example, by clicking or tabbing into another tabbable element outside of the dialog). By default, this is usually the disclosure element. The `finalFocus` prop can be used to define a different element to be focused. | true | |
initialFocus | HTMLElement RefObject<HTMLElement> Specifies the element that will receive focus when the dialog is first opened. It can be an `HTMLElement` or a `React.RefObject` with an `HTMLElement`. However, if `autoFocusOnShow` is set to `false`, this prop will have no effect. If left unset, the dialog will attempt to determine the initial focus element in the following order: 1. An element with an `autoFocus` prop. 2. The first tabbable element inside the dialog. 3. The first focusable element inside the dialog. 4. The dialog element itself. | ||
finalFocus | HTMLElement RefObject<HTMLElement> Determines the element that will receive focus once the dialog is closed, provided that no other element has been focused while the dialog was being hidden (e.g., by clicking or tabbing into another tabbable element outside of the dialog). However, if `autoFocusOnHide` is set to `false`, this prop will have no effect. If left unset, the element that was focused before the dialog was opened will be focused again. | ||
focusable | Boolean Determines if [Focusable](https://ariakit.org/components/focusable) features should be active on non-native focusable elements. **Note**: This prop only turns off the additional features provided by the [Focusable](https://ariakit.org/components/focusable) component. Non-native focusable elements will lose their focusability entirely. However, native focusable elements will retain their inherent focusability, but without added features such as improved [`autoFocus`](https://ariakit.org/reference/focusable#autofocus), [`accessibleWhenDisabled`](https://ariakit.org/reference/focusable#accessiblewhendisabled), [`onFocusVisible`](https://ariakit.org/reference/focusable#onfocusvisible), etc. | true | |
accessibleWhenDisabled | Boolean Indicates whether the element should be focusable even when it is [`disabled`](https://ariakit.org/reference/focusable#disabled). This is important when discoverability is a concern. For example: > A toolbar in an editor contains a set of special smart paste functions that are disabled when the clipboard is empty or when the function is not applicable to the current content of the clipboard. It could be helpful to keep the disabled buttons focusable if the ability to discover their functionality is primarily via their presence on the toolbar. Learn more on [Focusability of disabled controls](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#focusabilityofdisabledcontrols). | ||
onFocusVisible | BivariantCallback<(event: SyntheticEvent<Element, Event>) => void> Custom event handler invoked when the element gains focus through keyboard interaction or a key press occurs while the element is in focus. This is a programmatic equivalent of the `data-focus-visible` attribute. Live examples: - [Custom Checkbox](https://ariakit.org/examples/checkbox-custom) | ||
preserveTabOrder | Boolean When enabled, `preserveTabOrder` will keep the DOM element's tab order the same as the order in which the `Portal` component was mounted in the React tree. | false | |
portalRef | RefCallback<HTMLElement> MutableRefObject<HTMLElement> `portalRef` is similar to `ref` but is scoped to the portal node. It's useful when you need to be informed when the portal element is appended to the DOM or removed from the DOM. @example const [portalElement, setPortalElement] = useState(null); <Portal portalRef={setPortalElement} />; | ||
portal | Boolean Determines whether the element should be rendered as a React Portal. | true | |
portalElement | HTMLElement (element: HTMLElement) => HTMLElement An HTML element or a memoized callback function that returns an HTML element to be used as the portal element. By default, the portal element will be a `div` element appended to the `document.body`. @example const [portal, setPortal] = useState(null); <Portal portalElement={portal} />; <div ref={setPortal} />; @example const getPortalElement = useCallback(() => { const div = document.createElement("div"); const portalRoot = document.getElementById("portal-root"); portalRoot.appendChild(div); return div; }, []); <Portal portalElement={getPortalElement} />; | HTMLDivElement | |
composite | Boolean Whether the component should behave as a composite widget. This prop should be set to `false` when combining different composite widgets where only one should behave as such. Live examples: - [Multi-selectable Combobox](https://ariakit.org/examples/combobox-multiple) @example ```jsx // Combining two composite widgets (combobox and menu), where only the // Combobox component should behave as a composite widget. const combobox = useComboboxStore(); const menu = useMenuStore({ combobox }); <MenuButton store={menu}>Open Menu</MenuButton> <Menu store={menu} composite={false}> <Combobox store={combobox} /> <ComboboxList store={combobox}> <ComboboxItem value="Apple" /> <ComboboxItem value="Banana" /> <ComboboxItem value="Orange" /> </ComboboxList> </Menu> ``` | true | |
focusOnMove | Boolean Whether the active composite item should receive focus when `store.move` is called. | true | |
moveOnKeyPress | false true (arg: KeyboardEvent<HTMLElement>) => boolean Whether the composite widget should move focus to an item when pressing arrow keys. | true | |
typeahead | Boolean Determines whether the typeahead behavior is enabled. Live examples: - [Multi-selectable Combobox](https://ariakit.org/examples/combobox-multiple) | true |
Packages #
Dependencies #
Peer dependencies #
Previous
BreadcrumbNext
Link