Dial frame
A square face for one dial with its label, value and source under it, so a row of dials shares one face size.
On this page
Code
import { DialFrame } from "@bosunkit/components/dial-frame";
import {
Compass,
CompassDirection,
Priority,
RateOfTurn,
Rudder,
SpeedGauge,
Wind,
WindVariant,
} from "@bosunkit/instruments";
import type { ReactElement } from "react";
export const description: string =
"Five dials from the helm on passage to Audierne, each in a frame of one face size with its label, value and " +
"source under it, so the row lines up across the faces whatever the captions hold.";
export default function Showcase(): ReactElement {
return (
<div
style={{
display: "grid",
gridTemplateColumns: "repeat(auto-fit, minmax(9em, 1fr))",
gap: "var(--space-md)",
width: "100%",
}}
>
<DialFrame label="Heading" value="196°" source="Compass">
<Compass
heading={196}
courseOverGround={200}
headingSetpoint={196}
direction={CompassDirection.NorthUp}
priority={Priority.enhanced}
/>
</DialFrame>
<DialFrame label="True wind" value="18 kn" source="Masthead">
<Wind
variant={WindVariant.medium}
priority={Priority.enhanced}
currentWindSpeedKnots={18}
currentWindFromDirection={245}
vesselHeadingDeg={196}
/>
</DialFrame>
<DialFrame label="Speed over ground" value="6.4 kn" source="GPS">
<SpeedGauge speed={6.4} maxSpeed={10} tickmarkInterval={2} showLabels />
</DialFrame>
<DialFrame label="Rate of turn" value="4°/min" source="Compass">
<RateOfTurn rateOfTurnDegreesPerMinute={4} />
</DialFrame>
<DialFrame label="Rudder" value="3° S" source="Autopilot">
<Rudder angle={3} maxAngle={35} showLabels />
</DialFrame>
</div>
);
}
A dial frame holds one instrument in a square face and captions it: the label says what the
dial shows, the value beside it repeats the reading in figures, and the source under them says where the data comes
from. The instruments fill their parent, so the frame is what gives each dial its size. The face sits at the top of
the frame, so dials side by side in an even grid share one face size and one top line, however long their captions
are. The frame is a <figure> named by its label.
Examples
Face size
By default the face takes the frame's full width, so a grid of equal columns gives every dial one size. faceSize
fixes the face instead, in em, for dials in a row that is not a grid.
Code
import { DialFrame } from "@bosunkit/components/dial-frame";
import { Compass, CompassDirection, Priority, Rudder } from "@bosunkit/instruments";
import type { ReactElement } from "react";
export const description: string =
"Two dials with a fixed 8em face, side by side in a wide row: the faces stay 8em whatever the row's width.";
export default function FaceSize(): ReactElement {
return (
<div style={{ display: "flex", flexWrap: "wrap", gap: "var(--space-md)", width: "100%" }}>
<DialFrame label="Heading" value="196°" source="Compass" faceSize="8em">
<Compass heading={196} direction={CompassDirection.NorthUp} priority={Priority.enhanced} />
</DialFrame>
<DialFrame label="Rudder" value="3° S" source="Autopilot" faceSize="8em">
<Rudder angle={3} maxAngle={35} />
</DialFrame>
</div>
);
}
Caption
The label is required; the source and the value are optional. The frame is a size container, and a frame narrower than 8em puts the value under the label.
Code
import { DialFrame } from "@bosunkit/components/dial-frame";
import { DepthActual } from "@bosunkit/instruments";
import type { ReactElement } from "react";
export const description: string =
"The caption's three parts: the depth dial with its label alone, with its source, and with its value; in a narrow " +
"frame the value moves under the label.";
export default function Caption(): ReactElement {
return (
<div
style={{
display: "grid",
gridTemplateColumns: "repeat(3, minmax(6em, 10em))",
gap: "var(--space-md)",
width: "100%",
}}
>
<DialFrame label="Depth">
<DepthActual depth={12.4} draft={2.2} maxDepth={40} />
</DialFrame>
<DialFrame label="Depth" source="Sounder">
<DepthActual depth={12.4} draft={2.2} maxDepth={40} />
</DialFrame>
<DialFrame label="Depth" source="Sounder" value="12.4 m">
<DepthActual depth={12.4} draft={2.2} maxDepth={40} />
</DialFrame>
</div>
);
}
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| labelrequired | string | – | What the dial shows ("Heading", "True wind"), as the caller displays it; it names the figure. |
| source | string | undefined | – | Where the dial's data comes from ("Compass", "GPS"), as the caller displays it, under the label. |
| value | ReactNode | undefined | – | The dial's value in words or figures ("196°", "6.4 kn"), as the caller writes it, beside the label. |
| childrenrequired | ReactNode | – | The instrument the frame holds; it fills the square face. |
| faceSize | string | undefined | – | The side of the square face, as a CSS length in em ("9em"). By default the face takes the frame's full width,
so frames in an even grid share one face size. |
| className | string | undefined | – | Classes added to the frame's own. |
| testId | string | undefined | – | data-testid on the frame; its parts are ${testId}--face and ${testId}--caption. |
| ref | Ref<HTMLElement> | undefined | – | The frame's <figure> element. |
Related
- Instruments: the dials a frame holds, with their props.
- Reading: a value with its source and integrity, for a figure without a dial.
- Conning: a row of six framed dials at helm size.