Merged PR 204: Implement Properties' categories

This commit is contained in:
Eric Nguyen 2022-10-03 13:58:45 +00:00
parent fa3246b725
commit 34c00d267c
4 changed files with 365 additions and 257 deletions

View file

@ -4,25 +4,29 @@ import { ICategory } from '../../Interfaces/ICategory';
import { TruncateString } from '../../utils/stringtools'; import { TruncateString } from '../../utils/stringtools';
interface ICategoryProps { interface ICategoryProps {
children: JSX.Element[] heightClass?: string
children?: JSX.Element[] | JSX.Element
category: ICategory category: ICategory
defaultIsOpen?: boolean
} }
export function Category(props: ICategoryProps): JSX.Element { export function Category(props: ICategoryProps): JSX.Element {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(props.defaultIsOpen ?? false);
const categoryType: string = props.category.Type; const categoryType: string = props.category.Type;
const categoryDisplayedText: string = props.category.DisplayedText ?? categoryType; const categoryDisplayedText: string = props.category.DisplayedText ?? categoryType;
const heightClass = props.heightClass ?? 'h-16';
return ( return (
<div <div
className={` transition-all text-center ${isOpen ? 'overflow-hidden h-full' : 'overflow-visible h-16'}`} className={` transition-all text-center ${isOpen ? 'overflow-hidden h-full' : `overflow-visible ${heightClass}`}`}
key={categoryType} key={categoryType}
id={categoryType} id={categoryType}
title={categoryDisplayedText} title={categoryDisplayedText}
> >
<div <div
className={'flex flex-row group h-16 cursor-pointer'} className={`flex flex-row group cursor-pointer ${heightClass}`}
onClick={() => setIsOpen(!isOpen)} onClick={() => setIsOpen(!isOpen)}
> >
<span className={`transition-all flex-1 h-full justify-center sidebar-component-left ${isOpen ? 'rounded-b-none bg-slate-400/80 group-hover:bg-blue-600' : ''}`}> <span className={`transition-all flex-1 h-full justify-center sidebar-component-left ${isOpen ? 'rounded-b-none bg-slate-400/80 group-hover:bg-blue-600' : ''}`}>

View file

@ -12,6 +12,7 @@ import { PositionReferenceSelector } from '../RadioGroupButtons/PositionReferenc
import { OrientationSelector } from '../RadioGroupButtons/OrientationSelector'; import { OrientationSelector } from '../RadioGroupButtons/OrientationSelector';
import { OrientationCheckboxes } from '../CheckboxGroupButtons/OrientationCheckboxes'; import { OrientationCheckboxes } from '../CheckboxGroupButtons/OrientationCheckboxes';
import { PositionCheckboxes } from '../CheckboxGroupButtons/PositionCheckboxes'; import { PositionCheckboxes } from '../CheckboxGroupButtons/PositionCheckboxes';
import { Category } from '../Category/Category';
interface IContainerFormProps { interface IContainerFormProps {
properties: IContainerProperties properties: IContainerProperties
@ -28,8 +29,8 @@ function GetCSSInputs(properties: IContainerProperties,
id={key} id={key}
labelText={key} labelText={key}
inputKey={key} inputKey={key}
labelClassName='' labelClassName='col-span-2'
inputClassName='' inputClassName='col-span-3'
type='string' type='string'
value={(properties.style as any)[key]} value={(properties.style as any)[key]}
onChange={(value) => onChange(key, value, PropertyType.Style)} />); onChange={(value) => onChange(key, value, PropertyType.Style)} />);
@ -38,32 +39,9 @@ function GetCSSInputs(properties: IContainerProperties,
} }
export function ContainerForm(props: IContainerFormProps): JSX.Element { export function ContainerForm(props: IContainerFormProps): JSX.Element {
const categoryHeight = 'h-11';
return ( return (
<div className='grid grid-cols-1 md:grid-cols-2 gap-y-6 items-center'> <div className='grid grid-cols-1 gap-y-4 items-center'>
<InputGroup
labelText='Name'
inputKey='id'
labelClassName=''
inputClassName=''
type='string'
value={props.properties.id.toString()}
isDisabled={true} />
<InputGroup
labelText='Parent name'
inputKey='parentId'
labelClassName=''
inputClassName=''
type='string'
value={props.properties.parentId}
isDisabled={true} />
<InputGroup
labelText='Type'
inputKey='type'
labelClassName=''
inputClassName=''
type='string'
value={props.properties.type}
isDisabled={true} />
<TextInputGroup <TextInputGroup
id={`${props.properties.id}-displayedText`} id={`${props.properties.id}-displayedText`}
labelText='Displayed text' labelText='Displayed text'
@ -80,12 +58,62 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
value={props.properties.orientation} value={props.properties.orientation}
onChange={props.onChange} onChange={props.onChange}
/> />
<Category
category={{
Type: 'Properties',
DisplayedText: 'Properties'
}}
heightClass={`${categoryHeight}`}
>
<div className='grid grid-cols-1 gap-y-6 items-center prop-category-body'>
<div>
<InputGroup
labelText='Name'
inputKey='id'
labelClassName=''
inputClassName=''
type='string'
value={props.properties.id.toString()}
isDisabled={true} />
</div>
<div>
<InputGroup
labelText='Parent name'
inputKey='parentId'
labelClassName=''
inputClassName=''
type='string'
value={props.properties.parentId}
isDisabled={true} />
</div>
<div>
<InputGroup
labelText='Type'
inputKey='type'
labelClassName=''
inputClassName=''
type='string'
value={props.properties.type}
isDisabled={true} />
</div>
</div>
</Category>
<Category category={{
Type: 'Position',
DisplayedText: 'Position'
}}
defaultIsOpen={true}
heightClass={`${categoryHeight}`}
>
<div className='grid grid-cols-3 gap-y-2 items-center prop-category-body'>
<TextInputGroup <TextInputGroup
id={`${props.properties.id}-x`} id={`${props.properties.id}-x`}
labelText='x' labelText='x'
inputKey='x' inputKey='x'
labelClassName='' labelClassName=''
inputClassName='' inputClassName='col-span-2'
type='number' type='number'
isDisabled={props.properties.linkedSymbolId !== ''} isDisabled={props.properties.linkedSymbolId !== ''}
value={TransformX( value={TransformX(
@ -109,7 +137,7 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
labelText='y' labelText='y'
inputKey='y' inputKey='y'
labelClassName='' labelClassName=''
inputClassName='' inputClassName='col-span-2'
type='number' type='number'
value={TransformY( value={TransformY(
RemoveXMargin(props.properties.y, props.properties.margin.top), RemoveXMargin(props.properties.y, props.properties.margin.top),
@ -127,64 +155,65 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
props.properties.margin.top props.properties.margin.top
) )
)} /> )} />
</div>
</Category>
<Category category={{
Type: 'Size',
DisplayedText: 'Size'
}}
heightClass={`${categoryHeight}`}
>
<div className='grid grid-cols-5 gap-y-2 items-center prop-category-body'>
<TextInputGroup <TextInputGroup
id={`${props.properties.id}-minWidth`} id={`${props.properties.id}-minWidth`}
labelText='Minimum Width' labelText='Minimum Width'
inputKey='minWidth' inputKey='minWidth'
labelClassName='' labelClassName='col-span-2'
inputClassName='' inputClassName='col-span-3'
type='number' type='number'
min={1} min={1}
value={props.properties.minWidth.toString()} value={props.properties.minWidth.toString()}
onChange={(value) => props.onChange('minWidth', Number(value))} /> onChange={(value) => props.onChange('minWidth', Number(value))} />
<TextInputGroup
id={`${props.properties.id}-maxWidth`}
labelText='Maximum Width'
inputKey='maxWidth'
labelClassName=''
inputClassName=''
type='number'
min={1}
value={props.properties.maxWidth.toString()}
onChange={(value) => props.onChange('maxWidth', Number(value))} />
<TextInputGroup <TextInputGroup
id={`${props.properties.id}-width`} id={`${props.properties.id}-width`}
labelText='Width' labelText='Width'
inputKey='width' inputKey='width'
labelClassName='' labelClassName='col-span-2'
inputClassName='' inputClassName='col-span-3'
type='number' type='number'
min={props.properties.minWidth} min={props.properties.minWidth}
max={props.properties.maxWidth} max={props.properties.maxWidth}
value={(RemoveWidthMargin(props.properties.width, props.properties.margin.left, props.properties.margin.right)).toString()} value={(RemoveWidthMargin(props.properties.width, props.properties.margin.left, props.properties.margin.right)).toString()}
onChange={(value) => props.onChange('width', ApplyWidthMargin(Number(value), props.properties.margin.left, props.properties.margin.right))} onChange={(value) => props.onChange('width', ApplyWidthMargin(Number(value), props.properties.margin.left, props.properties.margin.right))}
isDisabled={props.properties.isFlex} /> isDisabled={props.properties.isFlex} />
<TextInputGroup
id={`${props.properties.id}-maxWidth`}
labelText='Maximum Width'
inputKey='maxWidth'
labelClassName='col-span-2'
inputClassName='col-span-3'
type='number'
min={1}
value={props.properties.maxWidth.toString()}
onChange={(value) => props.onChange('maxWidth', Number(value))} />
<div className='col-span-5 p-3'></div>
<TextInputGroup <TextInputGroup
id={`${props.properties.id}-minHeight`} id={`${props.properties.id}-minHeight`}
labelText='Minimum Height' labelText='Minimum Height'
inputKey='minHeight' inputKey='minHeight'
labelClassName='' labelClassName='col-span-2'
inputClassName='' inputClassName='col-span-3'
type='number' type='number'
min={1} min={1}
value={props.properties.minHeight.toString()} value={props.properties.minHeight.toString()}
onChange={(value) => props.onChange('minHeight', Number(value))} /> onChange={(value) => props.onChange('minHeight', Number(value))} />
<TextInputGroup
id={`${props.properties.id}-maxHeight`}
labelText='Maximum Height'
inputKey='maxHeight'
labelClassName=''
inputClassName=''
type='number'
min={1}
value={props.properties.maxHeight.toString()}
onChange={(value) => props.onChange('maxHeight', Number(value))} />
<TextInputGroup <TextInputGroup
id={`${props.properties.id}-height`} id={`${props.properties.id}-height`}
labelText='Height' labelText='Height'
inputKey='height' inputKey='height'
labelClassName='' labelClassName='col-span-2'
inputClassName='' inputClassName='col-span-3'
type='number' type='number'
min={props.properties.minHeight} min={props.properties.minHeight}
max={props.properties.maxHeight} max={props.properties.maxHeight}
@ -192,6 +221,26 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
onChange={(value) => props.onChange('height', ApplyWidthMargin(Number(value), props.properties.margin.top, props.properties.margin.bottom))} onChange={(value) => props.onChange('height', ApplyWidthMargin(Number(value), props.properties.margin.top, props.properties.margin.bottom))}
isDisabled={props.properties.isFlex} isDisabled={props.properties.isFlex}
/> />
<TextInputGroup
id={`${props.properties.id}-maxHeight`}
labelText='Maximum Height'
inputKey='maxHeight'
labelClassName='col-span-2'
inputClassName='col-span-3'
type='number'
min={1}
value={props.properties.maxHeight.toString()}
onChange={(value) => props.onChange('maxHeight', Number(value))} />
</div>
</Category>
<Category category={{
Type: 'Margins',
DisplayedText: 'Margins'
}}
heightClass={`${categoryHeight}`}
>
<div className='grid grid-cols-2 items-center gap-y-2 prop-category-body'>
<TextInputGroup <TextInputGroup
id={`${props.properties.id}-ml`} id={`${props.properties.id}-ml`}
labelText='Margin left' labelText='Margin left'
@ -232,11 +281,21 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
min={0} min={0}
value={(props.properties.margin.right ?? 0).toString()} value={(props.properties.margin.right ?? 0).toString()}
onChange={(value) => props.onChange('right', Number(value), PropertyType.Margin)} /> onChange={(value) => props.onChange('right', Number(value), PropertyType.Margin)} />
</div>
</Category>
<Category category={{
Type: 'Behaviors',
DisplayedText: 'Behaviors'
}}
heightClass={`${categoryHeight}`}
>
<div className='grid grid-cols-2 items-center gap-y-2 prop-category-body'>
<ToggleButton <ToggleButton
labelText='Flex' labelText='Flex'
inputKey='isFlex' inputKey='isFlex'
labelClassName='' labelClassName=''
inputClassName='' inputClassName='ml-auto mr-auto block'
type={ToggleType.Full} type={ToggleType.Full}
checked={props.properties.isFlex} checked={props.properties.isFlex}
onChange={(event) => props.onChange('isFlex', event.target.checked)} onChange={(event) => props.onChange('isFlex', event.target.checked)}
@ -245,10 +304,20 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
labelText='Anchor' labelText='Anchor'
inputKey='isAnchor' inputKey='isAnchor'
labelClassName='' labelClassName=''
inputClassName='' inputClassName='ml-auto mr-auto block'
type={ToggleType.Full} type={ToggleType.Full}
checked={props.properties.isAnchor} checked={props.properties.isAnchor}
onChange={(event) => props.onChange('isAnchor', event.target.checked)} /> onChange={(event) => props.onChange('isAnchor', event.target.checked)} />
</div>
</Category>
<Category category={{
Type: 'Alignment',
DisplayedText: 'Alignment'
}}
heightClass={`${categoryHeight}`}
>
<div className='prop-category-body'>
<PositionReferenceSelector <PositionReferenceSelector
id='positionReference' id='positionReference'
name='PositionReference' name='PositionReference'
@ -256,6 +325,7 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
value={props.properties.positionReference} value={props.properties.positionReference}
onChange={props.onChange} onChange={props.onChange}
/> />
<div className='p-3'></div>
<Select <Select
inputKey='linkedSymbolId' inputKey='linkedSymbolId'
labelText='Align with symbol' labelText='Align with symbol'
@ -268,9 +338,19 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
}))} }))}
value={props.properties.linkedSymbolId ?? ''} value={props.properties.linkedSymbolId ?? ''}
onChange={(event) => props.onChange('linkedSymbolId', event.target.value)} /> onChange={(event) => props.onChange('linkedSymbolId', event.target.value)} />
{GetCSSInputs(props.properties, props.onChange)} </div>
</Category>
<Category category={{
Type: 'Dimensions',
DisplayedText: 'Dimensions'
}}
heightClass={`${categoryHeight}`}
>
<div className='grid grid-cols-1 gap-6 prop-category-body'>
{ {
SHOW_SELF_DIMENSIONS && SHOW_SELF_DIMENSIONS &&
<div className='grid grid-cols-1 gap-2'>
<PositionCheckboxes <PositionCheckboxes
id='showSelfDimensions' id='showSelfDimensions'
name='ShowSelfDimensions' name='ShowSelfDimensions'
@ -278,9 +358,11 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
value={props.properties.showSelfDimensions} value={props.properties.showSelfDimensions}
onChange={props.onChange} onChange={props.onChange}
/> />
</div>
} }
{ {
SHOW_CHILDREN_DIMENSIONS && SHOW_CHILDREN_DIMENSIONS &&
<div className='grid grid-cols-1 gap-2'>
<PositionCheckboxes <PositionCheckboxes
id='showChildrenDimensions' id='showChildrenDimensions'
name='ShowChildrenDimensions' name='ShowChildrenDimensions'
@ -288,10 +370,12 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
value={props.properties.showChildrenDimensions} value={props.properties.showChildrenDimensions}
onChange={props.onChange} onChange={props.onChange}
/> />
</div>
} }
{ {
SHOW_BORROWER_DIMENSIONS && SHOW_BORROWER_DIMENSIONS &&
<> <>
<div className='grid grid-cols-1 gap-2'>
<OrientationCheckboxes <OrientationCheckboxes
id='markPosition' id='markPosition'
name='MarkPosition' name='MarkPosition'
@ -299,6 +383,8 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
labelText='Mark the position' labelText='Mark the position'
onChange={props.onChange} onChange={props.onChange}
/> />
</div>
<div className='grid grid-cols-1 gap-2'>
<PositionCheckboxes <PositionCheckboxes
id='showDimensionWithMarks' id='showDimensionWithMarks'
name='ShowDimensionWithMarks' name='ShowDimensionWithMarks'
@ -306,8 +392,22 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
value={props.properties.showDimensionWithMarks} value={props.properties.showDimensionWithMarks}
onChange={props.onChange} onChange={props.onChange}
/> />
</div>
</> </>
} }
</div> </div>
</Category>
<Category category={{
Type: 'Style',
DisplayedText: 'Style'
}}
heightClass={`${categoryHeight}`}
>
<div className='grid grid-cols-5 gap-6 items-center prop-category-body'>
{GetCSSInputs(props.properties, props.onChange)}
</div>
</Category>
</div>
); );
} }

View file

@ -35,7 +35,7 @@ export function ToggleButton(props: IToggleButtonProps): JSX.Element {
{ props.labelText } { props.labelText }
</label> </label>
<label <label
className="relative cursor-pointer" className={`relative cursor-pointer ${props.inputClassName}`}
htmlFor={props.inputKey} htmlFor={props.inputKey}
> >
<input <input

View file

@ -118,6 +118,10 @@
text-xs font-medium transition-all text-gray-800 mt-1 px-3 py-2 text-xs font-medium transition-all text-gray-800 mt-1 px-3 py-2
bg-white border-2 border-white rounded-lg placeholder-gray-800 bg-white border-2 border-white rounded-lg placeholder-gray-800
focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500 focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500
disabled:bg-slate-300 disabled:text-gray-500 disabled:border-slate-300 disabled:shadow-none; disabled:bg-slate-200 disabled:text-gray-500 disabled:border-slate-300 disabled:shadow-none;
}
.prop-category-body {
@apply rounded-lg bg-slate-300 p-3
} }
} }