Skip to content
design
Components

Scale picker

A level of an observation scale, the Beaufort force, the Douglas sea state or the cloud cover in oktas, chosen with its code, its name and the range it stands for.

On this page
Wind force

The wind measured is 24 kn, force 6.

0Calmbelow 1 kn1Light air1 to 3 kn2Light breeze4 to 6 kn3Gentle breeze7 to 10 kn4Moderate breeze11 to 16 kn5Fresh breeze17 to 21 kn6Strong breeze22 to 27 knMeasured7Near gale28 to 33 kn8Gale34 to 40 kn9Strong gale41 to 47 kn10Storm48 to 55 kn11Violent storm56 to 63 kn12Hurricane force64 kn and more
Force 4 is 11 to 16 kn, and the wind measured is 24 kn, force 6. Check the force.
Sea state

The waves measured are 1.8 m, sea state 4.

0Calm (glassy)no waves1Calm (rippled)0 to 0.1 m2Smooth0.1 to 0.5 m3Slight0.5 to 1.25 m4Moderate1.25 to 2.5 mMeasured5Rough2.5 to 4 m6Very rough4 to 6 m7High6 to 9 m8Very high9 to 14 m9Phenomenalover 14 m
A log entry's wind force beside the 24 kn the anemometer measures, and its sea state beside a measured 1.8 m of wave.
Code
import { ScalePicker } from "@bosunkit/components/scale-picker";
import { useState, type Dispatch, type ReactElement, type SetStateAction } from "react";

export const description: string =
  "A log entry's observations: the wind force estimated by eye beside the 24 kn the anemometer measures, and the sea " +
  "state beside a measured 1.8 m of wave. The measured level is marked, and a force chosen more than one away from " +
  "it is questioned.";

export default function Showcase(): ReactElement {
  const [force, setForce]: [number | null, Dispatch<SetStateAction<number | null>>] = useState<number | null>(4);
  const [sea, setSea]: [number | null, Dispatch<SetStateAction<number | null>>] = useState<number | null>(4);
  return (
    <div style={{ width: "100%", display: "grid", gap: "var(--space-xl)" }}>
      <ScalePicker label="Wind force" scale="beaufort" measured={24} value={force} onValueChange={setForce} />
      <ScalePicker label="Sea state" scale="douglas" measured={1.8} value={sea} onValueChange={setSea} />
    </div>
  );
}

A scale picker holds one level of a scale the crew estimate by eye and log as a code: the Beaufort wind force, 0 to 12; the Douglas sea state, WMO Code 3700, 0 to 9; or the cloud cover in oktas, WMO Code 2700, 0 to 8 and 9 for a sky hidden by fog or snow. Each level shows its code, its name in the crew's language and, for wind and sea, the range it stands for: force 3 is 7 to 10 kn, sea state 3 is 0.5 to 1.25 m. The ranges are bosund's own, from the same bounds that turn a measured wind or wave height into a force or a state, so a level logged by hand and one derived by the daemon agree. A height on a bound belongs to the lower state, as WMO Code 3700 assigns it.

It is a radio group: the arrow keys move the choice, and a code's digits typed choose it. Two digits typed together make a two-digit force, so 1 and then 1 is force 11. With measured, the true wind speed in knots or the significant wave height in meters, the level the measurement stands for is marked and said above the levels. A level chosen more than one away from it is questioned in an attention message that says what the chosen level stands for and what was measured. The choice stays the crew's: an anemometer can be sheltered or iced, and the sea can lag a rising wind.

Examples

Beaufort force

Wind force
0Calmbelow 1 kn1Light air1 to 3 kn2Light breeze4 to 6 kn3Gentle breeze7 to 10 kn4Moderate breeze11 to 16 kn5Fresh breeze17 to 21 kn6Strong breeze22 to 27 kn7Near gale28 to 33 kn8Gale34 to 40 kn9Strong gale41 to 47 kn10Storm48 to 55 kn11Violent storm56 to 63 kn12Hurricane force64 kn and more
The Beaufort scale: thirteen forces, each with the wind speeds in knots it stands for, as bosund's knotsToBeaufort bounds them.
Code
import { ScalePicker } from "@bosunkit/components/scale-picker";
import type { ReactElement } from "react";

export const description: string =
  "The Beaufort scale: thirteen forces, each with the wind speeds in knots it stands for, as bosund's knotsToBeaufort " +
  "bounds them.";

export default function Beaufort(): ReactElement {
  return <ScalePicker label="Wind force" scale="beaufort" defaultValue={5} />;
}

Douglas sea state

Sea state
0Calm (glassy)no waves1Calm (rippled)0 to 0.1 m2Smooth0.1 to 0.5 m3Slight0.5 to 1.25 m4Moderate1.25 to 2.5 m5Rough2.5 to 4 m6Very rough4 to 6 m7High6 to 9 m8Very high9 to 14 m9Phenomenalover 14 m
The Douglas sea scale, WMO Code 3700: ten states with their wave heights, a height on a bound belonging to the lower state.
Code
import { ScalePicker } from "@bosunkit/components/scale-picker";
import type { ReactElement } from "react";

export const description: string =
  "The Douglas sea scale, WMO Code 3700: ten states with their wave heights, a height on a bound belonging to the " +
  "lower state.";

export default function Douglas(): ReactElement {
  return <ScalePicker label="Sea state" scale="douglas" defaultValue={3} />;
}

Cloud cover

Cloud cover
0Sky clear11 okta or less22 oktas33 oktas44 oktas55 oktas66 oktas77 oktas or more, not overcast8Overcast9Sky obscured
Cloud cover in oktas, WMO Code 2700: eighths of the sky covered, and 9 for a sky hidden by fog or snow.
Code
import { ScalePicker } from "@bosunkit/components/scale-picker";
import type { ReactElement } from "react";

export const description: string =
  "Cloud cover in oktas, WMO Code 2700: eighths of the sky covered, and 9 for a sky hidden by fog or snow.";

export default function Oktas(): ReactElement {
  return <ScalePicker label="Cloud cover" scale="oktas" defaultValue={6} />;
}

Questioned

Wind force

The wind measured is 31 kn, force 7.

0Calmbelow 1 kn1Light air1 to 3 kn2Light breeze4 to 6 kn3Gentle breeze7 to 10 kn4Moderate breeze11 to 16 kn5Fresh breeze17 to 21 kn6Strong breeze22 to 27 kn7Near gale28 to 33 knMeasured8Gale34 to 40 kn9Strong gale41 to 47 kn10Storm48 to 55 kn11Violent storm56 to 63 kn12Hurricane force64 kn and more
Force 4 is 11 to 16 kn, and the wind measured is 31 kn, force 7. Check the force.
A force more than one away from the measured wind: the field says what the chosen force stands for and what was measured, and asks the crew to check. The choice stays theirs.
Code
import { ScalePicker } from "@bosunkit/components/scale-picker";
import type { ReactElement } from "react";

export const description: string =
  "A force more than one away from the measured wind: the field says what the chosen force stands for and what was " +
  "measured, and asks the crew to check. The choice stays theirs.";

export default function Questioned(): ReactElement {
  return <ScalePicker label="Wind force" scale="beaufort" measured={31} defaultValue={4} />;
}

Read-only

Sea state
0Calm (glassy)no waves1Calm (rippled)0 to 0.1 m2Smooth0.1 to 0.5 m3Slight0.5 to 1.25 m4Moderate1.25 to 2.5 m5Rough2.5 to 4 m6Very rough4 to 6 m7High6 to 9 m8Very high9 to 14 m9Phenomenalover 14 m
Read-only: the logged level shown, the others unpressable.
Code
import { ScalePicker } from "@bosunkit/components/scale-picker";
import type { ReactElement } from "react";

export const description: string = "Read-only: the logged level shown, the others unpressable.";

export default function ReadOnly(): ReactElement {
  return <ScalePicker label="Sea state" scale="douglas" readOnly defaultValue={5} />;
}

Disabled

Cloud cover
0Sky clear11 okta or less22 oktas33 oktas44 oktas55 oktas66 oktas77 oktas or more, not overcast8Overcast9Sky obscured
Disabled: dimmed, and takes no input.
Code
import { ScalePicker } from "@bosunkit/components/scale-picker";
import type { ReactElement } from "react";

export const description: string = "Disabled: dimmed, and takes no input.";

export default function Disabled(): ReactElement {
  return <ScalePicker label="Cloud cover" scale="oktas" disabled />;
}

Props

PropTypeDefaultDescription
labelrequiredstring–The group's name, translated by the caller: "Wind force", "Sea state", "Cloud cover".
scalerequiredObservationScale–The scale: beaufort, douglas or oktas.
valuenumber | null | undefined–The chosen level's code, or null for none.
defaultValuenumber | null | undefined–The level chosen at first, when the caller does not hold value.
onValueChange((code: number) => void) | undefined–Called with the code the crew choose.
measurednumber | undefined–What the instruments measure, in the scale's unit: the true wind speed in knots for Beaufort, the significant wave height in meters for Douglas. The level it stands for is marked, and a chosen level more than one away from it asks the crew to check.
hintstring | undefined–Text under the label, translated by the caller.
errorstring | undefined–The caller's own error, shown under the levels.
requiredboolean | undefined–Whether a level must be chosen.
disabledboolean | undefined–Whether the group takes no input.
readOnlyboolean | undefined–Whether the group shows its level without letting the crew change it.
namestring | undefined–The form field name; the form receives the code.
classNamestring | undefined–Classes added to the group's own.
testIdstring | undefined–data-testid on the group.
refRef<HTMLDivElement> | undefined–The group element.
  • Weather bar: the forecast's sea state, written with the same Douglas names.
  • Bearing input: the direction the wind and the sea come from.
  • Radio cards: a choice between a few options that each need a sentence.