<arc-rail> Overview
Guidelines
When to use
- Limit items to four to seven for a scannable icon column
- Use universally recognisable 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
- Use Rail as the only navigation on a content-heavy site — it is too compact
- Add more than seven items — vertical overflow will be confusing
- Rely solely on icon recognition — ensure tooltips or expand-on-hover labels are available
- Use Rail on mobile viewports — switch to BottomNav instead
- 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
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: `
<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
| Prop | Type | Default | Description |
|---|---|---|---|
items | Array<{ icon, label, value }> | [] | 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
| Event | Description |
|---|---|
arc-change | Fired when an item is selected with detail: { value }. |
See Also
- Sidebar Collapsible navigation sidebar with grouped sections, heading labels, and active link highlighting. Ideal for documentation sites, admin panels, and any layout that needs persistent vertical navigation.
- Navigation Menu Horizontal navigation bar with hover-triggered dropdown sub-menus and full keyboard accessibility. Designed for marketing sites, documentation hubs, and product landing pages where top-level sections expand into categorised link lists.
- Bottom Nav Mobile bottom bar with icon + label items. Active item gets accent-primary glow underline with surface-overlay background and backdrop blur.