Bluesky app fork with some witchin' additions 馃挮
at main 136 lines 3.6 kB view raw
1import { 2 type AccessibilityRole, 3 type GestureResponderEvent, 4 type StyleProp, 5 type ViewStyle, 6} from 'react-native' 7import {type SharedValue} from 'react-native-reanimated' 8 9import type * as Dialog from '#/components/Dialog' 10import { 11 type ItemProps as MenuItemProps, 12 type RadixPassThroughTriggerProps, 13} from '#/components/Menu/types' 14 15export type { 16 GroupProps, 17 ItemIconProps, 18 ItemTextProps, 19} from '#/components/Menu/types' 20 21export type AuxiliaryViewProps = { 22 children?: React.ReactNode 23 align?: 'left' | 'right' 24} 25 26export type ItemProps = Omit<MenuItemProps, 'onPress' | 'children'> & { 27 // remove default styles (i.e. for emoji reactions) 28 unstyled?: boolean 29 onPress: (evt?: GestureResponderEvent) => void 30 children?: React.ReactNode | ((hovered: boolean) => React.ReactNode) 31 // absolute position of the parent element. if undefined, assumed to 32 // be in the context menu. use this if using AuxiliaryView 33 position?: Measurement 34} 35 36export type Measurement = { 37 x: number 38 y: number 39 width: number 40 height: number 41} 42 43export type ContextType = { 44 isOpen: boolean 45 measurement: Measurement | null 46 /* Spring animation between 0 and 1 */ 47 animationSV: SharedValue<number> 48 /* Translation in Y axis to ensure everything's onscreen */ 49 translationSV: SharedValue<number> 50 mode: 'full' | 'auxiliary-only' 51 open: (evt: Measurement, mode: 'full' | 'auxiliary-only') => void 52 returnLocationSV: SharedValue<{x: number; y: number} | null> 53 close: () => void 54 registerHoverable: ( 55 id: string, 56 rect: Measurement, 57 onTouchUp: () => void, 58 ) => void 59 hoverablesSV: SharedValue<Record<string, {id: string; rect: Measurement}>> 60 hoveredMenuItem: string | null 61 setHoveredMenuItem: React.Dispatch<React.SetStateAction<string | null>> 62 onTouchUpMenuItem: (id: string) => void 63} 64 65export type MenuContextType = { 66 align: 'left' | 'right' 67} 68 69export type ItemContextType = { 70 disabled: boolean 71} 72 73export type TriggerProps = { 74 children(props: TriggerChildProps): React.ReactNode 75 label: string 76 /** 77 * When activated, this is the accessibility label for the entire thing that has been triggered. 78 * For example, if the trigger is a message bubble, use the message content. 79 * 80 * @platform ios, android 81 */ 82 contentLabel: string 83 hint?: string 84 role?: AccessibilityRole 85 style?: StyleProp<ViewStyle> 86} 87export type TriggerChildProps = 88 | { 89 IS_NATIVE: true 90 control: { 91 isOpen: boolean 92 open: (mode: 'full' | 'auxiliary-only') => void 93 } 94 state: { 95 hovered: false 96 focused: false 97 pressed: false 98 } 99 /** 100 * We don't necessarily know what these will be spread on to, so we 101 * should add props one-by-one. 102 * 103 * On web, these properties are applied to a parent `Pressable`, so this 104 * object is empty. 105 */ 106 props: { 107 ref: null 108 onPress: null 109 onFocus: null 110 onBlur: null 111 onPressIn: null 112 onPressOut: null 113 accessibilityHint: null 114 accessibilityLabel: string 115 accessibilityRole: null 116 } 117 } 118 | { 119 IS_NATIVE: false 120 control: Dialog.DialogOuterProps['control'] 121 state: { 122 hovered: false 123 focused: false 124 pressed: false 125 } 126 props: RadixPassThroughTriggerProps & { 127 onPress: () => void 128 onFocus: () => void 129 onBlur: () => void 130 onMouseEnter: () => void 131 onMouseLeave: () => void 132 accessibilityHint?: string 133 accessibilityLabel: string 134 accessibilityRole: AccessibilityRole 135 } 136 }