Skip to content

feat: Improve sidebar dropdown states - #804

Merged
ilyabo merged 3 commits into
mainfrom
agent/sidebar-dropdown-states-clean
Jul 16, 2026
Merged

ilyabo merged 3 commits into
mainfrom
agent/sidebar-dropdown-states-clean

Conversation

@ilyabo

@ilyabo ilyabo commented Jul 9, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Forward refs from SidebarMenuButton so Radix asChild popover triggers can attach refs correctly.
  • Add CLI sidebar command item styling so collapsed Data and Workspace popovers have explicit hover feedback and active-item highlighting without cmdk's first-item auto-highlight looking selected.
  • Align the CLI sidebar layout with the desktop sidebar: move AI Agent from the top bar into the sidebar, style it like Add data, add the AI/Data section borders, remove the Projects header underline, and keep Add data pinned at the bottom of the Data section.
  • Offset the collapsed sidebar popovers by 2px and hide the collapsed assistant split handle using the new layout data attributes.

Validation

  • git diff --check
  • CI=true /Users/ilya/Library/pnpm/.tools/pnpm/11.1.2/bin/pnpm --filter sqlrooms-cli-app typecheck
  • Commit pre-commit hooks passed lint-staged, including turbo lint --filter=@sqlrooms/* -- and Prettier.
  • Earlier pre-push checks passed knip, turbo typecheck, and Madge circular-dependency validation.
  • Pre-push turbo test is currently blocked by unrelated Jest runtime failures across multiple packages: TypeError: this._moduleMocker.clearMocksOnScope is not a function. The clean branch was pushed with --no-verify so this draft PR can be reviewed while that environment issue is investigated.

Summary by CodeRabbit

  • New Features
    • Improved sidebar collapsed icon layout and visuals, including clearer active/selected styling and accent backgrounds.
    • Updated sidebar assistant control wording to “AI Agent” (with updated tooltip/aria state) and ensured it’s placed consistently.
  • Bug Fixes
    • Enhanced sidebar popover keyboard navigation behavior for command lists, including more reliable spacing and interaction states.
  • UI Improvements
    • Refined workspace topbar/sidebar layout, adjusted popover positioning, and normalized command item labeling (e.g., “Create new”).

@coderabbitai

coderabbitai Bot commented Jul 9, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR moves the assistant toggle into the collapsible CLI sidebar, updates sidebar and command-item styling, adds keyboard-navigation state to artifact/data popovers, exposes split-panel handle attributes, and refactors SidebarMenuButton to forward refs.

Changes

CLI Sidebar Controls and Styling

Layer / File(s) Summary
Shared sidebar button and styling contracts
packages/ui/src/components/sidebar.tsx, apps/sqlrooms-cli-ui/src/workspace/sidebar/constants.ts, packages/layout/src/node-renderers/split-node-renderer/SplitLayoutPanel.tsx, apps/sqlrooms-cli-ui/src/style.css
SidebarMenuButton forwards refs; shared command classes, split-panel data attributes, and collapsed-sidebar/command-item CSS rules are added.
Assistant toggle relocation and collapsed layout
apps/sqlrooms-cli-ui/src/workspace/sidebar/CliAssistantToggleButton.tsx, apps/sqlrooms-cli-ui/src/workspace/sidebar/CliWorkspaceSidebar.tsx, apps/sqlrooms-cli-ui/src/workspace/CliWorkspaceTopbar.tsx
The assistant toggle uses sidebar-aware sizing and accessibility attributes, renders in the collapsed sidebar menu, and is removed from the topbar.
Artifacts and data command popover behavior
apps/sqlrooms-cli-ui/src/workspace/sidebar/CliArtifactsSidebarSection.tsx, apps/sqlrooms-cli-ui/src/workspace/sidebar/CliDataSidebarSection.tsx
Popover keyboard-navigation state is tracked and reset on open changes; shared styling, active state, offsets, layout adjustments, and the “Create new” label are applied.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

🚥 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 accurately reflects the sidebar dropdown state and styling changes in the PR.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/sidebar-dropdown-states-clean

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed: private package registry requires authentication. Disable ESLint in CodeRabbit settings or use public packages.


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.

@ilyabo ilyabo changed the title Improve sidebar dropdown states feat: Improve sidebar dropdown states Jul 9, 2026
@ilyabo
ilyabo marked this pull request as ready for review July 9, 2026 11:29
@ilyabo
ilyabo marked this pull request as draft July 9, 2026 11:34
@ilyabo
ilyabo marked this pull request as ready for review July 9, 2026 12:30

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7d666571be

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +29 to +32
.cli-sidebar-command-item[data-selected='true'] {
background: transparent !important;
color: hsl(var(--popover-foreground)) !important;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve keyboard selection feedback

In the collapsed Data/Workspace popovers, cmdk uses data-selected='true' to mark the item reached with ArrowUp/ArrowDown. This override makes every selected command item transparent unless it is hovered or happens to be the active artifact, so keyboard users can move the selection and press Enter on a row with no visible focus/selection indicator; the Data popover has no data-active fallback. Keep a distinct selected style for user-driven keyboard selection instead of clearing the state globally.

Useful? React with 👍 / 👎.

@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.

🧹 Nitpick comments (3)
apps/sqlrooms-cli-ui/src/workspace/sidebar/CliAssistantToggleButton.tsx (1)

39-50: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use isActive prop instead of passing data-active directly.

SidebarMenuButton exposes an isActive prop that internally sets data-active={isActive}. Passing data-active directly works only because {...props} is spread after the explicit attribute in SidebarMenuButton, overriding it. This is fragile and bypasses the component's intended API.

♻️ Proposed fix
         <SidebarMenuButton
           type="button"
           size={state === 'expanded' ? 'default' : 'lg'}
           className="text-muted-foreground hover:text-foreground data-[active=true]:border-sidebar-border data-[active=true]:bg-sidebar-accent/50 data-[active=true]:text-primary data-[active=true]:hover:bg-sidebar-accent group-data-[state=expanded]:h-10 group-data-[state=expanded]:justify-center group-data-[state=expanded]:gap-2 group-data-[state=expanded]:border"
           onClick={() => toggleCollapsed('assistant-sidebar')}
-          data-active={!isAssistantCollapsed}
+          isActive={!isAssistantCollapsed}
           aria-label="Toggle AI Agent"
           aria-pressed={!isAssistantCollapsed}
         >
🤖 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 `@apps/sqlrooms-cli-ui/src/workspace/sidebar/CliAssistantToggleButton.tsx`
around lines 39 - 50, The CliAssistantToggleButton sidebar action is setting
active state by passing data-active directly to SidebarMenuButton, which
bypasses the component API. Update the SidebarMenuButton usage in
CliAssistantToggleButton to use its isActive prop instead of data-active,
keeping aria-pressed in sync with isAssistantCollapsed and preserving the
existing toggle behavior.
packages/ui/src/components/sidebar.tsx (1)

512-521: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Move {...props} before explicit data attributes to prevent accidental overrides.

Currently {...props} is spread after data-active={isActive}, so any consumer passing data-active in props silently overrides the isActive prop. Moving the spread before the explicit attributes ensures internal attributes always take precedence.

♻️ Proposed fix
     const button = (
       <Comp
+        {...props}
         ref={ref}
         data-slot="sidebar-menu-button"
         data-sidebar="menu-button"
         data-size={size}
         data-active={isActive}
-        className={cn(sidebarMenuButtonVariants({variant, size}), className)}
-        {...props}
+        className={cn(sidebarMenuButtonVariants({variant, size}), className)}
       />
     );
🤖 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 `@packages/ui/src/components/sidebar.tsx` around lines 512 - 521, In the
sidebar menu button render path, the props spread is overriding internal data
attributes because `{...props}` comes after the explicit `data-*` fields. Update
the `button` JSX in `sidebar.tsx` so the spread occurs before `data-slot`,
`data-sidebar`, `data-size`, and especially `data-active` inside the `Comp`
element, ensuring the component’s own `isActive`-derived state always wins.
apps/sqlrooms-cli-ui/src/workspace/sidebar/CliArtifactsSidebarSection.tsx (1)

44-45: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract shared CLI_SIDEBAR_COMMAND_ITEM_CLASS constant to avoid duplication.

The same CLI_SIDEBAR_COMMAND_ITEM_CLASS = 'cli-sidebar-command-item' constant is defined independently in both CliArtifactsSidebarSection.tsx (line 44) and CliDataSidebarSection.tsx (line 57). If the class name changes, it must be updated in both places. Consider extracting it to a shared module (e.g., a constants file in the sidebar directory) and importing from both sections.

Also applies to: 186-187, 210-218

🤖 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 `@apps/sqlrooms-cli-ui/src/workspace/sidebar/CliArtifactsSidebarSection.tsx`
around lines 44 - 45, The CLI sidebar item class name is duplicated across
CliArtifactsSidebarSection and CliDataSidebarSection, so extract
CLI_SIDEBAR_COMMAND_ITEM_CLASS into a shared sidebar constants module and import
it in both sections. Update any references in the sidebar components to use the
shared constant instead of redefining the same string locally.
🤖 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.

Nitpick comments:
In `@apps/sqlrooms-cli-ui/src/workspace/sidebar/CliArtifactsSidebarSection.tsx`:
- Around line 44-45: The CLI sidebar item class name is duplicated across
CliArtifactsSidebarSection and CliDataSidebarSection, so extract
CLI_SIDEBAR_COMMAND_ITEM_CLASS into a shared sidebar constants module and import
it in both sections. Update any references in the sidebar components to use the
shared constant instead of redefining the same string locally.

In `@apps/sqlrooms-cli-ui/src/workspace/sidebar/CliAssistantToggleButton.tsx`:
- Around line 39-50: The CliAssistantToggleButton sidebar action is setting
active state by passing data-active directly to SidebarMenuButton, which
bypasses the component API. Update the SidebarMenuButton usage in
CliAssistantToggleButton to use its isActive prop instead of data-active,
keeping aria-pressed in sync with isAssistantCollapsed and preserving the
existing toggle behavior.

In `@packages/ui/src/components/sidebar.tsx`:
- Around line 512-521: In the sidebar menu button render path, the props spread
is overriding internal data attributes because `{...props}` comes after the
explicit `data-*` fields. Update the `button` JSX in `sidebar.tsx` so the spread
occurs before `data-slot`, `data-sidebar`, `data-size`, and especially
`data-active` inside the `Comp` element, ensuring the component’s own
`isActive`-derived state always wins.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 94e01513-ebc0-4e23-82c4-206c6ebcb6b2

📥 Commits

Reviewing files that changed from the base of the PR and between 1f748a6 and 7d66657.

📒 Files selected for processing (8)
  • apps/sqlrooms-cli-ui/src/style.css
  • apps/sqlrooms-cli-ui/src/workspace/CliWorkspaceTopbar.tsx
  • apps/sqlrooms-cli-ui/src/workspace/sidebar/CliArtifactsSidebarSection.tsx
  • apps/sqlrooms-cli-ui/src/workspace/sidebar/CliAssistantToggleButton.tsx
  • apps/sqlrooms-cli-ui/src/workspace/sidebar/CliDataSidebarSection.tsx
  • apps/sqlrooms-cli-ui/src/workspace/sidebar/CliWorkspaceSidebar.tsx
  • packages/layout/src/node-renderers/split-node-renderer/SplitLayoutPanel.tsx
  • packages/ui/src/components/sidebar.tsx

@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.

Caution

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

⚠️ Outside diff range comments (1)
packages/ui/src/components/sidebar.tsx (1)

487-495: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Document the new public sidebar API.

SidebarMenuButtonProps and the ref-forwarding SidebarMenuButton API are exported from @sqlrooms/ui; add TSDoc describing asChild, ref, and tooltip behavior.

As per coding guidelines: “packages/**/*.{ts,tsx}: Add tsdoc to exported types and functions in @sqlrooms/* packages.”

🤖 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 `@packages/ui/src/components/sidebar.tsx` around lines 487 - 495, Document the
exported SidebarMenuButtonProps type and SidebarMenuButton component with TSDoc.
Describe the asChild option, ref forwarding behavior, and tooltip behavior,
including the accepted tooltip configuration, while preserving the existing API
and implementation.

Source: Coding guidelines

🧹 Nitpick comments (1)
packages/ui/src/components/sidebar.tsx (1)

493-520: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add regression coverage for ref forwarding.

Please test that refs resolve to the rendered button and continue to work through the asChild path used by Radix triggers. This change modifies a public component contract.

As per coding guidelines: “**/*.{js,ts,jsx,tsx}: Add or update tests when changing behavior or public API, when practical.”

