You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
60 lines
1.6 KiB
TypeScript
60 lines
1.6 KiB
TypeScript
4 years ago
|
import clsx from "clsx";
|
||
|
|
||
|
// TODO: It might be "clever" to add option.icon to the existing component <ButtonSelect />
|
||
2 years ago
|
export const ButtonIconSelect = <T extends Object>(
|
||
|
props: {
|
||
|
options: {
|
||
|
value: T;
|
||
|
text: string;
|
||
|
icon: JSX.Element;
|
||
|
testId?: string;
|
||
|
/** if not supplied, defaults to value identity check */
|
||
|
active?: boolean;
|
||
|
}[];
|
||
|
value: T | null;
|
||
|
type?: "radio" | "button";
|
||
|
} & (
|
||
|
| { type?: "radio"; group: string; onChange: (value: T) => void }
|
||
|
| {
|
||
|
type: "button";
|
||
|
onClick: (
|
||
|
value: T,
|
||
|
event: React.MouseEvent<HTMLButtonElement, MouseEvent>,
|
||
|
) => void;
|
||
|
}
|
||
|
),
|
||
|
) => (
|
||
4 years ago
|
<div className="buttonList buttonListIcon">
|
||
2 years ago
|
{props.options.map((option) =>
|
||
|
props.type === "button" ? (
|
||
|
<button
|
||
|
key={option.text}
|
||
|
onClick={(event) => props.onClick(option.value, event)}
|
||
|
className={clsx({
|
||
|
active: option.active ?? props.value === option.value,
|
||
|
})}
|
||
3 years ago
|
data-testid={option.testId}
|
||
2 years ago
|
title={option.text}
|
||
|
>
|
||
|
{option.icon}
|
||
|
</button>
|
||
|
) : (
|
||
|
<label
|
||
|
key={option.text}
|
||
|
className={clsx({ active: props.value === option.value })}
|
||
|
title={option.text}
|
||
|
>
|
||
|
<input
|
||
|
type="radio"
|
||
|
name={props.group}
|
||
|
onChange={() => props.onChange(option.value)}
|
||
|
checked={props.value === option.value}
|
||
|
data-testid={option.testId}
|
||
|
/>
|
||
|
{option.icon}
|
||
|
</label>
|
||
|
),
|
||
|
)}
|
||
4 years ago
|
</div>
|
||
|
);
|