Merged PR 196: Implement Vertical orientation + Upgrade Heroicons to 2.0
Implémenter l'orientation verticale Modifier l'effet de append Implementer RigidBody Implementer Flex et simplex Implémenter Push Implémenter Swap Implement MinMaxHeight without behaviors Fix Margin for Height Implement PositionReference Fix dimension vertical position inside children Add orientation change in form Implement sortChildren Implement Anchor Fix warning message on overlapping Fix minimap when root container is vertical #7287 #7288 #7289 #7290 #7291 #7292 #7294 #7295 #7296 #7297 #7298 #7299 #7300 #7301 #7302
This commit is contained in:
parent
459e83a0c8
commit
18cbacaca1
45 changed files with 2112 additions and 1063 deletions
|
@ -1,15 +1,17 @@
|
|||
import { MenuAlt2Icon, MenuAlt3Icon, MenuIcon } from '@heroicons/react/outline';
|
||||
import { Bars3BottomLeftIcon, Bars3CenterLeftIcon, Bars3Icon, Bars3BottomRightIcon, Bars2Icon, ViewColumnsIcon } from '@heroicons/react/24/outline';
|
||||
import * as React from 'react';
|
||||
import { PropertyType } from '../../Enums/PropertyType';
|
||||
import { XPositionReference } from '../../Enums/XPositionReference';
|
||||
import { PositionReference } from '../../Enums/PositionReference';
|
||||
import { IContainerProperties } from '../../Interfaces/IContainerProperties';
|
||||
import { ISymbolModel } from '../../Interfaces/ISymbolModel';
|
||||
import { SHOW_BORROWER_DIMENSIONS, SHOW_CHILDREN_DIMENSIONS, SHOW_SELF_DIMENSIONS } from '../../utils/default';
|
||||
import { ApplyWidthMargin, ApplyXMargin, RemoveWidthMargin, RemoveXMargin, RestoreX, TransformX } from '../../utils/svg';
|
||||
import { ApplyWidthMargin, ApplyXMargin, RemoveWidthMargin, RemoveXMargin, RestoreX, RestoreY, TransformX, TransformY } from '../../utils/svg';
|
||||
import { InputGroup } from '../InputGroup/InputGroup';
|
||||
import { TextInputGroup } from '../InputGroup/TextInputGroup';
|
||||
import { RadioGroupButtons } from '../RadioGroupButtons/RadioGroupButtons';
|
||||
import { Select } from '../Select/Select';
|
||||
import { ToggleButton, ToggleType } from '../ToggleButton/ToggleButton';
|
||||
import { Orientation } from '../../Interfaces/Orientation';
|
||||
|
||||
interface IContainerFormProps {
|
||||
properties: IContainerProperties
|
||||
|
@ -37,7 +39,7 @@ function GetCSSInputs(properties: IContainerProperties,
|
|||
|
||||
export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
||||
return (
|
||||
<div className='grid grid-cols-2 gap-y-4 items-center'>
|
||||
<div className='grid grid-cols-2 gap-y-6 items-center'>
|
||||
<InputGroup
|
||||
labelText='Name'
|
||||
inputKey='id'
|
||||
|
@ -71,6 +73,7 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
type='string'
|
||||
value={props.properties.displayedText?.toString()}
|
||||
onChange={(value) => props.onChange('displayedText', value)} />
|
||||
<OrientationSelector {...props} />
|
||||
<TextInputGroup
|
||||
id={`${props.properties.id}-x`}
|
||||
labelText='x'
|
||||
|
@ -79,14 +82,18 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
inputClassName=''
|
||||
type='number'
|
||||
isDisabled={props.properties.linkedSymbolId !== ''}
|
||||
value={TransformX(RemoveXMargin(props.properties.x, props.properties.margin.left), props.properties.width, props.properties.xPositionReference).toString()}
|
||||
value={TransformX(
|
||||
RemoveXMargin(props.properties.x, props.properties.margin.left),
|
||||
props.properties.width,
|
||||
props.properties.positionReference
|
||||
).toString()}
|
||||
onChange={(value) => props.onChange(
|
||||
'x',
|
||||
ApplyXMargin(
|
||||
RestoreX(
|
||||
Number(value),
|
||||
props.properties.width,
|
||||
props.properties.xPositionReference
|
||||
props.properties.positionReference
|
||||
),
|
||||
props.properties.margin.left
|
||||
)
|
||||
|
@ -98,11 +105,25 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
labelClassName=''
|
||||
inputClassName=''
|
||||
type='number'
|
||||
value={(props.properties.y - (props.properties.margin?.top ?? 0)).toString()}
|
||||
onChange={(value) => props.onChange('y', Number(value) + (props.properties.margin?.top ?? 0))} />
|
||||
value={TransformY(
|
||||
RemoveXMargin(props.properties.y, props.properties.margin.top),
|
||||
props.properties.height,
|
||||
props.properties.positionReference
|
||||
).toString()}
|
||||
onChange={(value) => props.onChange(
|
||||
'y',
|
||||
ApplyXMargin(
|
||||
RestoreY(
|
||||
Number(value),
|
||||
props.properties.height,
|
||||
props.properties.positionReference
|
||||
),
|
||||
props.properties.margin.top
|
||||
)
|
||||
)} />
|
||||
<TextInputGroup
|
||||
id={`${props.properties.id}-minWidth`}
|
||||
labelText='Minimum width'
|
||||
labelText='Minimum Width'
|
||||
inputKey='minWidth'
|
||||
labelClassName=''
|
||||
inputClassName=''
|
||||
|
@ -112,7 +133,7 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
onChange={(value) => props.onChange('minWidth', Number(value))} />
|
||||
<TextInputGroup
|
||||
id={`${props.properties.id}-maxWidth`}
|
||||
labelText='Maximum width'
|
||||
labelText='Maximum Width'
|
||||
inputKey='maxWidth'
|
||||
labelClassName=''
|
||||
inputClassName=''
|
||||
|
@ -132,6 +153,26 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
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))}
|
||||
isDisabled={props.properties.isFlex} />
|
||||
<TextInputGroup
|
||||
id={`${props.properties.id}-minHeight`}
|
||||
labelText='Minimum Height'
|
||||
inputKey='minHeight'
|
||||
labelClassName=''
|
||||
inputClassName=''
|
||||
type='number'
|
||||
min={1}
|
||||
value={props.properties.minHeight.toString()}
|
||||
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
|
||||
id={`${props.properties.id}-height`}
|
||||
labelText='Height'
|
||||
|
@ -139,9 +180,12 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
labelClassName=''
|
||||
inputClassName=''
|
||||
type='number'
|
||||
min={0}
|
||||
value={(props.properties.height + (props.properties.margin?.top ?? 0) + (props.properties.margin?.bottom ?? 0)).toString()}
|
||||
onChange={(value) => props.onChange('height', Number(value) - (props.properties.margin?.top ?? 0) - (props.properties.margin?.bottom ?? 0))} />
|
||||
min={props.properties.minHeight}
|
||||
max={props.properties.maxHeight}
|
||||
value={(RemoveWidthMargin(props.properties.height, props.properties.margin.top, props.properties.margin.bottom)).toString()}
|
||||
onChange={(value) => props.onChange('height', ApplyWidthMargin(Number(value), props.properties.margin.top, props.properties.margin.bottom))}
|
||||
isDisabled={props.properties.isFlex}
|
||||
/>
|
||||
<TextInputGroup
|
||||
id={`${props.properties.id}-ml`}
|
||||
labelText='Margin left'
|
||||
|
@ -182,60 +226,33 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
min={0}
|
||||
value={(props.properties.margin.right ?? 0).toString()}
|
||||
onChange={(value) => props.onChange('right', Number(value), PropertyType.Margin)} />
|
||||
<InputGroup
|
||||
<ToggleButton
|
||||
labelText='Flex'
|
||||
inputKey='isFlex'
|
||||
labelClassName=''
|
||||
inputClassName=''
|
||||
type='checkbox'
|
||||
type={ToggleType.Full}
|
||||
checked={props.properties.isFlex}
|
||||
onChange={(event) => props.onChange('isFlex', event.target.checked)} />
|
||||
<InputGroup
|
||||
onChange={(event) => props.onChange('isFlex', event.target.checked)}
|
||||
/>
|
||||
<ToggleButton
|
||||
labelText='Anchor'
|
||||
inputKey='isAnchor'
|
||||
labelClassName=''
|
||||
inputClassName=''
|
||||
type='checkbox'
|
||||
type={ToggleType.Full}
|
||||
checked={props.properties.isAnchor}
|
||||
onChange={(event) => props.onChange('isAnchor', event.target.checked)} />
|
||||
<RadioGroupButtons
|
||||
name='XPositionReference'
|
||||
value={props.properties.xPositionReference.toString()}
|
||||
inputClassName='hidden'
|
||||
labelText='Horizontal alignment'
|
||||
inputGroups={[
|
||||
{
|
||||
text: (
|
||||
<div title='Left' aria-label='left' className='radio-button-icon'>
|
||||
<MenuAlt2Icon className='heroicon' />
|
||||
</div>
|
||||
),
|
||||
value: XPositionReference.Left.toString()
|
||||
},
|
||||
{
|
||||
text: (
|
||||
<div title='Center' aria-label='center' className='radio-button-icon'>
|
||||
<MenuIcon className='heroicon' />
|
||||
</div>
|
||||
),
|
||||
value: XPositionReference.Center.toString()
|
||||
},
|
||||
{
|
||||
text: (
|
||||
<div title='Right' aria-label='right' className='radio-button-icon'>
|
||||
<MenuAlt3Icon className='heroicon' />
|
||||
</div>
|
||||
),
|
||||
value: XPositionReference.Right.toString()
|
||||
}
|
||||
]}
|
||||
onChange={(event) => props.onChange('xPositionReference', Number(event.target.value))} />
|
||||
<AlignmentSelector
|
||||
{...props}
|
||||
/>
|
||||
<Select
|
||||
inputKey='linkedSymbolId'
|
||||
labelText='Align with symbol'
|
||||
labelClassName=''
|
||||
inputClassName=''
|
||||
inputs={[...props.symbols.values()].map(symbol => ({
|
||||
key: symbol.id,
|
||||
text: symbol.id,
|
||||
value: symbol.id
|
||||
}))}
|
||||
|
@ -244,43 +261,43 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
{GetCSSInputs(props.properties, props.onChange)}
|
||||
{
|
||||
SHOW_SELF_DIMENSIONS &&
|
||||
<InputGroup
|
||||
<ToggleButton
|
||||
labelText='Show dimension'
|
||||
inputKey='showSelfDimensions'
|
||||
labelClassName=''
|
||||
inputClassName=''
|
||||
type='checkbox'
|
||||
type={ToggleType.Full}
|
||||
checked={props.properties.showSelfDimensions}
|
||||
onChange={(event) => props.onChange('showSelfDimensions', event.target.checked)} />
|
||||
}
|
||||
{
|
||||
SHOW_CHILDREN_DIMENSIONS &&
|
||||
<InputGroup
|
||||
<ToggleButton
|
||||
labelText='Show overall dimension of its children'
|
||||
inputKey='showChildrenDimensions'
|
||||
labelClassName=''
|
||||
inputClassName=''
|
||||
type='checkbox'
|
||||
type={ToggleType.Full}
|
||||
checked={props.properties.showChildrenDimensions}
|
||||
onChange={(event) => props.onChange('showChildrenDimensions', event.target.checked)} />
|
||||
}
|
||||
{
|
||||
SHOW_BORROWER_DIMENSIONS &&
|
||||
<>
|
||||
<InputGroup
|
||||
<ToggleButton
|
||||
labelText='Mark the position'
|
||||
inputKey='markPositionToDimensionBorrower'
|
||||
labelClassName=''
|
||||
inputClassName=''
|
||||
type='checkbox'
|
||||
type={ToggleType.Full}
|
||||
checked={props.properties.markPositionToDimensionBorrower}
|
||||
onChange={(event) => props.onChange('markPositionToDimensionBorrower', event.target.checked)} />
|
||||
<InputGroup
|
||||
<ToggleButton
|
||||
labelText='Show dimension with marked children'
|
||||
inputKey='isDimensionBorrower'
|
||||
labelClassName=''
|
||||
inputClassName=''
|
||||
type='checkbox'
|
||||
type={ToggleType.Full}
|
||||
checked={props.properties.isDimensionBorrower}
|
||||
onChange={(event) => props.onChange('isDimensionBorrower', event.target.checked)} />
|
||||
</>
|
||||
|
@ -288,3 +305,135 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: Implement categories in the form
|
||||
|
||||
function OrientationSelector(props: IContainerFormProps): JSX.Element {
|
||||
return <RadioGroupButtons
|
||||
key='orientation'
|
||||
name='Orientation'
|
||||
value={props.properties.orientation.toString()}
|
||||
inputClassName='hidden'
|
||||
labelText='Orientation'
|
||||
colQty={2}
|
||||
inputGroups={[
|
||||
{
|
||||
key: 'orientation-horizontal',
|
||||
text: (
|
||||
<div title='Horizontal' aria-label='horizontal' className='radio-button-icon'>
|
||||
<ViewColumnsIcon className='heroicon' />
|
||||
</div>
|
||||
),
|
||||
value: Orientation.Horizontal.toString()
|
||||
},
|
||||
{
|
||||
key: 'orientation-vertical',
|
||||
text: (
|
||||
<div title='Vertical' aria-label='vertical' className='radio-button-icon'>
|
||||
<ViewColumnsIcon className='heroicon rotate-90' />
|
||||
</div>
|
||||
),
|
||||
value: Orientation.Vertical.toString()
|
||||
}
|
||||
]}
|
||||
onChange={(event) => {
|
||||
props.onChange('orientation', Number(event.target.value));
|
||||
}}
|
||||
/>;
|
||||
}
|
||||
|
||||
function AlignmentSelector(props: IContainerFormProps): JSX.Element {
|
||||
return <RadioGroupButtons
|
||||
key='positionReference'
|
||||
name='PositionReference'
|
||||
value={props.properties.positionReference.toString()}
|
||||
inputClassName='hidden'
|
||||
labelText='Alignment'
|
||||
colQty={3}
|
||||
inputGroups={[
|
||||
{
|
||||
key: 'position-reference-tl',
|
||||
text: (
|
||||
<div title='Top Left' aria-label='top left' className='radio-button-icon'>
|
||||
<Bars3BottomLeftIcon className='heroicon' />
|
||||
</div>
|
||||
),
|
||||
value: PositionReference.TopLeft.toString()
|
||||
},
|
||||
{
|
||||
key: 'position-reference-tc',
|
||||
text: (
|
||||
<div title='Top Center' aria-label='top center' className='radio-button-icon'>
|
||||
<Bars2Icon className='heroicon -scale-y-100' />
|
||||
</div>
|
||||
),
|
||||
value: PositionReference.TopCenter.toString()
|
||||
},
|
||||
{
|
||||
key: 'position-reference-tr',
|
||||
text: (
|
||||
<div title='Top Right' aria-label='top right' className='radio-button-icon'>
|
||||
<Bars3BottomRightIcon className='heroicon' />
|
||||
</div>
|
||||
),
|
||||
value: PositionReference.TopRight.toString()
|
||||
},
|
||||
{
|
||||
key: 'position-reference-cl',
|
||||
text: (
|
||||
<div title='Center Left' aria-label='center left' className='radio-button-icon'>
|
||||
<Bars3CenterLeftIcon className='heroicon' />
|
||||
</div>
|
||||
),
|
||||
value: PositionReference.CenterLeft.toString()
|
||||
},
|
||||
{
|
||||
key: 'position-reference-cc',
|
||||
text: (
|
||||
<div title='Center Center' aria-label='center center' className='radio-button-icon'>
|
||||
<Bars3Icon className='heroicon' />
|
||||
</div>
|
||||
),
|
||||
value: PositionReference.CenterCenter.toString()
|
||||
},
|
||||
{
|
||||
key: 'position-reference-cr',
|
||||
text: (
|
||||
<div title='Center Right' aria-label='center right' className='radio-button-icon'>
|
||||
<Bars3CenterLeftIcon className='heroicon -scale-x-100' />
|
||||
</div>
|
||||
),
|
||||
value: PositionReference.CenterRight.toString()
|
||||
},
|
||||
{
|
||||
key: 'position-reference-bl',
|
||||
text: (
|
||||
<div title='Bottom Left' aria-label='bottom left' className='radio-button-icon'>
|
||||
<Bars3BottomLeftIcon className='heroicon -scale-y-100' />
|
||||
</div>
|
||||
),
|
||||
value: PositionReference.BottomLeft.toString()
|
||||
},
|
||||
{
|
||||
key: 'position-reference-bc',
|
||||
text: (
|
||||
<div title='Bottom Center' aria-label='center center' className='radio-button-icon'>
|
||||
<Bars2Icon className='heroicon' />
|
||||
</div>
|
||||
),
|
||||
value: PositionReference.BottomCenter.toString()
|
||||
},
|
||||
{
|
||||
key: 'position-reference-br',
|
||||
text: (
|
||||
<div title='Bottom Right' aria-label='bottom right' className='radio-button-icon'>
|
||||
<Bars3BottomRightIcon className='heroicon -scale-y-100' />
|
||||
</div>
|
||||
),
|
||||
value: PositionReference.BottomRight.toString()
|
||||
}
|
||||
]}
|
||||
onChange={(event) => {
|
||||
props.onChange('positionReference', Number(event.target.value));
|
||||
}} />;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue