LegacyMenuItem
Examples
Draggable
Example
Live demo
Code
import { type DragEvent, useCallback, useState } from "react"
import { LegacyMenuItem as MenuItem, type LegacyMenuItemProps } from "blue-react"
export default function MenuItemExample() {
const bodyMenuItemProps: LegacyMenuItemProps = {
className: "w-100",
labelClassName: "d-inline-block",
caretClassName: "d-inline-block"
}
const [itemIDs, setItemIDs] = useState(["1", "2", "3", "4", "5"])
const dragStart = useCallback((event: DragEvent) => {
const target = event.target as HTMLElement
event.dataTransfer.setData("text/plain", target.id)
}, [])
const drop = useCallback(
(event: DragEvent) => {
event.preventDefault()
const draggedId = event.dataTransfer.getData("text")
const dropTargetId = (event.target as HTMLElement).id
const draggedIndex = itemIDs.indexOf(draggedId)
const dropTargetIndex = itemIDs.indexOf(dropTargetId)
const newItemIDs = [...itemIDs]
newItemIDs.splice(draggedIndex, 1)
newItemIDs.splice(dropTargetIndex, 0, draggedId)
setItemIDs(newItemIDs)
},
[itemIDs]
)
const dragOver = useCallback((event: DragEvent) => {
event.preventDefault()
}, [])
return (
<>
<p>
<strong>Important:</strong> To make draggable menu items work in Firefox, the <code>elementType</code>{" "}
must not be <code>"button"</code>. Set it to something else, like <code>"div"</code>.
</p>
<div onDrop={drop} onDragOver={dragOver}>
{itemIDs.map((id) => (
<MenuItem
{...bodyMenuItemProps}
elementType={"div"}
key={id}
id={id}
draggable
onDragStart={dragStart}
onDragOver={dragOver}
label={`Item ${id}`}
/>
))}
</div>
</>
)
}
Horizontal layout in sidebar
Example
Live demo
Code
import { useState } from "react"
import { MenuItem } from "blue-react"
import { SidebarMenu } from "blue-react"
export default function MenuItemExample() {
const [navigationSource, setNavigationSource] = useState<"user" | "default">("default")
return (
<div className="bg-primary position-relative">
<SidebarMenu sidebarClass="position-static shadow-none overflow-visible" menuClass="overflow-visible">
<div className="blue-sidebar-visible-on-open blue-sidebar-menu-horizontal-on-open">
<MenuItem
label="Default"
labelClassName="text-center w-100"
onClick={() => setNavigationSource("default")}
isActive={navigationSource === "default"}
/>
<MenuItem
label="User"
labelClassName="text-center w-100"
onClick={() => setNavigationSource("user")}
isActive={navigationSource === "user"}
/>
</div>
</SidebarMenu>
<p className="p-3 bg-body">Resize the browser to see how the sidebar and its items behave.</p>
</div>
)
}
Horizontal layout with dropdown
Example
Live demo
Code
import { MenuItem } from "blue-react"
import { SidebarMenu } from "blue-react"
import { BoxArrowLeft, House } from "react-bootstrap-icons"
import { IconMenuItem } from "blue-react"
import { useState } from "react"
export default function MenuItemExample() {
const [showDropdown, setShowDropdown] = useState(false)
return (
<div className="bg-primary position-relative">
<SidebarMenu
sidebarClass="position-static shadow-none overflow-visible"
menuClass="overflow-visible"
topContent={
<>
<div className="d-flex blue-sidebar-menu-horizontal-on-open">
<MenuItem
href="#home"
label="Home"
icon={<House className="bi" />}
labelClassName="text-center w-100"
/>
<div className="position-relative">
<IconMenuItem
title="More"
supportOutside
showDropdown={showDropdown}
onShowDropdown={setShowDropdown}
labelClassName="text-center w-100"
dropdownClassName="position-absolute z-3 end-0 blue-sidebar-menu-vertical-on-open"
>
<div
onClick={() => {
setShowDropdown(false)
}}
>
<MenuItem label="Sign out" icon={<BoxArrowLeft className="bi" />} />
</div>
</IconMenuItem>
</div>
</div>
</>
}
/>
<p className="p-3 bg-body">Resize the browser to see how the sidebar and its items behave.</p>
</div>
)
}
Sidebar
Example
Live demo
Code
import { MenuItem } from "blue-react"
import { SidebarMenu } from "blue-react"
export default function MenuItemExample() {
return (
<div className="bg-primary position-relative">
<SidebarMenu sidebarClass="position-static shadow-none overflow-visible" menuClass="overflow-visible">
<MenuItem icon={<span>😅</span>} label="Hello World" />
<MenuItem
icon={<span style={{ transform: "scale(-1, 1)" }}>👀</span>}
label="Click to see sub items"
supportOutside
>
<MenuItem label="I am a child, hi" />
<MenuItem label="Second child">
<MenuItem label="Even more nested" />
</MenuItem>
</MenuItem>
</SidebarMenu>
<p className="p-3 bg-body">Resize the browser to see how the sidebar and its items behave.</p>
</div>
)
}
Usage in body
Example
Live demo
Code
import { LegacyMenuItem as MenuItem, type LegacyMenuItemProps } from "blue-react"
import { EmojiHeartEyesFill } from "react-bootstrap-icons"
export default function MenuItemExample() {
const bodyMenuItemProps: LegacyMenuItemProps = {
className: "w-100",
labelClassName: "d-inline-block",
caretClassName: "d-inline-block"
}
return (
<>
<p>Usage in body without sidebar or action bar</p>
<div className="d-flex flex-column flex-md-row gap-3 w-100">
<article className="flex-fill">
<h4 className="mt-4 mb-3">Single menu item</h4>
<MenuItem {...bodyMenuItemProps} icon={<EmojiHeartEyesFill />} label="John Boy" />
</article>
<article className="flex-fill">
<h4 className="mt-4 mb-3">Dropdown</h4>
<MenuItem {...bodyMenuItemProps} icon={<EmojiHeartEyesFill />} label="John Boy">
<MenuItem {...bodyMenuItemProps} icon={<EmojiHeartEyesFill />} label="I am a child item" />
</MenuItem>
</article>
<article className="flex-fill">
<h4 className="mt-4 mb-3">Split dropdown</h4>
<div
className="d-grid w-100"
style={{
gridTemplateAreas: '"a b" "c c"',
gridTemplateColumns: "minmax(auto, calc(100% - 3rem)) 3rem"
}}
>
<MenuItem
{...bodyMenuItemProps}
style={{ gridArea: "a" }}
icon={<EmojiHeartEyesFill />}
label="John Boy"
/>
<MenuItem
{...bodyMenuItemProps}
style={{ gridArea: "b" }}
dropdownStyle={{ gridArea: "c" }}
supportOutside
>
<MenuItem {...bodyMenuItemProps} icon={<EmojiHeartEyesFill />} label="I am a child item" />
</MenuItem>
</div>
</article>
</div>
</>
)
}
Props
| Name | Description | Type | Default |
|---|