From c9c1c90b30e243563bb4f731da15b3fe657556d2 Mon Sep 17 00:00:00 2001
From: Armand Philippot <git@armandphilippot.com>
Date: Mon, 6 Nov 2023 18:08:04 +0100
Subject: refactor(components): replace Summary component with PostPreview

* rename component to PostPreview because Summary is an HTML element
and it could lead to confusion
* replace `title` and `titleLevel` with `heading` and `headingLvl`
because `title` is a native attribute
* rename `intro` prop to `excerpt`
* extract `cover` from `meta` prop
* rewrite meta type
* extract meta logic into a new component
---
 .../organisms/post-preview/post-preview.tsx        | 132 +++++++++++++++++++++
 1 file changed, 132 insertions(+)
 create mode 100644 src/components/organisms/post-preview/post-preview.tsx

(limited to 'src/components/organisms/post-preview/post-preview.tsx')

diff --git a/src/components/organisms/post-preview/post-preview.tsx b/src/components/organisms/post-preview/post-preview.tsx
new file mode 100644
index 0000000..df459e2
--- /dev/null
+++ b/src/components/organisms/post-preview/post-preview.tsx
@@ -0,0 +1,132 @@
+import {
+  type ForwardRefRenderFunction,
+  type ReactElement,
+  forwardRef,
+  type ReactNode,
+} from 'react';
+import { useIntl } from 'react-intl';
+import {
+  ButtonLink,
+  type HeadingLevel,
+  Icon,
+  Link,
+  VisuallyHidden,
+} from '../../atoms';
+import {
+  Card,
+  CardActions,
+  CardBody,
+  CardFooter,
+  CardHeader,
+  type CardProps,
+  CardTitle,
+  CardCover,
+} from '../../molecules';
+import { PostPreviewMeta, type PostPreviewMetaData } from './post-preview-meta';
+import styles from './post-preview.module.scss';
+
+const a11y = (chunks: ReactNode) => <VisuallyHidden>{chunks}</VisuallyHidden>;
+
+export type PostPreviewProps = Omit<
+  CardProps<undefined>,
+  'children' | 'cover' | 'linkTo' | 'meta' | 'variant'
+> & {
+  /**
+   * The post cover.
+   */
+  cover?: ReactElement;
+  /**
+   * The post excerpt.
+   */
+  excerpt: string;
+  /**
+   * The post title.
+   */
+  heading: string;
+  /**
+   * The heading level to use on post title.
+   */
+  headingLvl?: HeadingLevel;
+  /**
+   * The post meta.
+   */
+  meta?: PostPreviewMetaData;
+  /**
+   * The post url.
+   */
+  url: string;
+};
+
+const PostPreviewWithRef: ForwardRefRenderFunction<
+  HTMLDivElement,
+  PostPreviewProps
+> = (
+  { className, cover, excerpt, heading, headingLvl, meta, url, ...props },
+  ref
+) => {
+  const wrapperClass = `${styles.wrapper} ${className}`;
+  const intl = useIntl();
+  const coverLabel = intl.formatMessage(
+    {
+      defaultMessage: '{postTitle} cover',
+      description:
+        'PostPreview: an accessible name for the figure wrapping the cover',
+      id: 'iG5SHf',
+    },
+    { postTitle: heading }
+  );
+  const readMore = intl.formatMessage<ReactNode>(
+    {
+      defaultMessage: 'Read more<a11y> about {postTitle}</a11y>',
+      description: 'PostPreview: read more link',
+      id: 'BYdQze',
+    },
+    {
+      postTitle: heading,
+      a11y,
+    }
+  );
+
+  return (
+    <Card
+      {...props}
+      className={wrapperClass}
+      cover={
+        cover ? (
+          <CardCover aria-label={coverLabel} hasBorders>
+            {cover}
+          </CardCover>
+        ) : undefined
+      }
+      meta={meta ? <PostPreviewMeta meta={meta} /> : undefined}
+      ref={ref}
+    >
+      <CardHeader>
+        <CardTitle className={styles.heading} level={headingLvl}>
+          <Link href={url}>{heading}</Link>
+        </CardTitle>
+      </CardHeader>
+      <CardBody
+        className={styles.excerpt}
+        dangerouslySetInnerHTML={{ __html: excerpt }}
+      />
+      <CardFooter>
+        <CardActions>
+          <ButtonLink to={url}>
+            {readMore}
+            <Icon
+              aria-hidden
+              className={styles.icon}
+              // eslint-disable-next-line react/jsx-no-literals
+              orientation="right"
+              // eslint-disable-next-line react/jsx-no-literals
+              shape="arrow"
+            />
+          </ButtonLink>
+        </CardActions>
+      </CardFooter>
+    </Card>
+  );
+};
+
+export const PostPreview = forwardRef(PostPreviewWithRef);
-- 
cgit v1.2.3

