Getting StartedComponentsDesign TokensThemingTheme SynthesizerFrameworksAccessibilityUtilitiesServer RenderingBrowser SupportContributingChangelog App ShellAspect GridAuth ShellCenterClusterContainerDashboard GridDockFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkSpeed DialStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCalloutCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSeparatorSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridData TableDescription ListDiffEvent CalendarGaugeJSON TreeKanbanKey ValueLevel MeterListMeterSparklineStatStepperTableTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputOTP InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuGuided TourHover CardInline MessageLoading OverlayModalNotification PanelPopoverProgressProgress ToastSheetSnackbarSpotlightToastTooltip
ARC UI ARC Radiant Components
v3.2 Docs Components Tokens Synthesizer
Getting StartedFrameworksServer Rendering Design TokensThemingTheme SynthesizerTypographyUtilities All ComponentsAccessibilityBrowser SupportChangelogContributingStats App ShellAspect GridAuth ShellCenterClusterContainerDashboard GridDockFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkSpeed DialStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCalloutCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSeparatorSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridData TableDescription ListDiffEvent CalendarGaugeJSON TreeKanbanKey ValueLevel MeterListMeterSparklineStatStepperTableTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputOTP InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuGuided TourHover CardInline MessageLoading OverlayModalNotification PanelPopoverProgressProgress ToastSheetSnackbarSpotlightToastTooltip

Rail

Ultra-narrow icon-only vertical navigation like VS Code's activity bar. Icons use text-muted at rest, accent-primary glow on active. Expands on hover.

Components Rail
navigation interactive
<arc-rail>

Overview

Rail is an ultra-narrow vertical navigation strip — typically 48 to 56 pixels wide — that displays icon-only items in a single column. Inspired by the activity bar in VS Code and similar IDE layouts, it provides top-level section switching without consuming the horizontal space that a full Sidebar requires. Icons render in text-muted at rest and light up with an accent-primary glow when active, giving immediate visual feedback about the current section. On hover, the Rail can optionally expand to reveal text labels beside each icon, bridging the gap between compact icon-only navigation and a full labeled sidebar. This expand-on-hover behavior is controlled by the `expanded` prop and can also be toggled programmatically for accessibility — some users prefer the labels to remain visible at all times. Rail is designed to sit at the far-left edge of an AppShell, occupying a fixed vertical strip from top to bottom. It works well alongside a contextual Sidebar: the Rail handles top-level section switching (e.g. Explorer, Search, Source Control) while the Sidebar shows the detail panel for the active section. The component dispatches `arc-change` on item selection so your application can swap the adjacent content area accordingly.

Guidelines

When to use

  • Limit items to four to seven for a scannable icon column
  • Use universally recognizable icons — Rail has no visible labels by default
  • Place Rail at the far-left edge of the viewport inside an AppShell
  • Pair with a Sidebar to show detail content for the active Rail section
  • Provide aria-label on the Rail for screen-reader context

When not to use

  • Do not use Rail as the only navigation on a content-heavy site — it is too compact
  • Do not add more than seven items — vertical overflow will be confusing
  • Do not rely solely on icon recognition — ensure tooltips or expand-on-hover labels are available
  • Do not use Rail on mobile viewports — switch to BottomNav instead
  • Do not nest a Rail inside a Sidebar — Rail replaces the sidebar for top-level switching

Features

  • Ultra-narrow icon-only vertical navigation strip
  • Accent-primary glow on active item, text-muted at rest
  • Optional expand-on-hover to reveal text labels
  • Controlled expanded prop for programmatic label visibility
  • `arc-change` event on item selection
  • Designed for far-left positioning in AppShell layouts
  • Keyboard navigable with arrow keys and Enter activation
  • Pairs with Sidebar for section-detail navigation patterns
  • Token-driven theming via CSS custom properties

Preview

App content here.

Usage

This component requires JavaScript. No pure HTML/CSS version is available — use the Web Component directly or a framework wrapper.

<script type="module" src="@arclux/arc-ui"></script>

<arc-rail
  value="explorer"
  id="rail"
  items='[
    { "icon": "folder", "label": "Explorer", "value": "explorer" },
    { "icon": "magnifying-glass", "label": "Search", "value": "search" },
    { "icon": "git-branch", "label": "Source Control", "value": "scm" },
    { "icon": "puzzle-piece", "label": "Extensions", "value": "extensions" },
    { "icon": "gear", "label": "Settings", "value": "settings" }
  ]'
></arc-rail>

<script>
  document.querySelector('#rail').addEventListener('arc-change', (e) => {
    console.log('section:', e.detail.value);
  });
</script>
import { Rail } from '@arclux/arc-ui-react';

const items = [
  { icon: 'folder', label: 'Explorer', value: 'explorer' },
  { icon: 'search', label: 'Search', value: 'search' },
  { icon: 'git-branch', label: 'Source Control', value: 'scm' },
  { icon: 'puzzle', label: 'Extensions', value: 'extensions' },
  { icon: 'settings', label: 'Settings', value: 'settings' },
];

export function ActivityBar() {
  return (
    <Rail
      items={items}
      value="explorer"
      onArcChange={(e) => console.log('section:', e.detail.value)}
    />
  );
}
<script setup>
import { Rail } from '@arclux/arc-ui-vue';

const items = [
  { icon: 'folder', label: 'Explorer', value: 'explorer' },
  { icon: 'search', label: 'Search', value: 'search' },
  { icon: 'git-branch', label: 'Source Control', value: 'scm' },
  { icon: 'puzzle', label: 'Extensions', value: 'extensions' },
  { icon: 'settings', label: 'Settings', value: 'settings' },
];

function onChange(e) {
  console.log('section:', e.detail.value);
}
</script>

<template>
  <Rail :items="items" value="explorer" @arc-change="onChange" />
</template>
<script>
  import { Rail } from '@arclux/arc-ui-svelte';

  const items = [
    { icon: 'folder', label: 'Explorer', value: 'explorer' },
    { icon: 'search', label: 'Search', value: 'search' },
    { icon: 'git-branch', label: 'Source Control', value: 'scm' },
    { icon: 'puzzle', label: 'Extensions', value: 'extensions' },
    { icon: 'settings', label: 'Settings', value: 'settings' },
  ];
</script>

<Rail
  {items}
  value="explorer"
  on:arc-change={(e) => console.log('section:', e.detail.value)}
/>
import { Component } from '@angular/core';
import { Rail } from '@arclux/arc-ui-angular';

@Component({
  imports: [Rail],
  template: `
    <arc-rail
      [items]="items"
      value="explorer"
      (arc-change)="onChange($event)"
    />
  `,
})
export class ActivityBarComponent {
  items = [
    { icon: 'folder', label: 'Explorer', value: 'explorer' },
    { icon: 'search', label: 'Search', value: 'search' },
    { icon: 'git-branch', label: 'Source Control', value: 'scm' },
    { icon: 'puzzle', label: 'Extensions', value: 'extensions' },
    { icon: 'settings', label: 'Settings', value: 'settings' },
  ];

  onChange(e: CustomEvent) {
    console.log('section:', e.detail.value);
  }
}
import { Rail } from '@arclux/arc-ui-solid';

const items = [
  { icon: 'folder', label: 'Explorer', value: 'explorer' },
  { icon: 'search', label: 'Search', value: 'search' },
  { icon: 'git-branch', label: 'Source Control', value: 'scm' },
  { icon: 'puzzle', label: 'Extensions', value: 'extensions' },
  { icon: 'settings', label: 'Settings', value: 'settings' },
];

export function ActivityBar() {
  return (
    <Rail
      items={items}
      value="explorer"
      onArcChange={(e) => console.log('section:', e.detail.value)}
    />
  );
}
import { Rail } from '@arclux/arc-ui-preact';

const items = [
  { icon: 'folder', label: 'Explorer', value: 'explorer' },
  { icon: 'search', label: 'Search', value: 'search' },
  { icon: 'git-branch', label: 'Source Control', value: 'scm' },
  { icon: 'puzzle', label: 'Extensions', value: 'extensions' },
  { icon: 'settings', label: 'Settings', value: 'settings' },
];

export function ActivityBar() {
  return (
    <Rail
      items={items}
      value="explorer"
      onArcChange={(e) => console.log('section:', e.detail.value)}
    />
  );
}

API

items Array<{icon: string, label: string, value: string}> []
Array of navigation items, each with an icon name, text label, and value identifier.
value string ''
The value of the currently active item. Controls which icon receives the accent glow.
expanded boolean false
When true, the Rail widens to show text labels beside each icon. Can be toggled on hover or set permanently.

Events

arc-change detail: { value: string }
Fired when an item is selected with detail: { value }.

See Also