Help needed porting custom input component from V2 to V3 for Vimeo video async select
1 replies
Last updated: Jan 17, 2023
P
Hey! I need a little help porting a custom input component from V2 to V3. It's a Vimeo video async select.It's based on these great resources:
•
https://www.sanity.io/schemas/asynchronous-list-options-component-05f63a29 •
https://www.sanity.io/ui/docs/component/autocomplete#example-with-custom-rendering The last thing I need to do, and can't quite figure out how to, is to access an item's payload inside my
🙂 Thanks !
•
https://www.sanity.io/schemas/asynchronous-list-options-component-05f63a29 •
https://www.sanity.io/ui/docs/component/autocomplete#example-with-custom-rendering The last thing I need to do, and can't quite figure out how to, is to access an item's payload inside my
onChangeevent... I'm a Vue guy so it might be a very easy React trick but I'm kinda stuck now...The approach I have in mind is access my payload object then create my object as per my schema and then use the
set()to update my content lake.Here's my code so far. Any help will be appreciated
🙂 Thanks !
import {Card, Autocomplete, Flex, Box, Text} from '@sanity/ui' import {SearchIcon} from '@sanity/icons' import {BsPlayBtn} from 'react-icons/bs' import {useCallback, useEffect, useState} from 'react' import {set, unset} from 'sanity' import axios from 'axios' const params = '?fields=uri,created_time,name,description,link,pictures,files,width,height,duration&per_page=100' const AsyncVimeoSelect = (props) => { const [listItems, setListItems] = useState([]) const {onChange, value = '', id, focusRef, onBlur, onFocus, readOnly} = props const handleChange = useCallback( (event) => { // console.log(event) // const nextValue = event.currentTarget.value onChange(event ? set({name: event}) : unset()) }, [onChange] ) useEffect(() => { const getItems = async () => { const items = await axios .get( `<https://api.vimeo.com/me/projects/${> import.meta.env.SANITY_STUDIO_VIMEO_FOLDER }/videos${params}`, { headers: { Authorization: `Bearer ${import.meta.env.SANITY_STUDIO_VIMEO_TOKEN}`, }, } ) .then((res) => { return res.data.data.map((video) => { return {value: video.name, payload: video} }) }) setListItems(items) } getItems() }, []) return ( <Card padding={[3, 3, 4]} paddingBottom={[8, 8, 9]}> <Autocomplete filterOption={(query, option) => option.payload.name.toLowerCase().indexOf(query.toLowerCase()) > -1 } fontSize={[2, 2, 3]} icon={SearchIcon} openButton options={listItems} padding={[3, 3, 4]} placeholder="Type to find item …" renderOption={(option) => ( <Card as="button"> <Flex align="center"> <Box paddingLeft={3} paddingY={2}> <BsPlayBtn /> </Box> <Box flex={1} padding={3}> <Text size={[2, 2, 3]}>{option.payload.name}</Text> </Box> </Flex> </Card> )} renderValue={(value, option) => { return option.payload.name }} onChange={handleChange} /> </Card> ) } export default AsyncVimeoSelect
Jan 17, 2023, 10:51 AM
P
Little update. It's working now, But I don't know if using
import useState from 'react-usestateref'is the most elegant solution 😜 ?
import {Card, Autocomplete, Flex, Box, Text, Stack} from '@sanity/ui' import {SearchIcon} from '@sanity/icons' import {BsPlayBtn} from 'react-icons/bs' import useState from 'react-usestateref' import {useCallback, useEffect} from 'react' import {set, unset} from 'sanity' import axios from 'axios' const params = '?fields=uri,created_time,name,description,link,pictures,files,width,height,duration&per_page=100' const AsyncVimeoSelect = (props) => { const [listItems, setListItems, itemsRef] = useState([]) const {onChange, value = '', id, focusRef, onBlur, onFocus, readOnly} = props const handleChange = useCallback( (val) => { const item = val ? itemsRef.current.find((item) => (item.payload.uri = val)) : '' const itemObj = {...item?.payload} onChange(val ? set(itemObj) : unset()) }, [onChange] ) useEffect(() => { const getItems = async () => { const items = await axios .get( `<https://api.vimeo.com/me/projects/${> import.meta.env.SANITY_STUDIO_VIMEO_FOLDER }/videos${params}`, { headers: { Authorization: `Bearer ${import.meta.env.SANITY_STUDIO_VIMEO_TOKEN}`, }, } ) .then((res) => { return res.data.data.map((video) => { return {value: video.uri, payload: video} }) }) setListItems(items) } getItems() }, []) return ( <Autocomplete filterOption={(query, option) => option.payload.name.toLowerCase().indexOf(query.toLowerCase()) > -1 } fontSize={2} icon={SearchIcon} openButton options={listItems} padding={[2, 2, 3]} radius={0} placeholder="Type to find item …" renderOption={(option) => ( <Card as="button"> <Flex align="center"> <Box paddingLeft={3} paddingY={2}> <BsPlayBtn /> </Box> <Box flex={1} padding={3}> <Stack flex={1} space={2}> <Text size={2}>{option.payload.name}</Text> <Text muted size={1}> {option.payload.uri} </Text> </Stack> </Box> </Flex> </Card> )} renderValue={(value, option) => { return option.payload.name // return ( // <Box flex={1} padding={3}> // <Stack flex={1} space={2}> // <Text size={2}>{option.payload.name}</Text> // <Text muted size={1}> // {option.payload.uri} // </Text> // </Stack> // </Box> // ) }} onChange={handleChange} /> ) } export default AsyncVimeoSelect
Jan 17, 2023, 11:59 AM
Sanity– build remarkable experiences at scale
The Sanity Composable Content Cloud is the headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.