RD Pennell
Community 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;
Community Engineer at Sanity.io
Full stack developer at Spriio