blob: 711ade1bccfea51e291e13dd3dc47f3abda5f6f8 (
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
|
import { FC } from 'react';
import styles from './list.module.scss';
export type ListItem = {
/**
* Nested list.
*/
child?: ListItem[];
/**
* Item id.
*/
id: string;
/**
* Item value.
*/
value: any;
};
export type ListProps = {
/**
* Set additional classnames to the list wrapper.
*/
className?: string;
/**
* An array of list items.
*/
items: ListItem[];
/**
* Set additional classnames to the list items.
*/
itemsClassName?: string;
/**
* The list kind.
*/
kind?: 'ordered' | 'unordered' | 'flex';
/**
* Set margin between list items. Default: true.
*/
withMargin?: boolean;
};
/**
* List component
*
* Render either an ordered or an unordered list.
*/
const List: FC<ListProps> = ({
className = '',
items,
itemsClassName = '',
kind = 'unordered',
withMargin = true,
}) => {
const ListTag = kind === 'ordered' ? 'ol' : 'ul';
const kindClass = `list--${kind}`;
const marginClass = withMargin ? 'list--has-margin' : 'list--no-margin';
/**
* Retrieve the list items.
* @param array - An array of items.
* @returns {JSX.Element[]} - An array of li elements.
*/
const getItems = (array: ListItem[]): JSX.Element[] => {
return array.map(({ child, id, value }) => (
<li key={id} className={`${styles.list__item} ${itemsClassName}`}>
{value}
{child && (
<ListTag
className={`${styles.list} ${styles[kindClass]} ${styles[marginClass]} ${className}`}
>
{getItems(child)}
</ListTag>
)}
</li>
));
};
return (
<ListTag
className={`${styles.list} ${styles[kindClass]} ${styles[marginClass]} ${className}`}
>
{getItems(items)}
</ListTag>
);
};
export default List;
|