diff --git a/frontend/src/component/ui/Drawer.scss b/frontend/src/component/ui/Drawer.scss new file mode 100644 index 000000000..508c8fca5 --- /dev/null +++ b/frontend/src/component/ui/Drawer.scss @@ -0,0 +1,14 @@ +@import '../styles/color'; +@import '../styles/easing'; + +$drawer-width: 240px; + +.drawer { + width: $drawer-width; + margin-left: -$drawer-width; + transition: margin-left 300ms $ease-in-out-quart; + + &.open { + margin-left: 0; + } +} diff --git a/frontend/src/component/ui/Drawer.spec.tsx b/frontend/src/component/ui/Drawer.spec.tsx new file mode 100644 index 000000000..a94f53ef8 --- /dev/null +++ b/frontend/src/component/ui/Drawer.spec.tsx @@ -0,0 +1,49 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import { Drawer } from './Drawer'; + +describe('Drawer component', () => { + test('should render without crash', () => { + render(); + }); + + test('should render in open state by default', () => { + const { container } = render(); + + const drawer = container.querySelector('.drawer'); + expect(drawer).toBeTruthy(); + expect(drawer!.className).toContain('open'); + }); + + test('should close the drawer when triggered to close', () => { + const drawerRef = React.createRef(); + const { container } = render(); + + const drawer = container.querySelector('.drawer'); + expect(drawer).toBeTruthy(); + expect(drawer!.className).toContain('open'); + + drawerRef.current!.close(); + expect(drawer!.className).not.toContain('open'); + }); + + test('should open the drawer when triggered to open', () => { + const drawerRef = React.createRef(); + const { container } = render(); + + const drawer = container.querySelector('.drawer'); + expect(drawer).toBeTruthy(); + drawerRef.current!.close(); + expect(drawer!.className).not.toContain('open'); + + drawerRef.current!.open(); + expect(drawer!.className).toContain('open'); + }); + + test('should render component children correctly', () => { + const childContent = 'children of drawer component'; + const { container } = render( {childContent} ); + + expect(container.textContent).toContain(childContent); + }); +}); diff --git a/frontend/src/component/ui/Drawer.tsx b/frontend/src/component/ui/Drawer.tsx new file mode 100644 index 000000000..a7d4046d7 --- /dev/null +++ b/frontend/src/component/ui/Drawer.tsx @@ -0,0 +1,41 @@ +import React, { Component } from 'react'; + +import './Drawer.scss'; +import classNames from 'classnames'; + +interface IProps {} + +interface IState { + isOpen: boolean; +} + +export class Drawer extends Component { + constructor(props: IProps) { + super(props); + this.state = { + isOpen: true + }; + } + + open() { + this.setState({ isOpen: true }); + } + + close() { + this.setState({ isOpen: false }); + } + + render() { + const isOpen = this.state.isOpen; + return ( +
+ {this.props.children} +
+ ); + } +}