Geoff Ball
Support Engineer at Sanity.io
A custom input component that lets the schema creator control max, min, and step values on a number input.
import React from 'react';
import { TextInput } from '@sanity/ui';
import { FormField } from '@sanity/base/components';
import PatchEvent, { set, unset } from '@sanity/form-builder/PatchEvent';
import { useId } from '@reach/auto-id';
export const ControlledNumber = React.forwardRef((props, ref) => {
const {
type,
value,
readOnly,
markers,
presence,
compareValue,
onFocus,
onBlur,
onChange,
} = props;
const { title, description, placeholder, options } = type;
const { min, max, step } = options ?? { min: -Number.MAX_SAFE_INTEGER, max: Number.MAX_SAFE_INTEGER, step: 1 };
const handleChange = React.useCallback((event) => {
let inputValue = Number.parseFloat(event.currentTarget.value);
if (Math.abs(inputValue) > Number.MAX_SAFE_INTEGER) inputValue = Math.sign(inputValue) * Number.MAX_SAFE_INTEGER;
onChange(PatchEvent.from(inputValue ? set(inputValue) : unset()))
}, [onChange]);
const inputId = useId();
return (
<FormField
inputId={inputId}
compareValue={compareValue}
description={description}
title={title}
__unstable_markers={markers}
__unstable_presence={presence}
>
<TextInput
id={inputId}
onChange={handleChange}
value={value}
readOnly={readOnly}
placeholder={placeholder}
onFocus={onFocus}
onBlur={onBlur}
ref={ref}
type="number"
min={min || -Number.MAX_SAFE_INTEGER}
max={max || Number.MAX_SAFE_INTEGER}
step={step || 1}
/>
</FormField>
);
});
import { ControlledNumber } from '../path/to/controlled-number';
export default {
name: "documentName",
title: "Document Name",
type: "document",
fields: [
// ...,
{
name: 'numberField',
title: 'Number Field',
type: 'number',
// description: 'Optional description',
// placeholder: 'Optional placeholder value',
// validation: Rule => Rule.required().min(1),
inputComponent: ControlledNumber,
options: {
min: 1,
max: 10,
step: 1,
}
},
// ...
],
}
Using a custom input component, we can add an HTML input with type="number"
that lets the schema developer control the min
, max
, and/or step
values of that input.
The name and file location of your input component do not matter—you just need to be able to import the file into your schema.
The options
property is optional. When omitted, step
will default to 1 and max
and min
will default to positive and negative Number.MAX_SAFE_INTEGER
, respectively. However, at that point use of the custom component is moot.
Steps:
controlled-number.js
and put it in a components/
directory in the root of my studio) and add the input component code from above.ControlledNumber
:import { ControlledNumber } from '../components/controlled-number';
number
and an inputComponent
property of ControlledNumber
. Specify max
, min
, and step
in an options
object, as required.Support Engineer at Sanity.io
This snippet can be used to fetch current, previous and next articles based on publication date and related tags.
Go to Get current, previous and next post, filtered by tagsIf you'd like to be able to reference your project users within your content, you'll need to create a document for them.
Go to Create A Document for All Current Project UsersScript to batch remove a field from all documents that match a GROQ query
Go to Batch remove a fieldGROQ query that finds duplicate data in a given field.
Go to GROQ query to find duplicate data