Angle slider
An angle in degrees from a dial, dragged round or stepped by the keys, with marks.
Basic #
Heading
export const AngleSliderStyle = forSlots(AngleSliderSlots)(Recipes.AngleSlider({}))
/** What `update` and the view agree on: whole degrees, the compass points marked. */
export const HEADING_LAYOUT: AngleSlider.AngleSliderLayout = {
step: 1,
marks: [
{ value: 0, label: 'N' },
{ value: 90, label: 'E' },
{ value: 180, label: 'S' },
{ value: 270, label: 'W' },
],
}
/** The angle and the drag are the dial's Model, folded with `AngleSlider.update(HEADING_LAYOUT)`. */
export const angleSlider = <Message>(
style: NamedStyle<typeof AngleSliderSlots>,
model: AngleSlider.Model,
onMessage: (message: AngleSlider.Message) => Message,
h: HtmlBuilder<Message>,
): Html =>
AngleSlider.view(
{ ...HEADING_LAYOUT, model, onMessage, label: 'Heading', name: 'heading', style },
h,
)Kept to marks #
Rotation
/** A quarter turn at a time: a drag lands on the nearest mark, and the keys go mark to mark. */
export const ROTATION_LAYOUT: AngleSlider.AngleSliderLayout = {
step: 90,
marks: [{ value: 0 }, { value: 90 }, { value: 180 }, { value: 270 }],
restrictToMarks: true,
}
export const angleSliderMarks = <Message>(
style: NamedStyle<typeof AngleSliderSlots>,
model: AngleSlider.Model,
onMessage: (message: AngleSlider.Message) => Message,
h: HtmlBuilder<Message>,
): Html =>
AngleSlider.view(
{
...ROTATION_LAYOUT,
model,
onMessage,
label: 'Rotation',
format: value => `${value / 90} of 4`,
valueText: value => `${value} degrees`,
style,
},
h,
)Usage
Each example above names the function that drew it, over the theme module Create a theme writes. The preview passes it the style picked above instead of its default.