Form Preference Center
A grouped preference center with native tri-state controls and controlled or local selection.
Notification preferences
These settings update this example only; choose the notices you want to receive.
Customise
Code
import { useState } from "react";
const groups = [
{ id: "product-updates", label: "Product updates", preferences: [
{ id: "release-notes", label: "Release notes" },
{ id: "monthly-digest", label: "Monthly digest" },
] },
{ id: "billing", label: "Billing notices", preferences: [
{ id: "invoice-notices", label: "Invoice notices" },
] },
];
const [value, setValue] = useState({ "release-notes": true, "monthly-digest": false });
<FormPreferenceCenter
title="Notification preferences"
groups={groups}
value={value}
onValueChange={setValue}
/>Form Preference Center lets people review independent account and notification choices by group. Each group control reports whether all, none, or some options are enabled, and a group change updates only that group's preferences.
Supply controlled values when the page owns the settings, or use defaultValue for local interaction. Missing option values start disabled. The component does not save, submit, or infer consent policy.
Install
Add the @te registry to your components.json once:
{
"registries": {
"@te": "https://templateempire.io/r/{name}.json"
}
}Then install the component:
npx shadcn@latest add @te/form-preference-centerUsage
import { FormPreferenceCenter } from "@/components/form-preference-center";
<FormPreferenceCenter
title="Notification preferences"
groups={[
{
id: "product",
label: "Product updates",
preferences: [
{ id: "release-notes", label: "Release notes" },
{ id: "monthly-digest", label: "Monthly digest" },
],
},
]}
defaultValue={{ "release-notes": true }}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
| title | string | required | Visible section heading. |
| groups | FormPreferenceGroup[] | required | Ordered groups with unique IDs, labels, and at least one preference each. |
| value | Record<string, boolean> | undefined | Controlled preference values; missing keys are false and unknown keys are ignored. |
| defaultValue | Record<string, boolean> | undefined | Initial values for uncontrolled use; missing preferences start disabled. |
| onValueChange | (next) => void | undefined | Receives the complete next map of known preference IDs after a user change. |
| className | string | undefined | Additional classes merged onto the section. |
Customisation
Use groups to match the account or notification areas your product already has. Controlled values remain authoritative; group toggles only change the preferences in that group. The callback map includes every known preference ID once, so the page can store or submit it using its own policy.
<FormPreferenceCenter
title="Workspace notices"
groups={workspaceNoticeGroups}
value={settings}
onValueChange={setSettings}
/>Frequently asked questions
- What does a mixed group control do?
- It shows a Mixed state when some, but not all, preferences in that group are enabled. Activating it enables the whole group; activating an already complete group disables it.
- Does the component save preferences?
- No. It emits a complete next value map, but persistence, consent rules, and form submission belong to the consuming page.
- Are unknown value keys kept?
- No. Rendering and emitted maps use only the preference IDs supplied in groups.