{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "menu", "type": "registry:ui", "title": "Menu", "description": "A customizable menu component", "dependencies": [ "@base-ui/react", "clsx", "tailwind-merge", "lucide-react" ], "registryDependencies": [ "classes" ], "files": [ { "path": "src/registry/pure-ui/ui/menu/index.tsx", "content": "\"use client\";\r\n\r\nimport { createContext, useContext, useMemo } from \"react\";\r\nimport { Menu as MenuPrimitive } from \"@base-ui/react/menu\";\r\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\r\n\r\nimport { cn } from \"@/lib/classes\";\r\n\r\nconst cssAnimationPresets = {\r\n none: \"transition-none\",\r\n scale: [\r\n `[transition-property:scale,opacity] [will-change:scale,opacity]`,\r\n `data-starting-style:scale-80 data-starting-style:opacity-0 data-ending-style:opacity-0 data-ending-style:scale-80`,\r\n ],\r\n fade: [\r\n `[transition-property:opacity] [will-change:opacity]`,\r\n `data-starting-style:opacity-0 data-ending-style:opacity-0`,\r\n ],\r\n slideOutside: [\r\n `[transition-property:translate,opacity] [will-change:translate,opacity]`,\r\n // side=bottom\r\n `data-[side=bottom]:data-starting-style:opacity-0 data-[side=bottom]:data-starting-style:translate-y-[10px] data-[side=bottom]:data-ending-style:translate-y-[10px] data-[side=bottom]:data-ending-style:opacity-0`,\r\n // side=top\r\n `data-[side=top]:data-starting-style:opacity-0 data-[side=top]:data-starting-style:translate-y-[-10px] data-[side=top]:data-ending-style:translate-y-[-10px] data-[side=top]:data-ending-style:opacity-0`,\r\n // side=left\r\n `data-[side=left]:data-starting-style:opacity-0 data-[side=left]:data-starting-style:translate-x-[-10px] data-[side=left]:data-ending-style:translate-x-[-10px] data-[side=left]:data-ending-style:opacity-0`,\r\n // side=right\r\n `data-[side=right]:data-starting-style:opacity-0 data-[side=right]:data-starting-style:translate-x-[10px] data-[side=right]:data-ending-style:translate-x-[10px] data-[side=right]:data-ending-style:opacity-0`,\r\n // side=inline-start\r\n `data-[side=inline-start]:data-starting-style:opacity-0 data-[side=inline-start]:data-starting-style:translate-x-[-10px] data-[side=inline-start]:data-ending-style:translate-x-[-10px] data-[side=inline-start]:data-ending-style:opacity-0`,\r\n // side=inline-end\r\n `data-[side=inline-end]:data-starting-style:opacity-0 data-[side=inline-end]:data-starting-style:translate-x-[10px] data-[side=inline-end]:data-ending-style:translate-x-[10px] data-[side=inline-end]:data-ending-style:opacity-0`,\r\n ],\r\n slideInside: [\r\n `[transition-property:translate,opacity] [will-change:translate,opacity]`,\r\n // side=bottom\r\n `data-[side=bottom]:data-starting-style:opacity-0 data-[side=bottom]:data-starting-style:translate-y-[-10px] data-[side=bottom]:data-ending-style:translate-y-[-10px] data-[side=bottom]:data-ending-style:opacity-0`,\r\n // side=top\r\n `data-[side=top]:data-starting-style:opacity-0 data-[side=top]:data-starting-style:translate-y-[10px] data-[side=top]:data-ending-style:translate-y-[10px] data-[side=top]:data-ending-style:opacity-0`,\r\n // side=left\r\n `data-[side=left]:data-starting-style:opacity-0 data-[side=left]:data-starting-style:translate-x-[10px] data-[side=left]:data-ending-style:translate-x-[10px] data-[side=left]:data-ending-style:opacity-0`,\r\n // side=right\r\n `data-[side=right]:data-starting-style:opacity-0 data-[side=right]:data-starting-style:translate-x-[-10px] data-[side=right]:data-ending-style:translate-x-[-10px] data-[side=right]:data-ending-style:opacity-0`,\r\n // side=inline-start\r\n `data-[side=inline-start]:data-starting-style:opacity-0 data-[side=inline-start]:data-starting-style:translate-x-[10px] data-[side=inline-start]:data-ending-style:translate-x-[10px] data-[side=inline-start]:data-ending-style:opacity-0`,\r\n // side=inline-end\r\n `data-[side=inline-end]:data-starting-style:opacity-0 data-[side=inline-end]:data-starting-style:translate-x-[-10px] data-[side=inline-end]:data-ending-style:translate-x-[-10px] data-[side=inline-end]:data-ending-style:opacity-0`,\r\n ],\r\n wipe: [\r\n `[transition-property:clip-path] [will-change:clip-path]`,\r\n `[clip-path:inset(0_0_0_0_round_12px)] [-webkit-clip-path:inset(0_0_0_0_round_12px)]`,\r\n // side=bottom\r\n `data-[side=bottom]:data-starting-style:[clip-path:inset(0_0_100%_0_round_12px)] data-[side=bottom]:data-ending-style:[clip-path:inset(0_0_100%_0_round_12px)]`,\r\n // side=top\r\n `data-[side=top]:data-starting-style:[clip-path:inset(100%_0_0_0_round_12px)] data-[side=top]:data-ending-style:[clip-path:inset(100%_0_0_0_round_12px)]`,\r\n // side=left\r\n `data-[side=left]:data-starting-style:[clip-path:inset(0_0_0_100%_round_12px)] data-[side=left]:data-ending-style:[clip-path:inset(0_0_0_100%_round_12px)]`,\r\n // side=right\r\n `data-[side=right]:data-starting-style:[clip-path:inset(0_100%_0_0_round_12px)] data-[side=right]:data-ending-style:[clip-path:inset(0_100%_0_0_round_12px)]`,\r\n // side=inline-start\r\n `data-[side=inline-start]:data-starting-style:[clip-path:inset(0_0_0_100%_round_12px)] data-[side=inline-start]:data-ending-style:[clip-path:inset(0_0_0_100%_round_12px)]`,\r\n // side=inline-end\r\n `data-[side=inline-end]:data-starting-style:[clip-path:inset(0_100%_0_0_round_12px)] data-[side=inline-end]:data-ending-style:[clip-path:inset(0_100%_0_0_round_12px)]`,\r\n ],\r\n wipeScale: [\r\n `[transition-property:clip-path,scale] [will-change:clip-path,scale]`,\r\n `[clip-path:inset(0_0_0_0_round_12px)] [-webkit-clip-path:inset(0_0_0_0_round_12px)]`,\r\n `data-starting-style:scale-80 data-ending-style:scale-80`,\r\n // side=bottom\r\n `data-[side=bottom]:data-starting-style:[clip-path:inset(0_0_100%_0_round_12px)] data-[side=bottom]:data-ending-style:[clip-path:inset(0_0_100%_0_round_12px)]`,\r\n // side=top\r\n `data-[side=top]:data-starting-style:[clip-path:inset(100%_0_0_0_round_12px)] data-[side=top]:data-ending-style:[clip-path:inset(100%_0_0_0_round_12px)]`,\r\n // side=left\r\n `data-[side=left]:data-starting-style:[clip-path:inset(0_0_0_100%_round_12px)] data-[side=left]:data-ending-style:[clip-path:inset(0_0_0_100%_round_12px)]`,\r\n // side=right\r\n `data-[side=right]:data-starting-style:[clip-path:inset(0_100%_0_0_round_12px)] data-[side=right]:data-ending-style:[clip-path:inset(0_100%_0_0_round_12px)]`,\r\n // side=inline-start\r\n `data-[side=inline-start]:data-starting-style:[clip-path:inset(0_0_0_100%_round_12px)] data-[side=inline-start]:data-ending-style:[clip-path:inset(0_0_0_100%_round_12px)]`,\r\n // side=inline-end\r\n `data-[side=inline-end]:data-starting-style:[clip-path:inset(0_100%_0_0_round_12px)] data-[side=inline-end]:data-ending-style:[clip-path:inset(0_100%_0_0_round_12px)]`,\r\n ],\r\n motion: [\r\n `[transition-property:translate,scale,opacity,rotateX,rotateY,transform] [will-change:translate,scale,opacity,rotateX,rotateY,transform]`,\r\n `[transform:perspective(1000px)]`,\r\n // side=bottom\r\n `data-[side=bottom]:data-starting-style:translate-y-[7px] data-[side=bottom]:data-starting-style:opacity-0 data-[side=bottom]:data-starting-style:scale-[0.26] data-[side=bottom]:data-starting-style:rotate-x-[70deg] data-[side=bottom]:data-ending-style:translate-y-[7px] data-[side=bottom]:data-ending-style:opacity-0 data-[side=bottom]:data-ending-style:scale-[0.26] data-[side=bottom]:data-ending-style:rotate-x-[70deg]`,\r\n // side=top\r\n `data-[side=top]:data-starting-style:translate-y-[7px] data-[side=top]:data-starting-style:opacity-0 data-[side=top]:data-starting-style:scale-[0.26] data-[side=top]:data-starting-style:rotate-x-[70deg] data-[side=top]:data-ending-style:translate-y-[7px] data-[side=top]:data-ending-style:opacity-0 data-[side=top]:data-ending-style:scale-[0.26] data-[side=top]:data-ending-style:rotate-x-[70deg]`,\r\n // side=left\r\n `data-[side=left]:data-starting-style:translate-x-[-7px] data-[side=left]:data-starting-style:opacity-0 data-[side=left]:data-starting-style:scale-[0.26] data-[side=left]:data-starting-style:rotate-y-[-40deg] data-[side=left]:data-ending-style:translate-x-[-7px] data-[side=left]:data-ending-style:opacity-0 data-[side=left]:data-ending-style:scale-[0.26] data-[side=left]:data-ending-style:rotate-y-[-40deg]`,\r\n // side=right\r\n `data-[side=right]:data-starting-style:translate-x-[7px] data-[side=right]:data-starting-style:opacity-0 data-[side=right]:data-starting-style:scale-[0.26] data-[side=right]:data-starting-style:rotate-y-[40deg] data-[side=right]:data-ending-style:translate-x-[7px] data-[side=right]:data-ending-style:opacity-0 data-[side=right]:data-ending-style:scale-[0.26] data-[side=right]:data-ending-style:rotate-y-[40deg]`,\r\n // side=inline-start\r\n `data-[side=inline-start]:data-starting-style:translate-x-[-7px] data-[side=inline-start]:data-starting-style:opacity-0 data-[side=inline-start]:data-starting-style:scale-[0.26] data-[side=inline-start]:data-starting-style:rotate-y-[-40deg] data-[side=inline-start]:data-ending-style:translate-x-[-7px] data-[side=inline-start]:data-ending-style:opacity-0 data-[side=inline-start]:data-ending-style:scale-[0.26] data-[side=inline-start]:data-ending-style:rotate-y-[-40deg]`,\r\n // side=inline-end\r\n `data-[side=inline-end]:data-starting-style:translate-x-[7px] data-[side=inline-end]:data-starting-style:opacity-0 data-[side=inline-end]:data-starting-style:scale-[0.26] data-[side=inline-end]:data-starting-style:rotate-y-[40deg] data-[side=inline-end]:data-ending-style:translate-x-[7px] data-[side=inline-end]:data-ending-style:opacity-0 data-[side=inline-end]:data-ending-style:scale-[0.26] data-[side=inline-end]:data-ending-style:rotate-y-[40deg]`,\r\n ],\r\n motionBlur: [\r\n `[transition-property:translate,scale,opacity,rotateX,rotateY,transform,filter] [will-change:translate,scale,opacity,rotateX,rotateY,transform,filter]`,\r\n `[transform:perspective(1000px)]`,\r\n `data-starting-style:blur-[9px] data-ending-style:blur-[9px]`,\r\n // side=bottom\r\n `data-[side=bottom]:data-starting-style:translate-y-[7px] data-[side=bottom]:data-starting-style:opacity-0 data-[side=bottom]:data-starting-style:scale-[0.26] data-[side=bottom]:data-starting-style:rotate-x-[70deg] data-[side=bottom]:data-ending-style:translate-y-[7px] data-[side=bottom]:data-ending-style:opacity-0 data-[side=bottom]:data-ending-style:scale-[0.26] data-[side=bottom]:data-ending-style:rotate-x-[70deg]`,\r\n // side=top\r\n `data-[side=top]:data-starting-style:translate-y-[7px] data-[side=top]:data-starting-style:opacity-0 data-[side=top]:data-starting-style:scale-[0.26] data-[side=top]:data-starting-style:rotate-x-[70deg] data-[side=top]:data-ending-style:translate-y-[7px] data-[side=top]:data-ending-style:opacity-0 data-[side=top]:data-ending-style:scale-[0.26] data-[side=top]:data-ending-style:rotate-x-[70deg]`,\r\n // side=left\r\n `data-[side=left]:data-starting-style:translate-x-[-7px] data-[side=left]:data-starting-style:opacity-0 data-[side=left]:data-starting-style:scale-[0.26] data-[side=left]:data-starting-style:rotate-y-[-40deg] data-[side=left]:data-ending-style:translate-x-[-7px] data-[side=left]:data-ending-style:opacity-0 data-[side=left]:data-ending-style:scale-[0.26] data-[side=left]:data-ending-style:rotate-y-[-40deg]`,\r\n // side=right\r\n `data-[side=right]:data-starting-style:translate-x-[7px] data-[side=right]:data-starting-style:opacity-0 data-[side=right]:data-starting-style:scale-[0.26] data-[side=right]:data-starting-style:rotate-y-[40deg] data-[side=right]:data-ending-style:translate-x-[7px] data-[side=right]:data-ending-style:opacity-0 data-[side=right]:data-ending-style:scale-[0.26] data-[side=right]:data-ending-style:rotate-y-[40deg]`,\r\n // side=inline-start\r\n `data-[side=inline-start]:data-starting-style:translate-x-[-7px] data-[side=inline-start]:data-starting-style:opacity-0 data-[side=inline-start]:data-starting-style:scale-[0.26] data-[side=inline-start]:data-starting-style:rotate-y-[-40deg] data-[side=inline-start]:data-ending-style:translate-x-[-7px] data-[side=inline-start]:data-ending-style:opacity-0 data-[side=inline-start]:data-ending-style:scale-[0.26] data-[side=inline-start]:data-ending-style:rotate-y-[-40deg]`,\r\n // side=inline-end\r\n `data-[side=inline-end]:data-starting-style:translate-x-[7px] data-[side=inline-end]:data-starting-style:opacity-0 data-[side=inline-end]:data-starting-style:scale-[0.26] data-[side=inline-end]:data-starting-style:rotate-y-[40deg] data-[side=inline-end]:data-ending-style:translate-x-[7px] data-[side=inline-end]:data-ending-style:opacity-0 data-[side=inline-end]:data-ending-style:scale-[0.26] data-[side=inline-end]:data-ending-style:rotate-y-[40deg]`,\r\n ],\r\n};\r\n\r\nconst cssTransitionPresets = {\r\n inExpo: `duration-[0.35s] ease-[cubic-bezier(0.95,0.05,0.795,0.035)]`,\r\n outExpo: `duration-[0.35s] ease-[cubic-bezier(0.19,1,0.22,1)]`,\r\n inOutExpo: `duration-[0.35s] ease-[cubic-bezier(1,0,0,1)]`,\r\n anticipate: `duration-[0.35s] ease-[cubic-bezier(1,-0.4,0.35,0.95)]`,\r\n quickOut: `duration-[0.35s] ease-out`,\r\n overshootOut: `duration-[0.35s] ease-[cubic-bezier(0.175,0.885,0.32,1.275)]`,\r\n swiftOut: `duration-[0.35s] ease-[cubic-bezier(0.175,0.885,0.32,1.1)]`,\r\n snappyOut: `duration-[0.35s] ease-[cubic-bezier(0.19,1,0.22,1)]`,\r\n in: `duration-[0.35s] ease-[cubic-bezier(0.42,0,1,1)]`,\r\n out: `duration-[0.35s] ease-[cubic-bezier(0,0,0.58,1)]`,\r\n inOut: `duration-[0.25s] ease-[cubic-bezier(0.42,0,0.58,1)]`,\r\n outIn: `duration-[0.35s] ease-[cubic-bezier(0.1,0.7,0.9,0.5)]`,\r\n inQuad: `duration-[0.35s] ease-[cubic-bezier(0.55,0.085,0.68,0.53)]`,\r\n outQuad: `duration-[0.25s] ease-[cubic-bezier(0.25,0.46,0.45,0.94)]`,\r\n inOutQuad: `duration-[0.32s] ease-[cubic-bezier(0.455,0.03,0.515,0.955)]`,\r\n inCubic: `duration-[0.35s] ease-[cubic-bezier(0.55,0.055,0.675,0.19)]`,\r\n outCubic: `duration-[0.35s] ease-[cubic-bezier(0.215,0.61,0.355,1)]`,\r\n inOutCubic: `duration-[0.35s] ease-[cubic-bezier(0.645,0.045,0.355,1)]`,\r\n inQuart: `duration-[0.35s] ease-[cubic-bezier(0.895,0.03,0.685,0.22)]`,\r\n outQuart: `duration-[0.35s] ease-[cubic-bezier(0.165,0.84,0.44,1)]`,\r\n inOutQuart: `duration-[0.35s] ease-[cubic-bezier(0.77,0,0.175,1)]`,\r\n inQuint: `duration-[0.35s] ease-[cubic-bezier(0.755,0.05,0.855,0.06)]`,\r\n outQuint: `duration-[0.35s] ease-[cubic-bezier(0.23,1,0.32,1)]`,\r\n inOutQuint: `duration-[0.35s] ease-[cubic-bezier(0.86,0,0.07,1)]`,\r\n inCirc: `duration-[0.35s] ease-[cubic-bezier(0.6,0.04,0.98,0.335)]`,\r\n outCirc: `duration-[0.35s] ease-[cubic-bezier(0.075,0.82,0.165,1)]`,\r\n inOutCirc: `duration-[0.35s] ease-[cubic-bezier(0.785,0.135,0.15,0.86)]`,\r\n inOutBase: `duration-[0.35s] ease-[cubic-bezier(0.25,0.1,0.25,1)]`,\r\n};\r\n\r\ntype CSSAnimationPresets = keyof typeof cssAnimationPresets;\r\ntype CSSTransitionPresets = keyof typeof cssTransitionPresets;\r\n\r\ntype Backdrop = \"opaque\" | \"blur\" | \"transparent\";\r\n\r\ninterface MenuContextType {\r\n backdrop?: Backdrop;\r\n}\r\n\r\nconst MenuContext = createContext(undefined);\r\n\r\nfunction useMenu() {\r\n const context = useContext(MenuContext);\r\n if (!context) {\r\n throw new Error(\"useMenu must be used within a MenuProvider\");\r\n }\r\n return context;\r\n}\r\n\r\ninterface MenuProps extends MenuPrimitive.Root.Props {\r\n backdrop?: Backdrop;\r\n}\r\n\r\nfunction Menu({ backdrop = \"transparent\", ...props }: MenuProps) {\r\n return (\r\n \r\n \r\n \r\n );\r\n}\r\n\r\ninterface MenuTriggerProps extends MenuPrimitive.Trigger.Props {}\r\n\r\nfunction MenuTrigger({ ...props }: MenuTriggerProps) {\r\n return ;\r\n}\r\n\r\ninterface MenuPortalProps extends MenuPrimitive.Portal.Props {}\r\n\r\nfunction MenuPortal(props: MenuPortalProps) {\r\n return ;\r\n}\r\n\r\ninterface MenuBackdropProps extends MenuPrimitive.Backdrop.Props {}\r\n\r\nfunction MenuBackdrop({ className, ...props }: MenuBackdropProps) {\r\n const { backdrop = \"transparent\" } = useMenu();\r\n\r\n return (\r\n \r\n );\r\n}\r\n\r\ninterface MenuPositionerProps extends MenuPrimitive.Positioner.Props {}\r\n\r\nfunction MenuPositioner({\r\n sideOffset = 4,\r\n side = \"bottom\",\r\n className,\r\n ...rest\r\n}: MenuPositionerProps) {\r\n return (\r\n \r\n \r\n \r\n \r\n );\r\n}\r\n\r\ninterface MenuArrowProps extends MenuPrimitive.Arrow.Props {}\r\n\r\nfunction MenuArrow({ className, ...rest }: MenuArrowProps) {\r\n return (\r\n \r\n );\r\n}\r\n\r\nfunction ArrowSvg(props: React.ComponentProps<\"svg\">) {\r\n return (\r\n \r\n \r\n \r\n \r\n );\r\n}\r\n\r\ninterface MenuPopupProps\r\n extends MenuPrimitive.Popup.Props,\r\n Pick {\r\n animationPreset?: CSSAnimationPresets;\r\n transitionPreset?: CSSTransitionPresets;\r\n reduceMotion?: boolean;\r\n showArrow?: boolean;\r\n}\r\n\r\nfunction MenuPopup({\r\n className,\r\n animationPreset = \"scale\",\r\n transitionPreset = \"snappyOut\",\r\n reduceMotion = false,\r\n showArrow = false,\r\n side = \"bottom\",\r\n sideOffset = 4,\r\n align = \"center\",\r\n alignOffset = 0,\r\n children,\r\n ...rest\r\n}: MenuPopupProps) {\r\n const cssAnimationConfig = useMemo(() => {\r\n if (reduceMotion) return \"none\";\r\n\r\n if (animationPreset) {\r\n return cssAnimationPresets[animationPreset];\r\n }\r\n\r\n return cssAnimationPresets.scale;\r\n }, [animationPreset, reduceMotion, side]);\r\n\r\n const cssTransitionConfig = useMemo(() => {\r\n if (reduceMotion) return \"none\";\r\n\r\n if (transitionPreset) {\r\n return cssTransitionPresets[transitionPreset];\r\n }\r\n\r\n return cssTransitionPresets.snappyOut;\r\n }, [transitionPreset, reduceMotion, side]);\r\n\r\n return (\r\n \r\n \r\n {showArrow && (\r\n \r\n \r\n \r\n )}\r\n {children}\r\n \r\n }\r\n {...rest}\r\n />\r\n \r\n );\r\n}\r\n\r\ninterface MenuGroupProps extends MenuPrimitive.Group.Props {}\r\n\r\nfunction MenuGroup(props: MenuGroupProps) {\r\n return ;\r\n}\r\n\r\ninterface MenuGroupLabelProps extends MenuPrimitive.GroupLabel.Props {}\r\n\r\nfunction MenuGroupLabel({ className, ...rest }: MenuGroupLabelProps) {\r\n return (\r\n \r\n );\r\n}\r\n\r\nfunction MenuLabel({ className, ...props }: React.ComponentProps<\"span\">) {\r\n return (\r\n \r\n );\r\n}\r\n\r\ninterface MenuItemProps extends MenuPrimitive.Item.Props {}\r\n\r\nfunction MenuItem({ className, ...rest }: MenuItemProps) {\r\n return (\r\n \r\n );\r\n}\r\n\r\nfunction MenuSeparator({ className, ...props }: MenuPrimitive.Separator.Props) {\r\n return (\r\n \r\n );\r\n}\r\n\r\ninterface MenuCheckboxItemProps extends MenuPrimitive.CheckboxItem.Props {}\r\n\r\nfunction MenuCheckboxItem({\r\n className,\r\n children,\r\n ...rest\r\n}: MenuCheckboxItemProps) {\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n {children}\r\n \r\n );\r\n}\r\n\r\ninterface MenuRadioGroupContextType {\r\n activeIcon?: React.ReactNode;\r\n}\r\n\r\nconst MenuRadioGroupContext = createContext({});\r\n\r\ninterface MenuRadioGroupProps extends MenuPrimitive.RadioGroup.Props {\r\n activeIcon?: React.ReactNode;\r\n}\r\n\r\nfunction MenuRadioGroup({ activeIcon, ...props }: MenuRadioGroupProps) {\r\n return (\r\n \r\n \r\n \r\n );\r\n}\r\n\r\nfunction MenuRadioItem({\r\n className,\r\n children,\r\n value,\r\n ...props\r\n}: MenuPrimitive.RadioItem.Props) {\r\n const { activeIcon } = useContext(MenuRadioGroupContext);\r\n\r\n return (\r\n \r\n {children}\r\n \r\n \r\n {activeIcon ?? }\r\n \r\n \r\n \r\n );\r\n}\r\n\r\nfunction MenuShortcut({ className, ...props }: React.ComponentProps<\"span\">) {\r\n return (\r\n \r\n );\r\n}\r\n\r\ninterface MenuSubProps extends MenuPrimitive.SubmenuRoot.Props {}\r\n\r\nfunction MenuSub(props: MenuSubProps) {\r\n return ;\r\n}\r\n\r\ninterface MenuSubTriggerProps extends MenuPrimitive.SubmenuTrigger.Props {}\r\n\r\nfunction MenuSubTrigger({ className, children, ...rest }: MenuSubTriggerProps) {\r\n return (\r\n \r\n {children}\r\n \r\n \r\n );\r\n}\r\n\r\ninterface MenuSubmenuPortalProps extends MenuPrimitive.Portal.Props {}\r\n\r\nfunction MenuSubmenuPortal(props: MenuSubmenuPortalProps) {\r\n return ;\r\n}\r\n\r\ninterface MenuSubPositionerProps extends MenuPrimitive.Positioner.Props {}\r\n\r\nfunction MenuSubPositioner({\r\n sideOffset = 4,\r\n side = \"right\",\r\n className,\r\n ...rest\r\n}: MenuSubPositionerProps) {\r\n return (\r\n \r\n \r\n \r\n );\r\n}\r\n\r\ninterface MenuSubPopupProps\r\n extends MenuPrimitive.Popup.Props,\r\n Pick<\r\n MenuPositionerProps,\r\n \"side\" | \"sideOffset\" | \"align\" | \"alignOffset\"\r\n > {}\r\n\r\nfunction MenuSubPopup({\r\n className,\r\n children,\r\n side = \"right\",\r\n sideOffset = 4,\r\n align = \"start\",\r\n alignOffset = 0,\r\n ...rest\r\n}: MenuSubPopupProps) {\r\n return (\r\n \r\n \r\n {children}\r\n \r\n }\r\n {...rest}\r\n />\r\n \r\n );\r\n}\r\n\r\nexport {\r\n Menu,\r\n MenuTrigger,\r\n MenuPopup,\r\n MenuGroup,\r\n MenuGroupLabel,\r\n MenuItem,\r\n MenuSeparator,\r\n MenuCheckboxItem,\r\n MenuRadioGroup,\r\n MenuRadioItem,\r\n MenuSub,\r\n MenuSubTrigger,\r\n MenuSubPopup,\r\n MenuShortcut,\r\n MenuLabel,\r\n};\r\n", "type": "registry:ui", "target": "components/ui/menu.tsx" } ] }