The Dropdown Menu component is designed to display menus that when clicked triggers some action, there are different forms of Menu in Clay/Lexicon. This document describes the main ways to build a menu and recommendations.
Clay provides two possible possibilities to build a Menu, using composition that we call low-level that allows you to add new use cases and adapt them to your use case and components like high-level which are property-setting oriented components. We recommend that you always try to use compositing when you need flexibility, whether it’s configuring some internal components that aren’t possible in a high-level component or adding your own elements to an item, group, or other use cases that don’t exist in Clay.
Content
Dropdown Menu provides two options for building the menu using static content when data does not change during an application’s lifecycle and dynamic for content that changes during the application lifecycle or the data comes from the server.
Static
The simplest example of a static menu is rendering a simple list of options.
The example above shows how Clay even with the explicit composition of the menu structure manages to provide the filter to work OOTB with static content.
Compositing for dynamic content becomes simpler and also provides the same features as static, such as OOTB filter and groups. The component is also data agnostic designed from the ground up for this purpose to avoid transformations having to be done at render time.
The filter in a Menu works OOTB, just declaring the <DropDown.Search> component in the composition, as in the examples shown for static and dynamic content. The Filter can be done by DropDown itself as well as the developer can control the filter and make his own filter rule.
DropDown filters items according to the value rendered as children of <DropDown.Item>, when there are more detailed compositions in the item, the filter will not work because it cannot determine which value to use to filter, in this scenario configure the item’s value using the textValue property.
You may want to create a trigger that is not necessarily in the same tree as DropDown, due to HTML markup issues, for these cases you can use <ClayDropDown.Menu>.
Using <ClayDropDown.Menu> allows you to better control the state of DropDown but you will have to deal with visibility, focus management, and other details.
As a recommendation only use this component as a last resort, it doesn’t
provide some OOTB features like focus control or accessibility at all.
Snippet
importClayDropDownfrom'@clayui/drop-down';
importReact, {useState, useRef} from'react';
constMenu= ({children, hasLeftSymbols, hasRightSymbols}) => {
consttriggerElementRef=useRef(null);
const [expand, setExpand] =useState(false);
constmenuElementRef=useRef(null);
consthandleExpand= (event) => {
// This is not ideal for allowing you to have more than// one trigger for the same content but it simulates the// advantages of controlling `DropDown.Menu`.triggerElementRef.current=event.target;
setExpand(!expand);
};
return (
<div>
<div>
<buttontype="button"onClick={handleExpand}>
Home
</button>
</div>
<div>
<buttontype="button"onClick={handleExpand}>
Product
</button>
</div>
<ClayDropDown.Menuactive={expand}
alignElementRef={triggerElementRef}
hasLeftSymbols={hasLeftSymbols}
hasRightSymbols={hasRightSymbols}
onActiveChange={() =>setExpand(!expand)}
ref={menuElementRef}
>
{children}
</ClayDropDown.Menu>
</div>
);
};
Variants
Clay provides other ways to use the Clay component, which we call high-level components, which are designed to do a specific high-level behavior different from compositing that allow different possibilities, are less flexible.
Icon
To indicate a dropdown menu and improve user understanding, set the triggerIcon property and it will display the icon chosen alongside the button text to indicate the dropdown functionality.
The default value is null.
With Items
Allows you to create a simple DropDown, through its API you are able to create a Menu with groups of checkboxes and radios, links, buttons, search, caption, etc.
When using DropDownWithItems, you can customize the icon on the dropdown button via the triggerIcon prop.
Cascading Menu
DropDownWithItems allows the possibility to create a contextual menu, the nature of the API allows the creation of more cascade menus but the Lexicon specification recommends using only one level and using DropDownWithDrilldown component.
To render a cascading menu it is necessary to set the type of the item to contextual and add to the items object that follows the same API as the other items.
An important thing to have in mind, is that the DropDownWithDrilldown
component, will render its menus in the order that they are specified. This
means that if you specify the menus in the wrong order, the menu animation
will not behave correctly.
Caveats
One caveat with the drop down menu is that it is rendered inside of a React Portal and is rendered directly to the body element. This means if you are using the menuWidth prop set to auto, it will not respect the size of the node parent of the drop down, since the menu is rendered directly to the body.
Children content to render a dynamic or static content.
items
Array<T>|undefined
Property to render content with dynamic data.
active
boolean|undefined
Flag to indicate if the DropDown menu is active or not (controlled).
This API is generally used in conjunction with closeOnClickOutside=true
since often we are controlling the active state by clicking another element
within the document.
alignmentByViewport
boolean|undefined
Flag to align the DropDown menu within the viewport.
alignmentPosition
number|AlignPoints|undefined
Default position of menu element. Values come from ./Menu.
Prop to pass DOM element attributes to DropDown.Menu.
menuHeight
"auto"|undefined
Adds utility class name dropdown-menu-height-${height}
menuWidth
"sm"|"shrink"|"full"|undefined
The modifier class dropdown-menu-width-${width} makes the menu expand
the full width of the page.
sm makes the menu 500px wide.
shrink makes the menu auto-adjust to text and max 240px wide.
full makes the menu 100% wide.
onActiveChange
InternalDispatch<boolean>|undefined
Callback for when the active state changes (controlled).
This API is generally used in conjunction with closeOnClickOutside=true
since often we are controlling the active state by clicking another element
within the document.