倉庫指標
- 星標
- (1 顆星)
- PR 合併指標
- (PR 指標待抓取)
描述
Sub-issue of #1303.
Problem
Settings already has the necessary low-level controls, but page composition is not governed. SettingsRows is only a wrapper and the current SettingRow covers only read-only values, so pages hand-build editable rows, section spacing, status clusters, expanded fields, and async states.
The result is observable drift:
- General places expanded proxy fields directly inside a grouped card.
- Memory places status and a switch as independent flex children.
- Open Gateway places a proxy grid outside the grouped-row surface.
- Daily Review and Data implement different label/control ordering.
- equivalent loading, failure, empty, pending, and read-only states use different treatments.
This issue owns the shared Settings composition seam. It does not redesign Settings navigation or module pages.
Already completed
-
StatTilelong-value containment — #1335 -
DataTablewide-content containment — #1478
SettingsSection
- Own section heading, optional help, optional trailing action, and vertical spacing.
- Be unframed by default. Add a surface only when the contents form one grouped task.
- Do not repeat the page title or page description.
- Page code supplies content and data, not local padding, border, radius, or heading typography overrides.
ControlRow
Extend or rename the existing SettingsRows / SettingRow seam; do not leave a legacy editable-row path beside a new one.
- Own one label, optional description, one trailing control cluster, and optional status.
- Support horizontal and stacked layouts through one component-owned responsive rule.
- Keep control and status alignment inside one trailing cluster.
- Put conditional or full-width fields in an expanded-content slot or a separate section. Arbitrary grids, alerts, and action bars must not be direct children of the grouped-row container.
- Support read-only values, switches, selects, text fields, and row-scoped actions through the same label and description slots.
- Long labels, paths, identifiers, and localized values must wrap or truncate according to their semantics without horizontal page scroll.
- Static rows must not show hover feedback that implies the entire row is interactive.
Async states
- Keep the page header and stable section geometry while loading.
- Use a skeleton that resembles the eventual structure.
- Present failure as
Alertwith an inline retry action; failure is not an empty state. - Use the shared
EmptyState; add a compact variant only after at least two consumers demonstrate the need. - Show pending state on the initiating control with
aria-busy; disable only conflicting controls and keep layout stable.
Actions and confirmation
- One primary action per section.
- Row actions stay with the row; page-wide actions stay in the section footer.
- Reversible switches do not require confirmation.
- Destructive or irreversible actions use the governed confirmation dialog and name the affected object and consequence.
- Rare secondary actions may move to one overflow menu when they cannot fit at the supported narrow-window floor.
Reference consumers
The first migration must prove the grammar on:
- General proxy configuration;
- Memory status, preview, and maintenance actions;
- Open Gateway controls and proxy form;
- Daily Review settings;
- Web Search settings.
Page-group issues remain responsible for their page-specific hierarchy and content.
Acceptance
- Existing
SettingsRows/SettingRowis extended or fully migrated; no parallel editable-row implementation remains. -
SettingsSectionand the governed control row own their layout and responsive behavior. - General, Memory, Open Gateway, Daily Review, and Web Search demonstrate the same grammar where semantics match.
- The 480px floor has no page-level horizontal scroll and no clipped control.
- Loading, error, empty, pending, long-label, and long-value variants are represented in stories.
- Responsive stacking, trailing alignment, static-vs-interactive feedback, and overflow are locked by focused contracts.
- Shared visual decisions live with the shared seam; page CSS retains page placement only.