aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/organisms/toolbar
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/organisms/toolbar')
-rw-r--r--src/components/organisms/toolbar/index.ts3
-rw-r--r--src/components/organisms/toolbar/main-nav.stories.tsx34
-rw-r--r--src/components/organisms/toolbar/main-nav.test.tsx37
-rw-r--r--src/components/organisms/toolbar/main-nav.tsx54
-rw-r--r--src/components/organisms/toolbar/toolbar.tsx28
5 files changed, 75 insertions, 81 deletions
diff --git a/src/components/organisms/toolbar/index.ts b/src/components/organisms/toolbar/index.ts
index 9433412..316a52a 100644
--- a/src/components/organisms/toolbar/index.ts
+++ b/src/components/organisms/toolbar/index.ts
@@ -1,4 +1 @@
-export * from './main-nav';
-export * from './search';
-export * from './settings';
export * from './toolbar';
diff --git a/src/components/organisms/toolbar/main-nav.stories.tsx b/src/components/organisms/toolbar/main-nav.stories.tsx
index 57485d3..d79addf 100644
--- a/src/components/organisms/toolbar/main-nav.stories.tsx
+++ b/src/components/organisms/toolbar/main-nav.stories.tsx
@@ -1,13 +1,13 @@
-import { ComponentMeta, ComponentStory } from '@storybook/react';
-import { useState } from 'react';
-import { MainNav } from './main-nav';
+import type { ComponentMeta, ComponentStory } from '@storybook/react';
+import { useCallback, useState } from 'react';
+import { MainNavItem } from './main-nav';
/**
- * MainNav - Storybook Meta
+ * MainNavItem - Storybook Meta
*/
export default {
- title: 'Organisms/Toolbar/MainNav',
- component: MainNav,
+ title: 'Organisms/Toolbar/MainNavItem',
+ component: MainNavItem,
argTypes: {
className: {
control: {
@@ -54,28 +54,24 @@ export default {
},
},
},
-} as ComponentMeta<typeof MainNav>;
+} as ComponentMeta<typeof MainNavItem>;
-const Template: ComponentStory<typeof MainNav> = ({
+const Template: ComponentStory<typeof MainNavItem> = ({
isActive = false,
setIsActive: _setIsActive,
...args
}) => {
const [isOpen, setIsOpen] = useState<boolean>(isActive);
- return (
- <MainNav
- isActive={isOpen}
- setIsActive={() => {
- setIsOpen(!isOpen);
- }}
- {...args}
- />
- );
+ const toggle = useCallback(() => {
+ setIsOpen((prevState) => !prevState);
+ }, []);
+
+ return <MainNavItem isActive={isOpen} setIsActive={toggle} {...args} />;
};
/**
- * MainNav Stories - Inactive
+ * MainNavItem Stories - Inactive
*/
export const Inactive = Template.bind({});
Inactive.args = {
@@ -87,7 +83,7 @@ Inactive.args = {
};
/**
- * MainNav Stories - Active
+ * MainNavItem Stories - Active
*/
export const Active = Template.bind({});
Active.args = {
diff --git a/src/components/organisms/toolbar/main-nav.test.tsx b/src/components/organisms/toolbar/main-nav.test.tsx
index 054a14e..177e692 100644
--- a/src/components/organisms/toolbar/main-nav.test.tsx
+++ b/src/components/organisms/toolbar/main-nav.test.tsx
@@ -1,6 +1,10 @@
import { describe, expect, it } from '@jest/globals';
-import { render, screen } from '../../../../tests/utils';
-import { MainNav } from './main-nav';
+import { render, screen as rtlScreen } from '../../../../tests/utils';
+import { MainNavItem } from './main-nav';
+
+const doNothing = () => {
+ // do nothing
+};
const items = [
{ id: 'home', label: 'Home', href: '/' },
@@ -8,27 +12,34 @@ const items = [
{ id: 'contact', label: 'Contact', href: '/contact' },
];
-describe('MainNav', () => {
+describe('MainNavItem', () => {
it('renders a checkbox to open main nav', () => {
- render(<MainNav items={items} isActive={false} setIsActive={() => null} />);
- expect(screen.getByRole('checkbox')).toHaveAccessibleName('Open menu');
+ render(
+ <MainNavItem items={items} isActive={false} setIsActive={doNothing} />
+ );
+ expect(rtlScreen.getByRole('checkbox')).toHaveAccessibleName('Open menu');
});
it('renders a checkbox to close main nav', () => {
- render(<MainNav items={items} isActive={true} setIsActive={() => null} />);
- expect(screen.getByRole('checkbox')).toHaveAccessibleName('Close menu');
+ render(
+ <MainNavItem items={items} isActive={true} setIsActive={doNothing} />
+ );
+ expect(rtlScreen.getByRole('checkbox')).toHaveAccessibleName('Close menu');
});
it('renders the correct number of items', () => {
- render(<MainNav items={items} isActive={true} setIsActive={() => null} />);
- expect(screen.getAllByRole('listitem')).toHaveLength(items.length);
+ render(
+ <MainNavItem items={items} isActive={true} setIsActive={doNothing} />
+ );
+ expect(rtlScreen.getAllByRole('listitem')).toHaveLength(items.length);
});
it('renders some links with the right label', () => {
- render(<MainNav items={items} isActive={true} setIsActive={() => null} />);
- expect(screen.getByRole('link', { name: items[0].label })).toHaveAttribute(
- 'href',
- items[0].href
+ render(
+ <MainNavItem items={items} isActive={true} setIsActive={doNothing} />
);
+ expect(
+ rtlScreen.getByRole('link', { name: items[0].label })
+ ).toHaveAttribute('href', items[0].href);
});
});
diff --git a/src/components/organisms/toolbar/main-nav.tsx b/src/components/organisms/toolbar/main-nav.tsx
index a5a105e..ee799f5 100644
--- a/src/components/organisms/toolbar/main-nav.tsx
+++ b/src/components/organisms/toolbar/main-nav.tsx
@@ -1,28 +1,11 @@
-import {
- forwardRef,
- type ReactNode,
- type ForwardRefRenderFunction,
-} from 'react';
+import { forwardRef, type ForwardRefRenderFunction } from 'react';
import { useIntl } from 'react-intl';
-import {
- BooleanField,
- type BooleanFieldProps,
- Icon,
- Label,
- Nav,
-} from '../../atoms';
-import { NavList, NavItem, NavLink } from '../../molecules';
+import { BooleanField, type BooleanFieldProps, Icon, Label } from '../../atoms';
+import { type MainNavItem as Item, MainNav } from '../nav';
import mainNavStyles from './main-nav.module.scss';
import sharedStyles from './toolbar-items.module.scss';
-export type MainNavItem = {
- id: string;
- href: string;
- label: string;
- logo?: ReactNode;
-};
-
-export type MainNavProps = {
+export type MainNavItemProps = {
/**
* Set additional classnames to the nav element.
*/
@@ -34,17 +17,17 @@ export type MainNavProps = {
/**
* The main nav items.
*/
- items: MainNavItem[];
+ items: Item[];
/**
* A callback function to handle button state.
*/
setIsActive: BooleanFieldProps['onChange'];
};
-const MainNavWithRef: ForwardRefRenderFunction<HTMLDivElement, MainNavProps> = (
- { className = '', isActive = false, items, setIsActive },
- ref
-) => {
+const MainNavItemWithRef: ForwardRefRenderFunction<
+ HTMLDivElement,
+ MainNavItemProps
+> = ({ className = '', isActive = false, items, setIsActive }, ref) => {
const intl = useIntl();
const label = isActive
? intl.formatMessage({
@@ -76,24 +59,17 @@ const MainNavWithRef: ForwardRefRenderFunction<HTMLDivElement, MainNavProps> = (
>
<Icon shape="hamburger" />
</Label>
- <Nav
+ <MainNav
className={`${sharedStyles.modal} ${mainNavStyles.modal} ${className}`}
- >
- <NavList isInline spacing="2xs">
- {items.map(({ id, ...link }) => (
- <NavItem key={id}>
- <NavLink {...link} isStack variant="main" />
- </NavItem>
- ))}
- </NavList>
- </Nav>
+ items={items}
+ />
</div>
);
};
/**
- * MainNav component
+ * MainNavItem component
*
- * Render the main navigation.
+ * Render the main navigation as toolbar item.
*/
-export const MainNav = forwardRef(MainNavWithRef);
+export const MainNavItem = forwardRef(MainNavItemWithRef);
diff --git a/src/components/organisms/toolbar/toolbar.tsx b/src/components/organisms/toolbar/toolbar.tsx
index 94c9d95..999a29a 100644
--- a/src/components/organisms/toolbar/toolbar.tsx
+++ b/src/components/organisms/toolbar/toolbar.tsx
@@ -1,6 +1,7 @@
-import { FC, useState } from 'react';
+/* eslint-disable max-statements */
+import { type FC, useState, useCallback } from 'react';
import { useOnClickOutside, useRouteChange } from '../../../utils/hooks';
-import { MainNav, type MainNavProps } from './main-nav';
+import { MainNavItem, type MainNavItemProps } from './main-nav';
import { Search, type SearchProps } from './search';
import { Settings, type SettingsProps } from './settings';
import styles from './toolbar.module.scss';
@@ -14,7 +15,7 @@ export type ToolbarProps = Pick<SearchProps, 'searchPage'> &
/**
* The main nav items.
*/
- nav: MainNavProps['items'];
+ nav: MainNavItemProps['items'];
};
/**
@@ -43,23 +44,36 @@ export const Toolbar: FC<ToolbarProps> = ({
() => isSettingsOpened && setIsSettingsOpened(false)
);
+ const toggleMainNav = useCallback(
+ () => setIsNavOpened((prevState) => !prevState),
+ []
+ );
+ const toggleSearch = useCallback(
+ () => setIsSearchOpened((prevState) => !prevState),
+ []
+ );
+ const toggleSettings = useCallback(
+ () => setIsSettingsOpened((prevState) => !prevState),
+ []
+ );
+
useRouteChange(() => setIsSearchOpened(false));
return (
<div className={`${styles.wrapper} ${className}`}>
- <MainNav
+ <MainNavItem
className={styles.modal}
isActive={isNavOpened}
items={nav}
ref={mainNavRef}
- setIsActive={() => setIsNavOpened(!isNavOpened)}
+ setIsActive={toggleMainNav}
/>
<Search
className={`${styles.modal} ${styles['modal--search']}`}
isActive={isSearchOpened}
ref={searchRef}
searchPage={searchPage}
- setIsActive={() => setIsSearchOpened(!isSearchOpened)}
+ setIsActive={toggleSearch}
/>
<Settings
ackeeStorageKey={ackeeStorageKey}
@@ -67,7 +81,7 @@ export const Toolbar: FC<ToolbarProps> = ({
isActive={isSettingsOpened}
motionStorageKey={motionStorageKey}
ref={settingsRef}
- setIsActive={() => setIsSettingsOpened(!isSettingsOpened)}
+ setIsActive={toggleSettings}
/>
</div>
);