/** * Copyright (c) Paymium. * * This source code is licensed under the MIT license found in the * LICENSE file in the root of this projects source tree. */ import { GetProps, useUncontrolled, withStaticProperties } from '@crossed/core'; import { useMemo, type ComponentType, useId } from 'react'; import { createDropdownMain } from './Dropdown'; import { createDropdownTrigger } from './DropdownTrigger'; import { createDropdownContent } from './DropdownContent'; import { createDropdownPortal } from './DropdownPortal'; import { Provider } from './context'; import { createDropdownItem } from './DropdownItem'; import { createDropdownDivider } from './DropdownDivider'; import { createDropdownLabel } from './DropdownLabel'; export { Provider as ProviderDropdown, useContext as useDropdownContext, } from './context'; type Arg> = { context?: Context; }; export const createDropdown = < DropdownProps extends Record, TriggerProps extends Record, ContentProps extends Record, PortalProps extends Record, ItemProps extends Record, DividerProps extends Record, LabelProps extends Record, C extends Record, >( components: { Root: ComponentType; Trigger: ComponentType; Content: ComponentType; Portal: ComponentType; Item: ComponentType; Divider: ComponentType; Label: ComponentType; }, { context }: Arg = {} ) => { const { Root, Trigger, Content, Portal, Item, Divider, Label } = components; const Dropdown = createDropdownMain(Root); const DropdownTrigger = createDropdownTrigger(Trigger); const DropdownContent = createDropdownContent(Content); const DropdownPortal = createDropdownPortal(Portal); const DropdownItem = createDropdownItem(Item); const DropdownDivider = createDropdownDivider(Divider); const DropdownLabel = createDropdownLabel(Label); Dropdown.displayName = 'Dropdown'; DropdownTrigger.displayName = 'Dropdown.Trigger'; DropdownContent.displayName = 'Dropdown.Content'; DropdownPortal.displayName = 'Dropdown.Portal'; DropdownItem.displayName = 'Dropdown.Item'; DropdownDivider.displayName = 'Dropdown.Divider'; DropdownLabel.displayName = 'Dropdown.Label'; return withStaticProperties( ( props: GetProps & { value?: boolean; defaultValue?: boolean; onChangeOpen?: (_p: boolean) => void; } ) => { const id = useId(); const { value, defaultValue = false, onChangeOpen, ...otherProps } = props; const [open, setOpen] = useUncontrolled({ value, defaultValue, onChange: onChangeOpen, }); const contextProps = useMemo(() => { return Object.entries(context || {}).reduce( (acc, [key]) => { if ((props as any)[key]) { (acc as any)[key] = (props as any)[key]; } return acc; }, context || ({} as C) ); }, [props]); return ( ); }, { Trigger: DropdownTrigger, Content: DropdownContent, Portal: DropdownPortal, Item: DropdownItem, Divider: DropdownDivider, Label: DropdownLabel, } ); };