React Native Ios Context Menu Save

A react-native component to use context menu's (UIMenu) on iOS 13/14+

Project README

react-native-ios-context-menu


๐Ÿšงโš ๏ธ Documentation WIP โš ๏ธ๐Ÿšง

๐Ÿ“ Note: See TODO.md for progress.

  • The documentation is incomplete (some parts/sections are marked as TBA i.e. "to be added").
  • Some of the links in the documentation are broken (i.e. the URL points to PLACE_HOLDER_LINK).
  • Some of the gifs/images are old, or broken.
  • For now, please see the Usage And Examples section, and Showcase, Tests and Demos section for information on how to use this library.



Notice
๐Ÿ“ Note #1: Staring on version 2.x, this library now uses expo-modules, and contains a peer dependency to react-native-ios-utilites.
๐Ÿ“ Note #2: The documentation + examples are currently being rewritten.

๐Ÿ’… README-old.md โ€” The old version of the documentation (archived).
๐Ÿ’– example/src/examples โ€” The typescript rewrite of the examples (WIP).

Versions

Library Version Compatibility
2.1+ Uses Expo-Modules
Depends on [email protected]
Depends on ContextMenuAuxiliaryPreview
iOS 13+
Xcode 15+
2.0.x Uses Expo-Modules
Depends on [email protected]
iOS 13+
Xcode 15+
1.6.2 iOS 10 to iOS 15
Xcode 12+
1.4 iOS 10 to iOS 15
Xcode 13+
1.3 and Below iOS 10 to 14
Xcode 12+

๐Ÿ“ Note: Supports projects targeting iOS 10 but will use the action sheet fallback when running on iOS 12 and older.



Table of Contents

Sections and Links
A. Introduction

โ€ข Gifs and Demos
โ€ข Features
B. Installation

โ€ข Expo
โ€ข Troubleshooting
--โ€ข Xcode Build Error (Swift)
--โ€ข Xcode Build Error (Undefined symbol)
C. Basic Usage
D. Documentation

โ€ข D.1. Components
--โ€ข ContextMenuView Component
----โ€ข Props
----โ€ข Event Props
----โ€ข Properties/Methods
----โ€ข Experimental - Aux. Preview

--โ€ข ContextMenuButton Component
----โ€ข Props
----โ€ข Event Props
----โ€ข Properties/Methods

โ€ข D.2. Context
--โ€ข ContextMenuButtonContext
--โ€ข ContextMenuButtonContext

โ€ข D.3. Hooks
--โ€ข useMenuContext
--โ€ข useMenuButtonContext

โ€ข D.4. Objects and Types
--โ€ข MenuConfig.ts
----โ€ข Object Type: MenuConfig
----โ€ข Object Type: MenuActionConfig
----โ€ข Object Type: DeferredMenuElementConfig
----โ€ข String Union: MenuAttributes
----โ€ข String Union: MenuState
----โ€ข String Union: UIMenuOptions

--โ€ข MenuPreviewConfig.ts
----โ€ข Object Type: MenuPreviewConfig
----โ€ข String Union: ContextMenuInteractionCommitStyle
----โ€ข String Union: MenuPreviewSize
----โ€ข String Union: MenuPreviewType

--โ€ข MenuAuxiliaryPreviewConfig.ts
----โ€ข Object Type: MenuAuxiliaryPreviewConfig
----โ€ข String Union Type: MenuAuxiliaryPreviewAnchorPosition
----โ€ข String Union Type: MenuAuxiliaryPreviewHorizontalAlignment
----โ€ข String Union Type: UIViewAnimateOptions
----โ€ข Object Type: UIViewAnimateConfig
----โ€ข Object Type: MenuAuxiliaryPreviewBaseTransitionConfig
----โ€ข Object Union Type: MenuAuxiliaryPreviewTransitionConfig
----โ€ข Mixed Union Type: MenuAuxiliaryPreviewTransitionEntranceDelay

--โ€ข MenuIconConfig.ts
--โ€ข ImageItemConfig.ts
----โ€ข Object Type: ImageItemConfig
----โ€ข Object Type: ImageResolvedAssetSource
----โ€ข Object Type: ImageRectConfig
----โ€ข Object Type: ImageGradientConfig
----โ€ข Object Type: ImageSystemConfig

--โ€ข Undocumented Types

โ€ข D.5. Constants
E. Usage And Examples
๐Ÿ“ Note: See Example Index section for a complete list of examples + their descriptions.
F. Showcase, Tests and Demos
G. Meta
H. Licence

TOC: Examples Index

Examples
๐Ÿ“Œ ContextMenuView Example 01
๐Ÿ’ญ Summary: A basic context menu that has 3 menu action items.
๐Ÿ“Œ ContextMenuView Example 02
๐Ÿ’ญ Summary: Icon Example โ€” A basic context menu that has 3 menu action items, each with a different "SF Symbols" icon. This examples shows how to add a system icon in the context menu action.
๐Ÿ“Œ ContextMenuView Example 03
๐Ÿ’ญ Summary: Nested Menu โ€” This example shows a context menu that has a submenu item inside its list of menu actions.
๐Ÿ“Œ ContextMenuView Example 04
๐Ÿ’ญ Summary: Menu Attributes โ€” This example context menu showcases the MenuActionConfig.menuAttributes property.
๐Ÿ“Œ ContextMenuView Example 05
๐Ÿ’ญ Summary: Nested Menu + Menu Attributes โ€” A context menu that has a in-line submenu.
๐Ÿ“Œ ContextMenuView Example 06
๐Ÿ’ญ Summary: Menu Options โ€” A context menu that has a destructive submenu.
๐Ÿ“Œ ContextMenuView Example 07
๐Ÿ’ญ Summary: Menu Options โ€” A context menu that set to be both "destructive" and "display in-line".
๐Ÿ“Œ ContextMenuView Example 08
๐Ÿ’ญ Summary: Menu State โ€” A context menu with 3 actions that has 'on', 'off', and 'mixed' menuState.
๐Ÿ“Œ ContextMenuView Example 09
๐Ÿ’ญ Summary: Events โ€” An example for the onPressMenuItem event prop.
๐Ÿ“Œ ContextMenuView Example 10
๐Ÿ’ญ Summary: Dynamic Menu โ€” An example showing how to dynamically update the context menu while it's visible. In this example, the menu action changes every time the counter increments every second.
๐Ÿ“Œ ContextMenuView Example 11
๐Ÿ’ญ Summary: Context Menu Previews โ€” An example showing how to use a custom preview for the context menu.
๐Ÿ“Œ ContextMenuView Example 12
๐Ÿ’ญ Summary: Context Menu Previews โ€” An example showing a custom context menu preview that dynamically changes its size due to its contents updating every second.
๐Ÿ“Œ ContextMenuView Example 13
๐Ÿ’ญ Summary: Menu Action โ€” An example showing how to add a subtitle to menu action.
๐Ÿ“Œ ContextMenuView Example 14
๐Ÿ’ญ Summary: Context Menu Previews โ€” An example that changes the exit transition of the context menu preview when its tapped using the preferredCommitStyle config.
๐Ÿ“Œ ContextMenuView Example 15
๐Ÿ’ญ Summary: Context Menu Previews โ€” An example showing how to configure a context menu that uses targeted previews.
๐Ÿ“Œ ContextMenuView Example 15-02
๐Ÿ’ญ Summary: Context Menu Previews (Cont). โ€” An example showing how to configure a context menu that uses targeted previews + WrapperView.
๐Ÿ“Œ ContextMenuView Example 16
๐Ÿ’ญ Summary: Icon Example โ€” An example showing a context menu with an action that uses a 'IMAGE_ASSET' image for its icon.
๐Ÿ“Œ ContextMenuView Example 17
๐Ÿ’ญ Summary: Icon Example โ€” An example showing a context menu with action items that have different colored icons.
๐Ÿ“Œ ContextMenuView Example 18
๐Ÿ’ญ Summary: Icon Example โ€” An example showing a context menu with action items that has icons that uses local image assets imported via require(...).
๐Ÿ“Œ ContextMenuView Example 19
๐Ÿ’ญ Summary: Dynamic Menu โ€” An example showing a context menu that has a loading indicator using deferred menu elements.
๐Ÿ“Œ ContextMenuView Example 20
๐Ÿ’ญ Summary: Dynamic Menu โ€” An example showing a state-controlled context menu that shows a loading indicator using deferred menu elements.
๐Ÿ“Œ ContextMenuView Example 21
๐Ÿ’ญ Summary: Menu Element Size โ€” TBA
๐Ÿ“Œ ContextMenuView Example 22
๐Ÿ’ญ Summary: Menu Element Size โ€” TBA
๐Ÿ“Œ ContextMenuView Example 23
๐Ÿ’ญ Summary: Menu Element Size โ€” TBA
๐Ÿ“Œ ContextMenuView Example 24
๐Ÿ’ญ Summary: Menu Attributes โ€” keepsMenuPresented
๐Ÿ“Œ ContextMenuView Example 25
๐Ÿ’ญ Summary: Icon Example โ€” Advanced customization (E.g. scale, weight, paletteColors, hierarchicalColor).
๐Ÿ“Œ ContextMenuView Example 26
๐Ÿ’ญ Summary: Icon Example โ€” Network/Remote images as icons.
๐Ÿ“Œ ContextMenuView Example 27
๐Ÿ’ญ Summary: Icon Example โ€” Network/Remote images as icons + fallback image.
๐Ÿ“Œ ContextMenuView Example 28
๐Ÿ’ญ Summary: Programmatically shows the context menu.
๐Ÿ“Œ ContextMenuView Auxiliary Preview - Example 01
๐Ÿ’ญ Summary: TBA
๐Ÿ“Œ ContextMenuView Auxiliary Preview - Example 02
๐Ÿ’ญ Summary: TBA
๐Ÿ“Œ ContextMenuView Auxiliary Preview - Example 03
๐Ÿ’ญ Summary: TBA
๐Ÿ“Œ ContextMenuView Auxiliary Preview - Example 04
๐Ÿ’ญ Summary: TBA
๐Ÿ“Œ ContextMenuView Auxiliary Preview - Example 05
๐Ÿ’ญ Summary: TBA
๐Ÿ“Œ ContextMenuView Auxiliary Preview - Example 06
๐Ÿ’ญ Summary: TBA
๐Ÿ“Œ ContextMenuView Auxiliary Preview - Example 07
๐Ÿ’ญ Summary: TBA
๐Ÿ“Œ ContextMenuView Auxiliary Preview - Example 08
๐Ÿ’ญ Summary: TBA
๐Ÿ“Œ ContextMenuView Auxiliary Preview - Example 09
๐Ÿ’ญ Summary: TBA
๐Ÿ“Œ ContextMenuView Auxiliary Preview - Example 10
๐Ÿ’ญ Summary: TBA
๐Ÿ“Œ ContextMenuView Auxiliary Preview - Example 11
๐Ÿ’ญ Summary: TBA
๐Ÿ“Œ ContextMenuView Auxiliary Preview - Example 12
๐Ÿ’ญ Summary: TBA
๐Ÿ“Œ ContextMenuView Auxiliary Preview - Example 13
๐Ÿ’ญ Summary: TBA
๐Ÿ“Œ ContextMenuView Auxiliary Preview - Example 14
๐Ÿ’ญ Summary: TBA
๐Ÿ“Œ ContextMenuView Auxiliary Preview - Example 15
๐Ÿ’ญ Summary: TBA
๐Ÿ“Œ ContextMenuView Auxiliary Preview - Example 16
๐Ÿ’ญ Summary: Programmatically shows the auxiliary preview as a popover (w/o showing the context menu).
๐Ÿ“Œ ContextMenuButton Example 01
๐Ÿ’ญ Summary: TBA
๐Ÿ“Œ ContextMenuButton Example 02
๐Ÿ’ญ Summary: TBA



A. Introduction

A react native component to use UIMenu on iOS 13 and later.


Gifs and Demos

๐Ÿ“ Note: These gifs are from an older version of the library running on iOS 13 (see Usage And Examples section for updated example gifs).

ContextMenuView Examples, Left: Example 1, Example 2, and Right: Example 3, Example 4 Simple Example 1 to 4 Gifs

ContextMenuView examples, Left: Example 5, Example 6, and Right: Example 7, Example 8 Simple Example 5 to 8 Gifs

ContextMenuView example, Left: Example 9, and Right: Example 10 Simple Example 9 and 8 Gifs

ContextMenuView examples, Left: Example 11, Example 12, and Right: Example 13, Example 14 Simple Example 11 to 14 Gifs

ContextMenuView examples, Left: Example 15, Example 16, and Right: Example 17, Example 18 Simple Example 11 to 14 Gifs

ContextMenuView tests, Left: Test 1, and Right: Test 2 Context Menu View Test 1 and 2 Gifs

ContextMenuView tests, Left: Test 3, and Right: Test 4 Context Menu View Test 3 and 4 Gifs

ContextMenuView tests, Left: Test 5, and Right: Test 6 Context Menu View Test 5 and 6 Gifs

ContextMenuView tests, Left/Right: Test 7 Context Menu View 7 Gifs

ContextMenuView ActionSheetIOS fallback for simple example 1 to 9 Action Sheet Fallback for Simple Example 1 to 9 Gifs

ContextMenuView ActionSheetIOS fallback for context menu view test 1 to 6 Action Sheet Fallback for Context Menu View Test 1 to 6 Gifs

ContextMenuButton examples, Left: Example 1, and Right: Example 2 Simple Example 1 and 2 Gifs


