/** * Copyright 2025 LY Corporation * * LY Corporation licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at: * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ 'use client'; import * as React from 'react'; import type { DropdownMenuCheckboxItemProps } from '@radix-ui/react-dropdown-menu'; import * as DropdownPrimitive from '@radix-ui/react-dropdown-menu'; import { Slottable } from '@radix-ui/react-slot'; import type { TriggerType } from '../lib/types'; import { cn } from '../lib/utils'; import { Button } from './button'; import { Icon } from './icon'; import { ScrollArea, ScrollBar } from './scroll-area'; const DropdownContext = React.createContext<{ trigger: TriggerType; isHover: boolean; setTrigger: React.Dispatch>; setIsHover: React.Dispatch>; }>({ trigger: 'click', setTrigger: () => 'click', isHover: false, setIsHover: () => false, }); const Dropdown = ({ open = false, // eslint-disable-next-line @typescript-eslint/unbound-method onOpenChange, ...props }: React.ComponentPropsWithoutRef) => { const [trigger, setTrigger] = React.useState('click'); const [isHover, setIsHover] = React.useState(false); return ( { setIsHover(open); onOpenChange?.(open); }} /> ); }; const DropdownTrigger = React.forwardRef< React.ComponentRef, DropdownPrimitive.DropdownMenuTriggerProps & React.ComponentPropsWithoutRef & { trigger?: TriggerType; } >( ( { variant = 'outline', trigger, onMouseEnter, onMouseLeave, className, children, ...props }, ref, ) => { const { setTrigger, setIsHover } = React.useContext(DropdownContext); const handleMouseEnter = (e: React.MouseEvent) => { if (trigger === 'hover') { setIsHover(true); } onMouseEnter?.(e); }; const handleMouseLeave = (e: React.MouseEvent) => { if (trigger === 'hover') { setIsHover(false); } onMouseLeave?.(e); }; React.useEffect(() => { if (trigger) { setTrigger(trigger); } }, []); if (props.asChild) { return ( {children} ); } return ( ); }, ); DropdownTrigger.displayName = DropdownPrimitive.DropdownMenuTrigger.displayName; const DropdownGroup = DropdownPrimitive.Group; const DropdownPortal = DropdownPrimitive.Portal; const DropdownSub = DropdownPrimitive.Sub; const DropdownRadioGroup = DropdownPrimitive.RadioGroup; const DropdownSubTrigger = React.forwardRef< React.ComponentRef, React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => { return ( {children} ); }); DropdownSubTrigger.displayName = DropdownPrimitive.SubTrigger.displayName; const DropdownCaption = React.forwardRef< React.ComponentRef<'span'>, React.ComponentPropsWithoutRef<'span'> >(({ className, ...props }, ref) => ( )); DropdownCaption.displayName = 'DropdownCaption'; const DropdownSubContent = React.forwardRef< React.ComponentRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); DropdownSubContent.displayName = DropdownPrimitive.SubContent.displayName; const DropdownContent = React.forwardRef< React.ComponentRef, React.ComponentPropsWithoutRef & { maxHeight?: string; } >( ( { children, className, sideOffset = 4, maxHeight, onMouseEnter, onMouseLeave, ...props }, ref, ) => { const { trigger, setIsHover } = React.useContext(DropdownContext); const handleMouseEnter = (e: React.MouseEvent) => { if (trigger === 'hover') { setIsHover(true); } onMouseEnter?.(e); }; const handleMouseLeave = (e: React.MouseEvent) => { if (trigger === 'hover') { setIsHover(false); } onMouseLeave?.(e); }; return ( {children} ); }, ); DropdownContent.displayName = DropdownPrimitive.Content.displayName; const DropdownItem = React.forwardRef< React.ComponentRef, React.ComponentPropsWithoutRef >(({ children, className, ...props }, ref) => ( {children} )); DropdownItem.displayName = DropdownPrimitive.Item.displayName; const DropdownCheckboxItem = React.forwardRef< React.ComponentRef, React.ComponentPropsWithoutRef >(({ className, children, checked, ...props }, ref) => ( {children} )); DropdownCheckboxItem.displayName = DropdownPrimitive.CheckboxItem.displayName; const DropdownRadioItem = React.forwardRef< React.ComponentRef, React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( {children} )); DropdownRadioItem.displayName = DropdownPrimitive.RadioItem.displayName; const DropdownLabel = React.forwardRef< React.ComponentRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); DropdownLabel.displayName = DropdownPrimitive.Label.displayName; const DropdownSeparator = React.forwardRef< React.ComponentRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); DropdownSeparator.displayName = DropdownPrimitive.Separator.displayName; export { Dropdown, DropdownTrigger, DropdownContent, DropdownCaption, DropdownItem, DropdownCheckboxItem, DropdownRadioItem, DropdownLabel, DropdownSeparator, DropdownGroup, DropdownPortal, DropdownSub, DropdownSubContent, DropdownSubTrigger, DropdownRadioGroup, type DropdownMenuCheckboxItemProps, };