Implement Category

This commit is contained in:
Siklos 2022-09-15 12:48:52 +02:00 committed by Eric Nguyen
parent 320d68e27f
commit 4f0a6795ad
5 changed files with 114 additions and 8 deletions

View file

@ -0,0 +1,60 @@
import { ChevronRightIcon } from '@heroicons/react/outline';
import React, { useState } from 'react';
import { TruncateString } from '../../utils/stringtools';
interface ICategoryProps {
children: JSX.Element | JSX.Element[]
category: string
}
export function Category(props: ICategoryProps): JSX.Element {
const [isOpen, setIsOpen] = useState(false);
if (isOpen) {
return (
<button type="button"
className='overflow-hidden h-full transition-all'
key={props.category}
id={props.category}
title={props.category}
>
<div
className='flex flex-row group full'
onClick={() => setIsOpen(!isOpen)}
>
<span className={'transition-all flex-1 h-full justify-center sidebar-component-left rounded-b-none bg-slate-400/60 group-hover:bg-blue-600'}>
{TruncateString(props.category, 25)}
</span>
<span className={'flex-none h-full justify-center sidebar-component-right rounded-b-none'}>
<ChevronRightIcon className='transition-all w-5 rotate-90' />
</span>
</div>
<div className='transition-all grid gap-2 p-2 bg-slate-400/60 overflow-auto rounded-b-lg visible'>
{ props.children }
</div>
</button>
);
}
return (
<button type="button"
className='overflow-visible h-16 group transition-all'
key={props.category}
id={props.category}
title={props.category}
onClick={() => setIsOpen(!isOpen)}
>
<div className='flex flex-row h-full'>
<span className='flex-1 h-full justify-center sidebar-component-left'>
{TruncateString(props.category, 25)}
</span>
<span className='flex-none h-full justify-center sidebar-component-right'>
<ChevronRightIcon className='transition-all w-5' />
</span>
</div>
<div className='transition-all overflow-hidden rounded-b-lg hidden'>
{ props.children }
</div>
</button>
);
}

View file

@ -1,6 +1,8 @@
import { ChevronRightIcon } from '@heroicons/react/outline';
import * as React from 'react'; import * as React from 'react';
import { IAvailableContainer } from '../../Interfaces/IAvailableContainer'; import { IAvailableContainer } from '../../Interfaces/IAvailableContainer';
import { TruncateString } from '../../utils/stringtools'; import { TruncateString } from '../../utils/stringtools';
import { Category } from '../Category/Category';
interface ISidebarProps { interface ISidebarProps {
componentOptions: IAvailableContainer[] componentOptions: IAvailableContainer[]
@ -13,10 +15,16 @@ function HandleDragStart(event: React.DragEvent<HTMLButtonElement>): void {
} }
export function Sidebar(props: ISidebarProps): JSX.Element { export function Sidebar(props: ISidebarProps): JSX.Element {
const listElements = props.componentOptions.map(componentOption => const rootElements: Array<JSX.Element | undefined> = [];
componentOption.IsHidden !== true && const categories = new Map<string, JSX.Element[]>();
<button type="button" // build the components
className='justify-center transition-all sidebar-component' props.componentOptions.forEach(componentOption => {
if (componentOption.IsHidden === true) {
return;
}
const componentButton = (<button type="button"
className='w-full justify-center h-16 transition-all sidebar-component'
key={componentOption.Type} key={componentOption.Type}
id={componentOption.Type} id={componentOption.Type}
title={componentOption.Type} title={componentOption.Type}
@ -25,8 +33,33 @@ export function Sidebar(props: ISidebarProps): JSX.Element {
onDragStart={(event) => HandleDragStart(event)} onDragStart={(event) => HandleDragStart(event)}
> >
{TruncateString(componentOption.Type, 25)} {TruncateString(componentOption.Type, 25)}
</button> </button>);
); if (componentOption.Category === null || componentOption.Category === undefined) {
rootElements.push(componentButton);
return;
}
if (categories.get(componentOption.Category) === undefined) {
categories.set(componentOption.Category, []);
}
const category = categories.get(componentOption.Category);
if (category === undefined) {
// should never go here
return;
}
category.push(componentButton);
});
// build the categories
categories.forEach((options, category) => {
rootElements.unshift(
<Category category={category}>
{ options }
</Category>);
});
const isOpenClasses = props.isOpen ? 'left-16' : '-left-64'; const isOpenClasses = props.isOpen ? 'left-16' : '-left-64';
return ( return (
@ -38,7 +71,7 @@ export function Sidebar(props: ISidebarProps): JSX.Element {
</div> </div>
<div className='grid grid-cols-1 md:grid-cols-1 gap-2 <div className='grid grid-cols-1 md:grid-cols-1 gap-2
m-2 md:text-xs font-bold'> m-2 md:text-xs font-bold'>
{listElements} {rootElements}
</div> </div>
</div> </div>
); );

View file

@ -10,6 +10,9 @@ export interface IAvailableContainer {
/** type */ /** type */
Type: string Type: string
/** category */
Category?: string
/** horizontal offset */ /** horizontal offset */
X?: number X?: number

View file

@ -11,6 +11,14 @@
@apply transition-all px-2 py-6 text-sm rounded-lg bg-slate-300/60 hover:bg-blue-500 hover:text-slate-50 @apply transition-all px-2 py-6 text-sm rounded-lg bg-slate-300/60 hover:bg-blue-500 hover:text-slate-50
} }
.sidebar-component-left {
@apply transition-all px-2 py-6 text-sm rounded-l-lg bg-slate-300/60 group-hover:bg-blue-500 group-hover:text-slate-50
}
.sidebar-component-right {
@apply transition-all px-2 py-6 text-sm rounded-r-lg bg-slate-400/60 group-hover:bg-blue-600 group-hover:text-slate-50
}
.sidebar-component-card { .sidebar-component-card {
@apply transition-all overflow-hidden text-sm rounded-lg bg-slate-300/60 hover:bg-slate-300 @apply transition-all overflow-hidden text-sm rounded-lg bg-slate-300/60 hover:bg-slate-300
} }

View file

@ -65,6 +65,7 @@ const GetSVGLayoutConfiguration = () => {
}, },
ShowSelfDimensions: true, ShowSelfDimensions: true,
IsDimensionBorrower: true, IsDimensionBorrower: true,
Category: "Category"
}, },
{ {
Type: 'Trou', Type: 'Trou',
@ -82,7 +83,8 @@ const GetSVGLayoutConfiguration = () => {
strokeWidth: 2, strokeWidth: 2,
stroke: 'green', stroke: 'green',
fill: 'white' fill: 'white'
} },
Category: "Category"
}, },
{ {
Type: 'Remplissage', Type: 'Remplissage',