feat: 侧边卡片设置页视觉重构——分组容器卡片、计数徽标、自定义开关、加宽设置弹窗(描述 + 完成按钮),卡片齿轮与勾选徽标纵向对齐同尺寸

This commit is contained in:
Menghuan1918
2026-08-14 14:07:52 +08:00
parent efb2e2bd58
commit 047f48337d
4 changed files with 408 additions and 181 deletions
+28 -10
View File
@@ -5,9 +5,11 @@
* copy. The toggles are CARDS in a responsive grid: the card's main area is
* the switch, the visual state IS the state (highlighted = enabled),
* announced via `aria-pressed`, and the check badge sits at the far right.
* Features that declare related settings carry a gear corner button whose
* popup rows (native checkboxes) are tested through the extracted
* FeatureSettingsRows component (the Modal portal renders only while open).
* The general rows follow the DSH settings-row recipe with custom SWITCHES
* (real checkboxes driving a styled track). Features that declare related
* settings carry a gear corner button whose popup rows (switch controls)
* are tested through the extracted FeatureSettingsRows component (the Modal
* portal renders only while open).
*
* Rendered with renderToString (mount effects — the settings RPC sync — do
* not run in SSR; the initial store prefs are the render input).
@@ -78,14 +80,27 @@ describe('SideCardSection declarative inventory', () => {
expect(html).toContain('>explorer<')
expect(html).toContain('data-icon="subagent"')
expect(html).toContain('>Subagents<')
// Default prefs: openByDefault + interceptOpenPath + both tabs + the
// image viewer are all enabled → 5 cards pressed, none pressed=false.
// Default prefs: openByDefault + interceptOpenPath switches checked, and
// both tabs + the image viewer cards pressed (3 aria-pressed cards).
// The nested auto-open toggle is NOT an inline card (it lives in the popup).
expect(pressedCount(html, 'true')).toBe(5)
expect(pressedCount(html, 'true')).toBe(3)
expect(pressedCount(html, 'false')).toBe(0)
// The general toggles are custom switches (real checkboxes, checked).
expect(html.match(/checked=""/g)?.length).toBe(2)
expect(html).not.toContain('Auto-open Subagents')
})
it('renders the section intro and group headings with inventory counts', () => {
const { store, service } = mount()
const html = renderSection(store, service)
expect(html).toContain('Manage what the side card shows and how it behaves')
// Group headings carry the inventory count badge (2 tabs, 1 viewer).
expect(html).toContain('>Sidebar content</span><span')
expect(html).toContain('>File viewers</span><span')
expect(html).toContain('>2</span>')
expect(html).toContain('>1</span>')
})
it('renders one small card per registered viewer: icon + title + exts', () => {
const { store, service } = mount()
const html = renderSection(store, service)
@@ -111,8 +126,9 @@ describe('SideCardSection declarative inventory', () => {
expect(html).toContain('>Subagents<')
expect(html).toContain('>Image<')
expect(pressedCount(html, 'false')).toBe(2)
// openByDefault + interceptOpenPath + the explorer stay pressed.
expect(pressedCount(html, 'true')).toBe(3)
// The explorer card stays pressed; the general switches stay checked.
expect(pressedCount(html, 'true')).toBe(1)
expect(html.match(/checked=""/g)?.length).toBe(2)
})
it('hides the gear of a disabled feature (its related settings are dormant)', () => {
@@ -134,7 +150,7 @@ describe('FeatureSettingsRows (the secondary settings popup body)', () => {
desc: () => 'Expand on new subagent',
}]
it('renders one native checkbox row per declared toggle with its current value', () => {
it('renders one switch row per declared toggle with its current value', () => {
const html = renderToString(createElement(FeatureSettingsRows, {
toggles,
prefs,
@@ -142,7 +158,9 @@ describe('FeatureSettingsRows (the secondary settings popup body)', () => {
}))
expect(html).toContain('Auto-open Subagents')
expect(html).toContain('Expand on new subagent')
// The checkbox reflects the prefs value (false here → unchecked).
// The row's switch is a real checkbox (aria-label = the toggle title)
// reflecting the prefs value (false here → unchecked).
expect(html).toContain('aria-label="Auto-open Subagents"')
expect(html).not.toContain('checked=""')
})