diff --git a/src/Components/Bar/Bar.tsx b/src/Components/Bar/Bar.tsx new file mode 100644 index 0000000..1738a3f --- /dev/null +++ b/src/Components/Bar/Bar.tsx @@ -0,0 +1,39 @@ +import { ClockIcon, CubeIcon, MapIcon } from '@heroicons/react/outline'; +import * as React from 'react'; +import { BarIcon } from './BarIcon'; + +interface IBarProps { + isSidebarOpen: boolean + isElementsSidebarOpen: boolean + isHistoryOpen: boolean + ToggleSidebar: () => void + ToggleElementsSidebar: () => void + ToggleTimeline: () => void +} + +export const BAR_WIDTH = 64; // 4rem + +export const Bar: React.FC = (props) => { + return ( +
+ props.ToggleSidebar()}> + + + props.ToggleElementsSidebar()}> + + + props.ToggleTimeline()}> + + +
+ ); +}; diff --git a/src/Components/Bar/BarIcon.tsx b/src/Components/Bar/BarIcon.tsx new file mode 100644 index 0000000..5afaae7 --- /dev/null +++ b/src/Components/Bar/BarIcon.tsx @@ -0,0 +1,22 @@ +import * as React from 'react'; + +interface IBarIconProps { + title: string + children: React.ReactElement + isActive: boolean + onClick: () => void +} + +export const BarIcon: React.FC = (props) => { + const isActiveClasses = props.isActive ? 'border-l-4 border-blue-500 bg-slate-200' : ''; + return ( + + ); +}; diff --git a/src/Components/ElementsSidebar/ElementsSidebar.test.tsx b/src/Components/ElementsSidebar/ElementsSidebar.test.tsx index d52fe97..2dd5080 100644 --- a/src/Components/ElementsSidebar/ElementsSidebar.test.tsx +++ b/src/Components/ElementsSidebar/ElementsSidebar.test.tsx @@ -1,4 +1,4 @@ -import { describe, test, expect, vi } from 'vitest'; +import { describe, expect, vi } from 'vitest'; import * as React from 'react'; import { fireEvent, render, screen } from '../../utils/test-utils'; import { ElementsSidebar } from './ElementsSidebar'; @@ -11,7 +11,6 @@ describe.concurrent('Elements sidebar', () => { isOpen={true} isHistoryOpen={false} SelectedContainer={null} - onClick={() => {}} onPropertyChange={() => {}} selectContainer={() => {}} />); @@ -39,7 +38,6 @@ describe.concurrent('Elements sidebar', () => { isOpen={true} isHistoryOpen={false} SelectedContainer={null} - onClick={() => {}} onPropertyChange={() => {}} selectContainer={() => {}} />); @@ -69,7 +67,6 @@ describe.concurrent('Elements sidebar', () => { isOpen={true} isHistoryOpen={false} SelectedContainer={MainContainer} - onClick={() => {}} onPropertyChange={() => {}} selectContainer={() => {}} />); @@ -154,7 +151,6 @@ describe.concurrent('Elements sidebar', () => { isOpen={true} isHistoryOpen={false} SelectedContainer={MainContainer} - onClick={() => {}} onPropertyChange={() => {}} selectContainer={() => {}} />); @@ -207,7 +203,6 @@ describe.concurrent('Elements sidebar', () => { isOpen={true} isHistoryOpen={false} SelectedContainer={SelectedContainer} - onClick={() => {}} onPropertyChange={() => {}} selectContainer={selectContainer} />); @@ -229,7 +224,6 @@ describe.concurrent('Elements sidebar', () => { isOpen={true} isHistoryOpen={false} SelectedContainer={SelectedContainer} - onClick={() => {}} onPropertyChange={() => {}} selectContainer={selectContainer} />); diff --git a/src/Components/ElementsSidebar/ElementsSidebar.tsx b/src/Components/ElementsSidebar/ElementsSidebar.tsx index caa6081..bbbcba5 100644 --- a/src/Components/ElementsSidebar/ElementsSidebar.tsx +++ b/src/Components/ElementsSidebar/ElementsSidebar.tsx @@ -9,7 +9,6 @@ interface IElementsSidebarProps { isOpen: boolean isHistoryOpen: boolean SelectedContainer: IContainerModel | null - onClick: () => void onPropertyChange: (key: string, value: string) => void selectContainer: (container: IContainerModel) => void } @@ -42,8 +41,8 @@ export class ElementsSidebar extends React.PureComponent const selectedClass: string = this.props.SelectedContainer !== undefined && this.props.SelectedContainer !== null && this.props.SelectedContainer.properties.id === container.properties.id - ? 'bg-blue-500 hover:bg-blue-600' - : 'bg-slate-400 hover:bg-slate-600'; + ? 'border-l-4 border-blue-500 bg-slate-400/60 hover:bg-slate-400' + : 'bg-slate-300/60 hover:bg-slate-300'; containerRows.push( }); return ( -
- -
+
+
Elements
-
+
{ containerRows }
diff --git a/src/Components/FloatingButton/FloatingButton.tsx b/src/Components/FloatingButton/FloatingButton.tsx index 3145f45..d55f01b 100644 --- a/src/Components/FloatingButton/FloatingButton.tsx +++ b/src/Components/FloatingButton/FloatingButton.tsx @@ -21,7 +21,7 @@ const FloatingButton: React.FC = (props: IFloatingButtonPr : ; return ( -
+
{ props.children }
diff --git a/src/Components/History/History.tsx b/src/Components/History/History.tsx index 7487de1..c01298d 100644 --- a/src/Components/History/History.tsx +++ b/src/Components/History/History.tsx @@ -5,7 +5,6 @@ interface IHistoryProps { history: IHistoryState[] historyCurrentStep: number isOpen: boolean - onClick: () => void jumpTo: (move: number) => void } @@ -46,12 +45,9 @@ export class History extends React.PureComponent { states.reverse(); return ( -
- -
- History +
+
+ Timeline
{ states } diff --git a/src/Components/Properties/Properties.tsx b/src/Components/Properties/Properties.tsx index 0d30d3d..adcebe6 100644 --- a/src/Components/Properties/Properties.tsx +++ b/src/Components/Properties/Properties.tsx @@ -18,7 +18,7 @@ export class Properties extends React.PureComponent { .forEach((pair) => this.handleProperties(pair, groupInput)); return ( -
+
{ groupInput }
); @@ -33,12 +33,12 @@ export class Properties extends React.PureComponent { const isDisabled = key === 'id' || key === 'parentId'; // hardcoded groupInput.push(
- + { @@ -23,14 +24,14 @@ export class SVG extends React.PureComponent { constructor(props: ISVGProps) { super(props); this.state = { - viewerWidth: window.innerWidth, + viewerWidth: window.innerWidth - BAR_WIDTH, viewerHeight: window.innerHeight }; } resizeViewBox(): void { this.setState({ - viewerWidth: window.innerWidth, + viewerWidth: window.innerWidth - BAR_WIDTH, viewerHeight: window.innerHeight }); } @@ -60,7 +61,7 @@ export class SVG extends React.PureComponent { } return ( -
+
{ miniatureProps={{ position: 'left', background: '#616264', - width: window.innerWidth - 12, + width: window.innerWidth - 12 - BAR_WIDTH, height: 120 }} > diff --git a/src/Components/Sidebar/Sidebar.test.tsx b/src/Components/Sidebar/Sidebar.test.tsx index 8f283eb..0810741 100644 --- a/src/Components/Sidebar/Sidebar.test.tsx +++ b/src/Components/Sidebar/Sidebar.test.tsx @@ -5,29 +5,23 @@ import Sidebar from './Sidebar'; describe.concurrent('Sidebar', () => { it('Start default', () => { - const handleClick = vi.fn(); render( {}} /> ); const stuff = screen.queryByText(/stuff/i); - const close = screen.getByText(/close/i); expect(screen.getByText(/Components/i).classList.contains('left-0')).toBeDefined(); expect(stuff).toBeNull(); - fireEvent.click(close); - expect(handleClick).toHaveBeenCalledTimes(1); }); it('Start close', () => { render( {}} buttonOnClick={() => {}} />); @@ -49,7 +43,6 @@ describe.concurrent('Sidebar', () => { } ]} isOpen={true} - onClick={() => {}} buttonOnClick={handleButtonClick} />); const stuff = screen.getByText(/stuff/i); diff --git a/src/Components/Sidebar/Sidebar.tsx b/src/Components/Sidebar/Sidebar.tsx index b474cc9..c50730e 100644 --- a/src/Components/Sidebar/Sidebar.tsx +++ b/src/Components/Sidebar/Sidebar.tsx @@ -1,31 +1,38 @@ import * as React from 'react'; import { AvailableContainer } from '../../Interfaces/AvailableContainer'; +import { truncateString } from '../../utils/stringtools'; interface ISidebarProps { componentOptions: AvailableContainer[] isOpen: boolean - onClick: () => void buttonOnClick: (type: string) => void } export default class Sidebar extends React.PureComponent { public render(): JSX.Element { const listElements = this.props.componentOptions.map(componentOption => - ); - const isOpenClasses = this.props.isOpen ? 'left-0' : '-left-64'; + const isOpenClasses = this.props.isOpen ? 'left-16' : '-left-64'; return ( -
- -
+
+
Components
- {listElements} +
+ {listElements} +
); } diff --git a/src/Components/UI/UI.tsx b/src/Components/UI/UI.tsx index 7748c67..37420bd 100644 --- a/src/Components/UI/UI.tsx +++ b/src/Components/UI/UI.tsx @@ -7,6 +7,7 @@ import { ContainerModel } from '../../Interfaces/ContainerModel'; import { IHistoryState } from '../../App'; import { PhotographIcon, UploadIcon } from '@heroicons/react/outline'; import FloatingButton from '../FloatingButton/FloatingButton'; +import { Bar } from '../Bar/Bar'; interface IUIProps { current: IHistoryState @@ -58,7 +59,7 @@ export class UI extends React.PureComponent { /** * Toggle the elements */ - public ToggleHistory(): void { + public ToggleTimeline(): void { this.setState({ isHistoryOpen: !this.state.isHistoryOpen }); @@ -75,47 +76,34 @@ export class UI extends React.PureComponent { return ( <> + this.ToggleElementsSidebar()} + ToggleSidebar={() => this.ToggleSidebar()} + ToggleTimeline={() => this.ToggleTimeline()} + /> + this.ToggleSidebar()} buttonOnClick={(type: string) => this.props.AddContainer(type)} /> - - this.ToggleElementsSidebar()} onPropertyChange={this.props.OnPropertyChange} selectContainer={this.props.SelectContainer} /> - - this.ToggleHistory()} jumpTo={this.props.LoadState} /> - diff --git a/src/assets/fonts/RobotoFlex-Regular.ttf b/src/assets/fonts/RobotoFlex-Regular.ttf new file mode 100644 index 0000000..f857ae9 Binary files /dev/null and b/src/assets/fonts/RobotoFlex-Regular.ttf differ diff --git a/src/index.scss b/src/index.scss index ad410c8..6b98e1e 100644 --- a/src/index.scss +++ b/src/index.scss @@ -3,19 +3,45 @@ @tailwind utilities; @layer components { - .sidebar-row { - @apply p-6 w-full + .sidebar-title { + @apply p-6 font-bold } + + .sidebar-component { + @apply transition-all px-2 py-6 text-sm rounded-lg bg-slate-300/60 hover:bg-slate-300 + } + .elements-sidebar-row { @apply pl-6 pr-6 pt-2 pb-2 w-full } + .close-button { @apply transition-all w-full h-auto p-4 flex } + .mainmenu-btn { @apply transition-all bg-blue-100 hover:bg-blue-200 text-blue-700 text-lg font-semibold p-8 rounded-lg } + .floating-btn { @apply h-full w-full text-white align-middle items-center justify-center } + + .bar-btn { + @apply h-16 w-full p-3 bg-slate-100 hover:bg-slate-200 + transition-all text-gray-700 hover:text-gray-600 + } + + .heroicon { + @apply h-full w-full align-middle items-center justify-center + } + + .sidebar-tooltip { + @apply absolute w-auto p-2 m-2 min-w-max left-14 + rounded-md shadow-md + text-gray-800 bg-slate-100 + dark:text-white dark:bg-gray-800 + text-xs font-bold + transition-all duration-100 scale-0 origin-left; + } } \ No newline at end of file diff --git a/src/utils/stringtools.ts b/src/utils/stringtools.ts new file mode 100644 index 0000000..349e34a --- /dev/null +++ b/src/utils/stringtools.ts @@ -0,0 +1,6 @@ +export function truncateString(str: string, num: number): string { + if (str.length <= num) { + return str; + } + return `${str.slice(0, num)}...`; +}