/
MultikeyHandling.elm
80 lines (59 loc) · 1.62 KB
/
MultikeyHandling.elm
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
module MultikeyHandling
exposing
( defaultKeyHandler
, onKeydown
, whenKeydown
, whenEnter
, whenMetaEnter
, whenEscape
)
{-| Extra helpers for building Html.Attribute handling multiple key combinations.
# Html Attribute builder
@docs onKeydown
# Predefined key decoders
@docs whenKeydown, whenEnter, whenMetaEnter, whenEscape, defaultKeyHandler
-}
import Json.Decode as Json
import Html exposing (Attribute)
import Html.Events exposing (..)
{-| Default key handler, always return fails
-}
defaultKeyHandler : Json.Decoder msg
defaultKeyHandler =
Json.fail "Default handler"
{-| Build Html.Attribute from Json.Decoder
-}
onKeydown : Json.Decoder msg -> Attribute msg
onKeydown decoder =
on "keydown" decoder
{-| Build Decoder on custom key code
-}
whenKeydown : Int -> msg -> Json.Decoder msg -> Json.Decoder msg
whenKeydown code msg defaultDecoder =
keyCode
|> Json.andThen
(\c ->
if c == code
then Json.succeed msg
else defaultDecoder
)
{-| Build Decoder on enter key
-}
whenEnter : msg -> Json.Decoder msg -> Json.Decoder msg
whenEnter =
whenKeydown 13
{-| Build Decoder on Meta + Enter key
-}
whenMetaEnter : msg -> Json.Decoder msg -> Json.Decoder msg
whenMetaEnter msg decoder =
whenKeydown 13 msg decoder
|> withMetaKey
{-| Build Decoder on Escape key
-}
whenEscape : msg -> Json.Decoder msg -> Json.Decoder msg
whenEscape =
whenKeydown 27
withMetaKey : Json.Decoder msg -> Json.Decoder msg
withMetaKey decoder =
Json.field "metaKey" Json.bool
|> Json.andThen (\x -> if x then decoder else Json.fail "not meta")