-
Notifications
You must be signed in to change notification settings - Fork 22
/
iron-a11y-keys.js
173 lines (137 loc) · 5.78 KB
/
iron-a11y-keys.js
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/**
@license
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at
http://polymer.github.io/LICENSE.txt The complete set of authors may be found at
http://polymer.github.io/AUTHORS.txt The complete set of contributors may be
found at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as
part of the polymer project is also subject to an additional IP rights grant
found at http://polymer.github.io/PATENTS.txt
*/
import '@polymer/polymer/polymer-legacy.js';
import {IronA11yKeysBehavior} from '@polymer/iron-a11y-keys-behavior/iron-a11y-keys-behavior.js';
import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
/**
`iron-a11y-keys` provides a cross-browser interface for processing
keyboard commands. The interface adheres to [WAI-ARIA best
practices](http://www.w3.org/TR/wai-aria-practices/#kbd_general_binding).
It uses an expressive syntax to filter key presses.
## Basic usage
The sample code below is a portion of a custom element. The goal is to call
the `onEnter` method whenever the `paper-input` element is in focus and
the `Enter` key is pressed.
<iron-a11y-keys id="a11y" target="[[target]]" keys="enter"
on-keys-pressed="onEnter"></iron-a11y-keys>
<paper-input id="input"
placeholder="Type something. Press enter. Check console."
value="{{userInput::input}}"></paper-input>
The custom element declares an `iron-a11y-keys` element that is bound to a
property called `target`. The `target` property
needs to evaluate to the `paper-input` node. `iron-a11y-keys` registers
an event handler for the target node using Polymer's [annotated event handler
syntax](https://www.polymer-project.org/1.0/docs/devguide/events.html#annotated-listeners).
`{{userInput::input}}` sets the `userInput` property to the user's input on each
keystroke.
The last step is to link the two elements within the custom element's
registration.
...
properties: {
userInput: {
type: String,
notify: true,
},
target: {
type: Object,
value: function() {
return this.$.input;
}
},
},
onEnter: function() {
console.log(this.userInput);
}
...
## The `keys` attribute
The `keys` attribute expresses what combination of keys triggers the event.
The attribute accepts a space-separated, plus-sign-concatenated
set of modifier keys and some common keyboard keys.
The common keys are: `a-z`, `0-9` (top row and number pad), `*` (shift 8 and
number pad), `F1-F12`, `Page Up`, `Page Down`, `Left Arrow`, `Right Arrow`,
`Down Arrow`, `Up Arrow`, `Home`, `End`, `Escape`, `Space`, `Tab`, `Enter`.
The modifier keys are: `Shift`, `Control`, `Alt`, `Meta`.
All keys are expected to be lowercase and shortened. E.g.
`Left Arrow` is `left`, `Page Down` is `pagedown`, `Control` is `ctrl`,
`F1` is `f1`, `Escape` is `esc`, etc.
### Grammar
Below is the
[EBNF](http://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form) Grammar
of the `keys` attribute.
modifier = "shift" | "ctrl" | "alt" | "meta";
ascii = ? /[a-z0-9]/ ? ;
fnkey = ? f1 through f12 ? ;
arrow = "up" | "down" | "left" | "right" ;
key = "tab" | "esc" | "space" | "*" | "pageup" | "pagedown" |
"home" | "end" | arrow | ascii | fnkey;
event = "keypress" | "keydown" | "keyup";
keycombo = { modifier, "+" }, key, [ ":", event ] ;
keys = keycombo, { " ", keycombo } ;
### Example
Given the following value for `keys`:
`ctrl+shift+f7 up pagedown esc space alt+m`
The event is fired if any of the following key combinations are fired:
`Control` and `Shift` and `F7` keys, `Up Arrow` key, `Page Down` key,
`Escape` key, `Space` key, `Alt` and `M` keys.
### WAI-ARIA Slider Example
The following is an example of the set of keys that fulfills WAI-ARIA's
"slider" role [best
practices](http://www.w3.org/TR/wai-aria-practices/#slider):
<iron-a11y-keys target="[[target]]" keys="left pagedown down"
on-keys-pressed="decrement"></iron-a11y-keys>
<iron-a11y-keys target="[[target]]" keys="right pageup up"
on-keys-pressed="increment"></iron-a11y-keys>
<iron-a11y-keys target="[[target]]" keys="home"
on-keys-pressed="setMin"></iron-a11y-keys>
<iron-a11y-keys target="[[target]]" keys="end"
on-keys-pressed="setMax"></iron-a11y-keys>
The `target` properties must evaluate to a node. See the basic usage
example above.
Each of the values for the `on-keys-pressed` attributes must evalute
to methods. The `increment` method should move the slider a set amount
toward the maximum value. `decrement` should move the slider a set amount
toward the minimum value. `setMin` should move the slider to the minimum
value. `setMax` should move the slider to the maximum value.
@demo demo/index.html
*/
Polymer({
is: 'iron-a11y-keys',
/** @override */
_template: null,
behaviors: [IronA11yKeysBehavior],
properties: {
/** @type {?Node} */
target: {type: Object, observer: '_targetChanged'},
/**
* Space delimited list of keys where each key follows the format:
* `[MODIFIER+]*KEY[:EVENT]`.
* e.g. `keys="space ctrl+shift+tab enter:keyup"`.
* More detail can be found in the "Grammar" section of the documentation
*/
keys: {type: String, reflectToAttribute: true, observer: '_keysChanged'}
},
/** @override */
attached: function() {
if (!this.target) {
this.target = this.parentNode;
}
},
_targetChanged: function(target) {
this.keyEventTarget = target;
},
_keysChanged: function() {
this.removeOwnKeyBindings();
this.addOwnKeyBinding(this.keys, '_fireKeysPressed');
},
_fireKeysPressed: function(event) {
this.fire('keys-pressed', event.detail, {});
}
});