I have created a wrapper component for the Shopify Resource Picker.
import { useAppBridge } from '@shopify/app-bridge-react';
import { Button, type ButtonProps } from '@shopify/polaris';
import { useCallback } from 'react';
export type ResourcePickerSelectPayload = NonNullable<
Awaited<ReturnType<typeof shopify.resourcePicker>>
>;
interface ProductResourcePickerProps {
onSelect: (resources: ResourcePickerSelectPayload) => void;
options?: Parameters<typeof shopify.resourcePicker>[0];
buttonLabel?: string;
buttonProps?: Omit<ButtonProps, 'onClick'>;
}
export function ResourcePicker({
onSelect,
options = { type: 'product' },
buttonLabel = 'Select products',
buttonProps = {},
}: ProductResourcePickerProps) {
const shopify = useAppBridge();
const handleOpenPicker = useCallback(async () => {
const selected = await shopify.resourcePicker(options);
if (selected) {
onSelect(selected);
}
}, [onSelect, options, shopify]);
return (
<Button onClick={handleOpenPicker} {...buttonProps}>
{buttonLabel}
</Button>
);
}
The result of shopify.ResourcePicker
is defined as follows:
type ResourcePickerApi = (options: ResourcePickerOptions) => Promise<SelectPayload<ResourcePickerOptions['type']> | undefined>;
This leads to my ResourcePickerSelectPayload
being:
type ResourcePickerSelectPayload = ResourceSelection<"product" | "variant" | "collection">[] & {
selection: ResourceSelection<"product" | "variant" | "collection">[];
}
I am having difficulty figuring out how to pass the value from options.type
(product, variant, or collection) so that my component can return the specific type. For example, if options.type === 'product'
, then selected
should be of type ResourceSelection<'product'>
.
Since the ResourceSelection
type is not exported, I am unsure how to access it other than what I currently have.
I believe the problem lies in the fact that my ResourcePickerSelectPayload
is not generic, while ResourceSelection
is.
I attempted to pass the value of options.type
into my function and incorporate conditional returns, but unfortunately, it did not work as expected.