47 lines
1.0 KiB
TypeScript
47 lines
1.0 KiB
TypeScript
import type { ReactNode } from "react";
|
|
import { cn } from "./cn.js";
|
|
|
|
export interface SegmentedItem<T extends string> {
|
|
value: T;
|
|
label: string;
|
|
icon?: ReactNode;
|
|
disabled?: boolean;
|
|
}
|
|
|
|
export interface SegmentedControlProps<T extends string> {
|
|
value: T;
|
|
items: Array<SegmentedItem<T>>;
|
|
label: string;
|
|
className?: string;
|
|
onChange: (value: T) => void;
|
|
}
|
|
|
|
export function SegmentedControl<T extends string>({
|
|
value,
|
|
items,
|
|
label,
|
|
className,
|
|
onChange,
|
|
}: SegmentedControlProps<T>) {
|
|
return (
|
|
<div className={cn("nodedc-segmented", className)} role="tablist" aria-label={label}>
|
|
{items.map((item) => (
|
|
<button
|
|
key={item.value}
|
|
type="button"
|
|
className="nodedc-segmented__item"
|
|
role="tab"
|
|
aria-selected={item.value === value}
|
|
data-active={item.value === value ? "true" : undefined}
|
|
disabled={item.disabled}
|
|
onClick={() => onChange(item.value)}
|
|
>
|
|
{item.icon}
|
|
{item.label}
|
|
</button>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|
|
|