Summarise form progression by decorating the entire editing form for a document with a component loaded at the root level.
What you need to know:
This guide assumes that you know how to set up and configure a Sanity Studio and have basic knowledge about defining a schema with document and field types. Basic knowledge of React and TypeScript is also useful, although you should be able to copy-paste the example code to get a runnable result.
Custom form components by example
One of Sanity Studio’s most powerful features is custom drop-in replacements for form fields. This guide is one in a series of code examples.
Customize the document form and interact with its values
Make a form customization that’s composable using render methods
Use Sanity UI in combination with a third-party library to make a custom form progress bar UI
Schema preparation
The imaginary scenario is that your Studio contains preflight documents which contain a checklist to complete before getting approval to proceed. Users of this Studio could benefit from clearly showing how close to completion the current form is.
To complete this guide you’ll need to add a new document type first. Create the following file in your Studio and make sure to import it into the schema in sanity.config.ts:
Now create a new document. It’s a functional column of boolean fields.
A standard document with default boolean fields
All these fields should have detailed description values, but for brevity in this guide, they’ve been omitted. Now you can make this a truly excellent editing experience.
Customizing the document form
Create a custom form component to display the form’s current progress:
Unlike other guides in this series where the component is decorating or replacing a built-in part of the Studio – this component will receive props and be rendered on its own.
The props it receives will be the field members that make up the form. In the component you’ll check for every boolean type field, and create array of just their names and whether they’re currently to true or falsy.
The component will also be loaded from a different location, as demonstrated below:
// ./sanity.config.tsximport{defineConfig, isObjectInputProps}from'sanity'import{Stack}from'@sanity/ui'import{Progress}from'./schema/preflight/Progress'exportdefaultdefineConfig({// ...all other settings
form:{
components:{input:(props)=>{if(
props.id ==='root'&&
props.schemaType.type?.name ==='document'&&
props.schemaType.name ==='preflight'){returnProgress(props as ObjectInputProps)}return props.renderDefault(props)},},},})
Notice how you’ll only load the Progress component if the root of the form is being rendered, and only on the preflight schema type and it’s the document component. Yes, in this case the Studio treats the whole document form as an “input component”.
Open a preflight document now and try changing a few boolean fields. A summary of your progress is now displayed at the top of the form. It goes green once all fields are completed. Best of all, the counts will be correct even if boolean fields are added or removed from the document schema.
A normal document form with a component rendered at the top
Notice the imports include hues from @sanity/color so that this 3rd party component can still be styled to look like a consistently designed part of the Studio UI.
The document form now shows a Sanity color-compliant progress indicator!
Job done!
Next steps
Add a React confetti package to shower your author with celebratory praise when a document reaches completion.
Imagine how this might be used to call a 3rd party API to retrieve and display additional information based on values in the form.
Other ideas include using an image generation package like Satori to generate an image based on values in the document.
Object types use a preview property to display contextual information about an item when they are inside of an array; customizing the preview component can make them even more useful for content creators.