Skip to content
Open
Show file tree
Hide file tree
Changes from 6 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
187 changes: 136 additions & 51 deletions apps/www/src/app/examples/page.tsx

Large diffs are not rendered by default.

166 changes: 161 additions & 5 deletions apps/www/src/content/docs/components/sidebar/demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ export const preview = {
</Flex>
</Sidebar.Header>
<Sidebar.Main>
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />}>
Overview
</Sidebar.Item>
<Sidebar.Group label="Main">
<Sidebar.Item href="#" leadingIcon={<BellIcon width={16} height={16} />} active>
Dashboard
Expand All @@ -46,11 +49,6 @@ export const preview = {
Activities
</Sidebar.Item>
</Sidebar.Group>
<Sidebar.Group label="Support">
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />}>
Help
</Sidebar.Item>
</Sidebar.Group>
</Sidebar.Main>
<Sidebar.Footer>
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />}>
Expand All @@ -76,6 +74,7 @@ export const positionDemo = {
</Flex>
</Sidebar.Header>
<Sidebar.Main>
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />}>Overview</Sidebar.Item>
<Sidebar.Group label="Main">
<Sidebar.Item href="#" leadingIcon={<BellIcon width={16} height={16} />} active>Dashboard</Sidebar.Item>
<Sidebar.Item href="#" leadingIcon={<FilterIcon width={16} height={16} />}>Analytics</Sidebar.Item>
Expand All @@ -100,6 +99,7 @@ export const positionDemo = {
</Flex>
</Sidebar.Header>
<Sidebar.Main>
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />}>Overview</Sidebar.Item>
<Sidebar.Group label="Main">
<Sidebar.Item href="#" leadingIcon={<BellIcon width={16} height={16} />} active>Dashboard</Sidebar.Item>
<Sidebar.Item href="#" leadingIcon={<FilterIcon width={16} height={16} />}>Analytics</Sidebar.Item>
Expand All @@ -114,6 +114,75 @@ export const positionDemo = {
]
};

export const variantDemo = {
type: 'code',
tabs: [
{
name: 'Plain',
code: sidebarLayout(`
<Sidebar open={true} variant="plain">
<Sidebar.Header>
<Flex align="center" gap={3}>
<IconButton size={4} aria-label="Logo">
<BellIcon width={24} height={24} />
</IconButton>
<Text size={4} weight="medium" data-collapse-hidden>Apsara</Text>
</Flex>
</Sidebar.Header>
<Sidebar.Main>
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />}>Overview</Sidebar.Item>
<Sidebar.Group label="Main">
<Sidebar.Item href="#" leadingIcon={<BellIcon width={16} height={16} />} active>Dashboard</Sidebar.Item>
<Sidebar.Item href="#" leadingIcon={<FilterIcon width={16} height={16} />}>Analytics</Sidebar.Item>
</Sidebar.Group>
</Sidebar.Main>
</Sidebar>`)
},
{
name: 'Floating',
code: sidebarLayout(`
<Sidebar open={true} variant="floating">
<Sidebar.Header>
<Flex align="center" gap={3}>
<IconButton size={4} aria-label="Logo">
<BellIcon width={24} height={24} />
</IconButton>
<Text size={4} weight="medium" data-collapse-hidden>Apsara</Text>
</Flex>
</Sidebar.Header>
<Sidebar.Main>
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />}>Overview</Sidebar.Item>
<Sidebar.Group label="Main">
<Sidebar.Item href="#" leadingIcon={<BellIcon width={16} height={16} />} active>Dashboard</Sidebar.Item>
<Sidebar.Item href="#" leadingIcon={<FilterIcon width={16} height={16} />}>Analytics</Sidebar.Item>
</Sidebar.Group>
</Sidebar.Main>
</Sidebar>`)
},
{
name: 'Inset',
code: sidebarLayout(`
<Sidebar open={true} variant="inset">
<Sidebar.Header>
<Flex align="center" gap={3}>
<IconButton size={4} aria-label="Logo">
<BellIcon width={24} height={24} />
</IconButton>
<Text size={4} weight="medium" data-collapse-hidden>Apsara</Text>
</Flex>
</Sidebar.Header>
<Sidebar.Main>
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />}>Overview</Sidebar.Item>
<Sidebar.Group label="Main">
<Sidebar.Item href="#" leadingIcon={<BellIcon width={16} height={16} />} active>Dashboard</Sidebar.Item>
<Sidebar.Item href="#" leadingIcon={<FilterIcon width={16} height={16} />}>Analytics</Sidebar.Item>
</Sidebar.Group>
</Sidebar.Main>
</Sidebar>`)
}
]
};