Features

  • Support for creating menu actions and submenus (i.e. nested and in-line menus).
  • Support for customizing the menu icons (i.e. support for SF Symbols, require(image), and xcasset icons, icon tint, etc).
  • Extensive support for SF Symbols configuration (e.g. pointSize, weight, scale, hierarchicalColor, paletteColors).
  • Support for iOS 14 functionality (like the UIButton context menu, dynamically updating the menu while it's visible, etc).
  • Support for setting (almost) all of the native UIMenu and ๏ฟผUIAction properties (e.g. UIMenuElementState, MenuElementAtrributes, discoverabilityTitle, etc.)
  • Basic ActionSheetIOS menu fallback for iOS 12 and below.
  • Support for creating custom context menu previews (with support for dynamic or fixed preview sizes, setting the UIPreviewParameters, specifying a UITargetedPreview, etc).
  • Support for custom auxiliary previews (experimental).
  • Support for deferred context menu items.



B. Installation

# 1. install library + dependencies
npm install react-native-ios-utilities
npm install react-native-ios-context-menu

# 2. then run pod install (uses auto-linking)
cd ios && pod install

๐Ÿ“ Note A: You might encounter some build errors since this library is written in swift, so there's some extra step involved to use this library (see table below for reference).


๐Ÿ“ Note B: If you want to use an older or different version of this library, please refer to versions section's compatibility table.

Additional Steps
1๏ธโƒฃ Add an empty swift file to your project
2๏ธโƒฃ Update the project's "Library Search Paths" build settings

Installation (Experimental Version)

# 1. install library + dependencies
npm install react-native-ios-utilities@next
npm install react-native-ios-context-menu@next


# 2. then run pod install (uses auto-linking)
cd ios && pod install

Updating

This library has cocoapods dependency to ContextMenuAuxiliaryPreview, so you need to update it separately.

# A. Either update this specific pod...
pod update ContextMenuAuxiliaryPreview

# B. Or update all the pods
pod update

Expo


Versions and Dependencies

Library Version Dependencies + Versions
2.0.x react-native-ios-utilities - 4.x
2.1.x react-native-ios-utilities - 4.x
ContextMenuAuxiliaryPreview - 0.1.x
2.2.x react-native-ios-utilities - 4.x
ContextMenuAuxiliaryPreview - 0.2.x

Troubleshooting

If you encounter any errors/bugs while using this library, or want a particular feature implemented, please create an issue! (my inbox is a mess, please feel free to tag me). โœจ


Troubleshooting: Xcode Build Error (Swift)

๐Ÿ“ Note: This library is written in swift. If you are having trouble building your app after installing this library, try adding an empty swift file to your project:

  1. Open up your ios/project.xcworkspace project
  2. On the project navigator panel (located on the right side of Xcode), right click on your project group (or another folder/group i.e the blue or yellow icons) and select the "New File..." option
  3. In the popup sheet, select "Swift" as the template and then click the "Next" button
  4. A "Save As" popup sheet should appear and then click "Create" (you can rename the file first if you want to)
  5. If Xcode asks you to create a "Objective-C Bridging Header" choose "Create Objective-C Bridging Header"

Troubleshooting: Xcode Build Error (Undefined symbol)

When installing this library on Xcode 12+, you'll get the following error in Xcode:

Xcode linking build error

Undefined symbol: (extension in UIKit):
__C.UIMenu.init(title: Swift.String, image: __C.UIImage?, identifier: __C.UIMenuIdentifier?, options: __C.UIMenuOptions, children: [__C.UIMenuElement]) -> __C.UIMenu

Undefined symbol: (extension in UIKit):
__C.UIAction.init(title: Swift.String, image: __C.UIImage?, identifier: __C.UIActionIdentifier?, discoverabilityTitle: Swift.String?, attributes: __C.UIMenuElementAttributes, state: __C.UIMenuElementState, handler: (__C.UIAction) -> ()) -> __C.UIAction

To fix this, see screenshot + follow the steps below:

Xcode - Remove library search paths


  1. Open your ios/project.xcworkspace project.
  2. In the project navigator panel (located on the right side of Xcode), select your project group (i.e. the item with the blueprint icon).
  3. The Xcode project editor should appear. In the left panel, under the "Project" section, select your project (if it isn't already selected).
  4. In the project section's top tab bar, select the "Build Settings" tab (also make sure the "All" and "Combined" tabs are selected).
  5. In the project navigator list, under the "Search Path" section, there should be a "Library Search Paths" setting (alternatively, you can search for "Library Search Paths" in the search bar).
  6. According to this issue comment, you can clear all the items listed in the "Library Search Paths" setting by selecting the items in the list, and pressing the "-" button in the popover.
    • TLDR: Xcode automatically manages this setting, and the RN template hardcodes it to use Swift 5.0.
    • Alternatively, you can change the entry "$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)" to "$(TOOLCHAIN_DIR)/usr/lib/swift-5.3/$(PLATFORM_NAME)" i.e. change swift-5.0 to swift-5.3, or whatever the newest version of swift that comes with your Xcode installation (to show the popup dialog, double click the value/item).
  7. If you haven't already, make sure to create an empty swift file. Then clean the build folder (the option is in the menu bar under: "Product" -> "Clean Build Folder") and try building your project again.
  8. If you are still having problems building the app, try the following and build your project again:
  • Try clearing out Xcode's derivedData directory: rm -rf ~/Library/Developer/Xcode/DerivedData/* (check out this gist for instructions on how to clean up Xcode)
  • Try clearing out the Cocoapods cache: rm -rf "${HOME}/Library/Caches/CocoaPods" (and then try running pod install again).

Xcode - Remove library search paths


Explanation: Some versions of the react-native template hard codes the swift library search paths to use swift 5.0 (which causes the linker to mismatch the swift system libraries bundled with your Xcode + iOS/Simulator installation).

Here are some related issues in the RN repo: Issue 30202 and Issue 29178.



C. Basic Usage

For more examples, check out the Usage And Examples section.


๐Ÿ”— Full Example

import * as React from 'react';
import { StyleSheet, Text } from 'react-native';

import { ContextMenuView } from 'react-native-ios-context-menu';

export function BasicUsageExample01() {
  return (
    <ContextMenuView
      style={styles.container}
      menuConfig={{
        menuTitle: 'BasicUsageExample01',
        menuItems: [{
          actionKey  : 'key-01',
          actionTitle: 'Action #1',
        }, {
          actionKey  : 'key-02'   ,
          actionTitle: 'Action #2',
        }, {
          actionKey  : 'key-03'   ,
          actionTitle: 'Action #3',
        }],
      }}
    >
      <Text style={styles.text}>
        Press And Hold To Show Context Menu
      </Text>
    </ContextMenuView>
  );
};

const styles = StyleSheet.create({
  container: {
    margin: 10,
    padding: 10,
  },
  text: {
    fontSize: 16,
  },
});



D. Documentation

๐Ÿ’ก Tip: Most of the time, when a type or component is mentioned, you can click it to jump to that item in the README (or its declaration in the source code).


D.1. Components

ContextMenuView Component

ContextMenuView Component: Props
Prop Name and Type Description
โš›๏ธ ViewProps This component supports all the standard props from a <View/> component.
๐Ÿ”ค menuConfig

โš›๏ธ MenuConfig
This prop configures the context menu, along with what menu actions to show.

This prop accepts a MenuConfig object. This object is used to configure various aspects of the context menu. Here are some relevant properties:

1๏ธโƒฃ MenuConfig.menuTitle: the context menu title (required) โ€” if you don't want to show the menu title, pass in an empty string.

2๏ธโƒฃ MenuConfig.menuItems: the actions to show (e.g. the title, icons, subtitle, etc) โ€” accepts either an array of MenuActionConfig or MenuConfig objects.

3๏ธโƒฃ MenuConfig.menuOptions: the attributes of the context menu (e.g. destructive) โ€” accepts an array of UIMenuOptions string items, and any nested menus or submenus to show (see "Note A").

๐Ÿ“ Note A: Passing a MenuConfig object inside of the MenuConfig.menuItems property will result in a nested context menu (i.e. a submenu).

In this scenario, the MenuConfig.menuOptions and MenuConfig.icon can be used to configure the appearance of the submenu.

For usage examples regarding nested menus, see Example 06.

๐Ÿ“ Note B: Passing a value of null (or undefined) to this prop will not disable the context menu. Instead, please use the isContextMenuEnabled prop to disable the context menu.

๐Ÿ“ Note C: You can put MenuConfig in state if you want to dynamically change the menu configuration (this will allow you to add/remove submenu items, or update the current menu options).

If the context menu is currently visible, changing/updating the MenuConfig value passed to this prop will cause the context menu to change in real-time. This behavior is only supported on iOS 14+.

๐Ÿ“Œ Some example links to get you started:
โ€ข For basic usage examples regarding MenuConfig, see: Example 1,

โ€ข For examples on creating + configuring the menu action items (i.e MenuActionConfig), see: Example 2,

โ€ข For menu action attributes + menu state, and action subtitles, see: Example 4, Example 8, and Example 13,

โ€ข For examples regarding the usage of icons (i.e ImageItemConfig), see: Example 16, Example 17, and Example 18.
๐Ÿ”ค previewConfig

โš›๏ธ MenuPreviewConfig
Configures the context menu's preview.

If no configuration is provided then it will default to using the context menu component itself as the preview.

๐Ÿ“ Note: If you do not want to show a preview (i.e. only show the context menu itself), consider using a ContextMenuButton component instead.

๐Ÿ“Œ Some example links to get you started:
โ€ข For examples regarding the configuration of the context menu preview (e.g. custom previews), see: Example 11, Example 12, Example 14, and Example 15.
๐Ÿ”ค shouldUseDiscoverability
TitleAsFallbackValueForSubtitle

โš›๏ธ boolean

โœณ๏ธ Default: true
On iOS 15+, the value passed to the MenuActionConfig.discoverabilityTitle property is no longer displayed as a subtitle under the menu action.

Instead you need to set a different property called MenuActionConfig.subtitle.

The discoverabilityTitle property is now used for the "discoverability heads-up display" (e.g when an app supports keyboard shortcuts, holding down the command key presents a list of shortcuts; the discoverabilityTitle is then used as the title for the shortcut).

If this prop is set to true, it will then use the value passed on to the discoverabilityTitle value as the subtitle for the menu action, preserving the old behavior. In other words, this prop exists for backwards-compatibility reasons.

๐Ÿ“ Note: This prop is set to true by default; set this to false if you don't want this automatic behaviour to happen.
๐Ÿ”ค shouldWaitForMenuToHide
BeforeFiringOnPressMenuItem

โš›๏ธ boolean

โœณ๏ธ Default: true
If set to true (which it is by default), the onPressMenuItem event will be triggered after the context menu has been hidden (i.e. after onMenuDidHide event is triggered).

Set this to false if you want onPressMenuItem to trigger as soon as an item has been pressed in the context menu.

๐Ÿ“ Note: Layout updates while the context menu is transitioning from it's open to hidden state might cause layout flickering (e.g. Issue #43).
๐Ÿ”ค isContextMenuEnabled

โš›๏ธ boolean

โœณ๏ธ Default: true
Enables or disables the context menu. Useful if you want to temporarily disable the context menu.
๐Ÿ”ค lazyPreview

โš›๏ธ boolean

โœณ๏ธ Default: true
If set to true (which it is by default), the custom context menu preview (i.e. the component returned from the ContextMenuView.renderPreview prop) and the auxiliary preview (i.e. the component returned from the ContextMenuView.renderAuxillaryPreview prop) are only mounted/rendered when the context menu is visible.

Set this to false if you want the preview content to be always mounted.
๐Ÿ”ค shouldEnable
AggressiveCleanup

โš›๏ธ boolean

โœณ๏ธ Default: true
Deprecated. This prop no longer does anything (see shouldCleanupOnComponentWillUnmount
ForMenuPreview, and shouldCleanup
OnComponentWillUnmountForAuxPreview
).
๐Ÿ”ค useActionSheetFallback

โš›๏ธ boolean

โœณ๏ธ Default: true
Context menus are only supported on iOS 13+ (i.e context menus are not supported on iOS 12, and below).

On iOS 12 and below, a long press on a ContextMenuView will show a ActionSheetIOS menu based on the current menuConfig prop.

If you want to disable this behavior, set this prop to false.

๐Ÿ“ Note: Default value is false on iOS 13+, and true on iOS 12 and below.
๐Ÿ”ค renderPreview

โš›๏ธ () => React.ReactElement
This prop is a "render" prop, i.e it accepts a function that returns a react component.

The returned component will displayed in the context menu preview.
๐Ÿ”ค isAuxiliaryPreviewEnabled

โš›๏ธ boolean

โœณ๏ธ Default: false
โš ๏ธ Experimental: Please see Auxiliary Preview section.

TBA
๐Ÿ”ค auxiliaryPreviewConfig

โš›๏ธ MenuAuxiliaryPreviewConfig
โš ๏ธ Experimental: Please see Auxiliary Preview section.

TBA
๐Ÿ”ค renderAuxillaryPreview

โš›๏ธ () => React.ReactElement
โš ๏ธ Experimental: Please see Auxiliary Preview section.

TBA
๐Ÿ”ค internalCleanupMode

โš›๏ธ RNICleanupMode

โœณ๏ธ Default: automatic
Internally, a clean up routine is triggered whenever a component is unmounted.

However, if the clean up routine is triggered too early, this will lead to the context menu component disappearing (E.g. issue #34).

If you are experiencing this issue, you can disable the clean up routine from triggering altogether by setting this prop to disabled.

Additionally, you can also try setting this prop to either to viewController, didMoveToWindowNil, or reactComponentWillUnmount.

viewController mode will trigger the clean up routine via the UIViewController.viewWillDisappear lifecycle method, and didMoveToWindowNil will trigger the cleanup routine during the UIView.didMoveToWindow lifecycle method, while the reactComponentWillUnmount mode on the other hand, will trigger the clean up routine via the componentWillUnmount react lifecycle event.
๐Ÿ”ค shouldCleanupOnComponent
WillUnmountForMenuPreview

โš›๏ธ boolean

โœณ๏ธ Default: false
If set to true, the custom preview is immediately freed from memory once the context menu is closed.

๐Ÿ“ Note: For the immediately cleanup to take effect, the lazyPreview prop also needs to be enabled.
๐Ÿ”ค shouldCleanupOnComponent
WillUnmountForAuxPreview

โš›๏ธ boolean

โœณ๏ธ Default: false
If set to true, the aux. preview is immediately freed from memory once the context menu is closed.

๐Ÿ“ Note: For the immediately cleanup to take effect, the lazyPreview prop also needs to be enabled.



ContextMenuView Component: Event Props
Prop Name and Type Description
๐Ÿ”ค onMenuWillShow

โš›๏ธ OnMenuWillShowEvent
Event that gets called before the context menu is shown, i.e this event is immediately invoked when the menu is about to become visible.
๐Ÿ”ค onMenuDidShow

โš›๏ธ OnMenuDidShowEvent
Event that gets called after the context menu is shown, i.e this event is invoked after the menu entrance animation is finished.
๐Ÿ”ค onMenuWillHide

โš›๏ธ OnMenuWillHideEvent
Event that gets called before the context menu is hidden, i.e this event is immediately invoked when the menu is about to become hidden.
๐Ÿ”ค onMenuDidHide

โš›๏ธ OnMenuDidHideEvent
Event that gets called after the context menu is hidden, i.e this event is invoked after the menu exit animation is finished.
๐Ÿ”ค onMenuWillCancel

โš›๏ธ OnMenuWillCancelEvent
Event that gets called when the menu is cancelled and about to be hidden, i.e this event is immediately invoked when the context menu interaction is cancelled.
๐Ÿ”ค onMenuDidCancel

โš›๏ธ OnMenuDidCancelEvent
Event that gets called when the menu is cancelled and hidden, i.e. this event is invoked when the context menu is cancelled, and the menu exit transition is finished.
๐Ÿ”ค onPressMenuItem

โš›๏ธ OnPressMenuItemEvent
Event that gets called when a menu action is pressed.

You can identify which action was pressed via nativeEvent.actionKey property in the nativeEvent object.

Check out Example 1, and Example 9 for examples regarding the onPressMenuItem event prop.

๐Ÿ“ Note: If shouldWaitForMenuToHide
BeforeFiringOnPressMenuItem prop is set to true (which it is by default), then this event will fire after onMenuDidHide is triggered.
๐Ÿ”ค onPressMenuPreview

โš›๏ธ OnPressMenuPreviewEvent
Event that gets called when the menu's preview is pressed.
๐Ÿ”ค onMenuAuxiliaryPreviewWillShow

โš›๏ธ OnMenuAuxiliaryPreviewWillShowEvent
โš ๏ธ Experimental: Please see Auxiliary Preview section.

TBA
๐Ÿ”ค onMenuAuxiliaryPreviewDidShow

โš›๏ธ OnMenuAuxiliaryPreviewDidShowEvent
โš ๏ธ Experimental: Please see Auxiliary Preview section.

TBA
๐Ÿ”ค onMenuAuxiliaryPreviewDidShow

โš›๏ธ DeferredElementProvider i.e.
(deferredID, completion)ย =>ย void
This event gets called whenever a UIDeferredMenuElement needs to be loaded. A deferred menu element can be created via a DeferredMenuElementConfig object.

A deferred menu is a context menu is basically a placeholder โ€” i.e. it appears as a loading indicator in the context menu.

When you pass in a DeferredMenuElementConfig object to MenuConfig.menuItems, it means you want to load and add additional menu items once the context menu is opened.

This event will provide a completion callback โ€” use this to provide the additional context menu items you want to load.

๐Ÿ“ Note A: Deferred menu elements only work on iOS 14+.

๐Ÿ“ Note B: You can dynamically update the context menu items without using the prop โ€” the difference is that deferred menu items will show a placeholder loading indicator when the additional menu items haven't been loaded yet.

๐Ÿ“ Note C: It is possible to have multiple deferred menu elements (e.g. deferred elements can also provide deferred elements, and so on).

Just be sure to use a unique deferredID so you can tell them apart.

๐Ÿ“Œ Example Usage:
โ€ข ContextMenuViewExample19.

ContextMenuView Component: Properties/Methods
Prop Name and Type Description
๐Ÿ”ค dismissMenu

โš›๏ธ Promise<Void>
Allows you to programmatically dismiss the context menu. Only available on iOS 14 and above.
๐Ÿ”ค presentMenu

โš›๏ธ Promise<Void>
Allows you to programmatically show the context menu.
๐Ÿ”ค showAuxiliaryPreviewAsPopover

โš›๏ธ Promise<Void>
Allows you to programmatically show the auxiliary preview as a popover.

ContextMenuView Component: Experimental - Auxiliary Preview

The context menu auxiliary preview is an experimental feature, and is not officially part of UIKit's "Menu and Shortcuts" API.

This is just a feature that I've implemented myself and added to the library โ€” as such official support is limited and might break in a future iOS version. Please use at your own risk.


ContextMenuButton Component

For basic usage, please see Example 1 section.

  • The ContextMenuButton component is almost the same as the ContextMenuView component (It supports the same kind of props and events).

  • The only difference between them is that the ContextMenuButton component does not have a preview, and it can be immediately shown when its tapped instead of having to do a long press. See Example 2 for more details.

  • Note that ContextMenuButton is only available on iOS 14 and above. On iOS 13, it will use a ContextMenuButton, and on iOS 12 and below, it will use the ActionSheetFallback module to present a ActionSheetIOS menu.

  • If you want to add additional touch events, you can wrap this component inside a button component (e.g. TouchableOpacity).

    • When wrapping this component inside a button, please make sure to set the useActionSheetFallback prop to false.

ContextMenuButton Component: Props
Prop Name and Type Description
โš›๏ธ ViewProps This component supports all the standard props from a <View/> component.
๐Ÿ”ค menuConfig

โš›๏ธ MenuConfig
Same as ContextMenuView.menuConfig prop.
๐Ÿ”ค isMenuPrimaryAction

โš›๏ธ boolean
When set to true, the context menu will be shown when its tapped instead of a long press.
๐Ÿ”ค shouldUseDiscoverability
TitleAsFallbackValueForSubtitle

โš›๏ธ boolean

โœณ๏ธ Default: true
TBA / Not Implented
๐Ÿ”ค enableContextMenu

โš›๏ธ boolean

โœณ๏ธ Default: true
Same as ContextMenuView.enableContextMenu prop.
๐Ÿ”ค useActionSheetFallback

โš›๏ธ boolean

โœณ๏ธ Default: true
Same as ContextMenuView.useActionSheetFallback prop.

ContextMenuButton Component: Event Props
Prop Name and Type Description
๐Ÿ”ค onMenuWillShow

โš›๏ธ OnMenuWillShowEvent
Same as ContextMenuView.onMenuWillShow event.
๐Ÿ”ค onMenuDidShow

โš›๏ธ OnMenuDidShowEvent
Same as ContextMenuView.onMenuDidShow event.
๐Ÿ”ค onMenuWillHide

โš›๏ธ OnMenuWillHideEvent
Same as ContextMenuView.onMenuWillHide event.
๐Ÿ”ค onMenuDidHide

โš›๏ธ OnMenuDidHideEvent
Same as ContextMenuView.onMenuDidHide event.
๐Ÿ”ค onMenuWillCancel

โš›๏ธ OnMenuWillCancelEvent
Same as ContextMenuView.onMenuWillCancel event.
๐Ÿ”ค onMenuDidCancel

โš›๏ธ OnMenuDidCancelEvent
Same as ContextMenuView.onMenuDidCancel event.
๐Ÿ”ค onMenuWillCreate

โš›๏ธ OnMenuWillCreateEvent
Same as ContextMenuView.onMenuWillCreate event.
๐Ÿ”ค onPressMenuItem

โš›๏ธ OnPressMenuItemEvent
Same as ContextMenuView.onPressMenuItem event.

ContextMenuButton Component: Properties/Methods
Prop Name and Type Description
๐Ÿ”ค dismissMenu

โš›๏ธ Promise<Void>
Same as ContextMenuView.dismissMenu method.

ActionSheetFallback Module

A module to show a ActionSheetIOS menu based on a MenuConfig object.

This module attempts to approximate UIMenu behavior using ActionSheetIOS, so it's very limited (i.e. it does not support menu/action icons, etc.), but it does support things like submenu's, destructive actions/menu's, inline submenu's, and hidden actions.


  • Import the module like this: import { ActionSheetFallback } from "react-native-ios-context-menu";

  • To present a ๏ฟผ๏ฟผActionSheetIOS menu, call const selectedAction = await ActionSheetFallback.show(menuConfig)


Function Description
๐Ÿ”ค show

โš›๏ธ (menuConfig: MenuConfig):
Promise<MenuAction ยฆ null>
This function accepts a MenuConfig object and returns the selected MenuAction object or null if cancelled.

D.2. Context

ContextMenuViewContext Context

TBA

Property Description
๐Ÿ”ค isMenuVisible

โš›๏ธ boolean
TBA
๐Ÿ”ค getRefToContextMenuView

โš›๏ธ ()ย =>ย ContextMenuView
๐Ÿ“Œ ContextMenuView
TBA

ContextMenuButtonContext Context

TBA

Property Description
๐Ÿ”ค isMenuVisible

โš›๏ธ boolean
TBA
๐Ÿ”ค getRefToContextMenuButton

โš›๏ธ ()ย =>ย ContextMenuView
๐Ÿ“Œ ContextMenuButton
TBA

D.3. Hooks

useMenuContext Hook

A hook to use the ContextMenuViewContext context.

TBA


useMenuButtonContext Hook

A hook to use the ContextMenuButtonContext context.

TBA


D.4. Objects and Types

MenuConfig.ts

Object Type: MenuConfig

A container for grouping related menu elements in an app menu or contextual menu.

An object that is used to create and configure a context menu. Internally, this object is used to create a UIMenu instance (see apple docs for more information).


Name and Type Description
๐Ÿ”ค type

โš›๏ธ string, i.e"menu"
TBA
๐Ÿ”ค menuTitle

โš›๏ธ string
TBA

๐Ÿ“ Note: If you don't want a menu title to appear for your context menu, just pass in an empty string to this property.
๐Ÿ”ค menuSubtitle

โš›๏ธ string
TBA

๐Ÿ“ Note: Requires iOS 15+.
๐Ÿ”ค menuOptions

โš›๏ธ Array<UIMenuOptions>
๐Ÿ“Œ UIMenuOptions
TBA
๐Ÿ”ค menuPreferredElementSize

โš›๏ธ MenuElementSize
TBA
๐Ÿ”ค menuItems

โš›๏ธ MenuElementConfig[] i.e.
MenuConfig ยฆ MenuActionConfig
ยฆ DeferredMenuElementConfig

๐Ÿ“Œ MenuConfig
๐Ÿ“Œ MenuActionConfig
๐Ÿ“Œ DeferredMenuElementConfig
TBA
๐Ÿ”ค icon

โš›๏ธ IconConfigย ยฆย ImageItemConfig
๐Ÿ“Œ IconConfig (deprecated)
๐Ÿ“Œ ImageItemConfig
TBA

Object Type: MenuActionConfig

An object that is used to create a menu action item in the context menu. Internally, this object is used to create a UIAction instance (see apple docs for more information),


Name and Type Description
๐Ÿ”ค type

โš›๏ธ string, i.e "action"
TBA
๐Ÿ”ค Required: actionKey

โš›๏ธ string
TBA
๐Ÿ”ค Required: actionTitle

โš›๏ธ string
TBA
๐Ÿ”ค actionSubtitle

โš›๏ธ string
TBA
๐Ÿ”ค menuState

โš›๏ธ MenuState
TBA
๐Ÿ”ค menuAttributes

โš›๏ธ Array<MenuAttributes>
๐Ÿ“Œ MenuAtrributes
TBA
๐Ÿ”ค discoverabilityTitle

โš›๏ธ string
TBA
๐Ÿ”ค icon

โš›๏ธ IconConfig ยฆ ImageItemConfig
๐Ÿ“Œ IconConfig (deprecated)
๐Ÿ“Œ ImageItemConfig
TBA

Object Type: DeferredMenuElementConfig

An object that is used to create a deferred menu element. Internally, this object is used to create a UIDeferredMenuElement instance (see apple docs for more information),

Name and Type Description
๐Ÿ”ค Required: type

โš›๏ธ string i.e. deferred.
TBA
๐Ÿ”ค Required: deferredID

โš›๏ธ string
TBA
๐Ÿ”ค: shouldCache

โš›๏ธ boolean
TBA

String Union: MenuAttributes

Attributes that determine the style of the menu element.

A union string type that maps to UIMenuElement.Attributes enum (see apple docs for more information).


Type Description
โš›๏ธ hidden TBA
โš›๏ธ disabled TBA
โš›๏ธ destructive TBA
โš›๏ธ keepsMenuPresented TBA

String Union: MenuState

Constants that indicate the state of an action- or command-based menu element.

A union string type that maps to UIMenuElement.State enum (see apple docs for more information).


Type Description
โš›๏ธ on TBA
โš›๏ธ off TBA
โš›๏ธ mixed TBA

String Union: UIMenuOptions

Options for configuring a menu's appearance.

A union string type that maps to UIMenu.Options option set (see apple docs for more information).


Type Description
โš›๏ธ destructive TBA
โš›๏ธ displayInline TBA

String Union: MenuElementSize

Constants that determine the size of an element in a menu.

A union string type that maps to UIMenu.ElementSize enum (see apple docs for more information).


Type Description
โš›๏ธ small TBA
โš›๏ธ medium TBA
โš›๏ธ large TBA

MenuPreviewConfig.ts

Object Type: MenuPreviewConfig
Name and Type Description
๐Ÿ”ค previewType

โš›๏ธ MenuPreviewType

โœณ๏ธ Default: DEFAULT
TBA
๐Ÿ”ค previewSize

โš›๏ธ MenuPreviewSize

โœณ๏ธ Default: INHERIT
TBA
๐Ÿ”ค isResizeAnimated

โš›๏ธ boolean

โœณ๏ธ Default: true
TBA
๐Ÿ”ค borderRadius

โš›๏ธ number
TBA
๐Ÿ”ค backgroundColor

โš›๏ธ DynamicColorย ยฆย string
๐Ÿ“Œ DynamicColor
TBA
๐Ÿ”ค previewSize

โš›๏ธ ContextMenuInteractionCommitStyle

โœณ๏ธ Default: dismiss
TBA
๐Ÿ”ค targetViewNode

โš›๏ธ number
TBA

String Union: ContextMenuInteractionCommitStyle
Name and Type Description
โš›๏ธ dismiss TBA
โš›๏ธ pop TBA

String Union: MenuPreviewSize
Name and Type Description
โš›๏ธ INHERIT TBA
โš›๏ธ STRETCH TBA

String Union: MenuPreviewType
Name and Type Description
โš›๏ธ DEFAULT TBA
โš›๏ธ CUSTOM TBA

MenuAuxiliaryPreviewConfig.ts


Object Type: MenuAuxiliaryPreviewConfig
Name and Type Description
๐Ÿ”ค height

โš›๏ธ number
TBA
๐Ÿ”ค anchorPosition

โš›๏ธ MenuAuxiliaryPreviewAnchorPosition

โœณ๏ธ Default: automatic
TBA
๐Ÿ”ค alignmentHorizontal

โš›๏ธ MenuAuxiliaryPreviewHorizontalAlignment

โœณ๏ธ Default: stretchPreview
TBA
๐Ÿ”ค marginPreview

โš›๏ธ number
TBA
๐Ÿ”ค marginAuxiliaryPreview

โš›๏ธ number
TBA
๐Ÿ”ค transitionConfigEntrance

โš›๏ธ MenuAuxiliaryPreviewTransitionConfig
TBA
๐Ÿ”ค transitionEntranceDelay

โš›๏ธ MenuAuxiliaryPreviewTransitionEntranceDelay
TBA

String Union Type: MenuAuxiliaryPreviewAnchorPosition
Name and Type Description
โš›๏ธ top TBA
โš›๏ธ bottom TBA
โš›๏ธ automatic TBA

String Union Type: MenuAuxiliaryPreviewHorizontalAlignment
Name and Type Description
โš›๏ธ stretchScreen TBA
โš›๏ธ stretchPreview TBA
โš›๏ธ previewLeading TBA
โš›๏ธ previewTrailing TBA
โš›๏ธ previewCenter TBA

String Union Type: UIViewAnimateOptions
Name and Type Description
โš›๏ธ curveEaseIn TBA
โš›๏ธ curveEaseOut TBA
โš›๏ธ curveEaseInOut TBA
โš›๏ธ curveLinear TBA

Object Type: UIViewAnimateConfig
Name and Type Description
๐Ÿ”ค duration

โš›๏ธ number
TBA
๐Ÿ”ค delay

โš›๏ธ number
TBA
๐Ÿ”ค options

โš›๏ธ UIViewAnimateOptions[]
TBA

Object Type: MenuAuxiliaryPreviewBaseTransitionConfig

This type is an object tagged union type, with the transition property being the tag that separates the unions.

The table below defines the possible valid values that can be assigned to the type property (the subsequent tables are the different possible unions).

Name and Type Description
๐Ÿ”ค transition

โš›๏ธ string i.e. 'none' ยฆ 'fade'
'slide' ยฆ 'zoom' ยฆ 'zoomAndSlide'
TBA

Name and Type Description
๐Ÿ”ค transition

โš›๏ธ string i.e. none
TBA

Name and Type Description
๐Ÿ”ค transition

โš›๏ธ string i.e. fade
TBA

Name and Type Description
๐Ÿ”ค transition

โš›๏ธ string i.e. slide
TBA
๐Ÿ”ค slideOffset

โš›๏ธ number
TBA

Name and Type Description
๐Ÿ”ค transition

โš›๏ธ string i.e. zoom
TBA
๐Ÿ”ค zoomOffset

โš›๏ธ number
TBA

Name and Type Description
๐Ÿ”ค transition

โš›๏ธ string i.e. zoomAndSlide
TBA
๐Ÿ”ค slideOffset

โš›๏ธ number
TBA
๐Ÿ”ค zoomOffset

โš›๏ธ number
TBA

Object Union Type: MenuAuxiliaryPreviewTransitionConfig

This type is a union between the UIViewAnimateConfig object type, and the MenuAuxiliaryPreviewBaseTransitionConfig object type.

export type MenuAuxiliaryPreviewTransitionConfig = 
  | UIViewAnimateConfig
  | MenuAuxiliaryPreviewBaseTransitionConfig;

Mixed Union Type: MenuAuxiliaryPreviewTransitionEntranceDelay.
Name and Type Description
โš›๏ธ number TBA
โš›๏ธ RECOMMENDED TBA
โš›๏ธ AFTER_PREVIEW TBA

MenuIconConfig.ts


Object Type: IconConfig

This has been deprecated and will be removed in a future version. Use ImageItemConfig instead. For documentation regarding IconConfig, please see the documentation in the old README.


ImageItemConfig.ts


Object Type: ImageItemConfig

This type is an object tagged union type, with the type property being the tag that separates the unions. The table below defines the possible valid values that can be assigned to the type property.

Name and Type Description
๐Ÿ”ค Required: type

โš›๏ธ ImageItemConfigType string union, i.e. 'IMAGE_ASSET' ยฆ 'IMAGE_SYSTEM' ยฆ 'IMAGE_REQUIRE'
ยฆ 'IMAGE_EMPTY' ยฆ 'IMAGE_RECT' ยฆ 'IMAGE_GRADIENT'
ยฆ 'IMAGE_REMOTE_URL'
TBA

ImageItemConfig: IMAGE_ASSET
Name and Type Description
๐Ÿ”ค Required: type

โš›๏ธ string i.e 'IMAGE_ASSET'
TBA

๐Ÿ“Œ Maps to UIImage.init(named:) constructor in the apple docs.
๐Ÿ”ค Required: imageValue

โš›๏ธ string
TBA
๐Ÿ”ค imageOptions?

โš›๏ธ ImageOptions
TBA

ImageItemConfig: IMAGE_SYSTEM
Name and Type Description
๐Ÿ”ค Required: type

โš›๏ธ string i.e 'IMAGE_SYSTEM'
TBA

๐Ÿ“Œ Maps to UIImage.init(systemName:withConfiguration:) constructor in the apple docs.
๐Ÿ”ค Required: imageValue

โš›๏ธ ImageSystemConfig
TBA

๐Ÿ“Œ Maps to the withConfiguration argument label in the UIImage.init(systemName:withConfiguration:) constructor in the apple docs.
imageOptions

โš›๏ธ ImageOptions
TBA
๐Ÿ”ค imageLoadingConfig

โš›๏ธ ImageLoadingConfig
TBA

ImageItemConfig: IMAGE_EMPTY
Name and Type Description
๐Ÿ”ค Required: type

โš›๏ธ string i.e 'IMAGE_EMPTY'
TBA

ImageItemConfig: IMAGE_RECT
Name and Type Description
๐Ÿ”ค Required: type

โš›๏ธ string i.e 'IMAGE_RECT'
TBA

๐Ÿ“ Note: Programmatically creates an image using UIGraphicsImageRenderer.
๐Ÿ”ค Required: imageValue

โš›๏ธ ImageRectConfig
TBA

ImageItemConfig: IMAGE_GRADIENT
Name and Type Description
๐Ÿ”ค Required: type

โš›๏ธ string i.e 'IMAGE_GRADIENT'
TBA

๐Ÿ“ Note: Programmatically creates an image using UIGraphicsImageRenderer.
๐Ÿ”ค imageValue

โš›๏ธ ImageGradientConfig
TBA
imageOptions

โš›๏ธ ImageOptions
TBA

ImageItemConfig: IMAGE_REMOTE_URL
Name and Type Description
๐Ÿ”ค Required: type

โš›๏ธ string i.e 'IMAGE_REMOTE_URL'
TBA
๐Ÿ”ค imageValue

โš›๏ธ ImageRemoteUrlConfig
TBA
๐Ÿ”ค imageLoadingConfig

โš›๏ธ ImageLoadingConfig
TBA
imageOptions

โš›๏ธ ImageOptions
TBA

Object Type: ImageResolvedAssetSource

TBA

Name and Type Description
๐Ÿ”ค height

โš›๏ธ number
TBA
๐Ÿ”ค width

โš›๏ธ number
TBA
๐Ÿ”ค scale

โš›๏ธ number
TBA
๐Ÿ”ค uri

โš›๏ธ string
TBA

Object Type: ImageRectConfig

TBA

Name and Type Description
๐Ÿ”ค Required: width

โš›๏ธ number
TBA
๐Ÿ”ค Required: height

โš›๏ธ number
TBA
๐Ÿ”ค Required: fillColor

โš›๏ธ string
TBA
๐Ÿ”ค borderRadius?

โš›๏ธ number
TBA

Object Type: ImageGradientConfig

TBA

Name and Type Description
๐Ÿ”ค Required: width

โš›๏ธ number
TBA
๐Ÿ”ค Required: height

โš›๏ธ number
TBA
๐Ÿ”ค borderRadius?

โš›๏ธ number
TBA
๐Ÿ”ค Required: colors

โš›๏ธ Array<string>
TBA

๐Ÿ“Œ Maps to CAGradientLayer.colors property in the apple docs.
๐Ÿ”ค locations?

โš›๏ธ Array<number>
TBA

๐Ÿ“Œ Maps to CAGradientLayer.locations property in the apple docs.
๐Ÿ”ค startPoint?

โš›๏ธ Point ยฆ PointPreset

๐Ÿ“Œ Point
๐Ÿ“Œ PointPreset
TBA

๐Ÿ“Œ Maps to CAGradientLayer.startPoint property in the apple docs.
๐Ÿ”ค endPoint?

โš›๏ธ Point ยฆ PointPreset
๐Ÿ“Œ Point
๐Ÿ“Œ PointPreset
TBA

๐Ÿ“Œ Maps to CAGradientLayer.endPoint property in the apple docs.
๐Ÿ”ค type?

โš›๏ธ string i.e 'axial' ยฆ 'conic' ยฆ 'radial'
TBA

๐Ÿ“Œ Maps to CAGradientLayer.type property in the apple docs.

Object Type: ImageSystemConfig

TBA

Name and Type Description
๐Ÿ”ค Required: systemName

โš›๏ธ string
TBA

๐Ÿ“Œ Maps to the systemName argument label in the UIImage.init(systemName:withConfiguration:) constructor in the apple docs.
๐Ÿ”ค pointSize?

โš›๏ธ number
TBA

๐Ÿ“Œ Maps to UIImage.SymbolConfiguration.init(pointSize:) constructor in the apple docs.
๐Ÿ”ค weight?

โš›๏ธ ImageSymbolWeight
TBA

๐Ÿ“Œ Maps to UIImage.SymbolConfiguration.init(weight:) constructor in the apple docs.
๐Ÿ”ค scale?

โš›๏ธ ImageSymbolScale
TBA

๐Ÿ“Œ Maps to UIImage.SymbolConfiguration.init(scale:) constructor in the apple docs.
๐Ÿ”ค hierarchicalColor?

โš›๏ธ Array<string>
TBA

๐Ÿ“ Note A: Cannot be used at the same time with paletteColors (it's either one or the other).

๐Ÿ“ Note B: Requires iOS 15+.

๐Ÿ“Œ Maps to UIImage.SymbolConfiguration.init(hierarchicalColor:) constructor in the apple docs.
๐Ÿ”ค paletteColors?

โš›๏ธ string
TBA

๐Ÿ“ Note A: Cannot be used at the same time with hierarchicalColor (it's either one or the other).

๐Ÿ“ Note B: Requires iOS 15+.

๐Ÿ“Œ Maps to UIImage.SymbolConfiguration.init(paletteColors:) constructor in the apple docs.

Object Type: UIImageConfig

TBA

Name and Type Description
๐Ÿ”ค tint

โš›๏ธ stringย ยฆย DynamicColor
TBA
๐Ÿ”ค renderingMode

โš›๏ธ ImageRenderingModes
TBA

Object Union Type: ImageOptions

This type is a unioned with UIImageConfig object type, so it inherits its properties.

Name and Type Description
๐Ÿ”ค cornerRadius

โš›๏ธ number
TBA

Object Type: ImageRemoteUrlConfig

TBA

Name and Type Description
๐Ÿ”ค Required: url

โš›๏ธ string
TBA

Object Type: ImageLoadingConfig

TBA

Name and Type Description
๐Ÿ”ค shouldCache

โš›๏ธ boolean
TBA
๐Ÿ”ค shouldLazyLoad

โš›๏ธ boolean
TBA

Undocumented Types

TBA

Type Description
๐Ÿ“Œ Declaration: MenuEvents This file contains all the menu-related events and event objects.
๐Ÿ“Œ Declaration: MiscTypes.ts This file contains a bunch of types that haven't been categorized yet.

Contains: PointPreset, Point, DynamicColor, etc.
๐Ÿ“Œ Declaration: RNICleanupMode.ts TBA

D.5. Constants

Object: LIB_ENV

TBA


Type Description
๐Ÿ”ค isContextMenuButtonSupported

โš›๏ธ boolean
TBA
๐Ÿ”ค isContextMenuViewSupported

โš›๏ธ boolean
TBA



E. Usage And Examples

ContextMenuView Example 01

Summary: A basic context menu that has 3 menu action items (e.g. "Action #1", "Action #2", and "Action #3").


Notes
1๏ธโƒฃ โ€” The ContextMenuView.menuConfig prop accepts an optional MenuConfig object.
This object will be used to create and configure the context menu.
2๏ธโƒฃ โ€” You can set the context menu title via passing a string value to the MenuConfig.menuTitle property.

๐Ÿ“ Note: You can pass an empty string if you don't want a title to appear on top your context menu.
3๏ธโƒฃ โ€” To populate the context menu with action items, you can pass a MenuActionConfig object in the MenuConfig.menuItems property.

๐Ÿ“ Note A: The MenuConfig.menuItems property can accept an array of a MenuElementConfig union type.

To be more specific, the menuItems property can accept an array containing any of the following object types: MenuConfig object, MenuActionConfig, and DeferredMenuElementConfig.

๐Ÿ“ Note B: If you pass in a MenuConfig object in the MenuConfig.menuItems property, it means that you want to create a submenu. See ContextMenuView Example 03 for more details.

๐Ÿ“ Note C: If you pass in a DeferredMenuElementConfig object in the MenuConfig.menuItems property, it means that you want to create a deferred menu item (i.e. a menu item that has a loading indicator). See ContextMenuView Example 19 for more details.
4๏ธโƒฃ โ€” A MenuActionConfig object represents an action item in the context menu (e.g. copy, paste, delete, etc).

As such, if you pass in a MenuActionConfig object to MenuConfig.menuItems, it means that you want to create a context menu action.

๐Ÿ“ Note A: The MenuActionConfig.actionKey property serves as a unique identifier for your menu action. If you have multiple menu actions, the actionKey will help you differentiate them.

๐Ÿ“ Note B: You will receive the value you passed in MenuActionConfig.actionKey in the ContextMenuView.onPressMenuItem event (i.e. via the nativeEvent object).
5๏ธโƒฃ โ€” You can use the ContextMenuView.onPressMenuItem event prop to get notified whenever a menu action item has been selected.

The function you pass to the onPressMenuItem prop will receive a OnPressMenuItemEventObject object.

๐Ÿ“ Note A: Details about the selected menu action item can be accessed via the OnPressMenuItemEventObject.nativeEvent object.

E.g. OnPressMenuItemEventObject``.nativeEvent.actionKey.

๐Ÿ“ Note B: If ContextMenuView.shouldWaitForMenuToHide
BeforeFiringOnPressMenuItem prop is set to true (which it is by default), then this event will fire after the onMenuDidHide event is triggered.

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
import { ContextMenuView } from 'react-native-ios-context-menu';

export function ContextMenuViewExample01(props) {
  return (
    <ContextMenuView
      menuConfig={{
        // Note: If you don't want a menu title to appear for your
        // context menu, you can just pass in an empty string
        menuTitle: 'ContextMenuViewExample01',
        menuItems: [{
          actionKey  : 'key-01',
          actionTitle: 'Action #1',
        }, {
          actionKey  : 'key-02'   ,
          actionTitle: 'Action #2',
        }, {
          actionKey  : 'key-03'   ,
          actionTitle: 'Action #3',
        }],
      }}
      onPressMenuItem={({nativeEvent}) => {
        Alert.alert(
          'onPressMenuItem Event',
          `actionKey: ${nativeEvent.actionKey} - actionTitle: ${nativeEvent.actionTitle}`
        );
      }}
    >
      {/** Components */}
    </ContextMenuView>
  );
};

screenshot

Gif


ContextMenuView Example 02

Summary: Icon Example โ€” This examples shows how to add a system icon in the context menu action.


Notes
1๏ธโƒฃ โ€” A menu action (i.e. MenuActionConfig object) can be configured to show an icon via its MenuActionConfig.icon property.

๐Ÿ“ Note A: The icon property accepts a ImageItemConfig object.

๐Ÿ“ Note B: A ImageItemConfig object is used to describe images/assets (e.g. SF Symbols icons, images, xcasset images, programmatic images, etc).
2๏ธโƒฃ โ€” In this example, we want to use a "SF Symbols" icon for the menu action.

In order to do this, the ImageItemConfig.type property must be set to "IMAGE_SYSTEM".

๐Ÿ“ Note A: Passing in a value of "IMAGE_SYSTEM" to the type property means that we want to create a "SF Symbols" system icon.

๐Ÿ“ Note B: Using a "SF Symbols" icon requires iOS 13+.

๐Ÿ“ Note C: Via the ImageItemConfig object, you can also configure the context menu action to use other icons (e.g. xcasset items, images, gradients, solid colors, etc).

๐Ÿ“ Note D: You can apply a tint to the icon via the ImageItemConfig.imageOptions property using the UIImageConfig.tint and UIImageConfig.renderingMode property. See ContextMenuView Example 17 for more details.
3๏ธโƒฃ โ€” In order to configure what kind of "SF Symbols" icon we want to use for the menu action, we need to pass in a ImageSystemConfig object to the ImageItemConfig.imageValue property.

We can set what kind of icon to use via passing a string value to the ImageSystemConfig.systemName property.

๐Ÿ“ Note A: An ImageSystemConfig object is used to generate a "SF Symbols" image. Using this configuration object, we can optionally customize the "SF Symbols" icon further via the following properties: pointSize, weight, scale, hierarchicalColor, paletteColors, etc.

๐Ÿ“ Note B: The string value passed to the ImageSystemConfig.systemName property must be a valid SF Symbols name.

๐Ÿ“ Note C: To view the list of SF Symbols icons (along with their corresponding icon names), you'll need to download the SF Symbols Mac app from this page.

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
import { ContextMenuView } from 'react-native-ios-context-menu';

export function ContextMenuViewExample02(props) {
  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: 'ContextMenuViewExample02',
        menuItems: [{
          actionKey  : 'key-01',
          actionTitle: 'Action #1',
          icon: {
            type: 'IMAGE_SYSTEM',
            imageValue: {
              systemName: 'folder',
            },
          }
        }, {
          actionKey  : 'key-02'   ,
          actionTitle: 'Action #2',
          icon: {
            type: 'IMAGE_SYSTEM',
            imageValue: {
              systemName: 'dial.fill',
            },
          }
        }, {
          actionKey  : 'key-03'   ,
          actionTitle: 'Action #3',
          icon: {
            type: 'IMAGE_SYSTEM',
            imageValue: {
              systemName: 'archivebox.fill',
            },
          }
        }],
      }}
    >
      {/** Components */}
    </ContextMenuView>
  );
};

screenshot

Gif


ContextMenuView Example 03

Summary: Nested Menu โ€” This example shows a context menu that has a submenu item inside its list of menu actions.


Notes
1๏ธโƒฃ โ€” A context menu supports having nested menu's (i.e. submenu's).

A submenu is basically just another menu with it's own separate list of menu actions. Tapping it will show another context menu (visually this is similar to a dropdown menu).
2๏ธโƒฃ โ€” As mentioned in the earlier examples, the MenuConfig.menuItems property can accept a MenuActionConfig object, or a MenuConfig object.

Passing in a MenuActionConfig object to MenuConfig.menuItems makes a menu action, conversely passing in a MenuConfig object will create a submenu item.

In other words, to make a submenu, you just need to pass a MenuConfig item in the MenuConfig.menuItems property.

๐Ÿ“ Note: You can nest as many submenu's you want (but just remember that having more than 3 nested submenus is considered bad UX).

๐Ÿ”— Full Example

 // ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
import { ContextMenuView } from 'react-native-ios-context-menu';

export function ContextMenuViewExample03(props) {
  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: 'ContextMenuViewExample03',
        menuItems: [{
          actionKey  : 'key-01',
          actionTitle: 'Action #1',
          icon: {
            type: 'IMAGE_SYSTEM',
            imageValue: {
              systemName: 'folder',
            },
          }
        }, {
          menuTitle: 'Submenu...',
          menuItems: [{
            actionKey  : 'key-01-01',
            actionTitle: 'Submenu Action #1',
            icon: {
              type: 'IMAGE_SYSTEM',
              imageValue: {
                systemName: 'star',
              },
            }
          }, {
            actionKey  : 'key-01-02',
            actionTitle: 'Submenu Action #2',
            icon: {
              type: 'IMAGE_SYSTEM',
              imageValue: {
                systemName: 'star.lefthalf.fill',
              },
            }
          }, {
            actionKey  : 'key-01-03',
            actionTitle: 'Submenu Action #3',
            icon: {
              type: 'IMAGE_SYSTEM',
              imageValue: {
                systemName: 'star.fill',
              },
            }
          }]
        }],
      }}
    >
      {/** Components */}
    </ContextMenuView>
  );
};

