1
+ import { DocumentEventListener } from "@solid-primitives/event-listener" ;
2
+ import { RiArrowsArrowDropDownLine } from "solid-icons/ri" ;
1
3
import { Show , createSignal } from "solid-js" ;
2
4
import { JSX } from "solid-js/jsx-runtime" ;
3
- import { RiArrowsArrowDropDownLine } from "solid-icons/ri " ;
5
+ import hasParentWithCondition from "../../../utils/hasParentWithCondition.ts " ;
4
6
import { SelectContextProvider } from "./context.ts" ;
5
7
6
8
type Props < V > = {
@@ -14,6 +16,7 @@ type Props<V> = {
14
16
15
17
export default function Select < V > ( props : Props < V > ) {
16
18
const [ optionsVisible , setOptionsVisible ] = createSignal ( false ) ;
19
+ let rootElement : HTMLDivElement ;
17
20
18
21
function open ( ) {
19
22
setOptionsVisible ( true ) ;
@@ -33,8 +36,19 @@ export default function Select<V>(props: Props<V>) {
33
36
}
34
37
}
35
38
39
+ function onDocumentMouseDown ( ev : MouseEvent ) {
40
+ const clickedInsideSelect = hasParentWithCondition (
41
+ ev . target as Element ,
42
+ ( element ) => element === rootElement ,
43
+ ) ;
44
+
45
+ if ( ! clickedInsideSelect ) {
46
+ close ( ) ;
47
+ }
48
+ }
49
+
36
50
return (
37
- < div class = "relative w-full" >
51
+ < div ref = { rootElement ! } class = "relative w-full" >
38
52
< div
39
53
class = { `bg-gray-0 active:bg-gray-100 border border-gray-200 h-[35px] ${
40
54
optionsVisible ( ) ? "rounded-t-md" : "rounded-md"
@@ -49,6 +63,8 @@ export default function Select<V>(props: Props<V>) {
49
63
50
64
< SelectContextProvider onChange = { props . onChange } onClose = { close } >
51
65
< Show when = { optionsVisible ( ) } >
66
+ < DocumentEventListener onMousedown = { onDocumentMouseDown } />
67
+
52
68
< div class = "absolute w-full z-10 border border-gray-200 -mt-[1px] rounded-b-md overflow-hidden" >
53
69
{ props . children }
54
70
</ div >
0 commit comments