| ... | @@ -133,9 +133,25 @@ export function ControlPillMenu( | ... | @@ -133,9 +133,25 @@ export function ControlPillMenu( |
| 133 | } | 133 | } |
| 134 | | 134 | |
| 135 | const { className: _className, ...menuProps } = props; | 135 | const { className: _className, ...menuProps } = props; |
| | 136 | let children = menuProps.children; |
| | 137 | // In long-press mode the wrapped pressable still receives the touch (the |
| | 138 | // patched MenuView button is touch-transparent) and RN's Fabric touch |
| | 139 | // handler is never cancelled by the in-tree UIContextMenuInteraction, so a |
| | 140 | // bare onPress would fire on finger-up even after the menu opened — and |
| | 141 | // also on a long press released just under the menu threshold. A dispatched |
| | 142 | // onLongPress makes Pressability swallow the release, so holds past 350ms |
| | 143 | // (below the ~500ms context-menu threshold) can only open the menu, never |
| | 144 | // tap through. |
| | 145 | if (props.shouldOpenOnLongPress && isValidElement(children)) { |
| | 146 | const child = children as ReactElement<{ onLongPress?: () => void; delayLongPress?: number }>; |
| | 147 | children = cloneElement(child, { |
| | 148 | onLongPress: child.props.onLongPress ?? (() => undefined), |
| | 149 | delayLongPress: child.props.delayLongPress ?? 350, |
| | 150 | }); |
| | 151 | } |
| 136 | return ( | 152 | return ( |
| 137 | <MenuView {...menuProps} themeVariant={isDarkMode ? "dark" : "light"}> | 153 | <MenuView {...menuProps} themeVariant={isDarkMode ? "dark" : "light"}> |
| 138 | {menuProps.children} | 154 | {children} |
| 139 | </MenuView> | 155 | </MenuView> |
| 140 | ); | 156 | ); |
| 141 | } | 157 | } |