From a3a4c50f26b8750ae1c87f1f1103b84b7d2e6315 Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Tue, 14 Nov 2023 15:11:22 +0100 Subject: 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 --- .../widgets/links-widget/links-widget.tsx | 78 ++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/components/organisms/widgets/links-widget/links-widget.tsx (limited to 'src/components/organisms/widgets/links-widget/links-widget.tsx') 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[]) => ( + + {data.map((item) => ( + + + {item.label} + + {item.child?.length ? getLinksList(item.child) : null} + + ))} + + ), + [isOrdered, listClass] + ); + + return ( + + {getLinksList(items)} + + ); +}; + +/** + * LinksWidget component + * + * Render a list of links inside a widget. + */ +export const LinksWidget = forwardRef(LinksWidgetWithRef); -- cgit v1.2.3