Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Frontend UI Audit — CanvasDesignContextualComposer

**Files:** `src/engines/Simulator/apps/canvas/design/CanvasDesignSurface.tsx`, `src/engines/ChatPanel/InputArea/index.tsx`, `src/engines/ChatPanel/InputArea/inputAreaPresentation.ts`, `src/engines/ChatPanel/InputArea/components/InputComposerBars.tsx`, `src/engines/ChatPanel/InputArea/components/InputEditor.tsx`, `src/components/ComposerInput/index.scss`
**Date:** 2026-08-06
**Auditor:** Codex

## D1 — Raw HTML vs Design System

| Line | Element | Verdict | Reason | Suggested change |
| ----------------------------- | ---------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- |
| `InputArea/index.tsx:657` | hidden file `<input>` | keep with reason | Native file-input behavior and its imperative ref are required by the shared upload flow; the control is hidden and activated through the design-system composer action. | — |
| `CanvasDesignSurface.tsx:93` | selected-element pill | keep with reason | Uses the shared `BasePill` editor variant and existing pill size token rather than introducing a Canvas-specific chip. | — |
| `CanvasDesignSurface.tsx:397` | selection close action | keep with reason | Uses the shared `IconButton` rather than introducing a raw interactive element. | — |

## D2 — Arbitrary Tailwind Value vs Token

| Line | Value | Verdict | Reason | Suggested change |
| ---- | ----------------------------- | ---------------- | -------------------------------------------------------------------------------------- | ---------------- |
| — | No new arbitrary color values | keep with reason | The contextual composer uses existing surface, text, border, fill, and primary tokens. | — |

## D3 — Hardcoded Sizes / Colors

| Line | Value | Verdict | Reason | Suggested change |
| ------------------------------- | ------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| `CanvasDesignSurface.tsx:419` | 15px close icon | keep with reason | Sub-16px optical size matches compact toolbar icon proportions and does not represent layout spacing. | — |
| `CanvasDesignSurface.tsx:62-68` | prompt geometry constants | keep with reason | These values are viewport collision and Replay-control clearance bounds calculated in CSS pixels, not reusable visual spacing tokens. | — |

## D4 — Accessibility

| Line | Element | Verdict | Reason | Suggested change |
| ----------------------------- | -------------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------- | ---------------- |
| `CanvasDesignSurface.tsx:273` | contextual composer dialog | keep with reason | The portal has `role="dialog"` and a translated accessible name. | — |
| `CanvasDesignSurface.tsx:93` | selected-element pill | keep with reason | The dismiss action has a translated accessible name, native focus participation, and Enter/Space handling. | — |
| `CanvasDesignSurface.tsx:397` | close `IconButton` | keep with reason | The icon-only control has a translated `aria-label`; the nested icon is hidden from assistive technology. | — |

## D5 — Visual Patterns Observed

| Line | Element | Verdict | Reason | Suggested change |
| --------------------------------- | ------------------------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `InputComposerBars.tsx:383-415` | contextual selected-element reference | fix | The reference previously sat beside the full-width `InputEditor` inside `ComposerBar`, so the two independent layout boxes produced a tall, offset first row. | Route the existing `BasePill` through `InputEditor.leadingContent`, keeping it on the editor's first line without adding it to the serialized document. Implemented. |
| `InputArea/index.tsx:360-379` | contextual composer geometry | fix | The Design prompt previously forced the stacked shared-composer presentation even for a single-line draft, leaving unnecessary vertical space. | Route eligible contextual prompts through the existing compact `ComposerShell`/`ComposerBar` state and retain the existing multiline expansion gate. Implemented. |
| `CanvasDesignSurface.tsx:266-305` | contextual composer visual shell | fix | A Canvas-only rounded background wrapper painted behind the shared compact shell, creating a second surface with a mismatched radius at the right edge. | Remove the duplicate painted wrapper, keep the portal as a non-painting drop-shadow container, and let the shared `ComposerShell` own background, border, and radius. Implemented. |
| `CanvasDesignSurface.tsx:93-123` | selected-element pill shell | keep with reason | It reuses `BasePill`, `PILL_SIZE`, and the editor-pill pointer-to-close interaction, so icon, type, color, and baseline stay aligned with editable `@pill` references. | — |

- The feature extends the shared `InputArea`, `ComposerBar`, `ComposerShell`, `BasePill`, and `IconButton` paths. No parallel Canvas-only input or button pattern was introduced.
- The contextual layout is an explicit shared `InputArea` presentation and is covered alongside the existing compact presentation.
- `InputEditor.leadingContent` is deliberately a visual adornment rather than a `ComposerInput` document node: Canvas selection metadata already has a dedicated submit payload, so serializing the same reference would duplicate context and make an otherwise empty input appear sendable.

## Summary

- 3 fixes implemented
- 10 kept with documented reason
- 0 abstract candidates
46 changes: 46 additions & 0 deletions docs/frontend-ui-audit-2026-08-06/CanvasRevisionActivity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Frontend UI Audit — CanvasRevisionActivity

**Files:** `src/engines/ChatPanel/blocks/CanvasInlineCard/CanvasRevisionActivity.tsx`, `src/engines/ChatPanel/rendering/adapters/CanvasInlineAdapter.tsx`
**Date:** 2026-08-06
**Auditor:** Codex

## D1 — Raw HTML vs Design System

| Line | Element | Verdict | Reason | Suggested change |
| -------------------------------- | ------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| `CanvasRevisionActivity.tsx:101` | navigable activity header | keep with reason | Reuses the shared `EventBlockHeader` and its tokenized `EventNavigateIcon`; no Canvas-only button or clickable shell was added. | — |

## D2 — Arbitrary Tailwind Value vs Token

| Line | Value | Verdict | Reason | Suggested change |
| ---- | ----------------------------- | ---------------- | --------------------------------------------------------------------------------- | ---------------- |
| — | No new arbitrary color values | keep with reason | Navigation inherits the existing event-header fill, text, hover, and icon tokens. | — |

## D3 — Hardcoded Sizes / Colors

| Line | Value | Verdict | Reason | Suggested change |
| -------------------------------- | -------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| `CanvasRevisionActivity.tsx:130` | 14px timeline offset | keep with reason | Existing optical alignment centers the progress rail beneath the shared event icon; the navigation change does not alter it. | — |

## D4 — Accessibility

| Line | Element | Verdict | Reason | Suggested change |
| -------------------------------- | ---------------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| `CanvasRevisionActivity.tsx:101` | shared navigation affordance | keep with reason | Matches the established chat activity contract: the visible shared arrow is a native button, while the full header remains an additional pointer hit area. | — |

## D5 — Visual Patterns Observed

| Line | Element | Verdict | Reason | Suggested change |
| --------------------------------- | ----------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| `CanvasRevisionActivity.tsx:51` | event-to-Canvas locate | keep with reason | Reuses `useBlockHeader` and the session replay pointer used by existing tool activities instead of introducing a second Canvas navigation path. | — |
| `CanvasRevisionActivity.tsx:115` | variable activity title | keep with reason | Uses the shared title slot's truncation contract and native hover text, so long Canvas names stay inside narrow chat columns. | — |
| `CanvasInlineAdapter.tsx:110-114` | revision event identity | keep with reason | The adapter forwards the persisted revision event ID, allowing replay and Canvas projection to resolve the corresponding latest logical Canvas. | — |

- The activity deliberately uses the revision event as the replay anchor. The existing Canvas projection follows `target_event_id` / revision ancestry and materializes the latest valid state of that logical Canvas.
- Records without a stable event ID remain readable but inert, avoiding an ambiguous jump target.

## Summary

- 0 fixes required
- 7 kept with documented reason
- 0 abstract candidates
50 changes: 50 additions & 0 deletions docs/frontend-ui-audit-2026-08-06/CanvasRevisionProgress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Frontend UI Audit — CanvasRevisionActivityAndProgress

