aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/atoms/lists/description-list/description-list.tsx
blob: cc225fe1f19328a456ed05ebb8fe730dd3e7d799 (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
import {
  forwardRef,
  type CSSProperties,
  type HTMLAttributes,
  type ReactNode,
  type ForwardRefRenderFunction,
} from 'react';
import type { Spacing } from '../../../../types';
import styles from './description-list.module.scss';

export type DescriptionListProps = Omit<
  HTMLAttributes<HTMLDListElement>,
  'children'
> & {
  /**
   * The list items or groups.
   */
  children: ReactNode;
  /**
   * Should the list be inlined?
   *
   * @default false
   */
  isInline?: boolean;
  /**
   * Define the spacing between list items.
   *
   * @default null
   */
  spacing?: Spacing | null;
};

const DescriptionListWithRef: ForwardRefRenderFunction<
  HTMLDListElement,
  DescriptionListProps
> = (
  {
    children,
    className = '',
    isInline = false,
    spacing = null,
    style,
    ...props
  },
  ref
) => {
  const itemSpacing = spacing === null ? 0 : `var(--spacing-${spacing})`;
  const layoutClass = styles[isInline ? 'list--inline' : 'list--stack'];
  const listClass = `${styles.list} ${layoutClass} ${className}`;
  const listStyles = {
    ...style,
    '--itemSpacing': itemSpacing,
  } as CSSProperties;

  return (
    <dl {...props} className={listClass} ref={ref} style={listStyles}>
      {children}
    </dl>
  );
};

/**
 * DescriptionList component
 *
 * Render a description list.
 */
export const DescriptionList = forwardRef(DescriptionListWithRef);