A list of settings on a settings screen: each row has a title and a description, with its control on the right or under the text. Inside a form, use Field instead.
Installation
bun add @harmo-ui/css @harmo-ui/react
npm install @harmo-ui/css @harmo-ui/react
pnpm add @harmo-ui/css @harmo-ui/react
yarn add @harmo-ui/css @harmo-ui/react
bunx harmo-ui add settings
npx harmo-ui add settings
pnpm dlx harmo-ui add settings
yarn dlx harmo-ui add settings
Usage
import { Option, Select, Setting, Settings, Switch } from "@harmo-ui/react";<Settings> <Setting label="Recap emails" description="Send account recap emails to the recipients below." > <Switch /> </Setting> <Setting label="Default language" description="Used for new templates and automated replies." placement="below" > <Select defaultValue="en"> <Option value="en">English</Option> <Option value="es">Spanish</Option> </Select> </Setting></Settings>
Each row has a title and description, with its control on the right. The text isn't a label: the switch takes its name from the title with aria-labelledby and its description with aria-describedby. A disabled control grays its row's text.
Recap emails
Send account recap emails to the recipients below. Operational emails go to each member's sign-in email.
Web push availability
Controls whether web push can be enabled for this account. Members choose their push events in communication preferences.
Inbox translation
Managed by your administrator.
<Settings> <Setting label="Recap emails" description="Send account recap emails to the recipients below. Operational emails go to each member's sign-in email." > <Switch /> </Setting> <Setting label="Web push availability" description="Controls whether web push can be enabled for this account. Members choose their push events in communication preferences." > <Switch defaultChecked /> </Setting> <Setting label="Inbox translation" description="Managed by your administrator." > <Switch defaultChecked disabled /> </Setting></Settings>
<div class="hsettings"> <div class="hsetting"> <div class="hsetting-text"> <h3 class="hsetting-title" id="recap-title">Recap emails</h3> <p class="hsetting-description" id="recap-description"> Send account recap emails to the recipients below. Operational emails go to each member's sign-in email. </p> </div> <input class="hswitch" type="checkbox" role="switch" aria-labelledby="recap-title" aria-describedby="recap-description" /> </div> <div class="hsetting"> <div class="hsetting-text"> <h3 class="hsetting-title" id="push-title">Web push availability</h3> <p class="hsetting-description" id="push-description"> Controls whether web push can be enabled for this account. Members choose their push events in communication preferences. </p> </div> <input class="hswitch" type="checkbox" role="switch" aria-labelledby="push-title" aria-describedby="push-description" checked /> </div> <div class="hsetting"> <div class="hsetting-text"> <h3 class="hsetting-title" id="translate-title">Inbox translation</h3> <p class="hsetting-description" id="translate-description">Managed by your administrator.</p> </div> <input class="hswitch" type="checkbox" role="switch" aria-labelledby="translate-title" aria-describedby="translate-description" checked disabled /> </div></div>
Other controls
Compact controls, such as a Checkbox or a Button, sit on the right. A control that fills its container, such as a Select, goes inside .hsetting-text under the description and spans the text.
Daily digest
A summary of unanswered conversations, sent at 9:00.
Default language
Used for new templates and automated replies.
English
Spanish
Arabic
Export conversations
Download every conversation from the last 90 days as a CSV file.
<Settings> <Setting label="Daily digest" description="A summary of unanswered conversations, sent at 9:00." > <Checkbox defaultChecked /> </Setting> <Setting label="Default language" description="Used for new templates and automated replies." placement="below" > <Select defaultValue="en"> <Option value="en">English</Option> <Option value="es">Spanish</Option> <Option value="ar">Arabic</Option> </Select> </Setting> <Setting label="Export conversations" description="Download every conversation from the last 90 days as a CSV file." > <Button variant="secondary">Export</Button> </Setting></Settings>
In a narrow container, drawn dashed here, the text wraps and the control keeps its size, centered beside it.
Automatic away status
Set members as away after 15 minutes without activity, and back once they reply.
<Settings> <Setting label="Automatic away status" description="Set members as away after 15 minutes without activity, and back once they reply." > <Switch defaultChecked /> </Setting></Settings>
<div class="hsettings"> <div class="hsetting"> <div class="hsetting-text"> <h3 class="hsetting-title" id="away-title">Automatic away status</h3> <p class="hsetting-description" id="away-description"> Set members as away after 15 minutes without activity, and back once they reply. </p> </div> <input class="hswitch" type="checkbox" role="switch" aria-labelledby="away-title" aria-describedby="away-description" checked /> </div></div>
API reference
React
<Settings> renders the list, and <Setting> each row. A Setting's children are its control, named by the row's title and described by its description; a Button keeps its own label and takes only the description, and so does a control given its own aria-label or aria-labelledby. Other props are the <div>'s attributes.
Prop
Effect
label
The row's title
description
The text under it
labelAs
The title's element: h2 to h6, or p; h3 by default
placement
below puts the control under the text, for one that fills its container
HTML
A <div class="hsettings"> holding one <div class="hsetting"> per setting, each with a .hsetting-text holding .hsetting-title and .hsetting-description. The control takes aria-labelledby (the title's id) and aria-describedby (the description's id). Load settings.css, plus the controls' own, such as switch.css. It needs no script.
A compact control, such as a Switch, Checkbox, or Button, sits on the right as the row's last child.
A control that fills its container, such as an Input, Select, TextArea, or segmented control, goes inside .hsetting-text after the description and spans the text.
Use whichever heading level fits the page, or a <p>, for the title.
Only the control responds to clicks; the text isn't a <label>. The control takes its name from the title with aria-labelledby and its description with aria-describedby.