From c6a25f741f99e6a3fc88ed5589a9690e9175f99f Mon Sep 17 00:00:00 2001 From: Sauli Anto Date: Mon, 20 Jan 2025 09:04:39 +0200 Subject: [PATCH] OPHJOD-1194: Add NavigationBar and logos --- lib/components/Footer/Footer.stories.tsx | 2 +- lib/components/Logo/LogoArrow.tsx | 41 +++++ lib/components/Logo/LogoEn.tsx | 94 +++++++++++ lib/components/Logo/LogoFi.tsx | 148 ++++++++++++++++++ lib/components/Logo/LogoIcon.tsx | 76 +++++++++ lib/components/Logo/LogoSv.tsx | 94 +++++++++++ lib/components/Logo/types.d.ts | 3 + .../NavigationBar/NavigationBar.stories.tsx | 45 ++++++ .../NavigationBar/NavigationBar.test.tsx | 31 ++++ .../NavigationBar/NavigationBar.tsx | 90 +++++++++++ .../__snapshots__/NavigationBar.test.tsx.snap | 78 +++++++++ lib/main.ts | 13 ++ 12 files changed, 714 insertions(+), 1 deletion(-) create mode 100644 lib/components/Logo/LogoArrow.tsx create mode 100644 lib/components/Logo/LogoEn.tsx create mode 100644 lib/components/Logo/LogoFi.tsx create mode 100644 lib/components/Logo/LogoIcon.tsx create mode 100644 lib/components/Logo/LogoSv.tsx create mode 100644 lib/components/Logo/types.d.ts create mode 100644 lib/components/NavigationBar/NavigationBar.stories.tsx create mode 100644 lib/components/NavigationBar/NavigationBar.test.tsx create mode 100644 lib/components/NavigationBar/NavigationBar.tsx create mode 100644 lib/components/NavigationBar/__snapshots__/NavigationBar.test.tsx.snap diff --git a/lib/components/Footer/Footer.stories.tsx b/lib/components/Footer/Footer.stories.tsx index 41bbb52..2e2a5ae 100644 --- a/lib/components/Footer/Footer.stories.tsx +++ b/lib/components/Footer/Footer.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Footer, type FooterProps } from './Footer'; const meta = { - title: 'Footer', + title: 'Layout/Footer', component: Footer, tags: ['autodocs'], } satisfies Meta; diff --git a/lib/components/Logo/LogoArrow.tsx b/lib/components/Logo/LogoArrow.tsx new file mode 100644 index 0000000..9817a00 --- /dev/null +++ b/lib/components/Logo/LogoArrow.tsx @@ -0,0 +1,41 @@ +import { LogoProps } from './types'; + +interface LogoArrowProps extends LogoProps { + fill: string; +} + +const Arrow = ({ size, fill }: LogoArrowProps) => ( + + + + + + + + + +); + +export const LogoArrowBlack = ({ size }: LogoArrowProps) => { + return ; +}; + +export const LogoArrowOrange = ({ size }: LogoArrowProps) => { + return ; +}; + +export const LogoArrowPink = ({ size }: LogoArrowProps) => { + return ; +}; + +export const LogoArrowBlue = ({ size }: LogoArrowProps) => { + return ; +}; + +export const LogoArrowTurquoise = ({ size }: LogoArrowProps) => { + return ; +}; + +export const LogoArrowWhite = ({ size }: LogoArrowProps) => { + return ; +}; diff --git a/lib/components/Logo/LogoEn.tsx b/lib/components/Logo/LogoEn.tsx new file mode 100644 index 0000000..c20d7a7 --- /dev/null +++ b/lib/components/Logo/LogoEn.tsx @@ -0,0 +1,94 @@ +import { LogoProps } from './types'; + +export const LogoBlackEn = ({ size }: LogoProps) => ( + + + + + + + + + + + + + + + + + + + + +); + +export const LogoRgbEn = ({ size }: LogoProps) => ( + + + + + + + + + + + + + + + + + + + + +); + +export const LogoWhiteEn = ({ size }: LogoProps) => ( + + + + + + + + + + + + + + + + + + + + +); diff --git a/lib/components/Logo/LogoFi.tsx b/lib/components/Logo/LogoFi.tsx new file mode 100644 index 0000000..3e90ec9 --- /dev/null +++ b/lib/components/Logo/LogoFi.tsx @@ -0,0 +1,148 @@ +import { LogoProps } from './types'; + +export const LogoBlackFi = ({ size }: LogoProps) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +export const LogoRgbFi = ({ size }: LogoProps) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +export const LogoWhiteFi = ({ size }: LogoProps) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); diff --git a/lib/components/Logo/LogoIcon.tsx b/lib/components/Logo/LogoIcon.tsx new file mode 100644 index 0000000..23d805f --- /dev/null +++ b/lib/components/Logo/LogoIcon.tsx @@ -0,0 +1,76 @@ +import { LogoProps } from './types'; + +export const LogoIconBlack = ({ size }: LogoProps) => ( + + + + + + + + + + + + + + + +); + +export const LogoIconRgb = ({ size }: LogoProps) => ( + + + + + + + + + + + + + + + +); + +export const LogoIconWhite = ({ size }: LogoProps) => ( + + + + + + + + + + + + + + + +); diff --git a/lib/components/Logo/LogoSv.tsx b/lib/components/Logo/LogoSv.tsx new file mode 100644 index 0000000..f040682 --- /dev/null +++ b/lib/components/Logo/LogoSv.tsx @@ -0,0 +1,94 @@ +import { LogoProps } from './types'; + +export const LogoBlackSv = ({ size }: LogoProps) => ( + + + + + + + + + + + + + + + + + + + + +); + +export const LogoRgbSv = ({ size }: LogoProps) => ( + + + + + + + + + + + + + + + + + + + + +); + +export const LogoWhiteSv = ({ size }: LogoProps) => ( + + + + + + + + + + + + + + + + + + + + +); diff --git a/lib/components/Logo/types.d.ts b/lib/components/Logo/types.d.ts new file mode 100644 index 0000000..9c9fe1f --- /dev/null +++ b/lib/components/Logo/types.d.ts @@ -0,0 +1,3 @@ +export interface LogoProps { + size: number; +} diff --git a/lib/components/NavigationBar/NavigationBar.stories.tsx b/lib/components/NavigationBar/NavigationBar.stories.tsx new file mode 100644 index 0000000..65a6f5c --- /dev/null +++ b/lib/components/NavigationBar/NavigationBar.stories.tsx @@ -0,0 +1,45 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { NavigationBar } from './NavigationBar'; + +const meta = { + title: 'Layout/NavigationBar', + component: NavigationBar, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +const parameters = { + layout: 'fullscreen', + viewport: { + defaultViewport: 'desktop', + }, +}; + +export const Default: Story = { + parameters: { + ...parameters, + design: { + type: 'figma', + url: 'https://www.figma.com/design/6M2LrpSCcB0thlFDaQAI2J/cx_jod_client?node-id=2217-8027', + }, + docs: { + description: { + story: 'This is a light navigation bar with logo, menu, language, and user buttons.', + }, + }, + }, + args: { + languageButtonComponent: <>, + userButtonComponent: <>, + renderLink: ({ children }) => {children}, + logo: { + to: '/', + language: 'fi', + srText: 'JOD', + }, + }, +}; diff --git a/lib/components/NavigationBar/NavigationBar.test.tsx b/lib/components/NavigationBar/NavigationBar.test.tsx new file mode 100644 index 0000000..d1aef57 --- /dev/null +++ b/lib/components/NavigationBar/NavigationBar.test.tsx @@ -0,0 +1,31 @@ +import '@testing-library/jest-dom'; +import { render, screen } from '@testing-library/react'; +import { describe, expect, it } from 'vitest'; +import { NavigationBar, NavigationBarLinkProps } from './NavigationBar'; + +describe('NavigationBar', () => { + const user = { + name: 'Reetta Räppänä', + component: ({ children, ...rootProps }: NavigationBarLinkProps) => ( + + {children} + + ), + }; + + it('renders no navigation items and no user', () => { + const { container } = render( +
{children}
} + logo={{ to: '/', language: 'fi', srText: 'jod' }} + />, + ); + + // Assert snapshot + expect(container.firstChild).toMatchSnapshot(); + + // Assert user is not rendered + const userAvatar = screen.queryByTitle(user.name); + expect(userAvatar).toBeNull(); + }); +}); diff --git a/lib/components/NavigationBar/NavigationBar.tsx b/lib/components/NavigationBar/NavigationBar.tsx new file mode 100644 index 0000000..f0e4228 --- /dev/null +++ b/lib/components/NavigationBar/NavigationBar.tsx @@ -0,0 +1,90 @@ +import React from 'react'; +import { useMediaQueries } from '../../hooks/useMediaQueries'; +import { LogoIconRgb, LogoRgbEn, LogoRgbFi, LogoRgbSv } from '../../main'; + +export interface NavigationBarLinkProps { + className?: string; + role?: string; + title?: string; + children: React.ReactNode; +} + +export type NavigationBarLink = React.ComponentType; + +export interface NavigationBarProps { + /** Place for menu opener button */ + menuComponent?: React.ReactNode; + /** For language selection button **/ + languageButtonComponent?: React.ReactNode; + /** For user logout button **/ + userButtonComponent?: React.ReactNode; + /** For navigation link component */ + renderLink: React.ComponentType<{ + to: object | string; + className?: string; + children: React.ReactNode; + }>; + logo: { + to: object | string; + language: string; + srText: string; + }; + /** HTML Element refs */ + refs?: { + langMenuButtonRef: React.Ref; + }; +} + +const LogoRgb = ({ language, size }: { language: string; size: number }) => { + switch (language) { + case 'sv': + return ; + case 'en': + return ; + default: + return ; + } +}; + +/** + * This component is a navigation bar that displays a logo, and an avatar. + */ +export const NavigationBar = ({ + menuComponent, + languageButtonComponent, + userButtonComponent, + renderLink: Link, + logo, + refs, +}: NavigationBarProps) => { + const { sm } = useMediaQueries(); + + return ( +
+ +
+ ); +}; diff --git a/lib/components/NavigationBar/__snapshots__/NavigationBar.test.tsx.snap b/lib/components/NavigationBar/__snapshots__/NavigationBar.test.tsx.snap new file mode 100644 index 0000000..7a0e8a6 --- /dev/null +++ b/lib/components/NavigationBar/__snapshots__/NavigationBar.test.tsx.snap @@ -0,0 +1,78 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`NavigationBar > renders no navigation items and no user 1`] = ` +
+ +
+`; diff --git a/lib/main.ts b/lib/main.ts index a4cd2f4..bb45d6f 100644 --- a/lib/main.ts +++ b/lib/main.ts @@ -18,8 +18,21 @@ export { DiscussionCard } from './components/DiscussionCard/DiscussionCard'; export { Footer } from './components/Footer/Footer'; export { HeroCard } from './components/HeroCard/HeroCard'; export { InputField } from './components/InputField/InputField'; +export { + LogoArrowBlack, + LogoArrowBlue, + LogoArrowOrange, + LogoArrowPink, + LogoArrowTurquoise, + LogoArrowWhite, +} from './components/Logo/LogoArrow'; +export { LogoBlackEn, LogoRgbEn, LogoWhiteEn } from './components/Logo/LogoEn'; +export { LogoBlackFi, LogoRgbFi, LogoWhiteFi } from './components/Logo/LogoFi'; +export { LogoIconBlack, LogoIconRgb, LogoIconWhite } from './components/Logo/LogoIcon'; +export { LogoBlackSv, LogoRgbSv, LogoWhiteSv } from './components/Logo/LogoSv'; export { MediaCard } from './components/MediaCard/MediaCard'; export { Modal } from './components/Modal/Modal'; +export { NavigationBar } from './components/NavigationBar/NavigationBar'; export { Note } from './components/Note/Note'; export { Pagination, type PageChangeDetails } from './components/Pagination/Pagination'; export { PathProgress } from './components/PathProgress/PathProgress';