Skip to content

Commit e52afaf

Browse files
authored
add preview builder (#46)
* add preview builder * pass preview as prop
1 parent e78b833 commit e52afaf

File tree

5 files changed

+47
-7
lines changed

5 files changed

+47
-7
lines changed

example/App.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,17 @@ const App = () => {
4949
}} previewBackgroundColor="transparent">
5050
<View style={[styles.rectangle, {backgroundColor: color, borderRadius: circle ? 999 : 0}]} />
5151
</ContextMenu>
52+
<ContextMenu
53+
title={'Custom Preview'}
54+
actions={[
55+
{
56+
title: 'Test Item',
57+
},
58+
]}
59+
previewBackgroundColor="transparent"
60+
preview={<View style={[styles.rectangle, {backgroundColor: 'green'}]} />}>
61+
<View style={[styles.rectangle, {backgroundColor: 'red'}]} />
62+
</ContextMenu>
5263
<View style={{color: 'red', height: 100, width: 100}} />
5364
</SafeAreaView>
5465
);

index.d.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component } from 'react';
1+
import React, { Component } from 'react';
22
import { NativeSyntheticEvent, ViewProps, ViewStyle } from 'react-native';
33

44
export interface ContextMenuAction {
@@ -54,6 +54,10 @@ export interface ContextMenuProps extends ViewProps {
5454
* The background color of the preview. This is displayed underneath your view. Set this to transparent (or another color) if the default causes issues.
5555
*/
5656
previewBackgroundColor?: ViewStyle["backgroundColor"];
57+
/**
58+
* Custom preview component.
59+
*/
60+
preview?: React.ReactNode;
5761
}
5862

5963
export default class ContextMenu extends Component<ContextMenuProps> { }

index.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
1-
import { requireNativeComponent } from 'react-native';
1+
import React from "react";
2+
import { requireNativeComponent, View } from "react-native";
23

3-
const ContextMenu = requireNativeComponent('ContextMenu', null);
4+
const NativeContextMenu = requireNativeComponent("ContextMenu", null);
5+
6+
const ContextMenu = (props) => {
7+
return (
8+
<NativeContextMenu {...props}>
9+
<View>{props.children}</View>
10+
{props.preview}
11+
</NativeContextMenu>
12+
);
13+
};
414

515
export default ContextMenu;

ios/ContextMenuView.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@
1818
@property (nullable, nonatomic, copy) NSArray<ContextMenuAction*>* actions;
1919

2020
@property (nullable, nonatomic, copy) UIColor* previewBackgroundColor;
21+
@property (nonatomic, weak) UIView *customView;
2122

2223
@end

ios/ContextMenuView.m

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,20 @@ @implementation ContextMenuView {
2121

2222
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex
2323
{
24-
[super insertReactSubview:subview atIndex:atIndex];
2524
if (@available(iOS 13.0, *)) {
26-
UIContextMenuInteraction* contextInteraction = [[UIContextMenuInteraction alloc] initWithDelegate:self];
25+
if (atIndex == 0) {
26+
[super insertReactSubview:subview atIndex:atIndex];
2727

28-
[subview addInteraction:contextInteraction];
28+
UIContextMenuInteraction* contextInteraction = [[UIContextMenuInteraction alloc] initWithDelegate:self];
29+
30+
[subview addInteraction:contextInteraction];
31+
}
32+
33+
if (atIndex == 1) {
34+
self.customView = subview;
35+
}
36+
} else {
37+
[super insertReactSubview:subview atIndex:atIndex];
2938
}
3039
}
3140

@@ -45,7 +54,12 @@ - (void)layoutSubviews
4554
}
4655

4756
- (nullable UIContextMenuConfiguration *)contextMenuInteraction:(nonnull UIContextMenuInteraction *)interaction configurationForMenuAtLocation:(CGPoint)location API_AVAILABLE(ios(13.0)) {
48-
return [UIContextMenuConfiguration configurationWithIdentifier:nil previewProvider:nil actionProvider:^UIMenu * _Nullable(NSArray<UIMenuElement *> * _Nonnull suggestedActions) {
57+
return [UIContextMenuConfiguration configurationWithIdentifier:nil previewProvider: self.customView == nil ? nil : ^(){
58+
UIViewController* viewController = [[UIViewController alloc] init];
59+
viewController.preferredContentSize = self.customView.frame.size;
60+
viewController.view = self.customView;
61+
return viewController;
62+
} actionProvider:^UIMenu * _Nullable(NSArray<UIMenuElement *> * _Nonnull suggestedActions) {
4963
NSMutableArray* actions = [[NSMutableArray alloc] init];
5064

5165
[self.actions enumerateObjectsUsingBlock:^(ContextMenuAction* thisAction, NSUInteger idx, BOOL *stop) {

0 commit comments

Comments
 (0)