Skip to content

WorkspaceRail

<caos-workspace-rail>

the narrow strip of tiles for switching between workspaces

May be placed on a record page, an app’s home page and a page inside an app.

Name Attribute Description Type Default Required
current current, markup only Which workspace is open, by id. Set it AFTER the switch — this component does not set it on click, so a failed switch does not leave the rail claiming otherwise. text none declared Optional
Name When it fires What it carries
select Somebody chose a workspace. Nothing has changed yet: switching, and then setting current, is the surface’s. { id: string }

Nothing goes inside this piece.

Design token What it controls
--caos-color-surface-2 The rail itself, so it reads as a strip beside the workspace.
--caos-color-surface A tile that is not the current one.
--caos-color-border Each tile’s edge, and the rail’s edge against what is beside it.
--caos-color-text-muted The letters on a tile that is not current.
--caos-color-text The letters on a tile under the pointer.
--caos-color-accent-fill The current workspace’s tile.
--caos-color-accent-contrast The letters drawn on that fill, and on a count.
--caos-color-danger-fill The count on a workspace with something waiting — the one place in the set that is not the accent, because it is a thing somebody is missing rather than a thing they chose.
--caos-color-danger-contrast The number drawn on that fill.
--caos-font The typeface of the letters.
--caos-text-label The size of the letters.
--caos-font-weight-label The weight of the letters.
--caos-space-2 The gap between tiles and the padding of the rail.
--caos-radius-sm The roundness of a tile.
--caos-radius-pill The roundness of a count.
--caos-focus-ring The ring on a tile.

Nothing else drives this piece by calling it.

Nothing on this piece can be read back.

Part Which piece of it When it is there
::part(rail) the strip Always
::part(tile) one workspace Always
::part(count) the number on a workspace with something waiting Always

Somebody belongs to more than one workspace and moves between them often enough that a menu would be in the way. For two, or for a switch made once a week, a menu entry is less furniture.

  • AppLauncher — The choice is which APP to open inside the workspace already open. That is the level below this one, and the two are not alternatives — a screen can have both.
  • Topbar — The switch belongs in the account menu because it happens rarely. A permanent strip for a rare choice is a strip that is in the way for most of the day.
  • ChannelList — The choice is which conversation inside one workspace, which is what that list is for.

The rail is a role="navigation" holding a named list, and the current workspace carries aria-current. Each tile’s accessible name is the workspace’s NAME, never its letters — the letters are aria-hidden, because read out they say the same thing twice and the second time as nonsense. When something is waiting, the count is folded into that name (“Design, 4 unread”) rather than left as a hidden decoration, so the same two facts reach a reader who cannot see the number on the tile. Left to the author: aria-label on the element when a screen carries more than one navigation strip.

The current one is marked; another carries a count.

Cannot be shown as a page placement: is given aria-label, which is set on the element rather than declared as an input. A stored placement carries only a component’s own inputs, so a page copying this would place the piece without it.

<caos-workspace-rail current="platform" aria-label="Workspaces"></caos-workspace-rail>