svg-layout-designer-react/src/Components/Sidebar/Sidebar.tsx
Eric Nguyen 18cbacaca1 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
2022-09-28 16:07:56 +00:00

122 lines
3.9 KiB
TypeScript

import { EyeIcon, EyeSlashIcon } from '@heroicons/react/24/outline';
import * as React from 'react';
import { IAvailableContainer } from '../../Interfaces/IAvailableContainer';
import { ICategory } from '../../Interfaces/ICategory';
import { IContainerModel } from '../../Interfaces/IContainerModel';
import { TruncateString } from '../../utils/stringtools';
import { Category } from '../Category/Category';
interface ISidebarProps {
selectedContainer: IContainerModel | undefined
componentOptions: IAvailableContainer[]
categories: ICategory[]
isOpen: boolean
buttonOnClick: (type: string) => void
}
function HandleDragStart(event: React.DragEvent<HTMLButtonElement>): void {
event.dataTransfer.setData('type', (event.target as HTMLButtonElement).id);
}
interface SidebarCategory {
category: ICategory
children: JSX.Element[]
}
export function Sidebar(props: ISidebarProps): JSX.Element {
const [hideDisabled, setHideDisabled] = React.useState<boolean>(false);
const rootElements: Array<JSX.Element | undefined> = [];
const categories = new Map<string, SidebarCategory>(props.categories.map(category => [
category.Type,
{
category,
children: []
}
]));
// build the categories (sorted with categories first)
categories.forEach((categoryWrapper, categoryName) => {
rootElements.push(
<Category
key={categoryName}
category={categoryWrapper.category}
>
{ categoryWrapper.children }
</Category>);
});
const selectedContainer = props.selectedContainer;
const config = props.componentOptions.find(option => option.Type === selectedContainer?.properties.type);
// build the components
props.componentOptions.forEach(componentOption => {
if (componentOption.IsHidden === true) {
return;
}
let disabled = false;
if (config?.Whitelist !== undefined) {
disabled = config.Whitelist?.find(type => type === componentOption.Type) === undefined;
} else if (config?.Blacklist !== undefined) {
disabled = config.Blacklist?.find(type => type === componentOption.Type) !== undefined ?? false;
}
if (disabled && hideDisabled) {
return;
}
const componentButton = (<button
key={componentOption.Type}
type="button"
className='w-full justify-center h-16 transition-all sidebar-component'
id={componentOption.Type}
title={componentOption.Type}
onClick={() => props.buttonOnClick(componentOption.Type)}
draggable={true}
onDragStart={(event) => HandleDragStart(event)}
disabled={disabled}
>
{TruncateString(componentOption.DisplayedText ?? componentOption.Type, 25)}
</button>);
if (componentOption.Category === null || componentOption.Category === undefined) {
rootElements.push(componentButton);
return;
}
const category = categories.get(componentOption.Category);
if (category === undefined) {
console.error(`[Category] Category does not exists in configuration.Categories: ${componentOption.Category}`);
return;
}
category.children.push(componentButton);
});
const isOpenClasses = props.isOpen ? 'left-16' : '-left-64';
return (
<div className={`fixed z-10 bg-slate-200
text-gray-700 transition-all h-full w-64
overflow-y-auto ${isOpenClasses}`}>
<div className='bg-slate-100 sidebar-title flex place-content-between'>
Components
<button
onClick={() => { setHideDisabled(!hideDisabled); }}
className='h-6'
aria-label='Hide disabled component'
title='Hide disabled component'
>
{
hideDisabled
? <EyeSlashIcon className='heroicon' />
: <EyeIcon className='heroicon' />
}
</button>
</div>
<div className='transition-all grid grid-cols-1 md:grid-cols-1 gap-2
m-2 md:text-xs font-bold'>
{rootElements}
</div>
</div>
);
};