Skip to content

Instantly share code, notes, and snippets.

@stlk
Created April 10, 2025 17:48
Show Gist options
  • Save stlk/88ed53839742a98c69b32749c4fd0783 to your computer and use it in GitHub Desktop.
Save stlk/88ed53839742a98c69b32749c4fd0783 to your computer and use it in GitHub Desktop.
import React, { useMemo, useCallback, useState } from 'react';
import {
reactExtension,
Style,
View,
Text,
BlockStack,
TextField,
BlockLayout,
Pressable,
Divider,
} from '@shopify/ui-extensions-react/checkout';
// Mock data for cat breeds
const catBreeds = [
{ placeId: '1', text: 'Siamese', description: 'Vocal and social' },
{ placeId: '2', text: 'Maine Coon', description: 'Large and friendly' },
{ placeId: '3', text: 'Bengal', description: 'Wild appearance with spots' },
{ placeId: '4', text: 'Persian', description: 'Long-haired and calm' },
{ placeId: '5', text: 'Scottish Fold', description: 'Distinctive folded ears' },
{ placeId: '6', text: 'Ragdoll', description: 'Docile and affectionate' },
{ placeId: '7', text: 'Sphynx', description: 'Hairless and energetic' },
{ placeId: '8', text: 'British Shorthair', description: 'Round face and dense coat' },
];
function Example() {
const [searchQuery, setSearchQuery] = useState('');
const [showSuggestions, setShowSuggestions] = useState(false);
const [selectedBreed, setSelectedBreed] = useState(null);
// Filter cat breeds based on search query
const searchResults = useMemo(() => {
if (!searchQuery.trim()) return [];
return catBreeds.filter(breed =>
breed.text.toLowerCase().includes(searchQuery.toLowerCase())
);
}, [searchQuery]);
// Handle when a suggestion is selected
const handleSuggestionSelect = useCallback((result) => {
setSelectedBreed(result);
setSearchQuery(result.text);
setShowSuggestions(false);
}, []);
return(
<View>
<BlockLayout minBlockSize="fill" rows={["auto", "fill"]}>
<BlockStack>
<TextField
label="Search Cat Breeds"
value={searchQuery}
onChange={(value) => {
setSearchQuery(value);
setShowSuggestions(true);
}}
onInput={(value) => {
setSearchQuery(value);
setShowSuggestions(true);
}}
icon={{ source: 'magnify' }}
/>
<TextField
label="Your cat's name"
/>
<TextField
label="It's favorite food"
/>
<TextField
label="It's favorite toy"
/>
<TextField
label="It's favorite activity"
/>
</BlockStack>
{showSuggestions && searchResults.length > 0 && (
<View
background="transparent"
padding={Style.default("none").when({ viewportInlineSize: { min: "medium" } }, ["none", "tight", "none", "tight"])}
minInlineSize="fill"
position={{ type: "absolute", blockStart: 58 }}
>
<BlockStack
accessibilityRole="unorderedList"
background="base"
spacing="none"
borderRadius="base"
>
{searchResults.map((result, index) => (
<View
key={result.placeId}
accessibilityRole="listItem"
background={Style.default("base").when({ hover: true }, "subdued")}
borderRadius={index === searchResults.length - 1 ? ["none", "none", "base", "base"] : "none"}
>
<Pressable
minInlineSize="fill"
padding="base"
onPress={() => handleSuggestionSelect(result)}
>
<BlockStack spacing="tight">
<Text>{result.text}</Text>
<Text size="small" appearance="subdued">{result.description}</Text>
</BlockStack>
</Pressable>
{index !== searchResults.length - 1 && <Divider />}
</View>
))}
</BlockStack>
</View>
)}
{selectedBreed && (
<View padding="base">
<BlockStack spacing="base">
<Text size="medium" emphasis="bold">Selected Cat Breed:</Text>
<Text>{selectedBreed.text}</Text>
<Text>{selectedBreed.description}</Text>
</BlockStack>
</View>
)}
</BlockLayout>
</View>
)
}
const CheckoutBlock = reactExtension(
'purchase.checkout.block.render',
() => <Example />,
);
export default CheckoutBlock;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment