mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import {
2 type AccessibilityRole,
3 type GestureResponderEvent,
4 type StyleProp,
5 type ViewStyle,
6} from 'react-native'
7import {type SharedValue} from 'react-native-reanimated'
8import type React from 'react'
9
10import type * as Dialog from '#/components/Dialog'
11import {
12 type ItemProps as MenuItemProps,
13 type RadixPassThroughTriggerProps,
14} from '#/components/Menu/types'
15
16export type {
17 GroupProps,
18 ItemIconProps,
19 ItemTextProps,
20} from '#/components/Menu/types'
21
22export type AuxiliaryViewProps = {
23 children?: React.ReactNode
24 align?: 'left' | 'right'
25}
26
27export type ItemProps = Omit<MenuItemProps, 'onPress' | 'children'> & {
28 // remove default styles (i.e. for emoji reactions)
29 unstyled?: boolean
30 onPress: (evt?: GestureResponderEvent) => void
31 children?: React.ReactNode | ((hovered: boolean) => React.ReactNode)
32 // absolute position of the parent element. if undefined, assumed to
33 // be in the context menu. use this if using AuxiliaryView
34 position?: Measurement
35}
36
37export type Measurement = {
38 x: number
39 y: number
40 width: number
41 height: number
42}
43
44export type ContextType = {
45 isOpen: boolean
46 measurement: Measurement | null
47 /* Spring animation between 0 and 1 */
48 animationSV: SharedValue<number>
49 /* Translation in Y axis to ensure everything's onscreen */
50 translationSV: SharedValue<number>
51 mode: 'full' | 'auxiliary-only'
52 open: (evt: Measurement, mode: 'full' | 'auxiliary-only') => void
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 isNative: 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 isNative: 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 }