5 changed files with 120 additions and 62 deletions
@ -1,33 +1,59 @@
@@ -1,33 +1,59 @@
|
||||
import clsx from "clsx"; |
||||
|
||||
// TODO: It might be "clever" to add option.icon to the existing component <ButtonSelect />
|
||||
export const ButtonIconSelect = <T extends Object>({ |
||||
options, |
||||
value, |
||||
onChange, |
||||
group, |
||||
}: { |
||||
options: { value: T; text: string; icon: JSX.Element; testId?: string }[]; |
||||
value: T | null; |
||||
onChange: (value: T) => void; |
||||
group: string; |
||||
}) => ( |
||||
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; |
||||
} |
||||
), |
||||
) => ( |
||||
<div className="buttonList buttonListIcon"> |
||||
{options.map((option) => ( |
||||
<label |
||||
key={option.text} |
||||
className={clsx({ active: value === option.value })} |
||||
title={option.text} |
||||
> |
||||
<input |
||||
type="radio" |
||||
name={group} |
||||
onChange={() => onChange(option.value)} |
||||
checked={value === option.value} |
||||
{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, |
||||
})} |
||||
data-testid={option.testId} |
||||
/> |
||||
{option.icon} |
||||
</label> |
||||
))} |
||||
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> |
||||
), |
||||
)} |
||||
</div> |
||||
); |
||||
|
||||
Loading…
Reference in new issue