Skip to content

Commit 7693997

Browse files
committed
feat: upgrade wide mode to layout control sliders + keyboard shortcut
- Replace boolean wideMode toggle with maxWidth slider (0=centered, 5-100%) - Add font size slider (10-24px) in Appearance settings - Add Cmd+Shift+W keyboard shortcut to toggle wide mode - Slider-only UX: single control instead of toggle+slider - CSS transition already handled by session panel
1 parent ef33ba0 commit 7693997

4 files changed

Lines changed: 49 additions & 12 deletions

File tree

packages/app/src/components/settings-general.tsx

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -368,14 +368,40 @@ export const SettingsGeneral: Component = () => {
368368
</SettingsRow>
369369

370370
<SettingsRow
371-
title="Wide Mode"
372-
description="Use full window width for chat instead of centered narrow layout"
371+
title="Font Size"
372+
description="Base font size for code and messages"
373373
>
374-
<div data-action="settings-wide-mode">
375-
<Switch
376-
checked={settings.appearance.wideMode()}
377-
onChange={(checked) => settings.appearance.setWideMode(checked)}
374+
<div data-action="settings-font-size" class="flex items-center gap-3 w-full sm:w-[220px]">
375+
<input
376+
type="range"
377+
min="10"
378+
max="24"
379+
step="1"
380+
value={settings.appearance.fontSize()}
381+
onInput={(e) => settings.appearance.setFontSize(Number(e.currentTarget.value) || 14)}
382+
class="flex-1 accent-color-accent h-1.5 cursor-pointer"
383+
style={{ "transition": "all 200ms ease-out" }}
384+
/>
385+
<span class="text-12-regular text-text-weak tabular-nums w-8 text-right">{settings.appearance.fontSize()}px</span>
386+
</div>
387+
</SettingsRow>
388+
389+
<SettingsRow
390+
title="Chat Width"
391+
description="0 = centered layout, drag right for wider chat"
392+
>
393+
<div data-action="settings-max-width" class="flex items-center gap-3 w-full sm:w-[220px]">
394+
<input
395+
type="range"
396+
min="0"
397+
max="100"
398+
step="5"
399+
value={settings.appearance.maxWidth()}
400+
onInput={(e) => settings.appearance.setMaxWidth(Number(e.currentTarget.value) || 0)}
401+
class="flex-1 accent-color-accent h-1.5 cursor-pointer"
402+
style={{ "transition": "all 200ms ease-out" }}
378403
/>
404+
<span class="text-12-regular text-text-weak tabular-nums w-8 text-right">{settings.appearance.maxWidth() === 0 ? "auto" : `${settings.appearance.maxWidth()}%`}</span>
379405
</div>
380406
</SettingsRow>
381407
</SettingsList>

packages/app/src/context/settings.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export interface Settings {
3232
}
3333
appearance: {
3434
fontSize: number
35-
wideMode: boolean
35+
maxWidth: number
3636
mono: string
3737
sans: string
3838
}
@@ -99,7 +99,7 @@ const defaultSettings: Settings = {
9999
},
100100
appearance: {
101101
fontSize: 14,
102-
wideMode: false,
102+
maxWidth: 0,
103103
mono: "",
104104
sans: "",
105105
},
@@ -189,9 +189,9 @@ export const { use: useSettings, provider: SettingsProvider } = createSimpleCont
189189
setFontSize(value: number) {
190190
setStore("appearance", "fontSize", value)
191191
},
192-
wideMode: withFallback(() => store.appearance?.wideMode, defaultSettings.appearance.wideMode),
193-
setWideMode(value: boolean) {
194-
setStore("appearance", "wideMode", value)
192+
maxWidth: withFallback(() => store.appearance?.maxWidth, defaultSettings.appearance.maxWidth),
193+
setMaxWidth(value: number) {
194+
setStore("appearance", "maxWidth", Math.max(0, Math.min(100, value)))
195195
},
196196
font: withFallback(() => store.appearance?.mono, defaultSettings.appearance.mono),
197197
setFont(value: string) {

packages/app/src/pages/session.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ export default function Page() {
401401
if (desktopReviewOpen()) return `${layout.session.width()}px`
402402
return `calc(100% - ${layout.fileTree.width()}px)`
403403
})
404-
const centered = createMemo(() => isDesktop() && !desktopReviewOpen() && !settings.appearance.wideMode())
404+
const centered = createMemo(() => isDesktop() && !desktopReviewOpen() && settings.appearance.maxWidth() === 0)
405405

406406
function normalizeTab(tab: string) {
407407
if (!tab.startsWith("file://")) return tab

packages/app/src/pages/session/use-session-commands.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { useLocal } from "@/context/local"
99
import { usePermission } from "@/context/permission"
1010
import { usePrompt } from "@/context/prompt"
1111
import { useSDK } from "@/context/sdk"
12+
import { useSettings } from "@/context/settings"
1213
import { useSync } from "@/context/sync"
1314
import { useTerminal } from "@/context/terminal"
1415
import { showToast } from "@opencode-ai/ui/toast"
@@ -44,6 +45,7 @@ export const useSessionCommands = (actions: SessionCommandContext) => {
4445
const sync = useSync()
4546
const terminal = useTerminal()
4647
const layout = useLayout()
48+
const settings = useSettings()
4749
const navigate = useNavigate()
4850
const { params, tabs, view } = useSessionLayout()
4951

@@ -313,6 +315,15 @@ export const useSessionCommands = (actions: SessionCommandContext) => {
313315
keybind: "mod+\\",
314316
onSelect: () => layout.fileTree.toggle(),
315317
}),
318+
viewCommand({
319+
id: "wide.toggle",
320+
title: "Toggle Wide Mode",
321+
keybind: "mod+shift+w",
322+
onSelect: () => {
323+
const cur = settings.appearance.maxWidth()
324+
settings.appearance.setMaxWidth(cur === 0 ? 100 : 0)
325+
},
326+
}),
316327
viewCommand({
317328
id: "input.focus",
318329
title: language.t("command.input.focus"),

0 commit comments

Comments
 (0)