From 3c96478849a9eff607dda729cfdbd591cffd292e Mon Sep 17 00:00:00 2001 From: brooketopcoder Date: Thu, 31 Mar 2022 09:30:54 -0700 Subject: [PATCH 1/2] PROD-1086 #comment determine if a component is visible if it's clicked outside #time 1h --- .../profile-logged-in/ProfileLoggedIn.tsx | 22 +++++++++++++-- .../profile-panel/ProfilePanel.tsx | 8 ++++-- src/lib/form/validator-functions/index.ts | 1 - .../component-visible.functions.test.tsx | 6 ++++ .../component-visible.functions.tsx | 28 +++++++++++++++++++ .../component-visible-functions/index.ts | 1 + src/lib/functions/index.ts | 1 + src/lib/index.ts | 4 +++ 8 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 src/lib/functions/component-visible-functions/component-visible.functions.test.tsx create mode 100644 src/lib/functions/component-visible-functions/component-visible.functions.tsx create mode 100644 src/lib/functions/component-visible-functions/index.ts diff --git a/src/header/utility-selectors/UtilitySelector/ProfileSelector/profile-logged-in/ProfileLoggedIn.tsx b/src/header/utility-selectors/UtilitySelector/ProfileSelector/profile-logged-in/ProfileLoggedIn.tsx index 59c01a6af..b8d0fc6bb 100644 --- a/src/header/utility-selectors/UtilitySelector/ProfileSelector/profile-logged-in/ProfileLoggedIn.tsx +++ b/src/header/utility-selectors/UtilitySelector/ProfileSelector/profile-logged-in/ProfileLoggedIn.tsx @@ -2,10 +2,12 @@ import { Dispatch, FC, SetStateAction, useContext, useState } from 'react' import { Avatar, + ComponentVisible, IconOutline, logInfo, profileContext, ProfileContextData, + useHideClickOutside, } from '../../../../../lib' import { ProfilePanel } from './profile-panel' @@ -20,18 +22,33 @@ const ProfileLoggedIn: FC = (props: ProfileLoggedInProps) const { profile }: ProfileContextData = useContext(profileContext) const [profilePanelOpen, setProfilePanelOpen]: [boolean, Dispatch>] = useState(false) + const { + isComponentVisible, + ref, + setIsComponentVisible, + }: ComponentVisible = useHideClickOutside(false) + if (!profile) { logInfo('tried to render the logged in profile w/out a profile') return <> } function toggleProfilePanel(): void { - setProfilePanelOpen(!profilePanelOpen) + const toggleTo: boolean = !profilePanelOpen + setProfilePanelOpen(toggleTo) + setIsComponentVisible(toggleTo) + } + + if (!isComponentVisible && profilePanelOpen) { + setProfilePanelOpen(isComponentVisible) } return ( <> -
toggleProfilePanel()} > +
= (props: ProfileLoggedInProps)
{profilePanelOpen && ( diff --git a/src/header/utility-selectors/UtilitySelector/ProfileSelector/profile-logged-in/profile-panel/ProfilePanel.tsx b/src/header/utility-selectors/UtilitySelector/ProfileSelector/profile-logged-in/profile-panel/ProfilePanel.tsx index a6af31c73..616ae0b04 100644 --- a/src/header/utility-selectors/UtilitySelector/ProfileSelector/profile-logged-in/profile-panel/ProfilePanel.tsx +++ b/src/header/utility-selectors/UtilitySelector/ProfileSelector/profile-logged-in/profile-panel/ProfilePanel.tsx @@ -1,4 +1,4 @@ -import { FC, useContext } from 'react' +import { FC, MutableRefObject, useContext } from 'react' import { Link } from 'react-router-dom' import { @@ -12,6 +12,7 @@ import { import styles from './ProfilePanel.module.scss' interface ProfilePanelProps { + refObject: MutableRefObject settingsTitle: string toggleProfilePanel: () => void } @@ -27,7 +28,10 @@ const ProfilePanel: FC = (props: ProfilePanelProps) => { } return ( -
+
{profile.handle}
diff --git a/src/lib/form/validator-functions/index.ts b/src/lib/form/validator-functions/index.ts index 981143aa5..b8a690f34 100644 --- a/src/lib/form/validator-functions/index.ts +++ b/src/lib/form/validator-functions/index.ts @@ -8,5 +8,4 @@ export { sslUrl as validatorSslUrl, } from './validator.functions' export - // tslint:disable-next-line: no-unused-expression type { ValidatorFn } from './validator.functions' diff --git a/src/lib/functions/component-visible-functions/component-visible.functions.test.tsx b/src/lib/functions/component-visible-functions/component-visible.functions.test.tsx new file mode 100644 index 000000000..d3d793905 --- /dev/null +++ b/src/lib/functions/component-visible-functions/component-visible.functions.test.tsx @@ -0,0 +1,6 @@ +import '@testing-library/jest-dom' + +describe('component visible functions', () => { + + test('it should determine if components are visible', () => { }) +}) diff --git a/src/lib/functions/component-visible-functions/component-visible.functions.tsx b/src/lib/functions/component-visible-functions/component-visible.functions.tsx new file mode 100644 index 000000000..4ff589cc9 --- /dev/null +++ b/src/lib/functions/component-visible-functions/component-visible.functions.tsx @@ -0,0 +1,28 @@ +import { Dispatch, MutableRefObject, SetStateAction, useEffect, useRef, useState } from 'react' + +export interface ComponentVisible { + isComponentVisible: boolean + ref: MutableRefObject + setIsComponentVisible: Dispatch> +} + +export function useHideClickOutside(isVisible: boolean): ComponentVisible { + + const [isComponentVisible, setIsComponentVisible]: [boolean, Dispatch>] + = useState(isVisible) + + const ref: MutableRefObject = useRef(undefined) + + function onClick(event: globalThis.MouseEvent): void { + setIsComponentVisible(!!ref.current?.contains(event.target)) + } + + useEffect(() => { + document.addEventListener('click', onClick, true) + return () => { + document.removeEventListener('click', onClick, true) + } + }, []) + + return { ref, isComponentVisible, setIsComponentVisible } +} diff --git a/src/lib/functions/component-visible-functions/index.ts b/src/lib/functions/component-visible-functions/index.ts new file mode 100644 index 000000000..8ec07626d --- /dev/null +++ b/src/lib/functions/component-visible-functions/index.ts @@ -0,0 +1 @@ +export * from './component-visible.functions' diff --git a/src/lib/functions/index.ts b/src/lib/functions/index.ts index 8fad309fe..c2c032a5c 100644 --- a/src/lib/functions/index.ts +++ b/src/lib/functions/index.ts @@ -4,6 +4,7 @@ export { authUrlLogout, authUrlSignup, } from './authentication-functions' +export * from './component-visible-functions' export * from './logging-functions' export * from './user-functions' export * from './xhr-functions' diff --git a/src/lib/index.ts b/src/lib/index.ts index c3ad01716..4d6079de7 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -13,7 +13,11 @@ export { logError, logInitialize, logInfo, + useHideClickOutside, } from './functions' +export + // tslint:disable-next-line: no-unused-expression +type { ComponentVisible } from './functions' export * from './svgs' /* From bee73ac789808b227105793757c2c75cc65033d6 Mon Sep 17 00:00:00 2001 From: brooketopcoder Date: Thu, 31 Mar 2022 09:42:22 -0700 Subject: [PATCH 2/2] PROD-1086 #comment clean-up #time 5mn --- src/lib/form/validator-functions/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/form/validator-functions/index.ts b/src/lib/form/validator-functions/index.ts index b8a690f34..981143aa5 100644 --- a/src/lib/form/validator-functions/index.ts +++ b/src/lib/form/validator-functions/index.ts @@ -8,4 +8,5 @@ export { sslUrl as validatorSslUrl, } from './validator.functions' export + // tslint:disable-next-line: no-unused-expression type { ValidatorFn } from './validator.functions'