mirror of
https://github.com/NovaOSS/nova-betterchat.git
synced 2024-11-25 17:33:59 +01:00
Refact: hide dropdown prompt & palette when clicked outside (#223)
* Refact: hide dropdown prompt when clicked outside Added an event listener to hide prompts, when anything other than the dropdown is clicked, implemented via a click event. * Refact: hide palette color when clicked outside Added an event listener to hide palette color, when anything other than the dropdown palette is clicked, implemented via a click event. * Refactor: event listener conditions for dropdown Changed the event listener conditions for mousedown events, so they are only added when dropdown menu or color palette is visible. * shift paletteRef position --------- Co-authored-by: Jing Hua <tohjinghua123@gmail.com>
This commit is contained in:
parent
699ce66e3c
commit
02697408ce
|
@ -1,4 +1,4 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import useStore from '@store/store';
|
import useStore from '@store/store';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { matchSorter } from 'match-sorter';
|
import { matchSorter } from 'match-sorter';
|
||||||
|
@ -14,6 +14,7 @@ const CommandPrompt = ({
|
||||||
const [dropDown, setDropDown] = useState<boolean>(false);
|
const [dropDown, setDropDown] = useState<boolean>(false);
|
||||||
const [_prompts, _setPrompts] = useState<Prompt[]>(prompts);
|
const [_prompts, _setPrompts] = useState<Prompt[]>(prompts);
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
|
const dropdownRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const filteredPrompts = matchSorter(useStore.getState().prompts, input, {
|
const filteredPrompts = matchSorter(useStore.getState().prompts, input, {
|
||||||
|
@ -27,8 +28,29 @@ const CommandPrompt = ({
|
||||||
setInput('');
|
setInput('');
|
||||||
}, [prompts]);
|
}, [prompts]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleClickOutside = (event: MouseEvent) => {
|
||||||
|
if (
|
||||||
|
dropdownRef.current &&
|
||||||
|
!dropdownRef.current.contains(event.target as Node)
|
||||||
|
) {
|
||||||
|
setDropDown(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (dropDown) {
|
||||||
|
document.addEventListener('mousedown', handleClickOutside);
|
||||||
|
} else {
|
||||||
|
document.removeEventListener('mousedown', handleClickOutside);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('mousedown', handleClickOutside);
|
||||||
|
};
|
||||||
|
}, [dropdownRef, dropDown]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='relative max-wd-sm'>
|
<div className='relative max-wd-sm' ref={dropdownRef}>
|
||||||
<button
|
<button
|
||||||
className='btn btn-neutral btn-small'
|
className='btn btn-neutral btn-small'
|
||||||
onClick={() => setDropDown(!dropDown)}
|
onClick={() => setDropDown(!dropDown)}
|
||||||
|
|
|
@ -37,6 +37,7 @@ const ChatFolder = ({
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
const folderRef = useRef<HTMLDivElement>(null);
|
const folderRef = useRef<HTMLDivElement>(null);
|
||||||
const gradientRef = useRef<HTMLDivElement>(null);
|
const gradientRef = useRef<HTMLDivElement>(null);
|
||||||
|
const paletteRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const [_folderName, _setFolderName] = useState<string>(folderName);
|
const [_folderName, _setFolderName] = useState<string>(folderName);
|
||||||
const [isEdit, setIsEdit] = useState<boolean>(false);
|
const [isEdit, setIsEdit] = useState<boolean>(false);
|
||||||
|
@ -144,6 +145,27 @@ const ChatFolder = ({
|
||||||
if (inputRef && inputRef.current) inputRef.current.focus();
|
if (inputRef && inputRef.current) inputRef.current.focus();
|
||||||
}, [isEdit]);
|
}, [isEdit]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleClickOutside = (event: MouseEvent) => {
|
||||||
|
if (
|
||||||
|
paletteRef.current &&
|
||||||
|
!paletteRef.current.contains(event.target as Node)
|
||||||
|
) {
|
||||||
|
setShowPalette(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (showPalette) {
|
||||||
|
document.addEventListener('mousedown', handleClickOutside);
|
||||||
|
} else {
|
||||||
|
document.removeEventListener('mousedown', handleClickOutside);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('mousedown', handleClickOutside);
|
||||||
|
};
|
||||||
|
}, [paletteRef, showPalette]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`w-full transition-colors group/folder ${
|
className={`w-full transition-colors group/folder ${
|
||||||
|
@ -217,7 +239,10 @@ const ChatFolder = ({
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div className='relative md:hidden group-hover/folder:md:inline'>
|
<div
|
||||||
|
className='relative md:hidden group-hover/folder:md:inline'
|
||||||
|
ref={paletteRef}
|
||||||
|
>
|
||||||
<button
|
<button
|
||||||
className='p-1 hover:text-white'
|
className='p-1 hover:text-white'
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|
Loading…
Reference in a new issue