Skip to content

Instantly share code, notes, and snippets.

@madx
Forked from j-bullard/App.tsx
Last active July 29, 2022 05:58
Show Gist options
  • Save madx/0bcf355a539bf064d3090ec0f5bef93e to your computer and use it in GitHub Desktop.
Save madx/0bcf355a539bf064d3090ec0f5bef93e to your computer and use it in GitHub Desktop.
Headless UI with React Hook Forms
import "./styles.css";
import { Person } from "./types";
import { Listbox } from "./listbox/listbox";
import { useForm } from "react-hook-form";
const people: Person[] = [
{ id: 1, name: "Durward Reynolds", unavailable: false },
{ id: 2, name: "Kenton Towne", unavailable: false },
{ id: 3, name: "Therese Wunsch", unavailable: false },
{ id: 4, name: "Benedict Kessler", unavailable: true },
{ id: 5, name: "Katelyn Rohan", unavailable: false }
];
export default function App() {
const { control } = useForm();
return (
<div className="App">
<Listbox<Person>
name="people"
control={control}
rules={{ required: true }}
collection={people.map(person => ({
key: person.id,
label: person.name,
disabled: person.unavailable,
})}
/>
</div>
);
}
import { useController, UseControllerProps } from "react-hook-form";
import { Listbox as ListBox } from "@headlessui/react";
type ListboxItem = {
key: string,
label: string,
disabled: boolean,
};
type Props = {
collection: ListboxItem[];
defaultText: string;
};
export const Listbox = <T>(props: Props & UseControllerProps<T>) => {
const {
field: { value, onChange }
} = useController(props);
const { collection, defaultText } = props;
return (
<>
<ListBox value={value} onChange={onChange}>
<ListBox.Button>
{value ? value.label : defaultText}
</ListBox.Button>
<ListBox.Options>
{collection.map((item) => (
<ListBox.Option
key={item.key}
value={item}
disabled={item.disabled}
>
{item.label}
</ListBox.Option>
))}
</ListBox.Options>
</ListBox>
</>
);
};
export type Person = {
id: number;
name: string;
unavailable: boolean;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment