Primitives
Menu
Dropdown menu for actions, resources, labels, separators, and submenus.
Composition
The preferred shape for composing the installed primitive from its exported parts.
Parts
Exported compound parts from the installed source.
Menu├── MenuTrigger├── MenuContent├── MenuItem├── MenuSeparator└── MenuLabelThe refined source installs this primitive from src/registry/sources/refined/ui/menu.tsx. Install it on its own with the command above, or inspect the source below.
npx shadcn@latest add http://127.0.0.1:3000/r/refined/menu.jsonInstalled dependencies
Installed with this primitive because the slot depends on them; they are support files, not standalone sidebar items.
Control variants
src/registry/sources/refined/control-variants.tsSupportSurface variants
src/registry/sources/refined/surface-variants.tsSupportEffect utilities
src/registry/sources/refined/effects.cssEffectRaw code
Primary installed primitive source
Base UI Menu slot
src/registry/sources/refined/ui/menu.tsx
"use client";import { Menu as MenuPrimitive } from "@base-ui/react/menu";import type { ComponentProps } from "react";import type { MenuContentProps, MenuItemProps, MenuLabelProps, MenuProps, MenuSeparatorProps, MenuTriggerProps,} from "@/components/refined-ui/contracts";import { controlSize, controlSurfaceClasses } from "@/components/refined-ui/control-variants";import { cn } from "@/components/refined-ui/lib/cn";import { skinEffects, skinId, skinSlot } from "@/components/refined-ui/skin";import { floatingListContentClasses, floatingListItemClasses } from "@/components/refined-ui/surface-variants";// Refined skin slot, 100% Base UI: trigger shares --radius-control/controlSize w/ Button & Select — one token set, every trigger matches.type RefinedMenuTriggerProps = MenuTriggerProps & Pick<ComponentProps<typeof MenuPrimitive.Trigger>, "nativeButton" | "render">;export function Menu({ children, ...props }: MenuProps) { return <MenuPrimitive.Root {...props}>{children}</MenuPrimitive.Root>;}export function MenuTrigger({ size = "sm", className, children, disabled, ...props }: RefinedMenuTriggerProps) { const skinClasses = skinSlot("menu-trigger", { size }); return ( <MenuPrimitive.Trigger data-ui="agent" data-slot="menu-trigger" data-control="true" data-size={size} className={cn( "relative isolate inline-flex shrink-0 cursor-pointer items-center justify-center overflow-visible rounded-[var(--radius-control)] font-medium outline-none transition focus-visible:ring-2 focus-visible:ring-foreground/20 disabled:cursor-not-allowed disabled:opacity-45", controlSurfaceClasses, controlSize({ size }), skinClasses, className, )} disabled={disabled} {...props} > <span data-ui="agent" data-slot="control-content" className="relative z-[1] inline-flex items-center justify-center gap-[inherit]"> {children} </span> </MenuPrimitive.Trigger> );}export function MenuContent({ className, children, ...props }: MenuContentProps) { const skinClasses = skinSlot("menu-content", {}); return ( <MenuPrimitive.Portal> {/* Portal escapes token-scoped ancestor — positioner re-asserts ACTIVE skin's scope (theme.css mirrors). */} <MenuPrimitive.Positioner data-skin={skinId()} data-effects={skinEffects()} side="bottom" align="start" sideOffset={6} className="z-[80] outline-none" > <MenuPrimitive.Popup data-ui="agent" data-slot="menu-content" className={cn("min-w-[max(11rem,var(--anchor-width))]", floatingListContentClasses, skinClasses, className)} {...props} > {children} </MenuPrimitive.Popup> </MenuPrimitive.Positioner> </MenuPrimitive.Portal> );}export function MenuItem({ className, ...props }: MenuItemProps) { const skinClasses = skinSlot("menu-item", { disabled: Boolean(props.disabled) }); return ( <MenuPrimitive.Item data-ui="agent" data-slot="menu-item" className={cn(floatingListItemClasses, skinClasses, className)} {...props} /> );}export function MenuSeparator({ className, ...props }: MenuSeparatorProps) { const skinClasses = skinSlot("menu-separator", {}); return ( // -mx-[--popover-padding] bleeds rule through popup padding for edge-to-edge; rows keep inset, tracks same knob as popup. <MenuPrimitive.Separator data-ui="agent" data-slot="menu-separator" className={cn("-mx-[var(--popover-padding)] my-1 h-px bg-border", skinClasses, className)} {...props} /> );}export function MenuLabel({ className, ...props }: MenuLabelProps) { const skinClasses = skinSlot("menu-label", {}); return ( <div data-ui="agent" data-slot="menu-label" className={cn("px-2 py-1 text-micro font-medium uppercase tracking-[0.08em] text-muted-foreground", skinClasses, className)} {...props} /> );}