Flux 2.0

Component

Board

Records as cards in columns by stage, moved between stages by drag or keyboard.

Plain-text source, for agents and clipboard use: /components/source/board.txt

When to use it

Shows how many records sit at each stage of a process and lets people move one forward by moving its card. Each column is a stage with a count, each card is a record with its reference, name and key facts. Cards move by their handle: drag it, or focus it and use the keyboard. Every move is announced, the counts update, and the board dispatches flux-board-move so the product can save the new stage.

Not this
Not for a long list that people sort, filter and scan; use a Table with a status column. Not for reordering one list; use Reorder. Not when a stage change needs a reason or a confirmation every time; open a Modal from the card instead of letting a drag commit it.

Examples

Quotes by stage

Drag a card by its handle, or focus the handle, press Space, use the arrow keys and press Space to drop.

Enquiry

2
  1. QT-2208

    Golden Circle, Nordic Trails

    Departs 14 Nov24 passengers

  2. QT-2214

    Ring Road self-drive, Lindqvist family

    Departs 2 Dec4 passengers

Quoted

3
  1. QT-2190

    Northern Lights, Polar Agency

    Departs 21 Nov18 passengers

  2. QT-2197

    South Coast, Aurora Schools

    Departs 9 Jan36 passengers

  3. QT-2201

    Snæfellsnes, private group

    Departs 12 Dec8 passengers

On request

1
  1. QT-2176

    Glacier walk, Nordic Trails

    Departs 18 Nov12 passengers

Confirmed

1
  1. KB-104931

    Golden Circle, Anna Lindqvist

    Departs 14 Sep12 passengers

Press Space to pick the card up. The arrow keys move it within a column and between columns. Press Space to drop it, or Escape to put it back.

html
<div class="flux-board" data-flux-board role="region" aria-label="Quotes by stage" tabindex="0">
  <section class="flux-board__column" aria-labelledby="board-column-0">
    <div class="flux-board__header">
      <h3 class="flux-board__title" id="board-column-0">Enquiry</h3>
      <span class="flux-board__count">2</span>
    </div>
    <ol class="flux-board__cards">
      <li class="flux-board__card">
        <span class="flux-board__ref">QT-2208</span>
        <button class="flux-board__handle" type="button" aria-pressed="false" aria-label="Move QT-2208" aria-describedby="board-help"><svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><circle cx="6" cy="4" r="1.1" /><circle cx="10" cy="4" r="1.1" /><circle cx="6" cy="8" r="1.1" /><circle cx="10" cy="8" r="1.1" /><circle cx="6" cy="12" r="1.1" /><circle cx="10" cy="12" r="1.1" /></svg></button>
        <p class="flux-board__name">Golden Circle, Nordic Trails</p>
        <p class="flux-board__meta"><span>Departs 14 Nov</span><span>24 passengers</span></p>
      </li>
      <li class="flux-board__card">
        <span class="flux-board__ref">QT-2214</span>
        <button class="flux-board__handle" type="button" aria-pressed="false" aria-label="Move QT-2214" aria-describedby="board-help"><svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><circle cx="6" cy="4" r="1.1" /><circle cx="10" cy="4" r="1.1" /><circle cx="6" cy="8" r="1.1" /><circle cx="10" cy="8" r="1.1" /><circle cx="6" cy="12" r="1.1" /><circle cx="10" cy="12" r="1.1" /></svg></button>
        <p class="flux-board__name">Ring Road self-drive, Lindqvist family</p>
        <p class="flux-board__meta"><span>Departs 2 Dec</span><span>4 passengers</span></p>
      </li>
    </ol>
  </section>
  <section class="flux-board__column" aria-labelledby="board-column-1">
    <div class="flux-board__header">
      <h3 class="flux-board__title" id="board-column-1">Quoted</h3>
      <span class="flux-board__count">3</span>
    </div>
    <ol class="flux-board__cards">
      <li class="flux-board__card">
        <span class="flux-board__ref">QT-2190</span>
        <button class="flux-board__handle" type="button" aria-pressed="false" aria-label="Move QT-2190" aria-describedby="board-help"><svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><circle cx="6" cy="4" r="1.1" /><circle cx="10" cy="4" r="1.1" /><circle cx="6" cy="8" r="1.1" /><circle cx="10" cy="8" r="1.1" /><circle cx="6" cy="12" r="1.1" /><circle cx="10" cy="12" r="1.1" /></svg></button>
        <p class="flux-board__name">Northern Lights, Polar Agency</p>
        <p class="flux-board__meta"><span>Departs 21 Nov</span><span>18 passengers</span></p>
      </li>
      <li class="flux-board__card">
        <span class="flux-board__ref">QT-2197</span>
        <button class="flux-board__handle" type="button" aria-pressed="false" aria-label="Move QT-2197" aria-describedby="board-help"><svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><circle cx="6" cy="4" r="1.1" /><circle cx="10" cy="4" r="1.1" /><circle cx="6" cy="8" r="1.1" /><circle cx="10" cy="8" r="1.1" /><circle cx="6" cy="12" r="1.1" /><circle cx="10" cy="12" r="1.1" /></svg></button>
        <p class="flux-board__name">South Coast, Aurora Schools</p>
        <p class="flux-board__meta"><span>Departs 9 Jan</span><span>36 passengers</span></p>
      </li>
      <li class="flux-board__card">
        <span class="flux-board__ref">QT-2201</span>
        <button class="flux-board__handle" type="button" aria-pressed="false" aria-label="Move QT-2201" aria-describedby="board-help"><svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><circle cx="6" cy="4" r="1.1" /><circle cx="10" cy="4" r="1.1" /><circle cx="6" cy="8" r="1.1" /><circle cx="10" cy="8" r="1.1" /><circle cx="6" cy="12" r="1.1" /><circle cx="10" cy="12" r="1.1" /></svg></button>
        <p class="flux-board__name">Snæfellsnes, private group</p>
        <p class="flux-board__meta"><span>Departs 12 Dec</span><span>8 passengers</span></p>
      </li>
    </ol>
  </section>
  <section class="flux-board__column" aria-labelledby="board-column-2">
    <div class="flux-board__header">
      <h3 class="flux-board__title" id="board-column-2">On request</h3>
      <span class="flux-board__count">1</span>
    </div>
    <ol class="flux-board__cards">
      <li class="flux-board__card">
        <span class="flux-board__ref">QT-2176</span>
        <button class="flux-board__handle" type="button" aria-pressed="false" aria-label="Move QT-2176" aria-describedby="board-help"><svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><circle cx="6" cy="4" r="1.1" /><circle cx="10" cy="4" r="1.1" /><circle cx="6" cy="8" r="1.1" /><circle cx="10" cy="8" r="1.1" /><circle cx="6" cy="12" r="1.1" /><circle cx="10" cy="12" r="1.1" /></svg></button>
        <p class="flux-board__name">Glacier walk, Nordic Trails</p>
        <p class="flux-board__meta"><span>Departs 18 Nov</span><span>12 passengers</span></p>
      </li>
    </ol>
  </section>
  <section class="flux-board__column" aria-labelledby="board-column-3">
    <div class="flux-board__header">
      <h3 class="flux-board__title" id="board-column-3">Confirmed</h3>
      <span class="flux-board__count">1</span>
    </div>
    <ol class="flux-board__cards">
      <li class="flux-board__card">
        <span class="flux-board__ref">KB-104931</span>
        <button class="flux-board__handle" type="button" aria-pressed="false" aria-label="Move KB-104931" aria-describedby="board-help"><svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><circle cx="6" cy="4" r="1.1" /><circle cx="10" cy="4" r="1.1" /><circle cx="6" cy="8" r="1.1" /><circle cx="10" cy="8" r="1.1" /><circle cx="6" cy="12" r="1.1" /><circle cx="10" cy="12" r="1.1" /></svg></button>
        <p class="flux-board__name">Golden Circle, Anna Lindqvist</p>
        <p class="flux-board__meta"><span>Departs 14 Sep</span><span>12 passengers</span></p>
      </li>
    </ol>
  </section>
