Component reference
SegmentedControl
A single choice, using native radio keyboard semantics; tabs remain a separate component.
Preview
Form ownership and reset
Two controlled groups sit inside and outside a form; native reset does not change the host's current value.
render() {
const options = [
{ value: "a", label: "A" },
{ value: "b", label: "B" },
];
const inside = signal("a");
const outside = signal("a");
return (
<Stack gap="relaxed" align="start">
<form id="segmented-inside">
<Stack gap="compact" align="start">
<SegmentedControl
id="inside-choice"
name="mode"
label="Inner choice"
value={inside}
options={options}
onValueChange={(value) => {
inside.value = value;
}}
/>
<Button type="reset" variant="outline" size="small">
Reset inner form
</Button>
</Stack>
</form>
<Stack gap="compact" align="start">
<SegmentedControl
id="outside-choice"
name="mode"
form="segmented-outside"
label="Outer choice"
value={outside}
options={options}
onValueChange={(value) => {
outside.value = value;
}}
/>
<form id="segmented-outside">
<Button type="reset" variant="outline" size="small">
Reset outer form
</Button>
</form>
</Stack>
</Stack>
);
}Installation
bun add meowtail
Usage
import { SegmentedControl } from "meowtail";Examples
The other stories that show this component.
Segmented control, active text and confirmation
The segmented control keeps native radio semantics. Confirmation is only used for this local example and introduces no global action gate.
render() {
const mode = signal("comfortable");
const locked = signal(false);
const active = signal(true);
const open = signal(false);
const acknowledged = signal(false);
const feedback = signal("The example has not been removed.");
return (
<Stack align="start">
<SegmentedControl
id="reading-mode"
label="Reading spacing"
value={mode}
disabled={locked}
onValueChange={(next) => {
mode.value = next;
}}
options={[
{ value: "comfortable", label: "Comfortable" },
{ value: "locked", label: "Automatic", disabled: true },
{ value: "compact", label: "Compact" },
]}
/>
<Button
variant="quiet"
onClick={() => {
locked.value = !locked.value;
}}
>
Toggle selection lock
</Button>
<TextShimmer text="Reading the file content" active={active} />
<TextShimmer active={active} className="compound-shimmer">
<TextShimmer text="Checking" />
{" · "}
<TextShimmer text="src/components" />
</TextShimmer>
<Button
variant="quiet"
onClick={() => {
active.value = !active.value;
}}
>
Toggle active state
</Button>
<Button
variant="outline"
onClick={() => {
acknowledged.value = false;
open.value = true;
}}
>
Remove example
</Button>
<RiskConfirmation
id="remove-sample"
open={open}
title="Remove example"
description="This is a local component example; it does not delete real files."
acknowledgeLabel="I understand this action only affects the example."
cancelLabel="Cancel"
confirmLabel="Confirm removal"
acknowledged={acknowledged}
onAcknowledgedChange={(next) => {
acknowledged.value = next;
}}
onCancel={() => {
open.value = false;
}}
onConfirm={() => {
open.value = false;
feedback.value = "Removed the local example.";
}}
/>
<Note role="status">{feedback}</Note>
</Stack>
);
}API reference
Props
| Prop | Type | Default |
|---|---|---|
idRequired | string | – |
name | string | id |
form | string | – |
labelRequired | string | – |
valueRequired | MaybeSignal<string> | – |
optionsRequired | readonly SegmentedControlOption[] | – |
onValueChangeRequired | (value: string) => void | – |
disabled | MaybeSignal<boolean> | – |
Also takes className, children and the attributes and events of its root element.
DOM parts
rootlegendoptionsoptioninputlabel
Registry
The component is registered as segmented-control in the meowtail component registry.