55 lines
1.2 KiB
TypeScript
55 lines
1.2 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 type SegmentedControlSize = "default" | "dense";
|
|
|
|
export interface SegmentedControlProps<T extends string> {
|
|
value: T;
|
|
items: Array<SegmentedItem<T>>;
|
|
label: string;
|
|
size?: SegmentedControlSize;
|
|
className?: string;
|
|
onChange: (value: T) => void;
|
|
}
|
|
|
|
export function SegmentedControl<T extends string>({
|
|
value,
|
|
items,
|
|
label,
|
|
size = "default",
|
|
className,
|
|
onChange,
|
|
}: SegmentedControlProps<T>) {
|
|
return (
|
|
<div
|
|
className={cn("nodedc-segmented", className)}
|
|
role="tablist"
|
|
aria-label={label}
|
|
data-size={size === "default" ? undefined : size}
|
|
>
|
|
{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>
|
|
);
|
|
}
|