Skip to content
kerfjsGitHub

NotificationPreferences

A grid of what to be told about, and how.

SourcePackage @kerf-js/veneer

Preview

tsx
import { NotificationPreferences } from '@kerf-js/veneer'import type { PrefGroup } from '@kerf-js/veneer-core'export function Kerf() {  return (  <NotificationPreferences    groups={PREF_GROUPS}    channels={CHANNELS}    value={PREFS}    offered={PREF_OFFERED}    locked={PREF_LOCKED}    defaults={{ value: PREFS }}    onChange={() => pause(400)}    onDigest={() => pause(400)}  />  )}const CHANNELS = [  { id: 'inapp', label: 'In-app' },  { id: 'email', label: 'Email' },  { id: 'push', label: 'Push' },  { id: 'sms', label: 'SMS' },]const PREF_GROUPS: PrefGroup[] = [  {    id: 'deploys',    label: 'Deploys',    events: [      {        id: 'failed',        label: 'Failed deploys',        hint: 'A deploy you own fails a check',      },      {        id: 'live',        label: 'Deploys gone live',        hint: 'On projects you watch',      },      {        id: 'approve',        label: 'Approvals',        hint: 'A release needs your yes',      },    ],  },  {    id: 'team',    label: 'Team',    events: [      {        id: 'mention',        label: 'Mentions',        hint: 'Someone @-mentions you',      },      {        id: 'invite',        label: 'Invitations',        hint: 'New events and changes',      },    ],  },  {    id: 'account',    label: 'Account',    events: [      {        id: 'security',        label: 'Security alerts',        hint: 'New sign-in or API key',        instant: true,      },      {        id: 'billing',        label: 'Billing',        hint: 'Invoices and failed payments',      },    ],  },]const PREFS = {  failed: {    inapp: true,    email: true,    push: true,    sms: true,  },  live: { inapp: true, email: false, push: false },  approve: { inapp: true, email: true, push: true },  mention: {    inapp: true,    email: true,    push: true,    sms: false,  },  invite: { inapp: true, email: true },  security: {    inapp: true,    email: true,    push: true,    sms: true,  },  billing: { inapp: false, email: true },}const PREF_OFFERED = {  live: ['inapp', 'email', 'push'],  approve: ['inapp', 'email', 'push'],  invite: ['inapp', 'email'],  billing: ['inapp', 'email'],}const PREF_LOCKED = { security: ['email'] }const pause = (ms: number) =>  new Promise((done) => {    setTimeout(done, ms)  })

Installation

npm install @kerf-js/veneer

Usage

tsx
import { NotificationPreferences } from '@kerf-js/veneer'<NotificationPreferences  groups={PREF_GROUPS}  channels={CHANNELS}  value={PREFS}  offered={PREF_OFFERED}  locked={PREF_LOCKED}  defaults={{ value: PREFS }}  onChange={() => pause(400)}  onDigest={() => pause(400)}/>

Accessibility

Arrowkeys
Move between cells
Space
Toggles a cell
  • It is one grid with one tab stop. A channel an event cannot use still takes focus and says so.
  • Below 560px the same rows restack.

API Reference

PropTypeDefaultDescription
titlestring—The grid's name: the id of a heading, else this text is rendered in a visually hidden one.
groupsPrefGroup[]—The events, grouped.
channelsPrefChannel[]—The columns.
valuePrefValues | { value: PrefValues; } | (() => PrefValues)—What is on: event, then channel.
offeredRecord<string, string[]>—Which channels an event can use. Unlisted events can use all.
lockedRecord<string, string[]>—Which channels an event must use.
lockReasonstring—Why a box is locked.
digeststring—How often the digest channel sends.
digestChannelstring—The channel the digest applies to.
digests{ value: string; label: string; }[]—The email delivery choices, such as instant, hourly or daily.
defaults{ value: PrefValues; digest?: string | undefined; }—Enables Reset to defaults.
EventTypeDefaultDescription
onChange((changes: PrefChange[]) => void | Promise<unknown>)—A rejected promise flips the cells back and says why.
onDigest((digest: string) => void | Promise<unknown>)—Called with the delivery picked. A rejected promise puts the old one back.

Parts

Every element carries a stable name, so you can style it from your own CSS: [data-scope="prefs-matrix"] [data-part="sr-only"]

sr-onlygridfooterstatus

RelatedInboxPush soft ask