Created
December 10, 2021 14:19
-
-
Save SimeonGriggs/55522557a834db113eec35e1c9690760 to your computer and use it in GitHub Desktop.
Sanity.io Custom Input that will still resolve the default UI for field editing
This file contains 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
/** | |
* Custom Input that will resolve Sanity's default UI for field editing | |
* As well as display some contextual information from the document | |
* This is example is for an `array` field of `car` type fields | |
* For which the default UI is shown below an image from the first array item | |
* | |
* The implementation is *not* bulletproof and only has basic handling | |
* of the potential pitfalls of recursive rendering of the | |
* <FormBuilderInput /> component | |
*/ | |
/* eslint-disable react/prop-types */ | |
/* eslint-disable react/display-name */ | |
import React from 'react' | |
import {Stack, Text} from '@sanity/ui' | |
import {FormBuilderInput} from '@sanity/form-builder/lib/FormBuilderInput' | |
import {withDocument} from 'part:@sanity/form-builder' | |
import imageUrlBuilder from '@sanity/image-url' | |
import sanityClient from 'part:@sanity/base/client' | |
const builder = imageUrlBuilder(sanityClient) | |
const urlFor = (source) => builder.image(source) | |
const imageStyle = {width: `100%`, height: `auto`} | |
const DecoratedArray = React.forwardRef((props, ref) => { | |
const {type, document: sanityDocument} = props | |
// Attempt prevention of infinite loop in <FormBuilderInput /> | |
// Re-renders can still occur if this Component is used again in a nested field | |
const typeWithoutInputComponent = React.useMemo(() => ({...type, inputComponent: null}), [type]) | |
// Using some data from the document to decorate the UI | |
// This part can be removed and replaced with whatever contextual info you want to display | |
const displayImage = React.useMemo( | |
() => | |
sanityDocument?.cars?.length && sanityDocument.cars[0]?.image | |
? { | |
name: sanityDocument.cars[0].name, | |
url: urlFor(sanityDocument.cars[0].image).width(800).url(), | |
} | |
: null, | |
[sanityDocument] | |
) | |
return ( | |
<Stack space={2}> | |
{displayImage?.url ? ( | |
<img src={displayImage.url} alt={displayImage.name} style={imageStyle} /> | |
) : ( | |
<Text>No images or first item does not have an image</Text> | |
)} | |
<FormBuilderInput {...props} type={typeWithoutInputComponent} ref={ref} /> | |
</Stack> | |
) | |
}) | |
export default withDocument(DecoratedArray) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment