SettingsSection
A titled block of settings rows, each a label and hint with its control at the right (SettingsRow).
Demo
Notifications
What we email you about.
Danger
- Export dataA zip of everything, within a minute.
Get it
It needs theme.qwe, as every component does; or take the whole kit, quillo-ui.qwe. Each component brings its own styles to the pages that show it.
$ curl -O https://quillolang.org/components/ui/theme.qwe$ curl -O https://quillolang.org/components/ui/settings_section.qwemain.qwe
import ui/theme.qwe use theme_cssuse ui/settings_section.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>Example
The code of the preview above.
demos/settings_section.qwe
view SettingsSectionDemo() = <div.demo-stack> <SettingsSection id="settings-section-demo" title="Notifications" description="What we email you about." footer={<Button size="sm">Save</Button>}> <SettingsRow label="Replies" hint="When someone answers you." field="settings-demo-replies"> <Switch name="replies" checked={true}/> </SettingsRow> <SettingsRow label="Weekly digest" hint="A summary of what happened." field="settings-demo-digest"> <Select name="digest" field="settings-demo-digest" size="sm" value="monday" options={[{ label: "Never", value: "never" }, { label: "Mondays", value: "monday" }, { label: "Fridays", value: "friday" }]}/> </SettingsRow> <SettingsRow label="Signature" hint="Added to the end of every email." field="settings-demo-sig" wide={true}> <TextArea name="signature" field="settings-demo-sig" rows={2} value="— Ada"/> </SettingsRow> </SettingsSection> <SettingsSection title="Danger" level={3}> <SettingsRow label="Export data" hint="A zip of everything, within a minute."> <Button size="sm" variant="outline">Export</Button> </SettingsRow> </SettingsSection> </div>Source
ui/settings_section.qwe
// SettingsSection: one block of a settings page: a title, a line about it, and// rows each with a label and a hint on the left and its control on the right.// SettingsRow is one row.//// <SettingsSection title="Notifications" description="What we email you about.">// <SettingsRow label="Replies" hint="When someone answers you." field="n-replies">// <Switch name="replies" checked={true}/>// </SettingsRow>// <SettingsRow label="Digest" hint="A summary of the week." field="n-digest">// <Select name="digest" field="n-digest" options={["Never", "Weekly"]}/>// </SettingsRow>// </SettingsSection>//// SettingsSection: title (an <h2>; level sets the heading level), description,// children (SettingsRows), footer (HTML along the bottom: a Save button), id.// SettingsRow: label, hint (a quieter line under it), children (the control),// field: the control's id, so the label is a <label for> it (otherwise the label// is plain text and the control should carry its own aria-label), wide: the// control takes the whole row, under the label (a textarea, a table). On a phone// every row stacks.import ui/theme.qwe use ui_clslet settings_section_css = css`.ui-settings { border: 1px solid var(--ui-border); border-radius: var(--ui-radius); background: var(--ui-surface); font: 14px/1.5 var(--ui-font); color: var(--ui-fg); }.ui-settings-head { padding: 18px 20px 14px; border-bottom: 1px solid var(--ui-border); }.ui-settings-title { margin: 0; font-size: 16px; font-weight: 600; line-height: 1.3; }.ui-settings-desc { margin: 3px 0 0; color: var(--ui-muted); }.ui-settings-rows { margin: 0; padding: 0; list-style: none; }.ui-settings-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 24px; align-items: center; padding: 14px 20px; }.ui-settings-row + .ui-settings-row { border-top: 1px solid var(--ui-border); }.ui-settings-row-wide { grid-template-columns: minmax(0, 1fr); }.ui-settings-label { font-weight: 500; }.ui-settings-hint { display: block; color: var(--ui-muted); font-size: 13px; font-weight: 400; }.ui-settings-control { display: flex; justify-content: flex-end; align-items: center; min-width: 0; }.ui-settings-row-wide .ui-settings-control { justify-content: stretch; margin-top: 6px; }.ui-settings-row-wide .ui-settings-control > * { flex: 1; }.ui-settings-foot { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; padding: 12px 20px; border-top: 1px solid var(--ui-border); background: var(--ui-subtle); border-radius: 0 0 var(--ui-radius) var(--ui-radius); }@media (max-width: 560px) { .ui-settings-row { grid-template-columns: minmax(0, 1fr); } .ui-settings-control { justify-content: flex-start; margin-top: 6px; }}`view SettingsSection(title: str, description: str? = null, footer = null, level: int = 2, id: str? = null, class: str? = null, children) { style global settings_section_css let tid = id != null ? `${id}-title` : null let heading = match level { 3 => <h3.ui-settings-title id={tid}>{title}</h3> 4 => <h4.ui-settings-title id={tid}>{title}</h4> _ => <h2.ui-settings-title id={tid}>{title}</h2> } <section id={id} class={ui_cls(["ui-settings", class])} aria-labelledby={tid} aria-label={tid == null ? title : null}> <div.ui-settings-head> {heading} {description != null && <p.ui-settings-desc>{description}</p>} </div> <ul.ui-settings-rows>{children}</ul> {footer != null && <div.ui-settings-foot>{footer}</div>} </section>}view SettingsRow(label: str, hint: str? = null, field: str? = null, wide: bool = false, class: str? = null, children) { style global settings_section_css let text = [label, hint != null && <span.ui-settings-hint>{hint}</span>] <li class={ui_cls(["ui-settings-row", wide && "ui-settings-row-wide", class])}> {field != null ? <label.ui-settings-label for={field}>{text}</label> : <span.ui-settings-label>{text}</span>} <div.ui-settings-control>{children}</div> </li>}Related
ApiKeyFieldA secret shown masked in a read-only field, with Show and Copy buttons and a hidden input for forms.5 views · 6 downloadsDangerZoneA red-bordered block of destructive actions (DangerAction), each a form, link or callback that asks before it acts.6 views · 8 downloadsOnboardingChecklistSteps to finish setting up, with a progress bar, a tick on each done and a link to where the rest get done.7 views · 5 downloadsSessionListSigned-in devices with browser, system, place and time, this one marked, and Sign out for each or all the others.6 views · 5 downloadsDashboardGridWidgets on a twelve-column grid, each spanning columns and rows (DashboardCell), stacking on a phone.7 views · 9 downloadsPermissionsMatrixRoles across, permissions down, a checkbox at each: a form sends the pairs ticked, a column box ticks a whole role.6 views · 6 downloads
Thread
Thread 0 posts
On SettingsSection: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.