Help needed with building a nested category system in JavaScript
3 replies
Last updated: Feb 16, 2023
B
I know I've asked this before... but I can't find the answer anywhere, apologies.
In v2, when creating custom components, we could access the validation rules of a field to provide data back to the custom components. (see
here for v2 docs example)
Schema data example:
and in the custom component example:
Unfortunately, the v3 docs don't provide much insight into accessing the validation rules now. Any examples that someone could share?
In v2, when creating custom components, we could access the validation rules of a field to provide data back to the custom components. (see
here for v2 docs example)
Schema data example:
validation: Rule => Rule.max(100)
and in the custom component example:
import { TextInput, Stack, Text } from '@sanity/ui' ... const MaxConstraint = type.validation[0]._rules.filter(rule => rule.flag == 'max')[0].constraint const handleChange = React.useCallback( (event) => { const inputValue = event.currentTarget.value onChange(PatchEvent.from(inputValue ? set(inputValue) : unset())) }, [onChange] ) ... <Text muted size={1}>{value ? value.length : '0'} / {MaxConstraint}</Text>
Feb 10, 2023, 2:15 AM
I haven’t implemented them, but both
validationand
validationErrorare provided to a field component through
props. Maybe try playing around with one of those?
Feb 10, 2023, 7:14 PM
B
For others who might be interested...
I'm sure this could be done better. If you have any suggestions I'm all ears. This is very much a WIP ...
/ A function that returns only objects containing specified key/value pairs. // Not all validation rules are required for this component. // ! Be sure that your schema validation rules are concatenated `Rule.min(20).max(50)` and not passed as an array of rules `[Rule.min(20), Rule.max(50)]` function findByKeyValue(array: any, key: any, value: any) { var result = array.find(function (obj: any) { return obj[key] === value; }); return result || null; } export function CharacterCounterField(props: any) { // Assign our array for ease of use const rulesArray = props.schemaType.validation[0]._rules; // Get our min and max values from the validation rules const min = findByKeyValue(rulesArray, "flag", "min"); const max = findByKeyValue(rulesArray, "flag", "max"); // Set our colour based on the length of the value // @TODO Can this be logical query be improved? let myColour; max !== null && props.value?.length < max.constraint && min !== null && props.value?.length > min.constraint ? (myColour = "green") : (myColour = "red"); return ( <Stack space={3}> {!-- @TODO Customise TextInput for green bg and borders when in range --} {props.renderDefault(props)} <Text size={1} style={{ color: myColour, }} > Characters: {props.value?.length || 0}. </Text> </Stack> ); }
Feb 13, 2023, 11:25 AM
B
the
validationdata is exposed in a number of areas in the
props. I choose the
props.schemaTypeas opposed to
props.validationbut I'm not sure why multiple validation types are in the props? What is the purpose of
validationError? Does this provide custom validation error messages defined in the fields schema?
Feb 16, 2023, 4:02 AM
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.