aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/molecules/meta-list/meta-item/meta-item.tsx
blob: c5223c28c209ec5976d7dbeec91ee36d22ab0d59 (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
78
79
80
81
82
83
84
85
86
87
88
89
90
import {
  type ForwardRefRenderFunction,
  type ReactElement,
  type ReactNode,
  forwardRef,
} from 'react';
import { Description, Group, type GroupProps, Term } from '../../../atoms';
import styles from './meta-item.module.scss';

export type MetaValue = string | ReactElement;

export type MetaValues = {
  id: string;
  value: MetaValue;
};

export type MetaItemProps = Omit<GroupProps, 'children' | 'spacing'> & {
  /**
   * Should the values be bordered?
   *
   * @default false
   */
  hasBorderedValues?: boolean;
  /**
   * Should the values be inlined?
   *
   * @warning If you use it make sure the value is larger than the label. It
   * could mess up your design since we are removing the label width.
   *
   * @default false
   */
  hasInlinedValues?: boolean;
  /**
   * Should the label and values be centered?
   *
   * @default false
   */
  isCentered?: boolean;
  /**
   * The item label.
   */
  label: ReactNode;
  /**
   * The item value or values.
   */
  value: MetaValue | MetaValues[];
};

const MetaItemWithRef: ForwardRefRenderFunction<
  HTMLDivElement,
  MetaItemProps
> = (
  {
    className = '',
    hasBorderedValues = false,
    hasInlinedValues = false,
    isCentered = false,
    isInline = false,
    label,
    value,
    ...props
  },
  ref
) => {
  const itemClass = [
    styles.item,
    styles[hasBorderedValues ? 'item--bordered-values' : ''],
    styles[hasInlinedValues ? 'item--inlined-values' : ''],
    styles[isCentered ? 'item--centered' : ''],
    styles[isInline ? 'item--inlined' : 'item--stacked'],
    className,
  ].join(' ');

  return (
    <Group {...props} className={itemClass} isInline={isInline} ref={ref}>
      <Term className={styles.label}>{label}</Term>
      {Array.isArray(value) ? (
        value.map((item) => (
          <Description className={styles.value} key={item.id}>
            {item.value}
          </Description>
        ))
      ) : (
        <Description className={styles.value}>{value}</Description>
      )}
    </Group>
  );
};

export const MetaItem = forwardRef(MetaItemWithRef);