Using custom inputs to dynamically hide items in Sanity arrays.

16 replies
Last updated: Jan 4, 2023
Is there still no way to hide items from an array? mostly want to offer a cleaner editing experience to my clients so something like this:
   {
      title: 'Modules',
      name: 'modules',
      group: 'content',
      type: 'array',
      of: [
        {
          type: 'page.jobListings',
          hidden: ({document}) => document?.pageTemplate !== 'jobs',
        },
Jan 4, 2023, 7:18 PM
I may just make 4-5 different module arrays that are hidden at the main level but would love to keep it cleaner in a single modules[] field
Jan 4, 2023, 7:19 PM
You can't use the hidden callback, but you can use a custom input that leverages the
renderDefault
method to dynamically hide items in just a few lines of code. Here's an example of one that I made that hides items based on the current user's role.
Jan 4, 2023, 7:22 PM
rad let me check this out (still a v3 noob stuck in my old ways)
Jan 4, 2023, 7:22 PM
Ah, yeah, I should mention that's V3 specific and won't work in V2. You can do something similar in V2, but it would be significantly more code!
Jan 4, 2023, 7:24 PM
i’m using v3!
Jan 4, 2023, 7:24 PM
Perf!
Jan 4, 2023, 7:24 PM
so i am logging the props and don’t seem to have access to the doc i am on? trying to search the docs do i need to pass the pageTemplate field into options somehow?
Jan 4, 2023, 7:34 PM
You now have to use the hook
useFormValue
to get a field from the current document. For example:
import {useFormValue} from 'sanity'

const title = useFormValue(['title'])
Jan 4, 2023, 7:36 PM
💅 niiice
Jan 4, 2023, 7:49 PM
i think the only thing i noticed is the useFormValue doesn’t trigger right away does the field input need to be async?
Jan 4, 2023, 7:53 PM
like if i update the formValue(‘pageTemplate’) i actually need to hit it twice before it invalidates the input component
Jan 4, 2023, 7:54 PM
so basically if i switch to jobs (pageTemplate) and then to something else it shows me the jobs options after i switch and not when I initiall switched
Jan 4, 2023, 7:55 PM

const pageBlocks = [
  {type: 'page.jobListings', options: { template: 'jobs' }},
  {type: 'page.marquee', options: { template: 'any' }},
]

function PageTemplateInput(props) {
  const {schemaType, renderDefault} = props

  // Get active template
  const pageTemplate = useFormValue(['pageTemplate'])
  // filter allowed modules by the template type
  const allowedTypes = 
    schemaType.of.filter(({ options }) => {
      return options.template === pageTemplate || options.template === 'any'
    })
      
  //render the default component and replace the allowed types
  return renderDefault({...props, schemaType: {...schemaType, of: allowedTypes}})
}
Jan 4, 2023, 7:56 PM
Ah, that's currently a bug that's being addressed 😬
Jan 4, 2023, 7:56 PM
i’m always on the bleeding edge of bug finding
Jan 4, 2023, 7:56 PM
i can work around it for now cause i do think this is a much nicer experience
Jan 4, 2023, 7:57 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?