Skip to content

🎯 fix: Center Collapsed Sidebar Icons and Unclip Sidebar Focus Rings - #122

Open
dustinhealy wants to merge 4 commits into
mainfrom
fix/click-ui-sidebar
Open

🎯 fix: Center Collapsed Sidebar Icons and Unclip Sidebar Focus Rings#122
dustinhealy wants to merge 4 commits into
mainfrom
fix/click-ui-sidebar

Conversation

@dustinhealy

@dustinhealy dustinhealy commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Three sidebar polish issues, all pre-existing (introduced by the sidebar collapse refactor in #6, not by the click-ui 0.9.1 bump):

  1. In the collapsed rail, icons (logo, nav icons, avatar) sat left of center. The labels stay mounted for the slide animation, but the gap-2.5 between icon and label never collapsed and the truncated label spans kept a shrink-to-fit sliver of width, so justify-center had nothing to center. Collapsed rows now use gap-0 with justify-center, and every label span (logo title, nav labels, user-row name/email container) becomes w-0 flex-none overflow-hidden while collapsed so no residual width or flex-1 growth can absorb the free space. Measured result: icon centers moved from x=26.0 (logo x=20.0) to exactly x=27.5, the true center of the 55px inner rail.
  2. The user-profile button's focus ring was clipped instead of forming a full circle. The global focus convention draws a 1px ring at outline-offset: 2px outside the box, and the row wrapper's overflow-hidden cut it on all sides. The wrapper clip is removed; the labels already truncate and the aside still clips during the width transition.
  3. The collapse toggle at the bottom showed only the top edge of its focus ring: the button is flush with the aside's clipped left/right edges and the viewport bottom. A scoped .sidebar-toggle:focus-visible rule draws the ring inset (outline-offset: -2px), following the existing scoped-override convention in styles.css.

Change Type

  • Bug fix (non-breaking change which fixes an issue)

Testing

New Sidebar.test.tsx (3 cases) asserts the collapsed-state classes (justify-center, gap-0, no overflow-hidden on the user row, sidebar-toggle on the toggle) and that the expanded state restores gap-2.5. Geometry itself is not assertable in jsdom; visual verification below.

Manually verified in the app: collapsed icons center in the rail, the avatar focus ring is a full circle, and tabbing to the collapse toggle shows a complete ring.

Before/after proof:

01_AI-1764_sidebar-icon-centering 02_AI-1765_profile-focus-ring 03_AI-1766_expander-focus-ring

Test Configuration:

  • bunx tsc --noEmit, bunx eslint src/ --max-warnings 0, bunx vitest run (802/802), bun run build: all green
  • Local dev server against local LibreChat backend

Checklist

  • My code adheres to this project's style guidelines
  • I have performed a self-review of my own code
  • My changes do not introduce new warnings
  • I have written tests demonstrating that my changes are effective or that my feature works
  • Local unit tests pass with my changes

Inline @clickhouse/click-ui in vitest server deps and exclude .claude/** from test discovery. click-ui 0.9.1 ships ESM that imports .css files, which Node's loader cannot parse, so Vitest must process the package through Vite.
The collapsed sidebar kept its labels mounted with a gap-2.5 that never collapsed, so the 10px gap next to the zero-width truncated labels pushed the logo, nav icons, and avatar left of center and justify-* had no effect. Rows now drop to gap-0 with justify-center when collapsed, and the user row's flex-1 label container becomes w-0 flex-none so it cannot grow into the free space and offset the avatar.

The user row wrapper's overflow-hidden clipped the avatar button's focus ring, which the global convention draws at a 2px offset outside the box. The wrapper no longer clips; the name and email already truncate inside their min-w-0 container and the aside still clips during the width transition.

The collapse toggle is w-full and flush with the panel edges and the viewport bottom, so ancestor clipping leaves only the top segment of an outside ring visible. A scoped sidebar-toggle override draws the focus outline inset instead.
@dustinhealy dustinhealy changed the title 🐛 fix: Center Collapsed Sidebar Icons and Unclip Sidebar Focus Rings 🎯 fix: Center Collapsed Sidebar Icons and Unclip Sidebar Focus Rings Aug 11, 2026
@dustinhealy
dustinhealy marked this pull request as ready for review August 11, 2026 23:03
Base automatically changed from chore/click-ui-0.9.1 to main August 14, 2026 14:54
@dustinhealy

Copy link
Copy Markdown
Contributor Author

@codex review

@dustinhealy
dustinhealy marked this pull request as draft August 14, 2026 15:03

@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: a0ba92ba09

ℹ️ 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 thread src/components/Sidebar.test.tsx Outdated
Comment thread src/components/Sidebar.test.tsx Outdated
Comment thread src/components/Sidebar.tsx Outdated
…e real sidebar

The collapsed centering switched to w-full justify-center while the aside width was still animating between w-63 and w-14, so the logo, nav icons, and avatar jumped toward the middle of the still-wide sidebar and swept back as it narrowed. A w-10 rail matches the collapsed content width exactly (w-14 minus the px-2 container padding), so icons land in their final centered position immediately and never reflow during the width transition.

The sidebar tests now live under src/components/__tests__ per the repo convention and render the real component through a shared layout-test-utils helper with the real router, click-ui provider, theme provider, query client, and i18n, mocking only the server function boundary. This exercises the real dropdown trigger wrapper structure and capability gating instead of asserting classes on mocked stand-ins.
@dustinhealy

Copy link
Copy Markdown
Contributor Author

@codex re-review

@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: daf6611adf

ℹ️ 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 thread src/test/layout-test-utils.tsx Outdated
Locally defined interfaces live in src/types and are consumed through the types namespace import per the repo convention, so the test helper's options type moves next to SidebarProps in layout.ts.
@dustinhealy

Copy link
Copy Markdown
Contributor Author

@codex re-review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

Reviewed commit: efdc6b449f

ℹ️ 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".

@dustinhealy
dustinhealy marked this pull request as ready for review August 14, 2026 16:32
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