Giter Site home page Giter Site logo

tommy-mor / re-pressed Goto Github PK

View Code? Open in Web Editor NEW

This project forked from gadfly361/re-pressed

0.0 2.0 0.0 8.03 MB

re-pressed is a clojurescript library that handles keyboard events for re-frame applications.

License: MIT License

HTML 1.23% Clojure 98.77%

re-pressed's Introduction

re-pressed

Arthur: Shut up, will you, SHUT UP! Man: Aha! Now we see the violence inherent in the system! Arthur: SHUT UP! Man: Come and see the violence inherent in the system! HELP, HELP, I'M BEING REPRESSED! Arthur: Bloody PEASANT! Man: Oh, what a giveaway! Did'j'hear that, did'j'hear that, eh? That's what I'm all about! Did you see 'im repressing me? You saw it, didn't you?!

  • Monty Python and the Holy Grail

Re-pressed is a library that handles keyboard events for re-frame applications.

[re-pressed "0.2.2"]

And in your ns:

(ns your-ns
  (:require [re-pressed.core :as rp]))

Note: For now, this library should be considered alpha quality, as the api is still settling.

re-pressed gif not found

The Problem

If you aren't careful, it is easy to add a bunch of keyboard event listeners scattered throughout your application. When these listeners collide, this can lead to unexpected and hard to debug behavior.

In addition, the current state of how to identify a keyboard event in a cross-browser compatible way can be quite cumbersome ... you will likely be asking yourself, "Should I use keyCode, key, which, etc?".

Re-pressed's Solution

With re-pressed, you only set up one keyboard event listener when your application starts, with ::rp/add-keyboard-event-listener. However, that does not mean that you are locked in to one set of rules for how to handle keyboard events. By dispatching ::rp/set-keydown-rules, ::rp/set-keypress-rules, or ::rp/set-keyup-rules, you can update the rules dynamically.

In addition, jQuery is able to ensure cross-browser compatibility with their which attribute. Re-pressed trusts that jQuery will do a good job at keeping this current and uses it under the hood.

API

::rp/add-keyboard-event-listener

::rp/add-keyboard-event-listener adds the keyboard event listener to your application. Needs to be dispatched only once, when the application first loads.

There are three options, and you can use more than one if you'd like:

(re-frame/dispatch-sync [::rp/add-keyboard-event-listener "keydown"])

;; or
(re-frame/dispatch-sync [::rp/add-keyboard-event-listener "keypress"])

;; or
(re-frame/dispatch-sync [::rp/add-keyboard-event-listener "keyup"])

::rp/set-keydown-rules

::rp/set-keydown-rules takes a hash-map of :event-keys, :clear-keys, :always-listen-keys, and :prevent-default-keys and listens for keydown events.

  • For :event-keys, there is a vector of event + key combo vectors. If any of the key combos are true, then the event will get dispatched.
  • For :clear-keys, there is a vector of key combo vectors. If any of the key combos are true, then the recently recorded keys will be cleared.
  • For :always-listen-keys, there is a vector of just keys. If any of the keys are pressed, then that key will always be recorded by re-pressed. By default, keys are ignored when pressed inside of an input, select, or textarea.
  • For :prevent-default-keys there is a vector of just keys. If any of the keys are pressed, then the default browser action for that key will be prevented.

This is a description of the shape:

(re-frame/dispatch
 [::rp/set-keydown-rules
  {:event-keys [
                [<event vector>
                 <key-combo vector>
                 ...
                 <key-combo vectorN>]
                ]

   :clear-keys [<key-combo vector>
                ...
                <key-combo vectorN>]

   :always-listen-keys [<key>
                        ...
                        <keyN>]

   :prevent-default-keys [<key>
                          ...
                          <keyN>]

   }])

Here is an example:

(re-frame/dispatch
 [::rp/set-keydown-rules
  {;; takes a collection of events followed by key combos that can trigger the event
   :event-keys [
                ;; Event & key combos 1
                [;; this event
                 [:some-event-id1]
                 ;; will be triggered if
                 ;; enter
                 [{:which 13}]
                 ;; or delete
                 [{:which 46}]]
                ;; is pressed

                ;; Event & key combos 2
                [;; this event
                 [:some-event-id2]
                 ;; will be triggered if
                 ;; tab is pressed twice in a row
                 [{:which 9} {:which 9}]
                 ]]

   ;; takes a collection of key combos that, if pressed, will clear
   ;; the recorded keys
   :clear-keys
   ;; will clear the previously recorded keys if
   [;; escape
    [{:which 27}]
    ;; or Ctrl+g
    [{:which   71
      :ctrlKey true}]]
   ;; is pressed

   ;; takes a collection of keys that will always be recorded
   ;; (regardless if the user is typing in an input, select, or textarea)
   :always-listen-keys
   ;; will always record if
   [;; enter
    {:which 13}]
   ;; is pressed

   ;; takes a collection of keys that will prevent the default browser
   ;; action when any of those keys are pressed
   ;; (note: this is only available to keydown)
   :prevent-default-keys
   ;; will prevent the browser default action if
   [;; Ctrl+g
    {:which   71
      :ctrlKey true}]
    ;; is pressed
   }])

For :event-keys, :clear-keys, :always-listen-keys, and :prevent-default-keys, the keys take the following shape:

{:which    <int>
 :altKey   <boolean>
 :ctrlKey  <boolean>
 :metaKey  <boolean>
 :shiftKey <boolean>
 }

For :event-keys, the event will be called with a few things conjed on to the end of the event vector. For example:

;; this event
[:some-event-id1]

;; will be dispatched as
[:some-event-id1 js-event keyboard-keys]

Where:

  • js-event is the javascript event (i.e. jQuery event) of the most recently pressed key
  • keyboard-keys is a collection of the recently pressed keys taking the shape of the clojurescript hash-map described above.

::rp/set-keypress-rules

Listens to keypress events, otherwise it is the same as ::rp/set-keydown-rules (except :prevent-default-keys is not supported).

::rp/set-keyup-rules

Listens to keyup events, otherwise it is the same as ::rp/set-keydown-rules (except :prevent-default-keys is not supported).

Usage

Create a new re-frame application and add the +re-pressed option.

lein new re-frame foo +re-pressed

Gotchas

  • If you are seeing multiple instances of the same event being triggered, it is probably because you are dispatching ::rp/add-keyboard-event-listener multiple times. This happens most often when using hot reload tools, such as figwheel, and you dispatch-sync the ::rp/add-keyboard-event-listener event in a place that figwheel calls on reload ... instead of in a function that only gets called once when the application first starts.
  • For keypress events, you only have access to things like letters and numbers. This is unlike keydown and keyup events, where you have access to more things like the Escape key.
  • Using :prevent-default-keys only works with ::rp/set-keydown-rules. This is because the default browser action will happen before keypress and keyup events happen.
  • Certain browser default actions cannot be overwritten, like ctrl+n in chrome.

Side note:

When using re-pressed, you will need to dispatch a ::rp/set-keydown-rules, ::rp/set-keypress-rules, or ::rp/set-keyup-rules event somewhere. Personally, I like dispatching this in my routes file because I may want to handle keyboard events differently on each page.

Questions

If you have questions, I can usually be found hanging out in the clojurians #reagent slack channel (my handle is @gadfly361).

License

Copyright © 2018 Matthew Jaoudi

Distributed under the The MIT License (MIT).

re-pressed's People

Contributors

gadfly361 avatar reefersleep avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.