expo-quick-actions

repository·main·Indexed 20 days ago

https://github.com/evanbacon/expo-quick-actions

A React Native library for Expo projects to manage native home screen quick actions and dynamic app icons. It provides a QuickActions API for setting items and listening for triggers, convenience hooks for UI updates, and integration with Expo Router for deep linking. The library includes Config Plugins for configuring static iOS actions, Android adaptive icons, Android dynamic app icons, and iOS image assets.

Tokens
9K
Snippets
33
Records
37
Agent score
71%

What's inside expo-quick-actions

  1. Configure icons for quick actions

    main

    The icon property on an Action supports different types of images, primarily for iOS:

    • SF Symbols: Use the symbol: prefix to access Apple's SF Symbols (e.g., symbol:heart.fill). These are iOS-only.
    • System Icons: Use specific built-in names like compose, play, pause, add, location, search, share, etc. If a name doesn't match a built-in icon, it defaults to a custom image with that name.
    • Custom Images: Use the asset: prefix to load an image from the app's bundle (e.g., asset:heart). The image will be masked to conform to the system-defined icon style.

    For Android, refer to the Android design docs for shortcut icons.

    // Examples of icon strings
    const sfSymbolIcon = "symbol:heart.fill";
    const systemIcon = "search";
    const customAssetIcon = "asset:my_custom_icon";
  2. Integrate with Expo Router

    main

    To enable automatic linking from quick action params.href to your app's routes, use useQuickActionRouting from expo-quick-actions/router in your Layout Route. This allows you to treat quick actions as deep links.

    // app/(root)/_layout.tsx
    import { useEffect } from "react";
    import { Slot } from "expo-router";
    import { useQuickActionRouting, RouterAction } from "expo-quick-actions/router";
    import * as QuickActions from "expo-quick-actions";
    
    export default function Layout() {
      // Enable linking to the `href` param
      useQuickActionRouting();
    
      useEffect(() => {
        QuickActions.setItems<RouterAction>([
          {
            title: "New Chat",
            icon: "compose",
            id: "0",
            params: { href: "/compose" },
          },
          {
            title: "Search",
            icon: "search",
            id: "1",
            params: { href: "/search" },
          },
        ]);
      }, []);
    
      return <Slot />;
    }
    // app/(root)/_layout.tsx
    import { useEffect } from "react";
    import { Slot } from "expo-router";
    import { useQuickActionRouting, RouterAction } from "expo-quick-actions/router";
    import * as QuickActions from "expo-quick-actions";
    
    export default function Layout() {
      useQuickActionRouting();
    
      useEffect(() => {
        QuickActions.setItems<RouterAction>([
          {
            title: "New Chat",
            icon: "compose",
            id: "0",
            params: { href: "/compose" },
          },
          {
            title: "Search",
            icon: "search",
            id: "1",
            params: { href: "/search" },
          },
          {
            title: "Leave Feedback",
            subtitle: "Please provide feedback before deleting the app",
            icon: "symbol:envelope",
            id: "2",
            params: { href: "mailto:support@myapp.dev" },
          },
        ]);
      }, []);
    
      return <Slot />;
    }
  3. Install expo-quick-actions with correct versioning

    main

    Before installing, ensure your expo version matches the compatible expo-quick-actions version from the following table:

    expoexpo-quick-actions
    56.0.06.0.2
    54.0.06.0.0
    53.0.05.0.0
    52.0.0+3.0.0
    51.0.02.0.0
    50.0.01.0.0
    49.0.00.0.0
  4. Configure the expo-quick-actions Config Plugin

    main

    Use the config plugin in app.json to add static iOS actions and define icons for both Android and iOS.

    • androidIcons: Maps action icon keys to image assets. Can be a string (URL/path) or an object with foregroundImage and backgroundColor.
    • iosIcons: Maps action icon keys to iOS assets. Can be a string or an object with 1x, 2x, and 3x properties.
    • iosActions: An array of static iOS actions available on startup.

    Note: Static Android actions are not currently supported.

    {
      "plugins": [
        [
          "expo-quick-actions",
          {
            "androidIcons": {
              "shortcut_one": {
                "foregroundImage": "./assets/adaptive-icon.png",
                "backgroundColor": "#282A35"
              },
              "shortcut_two": "https://evanbacon.dev/pfp.png"
            },
            "iosIcons": {
              "shortcut_one": "./assets/adaptive-icon.png"
            },
            "iosActions": [
              {
                "id": "1",
                "title": "Shortcut One",
                "subtitle": "Subtitle One",
                "icon": "shortcut_one",
                "params": {
                  "href": "https://evanbacon.dev"
                }
              }
            ]
          }
        ]
      ]
    }
  5. Configure action icons

    main

    The icon property in an Action supports several formats:

    • Apple Built-in Icons: A set of predefined string identifiers (e.g., 'compose', 'play', 'search').
    • SF Symbols (iOS): Identified using the format `symbol:NAME` (e.g., `symbol:heart.fill`).
    • Local Assets: Identified using the format `asset:PATH`.
    • Custom Strings: Any other string can be provided, though behavior depends on the platform.
  6. Configure expo-quick-actions via the withQuickActions Config Plugin

    main

    The withQuickActions Config Plugin allows you to configure static quick actions and associated icons for both iOS and Android within your Expo project. You can provide custom icons for Android and iOS, and define static quick actions for iOS.

    To use this plugin, add it to your app.json or app.config.js under the plugins array.

    Supported Configuration Options:

    • androidIcons: A record mapping action names to image sources (Record<string, AndroidImageProps["src"]>).
    • iosIcons: A record mapping action names to image sources (Record<string, IosImageProps["src"]>).
    • iosActions: An array of iOS static quick action configurations (IosStaticQuickActionProps[]).
    {
      "plugins": [
        [
          "expo-quick-actions",
          {
            "androidIcons": {
              "actionName": "./path/to/android-icon.png"
            },
            "iosIcons": {
              "actionName": "./path/to/ios-icon.png"
            },
            "iosActions": [
              {
                "title": "My Action",
                "subtitle": "Description",
                "icon": "actionName"
              }
            ]
          }
        ]
      ]
    }
  7. Configure Android adaptive app icons with `withAndroidAppIcon`

    main

    Use the withAndroidAppIcon Expo Config Plugin to set up Android adaptive icons. This plugin handles the generation of multiple icon layers (foreground, background, and monochrome), manages legacy icon fallback for older Android versions, and automatically configures the necessary Android resource files (mipmap directories and colors.xml).

    Usage

    Pass an object to withAndroidAppIcon in your app.config.ts or app.json. You can provide either a simple string for a standard icon or an AdaptiveIcon object for full adaptive support.

    Adaptive Icon Options

    When using the adaptive icon mode, you can specify:

    • foregroundImage: The primary icon layer (required).
    • backgroundColor: A fallback background color (e.g., #FFFFFF).
    • backgroundImage: An image to serve as the background layer.
    • monochromeImage: An image for Android's monochrome icon support.

    Note: If backgroundImage is provided, it will override backgroundColor in the adaptive icon configuration.

    import { withAndroidAppIcon } from 'expo-quick-actions';
    
    export default ({ config }) => {
      return withAndroidAppIcon(config, {
        name: 'ic_launcher',
        src: {
          foregroundImage: './assets/icon-foreground.png',
          backgroundColor: '#FFFFFF',
          monochromeImage: './assets/icon-monochrome.png',
        },
      });
    };
  8. Configure Android dynamic app icons with withAndroidDynamicAppIcons

    main

    Use the withAndroidDynamicAppIcons Expo Config Plugin to automatically generate and register multiple app icons for Android. This plugin performs two main tasks:

    1. Generates Android Resources: It takes your provided icon images, resizes them into multiple densities (mipmap and drawable folders), and creates both square and round versions.
    2. Updates AndroidManifest.xml: It adds <activity-alias> entries to your AndroidManifest.xml. These aliases allow the system to switch between different icons by targeting the same MainActivity.

    Note: The generated activity aliases are set to android:enabled="false" by default, which is required so that only one icon is active at a time when you programmatically switch them via Quick Actions.

    import { withAndroidDynamicAppIcons } from 'expo-quick-actions';
    
    export default function withPlugins(config) {
      return withAndroidDynamicAppIcons(config, {
        icons: {
          'icon-name-1': './path/to/icon1.png',
          'icon-name-2': './path/to/icon2.png',
        },
      });
    }
  9. Use QuickAction hooks for UI and global updates

    main

    Convenience hooks are available via expo-quick-actions/hooks:

    • useQuickAction(): Returns the current Action or null. This hook triggers a re-render when the action changes, making it ideal for updating the UI.
    • useQuickActionCallback(callback): Registers a callback that fires when a quick action is triggered. This does not trigger a re-render, making it ideal for global side effects like navigation or analytics.
    import { useQuickAction, useQuickActionCallback } from "expo-quick-actions/hooks";
    
    function MyComponent() {
      // For UI updates
      const action = useQuickAction();
    
      // For side effects (navigation/analytics) without re-rendering
      useQuickActionCallback((action) => {
        console.log("Action triggered:", action);
      });
    
      return null;
    }
  10. Manage quick actions with the QuickActions API

    main

    The core QuickActions API allows you to check support, retrieve the initial action, and set the list of available actions.

    • isSupported(): Returns a Promise<boolean> indicating if the device supports quick actions.
    • initial: A static property returning the Action used to open the app, if any.
    • maxCount: A static property returning the maximum number of items allowed (iOS is hardcoded to 4; Android is dynamic).
    • setItems(items: Action[]): An async function to set the quick action items. Both Apple and Android recommend a maximum of 4 items.
    • addListener(listener: (payload: Action) => void): Adds a listener that fires when a quick action is triggered. Returns a Subscription.
    import * as QuickActions from "expo-quick-actions";
    
    // Check support
    const isSupported = await QuickActions.isSupported();
    
    // Get initial action
    const initialAction = QuickActions.initial;
    
    // Set items
    await QuickActions.setItems([
      {
        id: "0",
        title: "Open Settings",
        subtitle: "Go here to configure settings",
        icon: "heart",
        params: { href: "/settings" },
      },
    ]);
    
    // Listen for triggers
    const subscription = QuickActions.addListener((action) => {
      console.log(action);
    });
  11. Configure iOS static quick actions with withIosStaticQuickActions

    main

    Use the withIosStaticQuickActions Expo Config Plugin to define static quick actions that appear on the iOS home screen. This plugin modifies your Info.plist to include UIApplicationShortcutItems.

    Configuration Object

    Pass an array of IosStaticQuickActionProps objects to the plugin. Each object represents a single quick action:

    • title (string): The main text for the quick action.
    • id (string): A unique string that the system passes to your app when the action is triggered.
    • subtitle (string, optional): Additional descriptive text.
    • icon (string, optional): The icon to display. Supports three formats:
      • SF Symbols: Prefix the symbol name with symbol: (e.g., symbol:house).
      • Built-in System Icons: Use one of the supported system icon names (see System Icons).
      • Asset Files: Prefix the asset name with asset: (e.g., asset:my-icon-name).
    • params (XML.XMLObject, optional): An optional, app-defined dictionary passed to the app.
    import { withIosStaticQuickActions } from 'expo-quick-actions';
    
    // In your app.config.ts or app.json
    export default ({ config }) => ({
      ...config,
      plugins: [
        [
          'expo-quick-actions',
          [
            {
              title: 'New Message',
              id: 'compose_message',
              subtitle: 'Start a new chat',
              icon: 'symbol:message.fill',
            },
            {
              title: 'Settings',
              id: 'open_settings',
              icon: 'gear',
            },
          ],
        ],
      ],
    });
  12. Configure Android static quick actions with withAndroidStaticActions

    main

    Use the withAndroidStaticActions Expo Config Plugin to define static quick actions for Android. This plugin modifies the shortcuts.xml and AndroidManifest.xml during the prebuild process to register shortcuts that appear when a user long-presses your app icon.

    Each item in the configuration array requires an id, title, and icon. You can also provide optional params which are passed to the app as a JSON-stringified shortcut_data extra in the intent.

    // Example usage in app.config.js or app.json
    export default { 
      expo: {
        plugins: [
          [
            "expo-quick-actions",
            [
              {
                id: "search_action",
                title: "Search",
                icon: "path/to/icon",
                params: { query: "default" }
              }
            ]
          ]
        ]
      }
    };