From b52b8183ce299b5a2d3c3b2f4f8cb94bb443d746 Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Mon, 2 Oct 2023 18:07:34 +0200 Subject: refactor(components): rewrite Notice component * Rename message prop to children prop and set ReactNode as type --- src/components/atoms/index.ts | 1 + src/components/atoms/layout/index.ts | 1 - src/components/atoms/layout/notice.module.scss | 27 -------- src/components/atoms/layout/notice.stories.tsx | 86 -------------------------- src/components/atoms/layout/notice.test.tsx | 12 ---- src/components/atoms/layout/notice.tsx | 36 ----------- src/components/atoms/notice/index.ts | 1 + src/components/atoms/notice/notice.module.scss | 28 +++++++++ src/components/atoms/notice/notice.stories.tsx | 86 ++++++++++++++++++++++++++ src/components/atoms/notice/notice.test.tsx | 37 +++++++++++ src/components/atoms/notice/notice.tsx | 36 +++++++++++ src/components/templates/page/page-layout.tsx | 16 ++--- src/pages/blog/index.tsx | 5 +- src/pages/contact.tsx | 8 +-- src/pages/recherche/index.tsx | 5 +- 15 files changed, 204 insertions(+), 181 deletions(-) delete mode 100644 src/components/atoms/layout/notice.module.scss delete mode 100644 src/components/atoms/layout/notice.stories.tsx delete mode 100644 src/components/atoms/layout/notice.test.tsx delete mode 100644 src/components/atoms/layout/notice.tsx create mode 100644 src/components/atoms/notice/index.ts create mode 100644 src/components/atoms/notice/notice.module.scss create mode 100644 src/components/atoms/notice/notice.stories.tsx create mode 100644 src/components/atoms/notice/notice.test.tsx create mode 100644 src/components/atoms/notice/notice.tsx diff --git a/src/components/atoms/index.ts b/src/components/atoms/index.ts index abcc198..4aa367a 100644 --- a/src/components/atoms/index.ts +++ b/src/components/atoms/index.ts @@ -7,4 +7,5 @@ export * from './links'; export * from './lists'; export * from './loaders'; export * from './modal'; +export * from './notice'; export * from './sidebar'; diff --git a/src/components/atoms/layout/index.ts b/src/components/atoms/layout/index.ts index 9f467dc..3f2f8dc 100644 --- a/src/components/atoms/layout/index.ts +++ b/src/components/atoms/layout/index.ts @@ -5,5 +5,4 @@ export * from './footer'; export * from './header'; export * from './main'; export * from './nav'; -export * from './notice'; export * from './section'; diff --git a/src/components/atoms/layout/notice.module.scss b/src/components/atoms/layout/notice.module.scss deleted file mode 100644 index b532464..0000000 --- a/src/components/atoms/layout/notice.module.scss +++ /dev/null @@ -1,27 +0,0 @@ -@use "../../../styles/abstracts/functions" as fun; - -.wrapper { - padding: var(--spacing-2xs) var(--spacing-xs); - border: fun.convert-px(2) solid; - font-weight: bold; - - &--error { - border-color: var(--color-token-red); - color: var(--color-token-red); - } - - &--info { - border-color: var(--color-token-blue); - color: var(--color-token-blue); - } - - &--success { - border-color: var(--color-token-green); - color: var(--color-token-green); - } - - &--warning { - border-color: var(--color-token-orange); - color: var(--color-token-orange); - } -} diff --git a/src/components/atoms/layout/notice.stories.tsx b/src/components/atoms/layout/notice.stories.tsx deleted file mode 100644 index 57dddb3..0000000 --- a/src/components/atoms/layout/notice.stories.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Notice as NoticeComponent } from './notice'; - -/** - * Notice - Storybook Meta - */ -export default { - title: 'Atoms/Layout/Notice', - component: NoticeComponent, - argTypes: { - className: { - control: { - type: 'text', - }, - description: 'Set additional classnames to the notice wrapper.', - table: { - category: 'Styles', - }, - type: { - name: 'string', - required: false, - }, - }, - kind: { - control: { - type: 'select', - }, - description: 'The notice kind.', - options: ['error', 'info', 'success', 'warning'], - type: { - name: 'string', - required: true, - }, - }, - message: { - control: { - type: 'text', - }, - description: 'The notice body.', - type: { - name: 'string', - required: true, - }, - }, - }, -} as ComponentMeta; - -const Template: ComponentStory = (args) => ( - -); - -/** - * Notice stories - Error - */ -export const Error = Template.bind({}); -Error.args = { - kind: 'error', - message: 'Nisi provident sapiente.', -}; - -/** - * Notice stories - Info - */ -export const Info = Template.bind({}); -Info.args = { - kind: 'info', - message: 'Nisi provident sapiente.', -}; - -/** - * Notice stories - Success - */ -export const Success = Template.bind({}); -Success.args = { - kind: 'success', - message: 'Nisi provident sapiente.', -}; - -/** - * Notice stories - Warning - */ -export const Warning = Template.bind({}); -Warning.args = { - kind: 'warning', - message: 'Nisi provident sapiente.', -}; diff --git a/src/components/atoms/layout/notice.test.tsx b/src/components/atoms/layout/notice.test.tsx deleted file mode 100644 index f5213e4..0000000 --- a/src/components/atoms/layout/notice.test.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { describe, expect, it } from '@jest/globals'; -import { render, screen } from '../../../../tests/utils'; -import { Notice } from './notice'; - -const message = 'Tenetur consequuntur tempore.'; - -describe('Notice', () => { - it('renders a message', () => { - render(); - expect(screen.getByText(message)).toBeInTheDocument(); - }); -}); diff --git a/src/components/atoms/layout/notice.tsx b/src/components/atoms/layout/notice.tsx deleted file mode 100644 index 9f69af2..0000000 --- a/src/components/atoms/layout/notice.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { FC, HTMLAttributes } from 'react'; -import styles from './notice.module.scss'; - -export type NoticeKind = 'error' | 'info' | 'success' | 'warning'; - -export type NoticeProps = Omit, 'children'> & { - /** - * The notice kind. - */ - kind: NoticeKind; - /** - * The notice body. - */ - message: string; -}; - -/** - * Notice component - * - * Render a colored message depending on notice kind. - */ -export const Notice: FC = ({ - className = '', - kind, - message, - ...props -}) => { - const kindClass = `wrapper--${kind}`; - const noticeClass = `${styles.wrapper} ${styles[kindClass]} ${className}`; - - return ( -
- {message} -
- ); -}; diff --git a/src/components/atoms/notice/index.ts b/src/components/atoms/notice/index.ts new file mode 100644 index 0000000..6351718 --- /dev/null +++ b/src/components/atoms/notice/index.ts @@ -0,0 +1 @@ +export * from './notice'; diff --git a/src/components/atoms/notice/notice.module.scss b/src/components/atoms/notice/notice.module.scss new file mode 100644 index 0000000..31cfc2d --- /dev/null +++ b/src/components/atoms/notice/notice.module.scss @@ -0,0 +1,28 @@ +@use "../../../styles/abstracts/functions" as fun; + +.notice { + padding: var(--spacing-2xs) var(--spacing-xs); + border: fun.convert-px(2) solid; + border-radius: fun.convert-px(4); + font-weight: bold; + + &--error { + border-color: var(--color-token-red); + color: var(--color-token-red); + } + + &--info { + border-color: var(--color-token-blue); + color: var(--color-token-blue); + } + + &--success { + border-color: var(--color-token-green); + color: var(--color-token-green); + } + + &--warning { + border-color: var(--color-token-orange); + color: var(--color-token-orange); + } +} diff --git a/src/components/atoms/notice/notice.stories.tsx b/src/components/atoms/notice/notice.stories.tsx new file mode 100644 index 0000000..60d97d9 --- /dev/null +++ b/src/components/atoms/notice/notice.stories.tsx @@ -0,0 +1,86 @@ +import type { ComponentMeta, ComponentStory } from '@storybook/react'; +import { Notice as NoticeComponent } from './notice'; + +/** + * Notice - Storybook Meta + */ +export default { + title: 'Atoms/Notice', + component: NoticeComponent, + argTypes: { + className: { + control: { + type: 'text', + }, + description: 'Set additional classnames to the notice wrapper.', + table: { + category: 'Styles', + }, + type: { + name: 'string', + required: false, + }, + }, + kind: { + control: { + type: 'select', + }, + description: 'The notice kind.', + options: ['error', 'info', 'success', 'warning'], + type: { + name: 'string', + required: true, + }, + }, + children: { + control: { + type: 'text', + }, + description: 'The notice body.', + type: { + name: 'string', + required: true, + }, + }, + }, +} as ComponentMeta; + +const Template: ComponentStory = (args) => ( + +); + +/** + * Notice stories - Error + */ +export const ErrorKind = Template.bind({}); +ErrorKind.args = { + children: 'Nisi provident sapiente.', + kind: 'error', +}; + +/** + * Notice stories - Info + */ +export const InfoKind = Template.bind({}); +InfoKind.args = { + children: 'Nisi provident sapiente.', + kind: 'info', +}; + +/** + * Notice stories - Success + */ +export const SuccessKind = Template.bind({}); +SuccessKind.args = { + children: 'Nisi provident sapiente.', + kind: 'success', +}; + +/** + * Notice stories - Warning + */ +export const WarningKind = Template.bind({}); +WarningKind.args = { + children: 'Nisi provident sapiente.', + kind: 'warning', +}; diff --git a/src/components/atoms/notice/notice.test.tsx b/src/components/atoms/notice/notice.test.tsx new file mode 100644 index 0000000..dd6bef6 --- /dev/null +++ b/src/components/atoms/notice/notice.test.tsx @@ -0,0 +1,37 @@ +import { describe, expect, it } from '@jest/globals'; +import { render, screen as rtlScreen } from '@testing-library/react'; +import { Notice } from './notice'; + +describe('Notice', () => { + it('can render an error notice', () => { + const body = 'culpa sint ut'; + + render({body}); + + expect(rtlScreen.getByText(body)).toHaveClass('notice--error'); + }); + + it('can render an informative notice', () => { + const body = 'labore optio rerum'; + + render({body}); + + expect(rtlScreen.getByText(body)).toHaveClass('notice--info'); + }); + + it('can render a success notice', () => { + const body = 'dolorem voluptatem velit'; + + render({body}); + + expect(rtlScreen.getByText(body)).toHaveClass('notice--success'); + }); + + it('can render a warning notice', () => { + const body = 'ut non nihil'; + + render({body}); + + expect(rtlScreen.getByText(body)).toHaveClass('notice--warning'); + }); +}); diff --git a/src/components/atoms/notice/notice.tsx b/src/components/atoms/notice/notice.tsx new file mode 100644 index 0000000..0c8a60c --- /dev/null +++ b/src/components/atoms/notice/notice.tsx @@ -0,0 +1,36 @@ +import type { FC, HTMLAttributes, ReactNode } from 'react'; +import styles from './notice.module.scss'; + +export type NoticeKind = 'error' | 'info' | 'success' | 'warning'; + +export type NoticeProps = Omit, 'children'> & { + /** + * The notice body. + */ + children: ReactNode; + /** + * The notice kind. + */ + kind: NoticeKind; +}; + +/** + * Notice component + * + * Render a colored message depending on notice kind. + */ +export const Notice: FC = ({ + className = '', + children, + kind, + ...props +}) => { + const kindClass = styles[`notice--${kind}`]; + const noticeClass = `${styles.notice} ${kindClass} ${className}`; + + return ( +
+ {children} +
+ ); +}; diff --git a/src/components/templates/page/page-layout.tsx b/src/components/templates/page/page-layout.tsx index dfd9353..ee3fd3a 100644 --- a/src/components/templates/page/page-layout.tsx +++ b/src/components/templates/page/page-layout.tsx @@ -281,11 +281,9 @@ export const PageLayout: FC = ({ depth={2} Notice={ commentStatus?.isReply ? ( - + + {commentStatus.message} + ) : null } saveComment={saveComment} @@ -307,11 +305,9 @@ export const PageLayout: FC = ({ title={commentFormTitle} Notice={ commentStatus && !commentStatus.isReply ? ( - + + {commentStatus.message} + ) : null } /> diff --git a/src/pages/blog/index.tsx b/src/pages/blog/index.tsx index 7f6c540..7eef2f0 100644 --- a/src/pages/blog/index.tsx +++ b/src/pages/blog/index.tsx @@ -196,12 +196,13 @@ const BlogPage: NextPageWithLayout = ({ + {intl.formatMessage({ defaultMessage: 'Failed to load.', description: 'BlogPage: failed to load text', id: 'C/XGkH', })} - /> + ) : null} diff --git a/src/pages/contact.tsx b/src/pages/contact.tsx index d187a93..679896c 100644 --- a/src/pages/contact.tsx +++ b/src/pages/contact.tsx @@ -158,11 +158,9 @@ const ContactPage: NextPageWithLayout = () => { sendMail={submitMail} Notice={ statusMessage ? ( - + + {statusMessage} + ) : undefined } /> diff --git a/src/pages/recherche/index.tsx b/src/pages/recherche/index.tsx index 5acf352..54244b1 100644 --- a/src/pages/recherche/index.tsx +++ b/src/pages/recherche/index.tsx @@ -222,12 +222,13 @@ const SearchPage: NextPageWithLayout = ({ + {intl.formatMessage({ defaultMessage: 'Failed to load.', description: 'SearchPage: failed to load text', id: 'fOe8rH', })} - /> + ) : null} -- cgit v1.2.3