ohanhi / keyboard / Keyboard

Convenience helpers for working with keyboard inputs.

Msg and Update

Using Keyboard this way, you get all the help it can provide. Use either this approach, or the plain subscriptions and handle the state yourself.


type Msg

Keyboard's internal message type.

subscriptions : Platform.Sub.Sub Msg

The subscriptions needed for the "Msg and Update" way.

More advanced

updateWithParser : KeyParser -> Msg -> List Key -> List Key

A more advanced version of update. Provide it with a smaller KeyParser than anyKey and it will perform a little bit faster.


type KeyChange
    = KeyDown Key
    | KeyUp Key

The second value updateWithKeyChange may return, representing the actual change that happened during the update.

updateWithKeyChange : KeyParser -> Msg -> List Key -> ( List Key, Maybe KeyChange )

This alternate update function answers the question: "Did the pressed down keys in fact change just now?"

You might be wondering why this is a Maybe KeyChange – it's because keydown events happen many times per second when you hold down a key. Thus, not all incoming messages actually cause a change in the model. Also, you will only get updates for the keys that match your KeyParser.

Key parsers


type RawKey

An unprocessed key value.

Use a KeyParser to turn it into something useful.


type alias KeyParser =
RawKey -> Maybe Key

A key parser can turn RawKeys into meaningful Keys for your program.

anyKeyUpper : KeyParser

This parser tries to match with all the keys I can recognize. Spacebar is used for the space key and Characters are all uppercase. This parser is used in update.

If the key doesn't match any of the categories, Nothing is returned.

Note: If you experience performance issues, you can use oneOf with some specific parsers.

anyKeyOriginal : KeyParser

The same as anyKeyUpper, but with Characters in the original case.

characterKeyUpper : RawKey -> Maybe Key

Returns the character that was pressed, always uppercase.

NOTE There is no reasonable way of actually telling if a certain key is a character or not. For now at least, consider this a Western language focused "best guess".

Examples on a US layout:

[A] -> Just (Character "A")

[Shift] + [A] -> Just (Character "A")

[Shift] + [1] -> Just (Character "!")

[Shift] -> Nothing

characterKeyOriginal : RawKey -> Maybe Key

Returns the character that was pressed, in the original case.

NOTE There is no reasonable way of actually telling if a certain key is a character or not. For now at least, consider this a Western language focused "best guess".

Examples on a US layout:

[A] -> Just (Character "a")

[Shift] + [A] -> Just (Character "A")

[Shift] + [1] -> Just (Character "!")

[Shift] -> Nothing

modifierKey : RawKey -> Maybe Key

Converts a RawKey if it is one of the modifier keys.

[Alt] -> Just Alt

[Tab] -> Nothing

whitespaceKey : RawKey -> Maybe Key

Converts a RawKey if it is one of the whitespace keys.

[Tab] -> Just Tab

[Alt] -> Nothing

navigationKey : RawKey -> Maybe Key

Converts a RawKey if it is one of the navigation keys.

[ArrowLeft] -> Just ArrowLeft

[A] -> Nothing

editingKey : RawKey -> Maybe Key

Converts a RawKey if it is one of the editing keys.

[Backspace] -> Just Backspace

[Enter] -> Nothing

functionKey : RawKey -> Maybe Key

Converts a RawKey if it is one of the function keys.

[F4] -> Just F4

[6] -> Nothing

phoneKey : RawKey -> Maybe Key

Converts a RawKey if it is one of the phone keys.

mediaKey : RawKey -> Maybe Key

Converts a RawKey if it is one of the media keys.

Combining key parsers

oneOf : List KeyParser -> RawKey -> Maybe Key

Turn any RawKey into a Key using the processing functions (modifierKey, whitespaceKey, etc.) provided. If the key doesn't match any of the categories, Nothing is returned.

Plain Subscriptions

If you prefer to only get "the facts" and do your own handling, use these subscriptions. Otherwise, you may be more comfortable with the Msg and Update.

downs : (RawKey -> msg) -> Platform.Sub.Sub msg

Subscription for key down events.

Note When the user presses and holds a key, there may or may not be many of these messages before the corresponding key up message.

ups : (RawKey -> msg) -> Platform.Sub.Sub msg

Subscription for key up events.

Low level

rawValue : RawKey -> String

Get the original string value of the RawKey.

eventKeyDecoder : Json.Decode.Decoder RawKey

Use this with Html keyboard events to retrieve a RawKey representing the key which triggered the event.

Html.Events.on "keydown" eventKeyDecoder

Keyboard keys


type Key
    = Character String
    | Alt
    | AltGraph
    | CapsLock
    | Control
    | Fn
    | FnLock
    | Hyper
    | Meta
    | NumLock
    | ScrollLock
    | Shift
    | Super
    | Symbol
    | SymbolLock
    | Enter
    | Tab
    | Spacebar
    | ArrowDown
    | ArrowLeft
    | ArrowRight
    | ArrowUp
    | End
    | Home
    | PageDown
    | PageUp
    | Backspace
    | Clear
    | Copy
    | CrSel
    | Cut
    | Delete
    | EraseEof
    | ExSel
    | Insert
    | Paste
    | Redo
    | Undo
    | F1
    | F2
    | F3
    | F4
    | F5
    | F6
    | F7
    | F8
    | F9
    | F10
    | F11
    | F12
    | F13
    | F14
    | F15
    | F16
    | F17
    | F18
    | F19
    | F20
    | Again
    | Attn
    | Cancel
    | ContextMenu
    | Escape
    | Execute
    | Find
    | Finish
    | Help
    | Pause
    | Play
    | Props
    | Select
    | ZoomIn
    | ZoomOut
    | AppSwitch
    | Call
    | Camera
    | CameraFocus
    | EndCall
    | GoBack
    | GoHome
    | HeadsetHook
    | LastNumberRedial
    | Notification
    | MannerMode
    | VoiceDial
    | ChannelDown
    | ChannelUp
    | MediaFastForward
    | MediaPause
    | MediaPlay
    | MediaPlayPause
    | MediaRecord
    | MediaRewind
    | MediaStop
    | MediaTrackNext
    | MediaTrackPrevious

These are all the keys that have names in Keyboard.