Skip to content

softwarity/rail-nav

Repository files navigation

Softwarity

@softwarity/rail-nav

npm version license

Material Design 3 Navigation Rail component for Angular. Extends Angular Material mat-sidenav to provide a collapsible rail navigation pattern.

Live Demo

Rail Nav Collapsed Rail Nav Expanded

Features

  • Material Design 3 - Implements the Navigation Rail pattern from MD3
  • Extends Material - Built on top of MatSidenav for reliability
  • Navigation Items - rail-nav-item component with MD3 pill animation, badges, and router support
  • Expand/Collapse - Smooth transition between rail and drawer with adaptive width
  • Backdrop - Optional backdrop overlay when expanded
  • Position - Support for left (start) or right (end) positioning
  • Dark Mode - Automatically adapts to light/dark color scheme
  • SCSS Theming - Customizable via SCSS mixin following Angular Material pattern

Installation

npm install @softwarity/rail-nav

Peer Dependencies

Package Version
@angular/common >= 21.0.0
@angular/core >= 21.0.0
@angular/cdk >= 21.0.0
@angular/material >= 21.0.0

Usage

Import the components in your Angular component:

import {
  RailnavComponent,
  RailnavContainerComponent,
  RailnavContentComponent,
  RailnavItemComponent
} from '@softwarity/rail-nav';

@Component({
  imports: [
    RailnavComponent,
    RailnavContainerComponent,
    RailnavContentComponent,
    RailnavItemComponent
  ],
  template: `
    <rail-nav-container>
      <rail-nav title="My App" subtitle="v1.0">
        <rail-nav-item label="Home" routerLink="/home">
          <mat-icon>home</mat-icon>
        </rail-nav-item>
        <rail-nav-item label="Settings" routerLink="/settings">
          <mat-icon>settings</mat-icon>
        </rail-nav-item>
      </rail-nav>
      <rail-nav-content>
        <!-- Page content -->
      </rail-nav-content>
    </rail-nav-container>
  `
})
export class AppComponent {}

API

RailnavComponent

The main navigation rail component. Extends MatSidenav.

Input Type Default Description
position 'start' | 'end' 'start' Position of the rail (left or right)
title string - Title displayed next to burger when expanded
subtitle string - Subtitle displayed below title when expanded
hideDefaultHeader boolean false Hide the default header to provide custom content
autoCollapse boolean true Auto-collapse the rail when an item is clicked
Property/Method Type Description
expanded Signal<boolean> Read the current expanded state
toggleExpanded() void Toggle between collapsed and expanded
expand() void Expand the rail
collapse() void Collapse the rail

RailnavContainerComponent

Container component. Extends MatSidenavContainer.

Input Type Default Description
showBackdrop boolean true Show backdrop overlay when expanded

RailnavContentComponent

Content area component. Extends MatSidenavContent.

Note: When placed inside a rail-nav-container alongside a rail-nav, the component automatically detects the rail position and applies the correct margin using the --rail-nav-collapsed-width CSS variable.

RailnavItemComponent

Navigation item with MD3 pill animation.

Input Type Default Description
routerLink string | any[] - Router link for navigation
label string - Label text (below icon when collapsed, beside when expanded)
badge string | number | boolean - Badge value. Use true for a small dot badge
active boolean false Whether this item is active (for non-router usage)
Output Type Description
itemClick void Emitted when clicked (automatically collapses rail)

SCSS Theming

Use the SCSS mixin to customize colors following the Angular Material pattern:

@use '@softwarity/rail-nav/rail-nav-theme' as rail-nav;

:root {
  @include rail-nav.overrides((
    backdrop-color: rgba(0, 0, 0, 0.5),
    primary: #6200ea,
    surface-color: #f5f5f5,
  ));
}

Available Tokens

Token Default Description
collapsed-width 72px Width of the rail when collapsed
expanded-width fit-content Width of the rail when expanded
header-height 56px Height of the header area
backdrop-color - Background color for the backdrop overlay
surface-color - Background color for the rail
surface-container-high - Background color for hover states
on-surface - Text color for primary content
on-surface-variant - Text color for secondary content
secondary-container - Background color for active items
on-secondary-container - Text color for active items
primary - Focus ring color
error - Badge background color
on-error - Badge text color

CSS Custom Properties

You can also use CSS custom properties directly.

Size Properties

:root {
  --rail-nav-collapsed-width: 72px;
  --rail-nav-expanded-width: fit-content;
  --rail-nav-header-height: 56px;
}

Color Properties

Color properties support the CSS light-dark() function for automatic light/dark theme adaptation:

:root {
  /* Static colors (single theme) */
  --rail-nav-surface-color: #ffffff;
  --rail-nav-primary: #6750a4;

  /* Or use light-dark() for automatic theme adaptation */
  --rail-nav-surface-color: light-dark(#ffffff, #1e1e1e);
  --rail-nav-primary: light-dark(#6750a4, #d0bcff);
}

The component uses Material Design 3 system tokens (--mat-sys-*) as fallbacks.

Light/Dark Theme Support

Use the CSS light-dark() function to define colors that automatically adapt to the user's color scheme. The first value is for light mode, the second for dark mode.

With SCSS mixin

@use '@softwarity/rail-nav/rail-nav-theme' as rail-nav;

:root {
  @include rail-nav.overrides((
    backdrop-color: light-dark(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.6)),
    surface-color: light-dark(#ffffff, #1e1e1e),
    on-surface: light-dark(#1c1b1f, #e6e1e5),
    primary: light-dark(#6750a4, #d0bcff),
  ));
}

With CSS custom properties

:root {
  --rail-nav-backdrop-color: light-dark(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.6));
  --rail-nav-surface-color: light-dark(#ffffff, #1e1e1e);
  --rail-nav-on-surface: light-dark(#1c1b1f, #e6e1e5);
  --rail-nav-on-surface-variant: light-dark(#49454f, #cac4d0);
  --rail-nav-secondary-container: light-dark(#e8def8, #4a4458);
  --rail-nav-on-secondary-container: light-dark(#1d192b, #e8def8);
  --rail-nav-primary: light-dark(#6750a4, #d0bcff);
  --rail-nav-error: light-dark(#b3261e, #f2b8b5);
  --rail-nav-on-error: light-dark(#ffffff, #601410);
}

Setting up color-scheme

For light-dark() to work, set the color-scheme property on your document:

html {
  color-scheme: light;
  &.dark-mode { color-scheme: dark; }
}

/* Or use system preference */
html {
  color-scheme: light dark;
}

Example

@Component({
  imports: [
    RailnavComponent,
    RailnavContainerComponent,
    RailnavContentComponent,
    RailnavItemComponent,
    MatIconModule
  ],
  template: `
    <rail-nav-container [showBackdrop]="true">
      <rail-nav title="My App" subtitle="v1.0">
        <rail-nav-item label="Home" [badge]="3" routerLink="/home">
          <mat-icon>home</mat-icon>
        </rail-nav-item>
        <rail-nav-item label="Favorites" [badge]="true" routerLink="/favorites">
          <mat-icon>favorite</mat-icon>
        </rail-nav-item>
        <rail-nav-item label="Settings" routerLink="/settings">
          <mat-icon>settings</mat-icon>
        </rail-nav-item>
      </rail-nav>
      <rail-nav-content>
        <main>Your content here</main>
      </rail-nav-content>
    </rail-nav-container>
  `
})
export class MyComponent {}

License

MIT