From cccea5b8fe709de2577b07b6f3e258bab84b7637 Mon Sep 17 00:00:00 2001 From: paanSinghCoder Date: Tue, 3 Mar 2026 16:29:58 +0530 Subject: [PATCH 01/11] fix: sidebar css fixes --- .../components/sidebar/sidebar.module.css | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/packages/raystack/components/sidebar/sidebar.module.css b/packages/raystack/components/sidebar/sidebar.module.css index ed084adf8..34fa5a3bd 100644 --- a/packages/raystack/components/sidebar/sidebar.module.css +++ b/packages/raystack/components/sidebar/sidebar.module.css @@ -25,7 +25,7 @@ } .root[data-closed] { - width: 57px; + width: var(--rs-space-12); } .header { @@ -47,7 +47,7 @@ } .root[data-closed] .main { - align-items: center; + align-items: flex-start; } .root[data-closed] [data-collapse-hidden] { @@ -74,7 +74,7 @@ } .root[data-closed] .nav-item { - justify-content: center; + justify-content: flex-start; } .nav-item:hover { @@ -129,7 +129,7 @@ position: absolute; top: 0; right: 0; - width: 4px; + width: var(--rs-space-2); height: 100%; cursor: ew-resize; transition: background-color 0.2s ease; @@ -159,7 +159,7 @@ } .root[data-closed] .nav-group { - align-items: center; + align-items: flex-start; } .nav-group-header { @@ -186,8 +186,25 @@ width: 100%; } +/* Hide group header visually when collapsed but reserve vertical space to prevent shift */ +.root[data-closed] .nav-group-header { + visibility: hidden; +} + .root[data-closed] .nav-group-label { width: 0; + min-width: 0; + overflow: hidden; opacity: 0; - display: none; + visibility: hidden; + /* Keep in flow (no display: none) so header row height is preserved */ +} + +@media (prefers-reduced-motion: reduce) { + .root, + .nav-item, + .nav-text, + .resizeHandle { + transition: none; + } } From 6c07c92d96996a46e31fcc20373430f5930a9078 Mon Sep 17 00:00:00 2001 From: paanSinghCoder Date: Tue, 3 Mar 2026 16:36:43 +0530 Subject: [PATCH 02/11] feat: update Sidebar item with BellIcon and enhance documentation for accessibility --- apps/www/src/app/examples/page.tsx | 2 +- apps/www/src/content/docs/components/sidebar/index.mdx | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/www/src/app/examples/page.tsx b/apps/www/src/app/examples/page.tsx index f0cd70f19..d0dddafb7 100644 --- a/apps/www/src/app/examples/page.tsx +++ b/apps/www/src/app/examples/page.tsx @@ -97,7 +97,7 @@ const Page = () => { Dashboard - + }> Analytics diff --git a/apps/www/src/content/docs/components/sidebar/index.mdx b/apps/www/src/content/docs/components/sidebar/index.mdx index 02a9522fb..cff3cf910 100644 --- a/apps/www/src/content/docs/components/sidebar/index.mdx +++ b/apps/www/src/content/docs/components/sidebar/index.mdx @@ -73,6 +73,8 @@ You can use Sidebar as a controlled component to conditionally render different The Sidebar implements the following accessibility features: +- **Reduced motion** — Respects the user's motion preferences. When the system "Reduce motion" setting is enabled, collapse/expand and hover transitions are disabled so the sidebar updates without animation. + - Proper ARIA roles and attributes - `role="navigation"` for the main sidebar From b8cee0ee234830b169049f9871e82d1017ba2db3 Mon Sep 17 00:00:00 2001 From: paanSinghCoder Date: Tue, 3 Mar 2026 17:04:40 +0530 Subject: [PATCH 03/11] feat: enhance DemoPreview component with customizable preview styles and add new icons to Sidebar --- apps/www/src/components/demo/demo-preview.tsx | 20 ++- apps/www/src/components/demo/demo.tsx | 10 ++ .../www/src/components/demo/styles.module.css | 68 ++++++++ apps/www/src/components/demo/types.ts | 1 + .../content/docs/components/sidebar/demo.ts | 159 +++++++++++++----- 5 files changed, 211 insertions(+), 47 deletions(-) diff --git a/apps/www/src/components/demo/demo-preview.tsx b/apps/www/src/components/demo/demo-preview.tsx index bfb95ed53..bdb1c6849 100644 --- a/apps/www/src/components/demo/demo-preview.tsx +++ b/apps/www/src/components/demo/demo-preview.tsx @@ -12,7 +12,8 @@ export default function DemoPreview({ code, tabs, scope, - codePreview + codePreview, + previewClassName }: DemoPreviewProps) { const [activeTab, setActiveTab] = useState(0); const [activeCodePreviewTab, setActiveCodePreviewTab] = useState(0); @@ -39,8 +40,21 @@ export default function DemoPreview({ ))} )} -
- +
+
{Array.isArray(codePreview) ? ( diff --git a/apps/www/src/components/demo/demo.tsx b/apps/www/src/components/demo/demo.tsx index 83d2b8d66..58ec4b009 100644 --- a/apps/www/src/components/demo/demo.tsx +++ b/apps/www/src/components/demo/demo.tsx @@ -8,6 +8,12 @@ import { UploadIcon } from '@radix-ui/react-icons'; import * as Apsara from '@raystack/apsara'; +import { + BellIcon, + FilterIcon, + OrganizationIcon, + SidebarIcon +} from '@raystack/apsara/icons'; import dayjs from 'dayjs'; import { Home, Info, Laugh, X } from 'lucide-react'; import NextLink from 'next/link'; @@ -24,6 +30,10 @@ export default function Demo(props: DemoProps) { data, scope = { ...Apsara, + BellIcon, + FilterIcon, + OrganizationIcon, + SidebarIcon, DataTableDemo, LinearMenuDemo, PopoverColorPicker, diff --git a/apps/www/src/components/demo/styles.module.css b/apps/www/src/components/demo/styles.module.css index 9851210de..78fa1b67e 100644 --- a/apps/www/src/components/demo/styles.module.css +++ b/apps/www/src/components/demo/styles.module.css @@ -24,6 +24,74 @@ border-bottom: 0.5px solid var(--rs-color-border-base-primary); } +.previewTop { + align-items: flex-start; + justify-content: flex-start; + padding: 0; + min-height: unset; +} + +.previewContentTop { + padding: 0 !important; + align-items: flex-start; + justify-content: flex-start; + flex-direction: column; +} + +.previewContentTop > * { + margin-bottom: var(--rs-space-8); +} + +.previewContentTop::after { + content: ''; + display: block; + width: calc(100% - 2 * var(--rs-space-8)); + min-height: 200px; + margin: 0 var(--rs-space-8) var(--rs-space-8); + border: 2px dashed var(--rs-color-border-base-secondary); + box-sizing: border-box; +} + +.previewSidebar { + display: flex; + flex-direction: row; + align-items: stretch; + justify-content: flex-start; + min-height: 480px; + height: 480px; + width: 100%; + padding: 0; +} + +.previewSidebar > * { + padding-bottom: 0 !important; + margin-bottom: 0 !important; + height: 100%; + min-height: 0; +} + +.previewContentSidebar { + padding: 0 !important; + padding-bottom: 0 !important; + margin-bottom: 0 !important; + height: 100%; + width: 100%; + display: flex; + flex-direction: column; +} + +/* Single direct child (react-live wrapper) grows to fill so inner Flex/Sidebar get a defined height */ +.previewContentSidebar > * { + flex: 1; + min-height: 0; + height: 100%; +} + +/* Sidebar aside: height 100% doesn't resolve in this context, use fixed height to match preview */ +.previewSidebar aside { + height: 480px; +} + .previewReset { position: absolute; bottom: 8px; diff --git a/apps/www/src/components/demo/types.ts b/apps/www/src/components/demo/types.ts index 17f49060c..e11845460 100644 --- a/apps/www/src/components/demo/types.ts +++ b/apps/www/src/components/demo/types.ts @@ -10,6 +10,7 @@ export type DemoPreviewProps = { tabs?: { name: string; code: string }[]; scope?: ScopeType; codePreview?: string | TabProps[]; + previewClassName?: string; }; export type DemoPlaygroundProps = { diff --git a/apps/www/src/content/docs/components/sidebar/demo.ts b/apps/www/src/content/docs/components/sidebar/demo.ts index 8278e96f6..ec4b92c21 100644 --- a/apps/www/src/content/docs/components/sidebar/demo.ts +++ b/apps/www/src/content/docs/components/sidebar/demo.ts @@ -1,173 +1,244 @@ 'use client'; +const mainAreaStyle = `{{ flex: 1, border: '2px dashed var(--rs-color-border-base-secondary)', margin: 'var(--rs-space-4)', boxSizing: 'border-box' }}`; + +const sidebarLayout = (sidebar: string) => + ` + ${sidebar.trim()} + +`; + +const sidebarLayoutRight = (sidebar: string) => + ` + + ${sidebar.trim()} +`; + export const preview = { type: 'code', - code: ` + previewClassName: 'previewSidebar', + code: sidebarLayout(` - + Apsara - }> - } active> + + } active> Dashboard - } disabled> + }> + Analytics + + }> Settings + + }> + Reports + + }> + Activities + + - }> + }> Help - }> - Help + }> + Help & Support - ` + `) }; export const positionDemo = { type: 'code', + previewClassName: 'previewSidebar', tabs: [ { name: 'Left', - code: ` + code: sidebarLayout(` - + Apsara - } active>Dashboard - } disabled>Settings + + } active>Dashboard + }>Analytics + }>Settings + + + }>Help + - ` + `) }, { name: 'Right', - code: ` + code: sidebarLayoutRight(` - + Apsara - } active>Dashboard - } disabled>Settings + + } active>Dashboard + }>Analytics + }>Settings + + + }>Help + - ` + `) } ] }; export const stateDemo = { type: 'code', + previewClassName: 'previewSidebar', tabs: [ { name: 'Expanded', - code: ` + code: sidebarLayout(` - + Apsara - } active>Dashboard - } disabled>Settings + + } active>Dashboard + }>Analytics + }>Settings + + + }>Help + - ` + `) }, { name: 'Collapsed', - code: ` + code: sidebarLayout(` - + Apsara - } active>Dashboard - } disabled>Settings + + } active>Dashboard + }>Analytics + }>Settings + + + }>Help + - ` + `) }, { name: 'Uncontrolled', - code: ` + code: sidebarLayout(` - + Apsara - } active>Dashboard - } disabled>Settings + + } active>Dashboard + }>Analytics + }>Settings + + + }>Help + - ` + `) }, { name: 'Uncontrolled (default open)', - code: ` + code: sidebarLayout(` - + Apsara - } active>Dashboard - } disabled>Settings + + } active>Dashboard + }>Analytics + }>Settings + + + }>Help + - ` + `) } ] }; export const tooltipDemo = { type: 'code', - code: ` - + Apsara - } active>Dashboard - } disabled>Settings + + } active>Dashboard + }>Analytics + }>Settings + + + }>Help + - ` + `) }; From b52234627b462f6e7bd01e8697f2f90efe010e72 Mon Sep 17 00:00:00 2001 From: paanSinghCoder Date: Tue, 3 Mar 2026 17:11:53 +0530 Subject: [PATCH 04/11] feat: add collapsible and hide tooltip demos to Sidebar documentation --- .../www/src/components/demo/styles.module.css | 2 +- .../content/docs/components/sidebar/demo.ts | 42 +++++++++++++++++++ .../content/docs/components/sidebar/index.mdx | 42 ++++++++++++++++--- 3 files changed, 79 insertions(+), 7 deletions(-) diff --git a/apps/www/src/components/demo/styles.module.css b/apps/www/src/components/demo/styles.module.css index 78fa1b67e..0ddf03cd1 100644 --- a/apps/www/src/components/demo/styles.module.css +++ b/apps/www/src/components/demo/styles.module.css @@ -43,7 +43,7 @@ } .previewContentTop::after { - content: ''; + content: ""; display: block; width: calc(100% - 2 * var(--rs-space-8)); min-height: 200px; diff --git a/apps/www/src/content/docs/components/sidebar/demo.ts b/apps/www/src/content/docs/components/sidebar/demo.ts index ec4b92c21..6594b0a42 100644 --- a/apps/www/src/content/docs/components/sidebar/demo.ts +++ b/apps/www/src/content/docs/components/sidebar/demo.ts @@ -242,3 +242,45 @@ export const tooltipDemo = { `) }; + +export const collapsibleDemo = { + type: 'code', + previewClassName: 'previewSidebar', + code: sidebarLayout(` + + + + + + Apsara + + + + + } active>Dashboard + }>Analytics + + + `) +}; + +export const hideTooltipDemo = { + type: 'code', + previewClassName: 'previewSidebar', + code: sidebarLayout(` + + + + + + Apsara + + + + + } active>Dashboard + }>Settings + + + `) +}; diff --git a/apps/www/src/content/docs/components/sidebar/index.mdx b/apps/www/src/content/docs/components/sidebar/index.mdx index cff3cf910..e8c439d11 100644 --- a/apps/www/src/content/docs/components/sidebar/index.mdx +++ b/apps/www/src/content/docs/components/sidebar/index.mdx @@ -4,7 +4,14 @@ description: A collapsible side navigation panel component. source: packages/raystack/components/sidebar --- -import { preview, positionDemo, stateDemo, tooltipDemo } from "./demo.ts"; +import { + preview, + positionDemo, + stateDemo, + tooltipDemo, + collapsibleDemo, + hideTooltipDemo +} from "./demo.ts"; @@ -17,9 +24,12 @@ import { Sidebar } from "@raystack/apsara"; - - - + + + Item + + + ``` @@ -27,7 +37,7 @@ import { Sidebar } from "@raystack/apsara"; ### Root -Groups all parts of the sidebar navigation. +Groups all parts of the sidebar navigation. Use `collapsible={false}` to hide the resize handle and prevent toggling. Use `hideCollapsedItemTooltip` to disable tooltips on items when the sidebar is collapsed. @@ -35,16 +45,24 @@ Groups all parts of the sidebar navigation. The header section is a container component that accepts all `div` props. It's commonly used to create a header with an icon and title. +### Main + +The main section wraps navigation groups and items. It accepts all `div` props and scrolls when content overflows. + ### Group ### Item -*Note: `leadingIcon` is optional and will show a fallback avatar only in collapsed state. You can pass `<>` to render truly nothing.* +*Note: `leadingIcon` is optional and will show a fallback avatar only in collapsed state. You can pass `<>` to render truly nothing. Use the `as` prop to render as a custom element (e.g. a router `Link`).* +### Footer + +The footer section is a container that accepts all `div` props. It's commonly used for secondary links (e.g. Help, Preferences) and stays at the bottom of the sidebar. + ## Examples ### Position @@ -69,6 +87,18 @@ You can use Sidebar as a controlled component to conditionally render different +### Non-collapsible + +Set `collapsible={false}` to hide the resize handle and prevent the sidebar from being collapsed or expanded. + + + +### Hide item tooltips when collapsed + +Set `hideCollapsedItemTooltip` to disable tooltips on navigation items when the sidebar is collapsed. Useful when item labels are redundant with the collapse tooltip or you want a cleaner collapsed state. + + + ## Accessibility The Sidebar implements the following accessibility features: From c1a313be480639f9cabad2c8236e483c08a12893 Mon Sep 17 00:00:00 2001 From: paanSinghCoder Date: Tue, 3 Mar 2026 17:13:13 +0530 Subject: [PATCH 05/11] refactor: update SidebarItem tooltip implementation for better structure --- packages/raystack/components/sidebar/sidebar-item.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/raystack/components/sidebar/sidebar-item.tsx b/packages/raystack/components/sidebar/sidebar-item.tsx index a5e4a96eb..3df3305af 100644 --- a/packages/raystack/components/sidebar/sidebar-item.tsx +++ b/packages/raystack/components/sidebar/sidebar-item.tsx @@ -93,8 +93,9 @@ export const SidebarItem = forwardRef( if (isCollapsed && !hideCollapsedItemTooltip) { return ( - - {content} + + + {children} ); } From b7efa0f1a8d6c8553b04b7de7329537ca900d7e6 Mon Sep 17 00:00:00 2001 From: paanSinghCoder Date: Tue, 3 Mar 2026 17:18:02 +0530 Subject: [PATCH 06/11] refactor: update ARIA roles in Sidebar components for improved accessibility --- apps/www/src/content/docs/components/sidebar/index.mdx | 2 +- packages/raystack/components/sidebar/__tests__/sidebar.test.tsx | 2 +- packages/raystack/components/sidebar/sidebar-item.tsx | 2 +- packages/raystack/components/sidebar/sidebar-misc.tsx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/www/src/content/docs/components/sidebar/index.mdx b/apps/www/src/content/docs/components/sidebar/index.mdx index e8c439d11..7b58eb0d5 100644 --- a/apps/www/src/content/docs/components/sidebar/index.mdx +++ b/apps/www/src/content/docs/components/sidebar/index.mdx @@ -109,7 +109,7 @@ The Sidebar implements the following accessibility features: - `role="navigation"` for the main sidebar - `role="banner"` for the header - - `role="menuitem"` for navigation items + - `role="list"` for item containers (Main groups, Footer) and `role="listitem"` for navigation items - `aria-expanded` to indicate sidebar state - `aria-current="page"` for active items - `aria-disabled="true"` for disabled items diff --git a/packages/raystack/components/sidebar/__tests__/sidebar.test.tsx b/packages/raystack/components/sidebar/__tests__/sidebar.test.tsx index bbbc6e3e7..f5a8296b3 100644 --- a/packages/raystack/components/sidebar/__tests__/sidebar.test.tsx +++ b/packages/raystack/components/sidebar/__tests__/sidebar.test.tsx @@ -199,7 +199,7 @@ describe('Sidebar', () => { it('has proper ARIA attributes', () => { render(); - const footer = screen.getByRole('group', { name: 'Footer navigation' }); + const footer = screen.getByRole('list', { name: 'Footer navigation' }); expect(footer).toBeInTheDocument(); }); }); diff --git a/packages/raystack/components/sidebar/sidebar-item.tsx b/packages/raystack/components/sidebar/sidebar-item.tsx index 3df3305af..c2e2f20d9 100644 --- a/packages/raystack/components/sidebar/sidebar-item.tsx +++ b/packages/raystack/components/sidebar/sidebar-item.tsx @@ -63,7 +63,7 @@ export const SidebarItem = forwardRef( className: cx(styles['nav-item'], classNames?.root), 'data-active': active, 'data-disabled': disabled, - role: 'menuitem', + role: 'listitem', 'aria-current': active ? 'page' : undefined, 'aria-disabled': disabled, ...props diff --git a/packages/raystack/components/sidebar/sidebar-misc.tsx b/packages/raystack/components/sidebar/sidebar-misc.tsx index 8de58bca9..981860802 100644 --- a/packages/raystack/components/sidebar/sidebar-misc.tsx +++ b/packages/raystack/components/sidebar/sidebar-misc.tsx @@ -29,7 +29,7 @@ export const SidebarFooter = forwardRef< ref={ref} className={cx(styles.footer, className)} direction='column' - role='group' + role='list' aria-label='Footer navigation' {...props} > From 6ae09de0a9ab66cb4f76b010ddb546d87ff91816 Mon Sep 17 00:00:00 2001 From: paanSinghCoder Date: Tue, 3 Mar 2026 17:20:25 +0530 Subject: [PATCH 07/11] style: replace inline cursor style with CSS class for SidebarItem fallback avatar --- packages/raystack/components/sidebar/sidebar-item.tsx | 2 +- packages/raystack/components/sidebar/sidebar.module.css | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/raystack/components/sidebar/sidebar-item.tsx b/packages/raystack/components/sidebar/sidebar-item.tsx index c2e2f20d9..e3f6d3042 100644 --- a/packages/raystack/components/sidebar/sidebar-item.tsx +++ b/packages/raystack/components/sidebar/sidebar-item.tsx @@ -76,7 +76,7 @@ export const SidebarItem = forwardRef( variant='soft' color='neutral' fallback={children[0].toUpperCase()} - style={{ cursor: 'pointer' }} + className={styles['nav-fallback-avatar']} /> ) : null} diff --git a/packages/raystack/components/sidebar/sidebar.module.css b/packages/raystack/components/sidebar/sidebar.module.css index 34fa5a3bd..42e4ac51b 100644 --- a/packages/raystack/components/sidebar/sidebar.module.css +++ b/packages/raystack/components/sidebar/sidebar.module.css @@ -106,6 +106,10 @@ flex-shrink: 0; } +.nav-fallback-avatar { + cursor: pointer; +} + .nav-text { color: var(--rs-color-foreground-base-primary); font-size: var(--rs-font-size-small); From 51d4ec89962bb9d32cac838bf5a76e56f0e99e46 Mon Sep 17 00:00:00 2001 From: paanSinghCoder Date: Tue, 3 Mar 2026 17:32:33 +0530 Subject: [PATCH 08/11] style: update SidebarItem to always display text and improve hidden state styling for sr-only --- .../raystack/components/sidebar/sidebar-item.tsx | 8 +++----- .../components/sidebar/sidebar.module.css | 15 +++++++++++---- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/packages/raystack/components/sidebar/sidebar-item.tsx b/packages/raystack/components/sidebar/sidebar-item.tsx index e3f6d3042..e1e14c493 100644 --- a/packages/raystack/components/sidebar/sidebar-item.tsx +++ b/packages/raystack/components/sidebar/sidebar-item.tsx @@ -83,11 +83,9 @@ export const SidebarItem = forwardRef( {!shouldShowFallback && leadingIcon ? ( {leadingIcon} ) : null} - {!isCollapsed && ( - - {children} - - )} + + {children} + ); diff --git a/packages/raystack/components/sidebar/sidebar.module.css b/packages/raystack/components/sidebar/sidebar.module.css index 42e4ac51b..c68b9e284 100644 --- a/packages/raystack/components/sidebar/sidebar.module.css +++ b/packages/raystack/components/sidebar/sidebar.module.css @@ -124,9 +124,15 @@ } .root[data-closed] .nav-text { - width: 0; - opacity: 0; - display: none; + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; } .resizeHandle { @@ -205,10 +211,11 @@ } @media (prefers-reduced-motion: reduce) { + .root, .nav-item, .nav-text, .resizeHandle { transition: none; } -} +} \ No newline at end of file From a2f8abcac970926d325d6b9d583822e8a374fdfa Mon Sep 17 00:00:00 2001 From: paanSinghCoder Date: Tue, 3 Mar 2026 17:40:56 +0530 Subject: [PATCH 09/11] style: refine Sidebar CSS for reduced motion preference and update test for collapsed state accessibility --- .../raystack/components/sidebar/__tests__/sidebar.test.tsx | 4 ++-- packages/raystack/components/sidebar/sidebar.module.css | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/raystack/components/sidebar/__tests__/sidebar.test.tsx b/packages/raystack/components/sidebar/__tests__/sidebar.test.tsx index f5a8296b3..d51360720 100644 --- a/packages/raystack/components/sidebar/__tests__/sidebar.test.tsx +++ b/packages/raystack/components/sidebar/__tests__/sidebar.test.tsx @@ -246,10 +246,10 @@ describe('Sidebar', () => { expect(item).toHaveAttribute('aria-disabled', 'true'); }); - it('hides text when collapsed', () => { + it('keeps label in DOM when collapsed (sr-only for screen readers)', () => { render(); - expect(screen.queryByText(DASHBOARD_ITEM_TEXT)).not.toBeInTheDocument(); + expect(screen.getByText(DASHBOARD_ITEM_TEXT)).toBeInTheDocument(); }); }); diff --git a/packages/raystack/components/sidebar/sidebar.module.css b/packages/raystack/components/sidebar/sidebar.module.css index c68b9e284..3964281d3 100644 --- a/packages/raystack/components/sidebar/sidebar.module.css +++ b/packages/raystack/components/sidebar/sidebar.module.css @@ -211,11 +211,10 @@ } @media (prefers-reduced-motion: reduce) { - .root, .nav-item, .nav-text, .resizeHandle { transition: none; } -} \ No newline at end of file +} From e9423e52fcd8c8733a0c6d10f67892844c155ec5 Mon Sep 17 00:00:00 2001 From: paanSinghCoder Date: Thu, 12 Mar 2026 13:35:52 +0530 Subject: [PATCH 10/11] chore: do not renderf collapsed label --- .../components/sidebar/__tests__/sidebar.test.tsx | 8 ++++++-- .../raystack/components/sidebar/sidebar-item.tsx | 11 ++++++++--- .../raystack/components/sidebar/sidebar.module.css | 12 +++--------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/packages/raystack/components/sidebar/__tests__/sidebar.test.tsx b/packages/raystack/components/sidebar/__tests__/sidebar.test.tsx index d51360720..a56486e53 100644 --- a/packages/raystack/components/sidebar/__tests__/sidebar.test.tsx +++ b/packages/raystack/components/sidebar/__tests__/sidebar.test.tsx @@ -246,10 +246,14 @@ describe('Sidebar', () => { expect(item).toHaveAttribute('aria-disabled', 'true'); }); - it('keeps label in DOM when collapsed (sr-only for screen readers)', () => { + it('hides text when collapsed and sets aria-label for screen readers', () => { render(); - expect(screen.getByText(DASHBOARD_ITEM_TEXT)).toBeInTheDocument(); + expect(screen.queryByText(DASHBOARD_ITEM_TEXT)).not.toBeInTheDocument(); + const dashboardLink = screen.getByRole('listitem', { + name: DASHBOARD_ITEM_TEXT + }); + expect(dashboardLink).toHaveAttribute('aria-label', DASHBOARD_ITEM_TEXT); }); }); diff --git a/packages/raystack/components/sidebar/sidebar-item.tsx b/packages/raystack/components/sidebar/sidebar-item.tsx index 52974881b..0dac1fab0 100644 --- a/packages/raystack/components/sidebar/sidebar-item.tsx +++ b/packages/raystack/components/sidebar/sidebar-item.tsx @@ -66,6 +66,9 @@ export const SidebarItem = forwardRef( role: 'listitem', 'aria-current': active ? 'page' : undefined, 'aria-disabled': disabled, + ...(isCollapsed && typeof children === 'string' + ? { 'aria-label': children } + : {}), ...props }, <> @@ -83,9 +86,11 @@ export const SidebarItem = forwardRef( {!shouldShowFallback && leadingIcon ? ( {leadingIcon} ) : null} - - {children} - + {!isCollapsed && ( + + {children} + + )} ); diff --git a/packages/raystack/components/sidebar/sidebar.module.css b/packages/raystack/components/sidebar/sidebar.module.css index 3964281d3..42e4ac51b 100644 --- a/packages/raystack/components/sidebar/sidebar.module.css +++ b/packages/raystack/components/sidebar/sidebar.module.css @@ -124,15 +124,9 @@ } .root[data-closed] .nav-text { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0, 0, 0, 0); - white-space: nowrap; - border: 0; + width: 0; + opacity: 0; + display: none; } .resizeHandle { From 9e8d1576724d26a0bdc4e366ccc40e92ffadfa3d Mon Sep 17 00:00:00 2001 From: paanSinghCoder Date: Thu, 12 Mar 2026 13:43:37 +0530 Subject: [PATCH 11/11] chore: remove class and fix css --- apps/www/src/components/demo/demo-preview.tsx | 20 +----- .../www/src/components/demo/styles.module.css | 68 ------------------- apps/www/src/components/demo/types.ts | 1 - .../src/components/preview/preview.module.css | 2 +- .../content/docs/components/sidebar/demo.ts | 10 +-- 5 files changed, 6 insertions(+), 95 deletions(-) diff --git a/apps/www/src/components/demo/demo-preview.tsx b/apps/www/src/components/demo/demo-preview.tsx index bdb1c6849..bfb95ed53 100644 --- a/apps/www/src/components/demo/demo-preview.tsx +++ b/apps/www/src/components/demo/demo-preview.tsx @@ -12,8 +12,7 @@ export default function DemoPreview({ code, tabs, scope, - codePreview, - previewClassName + codePreview }: DemoPreviewProps) { const [activeTab, setActiveTab] = useState(0); const [activeCodePreviewTab, setActiveCodePreviewTab] = useState(0); @@ -40,21 +39,8 @@ export default function DemoPreview({ ))}
)} -
- +
+
{Array.isArray(codePreview) ? ( diff --git a/apps/www/src/components/demo/styles.module.css b/apps/www/src/components/demo/styles.module.css index 0ddf03cd1..9851210de 100644 --- a/apps/www/src/components/demo/styles.module.css +++ b/apps/www/src/components/demo/styles.module.css @@ -24,74 +24,6 @@ border-bottom: 0.5px solid var(--rs-color-border-base-primary); } -.previewTop { - align-items: flex-start; - justify-content: flex-start; - padding: 0; - min-height: unset; -} - -.previewContentTop { - padding: 0 !important; - align-items: flex-start; - justify-content: flex-start; - flex-direction: column; -} - -.previewContentTop > * { - margin-bottom: var(--rs-space-8); -} - -.previewContentTop::after { - content: ""; - display: block; - width: calc(100% - 2 * var(--rs-space-8)); - min-height: 200px; - margin: 0 var(--rs-space-8) var(--rs-space-8); - border: 2px dashed var(--rs-color-border-base-secondary); - box-sizing: border-box; -} - -.previewSidebar { - display: flex; - flex-direction: row; - align-items: stretch; - justify-content: flex-start; - min-height: 480px; - height: 480px; - width: 100%; - padding: 0; -} - -.previewSidebar > * { - padding-bottom: 0 !important; - margin-bottom: 0 !important; - height: 100%; - min-height: 0; -} - -.previewContentSidebar { - padding: 0 !important; - padding-bottom: 0 !important; - margin-bottom: 0 !important; - height: 100%; - width: 100%; - display: flex; - flex-direction: column; -} - -/* Single direct child (react-live wrapper) grows to fill so inner Flex/Sidebar get a defined height */ -.previewContentSidebar > * { - flex: 1; - min-height: 0; - height: 100%; -} - -/* Sidebar aside: height 100% doesn't resolve in this context, use fixed height to match preview */ -.previewSidebar aside { - height: 480px; -} - .previewReset { position: absolute; bottom: 8px; diff --git a/apps/www/src/components/demo/types.ts b/apps/www/src/components/demo/types.ts index e11845460..17f49060c 100644 --- a/apps/www/src/components/demo/types.ts +++ b/apps/www/src/components/demo/types.ts @@ -10,7 +10,6 @@ export type DemoPreviewProps = { tabs?: { name: string; code: string }[]; scope?: ScopeType; codePreview?: string | TabProps[]; - previewClassName?: string; }; export type DemoPlaygroundProps = { diff --git a/apps/www/src/components/preview/preview.module.css b/apps/www/src/components/preview/preview.module.css index 1121a7bca..33c3884a4 100644 --- a/apps/www/src/components/preview/preview.module.css +++ b/apps/www/src/components/preview/preview.module.css @@ -1,5 +1,5 @@ .preview { - padding: 40px 20px; + padding: 0; width: 100%; height: 100%; display: flex; diff --git a/apps/www/src/content/docs/components/sidebar/demo.ts b/apps/www/src/content/docs/components/sidebar/demo.ts index 6594b0a42..cfb8dc34e 100644 --- a/apps/www/src/content/docs/components/sidebar/demo.ts +++ b/apps/www/src/content/docs/components/sidebar/demo.ts @@ -3,20 +3,19 @@ const mainAreaStyle = `{{ flex: 1, border: '2px dashed var(--rs-color-border-base-secondary)', margin: 'var(--rs-space-4)', boxSizing: 'border-box' }}`; const sidebarLayout = (sidebar: string) => - ` + ` ${sidebar.trim()} `; const sidebarLayoutRight = (sidebar: string) => - ` + ` ${sidebar.trim()} `; export const preview = { type: 'code', - previewClassName: 'previewSidebar', code: sidebarLayout(` @@ -63,7 +62,6 @@ export const preview = { export const positionDemo = { type: 'code', - previewClassName: 'previewSidebar', tabs: [ { name: 'Left', @@ -118,7 +116,6 @@ export const positionDemo = { export const stateDemo = { type: 'code', - previewClassName: 'previewSidebar', tabs: [ { name: 'Expanded', @@ -217,7 +214,6 @@ export const stateDemo = { export const tooltipDemo = { type: 'code', - previewClassName: 'previewSidebar', code: sidebarLayout(` @@ -266,7 +261,6 @@ export const collapsibleDemo = { export const hideTooltipDemo = { type: 'code', - previewClassName: 'previewSidebar', code: sidebarLayout(`