import { forwardRef, useId } from 'react'; import { Pressable, View, type GestureResponderEvent } from 'react-native'; import { useControllableState } from '../../helpers/internal/hooks'; import { createContext } from '../../helpers/internal/utils'; import * as Slot from '../../primitives/slot'; import type { ContentProps, ContentRef, ISubMenuContext, RootProps, RootRef, TriggerProps, TriggerRef, } from './sub-menu.types'; const [SubMenuProvider, useSubMenuContext] = createContext({ strict: false, }); // -------------------------------------------------- const Root = forwardRef( ( { asChild, isOpen: isOpenProp, isDefaultOpen, onOpenChange: onOpenChangeProp, isDisabled = false, ...viewProps }, ref ) => { const [isOpen = false, onOpenChange] = useControllableState({ prop: isOpenProp, defaultProp: isDefaultOpen, onChange: onOpenChangeProp, }); const nativeID = useId(); const Component = asChild ? Slot.View : View; return ( ); } ); // -------------------------------------------------- const Trigger = forwardRef( ( { asChild, textValue, onPress: onPressProp, isDisabled: isDisabledProp = false, ...props }, ref ) => { const { nativeID, isOpen, onOpenChange, isDisabled: isDisabledRoot, } = useSubMenuContext(); const isDisabled = isDisabledProp || isDisabledRoot; function onPress(ev: GestureResponderEvent) { if (isDisabled) return; onOpenChange(!isOpen); onPressProp?.(ev); } const Component = asChild ? Slot.Pressable : Pressable; return ( ); } ); // -------------------------------------------------- const Content = forwardRef( ({ asChild = false, forceMount, ...props }, ref) => { const { isOpen, nativeID } = useSubMenuContext(); if (!forceMount) { if (!isOpen) { return null; } } const Component = asChild ? Slot.Pressable : Pressable; return ( ); } ); // -------------------------------------------------- Root.displayName = 'HeroUINative.SubMenu.Root'; Trigger.displayName = 'HeroUINative.SubMenu.Trigger'; Content.displayName = 'HeroUINative.SubMenu.Content'; export { Content, Root, Trigger, useSubMenuContext };