Skip to content
Merged
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
20 changes: 10 additions & 10 deletions src/core/packages/chrome/navigation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,6 @@ An adaptive side navigation system built with [Elastic UI](https://eui.elastic.c
| ----------------------------- | ------------------------------ |
| ![image](./expanded-mode.png) | ![image](./collapsed-mode.png) |

## Features

- **Responsive design** - automatically adapts between collapsed and expanded states based on screen size.
- **Smart menu system** - dynamic "More" menu that consolidates overflow items during window resize.
- **Nested navigation** - multi-level menu support with nested popover panels in collapsed mode.
- **Accessibility-first** - WCAG-compliant with proper ARIA labels, keyboard navigation, and screen reader support.
- **Modular architecture** - composable components with clean separation of concerns. Exported as a self-contained widget.
- **Dark mode** and **High contrast mode support**

## Usage

### Basic setup
Expand Down Expand Up @@ -66,6 +57,12 @@ const navigationItems = {

function App() {
const [isCollapsed, setIsCollapsed] = useState(false);
const [activeItemId, setActiveItemId] = useState('dashboard');

const handleItemClick = (item: MenuItem | SecondaryMenuItem | SideNavLogo) => {
setActiveItemId(item.id);
trackAnalytics(item.id);
};

return (
<div className="app">
Expand All @@ -80,6 +77,7 @@ function App() {
iconType: 'observabilityApp',
href: '/observability',
}}
onItemClick={handleItemClick}
setWidth={setNavigationWidth}
/>
<main className="app-content">{/* Your application content */}</main>
Expand All @@ -101,6 +99,7 @@ export const navigationItems = {
label: 'Overview',
iconType: 'info',
href: '/overview',
badgeType: 'techPreview', // for tech preview items
},
// Menu item with nested sections
{
Expand All @@ -111,7 +110,7 @@ export const navigationItems = {
sections: [
{
id: 'reports-section',
label: 'Reports', // or null for unlabeled sections
label: 'Reports', // omit for unlabeled sections
items: [
{
id: 'analytics', // has the same `id` as the parent item
Expand All @@ -122,6 +121,7 @@ export const navigationItems = {
id: 'sales-report',
label: 'Sales report',
href: '/analytics/sales',
badgeType: 'beta', // for beta items
},
{
id: 'traffic-report',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export default {
id: 'observability',
href: LOGO.href,
label: LOGO.label,
iconType: LOGO.type,
iconType: LOGO.iconType,
},
setWidth: () => {},
},
Expand All @@ -91,6 +91,7 @@ export const Default: StoryObj<PropsAndArgs> = {
);
},
],
render: (args) => <ControlledNavigation {...args} />,
};

export const Collapsed: StoryObj<PropsAndArgs> = {
Expand All @@ -108,6 +109,7 @@ export const Collapsed: StoryObj<PropsAndArgs> = {
args: {
isCollapsed: true,
},
render: (args) => <ControlledNavigation {...args} />,
};

export const WithMinimalItems: StoryObj<PropsAndArgs> = {
Expand All @@ -128,6 +130,7 @@ export const WithMinimalItems: StoryObj<PropsAndArgs> = {
footerItems: PRIMARY_MENU_FOOTER_ITEMS.slice(0, 2),
},
},
render: (args) => <ControlledNavigation {...args} />,
};

export const WithManyItems: StoryObj<PropsAndArgs> = {
Expand Down Expand Up @@ -168,6 +171,24 @@ export const WithManyItems: StoryObj<PropsAndArgs> = {
footerItems: PRIMARY_MENU_FOOTER_ITEMS,
},
},
render: (args) => <ControlledNavigation {...args} />,
};

export const WithinLayout: StoryObj<PropsAndArgs> = {
name: 'Navigation within Layout',
render: (args) => <Layout {...args} />,
};

const ControlledNavigation = ({ ...props }: PropsAndArgs) => {
const [activeItemId, setActiveItemId] = useState(props.activeItemId || PRIMARY_MENU_ITEMS[0].id);

return (
<Navigation
{...props}
activeItemId={activeItemId}
onItemClick={(item) => setActiveItemId(item.id)}
/>
);
};

const Layout = ({ ...props }: PropsAndArgs) => {
Expand Down Expand Up @@ -212,15 +233,7 @@ const Layout = ({ ...props }: PropsAndArgs) => {
backgroundColor={euiTheme.colors.backgroundFilledText}
/>
}
navigation={
<Navigation
activeItemId={props.activeItemId}
isCollapsed={props.isCollapsed}
items={props.items}
logo={props.logo}
setWidth={setNavigationWidth}
/>
}
navigation={<ControlledNavigation {...props} setWidth={setNavigationWidth} />}
sidebar={
<Box
label="Global Sidebar"
Expand Down Expand Up @@ -260,8 +273,3 @@ const Layout = ({ ...props }: PropsAndArgs) => {
</>
);
};

export const WithinLayout: StoryObj<PropsAndArgs> = {
name: 'Navigation within Layout',
render: (args) => <Layout {...args} />,
};
Loading