"use client" import * as React from "react" import { Menu02Icon } from "@hugeicons/core-free-icons" import { HugeiconsIcon } from "@hugeicons/react" import { useTheme } from "next-themes" import { useMounted } from "@/hooks/use-mounted" import { type MenuColorValue } from "@/registry/config" import { LockButton } from "@/app/(app)/(create)/components/lock-button" import { Picker, PickerContent, PickerGroup, PickerLabel, PickerRadioGroup, PickerRadioItem, PickerSeparator, PickerTrigger, } from "@/app/(app)/(create)/components/picker" import { usePreviewOverride } from "@/app/(app)/(create)/components/preview-override" import { isTranslucentMenuColor, useDesignSystemSearchParams, } from "@/app/(app)/(create)/lib/search-params" type ColorChoice = "default" | "inverted" type SurfaceChoice = "solid" | "translucent" function getMenuColorValue( color: ColorChoice, translucent: boolean ): MenuColorValue { if (color === "default") { return translucent ? "default-translucent" : "default" } return translucent ? "inverted-translucent" : "inverted" } const MENU_OPTIONS: { value: MenuColorValue; label: string }[] = [ { value: "default", label: "Default / Solid" }, { value: "default-translucent", label: "Default / Translucent" }, { value: "inverted", label: "Inverted / Solid" }, { value: "inverted-translucent", label: "Inverted / Translucent" }, ] export function MenuColorPicker({ isMobile, anchorRef, }: { isMobile: boolean anchorRef: React.RefObject }) { const [params, setParams] = useDesignSystemSearchParams() const { setOverride, clearOverride } = usePreviewOverride() const { resolvedTheme } = useTheme() const mounted = useMounted() const lastSolidMenuAccentRef = React.useRef(params.menuAccent) const isDark = mounted && resolvedTheme === "dark" const currentMenu = MENU_OPTIONS.find( (menu) => menu.value === params.menuColor ) const colorChoice: ColorChoice = params.menuColor === "inverted" || params.menuColor === "inverted-translucent" ? "inverted" : "default" const surfaceChoice: SurfaceChoice = params.menuColor === "default-translucent" || params.menuColor === "inverted-translucent" ? "translucent" : "solid" React.useEffect(() => { if (surfaceChoice === "solid") { lastSolidMenuAccentRef.current = params.menuAccent } }, [params.menuAccent, surfaceChoice]) const setColor = (color: ColorChoice) => { const nextMenuColor = getMenuColorValue( color, surfaceChoice === "translucent" ) setParams({ menuColor: nextMenuColor, ...(isTranslucentMenuColor(nextMenuColor) && { menuAccent: "subtle" }), }) } const setSurface = (choice: SurfaceChoice) => { const isTranslucent = choice === "translucent" const nextMenuColor = getMenuColorValue(colorChoice, isTranslucent) setParams({ menuColor: nextMenuColor, menuAccent: isTranslucent ? "subtle" : lastSolidMenuAccentRef.current, }) } // Hover previews mirror setColor/setSurface, including the menuAccent // coupling, so the previewed state matches what a click would commit. const previewColor = (color: ColorChoice) => { const nextMenuColor = getMenuColorValue( color, surfaceChoice === "translucent" ) setOverride({ menuColor: nextMenuColor, ...(isTranslucentMenuColor(nextMenuColor) && { menuAccent: "subtle" as const, }), }) } const previewSurface = (choice: SurfaceChoice) => { const isTranslucent = choice === "translucent" setOverride({ menuColor: getMenuColorValue(colorChoice, isTranslucent), menuAccent: isTranslucent ? "subtle" : lastSolidMenuAccentRef.current, }) } return (
{ if (!open) { clearOverride() } }} >
Menu
{currentMenu?.label}
Color { setColor(value as ColorChoice) }} onItemPreview={ isMobile ? undefined : (value) => previewColor(value as ColorChoice) } > Default Inverted Appearance { setSurface(value as SurfaceChoice) }} onItemPreview={ isMobile ? undefined : (value) => previewSurface(value as SurfaceChoice) } > Solid Translucent
) }