Action Sheet

A modal view that presents choices related to an action people initiate.

Apple
Apple
import { useActionSheet } from '@expo/react-native-action-sheet';
import { Icon } from '@roninoss/icons';
import { Stack } from 'expo-router';

import { Button, View, Text, ScrollView, Pressable } from 'react-native';

import { useColorScheme } from '~/lib/useColorScheme';

export default function ActionSheetScreen() {
  const { colorScheme, colors } = useColorScheme();
  const { showActionSheetWithOptions } = useActionSheet();
  return (
    <>
      <Stack.Screen
        options={{
          title: 'NativeWindUI',
          headerSearchBarOptions: {
            hideWhenScrolling: false,
          },
          headerLargeTitle: true,
          headerRight() {
            return (
              <Pressable className="opacity-80 active:opacity-40">
                <View className="opacity-90">
                  <Icon name="cog-outline" color={colors.foreground} />
                </View>
              </Pressable>
            );
          },
        }}
      />
      <ScrollView contentInsetAdjustmentBehavior="automatic" className="p-4">
        <View className="border-border bg-card gap-4 rounded-xl border p-4 pb-6 shadow-sm shadow-black/10 dark:shadow-none">
          <Text className="text-foreground text-center text-sm font-medium tracking-wider opacity-60">
            Action Sheet
          </Text>

          <Button
            color="grey"
            onPress={async () => {
              const options = ['Delete', 'Save', 'Cancel'];
              const destructiveButtonIndex = 0;
              const cancelButtonIndex = 2;

              showActionSheetWithOptions(
                {
                  options,
                  cancelButtonIndex,
                  destructiveButtonIndex,
                  containerStyle: {
                    backgroundColor: colorScheme === 'dark' ? 'black' : 'white',
                  },
                  textStyle: {
                    color: colors.foreground,
                  },
                },
                (selectedIndex) => {
                  switch (selectedIndex) {
                    case 1:
                      // Save
                      break;

                    case destructiveButtonIndex:
                      // Delete
                      break;

                    case cancelButtonIndex:
                    // Canceled
                  }
                }
              );
            }}
            title="Open action sheet"
          />
        </View>
      </ScrollView>
    </>
  );
}

Installation

1

Run the following command:

npx nwui-cli@latest add action-sheet
2

Edit _layout.tsx

Next, wrap your root component with an ActionSheetProvider.

~/app/_layout.tsx
    import '../global.css';
    import 'expo-dev-client';

+   import { ActionSheetProvider } from '@expo/react-native-action-sheet';    
    import { StatusBar } from 'expo-status-bar';
    // YOUR_OTHER_IMPORTS

    import { useColorScheme, useInitialAndroidBarSync } from '~/lib/useColorScheme';
    import { NAV_THEME } from '~/theme';

    export {    
      // Catch any errors thrown by the Layout component.
      ErrorBoundary,
    } from 'expo-router';

    export default function RootLayout() {    
      useInitialAndroidBarSync();
      const { colorScheme, isDarkColorScheme } = useColorScheme();
    
      return (
        <>
          <StatusBar
            key={root-status-bar-${isDarkColorScheme ? 'light' : 'dark'}}
            style={isDarkColorScheme ? 'light' : 'dark'}
          />
+         <ActionSheetProvider>
              <NavThemeProvider value={NAV_THEME[colorScheme]}>
                 {/* YOUR_ROOT_NAVIGATOR */}
              </NavThemeProvider>
+          </ActionSheetProvider>
        </>
      );
    }
🚀
Ship.
1

Add the following dependency to your project:

npx expo install @expo/react-native-action-sheet
2

Edit _layout.tsx

Next, wrap your root component with an ActionSheetProvider.

~/app/_layout.tsx
    import '../global.css';
    import 'expo-dev-client';

+   import { ActionSheetProvider } from '@expo/react-native-action-sheet';    
    import { StatusBar } from 'expo-status-bar';
    // YOUR_OTHER_IMPORTS

    import { useColorScheme, useInitialAndroidBarSync } from '~/lib/useColorScheme';
    import { NAV_THEME } from '~/theme';

    export {    
      // Catch any errors thrown by the Layout component.
      ErrorBoundary,
    } from 'expo-router';

    export default function RootLayout() {    
      useInitialAndroidBarSync();
      const { colorScheme, isDarkColorScheme } = useColorScheme();
    
      return (
        <>
          <StatusBar
            key={root-status-bar-${isDarkColorScheme ? 'light' : 'dark'}}
            style={isDarkColorScheme ? 'light' : 'dark'}
          />
+         <ActionSheetProvider>
              <NavThemeProvider value={NAV_THEME[colorScheme]}>
                 {/* YOUR_ROOT_NAVIGATOR */}
              </NavThemeProvider>
+          </ActionSheetProvider>
        </>
      );
    }
🛸
Ship.

Usage

import { useActionSheet } from '@expo/react-native-action-sheet';
const { showActionSheetWithOptions } = useActionSheet();

React.useEffect(() => {
  const options = ['Delete', 'Save', 'Cancel'];
  const destructiveButtonIndex = 0;
  const cancelButtonIndex = 2;

  showActionSheetWithOptions(
    {
      options,
      cancelButtonIndex,
      destructiveButtonIndex,
    },
    (selectedIndex: number) => {
      switch (selectedIndex) {
        case 1:
          // Save
          break;

        case destructiveButtonIndex:
          // Delete
          break;

        case cancelButtonIndex:
        // Canceled
      }
    }
  );
}, []);

Options

See the react-native-action-sheet documentation for all of the options.

© Ronin Technologies LLC 2024