From 92abdad9d535900a175156511aadcf14d37ea404 Mon Sep 17 00:00:00 2001 From: Marta Noya Date: Tue, 25 Jan 2022 23:17:14 +0100 Subject: [PATCH] Initial commit --- .gitignore | 1 + LICENSE | 30 ++++++++++++++++ README.md | 52 +++++++++++++++++++++++++++ elm.json | 15 ++++++++ src/HtmlKeyEvents.elm | 84 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 182 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 elm.json create mode 100644 src/HtmlKeyEvents.elm diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4bc8535 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +elm-stuff diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e0419a4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,30 @@ +Copyright (c) 2014-present, Evan Czaplicki + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of Evan Czaplicki nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..cebd58d --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ +# Html Key Events + +HTML Event listeners for on 'keyup' and on 'keydown'. + +For each one of them, it stops propagation. + +The `onKeyUp` will give you the ASCII code of the key being released. + +The `onKeyDown` will give you the ASCII code of the key being pressed. Plus, it will tell you if the `shift` key is pressed as well. + +### Why this package + +Event listeners on keys may be a very common usage, specially to know which keys are pressed/unpressed. +It would be nice if it was implemented inside `elm/html` in `Html.Events` just like the `onInput`, and [it seems to be in their future plants](https://package.elm-lang.org/packages/elm/html/latest/Html-Events#keyCode) as it says in the `note`, but in the meantime, this comes in handy. + +### Install + +Install with: +`elm install martouta/html-key-events` + +### Example + +A simple example of usage: +```elm +type Msg + = KeyDown ( Int, Bool ) + | KeyUp Int + +view : Html Msg +view = + textarea + [ rows 10 + , cols 40 + , onKeyDown KeyDown + , onKeyUp KeyUp + ] + [] + ] + +update : Msg -> Model -> ( Model, Cmd Msg ) +update msg model = + case msg of + KeyDown ( code, shift ) -> + (model, Cmd.none) + + KeyUp code -> + (model, Cmd.none) +``` + +### Learn more + +You can read more about custom html event decoders in [the documentation of the package elm/html](https://package.elm-lang.org/packages/elm/html/latest/Html-Events#targetValue). diff --git a/elm.json b/elm.json new file mode 100644 index 0000000..60fd63c --- /dev/null +++ b/elm.json @@ -0,0 +1,15 @@ +{ + "type": "package", + "name": "martouta/html-key-events", + "summary": "HTML Event listeners for on 'keyup' and on 'keydown'", + "license": "BSD-3-Clause", + "version": "1.0.0", + "exposed-modules": ["HtmlKeyEvents"], + "elm-version": "0.19.0 <= v < 0.20.0", + "dependencies": { + "elm/core": "1.0.0 <= v < 2.0.0", + "elm/html": "1.0.0 <= v < 2.0.0", + "elm/json": "1.0.0 <= v < 2.0.0" + }, + "test-dependencies": {} +} diff --git a/src/HtmlKeyEvents.elm b/src/HtmlKeyEvents.elm new file mode 100644 index 0000000..d5ea140 --- /dev/null +++ b/src/HtmlKeyEvents.elm @@ -0,0 +1,84 @@ +module HtmlKeyEvents exposing (onKeyDown, onKeyUp) + +{-| HTML Event listeners for on 'keyup' and on 'keydown'. +For each one of them, it stops propagation. + +[stop]: https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation + +@docs onKeyDown, onKeyUp +-} + +import Html exposing (Attribute) +import Html.Events exposing (keyCode, stopPropagationOn) +import Json.Decode exposing (Decoder, at, bool, int, map, map2) + + + +{-| It will give you the ASCII code of the key being pressed. +Plus, it will tell you if the `shift` key is pressed as well. +You can read a complete simple example in the README. + + type Msg + = KeyDown ( Int, Bool ) + + view : Html Msg + view = + textarea + [ rows 10 + , cols 40 + , onKeyDown KeyDown + ] + [] + ] + + update : Msg -> Model -> ( Model, Cmd Msg ) + update msg model = + case msg of + KeyDown ( code, shift ) -> + (model, Cmd.none) +-} +onKeyDown : (( Int, Bool ) -> msg) -> Attribute msg +onKeyDown tagger = + stopPropagationOn "keydown" <| + map alwaysStop (map tagger keyExtractor) + + + +{-| It will give you the ASCII code of the key being released- +You can read a complete simple example in the README. + + type Msg + KeyUp Int + + view : Html Msg + view = + textarea + [ rows 10 + , cols 40 + , onKeyUp KeyUp + ] + [] + ] + + update : Msg -> Model -> ( Model, Cmd Msg ) + update msg model = + case msg of + KeyUp code -> + (model, Cmd.none) +-} +onKeyUp : (Int -> msg) -> Attribute msg +onKeyUp tagger = + stopPropagationOn "keyup" <| + map alwaysStop (map tagger keyCode) + + +keyExtractor : Decoder ( Int, Bool ) +keyExtractor = + map2 Tuple.pair + (at [ "keyCode" ] int) + (at [ "shiftKey" ] bool) + + +alwaysStop : a -> ( a, Bool ) +alwaysStop x = + ( x, True )