</div>
<p class="flux-visually-hidden" id="board-help">Press Space to pick the card up. The arrow keys move it within a column and between columns. Press Space to drop it, or Escape to put it back.</p>

Anatomy

PartDescription
BoardA focusable horizontal scroll region of columns.
ColumnA section named by its heading, with a mono count and an ordered list of cards on layer-02.
CardA layer-01 list item with a hairline: mono reference, handle, name and meta.
HandleA button named “Move” and the reference, described by the instructions.
Lifted cardshadow-md and an interactive border while it is being moved.

API

NameKindDescription
flux-boardclassThe board. data-flux-board adds dragging, keyboard moves, announcements and counts. Give it role="region", a name and tabindex="0".
flux-board__column | __header | __title | __countclassA stage: its section, heading row, heading and count.
flux-board__cardsclassThe ordered list of cards in a stage. It keeps a minimum height so an empty stage is still a drop target.
flux-board__card | __ref | __name | __metaclassA card and its reference, name and facts.
flux-board__handleclassThe move button. aria-pressed is true while the card is lifted.
flux-board-moveelementCancelable event dispatched on the board after a move. detail holds card, from and to columns, and index. A framework that renders the cards cancels it: the card goes back where it started and the framework renders the move.

States

StateTreatment
Restinglayer-01 card with a hairline.
Liftedshadow-md and border-interactive; the handle turns brand and aria-pressed is true.
Empty stageThe column keeps its list ground so it can still be dropped into.

Keyboard

KeysAction
Space / EnterOn a handle, picks the card up; pressed again, drops it.
Arrow Up / Arrow DownMoves the lifted card within its column.
Arrow Left / Arrow RightMoves the lifted card to the previous or next column.
EscapePuts the lifted card back where it was.

Accessibility

  • Every pick-up, move and drop is announced with the column and position, through an assertive live region.
  • The handle carries the instructions through aria-describedby.
  • Columns are sections named by their headings, so a screen reader can jump between stages.
  • Offer another way to change a stage too, such as a status select on the record, for people who cannot drag.

Tokens

The tier-3 and tier-2 tokens this component binds to. Change the token, not the component.

  • --flux-board-column-width | -gap | -column-bg | -column-padding
  • --flux-board-card-bg | -card-border | -card-padding | -card-gap
  • --flux-board-lifted-shadow | -drop-border

Do and don’t

Do

  • Order columns the way records move, left to right.
  • Save on flux-board-move and move the card back if the save fails, with an error toast.

Don’t

  • Do not put a status badge on a card; the column is the status.
  • Do not colour columns. The stage name and count carry it.