import React from 'react' import {Pressable, StyleProp, View, ViewStyle} from 'react-native' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import flattenReactChildren from 'react-keyed-flatten-children' import {isNative} from 'platform/detection' import {atoms as a, useTheme} from '#/alf' import {Button, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' import {useInteractionState} from '#/components/hooks/useInteractionState' import {Context} from '#/components/Menu/context' import { ContextType, GroupProps, ItemIconProps, ItemProps, ItemTextProps, TriggerProps, } from '#/components/Menu/types' import {Text} from '#/components/Typography' export { type DialogControlProps as MenuControlProps, useDialogControl as useMenuControl, } from '#/components/Dialog' export function useMemoControlContext() { return React.useContext(Context) } export function Root({ children, control, }: React.PropsWithChildren<{ control?: Dialog.DialogOuterProps['control'] }>) { const defaultControl = Dialog.useDialogControl() const context = React.useMemo( () => ({ control: control || defaultControl, }), [control, defaultControl], ) return {children} } export function Trigger({children, label}: TriggerProps) { const {control} = React.useContext(Context) const {state: focused, onIn: onFocus, onOut: onBlur} = useInteractionState() const { state: pressed, onIn: onPressIn, onOut: onPressOut, } = useInteractionState() return children({ isNative: true, control, state: { hovered: false, focused, pressed, }, props: { onPress: control.open, onFocus, onBlur, onPressIn, onPressOut, accessibilityLabel: label, }, }) } export function Outer({ children, showCancel, }: React.PropsWithChildren<{ showCancel?: boolean style?: StyleProp }>) { const context = React.useContext(Context) return ( {/* Re-wrap with context since Dialogs are portal-ed to root */} {children} {isNative && showCancel && } ) } export function Item({children, label, style, onPress, ...rest}: ItemProps) { const t = useTheme() const {control} = React.useContext(Context) const {state: focused, onIn: onFocus, onOut: onBlur} = useInteractionState() const { state: pressed, onIn: onPressIn, onOut: onPressOut, } = useInteractionState() return ( { onPress(e) if (!e.defaultPrevented) { control?.close() } }} onFocus={onFocus} onBlur={onBlur} onPressIn={onPressIn} onPressOut={onPressOut} style={[ a.flex_row, a.align_center, a.gap_sm, a.px_md, a.rounded_md, a.border, t.atoms.bg_contrast_25, t.atoms.border_contrast_low, {minHeight: 44, paddingVertical: 10}, style, (focused || pressed) && [t.atoms.bg_contrast_50], ]}> {children} ) } export function ItemText({children, style}: ItemTextProps) { const t = useTheme() return ( {children} ) } export function ItemIcon({icon: Comp}: ItemIconProps) { const t = useTheme() return } export function Group({children, style}: GroupProps) { const t = useTheme() return ( {flattenReactChildren(children).map((child, i) => { return React.isValidElement(child) && child.type === Item ? ( {i > 0 ? ( ) : null} {React.cloneElement(child, { // @ts-ignore style: { borderRadius: 0, borderWidth: 0, }, })} ) : null })} ) } function Cancel() { const {_} = useLingui() const {control} = React.useContext(Context) return ( ) } export function Divider() { return null }