diff --git a/CLAUDE.md b/CLAUDE.md index bb43a925..99068d45 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -226,7 +226,7 @@ Test files: `ComponentName.test.tsx` ## Coding Conventions - **Indentation**: 2 spaces (Prettier, `useTabs: false`) -- **Comments**: do not add code comments unless strictly necessary — only to state a non-obvious constraint the code itself can't show. Never add comments that narrate what the next line does or why a change is correct. +- **Comments**: do not add code comments unless strictly necessary — only to state a non-obvious constraint the code itself can't show. Never add comments that narrate what the next line does or why a change is correct. Rationale for a change (why a selector moved, why a class is prefixed, what regression it fixes) belongs in the commit message or PR description, never in the source. Default to zero new comments; if you catch yourself explaining a decision, delete the comment and put it in the commit body. This applies to CSS and stylesheet files too. - **Quotes**: single quotes - **Line width**: 80 characters (Prettier default) - **TypeScript**: strict mode (`strict`, `noUnusedLocals`, `noUnusedParameters`) diff --git a/lib/components/Sidebar/Sidebar.css b/lib/components/Sidebar/Sidebar.css index 2de657df..912327fc 100644 --- a/lib/components/Sidebar/Sidebar.css +++ b/lib/components/Sidebar/Sidebar.css @@ -64,51 +64,6 @@ aside.konstruct-sidebar[data-mode='collapsed'] { padding: 0 0.5rem; } -.konstruct-sidebar li[role='option'] { - flex-shrink: 0; -} - -/* - * Padding lives on the inner anchor (not the `
  • `) so the full - * hover/click area routes through the link — both navigation clicks and - * the Radix Tooltip trigger (in collapsed + expandOnHover mode) cover the - * whole option, not just the icon. - */ -.konstruct-sidebar li[role='option'] > a { - padding: 0.625rem; -} -.konstruct-sidebar[data-mode='expanded'] li[role='option'] > a { - padding: 0.625rem 1rem; -} - -/* - * Hover / active styling driven by CSS custom properties. The properties - * are inherited from `.konstruct-sidebar` (or a closer ancestor) so the - * consumer can theme with a single inline `style` on the wrapper, which - * outranks any un-layered Tailwind utility shipped by federated remote - * micro-frontends. - */ -.konstruct-sidebar li[role='option']:hover { - background-color: var(--konstruct-sidebar-hover-bg, #252a41); - color: var(--konstruct-sidebar-hover-color, #fff); -} -.konstruct-sidebar li[role='option'][data-active='true'] { - background-color: var(--konstruct-sidebar-active-bg, #252a41); - color: var(--konstruct-sidebar-active-color, #fff); -} - -.konstruct-sidebar li[role='option'] > a { - align-items: center; - color: inherit; - display: flex; - gap: 1rem; - text-decoration: none; - width: 100%; -} - -/* Center icon-only content (option icons and Logo) in collapsed mode. */ -.konstruct-sidebar[data-mode='collapsed'] li[role='option'], -.konstruct-sidebar[data-mode='collapsed'] li[role='option'] > a, .konstruct-sidebar[data-mode='collapsed'] [data-konstruct-sidebar-logo] > a { justify-content: center; } diff --git a/lib/components/Sidebar/Sidebar.test.tsx b/lib/components/Sidebar/Sidebar.test.tsx index 7273af5b..afa8955a 100644 --- a/lib/components/Sidebar/Sidebar.test.tsx +++ b/lib/components/Sidebar/Sidebar.test.tsx @@ -123,6 +123,43 @@ describe('Sidebar', () => { expect(mockOnClick).toHaveBeenCalledTimes(1); }); + it('should let a consumer className override the default active and hover colors', async () => { + const { getLink } = setup({ + options: ( + + Option 1 + + ), + }); + + const option = (await getLink(/option 1/i)).closest('li'); + + expect(option).toHaveClass('data-[active=true]:bg-metal-800'); + expect(option).toHaveClass('hover:bg-metal-800'); + expect(option).not.toHaveClass( + 'data-[active=true]:bg-kubefirst-dark-blue-800', + ); + expect(option).not.toHaveClass('hover:bg-kubefirst-dark-blue-800'); + }); + + it('should apply the default active color when no override is passed', async () => { + const { getLink } = setup({ + options: ( + + Option 1 + + ), + }); + + const option = (await getLink(/option 1/i)).closest('li'); + + expect(option).toHaveClass('data-[active=true]:bg-kubefirst-dark-blue-800'); + expect(option).toHaveClass('hover:bg-kubefirst-dark-blue-800'); + }); + it("shouldn't have accessibility violations", async () => { const { component } = setup({ options: ( diff --git a/lib/components/Sidebar/Sidebar.types.ts b/lib/components/Sidebar/Sidebar.types.ts index 38b56300..e64b5871 100644 --- a/lib/components/Sidebar/Sidebar.types.ts +++ b/lib/components/Sidebar/Sidebar.types.ts @@ -122,9 +122,9 @@ export interface Props * Inline styles applied to the wrapper `