Skip to content

fix(desktop): resolve nested button hydration error in WorkspaceListItem#669

Merged
Kitenite merged 2 commits intomainfrom
descendant-button
Jan 8, 2026
Merged

fix(desktop): resolve nested button hydration error in WorkspaceListItem#669
Kitenite merged 2 commits intomainfrom
descendant-button

Conversation

@Kitenite
Copy link
Copy Markdown
Collaborator

@Kitenite Kitenite commented Jan 8, 2026

Summary

  • Fix HTML validation error where <button> elements were nested inside another <button> in WorkspaceListItem
  • Changed outer container from <button> to <div role="button"> with proper accessibility attributes
  • Added keyboard handler (Enter/Space) to maintain accessibility

Test plan

  • Verify hydration error no longer appears in console
  • Test workspace list item click behavior works correctly
  • Test keyboard navigation (Tab, Enter, Space) on workspace items
  • Verify drag-and-drop reordering still works

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Accessibility

    • Workspace sidebar items now support keyboard activation (Enter/Space), improving navigation for keyboard-only users.
  • Bug Fixes

    • Interaction behavior preserved for mouse, double-click, and drag/drop operations to ensure consistent usability.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 8, 2026

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Replaces outer <button> elements with div role="button" tabIndex={0} in the WorkspaceListItem component, preserves drag-and-drop refs and click/double-click handlers, and adds onKeyDown to activate the item on Enter or Space.

Changes

Cohort / File(s) Summary
WorkspaceListItem accessibility
apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx
Replaced native <button> wrappers with <div role="button" tabIndex={0}>, added onKeyDown to invoke click on Enter/Space, retained drag/drop refs, onClick, onMouseEnter, and onDoubleClick; updated closing tags and added biome-ignore lint comment.

Sequence Diagram(s)

(omitted — change is an accessibility/markup update without multi-component control-flow requiring a sequence diagram)

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

Poem

🐰
I swapped a button for a gentle div,
Gave keys their voice — Enter and Space now live.
Drag stays steady, clicks still land,
Small change, big hop — accessibility at hand.

🚥 Pre-merge checks | ✅ 2 | ❌ 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 (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: fixing a nested button hydration error in WorkspaceListItem. It is concise and directly related to the changeset.
Description check ✅ Passed The PR description covers the key aspects of the change including summary, test plan, and implementation details. However, it deviates from the provided template by using a custom summary format instead of the required template sections.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4956baf and a62a690.

📒 Files selected for processing (1)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx

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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx (1)

437-451: Wrap the close button's onClick handler with e.stopPropagation() to prevent event bubbling to the parent div.

Clicking the close button will currently bubble up to the parent div's onClick={handleClick} (line ~302), causing the workspace to activate when the user only intends to delete it. The Input component in the same file demonstrates this pattern correctly at lines 382-383. The BranchSwitcher component already handles this correctly, so no changes are needed there.

Suggested fix
 <Button
   type="button"
   variant="ghost"
   size="icon"
-  onClick={handleDeleteClick}
+  onClick={(e) => {
+    e.stopPropagation();
+    handleDeleteClick();
+  }}
   className={cn(
     "size-6 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity rounded-sm",
     "hover:bg-muted-foreground/10",
     isActive && "opacity-60",
   )}
   aria-label="Close or delete workspace"
 >
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f02bff8 and 4956baf.

📒 Files selected for processing (1)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx
🧰 Additional context used
📓 Path-based instructions (6)
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.{ts,tsx}: For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc
Use alias as defined in tsconfig.json when possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary.
For tRPC subscriptions with trpc-electron, ALWAYS use the observable pattern from @trpc/server/observable instead of async generators, as the library explicitly checks isObservable(result) and throws an error otherwise

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use object parameters for functions with 2+ parameters instead of positional arguments
Functions with 2+ parameters should accept a single params object with named properties for self-documentation and extensibility
Use prefixed console logging with context pattern: [domain/operation] message
Extract magic numbers and hardcoded values to named constants at module top
Use lookup objects/maps instead of repeated if (type === ...) conditionals
Avoid using any type - maintain type safety in TypeScript code
Never swallow errors silently - at minimum log them with context
Import from concrete files directly when possible - avoid barrel file abuse that creates circular dependencies
Avoid deep nesting (4+ levels) - use early returns, extract functions, and invert conditions
Use named properties in options objects instead of boolean parameters to avoid boolean blindness

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx
apps/desktop/src/renderer/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Never import Node.js modules (fs, path, os, net) in renderer process or shared code - they are externalized for browser compatibility

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx
**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

One component per file - do not create multi-component files

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx
apps/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Drizzle ORM for all database operations - never use raw SQL

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Biome for formatting and linting - run at root level with bun run lint:fix or biome check --write

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx
🧠 Learnings (1)
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/*/src/components/{ui,ai-elements,react-flow}/*.tsx : Use kebab-case single files for shadcn/ui components (e.g., button.tsx, base-node.tsx) in src/components/ui/, src/components/ai-elements, and src/components/react-flow/

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (1)
apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx (1)

301-306: LGTM! Keyboard accessibility implemented correctly.

The keyboard handler properly supports Enter and Space keys with preventDefault() to avoid unwanted scrolling. This maintains full keyboard accessibility after converting from button to div.

@Kitenite Kitenite merged commit 0dd7368 into main Jan 8, 2026
4 of 5 checks passed
@Kitenite Kitenite deleted the descendant-button branch January 8, 2026 21:05
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jan 8, 2026

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ⚠️ Neon database branch
  • ⚠️ Electric Fly.io app

Thank you for your contribution! 🎉

saddlepaddle pushed a commit that referenced this pull request Jan 10, 2026
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.

1 participant