Skip to content

Commit

Permalink
fix: fixed the behavior of dropdown list when clicked outside of its …
Browse files Browse the repository at this point in the history
…scope (#1838)

* Fixed the behavior of dropdownlist when clicked outside of its scope.

* removed unwanted console.log

* Fixed a bug

* removed unnecessary console.log()

* Restricted topbar icons to inherit click-outside functionality

---------

Co-authored-by: Rupali Haldiya <[email protected]>
  • Loading branch information
raghav1030 and rupali-codes authored Oct 11, 2023
1 parent 82e83b9 commit b1eec4b
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 13 deletions.
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

1 comment on commit b1eec4b

@vercel
Copy link

@vercel vercel bot commented on b1eec4b Oct 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.