You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In our Sanity schemas we often create custom functions instead of reusable fields to give more customisation and control over the schema building. An example of this is a re-usable externalLink function that takes the required as a prop, see the example here:
// Define a generic FieldDef type that captures additional properties via TOtherPropsexporttypeFieldDef<T,TNameextendsstring,TRequiredextendsboolean=boolean,TOtherProps=object,>=Omit<T,"type">&{name: TNamerequired: TRequiredgroup?: string}&TOtherPropsexportfunctionexternalLinkField<TNameextendsstring,TRequiredextendsboolean,TOtherProps=object,>(props: FieldDef<UrlDefinition<TRequired>,TName,TRequired,TOtherProps>){if(props.required===true){returndefineField({
...props,type: "url",options: {
...props.options,required: props.required,},validation: (Rule)=>{construles=[Rule.uri({scheme: ["https","http","mailto","tel"],}).error('Invalid URL. The URL must start with "https://", "http://", "mailto:" or "tel:',),Rule.required().error("This field is required."),]returnrules},})}returndefineField({
...props,type: "url",options: {
...props.options,required: props.required,},validation: (Rule)=>{construles=[Rule.uri({scheme: ["https","http","mailto","tel"],}).error('Invalid URL. The URL must start with "https://", "http://", "mailto:" or "tel:',),]returnrules},})}
This works fine but is a bit verbose. It does not work with a conditional validation on the rule.
A reason why we want to do this is to be more aware about validation when setting up schemas, as well as render a simple custom input component when fields are required (by checking schemaType.options.required).
My first question is then – is there any better way to do this pattern?
We also use these kinds of functions for fields with different options. A good example is this "figure" schema:
constaltText=defineField({name: "alt",title: "Alt text",type: "string",description:
"Describe the content of the image. Important for SEO and accessiblity.",hidden: ({
parent,}: {parent: {decorative: boolean}})=>{returnparent?.decorative},validation: (Rule)=>Rule.custom((field,context)=>{constparent=context.parentasImageFieldsTypeif(!parent)returntrueif(parent?.decorative||!parent?.asset||(field&&field.length>0)){returntrue}return"Alt text is required"}),})exportconstfigureField=<TNameextendsstring,TRequiredextendsboolean,TOtherPropsextends{showAlt?: booleanshowDecorative?: booleanshowCaption?: boolean},>(props: FieldDef<ImageDefinition<true,{name: TName},TRequired>,TName,TRequired,TOtherProps>,)=>{const{
name,
title,
group,
hidden,
showAlt =true,
showCaption =true,
showDecorative =true,}=props//const excludeAllFields = excludeCaption && excludeAltreturndefineField({
name,title: title,type: "image",
group,
hidden,options: {hotspot: true,},fields: [
...(showAlt ? [altText] : []),
...(showDecorative
? [defineField({name: "decorative",title: "Is the image purely decorative?",type: "boolean",initialValue: false,}),]
: []),
...(showCaption
? [defineField({name: "caption",title: "Caption",type: "string",}),]
: []),],validation: (Rule)=>{returnprops.required ? Rule.required().assetRequired() : Rule.optional()},preview: {select: {imageUrl: "asset.url",title: "caption",},prepare({ title, imageUrl }){return{title: title??" ",
imageUrl,}},},})}
Since neither of these add on fields are always required, they are defined as possibly undefined in the schema which is fine, but if we add a required to i.e. the caption our type expects it to always be a string regardless.
Is there any way to make this work? I guess I can solve this case by making the required conditional based on the showCaption
Also for some reason the "hack" with duplicate defineField does not work for this figureField.
Hopefully this is not out of bounds of this package, because it is a very powerful tool to create schemas. Any pointers or tips would be greatly appreciated!
The text was updated successfully, but these errors were encountered:
Hi!
In our Sanity schemas we often create custom functions instead of reusable fields to give more customisation and control over the schema building. An example of this is a re-usable externalLink function that takes the required as a prop, see the example here:
This works fine but is a bit verbose. It does not work with a conditional validation on the rule.
A reason why we want to do this is to be more aware about validation when setting up schemas, as well as render a simple custom input component when fields are required (by checking schemaType.options.required).
My first question is then – is there any better way to do this pattern?
We also use these kinds of functions for fields with different options. A good example is this "figure" schema:
Since neither of these add on fields are always required, they are defined as possibly undefined in the schema which is fine, but if we add a required to i.e. the caption our type expects it to always be a string regardless.
Is there any way to make this work? I guess I can solve this case by making the required conditional based on the showCaption
Also for some reason the "hack" with duplicate defineField does not work for this figureField.
Hopefully this is not out of bounds of this package, because it is a very powerful tool to create schemas. Any pointers or tips would be greatly appreciated!
The text was updated successfully, but these errors were encountered: