Skip to content
design
Components

Level tile

A tank or battery level at a glance, with the gauge bar beside its figure, name and one line of detail.

On this page
74
%
House bank−6 A, 49 h left
100
%
Starter batteryCharged, 12.8 V
69
%
Diesel152 of 220 L
89
%
Calorifier62 °C, 40 L
62
%
Fresh waterWatermaker on, 27 L/h
83
%
Black waterPump out within a day
2
%
PropaneChange the bottle
0
%
BilgeDry since Palma
Althea's tanks and batteries in an even grid, the batteries and fuel on vertical gauges and the water and gas on horizontal ones.
Code
import { LevelTile } from "@bosunkit/components/level-tile";
import type { ReactElement } from "react";

export const description: string =
  "Althea's tanks and batteries in an even grid: vertical gauges for the batteries and the fuel, horizontal ones " +
  "for the water and the gas, from a full starter battery to a dry bilge.";

export default function Showcase(): ReactElement {
  return (
    <div
      style={{
        display: "grid",
        gridTemplateColumns: "repeat(auto-fill, minmax(140px, 1fr))",
        gap: "var(--space-sm)",
        width: "100%",
        maxWidth: 620,
      }}
    >
      <LevelTile label="House bank" percent={74} detail={"−6\u00a0A, 49\u00a0h left"} />
      <LevelTile label="Starter battery" percent={100} detail={"Charged, 12.8\u00a0V"} />
      <LevelTile label="Diesel" percent={69} detail={"152 of 220\u00a0L"} type="tinted" />
      <LevelTile label="Calorifier" percent={89} detail={"62\u00a0°C, 40\u00a0L"} type="tinted" />
      <LevelTile
        label="Fresh water"
        percent={62}
        detail={"Watermaker on, 27\u00a0L/h"}
        direction="horizontal"
        type="tinted"
      />
      <LevelTile label="Black water" percent={83} detail="Pump out within a day" direction="horizontal" />
      <LevelTile label="Propane" percent={2} detail="Change the bottle" direction="horizontal" />
      <LevelTile label="Bilge" percent={0} detail="Dry since Palma" direction="horizontal" type="tinted" />
    </div>
  );
}

A level tile shows one level in percent: a gauge bar indicator in a fixed box on the left, and on the right the figure with its unit, the name under it and one line of detail under that. The figure, the name and the detail start on one left edge. The gauge sits at the middle of the text, and the tile fills its grid cell, so the vertical and horizontal gauges of a row sit on one center line. The detail keeps room for two lines, also when there is none, so a row whose details take no line, one or two keeps its figures on one top line. The tile is a group named by its label.

01The figure with its unitThe unit follows the figure on its line, so 100 % reads as one value and never runs into the next tile.
02One edge for the wordsThe figure, the name and the detail start at the same left edge, so the eye reads down one line of text.
03Gauges on one lineEvery gauge in a row has the same box and the same center, so a glance across the row compares the levels.

Examples

Detail

The detail is optional and wraps within the text column. With a detail of one line, of two lines or none, the tiles of a row keep their gauges on one center line and their figures on one top line.

69
%
Diesel152 of 220 L
62
%
Fresh waterWatermaker on, 27 L/h
41
%
Holding tank
Three tiles in a row with a detail of one line, of two lines and none: the gauges share one center line and the figures one top line.
Code
import { LevelTile } from "@bosunkit/components/level-tile";
import type { ReactElement } from "react";

export const description: string =
  "Three tiles in a row with a detail of one line, of two lines and none: the gauges share one center line and " +
  "the figures one top line.";

export default function Detail(): ReactElement {
  return (
    <div
      style={{
        display: "grid",
        gridTemplateColumns: "repeat(3, minmax(0, 150px))",
        gap: "var(--space-sm)",
        width: "100%",
      }}
    >
      <LevelTile label="Diesel" percent={69} detail={"152 of 220\u00a0L"} type="tinted" />
      <LevelTile label="Fresh water" percent={62} detail={"Watermaker on, 27\u00a0L/h"} type="tinted" />
      <LevelTile label="Holding tank" percent={41} />
    </div>
  );
}

Unknown level

percent={null} is a level nobody knows: the figure is a dash and the gauge box stays empty, so a sensor that has stopped reporting never reads as an empty tank.

‒
%
Grey waterNo reading from the sensor
A tank whose sensor has stopped reporting: a dash for the figure and an empty gauge box, never an empty tank.
Code
import { LevelTile } from "@bosunkit/components/level-tile";
import type { ReactElement } from "react";

export const description: string =
  "A tank whose sensor has stopped reporting: a dash for the figure and an empty gauge box, never an empty tank.";

export default function Unknown(): ReactElement {
  return (
    <div style={{ width: 150 }}>
      <LevelTile label="Grey water" percent={null} detail="No reading from the sensor" direction="horizontal" />
    </div>
  );
}

Props

PropTypeDefaultDescription
labelrequiredstring–What the level belongs to ("House bank", "Diesel"), as the caller displays it; it names the tile.
percentrequirednumber | null–The level in percent, 0 to 100: the gauge draws it and the figure shows it whole. null when no reading is known: the figure is a dash and the gauge draws no bar, so a lost reading never reads as empty.
detailstring | undefined–One line about the level ("152 of 220 L", "Pump out within a day"), as the caller writes it, under the label. It wraps to a second line within the text column; without it the tile keeps the room, so its row stays aligned.
directionGaugeBarIndicatorDirection | undefined"vertical"The gauge's direction: vertical (default) or horizontal.
typeGaugeBarIndicatorType | undefined"fill"The gauge's fill: fill (default), a solid bar, or tinted, a lighter bar with an end marker.
classNamestring | undefined–Classes added to the tile's own.
testIdstring | undefined–data-testid on the tile; its parts are --gauge, --text and --detail.
refRef<HTMLDivElement> | undefined–The tile's root element.
Do
100
%
Starter batteryCharged, 12.8 V
Show a level in a level tile, so the unit follows the figure and the name and the detail line up under it.
Don't
100
Starter battery
%
Don't put a readout beside a gauge bar. Its unit sits under the figure after the name, and the figure moves away from the words.
  • Gauge bar indicator: the bar the tile draws, with its directions and fills.
  • Reading: a live value with its source and integrity, for a figure without a gauge.
  • Dial frame: the frame that lines up a row of dials.