RD Pennell
Senior Support Engineer at Sanity.io
RD is located at Richmond, CA
This will allow you to display an array of references as a checklist from which you can multi-select.
{
name: "ReferenceMultiSelect",
description: "Select categories",
title: "Category Type",
type: "array",
of: [
{
type: "reference",
to: { type: "categories" },
},
],
components: {
input: ReferenceSelect,
},
},
import React, { useEffect, useState } from "react";
import { Card, Flex, Checkbox, Box, Text } from "@sanity/ui";
import client from "./client";
import { useId } from "@reach/auto-id";
import { FormField, PatchEvent, set } from "sanity";
const ReferenceSelect = React.forwardRef((props, ref) => {
const [categories, setCategories] = useState([]);
useEffect(() => {
const fetchCountries = async () => {
await client
.fetch(
`*[_type == 'categories']{
...,
_id,
category
}`
)
.then(setCategories);
};
fetchCountries();
}, []);
const {
type, // Schema information
value, // Current field value
readOnly, // Boolean if field is not editable
markers, // Markers including validation rules
presence, // Presence information for collaborative avatars
compareValue, // Value to check for "edited" functionality
onFocus, // Method to handle focus state
onBlur, // Method to handle blur state
onChange, // Method to handle patch events,
} = props;
const handleClick = React.useCallback(
(e) => {
const inputValue = {
_key: e.target.value.slice(0, 10),
_type: "reference",
_ref: e.target.value,
};
if (value) {
if (value.some((country) => country._ref === inputValue._ref)) {
onChange(
PatchEvent.from(
set(value.filter((item) => item._ref != inputValue._ref))
)
);
} else {
onChange(PatchEvent.from(set([...value, inputValue])));
}
} else {
onChange(PatchEvent.from(set([inputValue])));
}
},
[value]
);
const inputId = useId();
return (
<FormField
description={type?.schemaType.description} // Creates description from schema
title={type?.schemaType.title} // Creates label from schema title
__unstable_markers={markers} // Handles all markers including validation
__unstable_presence={presence} // Handles presence avatars
compareValue={compareValue} // Handles "edited" status
inputId={inputId} // Allows the label to connect to the input field
readOnly={readOnly}
>
{categories.map((cat, index) => (
<Card key={index} padding={2}>
<Flex align="center">
<Checkbox
id={cat._id}
style={{ display: "block" }}
onClick={handleClick}
onChange={() => console.log("changed")}
value={cat._id}
checked={
value ? value.some((item) => item._ref === cat._id) : false
}
/>
<Box flex={1} paddingLeft={3}>
<Text>
<label htmlFor={cat._id}>{cat.category}</label>
</Text>
</Box>
</Flex>
</Card>
))}
</FormField>
);
});
export default ReferenceSelect;
Senior Support Engineer at Sanity.io
Full stack developer at Spriio
Populate your list options in a string schema using an external API
Go to Asynchronous List Options ComponentUse the renderDefault function to easily control your available array options.
Go to Filter Array Options Based on the Current User Role