Fix settings navigation routing

Replace hash links in the settings side navigation with button-driven in-page scrolling so the hash router does not leave the settings page.
This commit is contained in:
Eyejoker
2026-05-02 03:11:15 +09:00
committed by GitHub
parent 1a2f879d11
commit 921d738bb0
3 changed files with 34 additions and 27 deletions

View File

@@ -37,7 +37,9 @@ describe('SettingsPanel', () => {
expect(html).toContain('MoA 참조 모델');
expect(html).toContain('패스트 모드');
expect(html).toContain('Codex 실험 기능');
expect(html).toContain('href="#settings-codex"');
expect(html).toContain('data-settings-target="settings-codex"');
expect(html).toContain('aria-controls="settings-codex"');
expect(html).not.toContain('href="#settings-codex"');
expect(html).toContain('/goal');
expect(html).toContain('변경 적용');
expect(html).toContain('불러오는 중');

View File

@@ -32,31 +32,15 @@ interface AccountData {
}
const SETTINGS_NAV_ITEMS = [
{ targetId: 'settings-general', title: '일반', detail: '표시 · 언어' },
{
href: '#settings-general',
title: '일반',
detail: '표시 · 언어',
},
{
href: '#settings-models',
targetId: 'settings-models',
title: '모델',
detail: 'owner · reviewer · arbiter',
},
{
href: '#settings-moa',
title: 'MoA',
detail: '참조 모델 · 연결 테스트',
},
{
href: '#settings-codex',
title: 'Codex',
detail: 'fast mode · /goal',
},
{
href: '#settings-accounts',
title: '계정',
detail: 'Claude · Codex',
},
{ targetId: 'settings-moa', title: 'MoA', detail: '참조 모델 · 연결 테스트' },
{ targetId: 'settings-codex', title: 'Codex', detail: 'fast mode · /goal' },
{ targetId: 'settings-accounts', title: '계정', detail: 'Claude · Codex' },
] as const;
export interface SettingsPanelProps {
@@ -171,13 +155,25 @@ function SettingsHero() {
}
function SettingsNav() {
const scrollToSection = (targetId: string) => {
document
.getElementById(targetId)
?.scrollIntoView({ behavior: 'smooth', block: 'start' });
};
return (
<aside className="settings-nav" aria-label="설정 섹션">
{SETTINGS_NAV_ITEMS.map((item) => (
<a href={item.href} key={item.href}>
<button
aria-controls={item.targetId}
data-settings-target={item.targetId}
key={item.targetId}
onClick={() => scrollToSection(item.targetId)}
type="button"
>
<strong>{item.title}</strong>
<small>{item.detail}</small>
</a>
</button>
))}
</aside>
);

View File

@@ -734,14 +734,17 @@ button:disabled {
box-shadow: var(--card-shadow);
}
.settings-nav a {
.settings-nav button {
display: grid;
gap: 2px;
padding: 10px 12px;
border: 1px solid transparent;
border-radius: 12px;
background: transparent;
color: var(--muted);
text-decoration: none;
font: inherit;
text-align: left;
cursor: pointer;
transition:
background 140ms ease,
border-color 140ms ease,
@@ -749,13 +752,19 @@ button:disabled {
transform 140ms ease;
}
.settings-nav a:hover {
.settings-nav button:hover,
.settings-nav button:focus-visible {
transform: translateX(2px);
border-color: rgba(214, 130, 88, 0.24);
background: rgba(214, 130, 88, 0.08);
color: var(--bg-ink);
}
.settings-nav button:focus-visible {
outline: 2px solid rgba(214, 130, 88, 0.34);
outline-offset: 2px;
}
.settings-nav strong {
color: currentColor;
font-size: 13px;