Skip to content

Commit 5d6ef67

Browse files
committed
⭐️ Impl. dismissMenu
1 parent ee5cafe commit 5d6ef67

File tree

7 files changed

+80
-11
lines changed

7 files changed

+80
-11
lines changed

ios/src_library/React Native/RCTContextMenuButton/RCTContextMenuButton.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,16 @@ class RCTContextMenuButton: UIButton {
108108
override func reactSetFrame(_ frame: CGRect) {
109109
super.reactSetFrame(frame);
110110
};
111+
};
111112

112113
// ---------------------------------------------------------
113114
// MARK: RCTContextMenuButton - Public Functions for Manager
114115
// ---------------------------------------------------------
115-
116-
func dismissMenu(){
117-
// TODO: wip
116+
117+
@available(iOS 14, *)
118+
extension RCTContextMenuButton {
119+
@objc func dissmissMenu(){
120+
self.contextMenuInteraction?.dismissMenu();
118121
};
119122
};
120123

ios/src_library/React Native/RCTContextMenuButton/RCTContextMenuButtonManager.m

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,10 @@ @interface RCT_EXTERN_MODULE(RCTContextMenuButtonManager, RCTViewManager)
3636
RCT_EXPORT_VIEW_PROPERTY(enableContextMenu , BOOL);
3737
RCT_EXPORT_VIEW_PROPERTY(isMenuPrimaryAction, BOOL);
3838

39+
// ---------------------------
40+
// MARK: View Manager Commands
41+
// ---------------------------
42+
43+
RCT_EXTERN_METHOD(dismissMenu:(nonnull NSNumber *)node);
44+
3945
@end

ios/src_library/React Native/RCTContextMenuButton/RCTContextMenuButtonManager.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,22 @@ class RCTContextMenuButtonManager: RCTViewManager {
2727
return RCTView();
2828
};
2929
};
30+
31+
@objc func dismissMenu(_ node: NSNumber) {
32+
DispatchQueue.main.async {
33+
guard let view = self.bridge.uiManager.view(forReactTag: node)
34+
else { return };
35+
36+
if #available(iOS 14, *),
37+
let contextMenuButton = view as? RCTContextMenuButton {
38+
39+
contextMenuButton.dissmissMenu();
40+
41+
} else if #available(iOS 13, *),
42+
let contextMenuView = view as? RCTContextMenuView {
43+
44+
contextMenuView.dissmissMenu();
45+
};
46+
};
47+
};
3048
};

ios/src_library/React Native/RCTContextMenuView/RCTContextMenuView.swift

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,14 +138,25 @@ class RCTContextMenuView: UIView {
138138
};
139139
};
140140

141+
// ------------------------------------------------
142+
// MARK: RCTContextMenuView - ViewManager Functions
143+
// ------------------------------------------------
144+
145+
@available(iOS 13, *)
146+
extension RCTContextMenuView {
147+
@objc func dissmissMenu(){
148+
self.contextMenuInteraction?.dismissMenu();
149+
};
150+
};
151+
141152
// --------------------------------------------
142153
// MARK: RCTContextMenuView - Private Functions
143154
// --------------------------------------------
144155

