ClayClay
  • Get Started
    • How to Use Clay
    • How to Read This Documentation
    • Composition Philosophy
    • Migrating From v2.x
    • Using Clay in JSPs
  • Components
    • Alert
    • Application Bar
    • Aspect Ratio
    • Autocomplete
    • Badge
    • Breadcrumb
    • Button Group
    • Buttons
    • Card
    • Chart
    • Color Picker
    • Data Provider
    • Date Picker
    • Drop Down
    • Empty State
    • Form
      • Checkbox
      • Dual List Box
      • Input
      • Radio Group
      • Select
      • Select Box
      • Toggle Switch
    • Forms Hierarchy
    • Heading
    • Icon
    • Label
    • Layout
    • Link
    • List
    • Loading Indicator
    • Localized Input
    • Management Toolbar
    • Menubar (Vertical Navigation)
    • Modal
    • Multi Select
    • Multi Step Nav
    • Nav
    • Navigation Bar
    • OverlayMask
    • Pagination
    • Pagination Bar
    • Panel
    • Popover
    • Progress Bar
    • Provider
    • Sidebar
    • Slider
    • Sticker
    • Table
    • Tabs
    • Text
    • Timelines
    • Time Picker
    • Toolbar
    • Tooltip
    • TreeView
    • Upper Toolbar
    • VerticalBar
  • Contributing
  • CSS Framework
    • Paver
    • SCSS
    • Color
    • Grid
    • Content
      • Typography
      • C Kbd
    • Utilities
      • Autofit
      • C Focus Inset
      • C Inner
      • C Spacing Utilities
      • Inline Item
      • Text
    • Playground
  • Examples
  • Docs
  • Sass API
  • Blog
  • Storybook
  • Codesandbox
  • Github
  • Use this menu to toggle between Atlas and Base Themes.

Drop Down

yarn add @clayui/drop-down

A dropdown menu displays a list of options for the element that triggers it.

  • Examples
  • Markup
  • API

Stable3.62.0View in LexiconCHANGELOGstorybook demos

  • Composing
    • Using dropdown without a trigger
  • DropDownWithItems
    • Cascading Menu
  • DropDownWithDrilldown
  • Caveats

Composing

DropDown's composition gives you the space to create more complex DropDowns, such as adding a form within DropDown, and creating simple DropDowns with the high-level ClayDropDownWithItems component that covers most basic Lexicon use cases.

Copied!

You may want to use only the content of DropDown for other cases, such as mounting an Autocomplete, so use DropDown.Menu instead of DropDown which gives you the flexibility to only control content without a trigger.

DropDown consists of a DropDown.Menu that controls the trigger and uses it as the basis for aligning DropDown content.

Using dropdown without a trigger

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.

import ClayDropDown from '@clayui/drop-down';
import React, {useState, useRef} from 'react';

const Menu = ({children, hasLeftSymbols, hasRightSymbols}) => {
	const triggerElementRef = useRef(null);
	const [expand, setExpand] = useState(false);
	const menuElementRef = useRef(null);

	const handleExpand = (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>
				<button type="button" onClick={handleExpand}>
					Home
				</button>
			</div>
			<div>
				<button type="button" onClick={handleExpand}>
					Product
				</button>
			</div>

			<ClayDropDown.Menu
				active={expand}
				alignElementRef={triggerElementRef}
				hasLeftSymbols={hasLeftSymbols}
				hasRightSymbols={hasRightSymbols}
				onActiveChange={() => setExpand(!expand)}
				ref={menuElementRef}
			>
				{children}
			</ClayDropDown.Menu>
		</div>
	);
};

DropDownWithItems

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.

Copied!
Code Sample (expand to see it)

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.

const items = [
	{label: 'Folder'},
	{type: 'divider'},
	{
		items: [
			{label: 'Basic Document'},
			{label: 'Contract'},
			{label: 'Marketing Banner'},
			{label: 'Spreadsheet'},
			{label: 'Presentation'},
		],
		label: 'Document',
		type: 'contextual',
	},
	{label: 'Shortcut'},
	{label: 'Repository'},
];

DropDownWithDrilldown

A Drilldown menu allows the user to navigate to and/or select an element from a contextual list. It can be triggered by a dropdown button.

Copied!
Code Sample (expand to see it)

The way the Drilldown component links the menus is done via reference, the menu needs a unique id.

const menus = {
	of23: [{title: 'First'}],
};

From the id you are able to link to another menu using the child property.

const menus = {
	of23: [{title: 'First', child: 'of09'}],
	of09: [{title: 'Three'}],
};

If you want to add separators between your menu items, it's possible to do so, by using an item that has this shape {type: 'divider'}.

const menus = {
	of23: [
		{title: 'First', child: 'of09'},
		{type: 'divider'},
		{title: 'Second'},
	],
	of09: [{title: 'Three'}],
};
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.

How can this be improved? Create an issue!