import { type Ref, forwardRef } from 'react'; import styled, { type AnyStyledComponent } from 'styled-components'; import { Root, Trigger, Content, Portal, Item, Separator } from '@radix-ui/react-dropdown-menu'; import { popoverMixins } from '@/styles/popoverMixins'; import { Icon, IconName } from '@/components/Icon'; import { Fragment } from 'react'; export type DropdownMenuItem = { value: T; icon?: React.ReactNode; label: React.ReactNode; onSelect?: () => void; separator?: boolean; highlightColor?: 'accent' | 'positive' | 'negative'; }; type StyleProps = { align?: 'center' | 'start' | 'end'; side?: 'top' | 'bottom'; sideOffset?: number; className?: string; }; type ElementProps = { children: React.ReactNode; items: DropdownMenuItem[]; slotTopContent?: React.ReactNode; }; type DropdownMenuProps = StyleProps & ElementProps; export const DropdownMenu = forwardRef( ( { align = 'center', children, className, items, slotTopContent, side = 'bottom', sideOffset = 8, }: DropdownMenuProps, ref: Ref ) => { return ( {children} {slotTopContent} {items.map((item: DropdownMenuItem) => ( {item.icon} {item.label} {item.separator && } ))} ); } ); const Styled: Record = {}; Styled.Separator = styled(Separator)` border-bottom: solid var(--border-width) var(--color-border); margin: 0.25rem 1rem; `; Styled.Item = styled(Item)<{ $highlightColor: 'accent' | 'positive' | 'negative' }>` ${popoverMixins.item} --item-font-size: var(--dropdownMenu-item-font-size); ${({ $highlightColor }) => ({ ['accent']: ` --item-highlighted-textColor: var(--color-accent); `, ['positive']: ` --item-highlighted-textColor: var(--color-positive); `, ['negative']: ` --item-highlighted-textColor: var(--color-negative); `, }[$highlightColor])} justify-content: start; color: var(--color-text-0); &[data-disabled] { cursor: default; } `; Styled.Trigger = styled(Trigger)` ${popoverMixins.trigger} ${popoverMixins.backdropOverlay} `; Styled.DropdownIcon = styled.span` display: inline-flex; font-size: 0.375em; transition: transform 0.3s var(--ease-out-expo); align-items: center; ${Styled.Trigger}[data-state='open'] & { transform: scaleY(-1); } `; Styled.Content = styled(Content)` --dropdownMenu-item-font-size: inherit; ${popoverMixins.popover} ${popoverMixins.popoverAnimation} `;