Skip to content

Commit

Permalink
feat(tag-input: add outside click handler to close tag popover on cli…
Browse files Browse the repository at this point in the history
…cks outside the tag input
  • Loading branch information
JaleelB committed Jun 23, 2024
1 parent 9674ab8 commit feae754
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 6 deletions.
7 changes: 7 additions & 0 deletions .changeset/rich-buttons-cry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'emblor': patch
---

🐞 Bug Fixes:

Restored Default Outside Click Behavior for TagPopover: Updated the TagPopover component to close when clicking outside its bounds, restoring the default behavior that was unintentionally overridden in previous updates. This issue arose due to modifications intended to keep the popover open under specific circumstances, such as focusing within the popover's content. The fix involved adjusting event handling to ensure that the popover's native functionality provided by Radix UI is preserved, allowing it to close as expected when focus is lost or an outside click is detected.
28 changes: 25 additions & 3 deletions packages/emblor/src/tag/autocomplete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const Autocomplete: React.FC<AutocompleteProps> = ({
const triggerContainerRef = useRef<HTMLDivElement | null>(null);
const triggerRef = useRef<HTMLButtonElement | null>(null);
const inputRef = useRef<HTMLInputElement | null>(null);
const popoverContentRef = useRef<HTMLDivElement | null>(null);

const [popoverWidth, setPopoverWidth] = useState<number>(0);
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
Expand All @@ -43,6 +44,26 @@ export const Autocomplete: React.FC<AutocompleteProps> = ({
);
}, [tags]);

// Close the popover when clicking outside of it
useEffect(() => {
const handleOutsideClick = (event) => {
if (
isPopoverOpen &&
triggerContainerRef.current &&
!triggerContainerRef.current.contains(event.target) &&
!popoverContentRef.current.contains(event.target)
) {
setIsPopoverOpen(false);
}
};

document.addEventListener('mousedown', handleOutsideClick);

return () => {
document.removeEventListener('mousedown', handleOutsideClick);
};
}, [isPopoverOpen]);

const handleOpenChange = useCallback(
(open: boolean) => {
if (open && triggerContainerRef.current) {
Expand Down Expand Up @@ -135,9 +156,9 @@ export const Autocomplete: React.FC<AutocompleteProps> = ({
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="lucide lucide-chevron-down h-4 w-4 shrink-0 opacity-50"
>
<path d="m6 9 6 6 6-6"></path>
Expand All @@ -146,6 +167,7 @@ export const Autocomplete: React.FC<AutocompleteProps> = ({
</PopoverTrigger>
</div>
<PopoverContent
ref={popoverContentRef}
side="bottom"
align="start"
className={cn(`p-0 relative`)}
Expand Down
28 changes: 25 additions & 3 deletions packages/emblor/src/tag/tag-popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const TagPopover: React.FC<TagPopoverProps> = ({
}) => {
const triggerContainerRef = useRef<HTMLDivElement | null>(null);
const triggerRef = useRef<HTMLButtonElement | null>(null);
const popoverContentRef = useRef<HTMLDivElement | null>(null);
const inputRef = useRef<HTMLInputElement | null>(null);

const [popoverWidth, setPopoverWidth] = useState<number>(0);
Expand All @@ -43,6 +44,26 @@ export const TagPopover: React.FC<TagPopoverProps> = ({
return () => window.removeEventListener('resize', handleResize);
}, [triggerContainerRef, triggerRef]);

// Close the popover when clicking outside of it
useEffect(() => {
const handleOutsideClick = (event) => {
if (
isPopoverOpen &&
triggerContainerRef.current &&
!triggerContainerRef.current.contains(event.target) &&
!popoverContentRef.current.contains(event.target)
) {
setIsPopoverOpen(false);
}
};

document.addEventListener('mousedown', handleOutsideClick);

return () => {
document.removeEventListener('mousedown', handleOutsideClick);
};
}, [isPopoverOpen]);

const handleOpenChange = useCallback(
(open: boolean) => {
if (open && triggerContainerRef.current) {
Expand Down Expand Up @@ -107,9 +128,9 @@ export const TagPopover: React.FC<TagPopoverProps> = ({
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="lucide lucide-chevron-down h-4 w-4 shrink-0 opacity-50"
>
<path d="m6 9 6 6 6-6"></path>
Expand All @@ -118,6 +139,7 @@ export const TagPopover: React.FC<TagPopoverProps> = ({
</PopoverTrigger>
</div>
<PopoverContent
ref={popoverContentRef}
className="w-full space-y-3"
style={{
marginLeft: `-${sideOffset}px`,
Expand Down

0 comments on commit feae754

Please sign in to comment.