From 5d3e8a4d0c2ce2ad8f22df857ab3ce54fcfc38ac Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Fri, 3 Nov 2023 12:22:47 +0100 Subject: refactor(components): replace Toolbar with Navbar component * remove SearchModal and SettingsModal components * add a generic NavbarItem component (instead of the previous toolbar items to avoid unreadable styles...) * move FlippingLabel component logic into NavbarItem since it is only used here --- .../organisms/navbar/navbar-item/navbar-item.tsx | 179 +++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 src/components/organisms/navbar/navbar-item/navbar-item.tsx (limited to 'src/components/organisms/navbar/navbar-item/navbar-item.tsx') diff --git a/src/components/organisms/navbar/navbar-item/navbar-item.tsx b/src/components/organisms/navbar/navbar-item/navbar-item.tsx new file mode 100644 index 0000000..8ef6ce3 --- /dev/null +++ b/src/components/organisms/navbar/navbar-item/navbar-item.tsx @@ -0,0 +1,179 @@ +import { + type ReactNode, + useCallback, + type ForwardRefRenderFunction, + forwardRef, + useRef, +} from 'react'; +import { + useOnClickOutside, + type useOnClickOutsideHandler, +} from '../../../../utils/hooks'; +import { + Checkbox, + Heading, + Icon, + type IconShape, + Label, + Overlay, + Flip, + FlipSide, + type ListItemProps, + ListItem, +} from '../../../atoms'; +import { Modal } from '../../../molecules'; +import styles from './navbar-item.module.scss'; + +export type NavbarItemProps = Omit< + ListItemProps, + 'children' | 'hideMarker' | 'id' +> & { + /** + * The modal contents. + */ + children: ReactNode; + /** + * An icon to illustrate the nav item. + */ + icon: IconShape; + /** + * The item id. + */ + id: string; + /** + * Should the modal be visible? + */ + isActive: boolean; + /** + * An accessible name for the nav item. + */ + label: string; + /** + * The modal heading. + */ + modalHeading?: string; + /** + * Make the modal always visible from the given breakpoint. + */ + modalVisibleFrom?: 'sm' | 'md'; + /** + * A callback function to handle modal deactivation. + */ + onDeactivate?: () => void; + /** + * A callback function to handle modal toggle. + */ + onToggle: () => void; + /** + * Should we add the icon on the modal? + * + * @default false + */ + showIconOnModal?: boolean; +}; + +const NavbarItemWithRef: ForwardRefRenderFunction< + HTMLLIElement, + NavbarItemProps +> = ( + { + children, + className = '', + icon, + id, + isActive, + label, + modalHeading, + modalVisibleFrom, + onDeactivate, + onToggle, + showIconOnModal = false, + ...props + }, + ref +) => { + const itemClass = [ + styles.item, + modalVisibleFrom + ? styles[`item--hidden-controller-${modalVisibleFrom}`] + : '', + className, + ].join(' '); + const labelRef = useRef(null); + const checkboxRef = useRef(null); + const deactivateItem: useOnClickOutsideHandler = useCallback( + (e) => { + const isCheckbox = + e.target && checkboxRef.current?.contains(e.target as Node); + const isLabel = e.target && labelRef.current?.contains(e.target as Node); + + if (onDeactivate && !isCheckbox && !isLabel) onDeactivate(); + }, + [onDeactivate] + ); + const modalRef = useOnClickOutside(deactivateItem); + + return ( + + + + + + {modalHeading} + + ) : null + } + icon={showIconOnModal ? : null} + ref={modalRef} + > + {children} + + + + ); +}; + +export const NavbarItem = forwardRef(NavbarItemWithRef); -- cgit v1.2.3