wrap settings row groups with styled container

This commit is contained in:
David Hill
2026-01-20 17:08:00 +00:00
parent 262aca1bca
commit 78bcbda2fa

View File

@@ -48,153 +48,159 @@ export const SettingsGeneral: Component = () => {
<div class="flex flex-col gap-1"> <div class="flex flex-col gap-1">
<h3 class="text-14-medium text-text-strong pb-2">Appearance</h3> <h3 class="text-14-medium text-text-strong pb-2">Appearance</h3>
<SettingsRow title="Appearance" description="Customise how OpenCode looks on your device"> <div class="bg-surface-raised-base px-4 rounded-lg">
<Select <SettingsRow title="Appearance" description="Customise how OpenCode looks on your device">
options={colorSchemeOptions} <Select
current={colorSchemeOptions.find((o) => o.value === theme.colorScheme())} options={colorSchemeOptions}
value={(o) => o.value} current={colorSchemeOptions.find((o) => o.value === theme.colorScheme())}
label={(o) => o.label} value={(o) => o.value}
onSelect={(option) => option && theme.setColorScheme(option.value)} label={(o) => o.label}
variant="secondary" onSelect={(option) => option && theme.setColorScheme(option.value)}
size="small" variant="secondary"
/> size="small"
</SettingsRow> />
</SettingsRow>
<SettingsRow <SettingsRow
title="Theme" title="Theme"
description={ description={
<> <>
Customise how OpenCode is themed.{" "} Customise how OpenCode is themed.{" "}
<a href="#" class="text-text-interactive-base"> <a href="#" class="text-text-interactive-base">
Learn more Learn more
</a> </a>
</> </>
} }
> >
<Select <Select
options={themeOptions()} options={themeOptions()}
current={themeOptions().find((o) => o.id === theme.themeId())} current={themeOptions().find((o) => o.id === theme.themeId())}
value={(o) => o.id} value={(o) => o.id}
label={(o) => o.name} label={(o) => o.name}
onSelect={(option) => { onSelect={(option) => {
if (!option) return if (!option) return
theme.setTheme(option.id) theme.setTheme(option.id)
}} }}
onHighlight={(option) => { onHighlight={(option) => {
if (!option) return if (!option) return
theme.previewTheme(option.id) theme.previewTheme(option.id)
return () => theme.cancelPreview() return () => theme.cancelPreview()
}} }}
variant="secondary" variant="secondary"
size="small" size="small"
/> />
</SettingsRow> </SettingsRow>
<SettingsRow title="Font" description="Customise the mono font used in code blocks"> <SettingsRow title="Font" description="Customise the mono font used in code blocks">
<Select <Select
options={fontOptions} options={fontOptions}
current={fontOptions.find((o) => o.value === settings.appearance.font())} current={fontOptions.find((o) => o.value === settings.appearance.font())}
value={(o) => o.value} value={(o) => o.value}
label={(o) => o.label} label={(o) => o.label}
onSelect={(option) => option && settings.appearance.setFont(option.value)} onSelect={(option) => option && settings.appearance.setFont(option.value)}
variant="secondary" variant="secondary"
size="small" size="small"
/> />
</SettingsRow> </SettingsRow>
</div>
</div> </div>
{/* System notifications Section */} {/* System notifications Section */}
<div class="flex flex-col gap-1"> <div class="flex flex-col gap-1">
<h3 class="text-14-medium text-text-strong pb-2">System notifications</h3> <h3 class="text-14-medium text-text-strong pb-2">System notifications</h3>
<SettingsRow <div class="bg-surface-raised-base px-4 rounded-lg">
title="Agent" <SettingsRow
description="Show system notification when the agent is complete or needs attention" title="Agent"
> description="Show system notification when the agent is complete or needs attention"
<Switch >
checked={settings.notifications.agent()} <Switch
onChange={(checked) => settings.notifications.setAgent(checked)} checked={settings.notifications.agent()}
/> onChange={(checked) => settings.notifications.setAgent(checked)}
</SettingsRow> />
</SettingsRow>
<SettingsRow title="Permissions" description="Show system notification when a permission is required"> <SettingsRow title="Permissions" description="Show system notification when a permission is required">
<Switch <Switch
checked={settings.notifications.permissions()} checked={settings.notifications.permissions()}
onChange={(checked) => settings.notifications.setPermissions(checked)} onChange={(checked) => settings.notifications.setPermissions(checked)}
/> />
</SettingsRow> </SettingsRow>
<SettingsRow title="Errors" description="Show system notification when an error occurs"> <SettingsRow title="Errors" description="Show system notification when an error occurs">
<Switch <Switch
checked={settings.notifications.errors()} checked={settings.notifications.errors()}
onChange={(checked) => settings.notifications.setErrors(checked)} onChange={(checked) => settings.notifications.setErrors(checked)}
/> />
</SettingsRow> </SettingsRow>
</div>
</div> </div>
{/* Sound effects Section */} {/* Sound effects Section */}
<div class="flex flex-col gap-1"> <div class="flex flex-col gap-1">
<h3 class="text-14-medium text-text-strong pb-2">Sound effects</h3> <h3 class="text-14-medium text-text-strong pb-2">Sound effects</h3>
<SettingsRow title="Agent" description="Play sound when the agent is complete or needs attention"> <div class="bg-surface-raised-base px-4 rounded-lg">
<Select <SettingsRow title="Agent" description="Play sound when the agent is complete or needs attention">
options={soundOptions} <Select
current={soundOptions.find((o) => o.id === settings.sounds.agent())} options={soundOptions}
value={(o) => o.id} current={soundOptions.find((o) => o.id === settings.sounds.agent())}
label={(o) => o.label} value={(o) => o.id}
onHighlight={(option) => { label={(o) => o.label}
if (!option) return onHighlight={(option) => {
playSound(option.src) if (!option) return
}} playSound(option.src)
onSelect={(option) => { }}
if (!option) return onSelect={(option) => {
settings.sounds.setAgent(option.id) if (!option) return
playSound(option.src) settings.sounds.setAgent(option.id)
}} playSound(option.src)
variant="secondary" }}
size="small" variant="secondary"
/> size="small"
</SettingsRow> />
</SettingsRow>
<SettingsRow title="Permissions" description="Play sound when a permission is required"> <SettingsRow title="Permissions" description="Play sound when a permission is required">
<Select <Select
options={soundOptions} options={soundOptions}
current={soundOptions.find((o) => o.id === settings.sounds.permissions())} current={soundOptions.find((o) => o.id === settings.sounds.permissions())}
value={(o) => o.id} value={(o) => o.id}
label={(o) => o.label} label={(o) => o.label}
onHighlight={(option) => { onHighlight={(option) => {
if (!option) return if (!option) return
playSound(option.src) playSound(option.src)
}} }}
onSelect={(option) => { onSelect={(option) => {
if (!option) return if (!option) return
settings.sounds.setPermissions(option.id) settings.sounds.setPermissions(option.id)
playSound(option.src) playSound(option.src)
}} }}
variant="secondary" variant="secondary"
size="small" size="small"
/> />
</SettingsRow> </SettingsRow>
<SettingsRow title="Errors" description="Play sound when an error occurs"> <SettingsRow title="Errors" description="Play sound when an error occurs">
<Select <Select
options={soundOptions} options={soundOptions}
current={soundOptions.find((o) => o.id === settings.sounds.errors())} current={soundOptions.find((o) => o.id === settings.sounds.errors())}
value={(o) => o.id} value={(o) => o.id}
label={(o) => o.label} label={(o) => o.label}
onHighlight={(option) => { onHighlight={(option) => {
if (!option) return if (!option) return
playSound(option.src) playSound(option.src)
}} }}
onSelect={(option) => { onSelect={(option) => {
if (!option) return if (!option) return
settings.sounds.setErrors(option.id) settings.sounds.setErrors(option.id)
playSound(option.src) playSound(option.src)
}} }}
variant="secondary" variant="secondary"
size="small" size="small"
/> />
</SettingsRow> </SettingsRow>
</div>
</div> </div>
</div> </div>
</div> </div>