summaryrefslogtreecommitdiffstats
path: root/src/components/atoms/lists/description-list.tsx
blob: a8e2d53673bfaab802f981225c6a563df370c7c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-w
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;
s="o">); text-decoration-color: var(--color-primary-light); text-decoration-thickness: 0.25ex; } &:active { background: var(--color-bg-tertiary); text-decoration-color: transparent; text-decoration-thickness: 0; } } &--ordered { @extend %reset-ordered-list; counter-reset: link; .list__link { counter-increment: link; &::before { padding-right: var(--spacing-2xs); content: counters(link, ".") ". "; color: var(--color-secondary); } } } &--unordered { @extend %reset-list; } &__item { &:not(:last-child) { border-bottom: fun.convert-px(1) solid var(--color-primary); } > .list { .list__link { padding-left: var(--spacing-md); } .list__item > .list { .list__link { padding-left: var(--spacing-xl); } } } } } }