From 20b82299e5e6d124ac8143ff8eb30364db7fca67 Mon Sep 17 00:00:00 2001 From: William Grosset Date: Sun, 14 Jan 2024 13:04:43 -0700 Subject: [PATCH] feat(toolbar): add onOutsideClick prop --- src/Toolbar/Toolbar.spec.tsx | 11 +++++++++++ src/Toolbar/Toolbar.tsx | 31 ++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/Toolbar/Toolbar.spec.tsx b/src/Toolbar/Toolbar.spec.tsx index dfe060a4..4576c322 100644 --- a/src/Toolbar/Toolbar.spec.tsx +++ b/src/Toolbar/Toolbar.spec.tsx @@ -26,4 +26,15 @@ describe('', () => { expect(toolbar).toHaveStyleRule('padding', '0'); }); }); + + describe('prop: onOutsideClick', () => { + it('should fire callback on container click', () => { + const mockCallBack = jest.fn(); + const { container } = render(); + + container.click(); + + expect(mockCallBack).toHaveBeenCalled(); + }); + }); }); diff --git a/src/Toolbar/Toolbar.tsx b/src/Toolbar/Toolbar.tsx index 032897cd..6737d5db 100644 --- a/src/Toolbar/Toolbar.tsx +++ b/src/Toolbar/Toolbar.tsx @@ -1,9 +1,11 @@ -import React, { forwardRef } from 'react'; +import React, { forwardRef, useRef, useEffect } from 'react'; import styled from 'styled-components'; +import useForkRef from '../common/hooks/useForkRef'; type ToolbarProps = { children?: React.ReactNode; noPadding?: boolean; + onOutsideClick?: () => void; } & React.HTMLAttributes; const StyledToolbar = styled.div` @@ -14,11 +16,34 @@ const StyledToolbar = styled.div` `; const Toolbar = forwardRef(function Toolbar( - { children, noPadding = false, ...otherProps }, + { children, noPadding = false, onOutsideClick, ...otherProps }, ref ) { + const toolbarRef = useRef(null); + const handleRef = useForkRef(ref, toolbarRef); + + useEffect(() => { + if (!onOutsideClick) { + return () => {}; + } + + const handleOutsideClick = (e: MouseEvent) => { + const target = e.target as Node; + + if (!toolbarRef.current?.contains(target)) { + onOutsideClick(); + } + }; + + document.addEventListener('click', handleOutsideClick); + + return () => { + document.removeEventListener('click', handleOutsideClick); + }; + }, [ref, onOutsideClick]); + return ( - + {children} );