diff options
| author | Armand Philippot <git@armandphilippot.com> | 2023-11-13 19:03:44 +0100 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2023-11-13 19:03:44 +0100 |
| commit | fb29b0f017fae162ffa7ad6bdfc80099346802de (patch) | |
| tree | 3f8aebb73457ee27b86b8b1a3106a5f9bc35e8da /src/components/organisms | |
| parent | e331106e56d59a8b987230860b66214139c12ef6 (diff) | |
refactor(components): replace SocialMedia with SocialMediaWidget
* the goal is to make the name of the widgets coherent
* remove useless CSS
* replace Media type with SocialMediaData
Diffstat (limited to 'src/components/organisms')
| -rw-r--r-- | src/components/organisms/widgets/index.ts | 2 | ||||
| -rw-r--r-- | src/components/organisms/widgets/social-media-widget/index.ts | 1 | ||||
| -rw-r--r-- | src/components/organisms/widgets/social-media-widget/social-media-widget.stories.tsx (renamed from src/components/organisms/widgets/social-media.stories.tsx) | 10 | ||||
| -rw-r--r-- | src/components/organisms/widgets/social-media-widget/social-media-widget.test.tsx | 27 | ||||
| -rw-r--r-- | src/components/organisms/widgets/social-media-widget/social-media-widget.tsx | 43 | ||||
| -rw-r--r-- | src/components/organisms/widgets/social-media.module.scss | 5 | ||||
| -rw-r--r-- | src/components/organisms/widgets/social-media.test.tsx | 47 | ||||
| -rw-r--r-- | src/components/organisms/widgets/social-media.tsx | 40 |
8 files changed, 77 insertions, 98 deletions
diff --git a/src/components/organisms/widgets/index.ts b/src/components/organisms/widgets/index.ts index 222ade0..03f845f 100644 --- a/src/components/organisms/widgets/index.ts +++ b/src/components/organisms/widgets/index.ts @@ -1,5 +1,5 @@ export * from './image-widget'; export * from './links-list-widget'; export * from './sharing'; -export * from './social-media'; +export * from './social-media-widget'; export * from './table-of-contents'; diff --git a/src/components/organisms/widgets/social-media-widget/index.ts b/src/components/organisms/widgets/social-media-widget/index.ts new file mode 100644 index 0000000..33a6f3f --- /dev/null +++ b/src/components/organisms/widgets/social-media-widget/index.ts @@ -0,0 +1 @@ +export * from './social-media-widget'; diff --git a/src/components/organisms/widgets/social-media.stories.tsx b/src/components/organisms/widgets/social-media-widget/social-media-widget.stories.tsx index 8064157..5c6efb0 100644 --- a/src/components/organisms/widgets/social-media.stories.tsx +++ b/src/components/organisms/widgets/social-media-widget/social-media-widget.stories.tsx @@ -1,16 +1,16 @@ import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Heading } from '../../atoms'; -import { SocialMedia as SocialMediaWidget, type Media } from './social-media'; +import { Heading } from '../../../atoms'; +import { SocialMediaWidget, type SocialMediaData } from './social-media-widget'; /** * SocialMedia - Storybook Meta */ export default { - title: 'Organisms/Widgets', + title: 'Organisms/Widgets/SocialMedia', component: SocialMediaWidget, argTypes: { media: { - description: 'The links data.', + description: 'The social media data.', type: { name: 'object', required: true, @@ -24,7 +24,7 @@ const Template: ComponentStory<typeof SocialMediaWidget> = (args) => ( <SocialMediaWidget {...args} /> ); -const media: Media[] = [ +const media: SocialMediaData[] = [ { icon: 'Github', id: 'github', label: 'Github', url: '#' }, { icon: 'LinkedIn', id: 'gitlab', label: 'Gitlab', url: '#' }, ]; diff --git a/src/components/organisms/widgets/social-media-widget/social-media-widget.test.tsx b/src/components/organisms/widgets/social-media-widget/social-media-widget.test.tsx new file mode 100644 index 0000000..197b9ac --- /dev/null +++ b/src/components/organisms/widgets/social-media-widget/social-media-widget.test.tsx @@ -0,0 +1,27 @@ +import { describe, expect, it } from '@jest/globals'; +import { render, screen as rtlScreen } from '@testing-library/react'; +import { Heading } from '../../../atoms'; +import { type SocialMediaData, SocialMediaWidget } from './social-media-widget'; + +describe('SocialMediaWidget', () => { + it('render the widget heading and a list of social media', () => { + const heading = 'aut dolorem molestiae'; + const headingLvl = 3; + const media = [ + { icon: 'Github', id: 'github', label: 'Github', url: '#github' }, + { icon: 'LinkedIn', id: 'linkedin', label: 'LinkedIn', url: '#linkedin' }, + ] satisfies SocialMediaData[]; + + render( + <SocialMediaWidget + heading={<Heading level={headingLvl}>{heading}</Heading>} + media={media} + /> + ); + + expect( + rtlScreen.getByRole('heading', { level: headingLvl }) + ).toHaveTextContent(heading); + expect(rtlScreen.getAllByRole('link')).toHaveLength(media.length); + }); +}); diff --git a/src/components/organisms/widgets/social-media-widget/social-media-widget.tsx b/src/components/organisms/widgets/social-media-widget/social-media-widget.tsx new file mode 100644 index 0000000..d75f48f --- /dev/null +++ b/src/components/organisms/widgets/social-media-widget/social-media-widget.tsx @@ -0,0 +1,43 @@ +import { forwardRef, type ForwardRefRenderFunction } from 'react'; +import { + List, + ListItem, + SocialLink, + type SocialLinkProps, +} from '../../../atoms'; +import { Collapsible, type CollapsibleProps } from '../../../molecules'; + +export type SocialMediaData = Required< + Pick<SocialLinkProps, 'icon' | 'id' | 'label' | 'url'> +>; + +export type SocialMediaProps = Omit<CollapsibleProps, 'children'> & { + media: SocialMediaData[]; +}; + +const SocialMediaWidgetWithRef: ForwardRefRenderFunction< + HTMLDivElement, + SocialMediaProps +> = ({ media, ...props }, ref) => ( + <Collapsible {...props} ref={ref}> + <List + hideMarker + isInline + // eslint-disable-next-line react/jsx-no-literals + spacing="xs" + > + {media.map(({ id, ...link }) => ( + <ListItem key={id}> + <SocialLink {...link} /> + </ListItem> + ))} + </List> + </Collapsible> +); + +/** + * Social Media widget component + * + * Render a social media list with links. + */ +export const SocialMediaWidget = forwardRef(SocialMediaWidgetWithRef); diff --git a/src/components/organisms/widgets/social-media.module.scss b/src/components/organisms/widgets/social-media.module.scss deleted file mode 100644 index 1cd3f57..0000000 --- a/src/components/organisms/widgets/social-media.module.scss +++ /dev/null @@ -1,5 +0,0 @@ -@use "../../../styles/abstracts/placeholders"; - -.list { - padding: 0 var(--spacing-2xs); -} diff --git a/src/components/organisms/widgets/social-media.test.tsx b/src/components/organisms/widgets/social-media.test.tsx deleted file mode 100644 index ead29d9..0000000 --- a/src/components/organisms/widgets/social-media.test.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { describe, expect, it } from '@jest/globals'; -import { render, screen as rtlScreen } from '../../../../tests/utils'; -import { SocialMedia, type Media } from './social-media'; -import { Heading } from 'src/components/atoms'; - -const media: Media[] = [ - { icon: 'Github', id: 'github', label: 'Github', url: '#' }, - { icon: 'LinkedIn', id: 'gitlab', label: 'Gitlab', url: '#' }, -]; -const title = 'Dolores ut ut'; -const titleLevel = 2; - -/** - * Next.js mock images with next/image component. So for now, I need to mock - * the svg files manually. - */ -jest.mock('@assets/images/social-media/github.svg', () => 'svg-file'); -jest.mock('@assets/images/social-media/gitlab.svg', () => 'svg-file'); -jest.mock('@assets/images/social-media/linkedin.svg', () => 'svg-file'); -jest.mock('@assets/images/social-media/twitter.svg', () => 'svg-file'); - -describe('SocialMedia', () => { - it('renders the widget title', () => { - render( - <SocialMedia - heading={<Heading level={titleLevel}>{title}</Heading>} - media={media} - /> - ); - expect( - rtlScreen.getByRole('heading', { - level: titleLevel, - name: new RegExp(title, 'i'), - }) - ).toBeInTheDocument(); - }); - - it('renders the correct number of items', () => { - render( - <SocialMedia - heading={<Heading level={titleLevel}>{title}</Heading>} - media={media} - /> - ); - expect(rtlScreen.getAllByRole('listitem')).toHaveLength(media.length); - }); -}); diff --git a/src/components/organisms/widgets/social-media.tsx b/src/components/organisms/widgets/social-media.tsx deleted file mode 100644 index 14c8fe6..0000000 --- a/src/components/organisms/widgets/social-media.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import type { FC } from 'react'; -import { List, ListItem, SocialLink, type SocialLinkProps } from '../../atoms'; -import { Collapsible, type CollapsibleProps } from '../../molecules'; -import styles from './social-media.module.scss'; - -export type Media = Required< - Pick<SocialLinkProps, 'icon' | 'id' | 'label' | 'url'> ->; - -export type SocialMediaProps = Omit<CollapsibleProps, 'children'> & { - media: Media[]; -}; - -/** - * Social Media widget component - * - * Render a social media list with links. - */ -export const SocialMedia: FC<SocialMediaProps> = ({ media, ...props }) => { - /** - * Retrieve the social media items. - * - * @param {SocialMedia[]} links - An array of social media name and url. - * @returns {JSX.Element[]} The social links. - */ - const getItems = (links: Media[]): JSX.Element[] => - links.map(({ id, ...link }) => ( - <ListItem key={id}> - <SocialLink {...link} /> - </ListItem> - )); - - return ( - <Collapsible {...props}> - <List className={styles.list} hideMarker isInline spacing="xs"> - {getItems(media)} - </List> - </Collapsible> - ); -}; |
