aboutsummaryrefslogtreecommitdiffstats
path: root/src/components
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2023-11-30 19:30:43 +0100
committerArmand Philippot <git@armandphilippot.com>2023-12-01 16:08:54 +0100
commit5b762b1b669454a89899c4bdf6008027d9615acf (patch)
tree37087f4ee9d14ae131bde15a48d7d04e83ae6cbd /src/components
parentf7e6f42216c3cbeab9add475a61bb407c6be3519 (diff)
refactor(pages): refine Article pages
* use rehype to update code blocks class names * fix widget heading level (after a level 1 it should always be a level 2 and not 3) * replace Spinner with LoadingPage and LoadingPageComments components to keep layout coherent * refactor useArticle and useComments hooks * fix URLs in JSON LD schema * add Cypress tests
Diffstat (limited to 'src/components')
-rw-r--r--src/components/atoms/links/sharing-link/sharing-link.module.scss2
-rw-r--r--src/components/organisms/comment/approved-comment/approved-comment.test.tsx4
-rw-r--r--src/components/organisms/comment/approved-comment/approved-comment.tsx5
-rw-r--r--src/components/templates/page/index.ts2
-rw-r--r--src/components/templates/page/loading-page-comments.stories.tsx22
-rw-r--r--src/components/templates/page/loading-page-comments.test.tsx13
-rw-r--r--src/components/templates/page/loading-page-comments.tsx34
-rw-r--r--src/components/templates/page/loading-page.stories.tsx22
-rw-r--r--src/components/templates/page/loading-page.test.tsx13
-rw-r--r--src/components/templates/page/loading-page.tsx28
-rw-r--r--src/components/templates/page/page.module.scss20
11 files changed, 156 insertions, 9 deletions
diff --git a/src/components/atoms/links/sharing-link/sharing-link.module.scss b/src/components/atoms/links/sharing-link/sharing-link.module.scss
index e1c9c3c..105c37f 100644
--- a/src/components/atoms/links/sharing-link/sharing-link.module.scss
+++ b/src/components/atoms/links/sharing-link/sharing-link.module.scss
@@ -6,7 +6,7 @@
padding: var(--spacing-2xs) var(--spacing-xs);
border-radius: fun.convert-px(3);
box-shadow: #{fun.convert-px(3)} #{fun.convert-px(3)} 0 0 var(--shadowColor);
- transition: all 0.3s linear 0s;
+ transition: all 0.2s linear 0s;
&:hover,
&:focus {
diff --git a/src/components/organisms/comment/approved-comment/approved-comment.test.tsx b/src/components/organisms/comment/approved-comment/approved-comment.test.tsx
index 2e29b5f..b244a63 100644
--- a/src/components/organisms/comment/approved-comment/approved-comment.test.tsx
+++ b/src/components/organisms/comment/approved-comment/approved-comment.test.tsx
@@ -52,7 +52,9 @@ describe('ApprovedComment', () => {
/>
);
- expect(rtlScreen.getByRole('img')).toHaveAccessibleName(author.avatar.alt);
+ expect(rtlScreen.getByRole('figure')).toHaveAccessibleName(
+ author.avatar.alt
+ );
});
it('can render a link to the author website', () => {
diff --git a/src/components/organisms/comment/approved-comment/approved-comment.tsx b/src/components/organisms/comment/approved-comment/approved-comment.tsx
index 233146d..d834ba3 100644
--- a/src/components/organisms/comment/approved-comment/approved-comment.tsx
+++ b/src/components/organisms/comment/approved-comment/approved-comment.tsx
@@ -117,9 +117,10 @@ const ApprovedCommentWithRef: ForwardRefRenderFunction<
className={commentClass}
cover={
author.avatar ? (
- <CardCover hasBorders>
+ <CardCover aria-label={author.avatar.alt} hasBorders>
<NextImage
- alt={author.avatar.alt}
+ // eslint-disable-next-line react/jsx-no-literals
+ alt=""
height={96}
src={author.avatar.src}
width={96}
diff --git a/src/components/templates/page/index.ts b/src/components/templates/page/index.ts
index f6d2d48..f5330a7 100644
--- a/src/components/templates/page/index.ts
+++ b/src/components/templates/page/index.ts
@@ -1,3 +1,5 @@
+export * from './loading-page';
+export * from './loading-page-comments';
export * from './page';
export * from './page-body';
export * from './page-comments';
diff --git a/src/components/templates/page/loading-page-comments.stories.tsx b/src/components/templates/page/loading-page-comments.stories.tsx
new file mode 100644
index 0000000..6069068
--- /dev/null
+++ b/src/components/templates/page/loading-page-comments.stories.tsx
@@ -0,0 +1,22 @@
+import type { ComponentMeta, ComponentStory } from '@storybook/react';
+import { LoadingPageComments } from './loading-page-comments';
+
+/**
+ * LoadingPageComments - Storybook Meta
+ */
+export default {
+ title: 'Templates/LoadingPageComments',
+ component: LoadingPageComments,
+ parameters: {
+ layout: 'fullscreen',
+ },
+} as ComponentMeta<typeof LoadingPageComments>;
+
+const Template: ComponentStory<typeof LoadingPageComments> = (args) => (
+ <LoadingPageComments {...args} />
+);
+
+/**
+ * LoadingPageComments Stories - Example
+ */
+export const Example = Template.bind({});
diff --git a/src/components/templates/page/loading-page-comments.test.tsx b/src/components/templates/page/loading-page-comments.test.tsx
new file mode 100644
index 0000000..b9ccb3e
--- /dev/null
+++ b/src/components/templates/page/loading-page-comments.test.tsx
@@ -0,0 +1,13 @@
+import { describe, expect, it } from '@jest/globals';
+import { render, screen as rtlScreen } from '../../../../tests/utils';
+import { LoadingPageComments } from './loading-page-comments';
+
+describe('LoadingPageComments', () => {
+ it('renders a spinner', () => {
+ render(<LoadingPageComments />);
+
+ expect(
+ rtlScreen.getByText('The comments are loading...')
+ ).toBeInTheDocument();
+ });
+});
diff --git a/src/components/templates/page/loading-page-comments.tsx b/src/components/templates/page/loading-page-comments.tsx
new file mode 100644
index 0000000..9235dcb
--- /dev/null
+++ b/src/components/templates/page/loading-page-comments.tsx
@@ -0,0 +1,34 @@
+import {
+ forwardRef,
+ type ForwardRefRenderFunction,
+ type HTMLAttributes,
+} from 'react';
+import { useIntl } from 'react-intl';
+import { Spinner } from '../../atoms';
+import styles from './page.module.scss';
+
+export type LoadingPageCommentsProps = Omit<
+ HTMLAttributes<HTMLDivElement>,
+ 'children'
+>;
+
+const LoadingPageCommentsWithRef: ForwardRefRenderFunction<
+ HTMLDivElement,
+ LoadingPageCommentsProps
+> = ({ className = '', ...props }, ref) => {
+ const wrapperClass = `${styles.comments} ${className}`;
+ const intl = useIntl();
+ const loadingMsg = intl.formatMessage({
+ defaultMessage: 'The comments are loading...',
+ description: 'LoadingPageComments: loading message',
+ id: 'gYbxP4',
+ });
+
+ return (
+ <div {...props} className={wrapperClass} ref={ref}>
+ <Spinner className={styles.spinner}>{loadingMsg}</Spinner>
+ </div>
+ );
+};
+
+export const LoadingPageComments = forwardRef(LoadingPageCommentsWithRef);
diff --git a/src/components/templates/page/loading-page.stories.tsx b/src/components/templates/page/loading-page.stories.tsx
new file mode 100644
index 0000000..2ea0b33
--- /dev/null
+++ b/src/components/templates/page/loading-page.stories.tsx
@@ -0,0 +1,22 @@
+import type { ComponentMeta, ComponentStory } from '@storybook/react';
+import { LoadingPage } from './loading-page';
+
+/**
+ * LoadingPage - Storybook Meta
+ */
+export default {
+ title: 'Templates/LoadingPage',
+ component: LoadingPage,
+ parameters: {
+ layout: 'fullscreen',
+ },
+} as ComponentMeta<typeof LoadingPage>;
+
+const Template: ComponentStory<typeof LoadingPage> = (args) => (
+ <LoadingPage {...args} />
+);
+
+/**
+ * LoadingPage Stories - Example
+ */
+export const Example = Template.bind({});
diff --git a/src/components/templates/page/loading-page.test.tsx b/src/components/templates/page/loading-page.test.tsx
new file mode 100644
index 0000000..5163943
--- /dev/null
+++ b/src/components/templates/page/loading-page.test.tsx
@@ -0,0 +1,13 @@
+import { describe, expect, it } from '@jest/globals';
+import { render, screen as rtlScreen } from '../../../../tests/utils';
+import { LoadingPage } from './loading-page';
+
+describe('LoadingPage', () => {
+ it('renders a spinner', () => {
+ render(<LoadingPage />);
+
+ expect(
+ rtlScreen.getByText('The requested page is loading...')
+ ).toBeInTheDocument();
+ });
+});
diff --git a/src/components/templates/page/loading-page.tsx b/src/components/templates/page/loading-page.tsx
new file mode 100644
index 0000000..18ceed0
--- /dev/null
+++ b/src/components/templates/page/loading-page.tsx
@@ -0,0 +1,28 @@
+import { forwardRef, type ForwardRefRenderFunction } from 'react';
+import { useIntl } from 'react-intl';
+import { Spinner } from '../../atoms';
+import { Page, type PageProps } from './page';
+import { PageBody } from './page-body';
+import styles from './page.module.scss';
+
+const LoadingPageWithRef: ForwardRefRenderFunction<
+ HTMLDivElement,
+ Omit<PageProps, 'children'>
+> = (props, ref) => {
+ const intl = useIntl();
+ const loadingMsg = intl.formatMessage({
+ defaultMessage: 'The requested page is loading...',
+ description: 'LoadingPage: loading message',
+ id: '0UzObH',
+ });
+
+ return (
+ <Page {...props} ref={ref}>
+ <PageBody>
+ <Spinner className={styles.spinner}>{loadingMsg}</Spinner>
+ </PageBody>
+ </Page>
+ );
+};
+
+export const LoadingPage = forwardRef(LoadingPageWithRef);
diff --git a/src/components/templates/page/page.module.scss b/src/components/templates/page/page.module.scss
index d2752a1..e7d3587 100644
--- a/src/components/templates/page/page.module.scss
+++ b/src/components/templates/page/page.module.scss
@@ -18,9 +18,6 @@
.section {
--border-size: #{fun.convert-px(3)};
--col-gap: clamp(var(--spacing-md), 4vw, var(--spacing-2xl));
- --left-col: 0;
- --right-col: 0;
- --main-col: minmax(0, 80ch);
@extend %grid;
@@ -30,6 +27,10 @@
.breadcrumbs,
.page--regular {
+ --left-col: 0;
+ --right-col: 0;
+ --main-col: minmax(0, 1fr);
+
margin-top: var(--spacing-sm);
}
@@ -74,7 +75,6 @@
.body {
grid-column: 2;
- margin-top: var(--spacing-sm);
padding-bottom: var(--spacing-md);
}
@@ -113,8 +113,9 @@
}
.section {
- --right-col: minmax(0, 1fr);
+ --main-col: minmax(0, 80ch);
--left-col: minmax(0, 1fr);
+ --right-col: minmax(0, 1fr);
@extend %grid;
@@ -202,6 +203,10 @@
}
}
+.spinner {
+ margin: var(--spacing-lg) auto 0;
+}
+
:where(.comments) {
.heading {
width: fit-content;
@@ -212,11 +217,16 @@
max-width: 40ch;
margin-inline: auto;
}
+
+ .spinner {
+ grid-column: 2;
+ }
}
@container page (width > #{var.get-breakpoint("md")}) {
.breadcrumbs,
.page--regular {
+ --main-col: minmax(0, 80ch);
--right-col: minmax(25ch, 1fr);
}