refactor(desktop): move the bot-chat cluster onto the Astryx settings kit - #1993
Merged
Conversation
… kit 远程接入 was the last page group speaking the pre-#1972 dialect — #1972 did not list it in its rewrite scope, so a user opening it saw a different product than every other settings page. - Overview: bespoke page container + section-header dialect + hand- rolled list grids become SettingsPage → SettingsSection → the kit's hairline rows. SettingsSection gains a `titleId` prop so the two sections keep the heading ids their aria-labelledby wiring names them by. The readiness Badge becomes the shared StatusDot + text idiom (the title span's aria-label keeps the row's accessible name byte-identical for the e2e). EmptyState drops its padding-override class for `isCompact`. - Detail: the runtime block was a full-width tinted card used as page structure (the named anti-pattern) — now an open SettingsSection whose action slot carries the test/connect/restart cluster. The 4→2→1-column <dl> status grid becomes MetadataList, which owns the responsive collapse the two media queries hand-rolled. The configuration header dialect becomes a bare-variant SettingsSection wrapping the mode toggle + credential form; the hand-tinted quick-setup plate becomes an Astryx Card (a genuine callout). - Deliberately untouched: `.settingsBotDetailHeader`'s pinned grid (settings.spec.ts asserts its back → switch → doc link → connect focus order), the brand plate, both QR frames, and the onboarding glyphs — documented art, not layout debt. - bot.css drops ~200 lines of retired dialect; the attention wash, planned-opacity, and 620px chevron-hiding row behaviors stay. Verified: desktop typecheck, check-dead-css, check-a11y/copy/console, product Storybook smoke (71 catalog renders x 3 viewports); e2e heading-name and focus-order contracts re-checked against the new DOM.
jackwener
added a commit
that referenced
this pull request
Aug 3, 2026
… seam (#1997) Adversarial review of #1984/#1991/#1993 (two independent lenses, findings verified before fixing) plus one user-reported shell defect. Shell: - The content column is a rounded floating plate flush to the sidebar; the theme's full-height sidenav hairline ran on the same seam and read as a doubled border beside the plate's corner radius. Dropped in the expanded state too (collapsed already did) — separation is tonal, per DESIGN.md's One Working Plane rule. Regressions from #1993, confirmed and fixed: - bot-chat-detail lost all inter-section rhythm: its wrapper pair kept a gap on a display:block section (inert) and a class with no CSS rule. The page is a SettingsPage now, like the overview next door; the back button keeps only its optical inline outdent. - bot.css had the file-header comment replace-all'd into the middle of `.settingsBotDetailHeader > .settingsBotLogo`. Parsed by luck; removed. - MetadataList destructures a closed prop list, so the runtime grid's aria-label was silently dropped — the group name rides a real role="group" wrapper now. - The kit section header now wraps: at the 480px window floor a multi-button action cluster drops under the title instead of crushing it (replaces the deleted bot-runtime media query). - Overview rows go flush-inline (the 10px inset was old card-grid residue); the WeChat QR dialog gets its height floor back (224px) so state swaps stop resizing the modal. Convergence completions the review surfaced: - claude-subscription-card drops its SectionHeader + full-width Card and repeated title: it renders under ProvidersPanel's RouteHeader like its sibling OAuth panels, as a bare VStack with the shared StatusDot + text status idiom. - ProvidersPanel connection status Badge -> StatusDot + text; health's hand-rolled five-arm dot mapping -> the shared statusDotVariant. - subagent-presets panel: Card-wrapped .settingsRows + a lead Item posing as a header -> SettingsSection; settings-surface fallback drops its Card wrap. - About hero pills referenced two classNames with no CSS rule — they are the Badges about.css's comment always described. - `.settingsPage .settingsPageStack` (rename slip) -> nested `.settingsPageStack .settingsPageStack`; quota labels round. Verified: typecheck, check-dead-css, check-a11y/copy/console, format:check, product Storybook smoke (71 renders x 3 viewports).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes out the settings convergence: 远程接入 (overview + detail) was the last page group on the pre-#1972 dialect — #1972 didn't list it in its rewrite scope, so opening it felt like a different product from every other settings page.
Overview (
bot-chat-overview.tsx)SettingsPage→SettingsSection→ the kit's hairline rows.SettingsSectiongains atitleIdprop (Heading id + sectionaria-labelledby) so both sections keep the ids the a11y wiring names them by.Badge→ the shared StatusDot + text idiom; the title span'saria-labelkeeps each row's accessible name byte-identical forsettings.spec.ts.EmptyStatedrops its padding-override class forisCompact.Detail (
bot-chat-detail.tsx)SettingsSectionwith the test/connect/restart cluster in itsactionslot.<dl>status grid →MetadataList, which owns the responsive collapse the two hand-rolled media queries used to carry.SettingsSectionwrapping the mode toggle + credential form (e2e'sheading '接入方式'stays a heading).Card(a genuine callout — the one legitimate Card use in a settings page).Deliberately untouched
.settingsBotDetailHeader's pinned grid (settings.spec.tsasserts its back → switch → doc link → connect focus order), the brand plate, both QR frames, and the onboarding glyphs — documented art, not layout debt.Verification
typecheck ✅ · check-dead-css ✅ · check-a11y/copy/console ✅ · product Storybook smoke 71 renders × 3 viewports ✅ · e2e heading-name/focus-order/accessible-name contracts re-checked against the new DOM (roles and names unchanged).
Net: 4 files, +114/−257 — bot.css sheds ~200 lines of retired dialect while keeping the attention wash, planned-opacity, and narrow-viewport row behaviors.