components/segmented/segmented.react.tsx
42 lines and 3 functions in DrDustinEdwards/capsomer, at commit d3966cc on 2026-10-24. This file on GitHub.
Functions
| Function | Lines | Complexity | Covered | CRAP | Mutation |
|---|---|---|---|---|---|
| Segmented | 30 to 45 | 7 | No data: no coverage report in this map | No data: no coverage report in this map | No data: mutation testing has not run on this repo yet |
| <anonymous:37> | 37 to 41 | 3 | No data: no coverage report in this map | No data: no coverage report in this map | No data: mutation testing has not run on this repo yet |
| <anonymous:39> | 39 to 39 | 1 | No data: no coverage report in this map | No data: no coverage report in this map | No data: mutation testing has not run on this repo yet |
Imports
It imports no other module of this repo. No module of this repo imports it.
Source
import { useId, type ReactNode } from "react";
export interface SegmentedOption<V extends string> {
value: V;
label: ReactNode;
disabled?: boolean;
}
export interface SegmentedProps<V extends string> {
// What is being chosen. Always given; hideLegend keeps it for screen readers only, where
// the context already says it (a theme switch in the top bar).
legend: ReactNode;
hideLegend?: boolean;
// Two to five.
options: Array<SegmentedOption<V>>;
value: V | null;
onChange: (value: V) => void;
// The radios' name, for a form; one is made up otherwise.
name?: string;
// The id of text that says why an option is disabled.
describedBy?: string;
size?: "sm" | "default" | "lg";
orientation?: "horizontal" | "vertical";
// Fill the row, the segments sharing it.
fill?: boolean;
// Wrong: marks the radios aria-invalid; say why in text that describedBy names.
invalid?: boolean;
}
export function Segmented<V extends string>({ legend, hideLegend = false, options, value, onChange, name, describedBy, size = "default", orientation = "horizontal", fill = false, invalid = false }: SegmentedProps<V>) {
const own = useId();
if ((options.length < 2 || options.length > 5)) console.warn("Segmented: use it for two to five options; a select or a combobox for more.");
return (
<fieldset className="cap-seg" aria-describedby={describedBy}>
<legend className={hideLegend ? "cap-sr-only" : undefined}>{legend}</legend>
<div className="cap-seg-options" data-size={size === "default" ? undefined : size} data-orientation={orientation === "vertical" ? "vertical" : undefined} data-fill={fill ? "" : undefined}>
{options.map((o) => (
<label key={o.value}>
<input type="radio" name={name ?? own} value={o.value} checked={value === o.value} disabled={o.disabled} aria-invalid={invalid || undefined} onChange={() => onChange(o.value)} /> {o.label}
</label>
))}
</div>
</fieldset>
);
}