mirror of https://github.com/portainer/portainer
74 lines
1.8 KiB
TypeScript
74 lines
1.8 KiB
TypeScript
import clsx from 'clsx';
|
|
import { PropsWithChildren } from 'react';
|
|
import type { Icon } from 'lucide-react';
|
|
|
|
import { TooltipWithChildren } from '@@/Tip/TooltipWithChildren';
|
|
|
|
import styles from './BoxOption.module.css';
|
|
import { BoxSelectorOption, Value } from './types';
|
|
|
|
interface Props<T extends Value> {
|
|
radioName: string;
|
|
option: BoxSelectorOption<T>;
|
|
onSelect?(value: T): void;
|
|
isSelected(value: T): boolean;
|
|
disabled?: boolean;
|
|
tooltip?: string;
|
|
className?: string;
|
|
type?: 'radio' | 'checkbox';
|
|
checkIcon: Icon;
|
|
}
|
|
|
|
export function BoxOption<T extends Value>({
|
|
radioName,
|
|
option,
|
|
onSelect = () => {},
|
|
isSelected,
|
|
disabled,
|
|
tooltip,
|
|
className,
|
|
type = 'radio',
|
|
children,
|
|
checkIcon: Check,
|
|
}: PropsWithChildren<Props<T>>) {
|
|
const selected = isSelected(option.value);
|
|
|
|
const item = (
|
|
<div className={clsx(styles.root, className)}>
|
|
<input
|
|
type={type}
|
|
name={radioName}
|
|
id={option.id}
|
|
checked={selected}
|
|
value={option.value.toString()}
|
|
disabled={disabled}
|
|
onChange={() => onSelect(option.value)}
|
|
/>
|
|
|
|
<label htmlFor={option.id} data-cy={`${radioName}_${option.value}`}>
|
|
{children}
|
|
|
|
{!disabled && (
|
|
<div
|
|
className={clsx(
|
|
'absolute top-4 right-4 h-4 w-4 rounded-full border border-solid border-blue-8 text-white font-bold flex items-center justify-center',
|
|
{
|
|
'bg-white': !selected,
|
|
'bg-blue-8': selected,
|
|
}
|
|
)}
|
|
>
|
|
{selected && <Check className="lucide" strokeWidth={3} />}
|
|
</div>
|
|
)}
|
|
</label>
|
|
</div>
|
|
);
|
|
|
|
if (tooltip) {
|
|
return <TooltipWithChildren message={tooltip}>{item}</TooltipWithChildren>;
|
|
}
|
|
|
|
return item;
|
|
}
|