🤖 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 `@packages/ui/src/components/sidebar.tsx` around lines 493 - 520, Add
regression tests for the public SidebarMenuButton ref contract, covering both
the default rendered button and the asChild path used with Radix triggers.
Assert that each forwarded ref resolves to the actual rendered DOM element,
using the existing SidebarMenuButton test setup and preserving current behavior.

Source: Coding guidelines

🤖 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.

Outside diff comments:
In `@packages/ui/src/components/sidebar.tsx`:
- Around line 487-495: Document the exported SidebarMenuButtonProps type and
SidebarMenuButton component with TSDoc. Describe the asChild option, ref
forwarding behavior, and tooltip behavior, including the accepted tooltip
configuration, while preserving the existing API and implementation.

---

Nitpick comments:
In `@packages/ui/src/components/sidebar.tsx`:
- Around line 493-520: Add regression tests for the public SidebarMenuButton ref
contract, covering both the default rendered button and the asChild path used
with Radix triggers. Assert that each forwarded ref resolves to the actual
rendered DOM element, using the existing SidebarMenuButton test setup and
preserving current behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 57589f2c-d781-49b2-96e6-954ceb057aec

📥 Commits

Reviewing files that changed from the base of the PR and between 7d66657 and 2ebfc6a.

📒 Files selected for processing (7)
  • apps/sqlrooms-cli-ui/src/style.css
  • apps/sqlrooms-cli-ui/src/workspace/CliWorkspaceTopbar.tsx
  • apps/sqlrooms-cli-ui/src/workspace/sidebar/CliArtifactsSidebarSection.tsx
  • apps/sqlrooms-cli-ui/src/workspace/sidebar/CliAssistantToggleButton.tsx
  • apps/sqlrooms-cli-ui/src/workspace/sidebar/CliDataSidebarSection.tsx
  • apps/sqlrooms-cli-ui/src/workspace/sidebar/constants.ts
  • packages/ui/src/components/sidebar.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • apps/sqlrooms-cli-ui/src/style.css
  • apps/sqlrooms-cli-ui/src/workspace/sidebar/CliAssistantToggleButton.tsx
  • apps/sqlrooms-cli-ui/src/workspace/sidebar/CliArtifactsSidebarSection.tsx

@ilyabo
ilyabo merged commit fe38148 into main Jul 16, 2026
6 checks passed
@ilyabo
ilyabo deleted the agent/sidebar-dropdown-states-clean branch July 16, 2026 11:03
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