Pattern

Selection bar

Choosing several rows for one bulk action: the bar docked at the bottom with the count, Select all, Clear, Cancel, and the primary.

Copy it from /dashboard/accounts/:acctId/sites/:siteId/animal-list/:group

Selecting

Docked at the bottom of the page for as long as selection mode is on, from "0 selected". Select all takes the rows on screen, then names every match when more match than are on screen; Clear empties the selection and stays in the mode, and Cancel leaves it. The primary acts on what is selected. Show the bar, then press Select all twice.

Route
/dashboard/accounts/:acctId/sites/:siteId/animal-list/:group
Screenshot
docs/agents/ui-patterns/selection-mode-1440.png
<SelectionBar
  selectedCount={selected.length}
  matchCount={offersAllMatching ? editableMatchCount : undefined}
  matchNoun={matchNoun}
  onSelectAll={offersLoaded
    ? () => selection.add(animals)
    : offersAllMatching
      ? selection.selectAllMatching
      : undefined}
  isSelectingAll={selection.isSelectingAll}
  onClear={selection.clear}
  onCancel={selection.cancel}
  primary={{
    label: `Edit ${pluralAnimals(selected.length)}`,
    onPress: onEdit,
  }}
  isSaving={isSaving}
  savingLabel={savingCount === undefined
    ? undefined
    : `Updating ${pluralAnimals(savingCount)}…`}
  countLabel={allMatching
    ? `All ${allMatching.count} ${matchNoun}${allMatching.search ? ` '${allMatching.search}'` : ''} on ${tabLabel}`
    : undefined}
>
  {/* the first five photos, then a "+N" tile for the rest */}
</SelectionBar>

Saving

While the bulk save runs, the bar says so with a spinner and offers nothing else: Cancel and the primary are disabled, and the page drops the photos’ remove controls. Show the bar, then press Edit 3 animals.

Route
/dashboard/accounts/:acctId/sites/:siteId/animal-list/:group
<SelectionBar
  selectedCount={selected.length}
  matchCount={offersAllMatching ? editableMatchCount : undefined}
  matchNoun={matchNoun}
  onSelectAll={offersLoaded
    ? () => selection.add(animals)
    : offersAllMatching
      ? selection.selectAllMatching
      : undefined}
  isSelectingAll={selection.isSelectingAll}
  onClear={selection.clear}
  onCancel={selection.cancel}
  primary={{
    label: `Edit ${pluralAnimals(selected.length)}`,
    onPress: onEdit,
  }}
  isSaving={isSaving}
  savingLabel={savingCount === undefined
    ? undefined
    : `Updating ${pluralAnimals(savingCount)}…`}
  countLabel={allMatching
    ? `All ${allMatching.count} ${matchNoun}${allMatching.search ? ` '${allMatching.search}'` : ''} on ${tabLabel}`
    : undefined}
>
  {/* the first five photos, then a "+N" tile for the rest */}
</SelectionBar>