From 0d59a6d2995b4119865271ed1908ede0bb96497c Mon Sep 17 00:00:00 2001
From: Armand Philippot <git@armandphilippot.com>
Date: Mon, 9 May 2022 18:19:38 +0200
Subject: refactor: rewrite DescriptionList and Meta components

The meta can have different layout. The previous implementation was not
enough to easily change the layout. Also, I prefer to restrict the meta
types and it prevents me to repeat myself for the labels.
---
 .../atoms/lists/description-list-item.tsx          | 73 ++++++++++++++++++++++
 1 file changed, 73 insertions(+)
 create mode 100644 src/components/atoms/lists/description-list-item.tsx

(limited to 'src/components/atoms/lists/description-list-item.tsx')

diff --git a/src/components/atoms/lists/description-list-item.tsx b/src/components/atoms/lists/description-list-item.tsx
new file mode 100644
index 0000000..9505d01
--- /dev/null
+++ b/src/components/atoms/lists/description-list-item.tsx
@@ -0,0 +1,73 @@
+import { FC, ReactNode, useId } from 'react';
+import styles from './description-list-item.module.scss';
+
+export type ItemLayout = 'inline' | 'inline-values' | 'stacked';
+
+export type DescriptionListItemProps = {
+  /**
+   * Set additional classnames to the list item wrapper.
+   */
+  className?: string;
+  /**
+   * Set additional classnames to the list item description.
+   */
+  descriptionClassName?: string;
+  /**
+   * The item label.
+   */
+  label: string;
+  /**
+   * The item layout.
+   */
+  layout?: ItemLayout;
+  /**
+   * Set additional classnames to the list item term.
+   */
+  termClassName?: string;
+  /**
+   * The item value.
+   */
+  value: ReactNode | ReactNode[];
+  /**
+   * If true, use a slash to delimitate multiple values.
+   */
+  withSeparator?: boolean;
+};
+
+/**
+ * DescriptionListItem component
+ *
+ * Render a couple of dt/dd wrapped in a div.
+ */
+const DescriptionListItem: FC<DescriptionListItemProps> = ({
+  className = '',
+  descriptionClassName = '',
+  label,
+  termClassName = '',
+  value,
+  layout = 'stacked',
+  withSeparator = false,
+}) => {
+  const id = useId();
+  const layoutStyles = styles[`wrapper--${layout}`];
+  const separatorStyles = withSeparator ? styles['wrapper--has-separator'] : '';
+  const itemValues = Array.isArray(value) ? value : [value];
+
+  return (
+    <div
+      className={`${styles.wrapper} ${layoutStyles} ${separatorStyles} ${className}`}
+    >
+      <dt className={`${styles.term} ${termClassName}`}>{label}</dt>
+      {itemValues.map((currentValue, index) => (
+        <dd
+          key={`${id}-${index}`}
+          className={`${styles.description} ${descriptionClassName}`}
+        >
+          {currentValue}
+        </dd>
+      ))}
+    </div>
+  );
+};
+
+export default DescriptionListItem;
-- 
cgit v1.2.3