screenshot

Gif


ContextMenuView Example 04

Summary: Menu Attributes โ€” This example context menu showcases the MenuActionConfig.menuAttributes property.


Notes
1๏ธโƒฃ โ€” The MenuActionConfig.menuAttributes property accepts an array of strings (i.e. an array of MenuAttributes items).

In this example, the context menu has 3 actions, each with a different menu attribute assigned to it.

The first menu action is a "disabled" action, i.e. it has it's menuAttributes set to ['disabled'], causing the action title text and icon becomes greyed out.
2๏ธโƒฃ โ€” The second menu action is a destructive action.

It has it's menuAttributes set to ['destructive'], causing the action title text and icon becomes red.
3๏ธโƒฃ โ€” The third menu action is a "hidden" action. It has it's menuAttributes set to ['hidden'].

The menu action is not visible in the menu's list of actions. This is useful for temporarily hiding a menu action item.
4๏ธโƒฃ โ€” The fourth menu action is a "disabled" + "destructive" action.
Visually, it looks very similar to an action that has the ['disabled'] attribute.

๐Ÿ”— Full Example

 // ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
import { ContextMenuView } from 'react-native-ios-context-menu';

export function ContextMenuViewExample04(props) {
  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: 'ContextMenuViewExample04',
        menuItems: [{
          actionKey     : 'key-01',
          actionTitle   : 'Disabled Action',
          menuAttributes: ['disabled'],
          icon: {
            type: 'IMAGE_SYSTEM',
            imageValue: {
              systemName: 'folder',
            },
          }
        }, {
          actionKey     : 'key-02'   ,
          actionTitle   : 'Destructive Action',
          menuAttributes: ['destructive'],
          icon: {
            type: 'IMAGE_SYSTEM',
            imageValue: {
              systemName: 'trash',
            },
          }
        }, {
          actionKey     : 'key-03'   ,
          actionTitle   : 'Hidden Action',
          menuAttributes: ['hidden'],
          icon: {
            type: 'IMAGE_SYSTEM',
            imageValue: {
              systemName: 'trash',
            },
          }
        }, {
          actionKey     : 'key-04'   ,
          actionTitle   : 'Disabled/Destructive',
          menuAttributes: ['disabled', 'destructive'],
          icon: {
            type: 'IMAGE_SYSTEM',
            imageValue: {
              systemName: 'trash.fill',
            },
          }
        }],
      }}
    >
      {/** Components */}
    </ContextMenuView>
  );
};

