86 lines
2.4 KiB
TypeScript
86 lines
2.4 KiB
TypeScript
import * as React from 'react';
|
|
|
|
interface ICheckboxGroupButtonsProps {
|
|
name: string
|
|
selectedValues: number[]
|
|
inputClassName: string
|
|
labelText: string
|
|
inputGroups: ICheckboxInputGroup[]
|
|
colQty: number
|
|
onChange: (newSelectedValues: number[]) => void
|
|
}
|
|
|
|
// TODO: After modeler uses Typescript >= 4.x, extends Omit<IInputGroup, 'value'>
|
|
interface ICheckboxInputGroup {
|
|
key: string
|
|
text: React.ReactNode
|
|
value: number
|
|
}
|
|
|
|
// Use whole class name for react to preparse
|
|
const GRID_COLS = [
|
|
'grid-cols-none',
|
|
'grid-cols-1',
|
|
'grid-cols-2',
|
|
'grid-cols-3',
|
|
'grid-cols-4',
|
|
'grid-cols-5',
|
|
'grid-cols-6',
|
|
'grid-cols-7',
|
|
'grid-cols-8',
|
|
'grid-cols-9',
|
|
'grid-cols-10',
|
|
'grid-cols-11',
|
|
'grid-cols-12'
|
|
];
|
|
|
|
export function CheckboxGroupButtons(props: ICheckboxGroupButtonsProps): JSX.Element {
|
|
const selectedOptions = new Set<number>(props.selectedValues);
|
|
const inputGroups = props.inputGroups.map((inputGroup) => (
|
|
<div key={inputGroup.key}>
|
|
<input
|
|
key={inputGroup.key}
|
|
id={inputGroup.key}
|
|
type='checkbox'
|
|
name={props.name}
|
|
className={`peer m-2 ${props.inputClassName}`}
|
|
value={inputGroup.value}
|
|
checked={IsChecked(inputGroup)}
|
|
onChange={(event) => {
|
|
const newSelectedValues = SetChecked(Number(event.target.value), event.target.checked);
|
|
props.onChange(newSelectedValues);
|
|
}} />
|
|
<label htmlFor={inputGroup.key} className='text-gray-400 peer-checked:text-blue-500 group'>
|
|
{inputGroup.text}
|
|
</label>
|
|
</div>
|
|
));
|
|
|
|
const gridColsClass = GRID_COLS[props.colQty];
|
|
|
|
return (
|
|
<>
|
|
<label className='text-xs font-medium text-gray-800'>
|
|
{props.labelText}
|
|
</label>
|
|
<div className={`grid ${gridColsClass}`}>
|
|
{inputGroups}
|
|
</div>
|
|
</>
|
|
);
|
|
|
|
function IsChecked(inputGroup: ICheckboxInputGroup): boolean {
|
|
return selectedOptions.has(inputGroup.value);
|
|
}
|
|
|
|
/**
|
|
* Sedt an option by using a bitwise operation and returns the new selected values
|
|
* example: set the 4th option to 0: (1001) xor (1 << 3) => 0001
|
|
* @param selectedValue The option to set
|
|
* @returns The new selected values
|
|
*/
|
|
function SetChecked(selectedValue: number, isChecked: boolean): number[] {
|
|
isChecked ? selectedOptions.add(selectedValue) : selectedOptions.delete(selectedValue);
|
|
return [...selectedOptions];
|
|
}
|
|
}
|