DropDownMenu
The DropDown Menu widget provides a ready-to-use wrapper for adding a menu to button-like elements. This type of menu expands when the content inside of its container is clicked. The DropDown Menu is useful for displaying additional options or actions related to the element.
Related resources
- Get the widget by installing the
@svar-ui/react-menu
package. - Check DropDownMenu API Reference to see the list of configuration properties and events.
- Explore the samples to visualize the available features.
Initialization
To create a DropDownMenu on a page, complete the following steps:
- Import the source file of the DropDownMenu widget on a page:
import { DropDownMenu } from "@svar-ui/react-menu";
- Apply the
<DropDownMenu>
tag to initialize a drop-down menu and wrap a button-like element in it. In case of a button, mind importing it into your component as well:
import { DropDownMenu } from "@svar-ui/react-menu";
import { Button } from "@svar-ui/react-core";
export default function App(){
return (
<DropDownMenu>
<Button type="primary">Click me</Button>
</DropDownMenu>
);
}
- Load a data set with options into the menu:
const options = [
{ id: "add-task:child", text: "Child task" },
{ id: "add-task:above", text: "Task above" },
{ id: "add-task:below", text: "Task below" },
];
export default function App(){
return (
<DropDownMenu options={options}>
<Button type="primary">Click me</Button>
</DropDownMenu>
);
}
- Make sure you apply a theme if you use the DropDownMenu component standalone. Please, refer to applying a theme for more information.
// Example wrapper with theme provider
import { Willow } from "@svar-ui/react-core";
export default function App(){
return (
<Willow>
<DropDownMenu options={options}>
<Button type="primary">Click me</Button>
</DropDownMenu>
</Willow>
);
}
Loading options
Options can be loaded into DropDownMenu on its initialization or after it. To begin with, you need to define a data set in the JSON format.
Specifying a data set
A data set will contain options of the DropDown Menu. You need to specify them as objects with attributes presented as key:value pairs. A data set for DropDownMenu can have both a plain structure and a more complex one - tree-like structure.
- a plain data set structure looks like this:
const options = [
{ id: "add-task:child", text: "Child task" },
{ id: "add-task:above", text: "Task above" },
{ id: "add-task:below", text: "Task below" },
];
- a tree-like data set structure is the following:
const options = [
{ id: "add-task", text: "Add", icon: "wxi wxi-plus", data:[
{ id: "child", text: "Child task" },
{ id: "above", text: "Task above" },
{ id: "below", text: "Task below" }
]}
];
Menu item object structure
Refer to the options property.
Loading options on initialization
To load a prepared data set on initialization of the DropDown Menu, you should use the options
property:
import { DropDownMenu } from "@svar-ui/react-menu";
import { Button } from "@svar-ui/react-core";
const options = [
{ id: "add-task:child", text: "Child task" },
{ id: "add-task:above", text: "Task above" },
{ id: "add-task:below", text: "Task below" },
];
export default function App(){
return (
<DropDownMenu options={options}>
<Button type="primary">Click me</Button>
</DropDownMenu>
);
}
Loading options after initialization
You can load options into DropDownMenu after its initialization from a separate JS file. These are the steps to follow:
- prepare a file with data ("data.js") in the same directory where your application is placed
- specify a function that will return an array of menu options in the data file and export this function to make it available from outside:
export function getProjects(){
return [
{ id:"a", text:"Project A" },
{ id:"b", text:"Project B" },
{ id:"c", text:"Project C" },
{ id:"d", text:"Project D" }
];
}
- import the function into your application and assign it to the variable specified for options
- use the options configuration property in the
<DropDownMenu>
tag. Set the name of the variable as its value or use the shorthand, if the name of the variable coincides with the name of the property:
import { DropDownMenu } from "@svar-ui/react-menu";
import { Button } from "@svar-ui/react-core";
import { getProjects } from "./data";
export default function App(){
const options = getProjects();
return (
<DropDownMenu options={options}>
<Button type="primary">Click me</Button>
</DropDownMenu>
);
}
Related sample: Dropdown menu
Adding custom options
Creating a menu option
You can use a custom component inside of a DropDownMenu item. To add a custom menu item, create a file that will contain the code of your item, for example:
import { Button, Text } from "@svar-ui/react-core";
export default function ButtonMenuOption({ item }){
return (
<div>
<div style={{ width: 120 }} onClick={(e) => e.preventDefault()}>
<Text placeholder={item.name} />
</div>
<Button icon="wxi-plus" type="primary" />
</div>
);
}
By default, clicking anywhere inside of a custom item component will activate menu closing and the click handler triggering. You can prevent it by intercepting the click event and using the preventDefault()
method as in the above example.
Registering the item
When a component is ready, you should register it like this:
import { Button } from "@svar-ui/react-core";
import { DropDownMenu } from "@svar-ui/react-menu";
import ButtonMenuOption from "./your_items/ButtonMenuOption.jsx";
import { registerMenuItem } from "../your_sources/helpers";
registerMenuItem("button", ButtonMenuOption);
export default function App(){
// ...
}
The above code has added the type: "button"
component.
Using the item as a DropDownMenu option
Now you can use the newly created item in the options configuration. A custom "Add New" button is added into the menu below:
import { DropDownMenu } from "@svar-ui/react-menu";
import { Button } from "@svar-ui/react-core";
const options = [
{ id: 1, text: "Add User", subtext: "Ctrl+A" },
{ id: 2, text: "Refresh", subtext: "Ctrl+R" },
{ id: 3, text: "Delete User", css: "danger" },
{ id: "btn", type: "button", name: "Add New" }
];
function clicked(ev){
// ev.action will contain the clicked item object
}
export default function App(){
return (
<DropDownMenu options={options} onClick={clicked}>
<Button type="primary">Click me</Button>
</DropDownMenu>
);
}
The result of adding a custom option into the menu is given below:
Related sample: Custom options
Setting the position of DropDownMenu
You can control the position of DropDownMenu relative to the target via the at
property. In the example below DropDownMenu appears to the right of the target.
import { DropDownMenu } from "@svar-ui/react-menu";
import { Button } from "@svar-ui/react-core";
export default function App(){
return (
<DropDownMenu options={options} at="bottom-fit" onClick={clicked}>
<Button type="primary">Click me (fit)</Button>
</DropDownMenu>
);
}
Related sample: Drop-down menu
The at property can have one of the values listed below:
- "bottom" - (default) a menu appears below the target node, left borders aligned (the menu goes to the right of the action area)
- "right" - a menu appears right to the target node
- "left" - a menu appears left to the target node
- "bottom-left" - a menu appears below the target node, right borders aligned (the menu goes to the left of the action area)
- "bottom-fit" - a menu appears below the target node, the width of the menu is equal to the width of the target node
- "point" - a menu appears at the specified left/top position and ignores the provided node
Related sample: Drop-down menu
Custom triggering of DropDownMenu
You can use DropDownMenu with a custom trigger that will allow you to show the menu anywhere and whenever you need. To do this in React, use a ref to get the menu object with available functions. The menu exposes the show function that can be invoked from the ref.
import { useRef } from "react";
import { DropDownMenu } from "@svar-ui/react-menu";
import { Button } from "@svar-ui/react-core";
export default function App(){
const menuRef = useRef(null);
const options = [ /* ... */ ];
return (
<>
<DropDownMenu ref={menuRef} options={options} />
<div onClick={(ev) => menuRef.current.show(ev)}>Open menu</div>
</>
);
}
The show function takes only one parameter:
// showing a menu manually with a DOM event
menuRef.current.show(ev);
Catching the change of a clicked option
You can catch the change of a clicked option by handling the onClick
event. Inside the event you can get an object of the clicked option as in:
import { useState } from "react";
import { DropDownMenu } from "@svar-ui/react-menu";
import { Button } from "@svar-ui/react-core";
export default function App(){
const [message, setMessage] = useState("");
const options = [ /* ... */ ];
function clicked(ev){
const action = ev.action;
setMessage(action ? `clicked on ${action.id}` : "closed");
}
return (
<>
<DropDownMenu options={options} onClick={clicked}>
<Button type="primary">Click me</Button>
</DropDownMenu>
<div>{message}</div>
</>
);
}
The action property of the event object will contain an object related to the clicked menu item.
Related sample: Drop-down menu
Styling an item of DropDownMenu
You can apply a particular style to a menu item via the css
attribute of an item object. Use a global CSS selector while specifying a style to reach an isolated menu item. In the example below, the text of the third menu option turns red:
import { DropDownMenu } from "@svar-ui/react-menu";
import { Button } from "@svar-ui/react-core";
const options = [
{ id: 1, text: "Add User", subtext: "Ctrl+A" },
{ id: 2, text: "Refresh", subtext: "Ctrl+R" },
{ id: 3, text: "Delete User", css: "my-color" }
];
export default function App(){
return (
<DropDownMenu options={options}>
<Button type="primary">Click me</Button>
</DropDownMenu>
);
}
Add the following CSS to your global stylesheet (e.g., App.css):
/* global CSS */
.item.my-color span {
color: red;
}
As a result, the menu will look like this:
Related sample: Item styling