Created
February 5, 2021 23:59
-
-
Save rexxars/1945c4b1b137cbd6f9b06e147ec4359d to your computer and use it in GitHub Desktop.
Custom product input, barebones
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 from 'react' | |
import Preview from 'part:@sanity/base/preview' | |
import FormField from 'part:@sanity/components/formfields/default' | |
import SearchableSelect from 'part:@sanity/components/selects/searchable' | |
import PatchEvent, {set, setIfMissing, unset} from 'part:@sanity/form-builder/patch-event' | |
const products = [ | |
{ | |
title: 'Adidas Superstar Canvas Green', | |
handle: 'canvas-grene', | |
image: {asset: {_ref: 'image-b22f453a74b78fcc40daaa3ecab5adb3b2f6b2d4-900x591-png'}}, | |
}, | |
{ | |
title: 'Adidas Superstar Vegan', | |
handle: 'vegan', | |
image: {asset: {_ref: 'image-2f6b31098bcc4a7c9824b3279c471a290bd50b0d-1350x778-png'}}, | |
}, | |
] | |
const searchProducts = (query) => | |
products.filter((prod) => prod.title.toLowerCase().includes(query.toLowerCase())) | |
export default React.forwardRef(function ProductInput(props, forwardedRef) { | |
const {type, value, level, markers, readOnly, presence, onChange} = props | |
const inputValue = value ? value.title : undefined | |
const errors = markers.filter( | |
(marker) => marker.type === 'validation' && marker.level === 'error' | |
) | |
const [hits, setHits] = React.useState([]) | |
const handleSearch = React.useCallback((query) => setHits(searchProducts(query)), [setHits]) | |
const handleOpen = () => handleSearch('') | |
const handleChange = (item) => | |
onChange(PatchEvent.from(setIfMissing({_type: type.name}), set(item))) | |
const handleClear = () => onChange(PatchEvent.from(unset())) | |
const renderHit = (item) => <Preview type={type} value={item} layout="default" /> | |
return ( | |
<FormField | |
markers={markers} | |
label={type.title} | |
level={level} | |
description={type.description} | |
presence={presence} | |
> | |
<SearchableSelect | |
ref={forwardedRef} | |
placeholder="Type to search…" | |
title={inputValue} | |
customValidity={errors.length > 0 ? errors[0].item.message : ''} | |
onOpen={handleOpen} | |
onFocus={props.onFocus} | |
onSearch={handleSearch} | |
onChange={handleChange} | |
onClear={handleClear} | |
value={value} | |
inputValue={inputValue === null ? value : inputValue} | |
renderItem={renderHit} | |
items={hits} | |
readOnly={readOnly} | |
/> | |
</FormField> | |
) | |
}) |
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 ProductInput from './ProductInput' | |
export default { | |
name: 'product', | |
title: 'Product', | |
type: 'object', | |
fields: [ | |
{ | |
name: 'title', | |
title: 'Title', | |
type: 'string', | |
}, | |
{ | |
name: 'handle', | |
title: 'Handle', | |
type: 'string', | |
}, | |
{ | |
name: 'image', | |
title: 'image', | |
type: 'image', | |
}, | |
], | |
preview: { | |
select: { | |
title: 'title', | |
media: 'image', | |
}, | |
}, | |
inputComponent: ProductInput, | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment