Skip to content

fix(wework): UI display fixes for narrow toolbar, cloud popover, and dialogs - #2094

Merged
qdaxb merged 2 commits into
wecode-ai:mainfrom
sdadunderscoresdad:fix/ui-display-bugs-clean
Jul 21, 2026
Merged

qdaxb merged 2 commits into
wecode-ai:mainfrom
sdadunderscoresdad:fix/ui-display-bugs-clean

Conversation

@sdadunderscoresdad

@sdadunderscoresdad sdadunderscoresdad commented Jul 21, 2026 •

Copy link
Copy Markdown
Contributor

Summary

This PR replaces #2090 with a clean, linear history on top of the latest upstream/main.

It bundles the following wework UI display fixes:

  • Cap model selector width and collapse quick phrase labels when the composer toolbar is narrow.
  • Render the cloud-work error popover via a portal and close it on outside click / Escape.
  • Remove forced dark mode from the add-device and cloud-work dialogs.
  • Revert model selector to left-opening and narrow browser occlusion to the cloud dialog.
  • Swallow arrow keys at native input boundaries on macOS to work around a WKWebView/Tauri bug.

Additionally, App.test.tsx is stabilized by mocking the auth provider/state so the login-route test no longer flakes depending on prior test order.

Test plan

  • pnpm --dir wework run typecheck passes
  • pnpm --dir wework test --run passes (192 files, 1914 tests)
  • Local pre-push quality checks pass

Notes

Summary by CodeRabbit

  • Bug Fixes

    • Improved model selector sizing and positioning in narrow desktop layouts.
    • Prevented unwanted horizontal navigation from arrow keys in macOS input fields.
    • Improved embedded browser behavior when cloud connection dialogs open or close.
  • Style

    • Updated project, cloud device, and connection dialogs to use consistent light and dark theme styling.

…dialogs

- Cap model selector width and collapse quick phrases in narrow composer toolbar
- Render cloud-work error popover via portal with outside-click/ESC dismissal
- Remove forced dark mode from add-device and cloud-work dialogs
- Revert model selector to left-opening and narrow browser occlusion to cloud dialog
- Swallow arrow keys at native input boundaries on macOS
- Stabilize App auth routing test by mocking auth state
@coderabbitai

coderabbitai Bot commented Jul 21, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Model selector desktop behavior

Layer / File(s) Summary
Selector width contract
wework/src/components/chat/composer/model-selector-types.ts, wework/src/components/chat/composer/ModelSelectorTrigger.tsx
Adds configurable closed-width caps through maxClosedWidth and --model-selector-width.
Selector layout integration
wework/src/components/chat/composer/ComposerToolbar.tsx, wework/src/components/chat/composer/ModelSelector.tsx, wework/src/components/chat/ChatInput.test.tsx
Applies compact-mode width limits and clamps desktop menus against the visible workspace boundary.
Selector layout tests
wework/src/components/chat/composer/ModelSelector.test.tsx
Tests workspace-relative positioning and capped trigger widths in closed and open states.

macOS input arrow-key guard

Layer / File(s) Summary
Guard implementation and lifecycle wiring
wework/src/lib/macosInputArrowKeyGuard.ts, wework/src/App.tsx
Adds a Tauri/macOS input guard and installs it for the AppShell lifecycle.
Guard behavior tests
wework/src/lib/macosInputArrowKeyGuard.test.ts
Covers platform checks, caret boundaries, composition, selections, and ineligible inputs.

Embedded-browser occlusion

Layer / File(s) Summary
Occlusion synchronization
wework/src/hooks/useEmbeddedBrowserOcclusion.ts, wework/src/features/cloud-connection/CloudConnectionDialog.tsx
Synchronizes cloud dialog visibility with embedded-browser occlusion.
Workspace and popover interaction coverage
wework/src/components/layout/workspace-panels/WorkspaceBrowserPanel.tsx, wework/src/components/layout/workspace-panels/WorkspaceBrowserPanel.test.tsx, wework/src/components/layout/DesktopSidebar.test.tsx
Updates listener lifecycle dependencies, download mocking, and cloud error popover click behavior.

Theme and test updates

Layer / File(s) Summary
Project dialog theme tokens
wework/src/components/projects/DeviceFolderPicker.tsx, wework/src/components/projects/StandaloneProjectDialogs.tsx, wework/src/components/settings/AddCloudDeviceDialog.tsx
Replaces hardcoded dark color classes with shared design-system tokens.
Routing and component test setup
wework/src/App.test.tsx, wework/src/components/chat/composer/QuickPhraseMenu.test.tsx
Mocks authentication directly, adds cleanup, and tests compact and icon-only quick-phrase buttons.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ComposerToolbar
  participant ModelSelector
  participant WorkspaceShell
  ComposerToolbar->>ModelSelector: pass compact width limit
  ModelSelector->>WorkspaceShell: read visible right boundary
  ModelSelector->>ModelSelector: position menu and submenu within boundary
Loading

Possibly related PRs

Suggested reviewers: qdaxb

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and matches the main UI-focused changes, especially the narrow toolbar, cloud popover, and dialog updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
wework/src/lib/macosInputArrowKeyGuard.test.ts (1)

144-156: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a test case for inputs that do not support selection.

If you apply the try/catch fix in macosInputArrowKeyGuard.ts for inputs that throw on selectionStart access, consider adding a corresponding test to guarantee it remains resilient.

🧪 Proposed test
   test('ignores disabled and read-only inputs', () => {
     isTauriRuntimeMock.mockReturnValue(true)
     userAgent = 'Macintosh; Intel Mac OS X 10_15_7'
     const dispose = installMacOSInputArrowKeyGuard()
     const disabledInput = createInput('hello', 5, 5)
     disabledInput.disabled = true
     expect(dispatchArrowKey(disabledInput, 'ArrowRight').defaultPrevented).toBe(false)
 
     const readOnlyInput = createInput('hello', 0, 0)
     readOnlyInput.readOnly = true
     expect(dispatchArrowKey(readOnlyInput, 'ArrowLeft').defaultPrevented).toBe(false)
     dispose()
   })
+
+  test('ignores inputs that do not support selection (e.g. type="number")', () => {
+    isTauriRuntimeMock.mockReturnValue(true)
+    userAgent = 'Macintosh; Intel Mac OS X 10_15_7'
+    const dispose = installMacOSInputArrowKeyGuard()
+    const numberInput = createInput('123', 0, 0)
+    numberInput.type = 'number'
+    
+    // Ensure it doesn't throw and does not swallow the event
+    expect(() => {
+      const event = dispatchArrowKey(numberInput, 'ArrowLeft')
+      expect(event.defaultPrevented).toBe(false)
+    }).not.toThrow()
+    
+    dispose()
+  })
 })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@wework/src/lib/macosInputArrowKeyGuard.test.ts` around lines 144 - 156, The
existing macOS arrow-key guard tests lack coverage for controls whose
selectionStart access throws. Add a test alongside the disabled/read-only case
that uses an input-like control without selection support, dispatches an arrow
key, and verifies the guard does not throw and leaves defaultPrevented
unchanged; clean up the guard afterward.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@wework/src/lib/macosInputArrowKeyGuard.ts`:
- Around line 32-39: Wrap the selection access and boundary checks in the macOS
arrow-key guard function in a try/catch so InvalidStateError from unsupported
input types is handled gracefully. Return false from the catch path, while
preserving the existing behavior for supported inputs and arrow-key boundary
conditions.

---

Nitpick comments:
In `@wework/src/lib/macosInputArrowKeyGuard.test.ts`:
- Around line 144-156: The existing macOS arrow-key guard tests lack coverage
for controls whose selectionStart access throws. Add a test alongside the
disabled/read-only case that uses an input-like control without selection
support, dispatches an arrow key, and verifies the guard does not throw and
leaves defaultPrevented unchanged; clean up the guard afterward.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9a33ac1c-cce6-4edc-81d8-45c13f05bc66

📥 Commits

Reviewing files that changed from the base of the PR and between 71c8846 and 19cd713.

