Launch prototype

Patterns

Banners

One full-width notice across the top of a screen, for the one thing a person should know about the whole screen, with the one step they can take. And the explainer card, for how something works.

Anatomy

A banner is a PageBanner (app/pages/_shared/page-banner.tsx): the full-width alert with the settings the pattern fixes, so no screen picks them. It sits directly under the header, above the content and outside anything that scrolls, so it is read first and does not move. The icon, the title and the one-line description read across, the action sits on the right, and one close control sits in the corner. Try closing this one.

Live example

Header

Some locations are approximate

Sensitive species are shown only to an approximate area. Request a Data Licencing Agreement (DLA) for full access.

The screen's content starts here, and does not move when the banner is closed.

The rules

  1. Placement. Full width, directly under the header, above the content and never inside what scrolls. Never in column 2 (contract section 3.10: column 2 holds navigation and actions, not information), and never floating over a map or the content.
  2. One fact, one step. The title says what is true, in a few words and sentence case. The description is one line on what it means for this person. The action is named by where it goes (Go to DLA, Sign up for access), never "OK" or "Learn more".
  3. Only for whom it is true. Who sees it is decided inside the screen from the role and the role-access matrix, never at the call site. A role that is not affected gets nothing, and one screen has one banner: if there are two things to say, the more important one gets it.
  4. Colour means the kind of notice. Warning for a limit on what someone can see or do, brand for information, error for something blocking, success sparingly, gray for a neutral status. It is tinted, never a solid fill.
  5. Closing. The corner icon is the only close control: there is no second Dismiss button beside the action. Closing lasts for the visit and the banner returns on reload. A notice that must stay leaves out onDismiss.
  6. Not for. A notice about one record or one section is the contained alert inside the content (the nomination status, an invitation pending). A confirmation that something just happened is a toast. A missing field is the form's inline error and its "Details missing" alert.

Banner or contained alert

Both are the same alert component. The page banner is about the screen and runs edge to edge under the header; the contained alert is about one thing on the screen and sits in the content with the same 24px margins as the rest of it.

Contained, for one record or section

Waiting for review

The sensitive species panel will pick it up. It can still be edited until the review starts.

Explainer card

A banner is a notice about the screen. To explain how something works (what a project is, how a nomination is reviewed), use the ExplainerCard (app/pages/_shared/explainer-card.tsx) above the list it belongs to, never in column 2 (contract section 3.10). It is a bordered card with a small heading, an optional one-line lead, and the subject as a row of steps: numbered when it is a sequence, an icon each when it is a structure. One link to more sits beside the close control.

Live example: a structure, with icons

What is a project?

Every record in BioData SA belongs to a project. A project describes one survey program: who runs it, where and how data is collected, and what is held back from public release.

Project

The survey program, and who runs it.

Site

Where the project's data is collected.

Visit

Each time a site is visited, sampling events are run.

Occurrence

A species found at a visit.

Observation

The measurements kept for what was found.

Usage

import { PageBanner } from "@/app/pages/_shared/page-banner";

// Between the header and the content, outside the scrolling area.
{!dismissed && !seesAllData && (
  <PageBanner
    title="Some locations are approximate"
    description="Sensitive species are shown only to an approximate area. Request a Data Licencing Agreement (DLA) for full access."
    actionLabel="Go to DLA"
    actionIcon={ArrowNarrowRight}
    actionIconPosition="trailing"
    onAction={requestDlaAccess}
    onDismiss={() => setDismissed(true)}
  />
)}

Where it is used