Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed the behavior of dropdownlist when clicked outside of its scope. #1838

Merged
merged 6 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions components/Backdrop/Backdrop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const Backdrop: FC<{

return createPortal(
<div
data-custom='restrict-click-outside'
className={`fixed inset-0 z-50 h-full w-full cursor-pointer bg-black/80
${className}
${status === 'preEnter' || status === 'entering' ? '' : 'opacity-0'}
Expand Down
6 changes: 4 additions & 2 deletions components/Cards/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const Card: FC<CardProps> = ({ data }) => {
}, [])

return (
<article className="z-10 h-full w-full rounded-3xl border border-dashed border-theme-secondary dark:border-theme-primary bg-[rgba(255,255,255,0.3)] shadow-md dark:bg-dark dark:text-text-primary dark:shadow-sm">
<article data-custom='restrict-click-outside' className="z-10 h-full w-full rounded-3xl border border-dashed border-theme-secondary dark:border-theme-primary bg-[rgba(255,255,255,0.3)] shadow-md dark:bg-dark dark:text-text-primary dark:shadow-sm">
<div className="card-body">
<header className="flex justify-between items-center gap-2">
<h2
Expand All @@ -32,7 +32,9 @@ export const Card: FC<CardProps> = ({ data }) => {
>
{name}
</h2>
<div className="flex items-center gap-1">
<div
className="flex items-center gap-1"
>
<CopyToClipboard url={url} />
<Share url={`${url}?ref=LinksHub`} title={name} />
</div>
Expand Down
4 changes: 2 additions & 2 deletions components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ export const Header: FC = () => {
<Logo className="text-3xl" />
</Link>
</div>
<div className="bg-light-primary relative h-full grow px-8 dark:bg-dark lg:dark:bg-dark-primary">
<div data-custom='restrict-click-outside' className="bg-light-primary relative h-full grow px-8 dark:bg-dark lg:dark:bg-dark-primary">
<TopBar
className="absolute left-8 hidden h-full md:flex"
results={results}
/>
<div className="absolute right-8 flex h-full gap-4">
<div data-custom='restrict-click-outside' className="absolute right-8 flex h-full gap-4">
<SocialMediaIconsList className="hidden lg:flex" />
<ThemeToggler />
<button
Expand Down
15 changes: 12 additions & 3 deletions components/SideNavbar/SideNavbarCategory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@ import { FaAngleDown } from 'react-icons/fa'
import { SideNavbarElement } from './SideNavbarElement'
import type { ISidebar } from '../../types'
import Link from 'next/link'
import useOnClickOutside from 'hooks/useOnClickOutside'
import { useRouter } from 'next/router'


export const SideNavbarCategory: FC<{
categoryData: ISidebar
expand: boolean
}> = ({ categoryData, expand }) => {
listRef: React.MutableRefObject<HTMLUListElement | null>
}> = ({ categoryData, expand, listRef }) => {
const [isOpen, setIsOpen] = useState(expand)

const { category, subcategory } = categoryData
const router = useRouter();
const sortedSubcategoryList = subcategory
.sort((a, b) => (a.name.toUpperCase() < b.name.toUpperCase() ? -1 : 1))
.map((subcategoryData, i) => (
Expand All @@ -27,11 +31,16 @@ export const SideNavbarCategory: FC<{
setIsOpen(!isOpen)
}

useOnClickOutside(listRef, () =>{
setIsOpen(false)
router.push('/')
})

return (
<li className="relative w-full transition-all ease-in-out text-theme-secondary dark:text-theme-primary dark:bg-opacity-5 hover:text-theme-secondary dark:hover:text-theme-primary rounded-md focus-visible:outline-none focus-visible:ring focus-visible:ring-theme-primary">
<Link
className="flex w-full cursor-pointer justify-between py-2"
onClick={handleToggle}
onClick={() => handleToggle()}
aria-label="toggle category"
href={`/${category}`}
>
Expand Down
8 changes: 6 additions & 2 deletions components/SideNavbar/SideNavbarCategoryList.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FC, useEffect, useState } from 'react'
import React, { FC, useEffect, useState, useRef } from 'react'
import type { SubCategories } from '../../types'
import { sidebarData } from 'database/data'
import { SideNavbarCategory } from './SideNavbarCategory'
Expand All @@ -10,6 +10,7 @@ export const SideNavbarCategoryList: FC<{
const categoriesList = getFilteredCategoryList(query)
const router = useRouter()
const [category, setCategory] = useState<string | undefined>('')
const listRef = useRef<HTMLUListElement | null>(null)

useEffect(() => {
const cat: string | undefined = router.query.category as string | undefined
Expand All @@ -28,10 +29,13 @@ export const SideNavbarCategoryList: FC<{
}

return (
<ul className="mt-2 flex flex-col justify-center px-4 pb-24">
<ul ref={listRef} className="mt-2 flex flex-col justify-center px-4 pb-24">
{/* Reset the open/close states of categories. This makes sure that
changes to the toggle state don't reflect when a new query is submitted */}
<React.Fragment key={query}>
{categoriesList.map((categoryData) => (
<SideNavbarCategory
listRef={listRef}
key={categoryData.category}
categoryData={categoryData}
expand={query.length > 0 || category === categoryData.category}
Expand Down
1 change: 1 addition & 0 deletions components/popup/popupInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const PopupInfo: React.FC<{
<Backdrop onClick={onClose} />
{createPortal(
<div
data-custom="restrict-click-outside"
onClick={(e) => e.stopPropagation()}
className={`fixed left-1/2 top-1/2 z-[150] max-w-[500px] -translate-x-1/2 -translate-y-1/2 transition-all ${
currentCard ? 'animate-scale-appearance' : 'animate-scale-hide'
Expand Down
32 changes: 32 additions & 0 deletions hooks/useOnClickOutside.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { MutableRefObject, useEffect } from 'react'

const useOnClickOutside = (
ref: MutableRefObject<HTMLUListElement | null>,
handler: () => void
) => {
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (
event.target &&
(event.target as HTMLElement)?.closest('[data-custom="restrict-click-outside"]') !== null) {
return
}

if (
ref.current &&
!ref.current.classList.contains('copy-to-clipboard-button') &&
!ref.current.contains(event.target as Node)
) {
handler()
}
}

document.addEventListener('mousedown', handleClickOutside)

return () => {
document.removeEventListener('mousedown', handleClickOutside)
}
}, [ref, handler])
}

export default useOnClickOutside
14 changes: 10 additions & 4 deletions pages/[category]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Link from 'next/link'

const CategoryPage = () => {
const router = useRouter()
const { category } = router.query as { category: string}
const { category } = router.query as { category: string }

const subcategories: SubCategories[] = []
sidebarData.forEach((c) => {
Expand Down Expand Up @@ -34,7 +34,10 @@ const CategoryPage = () => {
resources!
</p>
</div>
<div className="flex flex-wrap gap-3 mt-6 justify-center items-start mx-auto lg:max-w-sm max-md:max-w-sm">
<div
data-custom="restrict-click-outside"
className="flex flex-wrap gap-3 mt-6 justify-center items-start mx-auto lg:max-w-sm max-md:max-w-sm"
>
{subcategories.map((subcat, i) => (
<Link
key={i}
Expand All @@ -47,9 +50,12 @@ const CategoryPage = () => {
</div>
</>
) : (
<div className='text-center'>
<div className="text-center">
<p className="text-theme-secondary dark:text-gray-text w-fit mx-auto text-center">
<span className='md:text-7xl text-xl uppercase font-bold '>404|</span> No resources found.
<span className="md:text-7xl text-xl uppercase font-bold ">
404|
</span>{' '}
No resources found.
</p>
</div>
)}
Expand Down
Loading