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
27 changes: 27 additions & 0 deletions pr-body.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
## Fix: Workspace section collapsed/expanded states look identical (#976)

### Problem

The workspace section header in the NavPanel uses `collapsible` mode without `onSceneOpen`, so the `ChevronRight` indicator was never rendered. Users could collapse/expand the section but had no visual cue showing the current state — collapsed and expanded headers looked identical.

Additionally, when a user manually collapsed the workspace section and then added a new workspace, the section stayed collapsed, making the new workspace invisible until the user manually expanded it.

### Root Cause

In `SectionHeader.tsx`, the chevron indicator was gated behind `onSceneOpen ?` (line 63), so collapsible-only sections (workspace, assistant sessions) never showed an indicator.

### Changes

1. **`SectionHeader.tsx`** — Render the chevron for both `onSceneOpen` and `collapsible` sections. Added `--collapsed` and `--expanded` CSS modifier classes that rotate the chevron based on `isOpen` state.

2. **`NavPanel.scss`** — Added `transform: rotate(0deg)` for collapsed state and `transform: rotate(90deg)` for expanded state, with the existing `transition: transform` providing smooth animation.

3. **`MainNav.tsx`** — Added a `useEffect` that auto-expands the workspace section when a new workspace is added (tracks `normalWorkspacesList.length`), so newly created workspaces are immediately visible even if the user had previously collapsed the section.

### Validation

- `tsc --noEmit` — no errors in changed files
- `vitest run NavPanelLayout.test.ts` — 4/4 tests pass
- Existing chevron hover behavior (`translateX(1px)` for scene-link sections) is preserved — the rotation classes only apply to `collapsible` sections without `onSceneOpen`

Fixes #976
13 changes: 13 additions & 0 deletions src/web-ui/src/app/components/NavPanel/MainNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,19 @@ const MainNav: React.FC<MainNavProps> = ({
});
}, []);

// Auto-expand workspace section when a new workspace is added
const prevWorkspaceCountRef = useRef(normalWorkspacesList.length);
useEffect(() => {
if (normalWorkspacesList.length > prevWorkspaceCountRef.current) {
setExpandedSections(prev => {
const next = new Set(prev);
next.add('workspace');
return next;
});
}
prevWorkspaceCountRef.current = normalWorkspacesList.length;
}, [normalWorkspacesList.length]);

const closeWorkspaceMenu = useCallback(() => {
setWorkspaceMenuClosing(true);
window.setTimeout(() => {
Expand Down
8 changes: 8 additions & 0 deletions src/web-ui/src/app/components/NavPanel/NavPanel.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,14 @@ $_section-header-height: 24px;
}
}

&__section-indicator--collapsed {
transform: rotate(0deg);
}

&__section-indicator--expanded {
transform: rotate(90deg);
}

&__section-action {
display: inline-flex;
align-items: center;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,17 @@ const SectionHeader: React.FC<SectionHeaderProps> = ({
}
>
<span className="bitfun-nav-panel__section-label">{label}</span>
{onSceneOpen ? (
<span className="bitfun-nav-panel__section-indicator" aria-hidden="true">
{onSceneOpen || collapsible ? (
<span
className={[
'bitfun-nav-panel__section-indicator',
collapsible && !isOpen && 'bitfun-nav-panel__section-indicator--collapsed',
collapsible && isOpen && 'bitfun-nav-panel__section-indicator--expanded',
]
.filter(Boolean)
.join(' ')}
aria-hidden="true"
>
<ChevronRight size={14} />
</span>
) : null}
Expand Down