📒 Files selected for processing (19)
  • wework/src/App.test.tsx
  • wework/src/App.tsx
  • wework/src/components/chat/ChatInput.test.tsx
  • wework/src/components/chat/composer/ComposerToolbar.tsx
  • wework/src/components/chat/composer/ModelSelector.test.tsx
  • wework/src/components/chat/composer/ModelSelector.tsx
  • wework/src/components/chat/composer/ModelSelectorTrigger.tsx
  • wework/src/components/chat/composer/QuickPhraseMenu.test.tsx
  • wework/src/components/chat/composer/model-selector-types.ts
  • wework/src/components/layout/DesktopSidebar.test.tsx
  • wework/src/components/layout/workspace-panels/WorkspaceBrowserPanel.test.tsx
  • wework/src/components/layout/workspace-panels/WorkspaceBrowserPanel.tsx
  • wework/src/components/projects/DeviceFolderPicker.tsx
  • wework/src/components/projects/StandaloneProjectDialogs.tsx
  • wework/src/components/settings/AddCloudDeviceDialog.tsx
  • wework/src/features/cloud-connection/CloudConnectionDialog.tsx
  • wework/src/hooks/useEmbeddedBrowserOcclusion.ts
  • wework/src/lib/macosInputArrowKeyGuard.test.ts
  • wework/src/lib/macosInputArrowKeyGuard.ts

Comment on lines +32 to +39
const { selectionStart, selectionEnd, value } = input
if (selectionStart === null || selectionEnd === null) return false
if (selectionStart !== selectionEnd) return false

if (event.key === ARROW_LEFT && selectionStart === 0) return true
if (event.key === ARROW_RIGHT && selectionEnd === value.length) return true
return false
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Handle InvalidStateError when accessing selectionStart on unsupported input types.

Accessing selectionStart or selectionEnd on an HTMLInputElement where the type attribute does not support text selection (such as number, email, checkbox, or radio) throws an InvalidStateError DOMException in WebKit and other modern browsers.

Since this listener intercepts arrow keys globally for all inputs, navigating within a type="number" field using arrow keys will crash the event handler. Wrapping this block in a try/catch ensures the guard gracefully acts as a no-op for unsupported input types.

🛠️ Proposed fix
-  const { selectionStart, selectionEnd, value } = input
-  if (selectionStart === null || selectionEnd === null) return false
-  if (selectionStart !== selectionEnd) return false
-
-  if (event.key === ARROW_LEFT && selectionStart === 0) return true
-  if (event.key === ARROW_RIGHT && selectionEnd === value.length) return true
-  return false
+  try {
+    const { selectionStart, selectionEnd, value } = input
+    if (selectionStart === null || selectionEnd === null) return false
+    if (selectionStart !== selectionEnd) return false
+
+    if (event.key === ARROW_LEFT && selectionStart === 0) return true
+    if (event.key === ARROW_RIGHT && selectionEnd === value.length) return true
+    return false
+  } catch {
+    // Accessing selection properties throws an error on unsupported input types (e.g., type="number")
+    return false
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const { selectionStart, selectionEnd, value } = input
if (selectionStart === null || selectionEnd === null) return false
if (selectionStart !== selectionEnd) return false
if (event.key === ARROW_LEFT && selectionStart === 0) return true
if (event.key === ARROW_RIGHT && selectionEnd === value.length) return true
return false
}
try {
const { selectionStart, selectionEnd, value } = input
if (selectionStart === null || selectionEnd === null) return false
if (selectionStart !== selectionEnd) return false
if (event.key === ARROW_LEFT && selectionStart === 0) return true
if (event.key === ARROW_RIGHT && selectionEnd === value.length) return true
return false
} catch {
// Accessing selection properties throws an error on unsupported input types (e.g., type="number")
return false
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@wework/src/lib/macosInputArrowKeyGuard.ts` around lines 32 - 39, Wrap the
selection access and boundary checks in the macOS arrow-key guard function in a
try/catch so InvalidStateError from unsupported input types is handled
gracefully. Return false from the catch path, while preserving the existing
behavior for supported inputs and arrow-key boundary conditions.

@qdaxb
qdaxb merged commit beec233 into wecode-ai:main Jul 21, 2026
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants