diff options
| author | Armand Philippot <git@armandphilippot.com> | 2023-11-14 15:11:22 +0100 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2023-11-14 19:06:42 +0100 |
| commit | a3a4c50f26b8750ae1c87f1f1103b84b7d2e6315 (patch) | |
| tree | ae286c7c6b3ab4f556f20adf5e42b24641351296 /src/components/organisms/widgets/links-widget/links-widget.tsx | |
| parent | 50f1c501a87ef5f5650750dbeca797e833ec7c3a (diff) | |
refactor(components): replace LinksListWidget with LinksWidget
* avoid List component repeat
* rewrite tests and CSS
* add an id to LinksWidgetItemData (previously LinksListItems) type
because the label could be duplicated
Diffstat (limited to 'src/components/organisms/widgets/links-widget/links-widget.tsx')
| -rw-r--r-- | src/components/organisms/widgets/links-widget/links-widget.tsx | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/components/organisms/widgets/links-widget/links-widget.tsx b/src/components/organisms/widgets/links-widget/links-widget.tsx new file mode 100644 index 0000000..e28e15f --- /dev/null +++ b/src/components/organisms/widgets/links-widget/links-widget.tsx @@ -0,0 +1,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); |
