🔮 Sanity Create is here. Writing is reinvented. Try now, no developer setup

Passing down attributes in Sanity using functional components for complex structures

6 replies
Last updated: Dec 8, 2021
Is it possible to pass down attributes of an object like you would a React component? eg.

{
 name: 'someField',
 customAttribute: 'foo',
 type: array,
 fields: [
   {
   name: 'child',
   type: 'string',
   inheritedAttribute: parent.customAttribute,
   validation: Rule = Rule.max(inheritedAttribute)
   }.
 ]
}
Trying to use as simple validation as possible on the lowest possible level field to avoid some issues we are having with complex validation.
Dec 3, 2021, 3:41 AM
Hi Jeremy,
did you get solution to pass the attributes down to child objects?
Dec 3, 2021, 11:51 AM
You can't pass down attributes like this, but if you move the validation to the parent array you can set it up to validate its children .
Dec 3, 2021, 6:12 PM
Hey
user Q
and
user M
- I did find a solution and that is to make a ‘functional component’ ie. A function that returns a JSON object in Sanity’s format. This way you can handle inheritance kind of like you would a callback or React props.
Dec 8, 2021, 5:21 AM
import customValidations from "../helpers/customValidations";
import FilteredLocaleBlock from '../custom-inputs/filteredLocaleBlock'


const filteredLocaleImage = (options) => {
    
    const validOptions = {
        // TODO file types should be an array to support multiple valid files
        fileType: 'string',
        maxHeight: 'number',
        maxWidth: 'number',
    }
    
    // Checks Option structure before building object
    if( customValidations.validateOptions(options, validOptions) ) {
        
        return {
            name: 'filteredLocaleImage',
            title: 'Image',
            type: 'object',
            fieldsets: [{
                title: 'Translations',
                name: 'translationsImage',
                options: {
                    collapsible: true
                }
            }],
            
            fields: [{
                name: "baseImage",
                title: "Base English",
                type: 'image',
                options: {
                    collapsible: false
                },
                validation: Rule => Rule.required().custom((Image) => {
                    
                    // Only run validation where base Image exists
                    if(Image){
                        const baseImageValidation = customValidations.validateImage(Image, options.fileType, options.maxWidth, options.maxHeight)
                        if(typeof baseImageValidation === 'string'){
                            return baseImageValidation
                        }
                    }
                    return true
                    
                })
            },
            {
                name: "localisedImage",
                type: "localeImage",
                inputComponent: FilteredLocaleBlock,
                title: "Image",
                fieldset: 'translationsImage',
                validation: Rule => Rule.custom((Image) => {
                    
                    // Only run validation where base Image exists
                    if(Image){
                        const baseImageValidation = customValidations.validateImage(Image, options.fileType, options.maxWidth, options.maxHeight)
                        if(typeof baseImageValidation === 'string'){
                            return baseImageValidation
                        }
                    }
                    return true
                    
                })
            }
        ]
    }
}
}
Dec 8, 2021, 5:24 AM
This way you can pass rules down to the exact image that has the error and get more accurate error reporting - we found the solution
user M
recommends is good for validating a simple object and it’s children but since we have a bit more complex a structure the functional workflow allowed for more flexibility
Dec 8, 2021, 5:27 AM
Thanks for sharing,
user T
!
Dec 8, 2021, 4:17 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?