Repository navigation
Build the Core and Chat UI for web and Sim Desktop - #9687
emir-karabeg wants to merge 18 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
[Medium impact] The changes reach the standalone Platform’s Home, Chat, and Settings flows on web and Desktop. Fix the lost Stop control and covered desktop panel tabs before merging. Findings
SummaryAdds standalone Home, Chat and Settings routes for browsers and Sim Desktop, with shared controls, gated fixtures and browser/Electron checks.
|
| onStop={ | ||
| last?.response?.state === 'running' ? () => transition(last, 'stopped') : undefined | ||
| } | ||
| onSubmit={(draft) => { | ||
| const next = userTurn(draft) | ||
| if (id && !removed) { | ||
| changes.setTurnsFor(id, [...turns, next]) |
There was a problem hiding this comment.
In /chat/customer-onboarding?state=full, pressing Enter on a follow-up appends a user turn while the response is running. onStop then disappears because it checks only the last turn, which now has no response. The earlier response stays “Working” with no way to stop it. Track the running turn separately, or block submission while it is running.
| padding-inline: var(--spacing-12); | ||
| min-inline-size: 0; | ||
| height: var(--height-nav); | ||
| border-block-end: var(--spacing-stroke-default) solid var(--ui-divider); | ||
| } | ||
| :global([data-sim-desktop-title-bar]) .header { | ||
| height: var(--spacing-48); | ||
| -webkit-app-region: drag; |
There was a problem hiding this comment.
With the desktop sidebar collapsed, expanding the chat panel puts its tabs under the desktop toolbar and native window buttons. The shell places the content at the top-left, but the panel header keeps only 12px of left padding. Unlike the conversation header, it does not use --ui-navigation-inset. Reserve that space when the panel takes over so its first tab and close control remain clickable.
| <ChatPanels workspaces={shell?.workspaces ?? []} data={panel} key={id?.[0] ?? 'new'}> | ||
| <ChatScreen data={data?.chat ?? null} chatId={id?.[0]} /> |
There was a problem hiding this comment.
Switching chats discards unsent text and selected files. MessageComposer keeps both only in local state, while this route keys the whole panel tree by chat ID. Returning to the original chat creates a fresh composer. Keep drafts in the session, keyed by chat ID, so ordinary navigation does not erase unfinished messages.
| const [displayName, setDisplayName] = useState(name ?? '') | ||
| const [picture, setPicture] = useState<string>() |
There was a problem hiding this comment.
Saving a display name or choosing a profile picture lasts only until the user leaves Preferences. ProfileSettings owns these values locally and is removed on other Settings sections. Returning restores the fixture name and drops the picture. Keep these local edits in the session provider; no database write is needed.
| <ProductSurface preference={appearance}> | ||
| <PlatformShell data={shell} desktopTitle={desktopTitle} navigation={navigation}> | ||
| {children} | ||
| </PlatformShell> |
There was a problem hiding this comment.
Navigation resets shell changes
Each page creates its own PlatformShell, so moving between Home, Chat and Settings resets inbox read marks, dismissed notices and chat sorting. For example, reading an unread item, opening a chat and returning makes that item unread again. Move this session state above the page boundary, alongside the existing chat edits and interface preferences.
There was a problem hiding this comment.
6 issues found and verified against the latest diff
Confidence score: 3/5
chat-screen.tsxcan bring submitted attachments back into the composer when the first send creates a chat. Clear the draft attachments before the route change remounts the composer.recent-items.tsxleaves the remove and select controls too small to tap reliably on coarse-pointer devices. Give both controls larger hit targets.workspace-list.tsxhas no visible focus indicator, so keyboard users may lose track of which workspace is focused. Add a:focus-visibletreatment.product-surface.tsxbriefly renders light for users whose system theme is dark. Resolve the system theme before first paint to avoid the flash.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="apps/sim/platform/design-system/components/recent-items.tsx">
<violation number="1" location="apps/sim/platform/design-system/components/recent-items.tsx:32">
P2: These new recents controls do not provide a coarse-pointer hit target: the row grows to 44px, but the remove button remains an intrinsic icon-sized target and the select button remains text-sized. Give both controls a 44px touch target, such as the existing `IconButton` touch sizing or `TouchTarget` wrapper, while preserving the row layout.</violation>
</file>
<file name="apps/sim/platform/design-system/components/workspace-list.tsx">
<violation number="1" location="apps/sim/platform/design-system/components/workspace-list.tsx:43">
P2: This new keyboard-focusable workspace button has no visible focus indicator because the global stylesheet removes outlines and `.workspaceHit` adds none. Add a shared or workspace-specific `:focus-visible` treatment so keyboard users can identify the active row.</violation>
</file>
<file name="apps/sim/platform/design-system/components/product-surface.tsx">
<violation number="1" location="apps/sim/platform/design-system/components/product-surface.tsx:10">
P2: System appearance always renders light on the server, causing dark-system users to see a light flash before hydration applies the media-query result. Resolve the system theme before first paint, such as with a CSS media-query path plus explicit-theme override or a small theme bootstrap.</violation>
</file>
<file name="apps/sim/platform/design-system/components/select.tsx">
<violation number="1" location="apps/sim/platform/design-system/components/select.tsx:37">
P2: An arbitrary `theme` query can reach this controlled value without matching any option, so the Theme picker renders blank even though the surrounding product falls back to `system`. Ignore values outside `options` here or pass the normalized theme from the settings screen.</violation>
</file>
<file name="apps/sim/platform/design-system/features/chat/chat-screen.tsx">
<violation number="1" location="apps/sim/platform/design-system/features/chat/chat-screen.tsx:100">
P2: The first send from `/chat` clears the composer only until `router.replace` changes `id`; this prop then remounts `MessageComposer` with the unchanged draft attachments, so submitted files reappear in the new chat’s composer. Track and consume the initial draft when submitting before navigation.</violation>
</file>
<file name="apps/sim/platform/design-system/components/notification-tray.module.css">
<violation number="1" location="apps/sim/platform/design-system/components/notification-tray.module.css:10">
P2: The fixed notification stack ignores the bottom safe-area inset, so its action and dismiss controls can sit under the home indicator on notched mobile browsers. Use `max(var(--spacing-20), env(safe-area-inset-bottom))` for the bottom offset.
(Based on your team's feedback about toast safe-area minimum.) [8c7692a3-398e-4004-b266-f2a76922d36c]</violation>
</file>
Reply with feedback, questions, or to request a fix.
Turn on auto-fix | Re-trigger cubic
| {item.label} | ||
| {onRemove ? ( | ||
| <button | ||
| className={styles.removeRecent} |
There was a problem hiding this comment.
P2: These new recents controls do not provide a coarse-pointer hit target: the row grows to 44px, but the remove button remains an intrinsic icon-sized target and the select button remains text-sized. Give both controls a 44px touch target, such as the existing IconButton touch sizing or TouchTarget wrapper, while preserving the row layout.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At apps/sim/platform/design-system/components/recent-items.tsx, line 32:
<comment>These new recents controls do not provide a coarse-pointer hit target: the row grows to 44px, but the remove button remains an intrinsic icon-sized target and the select button remains text-sized. Give both controls a 44px touch target, such as the existing `IconButton` touch sizing or `TouchTarget` wrapper, while preserving the row layout.</comment>
<file context>
@@ -25,8 +27,26 @@ export function RecentItems({ label, title = label, items }: RecentItemsProps) {
- {item.label}
+ {onRemove ? (
+ <button
+ className={styles.removeRecent}
+ type='button'
+ aria-label={`Remove ${item.label} from recents`}
</file context>
Home, Chat, Settings and the navigation shell are real routes in the isolated Platform Next.js app. The browser and Sim Desktop share the renderer. A default-off server fixture supplies populated, empty and stress states without a database.
Home and Chat share a responsive reading column. The Home greeting aligns with its sidebar row and scrolls into the viewport-edge fade. The expand and collapse controls sit at the same toolbar height. A 12px inset surrounds the organization and both sides of the profile footer vertically. Email follows the chart; attention and Calendar share the other column. Inbox and calendar scroll independently. The Build/Search control selects Tasks run or Searches made across the chart and Customize Home. Both metrics share the selected calendar window; missing interior observations keep their day at zero. Calendar events use the solid muted button surface and open keyboard-accessible local details; linking provider records remains Phase 3.
Navigation, tabs, recents and attachment previews share ControlRow. Workspace names, the Workspaces launcher and its tab title are text-only. Compact × controls use the same neutral treatment in tabs, recents and drafts. Primary and destructive confirmations darken by equal perceptual steps, and all textareas suppress manual resize handles. Dialogs share a borderless surface and one quiet Cancel. Each message owns the hover area through its action row. Chat keeps thinking, tools and paragraphs 12px apart, balances tool payload insets and leaves space for the composer after the last turn. Copy and notice feedback share a four-second dwell. The notification count uses the compact Invite button and the same centered label/count treatment as email threads. Its expanded list casts a single subtle shadow outside the scroll viewport. Composer type stays stable across tablet widths; inline ellipses and the labeled range picker have no redundant tooltip. Mail, attention, file metadata, chat clocks and chart dates use a shared time formatter with deterministic fixture clocks.
See the component ownership map, Platform contract and Core/Chat source-state inventory. To run locally:
SIM_PLATFORM_FIXTURES=1 bun run --cwd apps/sim dev:platform; visit/home?state=full,/chat/weekly-review?state=fullor/settings?state=full.Verification exercises the production Next build, Chromium with fixture-on and fixture-off servers, and the native Electron renderer. Browser journeys measure scroll bounds, hit targets and spacing, exercise keyboard selection and focus return, and distinguish resting/hover/pressed feedback in both themes. The design audit checks ownership, token and variant use, timers, modal chrome and the fixture boundary.
Stacked on #9667, which targets staging.