Skip to main content

unstable_Picker

The Picker action set provides a search-based interface to help users find and select one or more resources. Unlike the ResourcePicker, it provides a lower-level API where you are in charge of providing the data as well as implementing search or pagination features.

A close-up image of a picker. The picker displays the title: Picker and a search input field with the label: Search resources. Below the search interface are rows of placeholder resources. Resource 1 and variant 1 are both selected. The picker features two buttons: a white button with the label Cancel, and a green button with the label Select.

You can use the contextual save bar in the following ways:

  1. Plain JavaScript
  2. React component
Caution

This feature is still under development. As such, the API might be updated without warning.


Create an app and import the unstable_Picker module from @shopify/app-bridge/actions. This sample app is used throughout the examples below.

Note

In the following example, config is a valid App Bridge configuration object. Learn more about configuring App Bridge.

import createApp from '@shopify/app-bridge';
import {unstable_Picker} from '@shopify/app-bridge/actions';

const app = createApp(config);

Anchor to Create a picker to display a list of resourcesCreate a picker to display a list of resources

The following snippet creates a Picker with 2 resources. The first resource has 2 options. We're also specifying the title, search placeholder, and action labels.

const picker = unstable_Picker.create(app, {
items: [
{
id: 'resource1',
name: 'Resource 1',
options: [
{
id: 'option1',
name: 'Option1',
},
{
id: 'option2',
name: 'Option2',
},
],
},
{
id: 'resource2',
name: 'Resource 2',
},
],
title: 'Select Resource',
searchQueryPlaceholder: 'Search resources',
primaryActionLabel: 'Save',
secondaryActionLabel: 'Cancel',
});

Anchor to Common Picker actionsCommon Picker actions

Anchor to Selection and CancellationSelection and Cancellation

The Picker has two main actions that you can subscribe to:

unstable_Picker.Action.SELECT - This action is dispatched when the user triggers the primary action. This action generally corresponds to a selection event. It receives a SelectPayload argument, which is an Object with id and selection keys. The selection key is an array of all the selected items.

unstable_Picker.Action.CANCEL - This action is dispatched when the user triggers the secondary action. This action generally corresponds to a cancelled event.

const picker = unstable_Picker.create(app, {
items: [...],
...
});

picker.subscribe(unstable_Picker.Action.SELECT, ({selection}) => {
// Do something with `selection`
});

picker.subscribe(unstable_Picker.Action.CANCEL, () => {
// Picker was cancelled
});

The Picker has the unstable_Picker.Action.SEARCH search action that you can subscribe to.

This action is dispatched when the user enters a search query string. It receives a SearchPayload argument, which is an Object with id and searchQuery. The searchQuery is a string.

const picker = unstable_Picker.create(app, {
items: [...],
...
});

picker.subscribe(unstable_Picker.Action.SEARCH, ({searchQuery}) => {
// Do something with the searchQuery
// You can then call picker.set({items: [...]}) in order to update the items with the result of the search query.
});

The Picker has the unstable_Picker.Action.LOAD_MORE pagination action that you can subscribe to. To enable this option make sure to set canLoadMore to true when creating your picker instance.

This action is dispatched when the user reaches the bottom of the list of items. It does not have any arguments.

const picker = unstable_Picker.create(app, {
items: [...],
...
});

picker.subscribe(unstable_Picker.Action.LOAD_MORE, () => {
// Do something to load additional data
// You can then call picker.set({items: [...]}) in order to update the items the additional items loaded.
});

  • default value: []
  • optional
  • type: BaseResource[]
  • note: items takes an array of minimal resource objects, which only need to contain a resource id and a name value. A resource may also contain child options. For example:
const picker = unstable_Picker.create(app, {
items: [
{
id: 'customResource1',
name: 'Custom Resource 1',
options: [
{
id: 'option1',
name: 'Option1',
},
{
id: 'option2',
name: 'Option2',
},
],
},
{
id: 'customResource2',
name: 'Custom Resource 2',
},
],
...
});

  • default value: []
  • optional
  • type: BaseResource[]
  • note: selectedItems takes an array of minimal resource objects, which only need to contain a resource id (in GraphQL ID format, ie 'gid://shopify/Product/1'). Resources may also contain selected options. If no option is specified, all options are selected.

  • default value: 0
  • optional
  • type: number
  • note: Limits the total number of selections to a maximum of the passed value, or 0 for no limit.

  • default value: undefined
  • optional
  • type: string
  • note: Used as the title of the modal.

  • default value: false
  • optional
  • type: boolean
  • note: Indicates if the picker should be in a loading state.

Anchor to searchQueryPlaceholdersearchQueryPlaceholder

  • default value: undefined
  • optional
  • type: string
  • note: Used as the placeholder in the search input.

  • default value: undefined
  • optional
  • type: string
  • note: The search query to be displayed in the search input field.

  • default value: undefined
  • optional
  • type: string
  • note: Label to be used on the primary action button.

Anchor to secondaryActionLabelsecondaryActionLabel

  • default value: undefined
  • optional
  • type: string
  • note: Label to be used on the secondary action button.

  • default value: false
  • optional
  • type: boolean
  • note: Whether the Picker can load more items on the list.

  • default value: false
  • optional
  • type: boolean
  • note: Indicates if the Picker is currently loading more items.

  • default value: undefined
  • optional
  • type: EmptySearchLabel
  • note: emptySearchLabel takes an object that describes the interface of the picker when there is no item to display. For example:
const picker = unstable_Picker.create(app, {
items: [],
emptySearchLabel: {
title: 'No resources',
description: 'There are no resources to display',
withIllustration: true,
}
});

Anchor to Subscribe to actionsSubscribe to actions

You can subscribe to Picker actions by calling subscribe. This returns a method that you can call to unsubscribe from the action. For example:

const picker = unstable_Picker.create(app, {
...
});

const selectUnsubscribe = picker.subscribe(unstable_Picker.Action.SELECT, ({selection}) => {
// Do something with `selection`
});

const cancelUnsubscribe = picker.subscribe(unstable_Picker.Action.CANCEL, () => {
// Picker was cancelled
});

// Unsubscribe to actions
selectUnsubscribe();
cancelUnsubscribe();

You can call unsubscribe to remove all subscriptions on the picker:

const picker = unstable_Picker.create(app, {
...
});

picker.subscribe(unstable_Picker.Action.SELECT, () => {
// Do something with `selection`
});

picker.subscribe(unstable_Picker.Action.CANCEL, () => {
// Picker was cancelled
});

// Unsubscribe from all actions
picker.unsubscribe();

const picker = unstable_Picker.create(app, {
...
});

// Open the picker
picker.dispatch(unstable_Picker.Action.OPEN);

You can call the set method with partial picker options. This automatically triggers the update action on the picker and merges the given options with the existing options:

const picker = unstable_Picker.create(app, {
...
});

picker.set({items: [/* a list of items*/]});

Import the Provider and unstable_Picker component from @shopify/app-bridge-react.

Note

In the following example, config is a valid App Bridge configuration object. Learn more about configuring App Bridge.

Note

When using the App Bridge React library, you need to wrap all of your App Bridge React code inside of a single App Bridge Provider.

import React from 'react';
import ReactDOM from 'react-dom';
import {
Provider,
unstable_Picker as Picker
} from '@shopify/app-bridge-react';

function MyApp() {
return (
<Provider config={config}>
<Picker
open
items={/* list of items */}
selectedItems={/* selected items */}
title="Resource Picker"
searchQueryPlaceholder="Search Resource"
primaryActionLabel="Select"
secondaryActionLabel="Cancel"
emptySearchLabel={
{
title: 'No resources',
description: 'There are no resources to display',
withIllustration: true,
}
}
onCancel={/* cancel even handler */}
onSelect={/* select even handler */}
onSearch={/* search even handler */}
onLoadMore={/* load more even handler */}
/>
</Provider>
);
}

const root = document.createElement('div');
document.body.appendChild(root);
ReactDOM.createRoot(root).render(<MyApp />);

NameTypeDescriptionRequired
openbooleanWhether the picker is open or not.Yes
itemsBaseResource[]The list of items to display.Yes
canLoadMorebooleanWhether the Picker can load more items on the list.No
selectedItemsBaseResource[]The items which are selected.No
maxSelectablenumberLimits the total number of selections to a maximum of the passed value, or 0 for no limit.No
titlestringUsed as the title of the modal.No
loadingbooleanIndicates if the Picker should be in a loading state.No
loadingMorebooleanIndicates if the Picker is currently loading more items.No
searchQueryPlaceholderstringUsed as the placeholder in the search input.No
searchQuerystringThe search query to be displayed in the search input field.No
primaryActionLabelstringLabel to be used on the primary action button.No
secondaryActionLabelstringLabel to be used on the secondary action button.No
emptySearchLabelEmptySearchLabelAn object that describes the interface of the picker when there is no item to display.No
onCancel() => voidCallback when the user triggers the secondary action.No
onSelect(selectPayload: SelectPayload) => voidCallback when a selection has been made. It receives a SelectPayload argument, which is an Object with id and selection keys. The selection key is an array of all the selected resources.No
onSearch(searchPayload: SearchPayload) => voidCallback when the user enters a search query string. It receives a SearchPayload argument, which is an Object with id and searchQuery. The searchQuery is a string.No
onLoadMore() => voidCallback when the user reaches the bottom of the list of items. It does not have any argument.No

Was this page helpful?