sanity
sanity copied to clipboard
Allow dynamic `options.list` for String type schema
Is your feature request related to a problem? Please describe. I want to create dynamic fields based on other fields. I need some behaviour like filter in references. There is built-in list for String schema which is fine, but I need the list to be dynamic, based on other field. The biggest use case for me is when I'm putting in an address and have country and region fields. The available regions is dependent on which country I pick.
Describe the solution you'd like Implement
type StaticList = Array<string> | Array<{title: string; value: string}>
type StringOptionsList = StaticList | (docOptions) => StaticList
Describe alternatives you've considered Nothing else really solves what I wanted
This is essentially a copy of #2821, which was autoclosed.
I was working on something like this (if I understand correctly). Keep in mind that's code for v3 but I haven't checked if it was working on the latest 3.x because I moved to another project at work.
Custom input component:
function ListOverrideField(props: StringInputProps) {
const document = useFormValue([])
//@ts-ignore
props.schemaType.options.list = props.schemaType.options.listGenerator({
document,
path: props.path,
})
return props.renderDefault(props)
}
Usage:
defineField({
name: 'group',
title: 'Group',
description: 'Decide if this variant is standalone or belongs to a group',
type: 'string',
components: {
input: ListOverrideField,
},
options: {
//@ts-ignore
listGenerator: ({document}) => {
const groups = (document.productVariantsGroups || []).map((group) => {
return {title: group.name, value: group._key}
})
return [{title: 'None', value: undefined}].concat(groups)
},
layout: 'radio',
},
}),
I had to add a few @ts-ignore because the default types are not ready for this kind of wizardry, but basically in this configuration the possibles string values for the group field are generated based on the values inside the productVariantsGroups field of the same document.
Was there any progress on this? I've been searching documentation
Besides @tbassetto's custom component, no, I don't think so.
@tbassetto Is there a way to execute a grok query in the list generator function?
@tbassetto Is there a way to execute a grok query in the list generator function?
We could find a way to pass down the client to listGenerator but it cannot be an async function so I am afraid we can't execute a GROQ query no.
Would be great if the API was simply:
{
name: '...',
type: 'string',
options: {
list: async () => {
const res = await ...
return res // { title: '...', value: '...' }[]
}
}
}
im with @sameerxanand this would be awesome
I know this is still not as direct as you might like, but I've used this pattern to build an options list based on the value of another field. Using a custom component.input to create the list allows for the use of useFormValue, useClient hooks or any other hooks, if needed.
But having a way to do this more directly would be cool too. Just thought I'd add this here in case someone stumbles on this and needs an immediate solution.
Yeah I would love similar functionality like this but to generate a an options.list attribute filled with slugs from other documents I have in my Sanity database.
This could solve the problem of doing internal linking a bit more developer-friendly, as you would be able to get slug fields without references, and therefore no need to expand your GROQ query everytime there is a link.
Keen to see any follow up or if anyone has an idea for my use case!