shadcn.io is not affiliated with official shadcn/ui
Notification Preference Grid Table Block for Ark UI
An events-by-channels grid of checkboxes with a tri-state head checkbox per channel, an All channels switch per event, a locked Required cell for security alerts by email and a saved-in-this-demo status line.
Installation
Overview
Let people choose how they are told about each thing, with this notification grid for React with Ark UI. A compact header names the settings and holds a Reset button. Inside a hairline frame with a plus mark on each corner, a native table puts six Nudgebox events down the side and Email, Push, SMS and Chat across, a Checkbox in every cell inside hairline lines. Under each channel's name a head checkbox turns that channel on or off for every event, ticked, empty or a dash when only some are on. Under each event's name a Switch, "All channels", does the same along the row. One cell is locked: Security alerts always go by email, so it is ticked, cannot be cleared and says "Required" under it. A polite line says what each change did and that it is saved in this demo. On a phone the channel names shorten to two letters. It is built from Checkbox, Switch, Button and Guides. For notification settings, channel preferences and any grid where a row and a column both mean something.
FAQ
How do I use my own events and channels?
Edit TOPICS (an id, a label, a note and the channel it requires, or an empty string), CHANNELS (with the two-letter form for phones) and START, the cells that begin on. Heads, switches and the dash all follow the data, so there is nothing else to keep in step.
How does the locked cell work?
A required cell is always on. Its box is ticked in a quieter solid, carries a lock and the word "Required", and stays focusable so its name can be read ("Email for Security alerts, required"). Pressing it answers in the status line, and the head and row controls skip it: turning Email off for every event leaves Security alerts on.
What do the head checkbox and the row switch do?
The head checkbox sets one channel for every event that allows it; it is ticked when all are on, empty when none and a dash when some. The row switch sets every channel of one event the same way and is on only when all four are. Both skip locked cells.
Is it accessible?
Every box is named by its channel and event, every switch by its event ("All channels for Weekly digest"), and the short heads on a phone keep the full names for assistive technology. The table has a caption and one polite line reports each change.
What stays local, and how do I save for real?
The choices are one useState list and "Saved in this demo" is only the message. To make it real, send each change from setCell, setChannel and setRow to your preferences API, and show the saved message when it answers; a server should also refuse to clear a required channel.