screenshot

Gif


ContextMenuView Example 05

Summary: Nested Menu + Menu Attributes โ€” A context menu that has a in-line submenu.


Notes
You can set the menu options via the MenuConfig.menuOptions property. It accepts an array of UIMenuOptions strings (e.g. 'destructive', 'displayInline').

If you pass in ['displayInline'] to menuOptions, the submenu will be added/combined to its parent menu, but with a small separator between them.

๐Ÿ”— Full Example

 // ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
import { ContextMenuView } from 'react-native-ios-context-menu';

export function ContextMenuViewExample05(props) {
  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: 'ContextMenuViewExample03',
        menuItems: [{
          actionKey  : 'key-01',
          actionTitle: 'Action #1',
          // ...
        }, {
          menuTitle: 'Submenu...',
          // Create an "Inline submenu" by adding `displayInline`
          // in the menu options...
          menuOptions: ['displayInline'],
          menuItems: [{
            actionKey  : 'key-01-01',
            actionTitle: 'Submenu Action #1',
            // ...
          }, {
            actionKey  : 'key-01-02',
            actionTitle: 'Submenu Action #2',
            // ...
          }, {
            actionKey  : 'key-01-03',
            actionTitle: 'Submenu Action #3',
            // ...
          }]
        }],
      }}
    >
      {/** Components */}
    </ContextMenuView>
  );
};

