ui(sync): compact device rows with click-to-expand drawer + shared primitives#964
Merged
kunickiaj merged 1 commit intoApr 23, 2026
Conversation
Owner
Author
Merged
1 task
This was referenced Apr 23, 2026
Owner
Author
Merge activity
|
4aaff9f to
0b90b9f
Compare
kunickiaj
added a commit
that referenced
this pull request
Apr 23, 2026
…ite (#965) ## Description PR 3 of the Sync tab redesign (plan: docs/plans/2026-04-23-sync-tab-redesign.md). Wires the loading-states vocabulary into the freshly-refactored device row: - **Syncing-pip override.** While a device is actively being contacted via Sync now, its PresencePip swaps to the pulsing \`syncing\` state (1.2s ease-in-out). Resolves back to its derived state when the operation completes. - **Device-row-shaped skeleton.** \`#syncPeersSkeleton\` now renders three shimmer rows that match the real row silhouette (pip · name block · chip block) so layout doesn't shift when data arrives. \`aria-busy="true"\` on the container; shimmer gated by \`prefers-reduced-motion\`. - **Zero-devices empty-state rewrite.** Copy now points at the existing Invite / Paste-invite actions above rather than the legacy pairing-command flow. Title becomes "No teammates yet" to match the plan's language. ## Type of Change - [x] UX redesign (plan-backed) ## Testing - \`pnpm run tsc && pnpm run lint && pnpm run test\` (1475 passing) - Manual (next step): click Sync now on a device row while its drawer is expanded; the pip pulses mint-green during the sync and settles back to its resolved color when done. On first load of the Sync tab, three skeleton rows show briefly instead of a generic block loader. Stacked on #964. PR 4 wraps up the series with handoff anatomy pages.
kunickiaj
added a commit
that referenced
this pull request
Apr 23, 2026
## Description PR 4 (final) of the Sync tab redesign (plan: docs/plans/2026-04-23-sync-tab-redesign.md). Ships four pattern anatomy pages + a README index at docs/design/: - \`device-row-anatomy.md\` — list-item density pattern (compact row + click-to-expand drawer). DOM structure, states, touch-target rules, accessibility wiring. - \`action-shelf-anatomy.md\` — toolbar layout and button-prominence rules. "At most one filled-primary per line of sight" convention for the devices toolbar and any future sibling toolbars. - \`attention-vocabulary-anatomy.md\` — the unified offline / degraded / attention / syncing visual language. Pip sizes, pulse timing, Gestalt pairing between attention rows and device rows. - \`disclosure-region-anatomy.md\` — inline-expand vs. popover vs. modal decision table, focus-management guidance, anti-patterns. These document the patterns introduced by PRs 1–3 so other tabs can adopt the same vocabulary without re-deriving decisions. ## Type of Change - [x] Documentation ## Testing Docs-only change; no \`tsc\`/\`lint\`/\`test\` impact. Verified that the four pages render correctly as markdown. Stacked on #965. Completes the 4-PR Sync tab redesign series: - #963 — diagnostics sub-view + Overview card removal - #964 — device-row + drawer + primitives - #965 — syncing-pip override + skeleton + empty state - #966 — handoff anatomy pages (this PR)
kunickiaj
added a commit
that referenced
this pull request
Apr 23, 2026
## Description Remediation PR on top of #963–#966. Addresses the findings from four brutal reviews across the stack. Batched here so reviewers see one coherent "Ramsay fix" diff instead of amending four in-flight PRs. ### Bugs fixed - **Deep-link regression (#963, P0).** Bookmarking \`#sync/diagnostics\` no longer lands on the main view. \`setActiveTab\` now only rewrites the hash when the top-level tab actually changed; a new \`parseTabFromHash\` helper centralizes the sub-view-aware split. - **Hashchange listener mismatch (#963, P0).** \`app.ts\` now uses \`parseTabFromHash\` too, so sub-view hash transitions (e.g. back button from \`#sync\` → \`#sync/diagnostics\`) fire \`switchTab\` correctly. - **Dead \`listMount\`/\`listHeading\` plumbing (#963, P1).** Removed from \`TeamSyncPanelProps\` and \`render-team-sync.ts\`. The old \`listHeading = list?.previousElementSibling\` was toggling the wrong sibling's \`hidden\` after the \`#syncTeamStatus\` element was removed — silent visibility corruption. - **Row \`<button>\` a11y grenade (#964, P0).** The row head is no longer a \`<button>\`. The chevron is now the only interactive element (\`.device-row-toggle\`), with a clean accessible name ("Expand device {name}"). Badges, direction glyphs, and the name with its \`title\` attribute no longer pollute the button's accessible-name computation. - **\`ActionShelf\` and \`TrustChip\` shipped unused (#964, P2).** Deleted both; along with their dead CSS (\`.action-shelf\`, \`.settings-button.sync-btn-primary\`, \`.peer-scope-chip\` tone variants). Reintroduce when a consumer actually needs them. - **\`syncing\` pip override is vaporware (#965, P1).** Reverted. The local \`syncBusy\` state only fires on the per-row Sync-now button; global Sync now never flipped any row, and the backend has no per-peer in-flight signal. The pulse CSS stays so the state is ready when a real signal lands. Filed as follow-up. ### Doc drift fixed (#966) - Removed phantom \`--pip-size-sm\` / \`--pip-size-md\` tokens (PresencePip sizes are just \`6 | 8\` literals). - Removed \`--accent-warm-strong\` implication that attention pips use a distinct hue — they don't, the CSS falls back to \`--accent-warm\`. Pulse alone distinguishes attention from offline. - \`DeviceRow\` props block relabeled as a proposed interface; the real component is still \`SyncPeerCard\`. - Deleted \`action-shelf-anatomy.md\` (no consumer primitive). - Updated "don't nest drawers" anti-pattern to acknowledge that inline sub-disclosures inside a drawer are fine (\`PeerScopeCollapsible\` inside the device drawer is the example). - Focus-management claim clarified as emergent, not designed. ### Code smell sweep (#964) - Deleted underscore-prefixed dead vars (\`_effectiveInclude\`, \`_effectiveExclude\`, \`_inheritsGlobal\`, \`_summaryText\`). - Moved the mid-file \`renderIntoSyncMount\` import to the top. ## Type of Change - [x] Bug fix - [x] Code cleanup - [x] Documentation correction ## Testing - \`pnpm run tsc && pnpm run lint && pnpm run test\` (1475 passing, 386 files linted — 2 fewer than before thanks to the primitive deletions). - Manual next step: bookmark \`#sync/diagnostics\`, reload, verify the sub-view loads; tab through the device row, verify only the chevron receives focus. Stacks on #966. Closes out the Ramsay review feedback across the redesign stack.
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.

Description
PR 2 of the Sync tab redesign (plan:
docs/plans/2026-04-23-sync-tab-redesign.md). Changes how each device
is presented in the People & devices list:
clickable row: PresencePip · name · direction arrow · trust badge ·
"Sync: {timestamp}" meta · chevron. Hover elevates, focus-visible
draws a 2px accent outline.
drawer that carries the existing device-management surface
(Sync now / rename / remove / ownership assignment / sharing
scope). Only one row's drawer is open at a time; clicking another
row collapses the previous one.
sectionlandmark for the drawer with a descriptive `aria-label`.
degraded / attention / syncing / unknown), pulse animations
gated by `prefers-reduced-motion`.
mapping. Not wired into the row yet — deferred to a follow-up
so the existing trust badge render path stays intact.
secondary buttons.
for the "at most one filled-accent button per line of sight" rule.
Type of Change
Testing
inline. Click another row; previous collapses. All existing device
actions (rename, sync, remove, scope, ownership) work unchanged.
Stacked on #963. PR 3 adds the loading-states vocabulary (skeletons,
empty state, pulse + pip wiring on Sync now). PR 4 is the handoff
anatomy pages.