@@ -3,7 +3,7 @@ import {Button} from 'web/components/buttons/button'
33import clsx from 'clsx'
44import toast from 'react-hot-toast'
55import { api } from 'web/lib/api'
6- import { useState } from 'react'
6+ import { useState , useEffect , useRef } from 'react'
77import { useUser } from "web/hooks/use-user" ;
88
99export type VoteChoice = 'for' | 'abstain' | 'against'
@@ -47,8 +47,32 @@ export function VoteButtons(props: {
4747 const { voteId, counts, onVoted, className} = props
4848 const [ loading , setLoading ] = useState < VoteChoice | null > ( null )
4949 const [ showPriority , setShowPriority ] = useState ( false )
50+ const containerRef = useRef < HTMLDivElement > ( null )
5051 const disabled = loading !== null
5152
53+ // Close the dropdown when clicking outside or pressing Escape
54+ useEffect ( ( ) => {
55+ if ( ! showPriority ) return
56+
57+ const handleClickOutside = ( e : MouseEvent ) => {
58+ const target = e . target as Node | null
59+ if ( containerRef . current && target && ! containerRef . current . contains ( target ) ) {
60+ setShowPriority ( false )
61+ }
62+ }
63+
64+ const handleKeyDown = ( e : KeyboardEvent ) => {
65+ if ( e . key === 'Escape' ) setShowPriority ( false )
66+ }
67+
68+ document . addEventListener ( 'mousedown' , handleClickOutside )
69+ document . addEventListener ( 'keydown' , handleKeyDown )
70+ return ( ) => {
71+ document . removeEventListener ( 'mousedown' , handleClickOutside )
72+ document . removeEventListener ( 'keydown' , handleKeyDown )
73+ }
74+ } , [ showPriority ] )
75+
5276 const sendVote = async ( choice : VoteChoice , priority : number ) => {
5377 try {
5478 setLoading ( choice )
@@ -79,7 +103,7 @@ export function VoteButtons(props: {
79103
80104 return (
81105 < Row className = { clsx ( 'gap-4 mt-2' , className ) } >
82- < div className = "relative" >
106+ < div className = "relative" ref = { containerRef } >
83107 < VoteButton
84108 color = { clsx ( 'bg-green-700 text-white hover:bg-green-500' ) }
85109 count = { counts . for }
@@ -89,15 +113,15 @@ export function VoteButtons(props: {
89113 />
90114 { showPriority && (
91115 < div className = { clsx (
92- 'absolute z-10 mt-2 w-40 rounded-md border border-ink-200 bg-white shadow-lg' ,
116+ 'absolute z-10 mt-2 w-40 rounded-md border border-ink-200 bg-canvas-50 shadow-lg' ,
93117 'dark:bg-ink-900'
94118 ) } >
95119 { priorities . map ( ( p ) => (
96120 < button
97121 key = { p . value }
98122 className = { clsx (
99- 'w-full text-left px-3 py-2 text-sm hover:bg-ink-100' ,
100- 'dark:hover:bg-ink-800 '
123+ 'w-full text-left px-3 py-2 text-sm hover:bg-ink-100 bg-canvas-50 ' ,
124+ 'dark:hover:bg-canvas-100 '
101125 ) }
102126 onClick = { async ( ) => {
103127 setShowPriority ( false )
0 commit comments