screenshot

Gif


ContextMenuView Example 06

Summary: Menu Options โ€” A context menu that has a destructive submenu.


Notes
You can set the menu options via the MenuConfig.menuOptions property. It accepts an array of UIMenuOptions strings (e.g. destructive, displayInline).

If you pass in ['destructive'] to menuOptions, it will tint the submenu to red (but it's menu items won't be affected).

๐Ÿ”— Full Example

 // ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
import { ContextMenuView } from 'react-native-ios-context-menu';

export function ContextMenuViewExample06(props) {
  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: 'ContextMenuViewExample06',
        menuItems: [{
          actionKey  : 'key-01',
          actionTitle: 'Action #1',
          // ...
        }, {
          menuTitle: 'Submenu...',
          // Create an "destructive" submenu by adding
          // `destructive` in the menu options...
          menuOptions: ['destructive'],
          menuItems: [{
            actionKey  : 'key-01-01',
            actionTitle: 'Submenu Action #1',
            // ...
          }, {
            actionKey  : 'key-01-02',
            actionTitle: 'Submenu Action #2',
            // ...
          }, {
            actionKey  : 'key-01-03',
            actionTitle: 'Submenu Action #3',
            // ...
          }]
        }],
      }}
    >
      {/** Components */}
    </ContextMenuView>
  );
};

screenshot

Gif


ContextMenuView Example 07

Summary: Menu Options โ€” A context menu that set to be both "destructive" and "display in-line".


Notes
You can set the menu options via the MenuConfig.menuOptions property. It accepts an array of UIMenuOptions strings (e.g. destructive, displayInline).

Passing in ['destructive', 'displayInline'] to menuOptions, is functionally the same as passing in ['displayInline'].

๐Ÿ”— Full Example

 // ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
import { ContextMenuView } from 'react-native-ios-context-menu';

export function ContextMenuViewExample07(props) {
  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: 'ContextMenuViewExample07',
        menuItems: [{
          actionKey  : 'key-01',
          actionTitle: 'Action #1',
          // ...
        }, {
          menuTitle: 'Submenu...',
          // Make the submenu both `'displayInline'` and
          // `'destructive'`.
          //
          // Visually, this is just the same as passing in 
          // 'displayInline'.
          menuOptions: ['displayInline', 'destructive'],
          menuItems: [{
            actionKey  : 'key-01-01',
            actionTitle: 'Submenu Action #1',
            // ...
          }, {
            actionKey  : 'key-01-02',
            actionTitle: 'Submenu Action #2',
            // ...
          }, {
            actionKey  : 'key-01-03',
            actionTitle: 'Submenu Action #3',
            // ...
          }]
        }],
      }}
    >
      {/** Components */}
    </ContextMenuView>
  );
};

screenshot

Gif


ContextMenuView Example 08

Summary: Menu State โ€” A context menu with 3 actions that has 'on', 'off', and 'mixed' menuState.


Notes
You can set an menu action item's the menu state via the MenuActionConfig.menuState property.

๐Ÿ“ Note: On iOS 13, an action item's menu state is indicated via changing it's icon to a checkmark. However on later version of iOS this behavior has been changed to showing a checkmark besides the action title (see gifs/screenshots below).

๐Ÿ”— Full Example

 // ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
import { ContextMenuView } from 'react-native-ios-context-menu';

export function ContextMenuViewExample08(props) {
  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: 'ContextMenuViewExample08',
        menuItems: [{
          actionKey  : 'key-01',
          actionTitle: 'menuState: on',
          // show a checkmark
          menuState: 'on',
          // ...
        }, {
          actionKey  : 'key-02'   ,
          actionTitle: 'menuState: off',
          // no checkmark
          menuState: 'off',
          // ...
        }, {
          actionKey  : 'key-03'   ,
          actionTitle: 'menuState: mixed',
          // visually this is the same as 'on'
          menuState: 'mixed',
          // ...
        }],
      }}
    >
      {/** Components */}
    </ContextMenuView>
  );
};

screenshot

Gif


ContextMenuView Example 09

Summary: Events โ€” An example for the onPressMenuItem event prop.

Notes
The onPressMenuItem event prop allows you to know which menu item was pressed via the nativeEvent.actionKey property in the event object.

๐Ÿ“ Note A: The entire menu action config (i.e. MenuActionConfig) object of the selected item can be accessed via the nativeEvent object (e.g. nativeEvent.actionTitle, nativeEvent.menuState, etc).

๐Ÿ“ Note B: For the full type declaration for all the events, see: MenuEvents.ts.

๐Ÿ”— Full Example

 // ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
import { ContextMenuView } from 'react-native-ios-context-menu';

export function ContextMenuViewExample09(props) {
  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: 'ContextMenuViewExample09',
        menuItems: [{
          actionKey  : 'save',
          actionTitle: 'Save',
          // ...
        }, {
          actionKey  : 'like',
          actionTitle: 'Like',
          // ...
        }, {
          actionKey  : 'play',
          actionTitle: 'Play',
          // ...
        }],
      }}
      // Use `actionKey` to identify which menu action was
      // pressed....
      onPressMenuItem={({nativeEvent}) => {
        switch (nativeEvent.actionKey) {
          case 'save':
            Alert.alert('saving...');
            break;

          case 'like':
            Alert.alert('liking...');
            break;

          case 'play':
            Alert.alert('playing...');
            break;
        };
      }}
    >
      {/** Components */}
    </ContextMenuView>
  );
};

screenshot

Gif


ContextMenuView Example 10

Summary: Dynamic Menu โ€” An example showing how to dynamically update the context menu while it's visible. In this example, the menu action changes every time the counter increments every second.


Notes
On iOS 14+ you can update the menu while it's visible, e.g. like adding and removing items in the context menu, or changing the action title, etc.

You can control the context menu config using state, and dynamically change it as shown in the example below.

๐Ÿ“ Note A: On iOS 13 the context menu will not update while it's visible.

๐Ÿ“ Note B: On iOS 15+, all changes to the context menu config are applied using a fade/crossfade transition.

๐Ÿ”— Full Example

 // ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuViewExample10(props) {
  // `timer` will increment every second... 
  const [timer, setTimer] = React.useState(0);

  // ...
  return (
    <ContextMenuView
      // ...
      menuConfig={{
        menuTitle: 'ContextMenuViewExample10',
        menuItems: [{
          actionKey  : 'key-00',
          actionTitle: `Static Action`,
          // ...
        }, {
          actionKey  : 'key-01',
          // update the action title every second...
          actionTitle: `timer: ${timer}`,
          icon: {
            type: 'IMAGE_SYSTEM',
            imageValue: {
               // update the icon every second...
              systemName: ((timer % 2 === 0)
                ? 'heart'
                : 'heart.fill'
              ),
            },
          }
        }, 
        // this item will be added and removed...
        (timer % 3 === 0) && {
          actionKey  : 'key-02',
          actionTitle: `Dynamic Action`,
          // ...
        }],
      }}
    >
      {/** Components */}
    </ContextMenuView>
  );
};

screenshot

Gif


ContextMenuView Example 11

Summary: Context Menu Previews โ€” An example showing how to use a custom preview for the context menu.


Notes
1๏ธโƒฃ โ€” The ContextMenuView.renderPreview render prop allows you show a custom preview when the context menu appears.

๐Ÿ“ Note: The renderPreview prop accepts a function that returns an element. The returned element will be shown inside the context menu preview.
2๏ธโƒฃ โ€” The ContextMenuView.previewConfig is used to control the behavior and appearance of the custom context menu preview.

In order to show the custom context menu preview, we must first set MenuPreviewConfig.previewType to 'CUSTOM'. By default, this property is set to 'DEFAULT', which means that you do not want to use a custom preview.

๐Ÿ“ Note A: The previewConfig prop accepts a MenuPreviewConfig object.

๐Ÿ“ Note B: The previewType property accepts a MenuPreviewType string. You can set this to 'DEFAULT' if you want to quickly disable the custom preview.
3๏ธโƒฃ โ€” In this example, we want the custom preview to be as big as possible, so we set the MenuPreviewConfig.previewSize property to 'STRETCH'.

๐Ÿ“ Note: The previewSize property accepts a MenuPreviewSize string. By default, this prop is set to 'INHERIT', which means to just match the size of the root view returned from renderPreview.

๐Ÿ”— Full Example

 // ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
import { ContextMenuView } from 'react-native-ios-context-menu';

export function ContextMenuViewExample11(props) {
  return (
    <ContextMenuView
      previewConfig={{
        previewType: 'CUSTOM',
        previewSize: 'STRETCH',
        backgroundColor: 'white'
      }}
      renderPreview={() => (
        <View>
          <Text>
            Hello World
          </Text>
          <Text>
            Hello World
          </Text>
          <Text>
            Hello World
          </Text>
        </View>
      )}
      onPressMenuPreview={() => {
        Alert.alert(
          'onPressMenuPreview Event',
          `Menu preview was pressed...`
        );
      }}
    >
      {/** Components */}
    </ContextMenuView>
  );
};

screenshot

Gif


ContextMenuView Example 12

Summary: Context Menu Previews โ€” An example showing a custom context menu preview that dynamically changes its size due to its contents updating every second.


Notes
๐Ÿ“ Note: By default, custom preview will animate to its new size. If you want to disable this behavior, set MenuPreviewConfig.isResizeAnimated property to false.

๐Ÿ”— Full Example

 // ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...

export function ContextMenuViewExample12(props) {
  // increments every second...
  const [timer, setTimer] = React.useState(0);

	// ...
  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: 'ContextMenuViewExample12',
        menuItems: [{
          // ...
        }],
      }}
      previewConfig={{
        previewType: 'CUSTOM',
        backgroundColor: 'white'
      }}
      // The context menu preview grows and shrinks due to the labels/
      // text changing every second...
      renderPreview={() => (
        <View>
          <Text>
            {`Counter: ${timer}`}
          </Text>
          <Text>
            {(timer % 2 === 0)? 'EVEN' : 'The number is: ODD'}
          </Text>
        </View>
      )}
      // ...
    >
      {/** Components */}
    </ContextMenuView>
  );
};

screenshot

Gif


ContextMenuView Example 13

Summary: Menu Action โ€” An example showing how to add a subtitle to menu action.


Notes
You can add a subtitle to a menu action via passing a string value to the MenuActionConfig.actionSubtitle property.

๐Ÿ“ Note A: On iOS 13/14, you add subtitles to the menu action via the MenuActionConfig.discoverabilityTitle property, but on iOS 15+ this property is now used for the "discoverability heads-up display" UI.

๐Ÿ“ Note B: For backwards compatibility, the string value you passed to discoverabilityTitle will also be used to set actionSubtitle on iOS 15+.

To disable this automatic behavior, set the ContextMenuView.shouldUseDiscoverability TitleAsFallbackValueForSubtitle prop to false.

๐Ÿ”— Full Example

 // ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
import { ContextMenuView } from 'react-native-ios-context-menu';

export function ContextMenuViewExample13(props) {
  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: 'ContextMenuViewExample13',
        menuItems: [{
          actionKey: 'key-01',
          actionTitle: 'Action #1',
          // old way of adding a subtitle...
          // iOS 13 to 14 (still works on iOS 15+)
          discoverabilityTitle: 'Action subtitle',
        }, {
          actionKey: 'key-02'   ,
          actionTitle: 'Action #2',
          // new way of adding a subtitle...
          // iOS 15+ only, but is automatically backwards compatible w/
          // iOS 13/14...
          actionSubtitle: 'Lorum ipsum sit amit dolor aspicing',
        }, {
          actionKey: 'key-03'   ,
          actionTitle: 'Action #3',
          actionSubtitle: 'Very long `discoverabilityTitle` lorum ipsum sit amit',
        }],
      }}
    >
      {/** Components */}
    </ContextMenuView>
  );
};

screenshot

Gif


ContextMenuView Example 14

Summary: Context Menu Previews โ€” An example that changes the exit transition of the context menu preview when its tapped using the preferredCommitStyleย  config.


Notes
The MenuPreviewConfig.preferredCommitStyle allows you to configure what preset exit transition to use when the context menu preview is pressed.

๐Ÿ“ Note A: By default, MenuPreviewConfig.preferredCommitStyle is set to 'dismiss'.

๐Ÿ“ Note B: A preferredCommitStyle of 'pop'' is usually used when navigating to another screen (i.e. a view controller is pushed without the normal push transition).

๐Ÿ”— Full Example

 // ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuViewExample14(props) {
  return (
    <ContextMenuView
      previewConfig={{
        previewType: 'CUSTOM',
        previewSize: 'STRETCH',
        backgroundColor: 'rgba(255,255,255,0.75)',
	      // change the exit transition that occurs when the 
        // context menu preview is pressed.
        preferredCommitStyle: 'pop',
      }}
      renderPreview={() => (
        {/** ... */}
      )}
    >
      {/** Components */}
    </ContextMenuView>
  );
};

screenshot

Gif


ContextMenuView Example 15

Summary: Context Menu Previews โ€” An example showing how to configure a context menu that uses targeted previews.


Notes
By default, the child elements you render inside the ContextMenuView component will be used as the preview when the context menu interaction is triggered.

Targeted previews allows you to specify which specific view to use for the context menu preview, so that when the context menu interaction begins, a different view will be used for the preview (including the initial transition, see the gif below the example code).

๐Ÿ“ Note A: The context menu interaction will still be triggered by long pressing on the child elements in the ContextMenuView component.

As such, if the view that you are using for the targeted preview is not a child of ContextMenuView, then holding down on that view will not trigger the context menu interaction.

๐Ÿ“ Note B: Targeted previews is different from setting a custom context menu preview via the renderPreview prop.

A custom preview will replace the contents of the context menu preview entirely with your custom view component once the menu is opened.

A targeted preview on the other hand will change which view to use for the context menu entrance/exit transition (as well as what view to show in the preview if you do not have a custom preview).

๐Ÿ”— Full Example

 // ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
import { ContextMenuView } from 'react-native-ios-context-menu';

export function ContextMenuViewExample15(props) {
  const [targetViewNode, setTargetViewNode] = React.useState();
  
  React.useEffect(() => {
    // please note that when a view unmounts and remounts (e.g.
    // when you have a view inside a list comp)., you need to
    // get the new associated `reactTag` for that view
    //
    // otherwise the `reactTag` value you provide to the 
    // `previewConfig` will be stale...
    //
    // this is why we have to set `targetViewNode` back to 
    // `udefined` when the component unmounts
    return () => {
      setTargetViewNode(undefined);
    }
  }, []);

  return (
    <ContextMenuView
      menuConfig={{
        // ...
      }}
      previewConfig={{
        // specify which view to use as the preview target
        targetViewNode: targetViewNode,
      }}
    >
      <View
        style={styles.targetContainer}
        // we need to get the `reactTag` of the view; one way is
        // to get it from the `onLayout` event
        //
        // alternatively, you can also obtain the `reactTag` of a  
        // a view via: `nativeViewRef?.nativeTag`
        //
        // the `reactTag` for a given view is the same across re-renders,
        // so we only really need to get it once when the view mounts...
        //
        onLayout={!targetViewNode && (({nativeEvent}) => {
          setTargetViewNode(nativeEvent.target)
        })}
      >
        <Text style={styles.text}>
          {`Hello! Target Node: ${targetViewNode}`}
        </Text>
      </View>
    </ContextMenuView>
  );
};

screenshot

Gif


ContextMenuView Example 15-02

Summary: Context Menu Previews (Cont). โ€” An example showing how to configure a context menu that uses targeted previews + WrapperView.


๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
import { ContextMenuView } from 'react-native-ios-context-menu';
import { WrapperView } from 'react-native-ios-utilities';

export function ContextMenuViewExample15_02(props) {
  // save a ref. to the `WrapperView` element containing the preview target you 
  // want to use for the context menu.
  //
  // you can then call `getNativeReactTag` to get the associated `reactTag`
  // for that view. 
  const wrapperViewRef = React.useRef();

  return (
    <ContextMenuView
      menuConfig={{
        // ...
      }}
      previewConfig={{
        // get the associated `reactTag` of the view element you want use as the 
        // preview target
        targetViewNode: wrapperViewRef.current?.getNativeReactTag(),
      }}
    >
      <WrapperView
        ref={wrapperViewRef}
        style={styles.targetContainer}
      >
        <Text style={styles.text}>
          {`Hello inside: WrapperView\nTarget Node: ${wrapperViewRef.current?.getNativeReactTag()}`}
        </Text>
      </WrapperView>
    </ContextMenuView>
  );
};

screenshot


ContextMenuView Example 16

Summary: Icon Example โ€” An example showing a context menu with an action that uses a 'IMAGE_ASSET' image for its icon.


Notes
A config of ImageItemConfig.type set to 'IMAGE_ASSET' means that you want to use a xcasset image asset.

๐Ÿ“ Note: The string value you pass to the ImageItemConfig.imageValue must match the corresponding asset that you want to use in your project's xcasset catalog.

๐Ÿ”— Full Example

 // ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
import { ContextMenuView } from 'react-native-ios-context-menu';

export function ContextMenuViewExample16(props) {
  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: 'ContextMenuViewExample16',
        menuItems: [{
          actionKey: 'key-01',
          actionTitle: 'Action #1',
          // ...
        }, {
          actionKey: 'key-02'   ,
          actionTitle: 'Action #2',
          // ...
        }, {
          actionKey  : 'key-03'   ,
          actionTitle: 'Action #3',
          discoverabilityTitle: 'Use "ASSET" icon',
          icon: {
            // specify that you want to use an asset icon
            type: 'IMAGE_ASSET',
            // pass the name of the asset
            imageValue: 'icon-rainbow-flag',
          }
        }],
      }}
    >
      {/** Components */}
    </ContextMenuView>
  );
};

screenshot

Gif


ContextMenuView Example 17

Summary: Icon Example โ€” An example showing a context menu with action items that have different colored icons.


Notes
A ImageItemConfig object has an optional called imageOptions. This property accepts a UIImageConfig object.

You can tint the image to a specified color using the UIImageConfig.tint property. This property accepts a color string in either rgb, rgba, or hex format.

You can also choose to provide a dynamic color config if you want to use a specific color for light/dark mode.

๐Ÿ“ Note A: Any image can be tinted to a specific color, not just 'IMAGE_SYSTEM' images.

๐Ÿ“ Note B: In order for the tint to take effect, set UIImageConfig.renderingMode to alwaysOriginal.

๐Ÿ”— Full Example

 // ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
import { ContextMenuView } from 'react-native-ios-context-menu';

export function ContextMenuViewExample17(props) {
  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: 'ContextMenuViewExample17',
        menuItems: [{
          actionKey  : 'key-01',
          actionTitle: 'Action #1',
          icon: {
            type: 'IMAGE_SYSTEM',
            imageValue: {
              systemName: 'cloud.heavyrain.fill',
            },
            // blue icon
            imageOptions: {
              tint: 'blue',
              renderingMode: 'alwaysOriginal',
            },
          },
        }, {
          actionKey  : 'key-02',
          actionTitle: 'Action #2',
          icon: {
            // ...
            // orange icon
            imageOptions: {
              tint: 'rgb(218,165,32)',
              renderingMode: 'alwaysOriginal',
            },
          },
        }, {
          actionKey  : 'key-03',
          actionTitle: 'Action #3',
          icon: {
            // ...
            // pink icon
            imageOptions: {
              tint: '#FF1493',
              renderingMode: 'alwaysOriginal',
            },
          },
        }, {
          actionKey  : 'key-04',
          actionTitle: 'Action #4',
          icon: {
            // ...
            // green icon
            imageOptions: {
              tint: 'rgba(124,252,0,0.5)',
              renderingMode: 'alwaysOriginal',
            },
          },
        }]
      }}
    >
      {/** Components */}
    </ContextMenuView>
  );
};

screenshot

Gif


ContextMenuView Example 18

Summary: Icon Example โ€” An example showing a context menu with action items that has icons that uses local image assets imported via require(...).


Notes
1๏ธโƒฃ โ€” The first step that we need to do is to generate a ImageResolvedAssetSource object of the local image asset we want to use. This object contains metadata about the image as well as its URI in the file system.

The Image.resolveAssetSource function returns a ImageResolvedAssetSource that corresponds to the source argument you pass into it. Give this function the return value of require(path/to/image.png).
2๏ธโƒฃ โ€” A config of ImageItemConfig.type set to 'IMAGE_REQUIRE' means that we want to use a local image asset imported via the require(...) function.

The ImageItemConfig.imageValue property accepts a ImageResolvedAssetSource object that corresponds to the image asset that you want to use.

๐Ÿ”— Full Example

 // ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
import { ContextMenuView } from 'react-native-ios-context-menu';

// Generate a `ImageResolvedAssetSource` object based on the
// image assets...

const iconA = Image.resolveAssetSource(
  require('../assets/emoji-pleading-face.png')
);

const iconB = Image.resolveAssetSource(
  require('../assets/emoji-smiling-face-with-hearts.png')
);

const iconC = Image.resolveAssetSource(
  require('../assets/emoji-sparkling-heart.png')
);

export function ContextMenuViewExample18(props) {
  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: 'ContextMenuViewExample18',
        menuItems: [{
          actionKey  : 'key-01'   ,
          actionTitle: 'Action #1',
          discoverabilityTitle: 'Use "REQUIRE" icon',
          // `IconConfig` has been deprecated, please use 
          // `ImageItemConfig` instead (but it'll still work 
          // for now).
          // 
          // The other two menu actions in this example 
          // uses `ImageItemConfig` to set the menu action icons. 
          icon: {
            iconType: 'REQUIRE',
            iconValue: iconA,
          }
        }, {
          actionKey: 'key-02'   ,
          actionTitle: 'Action #2',
          
          // Set config to use images via `require`
          type: 'IMAGE_REQUIRE',
          
          // Pass in the corresponding
          // `ImageResolvedAssetSource` object of the image
          // that you want to use as the icon...
          imageValue: iconB,
        }, {
          actionKey: 'key-03'   ,
          actionTitle: 'Action #3',
          icon: {
            type: 'IMAGE_REQUIRE',
            imageValue: iconC,
          }
        }],
      }}
    >
      {/** Components */}
    </ContextMenuView>
  );
};

screenshot

Gif


ContextMenuView Example 19

Summary: Dynamic Menu โ€” An example showing a context menu that shows a loading indicator using deferred menu elements.


Notes
1๏ธโƒฃ โ€” If you control your ContextMenuView.menuConfig via state, then you can already dynamically add menu items while the context menu is visible (See ContextMenuView Example 10). However, there is no indication in the UI that items are currently being loaded.

You can use a "deferred element" in order to add an action item that has a loading indicator. Once you are done loading the content, then you can replace the deferred element with the actual menu items that you want to add.

๐Ÿ“ Note: Deferred elements are only available on iOS 14 and above.
2๏ธโƒฃ โ€” As mentioned in the previous examples, the MenuConfig.menuItems property can accept an array of MenuElementConfig union type. This means that it can accept an array containing any of the following object types: MenuConfig object, MenuActionConfig, and DeferredMenuElementConfig.

If we pass in a DeferredMenuElementConfig to menuItems, it means that we want to create "deferred element" item.
3๏ธโƒฃ โ€” To create a deferred element, we just need to create a "config" object that has a property containing both type and deferredID.

The DeferredMenuElementConfig.type property must be set to a string value of 'deferred'. This indicates that we want to create a deferred element.

The DeferredMenuElementConfig.deferredID property must be set to a unique string value. Since we can have multiple deferred elements, the value you pass into this property will be used to identify which deferred element will be replaced with the menu items you want to add when the loading is complete.
4๏ธโƒฃ โ€” Once the context menu is open, any deferred menu items in MenuConfig.menuItems will trigger the ContextMenuView.onRequestDeferredElement event to fire. Via the event, you will receive two arguments: deferredID string and provider callback function.

The deferredID string corresponds to which deferred element that we need to load, while the provider callback function is used to provide the menu items that we want to add and replace the deferred element with.
5๏ธโƒฃ โ€” The provider callback function accepts an array of MenuElementConfig items.

To replace the deferred element with the menu items you want add, simply call the provider callback function with the array of MenuConfig, MenuActionConfig, or DeferredMenuElementConfig objects.

๐Ÿ“ Note A: Since the deferred elements were loaded/replaced using the onRequestDeferredElement event, there are now two sources of truths for the context menu config: One provided via the ContextMenuView.menuConfig prop, and the other via the onRequestDeferredElement event.

If you are using a state-controlled menu config, see: ContextMenuView Example 20.

๐Ÿ“ Note B: It is recommended that you cache the items you have loaded, and then combine them with the existing menuConfig once the menu has been closed.

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuViewExample19(props) {
  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: 'ContextMenuViewExample19',
        menuItems: [{
          actionKey  : 'key-01',
          actionTitle: 'Action #1',
          actionSubtitle: 'Dummy action'
        }, {
          // Create a deferred menu item... 
          // this will act as a placeholder and will be replaced
          // with the actual menu items later
          type: 'deferred',
          
          // if we have multiple deferred items, you can use 
          // the `deferredID` to distinguish between them
          deferredID: 'deferred-01'
        }],
      }}
      
      // this event will fire when a deferred menu item 
      // is present...
      onRequestDeferredElement={async (deferredID, provider) => {
        switch(deferredID) {
          case 'deferred-01':
            // dummy delay, wait for 1 second...
            await Helpers.timeout(1000);

            // provide the items to add to the context menu...
            provider([{
              type: 'action',
              actionKey: 'action-02',
              actionTitle: 'Deferred Item 02',
              actionSubtitle: 'Deferred item...'
            }, {
              type: 'action',
              actionKey: 'action-03',
              actionTitle: 'Deferred Item 03',
              actionSubtitle: 'Deferred item...'
            }]);
            break;
        };
      }}
    >
      {/** ... */}
    </ContextMenuView>
  );
};

example-ContextMenuViewExample19

example-ContextMenuViewExample19


ContextMenuView Example 20

Summary: Dynamic Menu โ€” An example showing a state-controlled context menu that shows a loading indicator using deferred menu elements.


Notes
TBA

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuViewExample20(props) {
  const [extraMenuItems, setExtraMenuItems] = React.useState([]);

  const [isLoading, setIsLoading] = React.useState(true);
  const [didLoadItems, setDidLoadItems] = React.useState(false);

  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: 'ContextMenuViewExample20',
        menuItems: [{
          actionKey  : 'key-01',
          actionTitle: 'Action #1',
          actionSubtitle: 'Dummy action'
        },

        // add deferred item so that the loading indicator
        // appears...
        isLoading && ({
          type: 'deferred',
          deferredID: 'deferred-01'
        }), 

        // add the extra menu items...
        ...extraMenuItems,

        didLoadItems && ({
          type: 'menu',
          menuTitle: '',
          menuOptions: ['displayInline'],
          menuItems: [{
            type: 'action',
            actionKey: 'clear_cache',
            actionTitle: 'Clear Cache',
            actionSubtitle: 'Remove loaded items...',
            menuAttributes: ['destructive'],
          }]
        })],
      }}
      // this event will fire when a deferred menu item is present...
      onMenuWillShow={async () => {
        if(didLoadItems) return;

        // for the purposes of this example, let's add a delay
        // before showing the loading indicator...
        // 
        // this way, we can see the context menu updating and
        // showing the loading indicator.
        // 
        // Ideally, `isLoading` should already be set to `true`
        // before the context menu is shown...
        await Helpers.timeout(750);
        setIsLoading(true);

        // loading...
        // dummy delay, wait for 2 second...
        await Helpers.timeout(2000);
        setDidLoadItems(true);

        // add extra menu items
        setExtraMenuItems([{
          type: 'action',
          actionKey: 'action-02',
          actionTitle: 'Deferred Item 02',
          actionSubtitle: 'Deferred item...'
        }, {
          type: 'action',
          actionKey: 'action-03',
          actionTitle: 'Deferred Item 03',
          actionSubtitle: 'Deferred item...'
        }]);

        // hide the loading indicator
        setIsLoading(false);
      }}
    >
      {/** ... */}
    </ContextMenuView>
  );
};

