import { Dropdown, DropdownItem, DropdownMenu } from '@duik/it'
import Dropdown, { DropdownItem, DropdownMenu } from '@duik/dropdown'
Use buttons in forms, as links with many varieties.
You can control apperence by simply passing boolean props to render some predefined stylings or you can pass your className or style props as well.
<Dropdown buttonText={<strong>Click me</strong>}> <DropdownItem> <Icon mr>camera</Icon>Item 1 </DropdownItem> <DropdownItem> <Icon mr>stats</Icon>Item 1 </DropdownItem> <DropdownItem Component={Link} to="#somewhere"> <Icon mr>tap_click_force_touch</Icon>Item as Link </DropdownItem> </Dropdown> <div class="outer-events-handler dropdown btn-group"> <button class="btn dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" type="button" role="button"> <strong>Click me</strong> </button> <div class="dropdown-menu bottom-right"> <button class="btn dropdown-item" type="button" role="button"> <i class="uikon mr">camera</i>Item 1 </button> <button class="btn dropdown-item" type="button" role="button"> <i class="uikon mr">stats</i>Item 1 </button> <a class="btn dropdown-item" role="button" href="/docs/react/dropdown#somewhere"> <i class="uikon mr">tap_click_force_touch</i>Item as Link </a> </div> </div> ReactHTML Snippet |
By default, the dropdown doesn't close when you click on the dropdown item. This is intentional. If you want to close the dropdown after clicking the option, you can pass closeOnOptionClick
prop as true. If you want to have a better control and decide per item, then check the example below.
<Dropdown buttonText={<strong>Click me</strong>}> <DropdownItem>Item 1</DropdownItem> <DropdownItem>Item 2</DropdownItem> <DropdownItem Component={Link} to="#somewhere">Item as Link</DropdownItem> </Dropdown> <div class="outer-events-handler dropdown btn-group"> <button class="btn dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" type="button" role="button"> <strong>Click me</strong> </button> <div class="dropdown-menu bottom-right"> <button class="btn dropdown-item" type="button" role="button">Item 1</button> <button class="btn dropdown-item" type="button" role="button">Item 2</button> <a class="btn dropdown-item" role="button" href="/docs/react/dropdown#somewhere">Item as Link </a> </div> </div> ReactHTML Snippet |
It wouldn't be really useful if you cannot control the state of the dropdown, for example you want to close the dropdown on selecting an option. Surely this could be implemented directly, but with this approach, we are giving you a better control over the state rather than enforcing the behaviour, especially when there are many use cases where you don't really want to close the dropdown.
<Dropdown> {({ handleClose, handleOpen, handleToggle, setOpenState, isOpen }) => ( <> <DropdownItem>Item 1</DropdownItem> <DropdownItem onClick={handleClose}>Item 2 with close</DropdownItem> </> )} </Dropdown> <div class="outer-events-handler dropdown btn-group"> <button class="btn dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" type="button" role="button">Action</button> <div class="dropdown-menu bottom-right"> <button class="btn dropdown-item" type="button" role="button">Item 1</button> <button class="btn dropdown-item" type="button" role="button">Item 2 with close</button> </div> </div> ReactHTML Snippet |
As it is clear from example, children can be a classic ReactNode or in this case a functional component format (props) => <>Something</>
which can accept several handlers. In most cases, you want to use handleClose or handleToggle, but for conveniency, other handlers are exposed as well.
The handlers are documented in useOpenState hook documentation, which is used for handling the state of the dropdown.
By default, the menu position is set to bottom-right (bottom from the click element, overflowing to the right). You can change this by passing menuPosition
prop. These values are supported
For Typescript, enum DropdownMenuPosition
is available.
If the menu doesn't fit the window viewport, the default menu component will try to reposition itself automatically. You would need to perform this action by yourself if you use custom MenuComponent
as a prop.
<Dropdown buttonText="Bottom Left" menuPosition="bottom-left"> <DropdownItem> Long Item to click </DropdownItem> </Dropdown> <div class="outer-events-handler dropdown btn-group"> <button class="btn dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" type="button" role="button">Bottom Left</button> <div class="dropdown-menu bottom-left"> <button class="btn dropdown-item" type="button" role="button">Long Item to click</button> </div> </div> ReactHTML Snippet | |
<Dropdown buttonText="Top Center" menuPosition="top-center"> <DropdownItem> Long Item to click </DropdownItem> </Dropdown> <div class="outer-events-handler dropdown btn-group"> <button class="btn dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" type="button" role="button">Top Center</button> <div class="dropdown-menu top-center"> <button class="btn dropdown-item" type="button" role="button">Long Item to click</button> </div> </div> ReactHTML Snippet | |
<Dropdown buttonText="Left Center" menuPosition="left-center"> <DropdownItem> Dropdown Item </DropdownItem> <DropdownItem> Dropdown Item </DropdownItem> <DropdownItem> Dropdown Item </DropdownItem> </Dropdown> <div class="outer-events-handler dropdown btn-group"> <button class="btn dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" type="button" role="button">Left Center</button> <div class="dropdown-menu left-center"> <button class="btn dropdown-item" type="button" role="button">Dropdown Item</button> <button class="btn dropdown-item" type="button" role="button">Dropdown Item</button> <button class="btn dropdown-item" type="button" role="button">Dropdown Item</button> </div> </div> ReactHTML Snippet | |
<Dropdown buttonText="Right Bottom" menuPosition="right-bottom"> <DropdownItem> Dropdown Item </DropdownItem> <DropdownItem> Dropdown Item </DropdownItem> <DropdownItem> Dropdown Item </DropdownItem> </Dropdown> <div class="outer-events-handler dropdown btn-group"> <button class="btn dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" type="button" role="button">Right Bottom</button> <div class="dropdown-menu right-bottom"> <button class="btn dropdown-item" type="button" role="button">Dropdown Item</button> <button class="btn dropdown-item" type="button" role="button">Dropdown Item</button> <button class="btn dropdown-item" type="button" role="button">Dropdown Item</button> </div> </div> ReactHTML Snippet |
In the previous examples, only DropdownItem
has been used. However this doesn't mean that Dropdown
limited to it. Let's render custom dropdown content.
Would you like to upgrade your account for $10? | <Dropdown buttonText="Upgrade Account" menuPosition="bottom-left" > {({ handleClose, handleOpen, handleToggle, setOpenState, isOpen }) => ( <div style={{ padding: 30, minWidth: 360 }}> <h3>Would you like to upgrade your account for $10?</h3> <div> <Button primary onClick={handleClose}>Upgrade to PRO</Button> <Button onClick={handleClose}>Maybe later</Button> </div> </div> )} </Dropdown> <div class="outer-events-handler dropdown btn-group"> <button class="btn dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" type="button" role="button">Upgrade Account</button> <div class="dropdown-menu top-right"> <div style="padding:30px;min-width:360px"> <h3>Would you like to upgrade your account for $10?</h3> <div> <button class="btn btn-primary" type="button" role="button">Upgrade to PRO</button> <button class="btn" type="button" role="button">Maybe later</button> </div> </div> </div> </div> ReactHTML Snippet |
You have 2 ways how to customize the button.
Simpler way, the clickable button component is @duik/button in it's core. You can customize it by passing props to it with "buttonProps". See example below.
<Dropdown buttonProps={{ primary: true }} menuPosition="bottom-left" > <DropdownItem> Item to click </DropdownItem> </Dropdown> <div class="outer-events-handler dropdown btn-group"> <button class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" type="button" role="button">Action</button> <div class="dropdown-menu bottom-left"> <button class="btn dropdown-item" type="button" role="button">Item to click</button> </div> </div> ReactHTML Snippet |
<Dropdown buttonProps={{ hideArrows: true, primary: true }} menuPosition="bottom-left" > <DropdownItem> Item to click </DropdownItem> </Dropdown> <div class="outer-events-handler dropdown btn-group"> <button class="btn btn-primary dropdown-toggle dropdown-toggle-no-arrows" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" type="button" role="button">Action</button> <div class="dropdown-menu bottom-left"> <button class="btn dropdown-item" type="button" role="button">Item to click</button> </div> </div> ReactHTML Snippet |
You can also define totally new Button component and pass it to the Dropdown
! Your component should accept useOpenState handlers. See example below.
import { DropdownButtonProps, Button } from '@duik/it' // Defining button (TS), don't forget class "dropdown-toggle" const ExampleButton = ({ // useOpenState hook handlers handleToggle, handleClose, handleOpen, setOpenState, isOpen }: DropdownButtonProps) => ( <Button success onClick={handleToggle} square> <Icon>edit</Icon> </Button> ) // Using custom button <Dropdown ButtonComponent={ExampleButton}> <DropdownItem>Item to click</DropdownItem> </Dropdown> <div class="outer-events-handler dropdown btn-group"> <button class="btn btn-success btn-square dropdown-toggle" type="button" role="button"> <i class="uikon">edit</i> </button> <div class="dropdown-menu top-right"> <button class="btn dropdown-item" type="button" role="button">Item to click</button> </div> </div> ReactHTML Snippet |
children | Required: false |
type: React.ReactNode or React.FunctionalComponent | |
You can pass regular react node or a render prop which can accepts several handlers to control the UI state. Your functional component will receive useOpenState controls as props. |
className | Required: false |
type: string | |
Passed to the wrapping element OuterEventsHandler |
buttonText | Required: false |
type: React.ReactNode | default value: "Actions" |
Text or node you want to appear in the button. |
ButtonComponent | Required: false |
type: React.FunctionalComponent | default value: DropdownButton |
You can pass your custom button component. Your component will receive set of useOpenState controls as props. |
buttonProps | Required: false |
type: Props of ButtonComponent | |
This comes handy if you want to pass some props to the button without defining a new ButtonComponent, such as className etc. |
menuPosition | Required: false |
type: DropdownMenuPosition | default value: "bottom-right" |
See Menu Positioning for more details |
MenuComponent | Required: false |
type: React.FunctionalComponent | default value: DropdownMenu |
You can pass your custom menu component. Your component will receive set of useOpenState controls as props. |
menuProps | Required: false |
type: Props of MenuComponent | |
This comes handy if you want to pass some props to the button without defining a new MenuComponent, such as className etc. |
...rest | Required: false |
type: any | |
Other properties are passed down to the wrapping element OuterEventsHandler |
DropdownItem is just a styled Button component and it supports all the props that are accepted by the Button, including appearence, sizes, Component prop and others.