- Get Started
- Product
- Resources
- Tools & SDKs
- Framework
- Reference
- Get Started
- Product
- Resources
- Tools & SDKs
- Framework
- Reference
Action Menu - Admin Components
The Medusa Admin often provides additional actions in a dropdown shown when users click a three-dot icon.
To create a component that shows this menu in your customizations, create the file src/admin/components/action-menu.tsx
with the following content:
1import { 2 DropdownMenu,3 IconButton,4 clx,5} from "@medusajs/ui"6import { EllipsisHorizontal } from "@medusajs/icons"7import { Link } from "react-router-dom"8 9export type Action = {10 icon: React.ReactNode11 label: string12 disabled?: boolean13} & (14 | {15 to: string16 onClick?: never17 }18 | {19 onClick: () => void20 to?: never21 }22)23 24export type ActionGroup = {25 actions: Action[]26}27 28export type ActionMenuProps = {29 groups: ActionGroup[]30}31 32export const ActionMenu = ({ groups }: ActionMenuProps) => {33 return (34 <DropdownMenu>35 <DropdownMenu.Trigger asChild>36 <IconButton size="small" variant="transparent">37 <EllipsisHorizontal />38 </IconButton>39 </DropdownMenu.Trigger>40 <DropdownMenu.Content>41 {groups.map((group, index) => {42 if (!group.actions.length) {43 return null44 }45 46 const isLast = index === groups.length - 147 48 return (49 <DropdownMenu.Group key={index}>50 {group.actions.map((action, index) => {51 if (action.onClick) {52 return (53 <DropdownMenu.Item54 disabled={action.disabled}55 key={index}56 onClick={(e) => {57 e.stopPropagation()58 action.onClick()59 }}60 className={clx(61 "[&_svg]:text-ui-fg-subtle flex items-center gap-x-2",62 {63 "[&_svg]:text-ui-fg-disabled": action.disabled,64 }65 )}66 >67 {action.icon}68 <span>{action.label}</span>69 </DropdownMenu.Item>70 )71 }72 73 return (74 <div key={index}>75 <DropdownMenu.Item76 className={clx(77 "[&_svg]:text-ui-fg-subtle flex items-center gap-x-2",78 {79 "[&_svg]:text-ui-fg-disabled": action.disabled,80 }81 )}82 asChild83 disabled={action.disabled}84 >85 <Link to={action.to} onClick={(e) => e.stopPropagation()}>86 {action.icon}87 <span>{action.label}</span>88 </Link>89 </DropdownMenu.Item>90 </div>91 )92 })}93 {!isLast && <DropdownMenu.Separator />}94 </DropdownMenu.Group>95 )96 })}97 </DropdownMenu.Content>98 </DropdownMenu>99 )100}
The ActionMenu
component shows a three-dots icon (or EllipsisHorizontal
) from the Medusa Icons package in a button.
When the button is clicked, a dropdown menu is shown with the actions passed in the props.
The component accepts the following props:
groups
object[]Groups of actions to be shown in the dropdown. Each group is separated by a divider.
groups
object[]Example#
Use the ActionMenu
component in any widget or UI route.
For example, create the widget src/admin/widgets/product-widget.tsx
with the following content:
1import { defineWidgetConfig } from "@medusajs/admin-sdk"2import { Pencil } from "@medusajs/icons"3import { Container } from "../components/container"4import { ActionMenu } from "../components/action-menu"5 6const ProductWidget = () => {7 return (8 <Container>9 <ActionMenu groups={[10 {11 actions: [12 {13 icon: <Pencil />,14 label: "Edit",15 onClick: () => {16 alert("You clicked the edit action!")17 },18 },19 ],20 },21 ]} />22 </Container>23 )24}25 26export const config = defineWidgetConfig({27 zone: "product.details.before",28})29 30export default ProductWidget
This widget also uses a Container custom component.
Use in Header#
You can also use the action menu in the Header component as part of its actions.
For example:
1import { defineWidgetConfig } from "@medusajs/admin-sdk"2import { Pencil } from "@medusajs/icons"3import { Container } from "../components/container"4import { Header } from "../components/header"5 6const ProductWidget = () => {7 return (8 <Container>9 <Header 10 title="Product Widget"11 subtitle="This is my custom product widget"12 actions={[13 {14 type: "action-menu",15 props: {16 groups: [17 {18 actions: [19 {20 icon: <Pencil />,21 label: "Edit",22 onClick: () => {23 alert("You clicked the edit action!")24 },25 },26 ],27 },28 ],29 },30 },31 ]}32 />33 </Container>34 )35}36 37export const config = defineWidgetConfig({38 zone: "product.details.before",39})40 41export default ProductWidget