**Files:** `src/engines/ChatPanel/blocks/CanvasInlineCard/CanvasRevisionActivity.tsx`, `src/engines/ChatPanel/blocks/CanvasInlineCard/CanvasRevisionProgress.tsx`, `src/engines/ChatPanel/blocks/CanvasInlineCard/CanvasRevisionSteps.tsx`, `src/engines/ChatPanel/events/stream/agent-message/index.tsx`, `src/engines/Simulator/apps/canvas/CanvasApp.tsx`, `src/config/toolIcons.tsx`
**Date:** 2026-08-06
**Auditor:** Codex

## D1 — Raw HTML vs Design System

| Line | Element | Verdict | Reason | Suggested change |
| ------------------------------- | ------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| `CanvasRevisionProgress.tsx:33` | progress status container | keep with reason | This is non-interactive status content, so a semantic `div` with `role="status"` is appropriate and does not duplicate a design-system control. | — |
| `CanvasApp.tsx:783` | Canvas overlay wrapper | keep with reason | The wrapper only positions a shared progress component and deliberately disables pointer events; it is not an interactive control. | — |

## D2 — Arbitrary Tailwind Value vs Token

| Line | Value | Verdict | Reason | Suggested change |
| ------------------------------- | ------------------------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| `CanvasRevisionProgress.tsx:41` | `max-w-[min(28rem,calc(100vw-2rem))]` | keep with reason | The expression combines the desired compact maximum with a viewport collision bound; no single design token captures both constraints. | — |

## D3 — Hardcoded Sizes / Colors

| Line | Value | Verdict | Reason | Suggested change |
| ---------------------------------- | ----------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| `CanvasRevisionProgress.tsx:46-48` | 13px pen / 27px activity ring | keep with reason | These are optical icon sizes inside the token-sized `h-7 w-7` status mark, not reusable layout spacing. | — |
| `CanvasRevisionProgress.tsx:57` | 11px secondary status text | keep with reason | The compact secondary line follows the existing event-metadata hierarchy and remains supplementary to the 12px title. | — |
| `CanvasRevisionSteps.tsx:19-35` | step icon size | keep with reason | The icons use the shared `SESSION_UI_TOKENS.ICON.SIZE_XS` value rather than introducing a Canvas-local size. | — |
| `CanvasRevisionActivity.tsx:120` | `ml-[14px]` timeline inset | abstract | The same 14px icon-column inset appears in Thinking, ContextCompacted, and StackedBlock; it is an established pattern with four consumers. | Promote the full timeline inset/border class to a shared event-block primitive in a dedicated cleanup sweep. |

## D4 — Accessibility

| Line | Element | Verdict | Reason | Suggested change |
| ---------------------------------- | ------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------ | ---------------- |
| `CanvasRevisionProgress.tsx:36-37` | streamed revision status | keep with reason | `role="status"` with polite live announcements exposes phase changes without interrupting the user. | — |
| `CanvasRevisionProgress.tsx:46-50` | decorative progress icons | keep with reason | Both icons are hidden from assistive technology, and reduced-motion users receive a static indicator. | — |
| `CanvasRevisionSteps.tsx:62-76` | ordered work-step list | keep with reason | A translated list label names the process; icon state is reinforced by text and DOM state rather than color alone. | — |

## D5 — Visual Patterns Observed

- Chat and Canvas reuse one `CanvasRevisionProgress` component; only the placement variant changes.
- Running and historical surfaces reuse one `CanvasRevisionSteps` component and one pure phase-state mapping.
- The persistent record reuses `EventBlockHeader`, its icon/title/subtitle slots, and `getEventBlockContainerClasses` instead of creating a Canvas-specific card shell.
- Canvas resolves its icon through the shared Rust-to-Lucide registry; the missing `layout` mapping was fixed in `toolIcons.tsx` rather than hardcoding an icon in the activity component.
- The component uses existing background, border, text, and primary tokens. No Canvas-only button, input, or color system was introduced.
- The Canvas overlay is pointer-transparent, so it cannot steal hover, selection, or Design-mode input from the preview beneath it.

## Summary

- 0 fixes recommended
- 9 kept with documented reason
- 1 abstract candidate
Loading
Loading