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
|
import { type ForwardRefRenderFunction, forwardRef, useCallback } from 'react';
import { Link, List, ListItem } from '../../../atoms';
import { Collapsible, type CollapsibleProps } from '../../../molecules';
import styles from './links-widget.module.scss';
export type LinksWidgetItemData = {
/**
* An array of name/url couple child of this list item.
*/
child?: LinksWidgetItemData[];
/**
* The item id.
*/
id: string;
/**
* The item name.
*/
label: string;
/**
* The item url.
*/
url: string;
};
export type LinksWidgetProps = Omit<
CollapsibleProps,
'children' | 'disablePadding' | 'hasBorders'
> & {
/**
* Should the links be ordered?
*
* @default false
*/
isOrdered?: boolean;
/**
* The links.
*/
items: LinksWidgetItemData[];
};
const LinksWidgetWithRef: ForwardRefRenderFunction<
HTMLDivElement,
LinksWidgetProps
> = ({ isOrdered = false, items, ...props }, ref) => {
const listClass = [
styles.list,
styles[isOrdered ? 'list--ordered' : 'list--unordered'],
].join(' ');
const getLinksList = useCallback(
(data: LinksWidgetItemData[]) => (
<List className={listClass} hideMarker isOrdered={isOrdered}>
{data.map((item) => (
<ListItem className={styles.item} key={item.id}>
<Link className={styles.link} href={item.url}>
{item.label}
</Link>
{item.child?.length ? getLinksList(item.child) : null}
</ListItem>
))}
</List>
),
[isOrdered, listClass]
);
return (
<Collapsible {...props} disablePadding hasBorders ref={ref}>
{getLinksList(items)}
</Collapsible>
);
};
/**
* LinksWidget component
*
* Render a list of links inside a widget.
*/
export const LinksWidget = forwardRef(LinksWidgetWithRef);
|