export const stateDemo = {
type: 'code',
tabs: [
Expand All @@ -129,6 +198,7 @@ export const stateDemo = {
</Flex>
</Sidebar.Header>
<Sidebar.Main>
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />}>Overview</Sidebar.Item>
<Sidebar.Group label="Main">
<Sidebar.Item href="#" leadingIcon={<BellIcon width={16} height={16} />} active>Dashboard</Sidebar.Item>
<Sidebar.Item href="#" leadingIcon={<FilterIcon width={16} height={16} />}>Analytics</Sidebar.Item>
Expand All @@ -152,6 +222,7 @@ export const stateDemo = {
</Flex>
</Sidebar.Header>
<Sidebar.Main>
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />}>Overview</Sidebar.Item>
<Sidebar.Group label="Main">
<Sidebar.Item href="#" leadingIcon={<BellIcon width={16} height={16} />} active>Dashboard</Sidebar.Item>
<Sidebar.Item href="#" leadingIcon={<FilterIcon width={16} height={16} />}>Analytics</Sidebar.Item>
Expand All @@ -175,6 +246,7 @@ export const stateDemo = {
</Flex>
</Sidebar.Header>
<Sidebar.Main>
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />}>Overview</Sidebar.Item>
<Sidebar.Group label="Main">
<Sidebar.Item href="#" leadingIcon={<BellIcon width={16} height={16} />} active>Dashboard</Sidebar.Item>
<Sidebar.Item href="#" leadingIcon={<FilterIcon width={16} height={16} />}>Analytics</Sidebar.Item>
Expand All @@ -198,6 +270,7 @@ export const stateDemo = {
</Flex>
</Sidebar.Header>
<Sidebar.Main>
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />}>Overview</Sidebar.Item>
<Sidebar.Group label="Main">
<Sidebar.Item href="#" leadingIcon={<BellIcon width={16} height={16} />} active>Dashboard</Sidebar.Item>
<Sidebar.Item href="#" leadingIcon={<FilterIcon width={16} height={16} />}>Analytics</Sidebar.Item>
Expand Down Expand Up @@ -227,6 +300,7 @@ export const tooltipDemo = {
</Flex>
</Sidebar.Header>
<Sidebar.Main>
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />}>Overview</Sidebar.Item>
<Sidebar.Group label="Main">
<Sidebar.Item href="#" leadingIcon={<BellIcon width={16} height={16} />} active>Dashboard</Sidebar.Item>
<Sidebar.Item href="#" leadingIcon={<FilterIcon width={16} height={16} />}>Analytics</Sidebar.Item>
Expand All @@ -251,6 +325,7 @@ export const collapsibleDemo = {
</Flex>
</Sidebar.Header>
<Sidebar.Main>
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />}>Overview</Sidebar.Item>
<Sidebar.Group label="Main">
<Sidebar.Item href="#" leadingIcon={<BellIcon width={16} height={16} />} active>Dashboard</Sidebar.Item>
<Sidebar.Item href="#" leadingIcon={<FilterIcon width={16} height={16} />}>Analytics</Sidebar.Item>
Expand All @@ -271,10 +346,91 @@ export const hideTooltipDemo = {
</Flex>
</Sidebar.Header>
<Sidebar.Main>
<Sidebar.Item href="#" leadingIcon={<BellIcon width={16} height={16} />}>Overview</Sidebar.Item>
<Sidebar.Group label="Main">
<Sidebar.Item href="#" leadingIcon={<BellIcon width={16} height={16} />} active>Dashboard</Sidebar.Item>
<Sidebar.Item href="#" leadingIcon={<FilterIcon width={16} height={16} />}>Settings</Sidebar.Item>
</Sidebar.Group>
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />}>
Help
</Sidebar.Item>
</Sidebar.Main>
</Sidebar>`)
};

export const accordionGroupDemo = {
type: 'code',
code: sidebarLayout(`<Sidebar defaultOpen>
<Sidebar.Header>
<Flex align="center" gap={3}>
<IconButton size={4} aria-label="Logo">
<BellIcon width={24} height={24} />
</IconButton>
<Text size={4} weight="medium" data-collapse-hidden>Apsara</Text>
</Flex>
</Sidebar.Header>
<Sidebar.Main>
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />}>
Overview
</Sidebar.Item>
<Sidebar.Group label="Resources" accordion>
<Sidebar.Item href="#" leadingIcon={<FilterIcon width={16} height={16} />}>
Reports
</Sidebar.Item>
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />}>
Activities
</Sidebar.Item>
</Sidebar.Group>
<Sidebar.Group label="Account" trailingIcon={<OrganizationIcon width={16} height={16} />}>
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />}>
Settings
</Sidebar.Item>
</Sidebar.Group>
</Sidebar.Main>
</Sidebar>`)
};

export const moreDemo = {
type: 'code',
code: sidebarLayout(`<Sidebar defaultOpen>
<Sidebar.Header>
<Flex align="center" gap={3}>
<IconButton size={4} aria-label="Logo">
<BellIcon width={24} height={24} />
</IconButton>
<Text size={4} weight="medium" data-collapse-hidden>Apsara</Text>
</Flex>
</Sidebar.Header>
<Sidebar.Main>
<Sidebar.Item href="#" leadingIcon={<BellIcon width={16} height={16} />} active>
Dashboard
</Sidebar.Item>
<Sidebar.Item href="#" leadingIcon={<FilterIcon width={16} height={16} />}>
Analytics
</Sidebar.Item>
<Sidebar.Group label="Resources">
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />}>
Reports
</Sidebar.Item>
<Sidebar.More label="More">
<Sidebar.Item href="#" leadingIcon={<BellIcon width={16} height={16} />}>
Activities
</Sidebar.Item>
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />} disabled>
Notifications
</Sidebar.Item>
</Sidebar.More>
</Sidebar.Group>
</Sidebar.Main>
<Sidebar.Footer>
<Sidebar.More label="More">
<Sidebar.Item href="#" leadingIcon={<OrganizationIcon width={16} height={16} />}>
Preferences
</Sidebar.Item>
<Sidebar.Item href="#" leadingIcon={<FilterIcon width={16} height={16} />}>
Documentation
</Sidebar.Item>
</Sidebar.More>
</Sidebar.Footer>
</Sidebar>`)
};
38 changes: 37 additions & 1 deletion apps/www/src/content/docs/components/sidebar/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ source: packages/raystack/components/sidebar
import {
preview,
positionDemo,
variantDemo,
accordionGroupDemo,
stateDemo,
tooltipDemo,
collapsibleDemo,
hideTooltipDemo
hideTooltipDemo,
moreDemo
} from "./demo.ts";

<Demo data={preview} />
Expand All @@ -27,6 +30,9 @@ import { Sidebar } from "@raystack/apsara";
<Sidebar.Main>
<Sidebar.Group label="Group name">
<Sidebar.Item href="#">Item</Sidebar.Item>
<Sidebar.More label="More">
<Sidebar.Item href="#">Hidden item</Sidebar.Item>
</Sidebar.More>
</Sidebar.Group>
</Sidebar.Main>
<Sidebar.Footer />
Expand Down Expand Up @@ -63,6 +69,14 @@ The main section wraps navigation groups and items. It accepts all `div` props a

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.

### More

Renders a sidebar row that opens an Apsara menu with additional `Sidebar.Item` entries. It can be used inside `Sidebar.Group` or directly under `Sidebar.Main` / `Sidebar.Footer`.

*Note: if `leadingIcon` is not provided, the trigger uses a default dots icon. In collapsed state, it follows the same item tooltip behavior and respects `hideCollapsedItemTooltip`.*

<auto-type-table path="./props.ts" name="SidebarMoreProps" />

## Examples

### Position
Expand All @@ -71,6 +85,16 @@ The Sidebar can be positioned on either the left or right side of the screen.

<Demo data={positionDemo} />

### Variants

Use `variant` to switch the Sidebar surface style:

- `plain` (default): regular surface with side border
- `floating`: lifted surface with shadow
- `inset`: transparent surface without border or shadow

<Demo data={variantDemo} />

### State

The Sidebar supports expanded and collapsed states with smooth transitions.
Expand Down Expand Up @@ -99,6 +123,18 @@ Set `hideCollapsedItemTooltip` to disable tooltips on navigation items when the

<Demo data={hideTooltipDemo} />

### Accordion Group

Enable `accordion` on `Sidebar.Group` to make section items collapsible. You can also pass `trailingIcon` for section-level actions.

<Demo data={accordionGroupDemo} />

### More

Use `Sidebar.More` when you want to keep a section compact and move secondary items into a menu.

<Demo data={moreDemo} />

## Accessibility

The Sidebar implements the following accessibility features:
Expand Down
30 changes: 30 additions & 0 deletions apps/www/src/content/docs/components/sidebar/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ export interface SidebarRootProps {
*/
position?: 'left' | 'right';

/** Visual style variant of the Sidebar.
* @default "plain"
*/
variant?: 'plain' | 'floating' | 'inset';

/** Hide tooltips on sidebar items when sidebar is collapsed.
* @default false
*/
Expand Down Expand Up @@ -83,3 +88,28 @@ export interface SidebarItemProps {
text?: string;
};
}

export interface SidebarMoreProps {
/** String for the more trigger label. */
label?: string;

/** Optional ReactNode for the trigger icon. */
leadingIcon?: ReactNode;

/** Sidebar items rendered inside the menu content. */
children?: ReactNode;

/** Optional class names for customizing parts of the more trigger/menu. */
classNames?: {
/** Class name for the trigger root element. */
root?: string;
/** Class name for the leading icon container. */
leadingIcon?: string;
/** Class name for the text element. */
text?: string;
/** Class name for menu item root elements. */
menuItem?: string;
/** Class name for menu content container. */
menuContent?: string;
};
}
Loading
Loading