Raft 设计系统

组件 · 导航

AppRail

The leftmost desktop column, on the frame, under the web top bar — the product's destinations at the top, help and settings at the bottom.

稳定也叫 Rail
import { AppRail } from "@botiverse/raft-ui";
本页尚未翻译
译文完成之前,这里显示英文原文。 阅读英文版

AppRail is the desktop's leftmost column of destinations, on the yellow frame, under the web top bar. The product's destinations are at the top, and help and settings sit at the bottom; the server and the bell are in the top bar (Page structure). Selecting a destination fills the Sidebar next to it.

app-rail/compositions/with-top-bar

When to use

SituationUse
A product's destinations on desktopAppRail
The same destinations on a phoneMobileNav
What the selected destination containsSidebar

Which destinations a product has, and in which order, is on its own page (Raft Chat).

Anatomy

  • AppRailRoot: the column, on layer-frame, with a line-seam along its right edge.
  • AppRailHeader: the 56px square at the top, holding the workspace tile. Its seam lines up with the sidebar's and the panel's (Page structure). It is left out when the web top bar is shown.
  • AppRailNav: the destinations.
  • AppRailItem: one destination: an AppRailItemIcon with a 20px icon, and an AppRailItemLabel with its name.
  • AppRailItemAttention: the pink pixel on an item, with text for assistive technology. It is built on AppRailItemIndicator.
  • AppRailItemBadge: a count in the same corner. Not recommended, and to be removed: a rail icon shows only the dot, never a number (Badge).
  • AppRailFooter: notifications, help and settings. Notifications sit here only when there is no web top bar; with it, the bell is in the top bar (Navigation).

Without the web top bar (an older desktop build, the app embedded in another host, a server's public page), the rail has its header with the workspace tile, search is a destination and the bell sits in the footer:

app-rail/compositions/without-top-bar

Variants

VariantUse for
Icons only (default)Every product today. 56px wide plus the seam; each item is 40px square, and its name appears in a tooltip to the right
Icons with labelsNames under the icons, in text-label (bold when selected). 68px wide plus the seam; each item is 60×52px, and the selected sticker wraps the icon and the label. The footer tools keep icons only, because "Notifications" doesn't fit under an icon

The product ships the icons-only rail, and raft-ui implements only that one (Open questions). A labeled rail can't keep a square top-left corner (it is 68×56px), and the product pins that square with a UI test (leftrail-square-slot).

States

  • Selected: a sticker on the frame, white in light mode and yellow in dark mode (States).
  • Attention: one pink pixel at the top right of the icon, never a count. The selected item never shows it, with no exception.
  • Hover and press lay fill-frame-medium over the item, the medium tier on the frame (Hover and press). The selected item doesn't change on hover.

Behavior

  • Space every item, in the nav and in the footer, the same way: 40px items, 6px apart, 8px from both ends of the rail. Don't wrap the footer tools in fixed-height cells.
  • Under the header, start the first item 8px below the header's seam, the same 8px as under the web top bar and at the bottom of the rail, so the rail has one inset.
  • With the web top bar, the rail has no header and the server moves to the top bar, as the workspace button (Page structure).
  • In a window shorter than 600px, the rail shrinks with the headers (Responsive layout), and its items keep 6px from both ends.

Content

  • Name every item, even in the icons-only rail. Names are Title Case (Typography).

Accessibility

  • AppRailNav renders a nav. Name it with aria-label="Primary".
  • AppRailItem renders the Base UI Button; selected sets aria-pressed. For an item that navigates, render a link (render={<a href="…" />} with nativeButton={false}) and set aria-current="page" on the selected one: raft-ui sets neither on a link.
  • AppRailItemLabel is visually hidden and names the item. Repeat the name in a Tooltip on the right for pointer users.
  • Say the attention dot in the item's name with AppRailItemAttention's title: "Activity, new". The pixel itself is aria-hidden.
  • Name the workspace tile after the server and what it does: "Raft HQ, switch server".

Rules

  • Make the workspace tile ink with the server's initial in yellow. It opens the server list next to the tile (Built from existing parts).

API

AppRailFooter, AppRailHeader

Prop类型默认值
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

AppRailItem

Prop类型默认值
nativeButtonbooleantrue
selectedboolean
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

AppRailItemAttention

Prop类型默认值
titleRead to assistive tech; the pixel itself is decorative.string

AppRailItemBadge, AppRailItemIcon

Prop类型默认值
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

AppRailItemIndicator

Prop类型默认值
presenceA status light (online, busy, error, offline, external): a fixed meaning that needs its word nearby, or an aria-label. It takes the place of `variant`'s colour."online" | "busy" | "error" | "offline" | "external"
size"xs" | "sm" | "md" | "lg""sm"
variant"primary" | "accent" | "warning" | "danger" | "default" | "information" | "muted" | "success"
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

AppRailItemLabel, AppRailNav, AppRailRoot

Prop类型默认值
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

改动

  • 0.6.0 · Breaking ChangesProps that no longer change anything are removed: Badge uppercase; Checkbox size, variant, color; Status pulse, attention (status never animates); Switch / SwitchThumb size; SidebarItem variant; SidebarItemCount / SidebarItemIndicator variant and appearance (the count is always the pink sticker, the indicator the yellow @); NotificationCenterActionButton variant; DrawerContent width (one-go forms use the wide Dialog); AppRailItemIndicator attention; AppRailItemAttention children; Steps size, track, renderIndicator, renderTraveler; FilePreviewBadge type, color. Remove them at call sites.
  • 0.4.0 · ChangedAppShell no longer draws column dividers. AppShellRailSlot and AppShellSidebarSlot dropped their border classes in both themes. The rail|sidebar divider now lives on AppRailRoot (brutal); seam borders the shell used to own (e.g. sidebar|main with an inset main panel) must be added by the caller. ([e219fd8](https://github.com/botiverse/rui/commit/e219fd8))