From ace6bcee5538354ec692676857eb16e0ba70c6a7 Mon Sep 17 00:00:00 2001 From: Leonardo Negreiros de Oliveira Date: Thu, 21 Sep 2023 12:07:08 -0300 Subject: [PATCH] Create ContentSidebar (#674) * Create Right Sidebar * Create responsive layout for sidebars * Remove width test from Sidebar.test.tsx This test doesn't fit well with RTL unit testing, this test case will be covered later by integration tests. * Rename RightSidebar to ContentSidebar * Add ScreenReaderOnly test * Center SkipNavigation link --- frontend/src/app/globals.css | 4 + frontend/src/app/layout.tsx | 4 + frontend/src/app/page.tsx | 2 +- .../src/ui/CollapseButton/CollapseButton.tsx | 35 ++++++++ .../__tests__/CollapseButton.test.tsx | 26 ++++++ .../src/ui/ContentSidebar/ContentSidebar.tsx | 41 ++++++++++ .../__tests__/ScreenReaderOnly.test.tsx | 10 +++ frontend/src/ui/Sidebar/DarkModeSwitch.tsx | 18 +++-- frontend/src/ui/Sidebar/Sidebar.tsx | 79 +++++++++++-------- .../src/ui/Sidebar/__tests__/Sidebar.test.tsx | 22 +----- .../src/ui/SkipNavigation/SkipNavigation.tsx | 10 ++- 11 files changed, 185 insertions(+), 66 deletions(-) create mode 100644 frontend/src/ui/CollapseButton/CollapseButton.tsx create mode 100644 frontend/src/ui/CollapseButton/__tests__/CollapseButton.test.tsx create mode 100644 frontend/src/ui/ContentSidebar/ContentSidebar.tsx create mode 100644 frontend/src/ui/ScreenReaderOnly/__tests__/ScreenReaderOnly.test.tsx diff --git a/frontend/src/app/globals.css b/frontend/src/app/globals.css index a69a5c7d2..5b1259509 100644 --- a/frontend/src/app/globals.css +++ b/frontend/src/app/globals.css @@ -94,6 +94,10 @@ body { rgb(var(--background-end-rgb)) ) rgb(var(--background-start-rgb)); + + @media (max-width: 600px) { + flex-direction: column; + } } a { diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index b311d121d..320a03938 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -3,6 +3,7 @@ import type { Metadata } from 'next' import localFont from 'next/font/local' import { AuthProvider } from '@/app/auth/AuthProvider' import { Sidebar } from '@/ui/Sidebar/Sidebar' +import { ContentSidebar } from '@/ui/ContentSidebar/ContentSidebar' import { CssVarsProvider } from '@mui/joy/styles' import { theme } from '@/ui/theme' import { Main, SkipNavigation } from '@/ui/SkipNavigation/SkipNavigation' @@ -28,6 +29,9 @@ export default function RootLayout({ children }: { children: React.ReactNode })
{children}
+ +
Right Sidebar
+
diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index 21199f4e8..5ae538f2e 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -3,7 +3,7 @@ import { AuthorizedPage } from '@/app/auth/AuthorizedPage' export default function Home() { return ( -
Testing auth
+
Testing auth
) } diff --git a/frontend/src/ui/CollapseButton/CollapseButton.tsx b/frontend/src/ui/CollapseButton/CollapseButton.tsx new file mode 100644 index 000000000..471f2d8c2 --- /dev/null +++ b/frontend/src/ui/CollapseButton/CollapseButton.tsx @@ -0,0 +1,35 @@ +import Button from '@mui/joy/Button' +import { ChevronRight16Filled } from '@fluentui/react-icons' +import { ScreenReaderOnly } from '@/ui/ScreenReaderOnly/ScreenReaderOnly' +import { SxProps } from '@mui/joy/styles/types' + +type CollapseButtonProps = { + onClick: () => void + sx: SxProps +} + +export const CollapseButton = ({ onClick, sx }: CollapseButtonProps) => { + return ( + + ) +} diff --git a/frontend/src/ui/CollapseButton/__tests__/CollapseButton.test.tsx b/frontend/src/ui/CollapseButton/__tests__/CollapseButton.test.tsx new file mode 100644 index 000000000..65667a727 --- /dev/null +++ b/frontend/src/ui/CollapseButton/__tests__/CollapseButton.test.tsx @@ -0,0 +1,26 @@ +import { render, screen, fireEvent } from '@/test-utils/test-utils' +import { CollapseButton } from '../CollapseButton' + +describe('CollapseButton', () => { + it('should have an invisible screen-reader text for the collapse button', () => { + render( {}} />) + + const collapseButton = screen.getByRole('button') + + expect(collapseButton).toHaveTextContent('Expand/collapse menu') + }) + + it('receives an sx to extend component style', () => { + render( {}} />) + const collapseButton = screen.getByRole('button') + expect(collapseButton).toHaveStyle({ top: '60px' }) + }) + + it('calls onClick prop when clicked', () => { + const onClick = jest.fn() + render() + const collapseButton = screen.getByRole('button') + fireEvent.click(collapseButton) + expect(onClick).toHaveBeenCalled() + }) +}) diff --git a/frontend/src/ui/ContentSidebar/ContentSidebar.tsx b/frontend/src/ui/ContentSidebar/ContentSidebar.tsx new file mode 100644 index 000000000..afabed2f0 --- /dev/null +++ b/frontend/src/ui/ContentSidebar/ContentSidebar.tsx @@ -0,0 +1,41 @@ +'use client' + +import { useState } from 'react' +import Box from '@mui/joy/Box' +import { CollapseButton } from '../CollapseButton/CollapseButton' + +type ContentSidebarProps = { + children: React.ReactNode +} + +export const ContentSidebar = ({ children }: ContentSidebarProps) => { + const [expanded, setExpanded] = useState(false) + + return ( + + setExpanded((prevState) => !prevState)} + /> + {children} + + ) +} diff --git a/frontend/src/ui/ScreenReaderOnly/__tests__/ScreenReaderOnly.test.tsx b/frontend/src/ui/ScreenReaderOnly/__tests__/ScreenReaderOnly.test.tsx new file mode 100644 index 000000000..42c71358b --- /dev/null +++ b/frontend/src/ui/ScreenReaderOnly/__tests__/ScreenReaderOnly.test.tsx @@ -0,0 +1,10 @@ +import { render, screen } from '@/test-utils/test-utils' +import { ScreenReaderOnly } from '../ScreenReaderOnly' + +describe('ScreenReaderOnly', () => { + it('renders the component with children', () => { + render(Test text) + + expect(screen.getByText('Test text')).toBeInTheDocument() + }) +}) diff --git a/frontend/src/ui/Sidebar/DarkModeSwitch.tsx b/frontend/src/ui/Sidebar/DarkModeSwitch.tsx index c54cb78eb..b59dfe89e 100644 --- a/frontend/src/ui/Sidebar/DarkModeSwitch.tsx +++ b/frontend/src/ui/Sidebar/DarkModeSwitch.tsx @@ -16,7 +16,7 @@ type SwitchComponentProps = { } const TrackText = ({ icon: Icon, children, sx }: SwitchComponentProps) => ( - + {children} @@ -36,7 +36,9 @@ const SwitchThumb = ({ icon: Icon, children }: SwitchComponentProps) => ( }} > - {children} + + {children} + ) @@ -69,12 +71,6 @@ export const DarkModeSwitch = ({ sx }: DarkModeSwitchProps) => { } }} sx={{ - '--Switch-thumbWidth': '148px', - '--Switch-thumbSize': '30px', - '--Switch-trackWidth': '260px', - '--Switch-thumbRadius': '20px', - '--Switch-trackHeight': '40px', - '--Switch-trackRadius': '25px', '--Switch-thumbBackground': '#00396d', '--Switch-trackBackground': '#030D1A', '&:hover': { @@ -87,6 +83,12 @@ export const DarkModeSwitch = ({ sx }: DarkModeSwitchProps) => { '--Switch-trackBackground': '#030D1A' } }, + '--Switch-thumbWidth': { xs: '40px', sm: '148px' }, + '--Switch-thumbSize': { xs: '20px', sm: '30px' }, + '--Switch-trackWidth': { xs: '60px', sm: '260px' }, + '--Switch-thumbRadius': { xs: '', sm: '20px' }, + '--Switch-trackHeight': { xs: '', sm: '40px' }, + '--Switch-trackRadius': { xs: '', sm: '25px' }, ...sx }} /> diff --git a/frontend/src/ui/Sidebar/Sidebar.tsx b/frontend/src/ui/Sidebar/Sidebar.tsx index 639eebede..c35afa72f 100644 --- a/frontend/src/ui/Sidebar/Sidebar.tsx +++ b/frontend/src/ui/Sidebar/Sidebar.tsx @@ -2,23 +2,21 @@ import { useState } from 'react' import Stack from '@mui/joy/Stack' -import Button from '@mui/joy/Button' import Typography from '@mui/joy/Typography' import Box from '@mui/joy/Box' import Image from 'next/image' import { - ChevronRight16Filled, TaskListSquareAdd24Filled, Beach24Filled, DataArea24Filled, DataPie24Filled } from '@fluentui/react-icons' -import smallLogo from '@/assets/images/small_logo.png' import fullLogo from '@/assets/images/full_logo.png' import { styled } from '@mui/joy/styles' import Link from 'next/link' import { DarkModeSwitch } from './DarkModeSwitch' -import { ScreenReaderOnly } from '@/ui/ScreenReaderOnly/ScreenReaderOnly' +import { CollapseButton } from '../CollapseButton/CollapseButton' +import { SxProps } from '@mui/joy/styles/types' export const Sidebar = () => { const [expanded, setExpanded] = useState(false) @@ -26,48 +24,38 @@ export const Sidebar = () => { return ( - - - + onClick={() => setExpanded((prevState) => !prevState)} + /> + + { - + ) } const Logo = styled(Image)` margin-bottom: 50px; + grid-area: 'logo'; + padding: 0 4px; ` const NavLink = styled(Link)` @@ -122,3 +114,22 @@ const NavLink = styled(Link)` gap: 30px; align-items: center; ` + +const navGridStyle: SxProps = { + overflow: 'hidden', + height: '100%', + display: 'grid', + gridTemplateAreas: { + xs: ` + 'logo switch' + 'nav nav'`, + sm: ` + 'logo' + 'nav' + 'switch' + ` + }, + gridTemplateRows: '32px 1fr', + gridTemplateColumns: '50%', + rowGap: '20px' +} diff --git a/frontend/src/ui/Sidebar/__tests__/Sidebar.test.tsx b/frontend/src/ui/Sidebar/__tests__/Sidebar.test.tsx index b76064cb4..2a70445b9 100644 --- a/frontend/src/ui/Sidebar/__tests__/Sidebar.test.tsx +++ b/frontend/src/ui/Sidebar/__tests__/Sidebar.test.tsx @@ -1,5 +1,5 @@ import { Sidebar } from '../Sidebar' -import { render, screen, fireEvent } from '@/test-utils/test-utils' +import { render, screen } from '@/test-utils/test-utils' describe('Sidebar', () => { it('renders the Igalia logo', () => { @@ -22,24 +22,4 @@ describe('Sidebar', () => { expect(screen.getByRole('checkbox')).toBeInTheDocument() }) - - it('expand and collapses', () => { - render() - - const expandButton = screen.getByRole('button') - - expect(screen.getByRole('complementary')).toHaveStyle({ width: '73px' }) - fireEvent.click(expandButton) - expect(screen.getByRole('complementary')).toHaveStyle({ width: '336px' }) - fireEvent.click(expandButton) - expect(screen.getByRole('complementary')).toHaveStyle({ width: '73px' }) - }) - - it('should have an invisible screen-reader text for the collapse button', () => { - render() - - const expandButton = screen.getByRole('button') - - expect(expandButton).toHaveTextContent('Expand/collapse menu') - }) }) diff --git a/frontend/src/ui/SkipNavigation/SkipNavigation.tsx b/frontend/src/ui/SkipNavigation/SkipNavigation.tsx index 620b609fe..0b9a38c1f 100644 --- a/frontend/src/ui/SkipNavigation/SkipNavigation.tsx +++ b/frontend/src/ui/SkipNavigation/SkipNavigation.tsx @@ -8,13 +8,19 @@ export const SkipNavigation = styled('a')` z-index: 1; &:focus { - right: 5px; + left: 0; + right: 0; top: 5px; - left: unset; + margin: 0 auto; + width: fit-content; } ` export const Main = styled('main')` + width: 100%; + height: 100%; + padding: 30px 0; + &:focus { outline: none; }