diff --git a/components/common/I18nWidget/I18nWidget.tsx b/components/common/I18nWidget/I18nWidget.tsx index 5c82e3a9a..92b40322d 100644 --- a/components/common/I18nWidget/I18nWidget.tsx +++ b/components/common/I18nWidget/I18nWidget.tsx @@ -1,9 +1,10 @@ import cn from 'classnames' import Link from 'next/link' -import { FC, useState } from 'react' +import { useRef, FC, useState } from 'react' import { useRouter } from 'next/router' import s from './I18nWidget.module.css' import { Cross, ChevronUp } from '@components/icons' +import ClickOutside from '@lib/click-outside' interface LOCALE_DATA { name: string img: { @@ -37,55 +38,62 @@ const I18nWidget: FC = () => { defaultLocale = 'en-US', asPath: currentPath, } = useRouter() + const options = locales?.filter((val) => val !== locale) const currentLocale = locale || defaultLocale + const ref = useRef(null) return ( - + ) : null} + + + ) } diff --git a/lib/click-outside/click-outside.tsx b/lib/click-outside/click-outside.tsx new file mode 100644 index 000000000..2af0497a6 --- /dev/null +++ b/lib/click-outside/click-outside.tsx @@ -0,0 +1,45 @@ +import React, { forwardRef, useEffect, Ref, MouseEvent } from 'react' +import hasParent from './has-parent' + +interface ClickOutsideProps { + active: boolean + onClick: (e?: MouseEvent) => void + children: any +} + +const ClickOutside = ( + { active = true, onClick, children }: ClickOutsideProps, + ref: Ref | null | any = {} +) => { + console.log('--------', active, '-----------') + const innerRef = ref?.current + + const handleClick = (event: any) => { + console.log(innerRef, event.target) + if (!hasParent(event.target, innerRef)) { + if (typeof onClick === 'function') { + event.preventDefault() + event.stopImmediatePropagation() + onClick(event) + } + } + } + + useEffect(() => { + if (active) { + document.addEventListener('mousedown', handleClick) + document.addEventListener('touchstart', handleClick) + } + + return () => { + if (active) { + document.removeEventListener('mousedown', handleClick) + document.removeEventListener('touchstart', handleClick) + } + } + }) + + return React.cloneElement(children, { ref }) +} + +export default forwardRef(ClickOutside) diff --git a/lib/click-outside/has-parent.js b/lib/click-outside/has-parent.js new file mode 100644 index 000000000..06cd3ca91 --- /dev/null +++ b/lib/click-outside/has-parent.js @@ -0,0 +1,5 @@ +import isInDOM from './is-in-dom' + +export default function hasParent(element, root) { + return root && root.contains(element) && isInDOM(element) +} diff --git a/lib/click-outside/index.ts b/lib/click-outside/index.ts new file mode 100644 index 000000000..2df916f9c --- /dev/null +++ b/lib/click-outside/index.ts @@ -0,0 +1 @@ +export { default } from './click-outside' diff --git a/lib/click-outside/is-in-dom.js b/lib/click-outside/is-in-dom.js new file mode 100644 index 000000000..5d7438ed7 --- /dev/null +++ b/lib/click-outside/is-in-dom.js @@ -0,0 +1,3 @@ +export default function isInDom(obj) { + return Boolean(obj.closest('body')) +}