aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/molecules/layout
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/molecules/layout')
-rw-r--r--src/components/molecules/layout/card.tsx10
-rw-r--r--src/components/molecules/layout/meta.module.scss17
-rw-r--r--src/components/molecules/layout/meta.stories.tsx34
-rw-r--r--src/components/molecules/layout/meta.test.tsx8
-rw-r--r--src/components/molecules/layout/meta.tsx103
-rw-r--r--src/components/molecules/layout/page-footer.tsx4
-rw-r--r--src/components/molecules/layout/page-header.tsx9
7 files changed, 81 insertions, 104 deletions
diff --git a/src/components/molecules/layout/card.tsx b/src/components/molecules/layout/card.tsx
index 722e5a5..c9e7a90 100644
--- a/src/components/molecules/layout/card.tsx
+++ b/src/components/molecules/layout/card.tsx
@@ -72,15 +72,7 @@ export const Card: FC<CardProps> = ({
{tagline ? <div className={styles.tagline}>{tagline}</div> : null}
{meta ? (
<footer className={styles.footer}>
- <Meta
- data={meta}
- // eslint-disable-next-line react/jsx-no-literals -- Hardcoded config
- layout="inline"
- className={styles.list}
- groupClassName={styles.meta__item}
- labelClassName={styles.meta__label}
- valueClassName={styles.meta__value}
- />
+ <Meta className={styles.list} data={meta} spacing="sm" />
</footer>
) : null}
</article>
diff --git a/src/components/molecules/layout/meta.module.scss b/src/components/molecules/layout/meta.module.scss
index f572b65..26faac3 100644
--- a/src/components/molecules/layout/meta.module.scss
+++ b/src/components/molecules/layout/meta.module.scss
@@ -1,3 +1,16 @@
-.value {
- word-break: break-all;
+.list {
+ .description:not(:first-of-type) {
+ &::before {
+ display: inline;
+ float: left;
+ content: "/";
+ margin-right: var(--itemSpacing);
+ }
+ }
+
+ &--stack {
+ .term {
+ flex: 0 0 100%;
+ }
+ }
}
diff --git a/src/components/molecules/layout/meta.stories.tsx b/src/components/molecules/layout/meta.stories.tsx
index 50ed252..6faa265 100644
--- a/src/components/molecules/layout/meta.stories.tsx
+++ b/src/components/molecules/layout/meta.stories.tsx
@@ -1,7 +1,5 @@
-import { ComponentMeta, ComponentStory } from '@storybook/react';
-import descriptionListItemStories from '../../atoms/lists/description-list-group.stories';
-import descriptionListStories from '../../atoms/lists/description-list.stories';
-import { Meta as MetaComponent, MetaData } from './meta';
+import type { ComponentMeta, ComponentStory } from '@storybook/react';
+import { Meta as MetaComponent, type MetaData } from './meta';
/**
* Meta - Storybook Meta
@@ -9,12 +7,8 @@ import { Meta as MetaComponent, MetaData } from './meta';
export default {
title: 'Molecules/Layout',
component: MetaComponent,
- args: {
- itemsLayout: 'inline-values',
- withSeparator: false,
- },
+ args: {},
argTypes: {
- className: descriptionListStories.argTypes?.className,
data: {
description: 'The page metadata.',
type: {
@@ -23,24 +17,6 @@ export default {
value: {},
},
},
- groupClassName: descriptionListStories.argTypes?.groupClassName,
- itemsLayout: {
- ...descriptionListItemStories.argTypes?.layout,
- table: {
- ...descriptionListItemStories.argTypes?.layout?.table,
- defaultValue: { summary: 'inline-values' },
- },
- },
- labelClassName: descriptionListStories.argTypes?.labelClassName,
- layout: descriptionListStories.argTypes?.layout,
- valueClassName: descriptionListStories.argTypes?.valueClassName,
- withSeparator: {
- ...descriptionListStories.argTypes?.withSeparator,
- table: {
- ...descriptionListStories.argTypes?.withSeparator?.table,
- defaultValue: { summary: true },
- },
- },
},
} as ComponentMeta<typeof MetaComponent>;
@@ -51,10 +27,10 @@ const Template: ComponentStory<typeof MetaComponent> = (args) => (
const data: MetaData = {
publication: { date: '2022-04-09', time: '01:04:00' },
thematics: [
- <a key="category1" href="#">
+ <a key="category1" href="#a">
Category 1
</a>,
- <a key="category2" href="#">
+ <a key="category2" href="#b">
Category 2
</a>,
],
diff --git a/src/components/molecules/layout/meta.test.tsx b/src/components/molecules/layout/meta.test.tsx
index f19c408..0635fc3 100644
--- a/src/components/molecules/layout/meta.test.tsx
+++ b/src/components/molecules/layout/meta.test.tsx
@@ -1,15 +1,15 @@
import { describe, expect, it } from '@jest/globals';
-import { render, screen } from '../../../../tests/utils';
+import { render, screen as rtlScreen } from '../../../../tests/utils';
import { getFormattedDate } from '../../../utils/helpers';
import { Meta } from './meta';
const data = {
publication: { date: '2022-04-09' },
thematics: [
- <a key="category1" href="#">
+ <a key="category1" href="#a">
Category 1
</a>,
- <a key="category2" href="#">
+ <a key="category2" href="#b">
Category 2
</a>,
],
@@ -19,7 +19,7 @@ describe('Meta', () => {
it('format a date string', () => {
render(<Meta data={data} />);
expect(
- screen.getByText(getFormattedDate(data.publication.date))
+ rtlScreen.getByText(getFormattedDate(data.publication.date))
).toBeInTheDocument();
});
});
diff --git a/src/components/molecules/layout/meta.tsx b/src/components/molecules/layout/meta.tsx
index 53128a7..094c420 100644
--- a/src/components/molecules/layout/meta.tsx
+++ b/src/components/molecules/layout/meta.tsx
@@ -1,16 +1,19 @@
-import { FC, ReactNode } from 'react';
+import type { FC, ReactNode } from 'react';
import { useIntl } from 'react-intl';
import { getFormattedDate, getFormattedTime } from '../../../utils/helpers';
import {
DescriptionList,
type DescriptionListProps,
- type DescriptionListItem,
Link,
+ Group,
+ Term,
+ Description,
} from '../../atoms';
+import styles from './meta.module.scss';
export type CustomMeta = {
label: string;
- value: ReactNode | ReactNode[];
+ value: ReactNode;
};
export type MetaComments = {
@@ -106,24 +109,16 @@ export type MetaData = {
website?: string;
};
-export type MetaKey = keyof MetaData;
+const isCustomMeta = (
+ key: keyof MetaData,
+ _value: unknown
+): _value is MetaData['custom'] => key === 'custom';
-export type MetaProps = Omit<
- DescriptionListProps,
- 'items' | 'withSeparator'
-> & {
+export type MetaProps = Omit<DescriptionListProps, 'children'> & {
/**
* The meta data.
*/
data: MetaData;
- /**
- * The items layout.
- */
- itemsLayout?: DescriptionListItem['layout'];
- /**
- * If true, use a slash to delimitate multiple values. Default: true.
- */
- withSeparator?: DescriptionListProps['withSeparator'];
};
/**
@@ -132,11 +127,13 @@ export type MetaProps = Omit<
* Renders the given metadata.
*/
export const Meta: FC<MetaProps> = ({
+ className = '',
data,
- itemsLayout = 'inline-values',
- withSeparator = true,
+ isInline = false,
...props
}) => {
+ const layoutClass = styles[isInline ? 'list--inline' : 'list--stack'];
+ const listClass = `${styles.list} ${layoutClass} ${className}`;
const intl = useIntl();
/**
@@ -316,7 +313,7 @@ export const Meta: FC<MetaProps> = ({
* @param {ValueOf<MetaData>} value - The meta value.
* @returns {string|ReactNode|ReactNode[]} - The formatted value.
*/
- const getValue = <T extends MetaKey>(
+ const getValue = <T extends keyof MetaData>(
key: T,
value: MetaData[T]
): string | ReactNode | ReactNode[] => {
@@ -338,12 +335,11 @@ export const Meta: FC<MetaProps> = ({
{ postsCount: value as number }
);
case 'website':
- const url = value as string;
- return (
- <Link href={url} external={true}>
- {url}
+ return typeof value === 'string' ? (
+ <Link href={value} external={true}>
+ {value}
</Link>
- );
+ ) : null;
default:
return value as string | ReactNode | ReactNode[];
}
@@ -355,36 +351,45 @@ export const Meta: FC<MetaProps> = ({
* @param {MetaData} items - The meta.
* @returns {DescriptionListItem[]} The formatted description list items.
*/
- const getItems = (items: MetaData): DescriptionListItem[] => {
- const listItems: DescriptionListItem[] = Object.entries(items)
- .map(([key, value]) => {
- if (!key || !value) return;
-
- const metaKey = key as MetaKey;
+ const getItems = (items: MetaData) => {
+ const entries = Object.entries(items) as [
+ keyof MetaData,
+ MetaData[keyof MetaData],
+ ][];
+ const listItems = entries.map(([key, meta]) => {
+ if (!meta) return null;
- return {
- id: metaKey,
- label:
- metaKey === 'custom'
- ? (value as CustomMeta).label
- : getLabel(metaKey),
- layout: itemsLayout,
- value:
- metaKey === 'custom' && (value as CustomMeta)
- ? (value as CustomMeta).value
- : getValue(metaKey, value),
- } as DescriptionListItem;
- })
- .filter((item): item is DescriptionListItem => !!item);
+ return (
+ <Group isInline key={key} spacing="2xs">
+ <Term className={styles.term}>
+ {isCustomMeta(key, meta) ? meta.label : getLabel(key)}
+ </Term>
+ {Array.isArray(meta) ? (
+ meta.map((singleMeta, index) => (
+ /* eslint-disable-next-line react/no-array-index-key -- Unsafe,
+ * but also temporary. This component should be removed or
+ * refactored. */
+ <Description className={styles.description} key={index}>
+ {isCustomMeta(key, singleMeta)
+ ? singleMeta
+ : getValue(key, singleMeta)}
+ </Description>
+ ))
+ ) : (
+ <Description className={styles.description}>
+ {isCustomMeta(key, meta) ? meta.value : getValue(key, meta)}
+ </Description>
+ )}
+ </Group>
+ );
+ });
return listItems;
};
return (
- <DescriptionList
- {...props}
- items={getItems(data)}
- withSeparator={withSeparator}
- />
+ <DescriptionList {...props} className={listClass} isInline={isInline}>
+ {getItems(data)}
+ </DescriptionList>
);
};
diff --git a/src/components/molecules/layout/page-footer.tsx b/src/components/molecules/layout/page-footer.tsx
index 5f3b176..375cbc4 100644
--- a/src/components/molecules/layout/page-footer.tsx
+++ b/src/components/molecules/layout/page-footer.tsx
@@ -15,7 +15,5 @@ export type PageFooterProps = Omit<FooterProps, 'children'> & {
* Render a footer to display page meta.
*/
export const PageFooter: FC<PageFooterProps> = ({ meta, ...props }) => (
- <Footer {...props}>
- {meta ? <Meta data={meta} withSeparator={false} /> : null}
- </Footer>
+ <Footer {...props}>{meta ? <Meta data={meta} /> : null}</Footer>
);
diff --git a/src/components/molecules/layout/page-header.tsx b/src/components/molecules/layout/page-header.tsx
index 92650c5..b727cc1 100644
--- a/src/components/molecules/layout/page-header.tsx
+++ b/src/components/molecules/layout/page-header.tsx
@@ -56,14 +56,7 @@ export const PageHeader: FC<PageHeaderProps> = ({
{title}
</Heading>
{meta ? (
- <Meta
- className={styles.meta}
- data={meta}
- // eslint-disable-next-line react/jsx-no-literals -- Layout allowed
- itemsLayout="inline"
- // eslint-disable-next-line react/jsx-no-literals -- Layout allowed
- layout="column"
- />
+ <Meta className={styles.meta} data={meta} isInline spacing="xs" />
) : null}
{intro ? getIntro() : null}
</div>