aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/templates/page/page.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/templates/page/page.tsx')
-rw-r--r--src/components/templates/page/page.tsx56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/components/templates/page/page.tsx b/src/components/templates/page/page.tsx
new file mode 100644
index 0000000..f5f3ea5
--- /dev/null
+++ b/src/components/templates/page/page.tsx
@@ -0,0 +1,56 @@
+import {
+ type ForwardRefRenderFunction,
+ forwardRef,
+ type HTMLAttributes,
+} from 'react';
+import { useIntl } from 'react-intl';
+import { Article } from '../../atoms';
+import { Breadcrumbs, type BreadcrumbsItem } from '../../organisms/nav';
+import styles from './page.module.scss';
+
+export type PageProps = HTMLAttributes<HTMLDivElement> & {
+ /**
+ * The breadcrumbs items.
+ */
+ breadcrumbs?: BreadcrumbsItem[];
+ /**
+ * Add an extra padding to the body when there are no footer/comments.
+ *
+ * Note: this should be refactored when `:has()` pseudo-class will have a
+ * better support.
+ *
+ * @default false
+ */
+ isBodyLastChild?: boolean;
+};
+
+const PageWithRef: ForwardRefRenderFunction<HTMLDivElement, PageProps> = (
+ { breadcrumbs, children, className = '', isBodyLastChild = false, ...props },
+ ref
+) => {
+ const wrapperClass = `${styles.wrapper} ${className}`;
+ const pageClass = `${styles.page} ${
+ styles[isBodyLastChild ? 'page--body-last' : '']
+ }`;
+ const intl = useIntl();
+ const breadcrumbsLabel = intl.formatMessage({
+ defaultMessage: 'Breadcrumbs',
+ description: 'Page: an accessible name for the breadcrumb nav.',
+ id: '/TTRRX',
+ });
+
+ return (
+ <div {...props} className={wrapperClass} ref={ref}>
+ {breadcrumbs ? (
+ <Breadcrumbs
+ aria-label={breadcrumbsLabel}
+ className={styles.breadcrumbs}
+ items={breadcrumbs}
+ />
+ ) : null}
+ <Article className={pageClass}>{children}</Article>
+ </div>
+ );
+};
+
+export const Page = forwardRef(PageWithRef);