example-ContextMenuViewExample20

example-ContextMenuViewExample20


ContextMenuView Example 21

Summary: Menu Element Size โ€” TBA


Notes
TBA

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuViewExample21(props) {

  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: 'ContextMenuViewExample21',
        menuPreferredElementSize: 'medium',
        menuItems: [{
          actionKey: 'key-01',
          actionTitle: 'Action #1',
          // ...
        }, {
          actionKey: 'key-02'   ,
          actionTitle: 'Action #2',
          // ...

        }, {
          actionKey  : 'key-03'   ,
          actionTitle: 'Action #3',
          // ...
        }],
      }}
    >
      {/** ... */}
    </ContextMenuView>
  );
};

example-ContextMenuViewExample21

example-ContextMenuViewExampleXX


ContextMenuView Example 22

Summary: Menu Element Size โ€” TBA


Notes
TBA

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuViewExample22(props) {

  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: '',
        menuPreferredElementSize: 'small',
        menuItems: [{
          actionKey: 'key-01',
          actionTitle: '',
          // ...
        }, {
          actionKey: 'key-02'   ,
          actionTitle: '',
          // ...
          }
        }, {
          actionKey: 'key-03',
          actionTitle: '',
          // ...
        }],
      }}
    >
      {/** ... */}
    </ContextMenuView>
  );
};

example-ContextMenuViewExample22

example-ContextMenuViewExampleXX


ContextMenuView Example 23

Summary: Menu Element Size โ€” TBA


Notes

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuViewExample23(props) {

  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: '',
        menuItems: [{
          type: 'action',
          actionKey: 'remove-rating',
          menuAttributes: ['destructive'],
          actionTitle: 'Remove Rating',
           icon: { /** ... */ }
        }, {
          type: 'action',
          actionKey: 'info',
          actionTitle: 'Information',
           icon: { /** ... */ }
        }, {
          type: 'menu',
          menuTitle: '',
          menuOptions: ['displayInline'],
          menuPreferredElementSize: 'small',
          menuItems: [{
            actionKey: 'key-01-01',
            actionTitle: '',
            icon: { /** ... */ }
          }, {
            actionKey: 'key-01-02',
            actionTitle: '',
            icon: { /** ... */ }
          }, {
            actionKey: 'key-01-03',
            actionTitle: '',
            icon: { /** ... */ }
          }],
        }, {
          type: 'menu',
          menuTitle: '',
          menuOptions: ['displayInline'],
          menuPreferredElementSize: 'small',
          menuItems: [{
            actionKey: 'key-02-01',
            actionTitle: '',
            icon: { /** ... */ }
          }, {
            actionKey: 'key-02-02',
            actionTitle: '',
            icon: { /** ... */ }
          }, {
            actionKey: 'key-02-03',
            actionTitle: '',
            icon: { /** ... */ }
          }],
        }]
      }}
    >
      { /** ... */ }
    </ContextMenuView>
  );
};

example-ContextMenuViewExample23

example-ContextMenuViewExampleXX


ContextMenuView Example 24

Summary: Menu Attributes โ€” keepsMenuPresented


Notes
TBA

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuViewExample24(props) {
  const [actionState1, setActionState1] = React.useState(false);
  const [actionState2, setActionState2] = React.useState(false);
  const [actionState3, setActionState3] = React.useState(false);

  const isResetEnabled = (
    actionState1 ||
    actionState2 ||
    actionState3 
  );

  const handleOnPressMenuItem = ({nativeEvent}) => {
    // ...
  };

  return (
    <ContextMenuView
      style={props.style}
      onPressMenuItem={handleOnPressMenuItem}
      menuConfig={{
        menuTitle: 'ContextMenuViewExample24',
        menuItems: [{
          actionKey: 'key-01',
          actionTitle: `Action 1: ${actionState1? 'on' : 'off'}`,
          menuState: (actionState1? 'on' : 'off'),
          menuAttributes: ['keepsMenuPresented'],
          icon: { /** ... */ }
        }, {
          actionKey  : 'key-02',
          actionTitle: `Action 2: ${actionState2? 'on' : 'off'}`,
          menuState  : (actionState2? 'on' : 'off'),
          menuAttributes: ['keepsMenuPresented'],
          icon: { /** ... */ }
        }, {
          actionKey: 'key-03',
          actionTitle: `Action 3: ${actionState3? 'on' : 'off'}`,
          menuState: (actionState3? 'on' : 'off'),
          menuAttributes: ['keepsMenuPresented'],
          icon: { /** ... */ }
        }, {
          actionKey: 'key-04',
          actionTitle: `Reset All`,
          menuAttributes: [
            'keepsMenuPresented',
            isResetEnabled? 'destructive' : 'hidden',
          ],
          icon: { /** ... */ }
        }]
      }}
    >
      { /** ... */ }
    </ContextMenuView>
  );
};

example-ContextMenuViewExample24

example-ContextMenuViewExampleXX


ContextMenuView Example 25

Summary: Icon Example โ€” Advanced customization (e.g. scale, weight, paletteColors, hierarchicalColor).


Notes
TBA

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuViewExample25(props) {
  return (
    <ContextMenuView
      style={props.style}
      menuConfig={{
        menuTitle: 'ContextMenuViewExample25',
        menuItems: [{
          type: 'menu',
          menuTitle: '',
          menuOptions: ['displayInline'],
          menuItems: [{
            actionKey: 'key-01-01',
            actionTitle: 'small',
            icon: {
              type: 'IMAGE_SYSTEM',
              imageValue: {
                systemName: 'heart',
                scale: 'small',
              },
            }
          }, {
            actionKey: 'key-01-02',
            actionTitle: 'medium',
            icon: {
              type: 'IMAGE_SYSTEM',
              imageValue: {
                systemName: 'heart',
                scale: 'medium',
              },
            }
          }, {
            actionKey: 'key-01-03',
            actionTitle: 'large',
            icon: {
              type: 'IMAGE_SYSTEM',
              imageValue: {
                systemName: 'heart',
                scale: 'large',
              },
            }
          }],
        }, {
          type: 'menu',
          menuTitle: '',
          menuOptions: ['displayInline'],
          menuItems: [{
            actionKey: 'key-02-01',
            actionTitle: 'ultraLight',
            icon: {
              type: 'IMAGE_SYSTEM',
              imageValue: {
                systemName: 'heart',
                weight: 'ultraLight',
              },
            }
          }, {
            actionKey: 'key-02-02',
            actionTitle: 'semibold',
            icon: {
              type: 'IMAGE_SYSTEM',
              imageValue: {
                systemName: 'heart',
                weight: 'semibold',
              },
            }
          }, {
            actionKey: 'key-02-03',
            actionTitle: 'black',
            icon: {
              type: 'IMAGE_SYSTEM',
              imageValue: {
                systemName: 'heart',
                weight: 'black',
              },
            }
          }],
        },  {
          type: 'menu',
          menuTitle: '',
          menuOptions: ['displayInline'],
          menuItems: [{
            actionKey: 'key-03-01',
            actionTitle: 'paletteColors',
            icon: {
              type: 'IMAGE_SYSTEM',
              imageValue: {
                systemName: 'delete.left.fill',
                paletteColors: ['red', 'blue']
              },
            }
          }, {
            actionKey: 'key-03-02',
            actionTitle: 'semibold',
            icon: {
              type: 'IMAGE_SYSTEM',
              imageValue: {
                systemName: 'delete.left.fill',
                hierarchicalColor: 'red',
              },
            }
          }, {
            actionKey: 'key-03-03',
            actionTitle: 'paletteColors',
            icon: {
              type: 'IMAGE_SYSTEM',
              imageValue: {
                systemName: 'folder.fill.badge.plus',
                paletteColors: ['blue', 'red']
              },
            }
          },  {
            actionKey: 'key-03-04',
            actionTitle: 'hierarchicalColor',
            icon: {
              type: 'IMAGE_SYSTEM',
              imageValue: {
                systemName: 'folder.fill.badge.plus',
                hierarchicalColor: 'blue',
              },
            }
          }],
        }],
      }}
    >
      {/** .... */}
    </ContextMenuView>
  );
};

example-ContextMenuViewExample25

example-ContextMenuViewExampleXX


ContextMenuView Example 26

Summary: Icon Example โ€” Network/Remote images as icons.


Notes
TBA

๐Ÿ”— Full Example


// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuViewExample26(props) {
  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: 'ContextMenuViewExample26',
        menuItems: [{
          actionKey  : 'key-01'   ,
          actionTitle: 'Action #1',
          menuSubtitle: 'Use "IMAGE_REMOTE_URL" icon',
          icon: {
            type: 'IMAGE_REMOTE_URL',
            imageValue: {
              url: 'https://picsum.photos/id/1/100'
            },
          }
        }, {
          actionKey  : 'key-02'   ,
          actionTitle: 'Action #2',
          menuSubtitle: '"IMAGE_REMOTE_URL" + shouldLazyLoad',
          icon: {
            type: 'IMAGE_REMOTE_URL',
            imageValue: {
              url: 'https://picsum.photos/id/2/100'
            },
            imageLoadingConfig: {
              shouldLazyLoad: true,
            },
            imageOptions: {
              cornerRadius: 15,
            },
          }
        }, {
          actionKey  : 'key-03'   ,
          actionTitle: 'Action #3',
          menuSubtitle: '"IMAGE_REMOTE_URL" + shouldLazyLoad + shouldCache',
          icon: {
            type: 'IMAGE_REMOTE_URL',
            imageValue: {
              url: 'https://picsum.photos/id/2/100'
            },
            imageLoadingConfig: {
              shouldLazyLoad: true,
              shouldCache: true,
            },
            imageOptions: {
              cornerRadius: 30,
              tint: 'rgba(255,0,0,0.5)',
              renderingMode: 'alwaysOriginal',
            },
          }
        }],
      }}
    >
      {/** ... */}
    </ContextMenuView>
  );
};

example-ContextMenuViewExampleXX

example-ContextMenuViewExample26


ContextMenuView Example 27

Summary: Icon Example โ€” Network/Remote images as icons + fallback image.


Notes
TBA

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuViewExample27(props) {
  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: 'ContextMenuViewExample27',
        menuItems: [{
          actionKey  : 'key-01'   ,
          actionTitle: 'Action #1',
          actionSubtitle: 'fallbackBehavior: whileNotLoaded',
          icon: {
            type: 'IMAGE_REMOTE_URL',
            imageValue: {
              url: 'https://fake.url.com/asset-1',
              fallbackImage: {
                type: 'IMAGE_SYSTEM',
                imageValue: {
                  systemName: 'trash',
                },
              },
            },
            imageLoadingConfig: {
              // will use the fallback image while the remote
              // image hasn't been loaded yet
              fallbackBehavior: 'whileNotLoaded',
              shouldLazyLoad: true,
              shouldImmediatelyRetryLoading: true,
              maxRetryAttempts: 20,
            },
          }, 
        }, {
          actionKey  : 'key-02'   ,
          actionTitle: 'Action #2',
          actionSubtitle: 'fallbackBehavior: onLoadError',
          icon: {
            type: 'IMAGE_REMOTE_URL',
            imageValue: {
              url: 'https://fake.url.com/asset-2',
              fallbackImage: {
                type: 'IMAGE_SYSTEM',
                imageValue: {
                  systemName: 'trash',
                },
              },
            },
            imageLoadingConfig: {
              // will use the fallback image when it encounters
              // an error whe loading the remote image
              fallbackBehavior: 'onLoadError',
              shouldLazyLoad: true,
              shouldImmediatelyRetryLoading: true,
              maxRetryAttempts: 20,
            },
          }
        },  {
          actionKey  : 'key-03'   ,
          actionTitle: 'Action #3',
          actionSubtitle: 'fallbackBehavior: afterFinalAttempt',
          icon: {
            type: 'IMAGE_REMOTE_URL',
            imageValue: {
              url: 'https://fake.url.com/asset-3',
              fallbackImage: {
                type: 'IMAGE_SYSTEM',
                imageValue: {
                  systemName: 'trash',
                },
              },
            },
            imageLoadingConfig: {
              // will use the fallback image when it encounters
              // an error whe loading the remote image, and the
              // number of loading attempts exceeds 
              // `maxRetryAttempts` 
              fallbackBehavior: 'afterFinalAttempt',
              shouldLazyLoad: true,
              shouldImmediatelyRetryLoading: true,
              maxRetryAttempts: 20,
            },
          }
        }],
      }}
    >
      {/** ... */}
    </ContextMenuView>
  );
};

example-ContextMenuViewExampleXX

example-ContextMenuViewExampleXX


ContextMenuView Example 28

Summary: Programmatically shows the context menu


Notes
TBA

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuViewExample28(props) {
  const menuRef = React.useRef<ContextMenuView>(null);
  
  return (
    <ContextMenuView
      ref={menuRef}
      menuConfig={{ /* ... */ }}
    >
      <ContextMenuCard /* ... */>
        <CardButton
          title={'Show Context Menu'}
          subtitle={'Programmatically shows the context menu'}
          onPress={() => {
            menuRef.current?.presentMenu();
          }}
        />
      </ContextMenuCard>
    </ContextMenuView>
  );
};

example-ContextMenuViewExample28


ContextMenuView Auxiliary Preview - Example 01

Summary: TBA


Notes
TBA

๐Ÿ“ Note A:

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuAuxPreviewExample01() {
  return (
    <ContextMenuView
      menuConfig={{
        // ...
      }}
      isAuxiliaryPreviewEnabled={true}
      renderAuxiliaryPreview={() => (
        <View style={[styles.auxRootContainer, {
          // The view you return will be wrapped by another view. 
          // The parent view will be resized to match the width of the aux. 
          // preview.
          //
          // since this view is going to be resized, let's stretch to match the 
          // the size of the parent, and center the content
          flex: 1,
          alignItems: 'center',
          justifyContent: 'center',
        }]}>
          <TouchableOpacity style={styles.buttonContainer}>
            { /** ... */ }
          </TouchableOpacity>
        </View>
      )}
    >
      {/** ... */}
    </ContextMenuView>
  );
};

ContextMenuAuxPreviewExample01

placeholder


ContextMenuView Auxiliary Preview - Example 02

Summary: TBA


Notes
TBA

๐Ÿ“ Note A:

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuAuxPreviewExample02() {
  return (
    <ContextMenuView
      menuConfig={{
        // ...
      }}
      // If you want to immediately show the aux. preview, then
      // set `transitionEntranceDelay` to: `RECOMMENDED`.
      // 
      // The default is: `AFTER_PREVIEW`.
      //
      // You can also pass in a number indicating how long delay
      // is in seconds  (e.g. 0.3).
      //
      // Note: Do not pass in a number below 0.25 to avoid any
      // layout bugs...
      auxiliaryPreviewConfig={{
        transitionEntranceDelay: 'RECOMMENDED'
      }}
      renderAuxiliaryPreview={() => (
        <View style={styles.auxRootContainer}>
          <Text style={styles.textLabel}>
            Faster Transition
          </Text>
        </View>
      )}
    >
      {/** ... */}
    </ContextMenuView>
  );
};

ContextMenuAuxPreviewExample02

placeholder


ContextMenuView Auxiliary Preview - Example 03

Summary: TBA


Notes
TBA

