7.9 KiB
7.9 KiB
planning-ui.md
UI Planning for workspace-chat-polish
This document outlines the visual hierarchy, component boundaries, interaction affordances, keyboard parity, responsive behavior, and handoff decisions for the Chat sidebar polish, grounded in the existing specification.
1. Overview
- The Chat sidebar is a reusable, contextual component mounted only on Chat routes, replacing the Spaces sidebar in that context.
- It contains exactly three collapsible sections: Favorites, Channels, and DMs.
- The sidebar must not own message history; conversation ownership remains with
ChatWorkspace.
2. Visual Hierarchy
| Level | Component | Responsibility | Evidence |
|---|---|---|---|
| Global Shell | AppShell |
Determines if current route is a Chat route and selects Sidebar vs ChatSidebar. |
Spec §182 |
| Chat Context | ChatSidebar |
Owns section state, search/filter, navigation, and mutations. | Spec §183 |
| Section Header | ChatSectionHeader |
Disclosure control, hover/focus actions, Add, More menu. | Spec §100‑104 |
| List Rows | ChatListRow (shared) |
Avatar, label, preview/count, selected state, unread treatment. | Spec §125‑126 |
| Conversation | ChatWorkspace |
Owns message history, thread state, composer, message mutations. | Spec §186 |
| Composer | ChatComposer |
Accepts explicit send/edit mode, controlled body, submit/cancel callbacks. |
Spec §146‑147 |
| Delete | Shared accessible dialog | Confirms destructive action, traps/restores focus, disables duplicate submission. | Spec §148‑149 |
3. Component Boundaries
ChatSidebar: Reusable, route‑aware, must not own message history.ChatSectionHeader: Handles disclosure (aria-expanded), hover/focus visibility, Add and More actions.ChatListRow: Shared row primitive for Favorites, Channels, DMs with variants for metadata, unread state, and participant avatars.ChatWorkspace: AfterChatSidebarmounts, removes its own channel‑navigation aside to avoid duplicate navigation.ChatComposer: Controlled edit state; populates composer with original body, showsUpdate/Cancel, preserves conflict recovery.
4. Interaction Affordances
- Hover/Focus: All actions (Add, More, disclosure) hidden at rest but exposed on
:hoverand:focus-within. Usefocus-visiblefor keyboard exposure. - Section Disclosure:
aria-expandedon the disclosure control; labelled region for section body. - Add Actions: Right‑aligned in section header; also accessible via keyboard focus.
- More Menu: Right‑aligned in section header; provides section‑level actions.
- Message Identity: Use avatar primitive; display name > email > fallback (e.g.,
Unknown member). Raw UUID never shown as primary label. Tooltip for abbreviated identity. - Edit Flow: Focus primary composer → load original body → show
Update/SaveandCancel→ preserve edited message in history with editing indicator. - Delete Flow: Open shared accessible dialog stating “deletion is destructive”, provide Cancel and Delete actions, prevent accidental submission, restore focus to originating message action on Cancel.
5. Keyboard Parity
- All hover‑only controls must be reachable via keyboard (
focus-within). - Section headers and row actions must have clear accessible names and maintain
aria-expandedstate. - Focus management: Delete dialog traps focus; on Cancel restores focus to the originating message action.
6. Responsive Behavior
- Desktop: Secondary Chat surface 260–300 px wide, bordered from conversation; both are independently scrollable.
- Narrow Viewports: Chat surface becomes an accessible sheet/drawer (single column) rather than forcing a three‑column layout.
- Maintain global rail width and behavior across breakpoints.
7. Open Risks & Decisions
| Risk | Description | Decision / Mitigation |
|---|---|---|
| Flat Channels list length | May become long; requires search/filter now but keep grouping opt‑in. | Implement search/filter affordance in ChatSectionHeader now; grouping remains user‑selected later (Spec §161). |
| System status visibility | Save, send failures, reconnect, delete completion need visible status and non‑visual announcements. | Use existing status primitives (toast/aria-live) and ensure announcements on mutation completion (Spec §162). |
| Edit Cancel path clarity | Must be obvious; edit state belongs to conversation scope. | Ensure Update/Cancel buttons are prominently styled and keyboard‑accessible; focus returns to message action after cancel (Spec §163). |
| Edit pending state | Disable actions while mutations pending; show conflict recovery. | Disable Update/Delete during pending; surface conflict message rather than losing text (Spec §166). |
| Delete dialog focus handling | Must trap focus and restore on Cancel. | Use shared dialog primitive with focus trap; verify focus restoration after cancel (Spec §149). |
| Profile fallback | Should never render raw UUID as primary author label. | Fallback to initials or Unknown member; show tooltip for abbreviated identity (Spec §132). |
| Favorite cross‑workspace authorization | Must reject targets outside active workspace. | Enforce via service authorization; unique indexes on discriminated target; do not weaken cross‑workspace checks (Spec §198). |
| Channel metadata & space links | Optional nullable spaceId only if justified; must stay tenant‑scoped. |
Add minimal reusable fields (nullable spaceId + bounded metadata) and enforce object‑type validation in service layer (Spec §199). |
| DM participant projection | Must validate one or many participants and render identity safely. | Reuse existing createDirect input; ensure participant picker shows safe identity; group‑DM indicator for >1 participant (Spec §128‑129, §222). |
| Route detection helper | Must avoid false positives; recognize only /[workspaceSlug]/chat and descendants. |
Implement segment‑aware helper based on usePathname (Spec §191). |
| Message history ownership | ChatSidebar must not own message history. |
Ensure ChatWorkspace remains sole owner; ChatSidebar only provides navigation and section state (Spec §183‑186). |
8. Handoff Decisions
- Route‑aware shell to render
ChatSidebaronly on Chat routes; preserve existingSidebarelsewhere. - Extract ChatSidebar contracts from
ChatWorkspacewithout altering data behavior (Spec §110‑111). - Implement profile projection for channel authors to display safe identity (Spec §197).
- Reuse existing composer for edit mode; add explicit
editmode control. - Adopt shared accessible dialog for delete flow; no inline delete panel.
- Favorites persistence to evolve from object‑only to discriminated target (
object/chatChannel) with mutual‑exclusion and unique indexes (Spec §198). - Channel metadata to be added only if product use requires it; keep space grouping optional and non‑visual by default.
File: /workspace/submatter/.convoys/workspace-chat-polish/planning-ui.md
Key Decisions:
- ChatSidebar is route‑aware, reusable, and owns only section state (no message history).
- Component boundaries defined:
ChatSidebar,ChatSectionHeader,ChatListRow,ChatWorkspace,ChatComposer, shared dialog. - Visual language reuses existing primitives; hover/focus actions exposed via
focus-within. - Responsive: 260–300 px sidebar on desktop, sheet/drawer on narrow viewports.
- Edit uses primary composer with
Update/Cancel; delete uses shared accessible dialog with focus management. - Open risks addressed via search/filter, status announcements, edit pending state handling, delete focus trap, profile fallback, cross‑workspace favorite validation, channel metadata justification, DM participant safety, and segment‑aware route detection.