Created
April 10, 2025 17:48
-
-
Save stlk/88ed53839742a98c69b32749c4fd0783 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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