145156
@available(iOS 13, *)
146-
extension RCTContextMenuView {
157+
fileprivate extension RCTContextMenuView {
147158

148-
private func notifyForBoundsChange(_ newBounds: CGRect){
159+
func notifyForBoundsChange(_ newBounds: CGRect){
149160
guard
150161
let bridge = self.bridge,
151162
let reactView = self.reactPreviewView else { return };
@@ -154,7 +165,7 @@ extension RCTContextMenuView {
154165
};
155166

156167
/// create `UIMenu` based on `menuConfig` prop
157-
private func createMenu(_ suggestedAction: [UIMenuElement]) -> UIMenu? {
168+
func createMenu(_ suggestedAction: [UIMenuElement]) -> UIMenu? {
158169
guard let menuConfig = self._menuConfig else {
159170
#if DEBUG
160171
print("RCTContextMenuView, createMenu"
@@ -170,8 +181,8 @@ extension RCTContextMenuView {
170181
};
171182
};
172183

173-
174-
private func createMenuPreview() -> UIViewController? {
184+
/// create custom menu preview based on `previewConfig` and `reactPreviewView`
185+
func createMenuPreview() -> UIViewController? {
175186
// alias to variable
176187
let previewConfig = self._previewConfig;
177188

@@ -190,7 +201,8 @@ extension RCTContextMenuView {
190201
return vc;
191202
};
192203

193-
private func makeTargetedPreview() -> UITargetedPreview {
204+
/// confgiure target preview based on `previewConfig`
205+
func makeTargetedPreview() -> UITargetedPreview {
194206
// alias to variable
195207
let previewConfig = self._previewConfig;
196208

ios/src_library/React Native/RCTContextMenuView/RCTContextMenuViewManager.m

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,10 @@ @interface RCT_EXTERN_MODULE(RCTContextMenuViewManager, RCTViewManager)
3535
RCT_EXPORT_VIEW_PROPERTY(menuConfig , NSDictionary);
3636
RCT_EXPORT_VIEW_PROPERTY(previewConfig, NSDictionary);
3737

38+
// ---------------------------
39+
// MARK: View Manager Commands
40+
// ---------------------------
41+
42+
RCT_EXTERN_METHOD(dismissMenu:(nonnull NSNumber *)node);
43+
3844
@end

ios/src_library/React Native/RCTContextMenuView/RCTContextMenuViewManager.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,22 @@ class RCTContextMenuViewManager: RCTViewManager {
1515
};
1616

1717
override func view() -> UIView! {
18-
if #available(iOS 13, *) {
18+
if #available(iOS 13.0, *) {
1919
return RCTContextMenuView(bridge: self.bridge);
2020

2121
} else {
2222
return RCTView();
2323
};
2424
};
25+
26+
@objc func dismissMenu(_ node: NSNumber) {
27+
DispatchQueue.main.async {
28+
guard #available(iOS 13.0, *),
29+
let view = self.bridge.uiManager.view(forReactTag: node),
30+
let contextMenuView = view as? RCTContextMenuView
31+
else { return };
32+
33+
contextMenuView.dissmissMenu();
34+
};
35+
};
2536
};

src/ContextMenuView.ios.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { StyleSheet, Platform, requireNativeComponent, UIManager, View, TouchableOpacity, processColor } from 'react-native';
2+
import { StyleSheet, Platform, requireNativeComponent, UIManager, View, TouchableOpacity, processColor, findNodeHandle } from 'react-native';
33
import Proptypes from 'prop-types';
44

55
import { PreviewType } from './Enums';
@@ -34,6 +34,10 @@ const NATIVE_PROP_KEYS = {
3434
onPressMenuPreview: 'onPressMenuPreview',
3535
};
3636

37+
const NATIVE_COMMAND_KEYS = {
38+
'dismissMenu': 'dismissMenu',
39+
};
40+
3741

3842
export class ContextMenuView extends React.PureComponent {
3943
static proptypes = {
@@ -99,6 +103,14 @@ export class ContextMenuView extends React.PureComponent {
99103
return { nativeProps, ...otherProps };
100104
};
101105

106+
dismissMenu = () => {
107+
UIManager.dispatchViewManagerCommand(
108+
findNodeHandle(this.nativeRef),
109+
NativeCommands?.[NATIVE_COMMAND_KEYS.dismissMenu],
110+
null
111+
);
112+
};
113+
102114
//#region - Event Handlers
103115
_handleOnLongPress = async () => {
104116
const { menuConfig, ...props } = this.props;
@@ -187,6 +199,7 @@ export class ContextMenuView extends React.PureComponent {
187199
return(
188200
<NativeComponent
189201
style={[styles.menuView, style]}
202+
ref={r => this.nativeRef = r}
190203
{...nativeCompProps}
191204
>
192205
<View style={styles.previewContainer}>

0 commit comments

Comments
 (0)