๐Ÿ“ Note A:

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuAuxPreviewExample03() {
  return (
    <ContextMenuView
      menuConfig={{
        // ...
      }}
      auxiliaryPreviewConfig={{
        // Align the aux. preview to the left...
        // ๐Ÿ“ Note: By default, this is set to: `stretchPreview`
        alignmentHorizontal: 'previewLeading',
      }}
      renderAuxiliaryPreview={() => (
        <View style={styles.auxRootContainer}>
          <Text style={styles.textLabel}>
            To the left (to the left)
          </Text>
        </View>
      )}
    >
      {/** ... */}
    </ContextMenuView>
  );
};

ContextMenuAuxPreviewExample03

placeholder


ContextMenuView Auxiliary Preview - Example 04

Summary: TBA


Notes
TBA

๐Ÿ“ Note A:

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuAuxPreviewExample04() {
  return (
    <ContextMenuView
      menuConfig={{
        // ...
      }}
      auxiliaryPreviewConfig={{
        // Align the aux. preview to the right...
        // ๐Ÿ“ Note: By default, this is set to: `stretchPreview`
        alignmentHorizontal: 'previewTrailing',
      }}
      renderAuxiliaryPreview={() => (
        <View style={styles.auxRootContainer}>
          <Text style={styles.textLabel}>
            Yeah right, yeah right
          </Text>
        </View>
      )}
    >
      {/** ... */}
    </ContextMenuView>
  );
};

ContextMenuAuxPreviewExample04

placeholder


ContextMenuView Auxiliary Preview - Example 05

Summary: TBA


Notes
TBA

๐Ÿ“ Note A:

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuAuxPreviewExample05() {
  return (
    <ContextMenuView
      menuConfig={{
        // ...
      }}
      // Align the aux. preview to the center of the context
      // menu preview...
      //
      // ๐Ÿ“ Note: By default, this is set to: `stretchPreview`
      auxiliaryPreviewConfig={{
        alignmentHorizontal: 'previewCenter',
      }}
      renderAuxiliaryPreview={() => (
        <View style={styles.auxRootContainer}>
          <Text style={styles.textLabel}>
            Center
          </Text>
        </View>
      )}
    >
      { /** ... */ }
    </ContextMenuView>
  );
};

ContextMenuAuxPreviewExample05

placeholder


ContextMenuView Auxiliary Preview - Example 06

Summary: TBA


Notes
TBA

๐Ÿ“ Note A:

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuAuxPreviewExample06(props) {
  return (
    <ContextMenuView
      menuConfig={{
        // ...
      }}
      auxiliaryPreviewConfig={{
        // Configure the aux. preview to use the entire width of
        // the screen...
        //
        // ๐Ÿ“ Note: By default, this is set to: `stretchPreview`
        alignmentHorizontal: 'stretchScreen',
      }}
      renderAuxiliaryPreview={() => (
        <View style={styles.auxRootContainer}>
          <View style={styles.innerContainer}>
            <Text style={styles.textLabel}>
              Stretch to Edges of Screen
            </Text>
          </View>
        </View>
      )}
    >
      {/** ... */}
    </ContextMenuView>
  );
};

ContextMenuAuxPreviewExample06

placeholder


ContextMenuView Auxiliary Preview - Example 07

Summary: TBA


Notes
TBA

๐Ÿ“ Note A:

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuAuxPreviewExample07(props) {
  return (
    <ContextMenuView
      menuConfig={{
        // ...
      }}
      auxiliaryPreviewConfig={{
        // Configure the aux. preview to have a fixed size 
        // of 100 x 100
        width: 100,
        height: 100,
        alignmentHorizontal: 'previewCenter',
      }}
      renderAuxiliaryPreview={() => (
        <View style={[styles.auxRootContainer, {
          // Parent has been reized to `100x100`,
          // so fit to the size of the parent view...
          flex: 1,
        }]}>
          <Text style={styles.textLabel}>
            100
          </Text>
          <Text style={styles.textLabel}>
            x
          </Text>
          <Text style={styles.textLabel}>
            100
          </Text>
        </View>
      )}
    >
      {/** ... */}
    </ContextMenuView>
  );
};

ContextMenuAuxPreviewExample07

placeholder


ContextMenuView Auxiliary Preview - Example 08

Summary: TBA


Notes
TBA

๐Ÿ“ Note A:

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuAuxPreviewExample08(props) {
  return (
    <ContextMenuView
      menuConfig={{
        menuTitle: 'ContextMenuAuxPreviewExample08',
      }}
      auxiliaryPreviewConfig={{
        // Configure the aux. preview to always appear on top of
        // the context menu preview...
        //
        // ๐Ÿ“ Note: This is set to `automatic` by default.
        anchorPosition: 'top',
      }}
      renderAuxiliaryPreview={() => (
        // ...
      )}
    >
      {/** ... */}
    </ContextMenuView>
  );
};

ContextMenuAuxPreviewExample08

placeholder


ContextMenuView Auxiliary Preview - Example 09

Summary: TBA


Notes
TBA

๐Ÿ“ Note A:

๐Ÿ”— Full Example

export function ContextMenuAuxPreviewExample09(props) {
  return (
    <ContextMenuView
      // ...
      auxiliaryPreviewConfig={{
        // Configure the aux. preview to always appear on the
        // bottom of the context menu preview...
        //
        // ๐Ÿ“ Note: This is set to `automatic` by default.
        anchorPosition: 'bottom',
      }}
      renderAuxiliaryPreview={() => (
        <View style={styles.auxRootContainer}>
          <Text style={styles.textLabel}>
            Always Bottom
          </Text>
        </View>
      )}
    >
      {/** ... */}
    </ContextMenuView>
  );
};

ContextMenuAuxPreviewExample09

placeholder


ContextMenuView Auxiliary Preview - Example 10

Summary: TBA


Notes
TBA

๐Ÿ“ Note A:

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuAuxPreviewExample10(props) {
  return (
    <ContextMenuView
      menuConfig={{
        // ...
      }}
      auxiliaryPreviewConfig={{
        // configure the entrance transition for the aux.
        // preview to use a 'slide' transition...
        transitionEntranceDelay: 0.5,
        transitionConfigEntrance: {
          transition: 'slide',
          duration: 0.4,
          options: ['curveEaseIn'],
        },
      }}
      renderAuxiliaryPreview={() => (
        // ...
      )}
    >
      {/** .... */}
    </ContextMenuView>
  );
};

ContextMenuAuxPreviewExample10

placeholder


ContextMenuView Auxiliary Preview - Example 11

Summary: TBA


Notes
TBA

๐Ÿ“ Note A:

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuAuxPreviewExample11(props) {
  return (
    <ContextMenuView
      menuConfig={{
        // ...
      }}
      auxiliaryPreviewConfig={{
        // configure the entrance transition for the aux.
        // preview to use a 'zoom' transition...
        transitionConfigEntrance: {
          transition: 'zoom',
          duration: 0.5,
          options: ['curveEaseOut'],
        },
      }}
      renderAuxiliaryPreview={() => (
        // ...
      )}
    >
      {/** ... */}
    </ContextMenuView>
  );
};

ContextMenuAuxPreviewExample11

placeholder


ContextMenuView Auxiliary Preview - Example 12

Summary: TBA


Notes
TBA

๐Ÿ“ Note A:

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuAuxPreviewExample12(props) {
  return (
    <ContextMenuView
      menuConfig={{
        // ...
      }}
      auxiliaryPreviewConfig={{
        transitionConfigEntrance: {
          // configure the entrance transition for the aux.
          // preview to use a 'zoom' transition...
          transition: 'zoomAndSlide',
          duration: 0.4,
          options: ['curveEaseInOut'],

          // change transition offsets
          zoomOffset: 0.2,
          slideOffset: 100,
        },
      }}
      renderAuxiliaryPreview={() => (
        // ...
      )}
    >
      {/** ... */}
    </ContextMenuView>
  );
};

ContextMenuAuxPreviewExample12

placeholder


ContextMenuView Auxiliary Preview - Example 13

Summary: TBA


Notes
TBA

๐Ÿ“ Note A:

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuAuxPreviewExample13(props) {
  return (
    <ContextMenuView
      menuConfig={{
        // ...
      }}
      auxiliaryPreviewConfig={{
        // Add some space between the aux. preview, and the
        // menu preview...
        marginPreview: 30,
      }}
      renderAuxiliaryPreview={() => (
        // ...
      )}
    >
      {/** ... */}
    </ContextMenuView>
  );
};

ContextMenuAuxPreviewExample13

placeholder


ContextMenuView Auxiliary Preview - Example 14

Summary: TBA


Notes
TBA

๐Ÿ“ Note A:

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuAuxPreviewExample14(props) {
  return (
    <ContextMenuView
      menuConfig={{
        // ...
      }}
      auxiliaryPreviewConfig={{
        // Add some space between the edges of the screen and
        // the aux. preview...
        marginAuxiliaryPreview: 30,
      }}
      renderAuxiliaryPreview={() => (
        // ...
      )}
    >
      {/** ... */}
    </ContextMenuView>
  );
};

ContextMenuAuxPreviewExample14

placeholder


ContextMenuView Auxiliary Preview - Example 15

Summary: TBA


Notes
TBA

๐Ÿ“ Note A:

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...

export function ContextMenuAuxPreviewExample15(props) {
  return (
    <ContextMenuView
      menuConfig={{
        // ...
      }}
      auxiliaryPreviewConfig={{
        // ...
        
        // The space between the aux. preview, and the
        // menu preview...
        // 
        // A negative value means that you want the aux. preview
        // to appear closer to the menu preview.
        //
        // This is particularly useful if the menu preview is
        // too big, and it causes the menu items to go out of 
        // bounds...
        marginPreview: -60,
      }}
      renderAuxiliaryPreview={() => (
        <View style={[styles.auxRootContainer, {
          alignItems: 'center',
          justifyContent: 'center',
        }]}>
          <Text style={styles.textLabel}>
            Aux. Preview
          </Text>
        </View>
      )}
      previewConfig={{
        previewType: 'CUSTOM',
        previewSize: 'STRETCH',
      }}
      renderPreview={() => (
        <View style={[styles.previewRootContainer, {
          alignItems: 'center',
          justifyContent: 'center',
        }]}>
          <Text style={styles.textLabel}>
            Custom Menu Preview
          </Text>
        </View>
      )}
    >
      {/** ... */}
    </ContextMenuView>
  );
};

ContextMenuAuxPreviewExample15

placeholder


ContextMenuView Auxiliary Preview - Example 16

Summary: Programmatically shows the auxiliary preview as a popover, without showing the context menu.


Notes
TBA

๐Ÿ”— Full Example

// ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
export function ContextMenuAuxPreviewExample16(props) {
  const menuRef = React.useRef<ContextMenuView>(null);
  
  return (
    <ContextMenuView
      ref={menuRef}
      menuConfig={/* ... */}
      auxiliaryPreviewConfig={{
        alignmentHorizontal: 'previewCenter',
        transitionEntranceDelay: 'RECOMMENDED',
        height: 100,
        width: 150,
      }}
      renderAuxiliaryPreview={() => (
        <View style={[styles.auxRootContainer, {
          flex: 1,
          alignItems: 'center',
          justifyContent: 'center',
        }]}>
          <Text style={styles.textLabel}>
            Center
          </Text>
        </View>
      )}
    >
      <ContextMenuCard /* ... */>
        <CardButton
          title={'Show Aux. Preview as Popover'}
          onPress={() => {
            menuRef.current?.showAuxiliaryPreviewAsPopover();
          }}
        />
      </ContextMenuCard>
    </ContextMenuView>
  );
};

example-ContextMenuViewExample16


ContextMenuButton Example 01

Summary: TBA


Notes
TBA

๐Ÿ“ Note A:

๐Ÿ”— Full Example

 // ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...

import { ContextMenuButton } from 'react-native-ios-context-menu';

export function ContextMenuButtonExample01() {
  return (
    <ContextMenuButton
      menuConfig={{
        menuTitle: 'ContextMenuButtonSimpleExample01',
          menuItems: [{
            actionKey  : 'key-01',
            actionTitle: 'Action #1',
          }, {
            actionKey  : 'key-02'   ,
            actionTitle: 'Action #2',
          }, {
            actionKey  : 'key-03'   ,
            actionTitle: 'Action #3',
          }],
      }}
      onPressMenuItem={({nativeEvent}) => {
        Alert.alert(
          'onPressMenuItem Event',
          `actionKey: ${nativeEvent.actionKey} - actionTitle: ${nativeEvent.actionTitle}`
        );
      }}
    >
      {/** Components */}
    </ContextMenuButton>
  );
};

screenshot

Gif


ContextMenuButton Example 02

Summary: TBA


Notes
TBA

๐Ÿ“ Note A:

๐Ÿ”— Full Example

 // ๐Ÿ“ Note: for the sake of brevity, some of the code is omitted...
import { ContextMenuButton } from 'react-native-ios-context-menu';

export function ContextMenuButtonExample02(props) {
  return (
    <ContextMenuButton
      isMenuPrimaryAction={true}
      menuConfig={{
        menuTitle: 'ContextMenuButtonSimpleExample02',
        menuItems: [{
          actionKey  : 'key-01',
          actionTitle: 'Action #1',
          icon: {
            type: 'IMAGE_SYSTEM',
            imageValue: {
              systemName: 'folder',
            },
          }
        }, {
          actionKey  : 'key-02'   ,
          actionTitle: 'Action #2',
          icon: {
            type: 'IMAGE_SYSTEM',
            imageValue: {
              systemName: 'dial.fill',
            },
          }
        }, {
          actionKey  : 'key-03'   ,
          actionTitle: 'Action #3',
          icon: {
            type: 'IMAGE_SYSTEM',
            imageValue: {
              systemName: 'archivebox.fill',
            },
          }
        }],
      }}
      onPressMenuItem={({nativeEvent}) => {
        Alert.alert(
          'onPressMenuItem Event',
          `actionKey: ${nativeEvent.actionKey} - actionTitle: ${nativeEvent.actionTitle}`
        );
      }}
    >
      {/** Components */}
    </ContextMenuButton>
  );
};

screenshot

Gif



F. Showcase, Tests and Demos

ContextMenuView Test 01

Summary: Test for multiple nested/deep submenus.

๐Ÿ”— Source Code

Gif


ContextMenuView Test 02

Summary: Test for multiple inline menus + nested submenus.

๐Ÿ”— Source Code

Gif


ContextMenuView Test 03

Summary: Test for toggling the menuState on and off.

๐Ÿ”— Source Code

Gif


ContextMenuView Test 04

Summary: Test for changing the menu icons based on the current menuState.

๐Ÿ”— Source Code

Gif


ContextMenuView Test 05

Summary: Test for logging all the menu-related events.

๐Ÿ”— Source Code

Gif


ContextMenuView Test 06

Summary: Test for programmatically adding a menu action item.

๐Ÿ”— Source Code

Gif


ContextMenuView Test 07

Summary: Test for checking the different possible custom menu preview configurations.

๐Ÿ”— Source Code

Gif


ContextMenuView Test 08

Summary: Test for programmatically dismissing the menu.

๐Ÿ”— Source Code

Gif


ContextMenuView Test 09

Summary: Generate new 'deferredID' everytime the context menu is shown/hide. This is a test for cleanupOrphanedDeferredElements.

๐Ÿ”— Source Code

Gif


ContextMenuView Test 10

Summary: Test for nested menus, deferred elements, large icons, and small menus,

๐Ÿ”— Source Code

Gif


ContextMenuAuxPreview Test 01

Summary: TBA

๐Ÿ”— Source Code

Gif


Test02Screen

Summary: Repro for Issue #43

๐Ÿ”— Source Code

Gif


Test03Screen

Summary: Repro for Issue #47

๐Ÿ”— Source Code

Gif



G. Meta



H. Licence

MIT



Misc and Contact

Open Source Agenda is not affiliated with "React Native Ios Context Menu" Project. README Source: dominicstop/react-native-ios-context-menu

Open Source Agenda Badge

Open Source Agenda Rating