mirror of
https://github.com/CopilotKit/CopilotKit.git
synced 2026-09-14 16:26:20 +08:00
b24c3e4135
Redesigns the shared `<copilotkit-threads-drawer>` element (`@copilotkit/web-components`) to the new Figma UX, keeping the React, Vue, and Angular wrappers in lockstep. Pure-VIEW change — no `@copilotkit/core`, runtime, or `useThreads` changes. **Ticket:** [ENT-1051](https://linear.app/copilotkit/issue/ENT-1051) · **Figma:** [Thread Drawer](https://www.figma.com/design/feSsBJw1qCfLp0JNnOurrJ/CopilotKit-Intelligence?node-id=723-78) · **Spec:** [Notion](https://app.notion.com/p/3953aa381852819ab464dae3894e7f18) ## What changed - **Header** → right-aligned icon row. On desktop it holds the **collapse** toggle (sidebar glyph); on mobile the **close** toggle. No title text, no "+ New" pill. Optional `slot="header"` preserved (empty by default; the toggle right-aligns after it). - **New Conversation** row (plus-square + label) below the header — keeps `part="new-thread-button"` + the `new-thread` event. - **Recent Conversations** heading + **funnel** filter icon → Active/All popover. Preserves `_filter` + `filter-change` and `part="filter-active"`/`filter-all"`. - **Per-row kebab menu** (⋮) holding Archive/Unarchive + Delete — preserves those events + parts. An open kebab now shields the rest of the list from hover so it reads as a single surface (see Review fixes). - **Delete confirm** is a native `<dialog>` opened with `showModal()` (browser top layer), centered over the drawer's visible box — it can't paint under other UI or drop below the fold. jsdom falls back to the `open` attribute. - **Archived rows** render italic/muted inline in the "All" view. - **Desktop collapse** → `collapsed` / `collapsible` props (default **expanded**) + a `collapse-change` event / `CollapseChangeDetail`. Collapsing sets `--cpk-drawer-reserved-width: 0` on the document root so the host grid reclaims the column with no hydration flicker. - **Unified floating cluster** (Figma "closed" mockup) = `[sidebar-toggle] [+ New Conversation]`, shown in both the mobile-closed and desktop-collapsed states. Mobile stays an off-canvas modal (backdrop / Escape / focus-trap). ## Compatibility - All existing `::part()` names and events are preserved; only **additive** parts are introduced: `collapse-toggle`, `close-toggle`, `section-heading`, `filter-toggle`, `row-menu`, `row-menu-popover`, `launcher-cluster`, `launcher`, `launcher-new-thread`, plus `confirm-dialog`/`confirm-cancel`/`confirm-delete`/`backdrop`. One additive event: `collapse-change`. - Additive wrapper props: `recentLabel` (all frameworks); `collapsible`/`collapsed` + `onCollapseChange` (React) / equivalents in Vue & Angular. - **Usage note (now in the docs):** the drawer and `<CopilotChat>` must share a chat-configuration provider so the drawer drives the chat — `CopilotChatConfigurationProvider` (React/Vue) / `provideCopilotChatConfiguration()` (Angular). The v2 `CopilotKitProvider` does not provide that context on its own. - Verified: **no example `::part()` theme changes required** — every example themes the drawer via inherited `--cpk-drawer-*` custom properties. ## Descoped / changed during development (re: earlier review) - **Client-side search was removed at the designer's request.** There is **no** search UI, `search` event, `search-toggle`/`search-input` part, or `onSearch` wrapper prop in the shipped element. Any remaining "search" mention in older comments is stale. - **Desktop collapse was briefly backed out, then re-restored** per the designer (commit `8bfd245305`). The shipped element **has** collapse (`collapsed` is a live public property — it was not removed). ## Review fixes (commit `0b4f6ca392`) Addressing @MikeRyanDev and @marthakelly: - **`core/threads.ts`** — a full-list refetch (filter-change / retry) now clears `fetchMoreError` on both `listRequested` and `listSucceeded`, so the inline "couldn't load more — retry" banner no longer survives onto a fresh list. - **Escape while confirming delete** — the host keydown handler now consumes Escape while a confirmation is open; previously the bubbled keydown fell through and closed the whole mobile drawer along with the confirmation. - **Open kebab menu shields the list** — `.list.menu-open .row:not(.menu-open)` gets `pointer-events: none`, so other rows no longer reveal their kebab / paint a host `::part(row):hover` background around or behind the open popover. Click-away dismissal is preserved via the existing document pointerdown handler. (Verified live in the langgraph-js example.) - **Docs token** — dropped the removed `--cpk-drawer-rail-width` from the web-components README. ## Testing All suites run via `nx`, green through each package's lefthook pre-commit gate: - `@copilotkit/web-components` — **92** drawer element tests + `:build` green. Covers header collapse/close toggles, New Conversation, funnel filter switch, `recentLabel`, kebab open + archive/delete routing, confirm-dialog gating + native cancel + **backdrop-click dismiss**, **Escape-while-confirming (no drawer close)**, **open-menu row shield**, collapse/cluster/column-reclaim, archived-italic, preserved parts/events, `header` slot + `label` aria-labels. - `@copilotkit/core` — **553** tests incl. the new `clears a lingering fetchMoreError when a full list refetch succeeds`. - `@copilotkit/react-core` — CopilotThreadsDrawer suite + full package **1419** green. - `@copilotkit/vue` — **32** incl. SSR + the `collapsible` boolean-prop-default regression test. - `@copilotkit/angular` — CopilotThreadsDrawer spec **35** (incl. **scoped-chat-input focus**: prefers the ancestor `copilot-chat-view` over the document-global fallback); full package **178**. ## Follow-on - Docs (screenshot + reference/guide) on the release-gated docs PR **#5780**. - Release (`web-components` + `react-core` + `vue` + `angular`, lockstep) + CLI scaffolding bump. - Example grid/theme updates ride the release in **#5828**. - **[ENT-1080](https://linear.app/copilotkit/issue/ENT-1080)** — dedup the per-wrapper `findChatInput` / open-state fallback (marthakelly #6, deliberately deferred as a cross-package refactor). 🤖 Generated with [Claude Code](https://claude.com/claude-code)