Unlock seamless workflows and faster delivery with our latest releases - Join the deep dive

Field components

About field and input components

In v2 you would use the inputComponent property to define custom inputs for any field in your schemas. This would often lead to having to write a lot of boilerplate code to make sure the studio would render your input component properly with all the bells and whistles – such as focus management, title and description and presence markers – before you could get to customizing the input itself.

In v3, creating input components has been made a lot easier by the assumption that in most cases you will be fine with the studio’s default rendering of fields, leaving you to concentrate on the input itself when you use the components.input property. You most likely want to use an input component, unless you need to override field meta info, validation, and or presence.

When you do want to control the rendering of the entire field there is components.field!

So, in v2, you'd do:

// v2

// schemas/post.js
{
   name: 'title',
   title: 'Title',
   type: 'string',
   inputComponent: MyStringInput,
},

And in v3, you'll use components.field:

// v3

// schemas/post.ts
{
  name: 'title',
  title: 'Title',
  type: 'string',
  components: {
    input: MyStringInput,
    field: MyStringField,
  },
},

This is how, in Studio v3, the concerns between fields and inputs are separated:

Minimal code example

This somewhat contrived example show how to change the color of the entire field based on the fields value. Fields of composite types may require some more implementation.

import {Card, Text} from '@sanity/ui'
import {StringFieldProps} from 'sanity'

function CustomStringField(props: StringFieldProps) {
  const {children , title, description, value='' } = props
  return (
    <Card padding={2} tone={value?.length > 15 ? 'caution' : 'positive'}  border>
      <Card paddingY={2}>
        <Text size={1} weight="semibold">{title}</Text>
      </Card>
      <Card paddingTop={1} paddingBottom={2}>
        <Text size={1} muted>{description}</Text>
      </Card>
      <Card>
        {children}
      </Card>
    </Card>
  )
}

Gotcha

Work in progress!

Documentation for all the new studio component types is not finished and you may find it lacks some depth and detail! Please let us know if this is important to you so we can prioritize!

Was this article helpful?