From 7cc162c57c056cbe4840e73c0fcae32f50fefbf2 Mon Sep 17 00:00:00 2001 From: Elmar <102954831+elmar-vega@users.noreply.github.com> Date: Mon, 27 Jun 2022 16:55:51 +0100 Subject: [PATCH] Feat/525 update drawer (#611) * feat(console-lite): add nav icons * feat(console-lite): refactor resizing into reusable hook * feat(console-lite): refactor navigation drawer * feat(console-lite): add blue colour to theme-lite.js * feat(console-lite): remove liquidity from nav items * feat(console-lite): make style changes to navbar and add tab-bar for mobile * chore(console-lite): change div to aside * fix(console-lite): drawer left to right mode on mobile * fix(console-lite): add missing className prop to drawer-wrapper.tsx * feat(console-lite): add accessibility related changes * fix(console-lite): fix linting errors * fix(console-lite): fix failing test and add extra accessibility label * refactor(console-lite): refactor conditional classNames * refactor(console-lite): move useResize to react-helpers library * refactor(console-lite): refactor sun and moon classNames * fix(console-lite): fix broken e2e tests --- .../src/integration/market-list.test.ts | 5 +- apps/simple-trading-app/src/app/app.tsx | 19 +++-- .../components/drawer/drawer-container.tsx | 14 ---- .../app/components/drawer/drawer-content.tsx | 21 +++++ .../src/app/components/drawer/drawer-menu.tsx | 38 --------- .../app/components/drawer/drawer-toggle.tsx | 17 ++-- .../app/components/drawer/drawer-wrapper.tsx | 13 +++ .../src/app/components/drawer/drawer.tsx | 84 +++++++++---------- .../src/app/components/drawer/index.ts | 4 +- .../src/app/components/icons/icon.tsx | 51 +++++++++++ .../src/app/components/icons/index.tsx | 1 + .../app/components/icons/liquidity-icon.tsx | 15 ++++ .../src/app/components/icons/market-icon.tsx | 17 ++++ .../app/components/icons/portfolio-icon.tsx | 17 ++++ .../src/app/components/icons/trade-icon.tsx | 14 ++++ .../src/app/components/main/index.tsx | 41 +++------ .../src/app/components/nav/index.tsx | 2 + .../src/app/components/nav/nav-item.tsx | 16 ++++ .../src/app/components/nav/nav.tsx | 30 +++++++ .../src/app/components/nav/tab-bar.tsx | 15 ++++ .../src/app/routes/router-config.tsx | 17 +--- libs/react-helpers/src/hooks/index.ts | 1 + libs/react-helpers/src/hooks/use-resize.ts | 34 ++++++++ libs/tailwindcss-config/src/theme-lite.js | 1 + .../src/components/theme-switcher/icons.tsx | 25 ++++++ .../src/components/theme-switcher/index.tsx | 1 + .../theme-switcher/theme-switcher.tsx | 53 ++++++------ 27 files changed, 380 insertions(+), 186 deletions(-) delete mode 100644 apps/simple-trading-app/src/app/components/drawer/drawer-container.tsx create mode 100644 apps/simple-trading-app/src/app/components/drawer/drawer-content.tsx delete mode 100644 apps/simple-trading-app/src/app/components/drawer/drawer-menu.tsx create mode 100644 apps/simple-trading-app/src/app/components/drawer/drawer-wrapper.tsx create mode 100644 apps/simple-trading-app/src/app/components/icons/icon.tsx create mode 100644 apps/simple-trading-app/src/app/components/icons/index.tsx create mode 100644 apps/simple-trading-app/src/app/components/icons/liquidity-icon.tsx create mode 100644 apps/simple-trading-app/src/app/components/icons/market-icon.tsx create mode 100644 apps/simple-trading-app/src/app/components/icons/portfolio-icon.tsx create mode 100644 apps/simple-trading-app/src/app/components/icons/trade-icon.tsx create mode 100644 apps/simple-trading-app/src/app/components/nav/index.tsx create mode 100644 apps/simple-trading-app/src/app/components/nav/nav-item.tsx create mode 100644 apps/simple-trading-app/src/app/components/nav/nav.tsx create mode 100644 apps/simple-trading-app/src/app/components/nav/tab-bar.tsx create mode 100644 libs/react-helpers/src/hooks/use-resize.ts create mode 100644 libs/ui-toolkit/src/components/theme-switcher/icons.tsx diff --git a/apps/simple-trading-app-e2e/src/integration/market-list.test.ts b/apps/simple-trading-app-e2e/src/integration/market-list.test.ts index 0c965291c..08ed6f933 100644 --- a/apps/simple-trading-app-e2e/src/integration/market-list.test.ts +++ b/apps/simple-trading-app-e2e/src/integration/market-list.test.ts @@ -5,7 +5,10 @@ describe('market list', () => { }); it('selects menus', () => { - cy.get('.MuiDrawer-root [aria-current]').should('have.text', 'Markets'); + cy.get('[aria-label="Sidebar Navigation Menu"] [aria-current]').should( + 'have.text', + 'Markets' + ); cy.getByTestId('state-trigger').should('have.text', 'Active'); cy.get('[aria-label="Future"]').click(); cy.get('[data-testid="market-assets-menu"] a.active').should( diff --git a/apps/simple-trading-app/src/app/app.tsx b/apps/simple-trading-app/src/app/app.tsx index 10bbe605e..a4a53f682 100644 --- a/apps/simple-trading-app/src/app/app.tsx +++ b/apps/simple-trading-app/src/app/app.tsx @@ -40,13 +40,7 @@ function App() {
-
- - +
@@ -56,8 +50,17 @@ function App() { setVegaWallet((x) => ({ ...x, manage: open })) } /> - +
+
diff --git a/apps/simple-trading-app/src/app/components/drawer/drawer-container.tsx b/apps/simple-trading-app/src/app/components/drawer/drawer-container.tsx deleted file mode 100644 index 62922c51b..000000000 --- a/apps/simple-trading-app/src/app/components/drawer/drawer-container.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import * as React from 'react'; -import type { ReactElement } from 'react'; - -interface Props { - children: ReactElement | ReactElement[]; -} - -export const DrawerContainer = ({ children }: Props) => ( -
{children}
-); - -export const DrawerWrapper = ({ children }: Props) => ( -
{children}
-); diff --git a/apps/simple-trading-app/src/app/components/drawer/drawer-content.tsx b/apps/simple-trading-app/src/app/components/drawer/drawer-content.tsx new file mode 100644 index 000000000..060504fc3 --- /dev/null +++ b/apps/simple-trading-app/src/app/components/drawer/drawer-content.tsx @@ -0,0 +1,21 @@ +import * as React from 'react'; +import classNames from 'classnames'; +import type { ReactElement } from 'react'; + +interface Props { + children: ReactElement | ReactElement[]; + className?: string; +} + +export const DrawerContent = ({ children, className = '' }: Props) => { + const classes = classNames( + 'w-full sm:w-full grow-1 p-20 overflow-hidden', + className + ); + + return ( +
+ {children} +
+ ); +}; diff --git a/apps/simple-trading-app/src/app/components/drawer/drawer-menu.tsx b/apps/simple-trading-app/src/app/components/drawer/drawer-menu.tsx deleted file mode 100644 index 5ab061d33..000000000 --- a/apps/simple-trading-app/src/app/components/drawer/drawer-menu.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import * as React from 'react'; -import type { ReactElement } from 'react'; -import { Button } from '@vegaprotocol/ui-toolkit'; -import type { ButtonProps } from '@vegaprotocol/ui-toolkit'; - -type MenuItem = { - label: string; - component: ReactElement | ReactElement[]; - onClick(): void; - active: boolean; -}; - -interface Props { - /** - * Menu items passed as an array - */ - menuItems: MenuItem[]; -} - -export const NavigationDrawerMenu = ({ menuItems }: Props) => { - return ( -
    - {menuItems.map((item, index) => { - const btnProps = { - variant: item.active ? 'accent' : 'primary', - className: 'w-full mb-8', - onClick: item.onClick, - } as ButtonProps; - - return ( -
  • - -
  • - ); - })} -
- ); -}; diff --git a/apps/simple-trading-app/src/app/components/drawer/drawer-toggle.tsx b/apps/simple-trading-app/src/app/components/drawer/drawer-toggle.tsx index aec0e1c18..777ebdab5 100644 --- a/apps/simple-trading-app/src/app/components/drawer/drawer-toggle.tsx +++ b/apps/simple-trading-app/src/app/components/drawer/drawer-toggle.tsx @@ -19,12 +19,10 @@ interface Props { export const DrawerToggle = ({ onToggle, variant = DRAWER_TOGGLE_VARIANTS.CLOSE, - className, + className = '', }: Props) => { const [iconName, setIconName] = useState(IconNames.MENU); - const classes = classNames('md:hidden', { - [className as string]: className, - }); + const classes = classNames('md:hidden', className); useEffect(() => { if (variant === DRAWER_TOGGLE_VARIANTS.OPEN) { @@ -34,8 +32,17 @@ export const DrawerToggle = ({ } }, [variant]); + const ariaLabel = `${ + variant === DRAWER_TOGGLE_VARIANTS.OPEN ? 'Open' : 'Close' + } Sidebar Navigation Menu`; + return ( - ); diff --git a/apps/simple-trading-app/src/app/components/drawer/drawer-wrapper.tsx b/apps/simple-trading-app/src/app/components/drawer/drawer-wrapper.tsx new file mode 100644 index 000000000..b689e630e --- /dev/null +++ b/apps/simple-trading-app/src/app/components/drawer/drawer-wrapper.tsx @@ -0,0 +1,13 @@ +import * as React from 'react'; +import classNames from 'classnames'; +import type { ReactElement } from 'react'; + +interface Props { + children: ReactElement | ReactElement[]; + className?: string; +} + +export const DrawerWrapper = ({ children, className = '' }: Props) => { + const classes = classNames('flex dark:bg-black md:flex-row', className); + return
{children}
; +}; diff --git a/apps/simple-trading-app/src/app/components/drawer/drawer.tsx b/apps/simple-trading-app/src/app/components/drawer/drawer.tsx index 552098b4b..128259e32 100644 --- a/apps/simple-trading-app/src/app/components/drawer/drawer.tsx +++ b/apps/simple-trading-app/src/app/components/drawer/drawer.tsx @@ -1,66 +1,60 @@ import * as React from 'react'; -import { themelite as theme } from '@vegaprotocol/tailwindcss-config'; +import classNames from 'classnames'; import type { ReactElement } from 'react'; -import { useEffect } from 'react'; -import Drawer from '@mui/material/Drawer'; interface Props { children?: ReactElement | ReactElement[]; isMenuOpen?: boolean; onToggle(): void; + rtl?: boolean; + outerClasses?: string; + innerClasses?: string; } export const NavigationDrawer = ({ isMenuOpen = false, onToggle, children, + rtl, + outerClasses = '', + innerClasses = '', }: Props) => { - const [windowSize, setWindowSize] = React.useState({ - width: window.innerWidth, - height: window.innerHeight, + const width = 'w-full md:w-auto md:min-w-[15%] shrink-0'; + const position = 'absolute inset-0 h-full z-10 md:static'; + const background = 'bg-black/50 dark:bg-white/50'; + const flex = 'flex justify-end overflow-hidden'; + const joinedClasses = [flex, width, position, background].join(' '); + + const outerStyles = classNames(joinedClasses, { + visible: isMenuOpen, + 'invisible md:visible': !isMenuOpen, + 'flex-row-reverse': !rtl, + [outerClasses]: outerClasses, }); - const mobileScreenWidth = parseInt(theme.screens.md); - const isMobile = windowSize.width <= mobileScreenWidth; - const timeout = React.useRef(0); - const handleResize = () => { - if (timeout.current) { - window.cancelAnimationFrame(timeout.current); - } + const translateClose = rtl ? 'translate-x-full' : '-translate-x-full'; - // Setup the new requestAnimationFrame() - timeout.current = window.requestAnimationFrame(function () { - setWindowSize({ - width: window.innerWidth, - height: window.innerHeight, - }); - }); - }; - - useEffect(() => { - window.addEventListener('resize', handleResize); - return () => { - window.removeEventListener('resize', handleResize); - window.cancelAnimationFrame(timeout.current); - }; - }, []); - - const drawerRootClasses = { - root: 'w-3/4 md:w-1/4 shrink-0', - paper: 'p-16 w-3/4 md:w-1/4 box-border', - }; + const innerStyles = classNames('w-3/4 md:w-full bg-white dark:bg-black', { + 'translate-x-0 transition-transform md:transform-none': isMenuOpen, + [`${translateClose} md:transform-none`]: !isMenuOpen, + [innerClasses]: innerClasses, + }); return ( - - {children} - + ); }; diff --git a/apps/simple-trading-app/src/app/components/drawer/index.ts b/apps/simple-trading-app/src/app/components/drawer/index.ts index 276f51c6c..1fd661bcf 100644 --- a/apps/simple-trading-app/src/app/components/drawer/index.ts +++ b/apps/simple-trading-app/src/app/components/drawer/index.ts @@ -1,4 +1,4 @@ export * from './drawer'; -export * from './drawer-menu'; export * from './drawer-toggle'; -export * from './drawer-container'; +export * from './drawer-content'; +export * from './drawer-wrapper'; diff --git a/apps/simple-trading-app/src/app/components/icons/icon.tsx b/apps/simple-trading-app/src/app/components/icons/icon.tsx new file mode 100644 index 000000000..24dc1c9a0 --- /dev/null +++ b/apps/simple-trading-app/src/app/components/icons/icon.tsx @@ -0,0 +1,51 @@ +import type { ReactElement } from 'react'; +import { LiquidityIconPath } from './liquidity-icon'; +import { MarketIconPath } from './market-icon'; +import { TradeIconPath } from './trade-icon'; +import { PortfolioIconPath } from './portfolio-icon'; + +interface IconProps { + name: string; + className: string; +} + +interface IconSVGWrapperProps { + className: string; + children: ReactElement | ReactElement[] | null; +} + +const getIconPath = (name: string): ReactElement | null => { + switch (name) { + case 'liquidity': + return ; + case 'market': + return ; + case 'trade': + return ; + case 'portfolio': + return ; + default: + return null; + } +}; + +const IconSVGWrapper = ({ className, children }: IconSVGWrapperProps) => { + return ( + + {children} + + ); +}; + +export const Icon = ({ name, className }: IconProps) => { + return ( + {getIconPath(name)} + ); +}; diff --git a/apps/simple-trading-app/src/app/components/icons/index.tsx b/apps/simple-trading-app/src/app/components/icons/index.tsx new file mode 100644 index 000000000..af77d84ef --- /dev/null +++ b/apps/simple-trading-app/src/app/components/icons/index.tsx @@ -0,0 +1 @@ +export * from './icon'; diff --git a/apps/simple-trading-app/src/app/components/icons/liquidity-icon.tsx b/apps/simple-trading-app/src/app/components/icons/liquidity-icon.tsx new file mode 100644 index 000000000..cd4be2d4e --- /dev/null +++ b/apps/simple-trading-app/src/app/components/icons/liquidity-icon.tsx @@ -0,0 +1,15 @@ +export const LiquidityIconPath = () => ( + <> + + + + + + + + +); diff --git a/apps/simple-trading-app/src/app/components/icons/market-icon.tsx b/apps/simple-trading-app/src/app/components/icons/market-icon.tsx new file mode 100644 index 000000000..e9e27aec4 --- /dev/null +++ b/apps/simple-trading-app/src/app/components/icons/market-icon.tsx @@ -0,0 +1,17 @@ +export const MarketIconPath = () => ( + <> + + + + + + + + + + +); diff --git a/apps/simple-trading-app/src/app/components/icons/portfolio-icon.tsx b/apps/simple-trading-app/src/app/components/icons/portfolio-icon.tsx new file mode 100644 index 000000000..91ddcd8c5 --- /dev/null +++ b/apps/simple-trading-app/src/app/components/icons/portfolio-icon.tsx @@ -0,0 +1,17 @@ +export const PortfolioIconPath = () => ( + <> + + + + + + + + + + +); diff --git a/apps/simple-trading-app/src/app/components/icons/trade-icon.tsx b/apps/simple-trading-app/src/app/components/icons/trade-icon.tsx new file mode 100644 index 000000000..f4938d4f3 --- /dev/null +++ b/apps/simple-trading-app/src/app/components/icons/trade-icon.tsx @@ -0,0 +1,14 @@ +export const TradeIconPath = () => ( + <> + + + +); diff --git a/apps/simple-trading-app/src/app/components/main/index.tsx b/apps/simple-trading-app/src/app/components/main/index.tsx index 3515d6dd3..5c80a1d6f 100644 --- a/apps/simple-trading-app/src/app/components/main/index.tsx +++ b/apps/simple-trading-app/src/app/components/main/index.tsx @@ -1,62 +1,41 @@ import React from 'react'; -import { useRoutes, NavLink } from 'react-router-dom'; +import { useRoutes } from 'react-router-dom'; import { NavigationDrawer, DrawerWrapper, - DrawerContainer, + DrawerContent, DrawerToggle, DRAWER_TOGGLE_VARIANTS, } from '../drawer'; +import { Nav, TabBar } from '../nav'; import { routerConfig } from '../../routes/router-config'; export interface RouteChildProps { name: string; } -export const AppRouter = () => { - const routes = useRoutes(routerConfig); - - return
{routes}
; -}; - -export const Menu = () => ( - -); +export const AppRouter = () => useRoutes(routerConfig); interface Props { onToggle(): void; - isMenuOpen: boolean; } export const Main = ({ onToggle, isMenuOpen }: Props) => { return ( - + - +