summaryrefslogtreecommitdiffstats
path: root/src/components/atoms/lists/description-list.tsx
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2022-05-24 19:35:12 +0200
committerGitHub <noreply@github.com>2022-05-24 19:35:12 +0200
commitc85ab5ad43ccf52881ee224672c41ec30021cf48 (patch)
tree8058808d9bfca19383f120c46b34d99ff2f89f63 /src/components/atoms/lists/description-list.tsx
parent52404177c07a2aab7fc894362fb3060dff2431a0 (diff)
parent11b9de44a4b2f305a6a484187805e429b2767118 (diff)
refactor: use storybook and atomic design (#16)
BREAKING CHANGE: rewrite most of the Typescript types, so the content format (the meta in particular) needs to be updated.
Diffstat (limited to 'src/components/atoms/lists/description-list.tsx')
-rw-r--r--src/components/atoms/lists/description-list.tsx103
1 files changed, 103 insertions, 0 deletions
diff --git a/src/components/atoms/lists/description-list.tsx b/src/components/atoms/lists/description-list.tsx
new file mode 100644
index 0000000..a8e2d53
--- /dev/null
+++ b/src/components/atoms/lists/description-list.tsx
@@ -0,0 +1,103 @@
+import { FC } from 'react';
+import DescriptionListItem, {
+ type DescriptionListItemProps,
+} from './description-list-item';
+import styles from './description-list.module.scss';
+
+export type DescriptionListItem = {
+ /**
+ * The item id.
+ */
+ id: string;
+ /**
+ * The list item layout.
+ */
+ layout?: DescriptionListItemProps['layout'];
+ /**
+ * A list label.
+ */
+ label: DescriptionListItemProps['label'];
+ /**
+ * An array of values for the list item.
+ */
+ value: DescriptionListItemProps['value'];
+};
+
+export type DescriptionListProps = {
+ /**
+ * Set additional classnames to the list wrapper.
+ */
+ className?: string;
+ /**
+ * Set additional classnames to the `dt`/`dd` couple wrapper.
+ */
+ groupClassName?: string;
+ /**
+ * The list items.
+ */
+ items: DescriptionListItem[];
+ /**
+ * Set additional classnames to the `dt` element.
+ */
+ labelClassName?: string;
+ /**
+ * The list layout. Default: column.
+ */
+ layout?: 'inline' | 'column';
+ /**
+ * Set additional classnames to the `dd` element.
+ */
+ valueClassName?: string;
+ /**
+ * If true, use a slash to delimitate multiple values.
+ */
+ withSeparator?: DescriptionListItemProps['withSeparator'];
+};
+
+/**
+ * DescriptionList component
+ *
+ * Render a description list.
+ */
+const DescriptionList: FC<DescriptionListProps> = ({
+ className = '',
+ groupClassName = '',
+ items,
+ labelClassName = '',
+ layout = 'column',
+ valueClassName = '',
+ withSeparator,
+}) => {
+ const layoutModifier = `list--${layout}`;
+
+ /**
+ * Retrieve the description list items.
+ *
+ * @param {DescriptionListItem[]} listItems - An array of items.
+ * @returns {JSX.Element[]} The description list items.
+ */
+ const getItems = (listItems: DescriptionListItem[]): JSX.Element[] => {
+ return listItems.map(({ id, layout: itemLayout, label, value }) => {
+ return (
+ <DescriptionListItem
+ key={id}
+ label={label}
+ value={value}
+ layout={itemLayout}
+ className={groupClassName}
+ descriptionClassName={valueClassName}
+ termClassName={labelClassName}
+ withSeparator={withSeparator}
+ />
+ );
+ });
+ };
+
+ return (
+ <dl className={`${styles.list} ${styles[layoutModifier]} ${className}`}>
+ {getItems(items)}
+ </dl>
+ );
+};
+
+export default DescriptionList;