-
Notifications
You must be signed in to change notification settings - Fork 41
/
GlobalEvents.purs
117 lines (107 loc) · 2.77 KB
/
GlobalEvents.purs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
-- | These helper components register and unregister event callbacks
-- | using React's the lifecycle callbacks. They're useful for
-- | declaratively defining global behavior which is associated with
-- | a particular component being mounted without having to wire
-- | all that lifecycle logic up manually.
-- |
-- | For example:
-- |
-- | ```purs
-- | render self =
-- | R.div
-- | { className: "dropdown-wrapper"
-- | , children:
-- | [ dropdownButton
-- | , guard showDropdown $
-- | windowEvent
-- | { eventType: EventType "click"
-- | , options: defaultOptions
-- | , handler: \_ -> send self CloseDropdown
-- | }
-- | dropdownMenu
-- | ]
-- | }
-- | ```
module React.Basic.DOM.Components.GlobalEvents
( EventHandlerOptions
, defaultOptions
, globalEvent
, globalEvents
, windowEvent
, windowEvents
) where
import Prelude
import Data.Foldable (foldr)
import Effect (Effect)
import Effect.Unsafe (unsafePerformEffect)
import React.Basic (JSX, ReactComponent, element)
import Web.Event.Event (EventType)
import Web.Event.Internal.Types (Event, EventTarget)
import Web.HTML (window)
import Web.HTML.Window as Window
type EventHandlerOptions =
{ capture :: Boolean
, once :: Boolean
, passive :: Boolean
}
defaultOptions :: EventHandlerOptions
defaultOptions =
{ capture: false
, once: false
, passive: false
}
foreign import globalEvent_
:: ReactComponent
{ target :: EventTarget
, eventType :: EventType
, handler :: Event -> Effect Unit
, options :: EventHandlerOptions
, child :: JSX
}
globalEvent
:: EventTarget
-> { eventType :: EventType
, options :: EventHandlerOptions
, handler :: Event -> Effect Unit
}
-> JSX
-> JSX
globalEvent target { eventType, options, handler } child =
element globalEvent_
{ target
, eventType
, handler
, options
, child
}
globalEvents
:: EventTarget
-> Array
{ eventType :: EventType
, options :: EventHandlerOptions
, handler :: Event -> Effect Unit
}
-> JSX
-> JSX
globalEvents target = flip (foldr (globalEvent target))
windowEvents
:: Array
{ eventType :: EventType
, options :: EventHandlerOptions
, handler :: Event -> Effect Unit
}
-> JSX
-> JSX
windowEvents = globalEvents $ unsafePerformEffect $ map Window.toEventTarget window
windowEvent
:: { eventType :: EventType
, options :: EventHandlerOptions
, handler :: Event -> Effect Unit
}
-> JSX
-> JSX
windowEvent = windowEvents <<< pure
-- | Hide "unused ffi export" warning.
-- | The export is required to prevent
-- | PS' bundler from stripping it out.
foreign import _passiveSupported :: Void