aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/atoms/notice
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2023-10-02 18:07:34 +0200
committerArmand Philippot <git@armandphilippot.com>2023-11-11 18:14:41 +0100
commitb52b8183ce299b5a2d3c3b2f4f8cb94bb443d746 (patch)
tree2ec276a4ebd5d39b891ff8fe8d8bf45c478fb97e /src/components/atoms/notice
parent6221fa82e41915702d8139cade5c25e9d61e619f (diff)
refactor(components): rewrite Notice component
* Rename message prop to children prop and set ReactNode as type
Diffstat (limited to 'src/components/atoms/notice')
-rw-r--r--src/components/atoms/notice/index.ts1
-rw-r--r--src/components/atoms/notice/notice.module.scss28
-rw-r--r--src/components/atoms/notice/notice.stories.tsx86
-rw-r--r--src/components/atoms/notice/notice.test.tsx37
-rw-r--r--src/components/atoms/notice/notice.tsx36
5 files changed, 188 insertions, 0 deletions
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<typeof NoticeComponent>;
+
+const Template: ComponentStory<typeof NoticeComponent> = (args) => (
+ <NoticeComponent {...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(<Notice kind="error">{body}</Notice>);
+
+ expect(rtlScreen.getByText(body)).toHaveClass('notice--error');
+ });
+
+ it('can render an informative notice', () => {
+ const body = 'labore optio rerum';
+
+ render(<Notice kind="info">{body}</Notice>);
+
+ expect(rtlScreen.getByText(body)).toHaveClass('notice--info');
+ });
+
+ it('can render a success notice', () => {
+ const body = 'dolorem voluptatem velit';
+
+ render(<Notice kind="success">{body}</Notice>);
+
+ expect(rtlScreen.getByText(body)).toHaveClass('notice--success');
+ });
+
+ it('can render a warning notice', () => {
+ const body = 'ut non nihil';
+
+ render(<Notice kind="warning">{body}</Notice>);
+
+ 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<HTMLAttributes<HTMLElement>, '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<NoticeProps> = ({
+ className = '',
+ children,
+ kind,
+ ...props
+}) => {
+ const kindClass = styles[`notice--${kind}`];
+ const noticeClass = `${styles.notice} ${kindClass} ${className}`;
+
+ return (
+ <div {...props} className={noticeClass}>
+ {children}
+ </div>
+ );
+};