Skip to content

Settings row

The shape every settings page becomes. Title on the left, optional description below it, control on the right.

'use client';
import type { ReactNode } from 'react';
import { Stack, Text } from '@helixui/core';
export interface SettingsRowProps {
title: ReactNode;
description?: ReactNode;
/** The control: a Switch, a Select, a Button, anything. */
control: ReactNode;
}
export function SettingsRow({ title, description, control }: SettingsRowProps) {
return (
<Stack
direction="row"
align="center"
justify="between"
gap={4}
style={{ paddingBlock: 'var(--helixui-space-4)', borderBottom: '1px solid var(--helixui-color-border-subtle)' }}
>
<Stack gap={0} style={{ flex: 1, minWidth: 0 }}>
<Text weight="semibold">{title}</Text>
{description ? <Text size="sm" tone="muted">{description}</Text> : null}
</Stack>
<div>{control}</div>
</Stack>
);
}

Usage

import { Switch, Button, Stack } from '@helixui/core';
import { SettingsRow } from './SettingsRow';
<Stack gap={0}>
<SettingsRow
title="Email notifications"
description="Weekly digest + critical alerts."
control={<Switch defaultSelected />}
/>
<SettingsRow
title="Two-factor authentication"
description="Required for admin accounts."
control={<Button variant="outline">Configure</Button>}
/>
<SettingsRow
title="Delete account"
description="Permanently remove your account and all data."
control={<Button tone="danger">Delete</Button>}
/>
</Stack>

The borderBottom lives on the row, not on the container, so dropping new rows in doesn’t require touching the parent.