Merged PR 199: Add more Position for the dimensions + rename isDimensionBorrower and MarkPosition... + Refactor components in ContainerForm with Checkboxes and Selector + Add more docs

Add more Position for the dimensions

Rename isDimensionBorrower and MarkPosition...

Refactor components in ContainerForm with Checkboxes and Selector

Add more docs
This commit is contained in:
Eric Nguyen 2022-09-30 09:28:08 +00:00
parent 38666af314
commit b88539e34d
13 changed files with 494 additions and 314 deletions

View file

@ -0,0 +1,88 @@
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'>
{inputGroup.text}
</label>
</div>
));
const gridColsClass = GRID_COLS[props.colQty];
return (
<>
<label className='text-xs font-medium text-gray-800'>
{props.labelText}
</label>
<div id='XPositionReference'
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];
}
}

View file

@ -0,0 +1,52 @@
import React from 'react';
import { ChevronUpDownIcon } from '@heroicons/react/20/solid';
import { CheckboxGroupButtons } from './CheckboxGroupButtons';
import { Orientation } from '../../Enums/Orientation';
interface IOrientationCheckboxesProps {
id: string
name: string
labelText: string
value: Orientation[]
onChange: (key: string, value: number[]) => void
}
export function OrientationCheckboxes({
id,
name,
labelText,
value,
onChange
}: IOrientationCheckboxesProps): JSX.Element {
return <CheckboxGroupButtons
key={id}
name={name}
selectedValues={value}
inputClassName='hidden'
labelText={labelText}
colQty={2}
inputGroups={[
{
key: `${id}-horizontal`,
text: (
<div title='Horizontal' aria-label='horizontal' className='radio-button-icon'>
<ChevronUpDownIcon className='heroicon p-1' />
</div>
),
value: Orientation.Horizontal
},
{
key: `${id}-vertical`,
text: (
<div title='Vertical' aria-label='vertical' className='radio-button-icon'>
<ChevronUpDownIcon className='heroicon rotate-90 p-1' />
</div>
),
value: Orientation.Vertical
}
]}
onChange={(newSelectedValues) => {
onChange(id, newSelectedValues);
}}
/>;
}

View file

@ -0,0 +1,70 @@
import React from 'react';
import { ArrowDownIcon, ArrowLeftIcon, ArrowRightIcon, ArrowUpIcon } from '@heroicons/react/20/solid';
import { Position } from '../../Enums/Position';
import { CheckboxGroupButtons } from './CheckboxGroupButtons';
interface IPositionCheckboxesProps {
id: string
name: string
labelText: string
value: Position[]
onChange: (key: string, value: number[]) => void
}
export function PositionCheckboxes({
id,
name,
labelText,
value,
onChange
}: IPositionCheckboxesProps): JSX.Element {
return <CheckboxGroupButtons
key={id}
name={name}
selectedValues={value}
inputClassName='hidden'
labelText={labelText}
colQty={4}
inputGroups={[
{
key: `${id}-left`,
text: (
<div title='Left' aria-label='left' className='radio-button-icon'>
<ArrowLeftIcon className='heroicon p-1' />
</div>
),
value: Position.Left
},
{
key: `${id}-down`,
text: (
<div title='Down' aria-label='down' className='radio-button-icon'>
<ArrowDownIcon className='heroicon p-1' />
</div>
),
value: Position.Down
},
{
key: `${id}-up`,
text: (
<div title='Up' aria-label='up' className='radio-button-icon'>
<ArrowUpIcon className='heroicon p-1' />
</div>
),
value: Position.Up
},
{
key: `${id}-right`,
text: (
<div title='Right' aria-label='right' className='radio-button-icon'>
<ArrowRightIcon className='heroicon p-1' />
</div>
),
value: Position.Right
}
]}
onChange={(newSelectedValues) => {
onChange(id, newSelectedValues);
}}
/>;
}