Skip to content

Commit f5057d6

Browse files
authored
Merge pull request #379 from materializecss/refactoring-events
Refactoring events
2 parents a020255 + 2ea62d5 commit f5057d6

14 files changed

+265
-125
lines changed

docs/css/ghpages-materialize.css

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/js/materialize.js

+43-33
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/autocomplete.ts

+7-8
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,12 @@ export class Autocomplete extends Component {
172172
}
173173
}
174174

175-
_handleInputKeyupAndFocus = (e) => {
175+
_handleInputKeyupAndFocus = (e: KeyboardEvent) => {
176176
if (e.type === 'keyup') Autocomplete._keydown = false;
177177
this.count = 0;
178178
const actualValue = this.el.value.toLowerCase();
179179
// Don't capture enter or arrow key usage.
180-
if (e.keyCode === 13 || e.keyCode === 38 || e.keyCode === 40) return;
180+
if (M.keys.ENTER.includes(e.key) || M.keys.ARROW_UP.includes(e.key) || M.keys.ARROW_DOWN.includes(e.key)) return;
181181
// Check if the input isn't empty
182182
// Check if focus triggered by tab
183183
if (this.oldVal !== actualValue && (M.tabPressed || e.type !== 'focus')) {
@@ -196,13 +196,12 @@ export class Autocomplete extends Component {
196196
this.oldVal = actualValue;
197197
}
198198

199-
_handleInputKeydown = (e) => {
199+
_handleInputKeydown = (e: KeyboardEvent) => {
200200
Autocomplete._keydown = true;
201201
// Arrow keys and enter key usage
202-
const keyCode = e.keyCode;
203202
const numItems = this.container.querySelectorAll('li').length;
204203
// select element on Enter
205-
if (keyCode === M.keys.ENTER && this.activeIndex >= 0) {
204+
if (M.keys.ENTER.includes(e.key) && this.activeIndex >= 0) {
206205
const liElement = this.container.querySelectorAll('li')[this.activeIndex];
207206
if (liElement) {
208207
this.selectOption(liElement.getAttribute('data-id'));
@@ -211,10 +210,10 @@ export class Autocomplete extends Component {
211210
return;
212211
}
213212
// Capture up and down key
214-
if (keyCode === M.keys.ARROW_UP || keyCode === M.keys.ARROW_DOWN) {
213+
if (M.keys.ARROW_UP.includes(e.key) || M.keys.ARROW_DOWN.includes(e.key)) {
215214
e.preventDefault();
216-
if (keyCode === M.keys.ARROW_UP && this.activeIndex > 0) this.activeIndex--;
217-
if (keyCode === M.keys.ARROW_DOWN && this.activeIndex < numItems - 1) this.activeIndex++;
215+
if (M.keys.ARROW_UP.includes(e.key) && this.activeIndex > 0) this.activeIndex--;
216+
if (M.keys.ARROW_DOWN.includes(e.key) && this.activeIndex < numItems - 1) this.activeIndex++;
218217
this.$active?.classList.remove('active');
219218
if (this.activeIndex >= 0) {
220219
this.$active = this.container.querySelectorAll('li')[this.activeIndex];

src/chips.ts

+12-16
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ export class Chips extends Component {
107107
this._input.removeEventListener('keydown', this._handleInputKeydown);
108108
}
109109

110-
_handleChipClick = (e) => {
110+
_handleChipClick = (e: Event) => {
111111
const _chip = (<HTMLElement>e.target).closest('.chip');
112112
const clickedClose = (<HTMLElement>e.target).classList.contains('close');
113113
if (_chip) {
@@ -126,7 +126,7 @@ export class Chips extends Component {
126126
}
127127
}
128128

129-
static _handleChipsKeydown(e) {
129+
static _handleChipsKeydown(e: KeyboardEvent) {
130130
Chips._keydown = true;
131131
const chips = (<HTMLElement>e.target).closest('.chips');
132132
const chipsKeydown = e.target && chips;
@@ -136,8 +136,8 @@ export class Chips extends Component {
136136
if (tag === 'INPUT' || tag === 'TEXTAREA' || !chipsKeydown) return;
137137

138138
const currChips: Chips = (chips as any).M_Chips;
139-
// backspace and delete
140-
if (e.keyCode === 8 || e.keyCode === 46) {
139+
140+
if (M.keys.BACKSPACE.includes(e.key) || M.keys.DELETE.includes(e.key)) {
141141
e.preventDefault();
142142
let selectIndex = currChips.chipsData.length;
143143
if (currChips._selectedChip) {
@@ -152,16 +152,14 @@ export class Chips extends Component {
152152
else
153153
currChips._input.focus();
154154
}
155-
// left arrow key
156-
else if (e.keyCode === 37) {
155+
else if (M.keys.ARROW_LEFT.includes(e.key)) {
157156
if (currChips._selectedChip) {
158157
const selectIndex = gGetIndex(currChips._selectedChip) - 1;
159158
if (selectIndex < 0) return;
160159
currChips.selectChip(selectIndex);
161160
}
162161
}
163-
// right arrow key
164-
else if (e.keyCode === 39) {
162+
else if (M.keys.ARROW_RIGHT.includes(e.key)) {
165163
if (currChips._selectedChip) {
166164
const selectIndex = gGetIndex(currChips._selectedChip) + 1;
167165
if (selectIndex >= currChips.chipsData.length)
@@ -172,11 +170,11 @@ export class Chips extends Component {
172170
}
173171
}
174172

175-
static _handleChipsKeyup(e) {
173+
static _handleChipsKeyup(e: Event) {
176174
Chips._keydown = false;
177175
}
178176

179-
static _handleChipsBlur(e) {
177+
static _handleChipsBlur(e: Event) {
180178
if (!Chips._keydown && document.hidden) {
181179
const chips = (<HTMLElement>e.target).closest('.chips');
182180
const currChips: Chips = (chips as any).M_Chips;
@@ -192,10 +190,9 @@ export class Chips extends Component {
192190
this.el.classList.remove('focus');
193191
}
194192

195-
_handleInputKeydown = (e) => {
193+
_handleInputKeydown = (e: KeyboardEvent) => {
196194
Chips._keydown = true;
197-
// enter
198-
if (e.keyCode === 13) {
195+
if (M.keys.ENTER.includes(e.key)) {
199196
// Override enter if autocompleting.
200197
if (this.hasAutocomplete && this.autocomplete && this.autocomplete.isOpen) {
201198
return;
@@ -205,10 +202,9 @@ export class Chips extends Component {
205202
this.addChip({id: this._input.value});
206203
}
207204
this._input.value = '';
208-
// delete or left
209205
}
210-
else if (
211-
(e.keyCode === 8 || e.keyCode === 37) &&
206+
else if (
207+
(M.keys.BACKSPACE.includes(e.key) || M.keys.ARROW_LEFT.includes(e.key)) &&
212208
this._input.value === '' &&
213209
this.chipsData.length
214210
) {

src/collapsible.ts

+18-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,22 @@
1+
import { M } from "./global";
12
import { Component } from "./component";
23
import anim from "animejs";
34

4-
const _defaults = {
5+
interface CollapsibleOptions {
6+
accordion: boolean;
7+
onOpenStart: Function|undefined;
8+
onOpenEnd: Function|undefined;
9+
onCloseStart: Function|undefined;
10+
onCloseEnd: Function|undefined;
11+
inDuration: number;
12+
outDuration: number;
13+
}
14+
15+
const _defaults: CollapsibleOptions = {
516
accordion: true,
617
onOpenStart: undefined,
718
onOpenEnd: undefined,
8-
onCloseStart: undefined,
19+
onCloseStart: undefined,
920
onCloseEnd: undefined,
1021
inDuration: 300,
1122
outDuration: 300
@@ -14,9 +25,9 @@ const _defaults = {
1425
export class Collapsible extends Component {
1526
private _headers: HTMLElement[];
1627

17-
constructor(el, options) {
28+
constructor(el: HTMLElement, options: CollapsibleOptions) {
1829
super(Collapsible, el, options);
19-
(this.el as any).M_Collapsible = this;
30+
this.el['M_Collapsible'] = this;
2031
this.options = {...Collapsible.defaults, ...options};
2132
// Setup tab indices
2233
this._headers = Array.from(this.el.querySelectorAll('li > .collapsible-header'));
@@ -46,7 +57,7 @@ export class Collapsible extends Component {
4657

4758
destroy() {
4859
this._removeEventHandlers();
49-
(this.el as any).M_Collapsible = undefined;
60+
this.el['M_Collapsible'].M_Collapsible = undefined;
5061
}
5162

5263
_setupEventHandlers() {
@@ -76,8 +87,8 @@ export class Collapsible extends Component {
7687
}
7788
}
7889

79-
_handleCollapsibleKeydown = (e) => {
80-
if (e.keyCode === 13) {
90+
_handleCollapsibleKeydown = (e: KeyboardEvent) => {
91+
if (M.keys.ENTER.includes(e.key)) {
8192
this._handleCollapsibleClick(e);
8293
}
8394
}

src/datepicker.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -743,8 +743,8 @@ export class Datepicker extends Component {
743743
this.open();
744744
}
745745

746-
_handleInputKeydown = (e) => {
747-
if (e.which === M.keys.ENTER) {
746+
_handleInputKeydown = (e: KeyboardEvent) => {
747+
if (M.keys.ENTER.includes(e.key)) {
748748
e.preventDefault();
749749
this.open();
750750
}

src/dropdown.ts

+16-13
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,10 @@ export class Dropdown extends Component {
164164
this.isTouchMoving = false;
165165
}
166166

167-
_handleTriggerKeydown = (e) => {
167+
_handleTriggerKeydown = (e: KeyboardEvent) => {
168168
// ARROW DOWN OR ENTER WHEN SELECT IS CLOSED - open Dropdown
169-
if ((e.which === M.keys.ARROW_DOWN || e.which === M.keys.ENTER) && !this.isOpen) {
169+
const arrowDownOrEnter = M.keys.ARROW_DOWN.includes(e.key) || M.keys.ENTER.includes(e.key);
170+
if (arrowDownOrEnter && !this.isOpen) {
170171
e.preventDefault();
171172
this.open();
172173
}
@@ -187,15 +188,16 @@ export class Dropdown extends Component {
187188
}
188189
}
189190

190-
_handleDropdownKeydown = (e) => {
191-
if (e.which === M.keys.TAB) {
191+
_handleDropdownKeydown = (e: KeyboardEvent) => {
192+
const arrowUpOrDown = M.keys.ARROW_DOWN.includes(e.key) || M.keys.ARROW_UP.includes(e.key);
193+
if (M.keys.TAB.includes(e.key)) {
192194
e.preventDefault();
193195
this.close();
194196
}
195197
// Navigate down dropdown list
196-
else if ((e.which === M.keys.ARROW_DOWN || e.which === M.keys.ARROW_UP) && this.isOpen) {
198+
else if (arrowUpOrDown && this.isOpen) {
197199
e.preventDefault();
198-
const direction = e.which === M.keys.ARROW_DOWN ? 1 : -1;
200+
const direction = M.keys.ARROW_DOWN.includes(e.key) ? 1 : -1;
199201
let newFocusedIndex = this.focusedIndex;
200202
let hasFoundNewIndex = false;
201203
do {
@@ -218,7 +220,7 @@ export class Dropdown extends Component {
218220
}
219221
}
220222
// ENTER selects choice on focused item
221-
else if (e.which === M.keys.ENTER && this.isOpen) {
223+
else if (M.keys.ENTER.includes(e.key) && this.isOpen) {
222224
// Search for <a> and <button>
223225
const focusedElement = this.dropdownEl.children[this.focusedIndex];
224226
const activatableElement = <HTMLElement>focusedElement.querySelector('a, button');
@@ -233,16 +235,17 @@ export class Dropdown extends Component {
233235
}
234236
}
235237
// Close dropdown on ESC
236-
else if (e.which === M.keys.ESC && this.isOpen) {
238+
else if (M.keys.ESC.includes(e.key) && this.isOpen) {
237239
e.preventDefault();
238240
this.close();
239241
}
240242

241-
// CASE WHEN USER TYPE LETTERS
242-
const letter = String.fromCharCode(e.which).toLowerCase();
243-
const nonLetters = [9, 13, 27, 38, 40];
244-
if (letter && nonLetters.indexOf(e.which) === -1) {
245-
this.filterQuery.push(letter);
243+
// CASE WHEN USER TYPE LTTERS
244+
const keyText = e.key.toLowerCase();
245+
const isLetter = /[a-zA-Z0-9-_]/.test(keyText);
246+
const specialKeys = [...M.keys.ARROW_DOWN, ...M.keys.ARROW_UP, ...M.keys.ENTER, ...M.keys.ESC, ...M.keys.TAB];
247+
if (isLetter && !specialKeys.includes(e.key)) {
248+
this.filterQuery.push(keyText);
246249
const string = this.filterQuery.join('');
247250
const newOptionEl = Array.from(this.dropdownEl.querySelectorAll('li'))
248251
.find((el) => el.innerText.toLowerCase().indexOf(string) === 0);

src/forms.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,12 @@ export class Forms {
7676
static Init(){
7777
document.addEventListener("DOMContentLoaded", () => {
7878

79-
document.addEventListener('keyup', e => {
79+
document.addEventListener('keyup', (e: KeyboardEvent) => {
8080
const target = <HTMLInputElement>e.target;
8181
// Radio and Checkbox focus class
8282
if (target instanceof HTMLInputElement && ['radio','checkbox'].includes(target.type)) {
8383
// TAB, check if tabbing to radio or checkbox.
84-
if (e.which === M.keys.TAB) {
84+
if (M.keys.TAB.includes(e.key)) {
8585
target.classList.add('tabbed');
8686
target.addEventListener('blur', e => target.classList.remove('tabbed'), {once: true});
8787
}

src/global.ts

+15-11
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,15 @@ export class M {
3030
static version = '2.0.1-alpha';
3131

3232
static keys = {
33-
TAB: 9,
34-
ENTER: 13,
35-
ESC: 27,
36-
ARROW_UP: 38,
37-
ARROW_DOWN: 40
33+
TAB: ['Tab'],
34+
ENTER: ['Enter'],
35+
ESC: ['Escape', 'Esc'],
36+
BACKSPACE: ['Backspace'],
37+
ARROW_UP: ['ArrowUp', 'Up'],
38+
ARROW_DOWN: ['ArrowDown', 'Down'],
39+
ARROW_LEFT: ['ArrowLeft', 'Left'],
40+
ARROW_RIGHT: ['ArrowRight', 'Right'],
41+
DELETE: ['Delete', 'Del'],
3842
};
3943

4044
static Autocomplete: typeof Autocomplete = Autocomplete;
@@ -61,19 +65,19 @@ export class M {
6165
static Range: typeof Range = Range;
6266
static Waves: typeof Waves = Waves;
6367

64-
static tabPressed:boolean = false;
65-
static keyDown:boolean = false;
68+
static tabPressed: boolean = false;
69+
static keyDown: boolean = false;
6670

67-
static docHandleKeydown(e) {
71+
static docHandleKeydown(e: KeyboardEvent) {
6872
M.keyDown = true;
69-
if (e.which === M.keys.TAB || e.which === M.keys.ARROW_DOWN || e.which === M.keys.ARROW_UP) {
73+
if ([...M.keys.TAB, ...M.keys.ARROW_DOWN, ...M.keys.ARROW_UP].includes(e.key)) {
7074
M.tabPressed = true;
7175
}
7276
}
7377

74-
static docHandleKeyup(e) {
78+
static docHandleKeyup(e: KeyboardEvent) {
7579
M.keyDown = false;
76-
if (e.which === M.keys.TAB || e.which === M.keys.ARROW_DOWN || e.which === M.keys.ARROW_UP) {
80+
if ([...M.keys.TAB, ...M.keys.ARROW_DOWN, ...M.keys.ARROW_UP].includes(e.key)) {
7781
M.tabPressed = false;
7882
}
7983
}

src/materialbox.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,8 @@ export class Materialbox extends Component {
9494
if (this.overlayActive) this.close();
9595
}
9696

97-
_handleWindowEscape = (e) => {
98-
// ESC key
99-
if (e.keyCode === 27 && this.doneAnimating && this.overlayActive) this.close();
97+
_handleWindowEscape = (e: KeyboardEvent) => {
98+
if (M.keys.ESC.includes(e.key) && this.doneAnimating && this.overlayActive) this.close();
10099
}
101100

102101
_makeAncestorsOverflowVisible() {

src/modal.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,8 @@ export class Modal extends Component {
9696
if (closeTrigger) this.close();
9797
}
9898

99-
_handleKeydown = (e) => {
100-
// ESC key
101-
if (e.keyCode === 27 && this.options.dismissible) this.close();
99+
_handleKeydown = (e: KeyboardEvent) => {
100+
if (M.keys.ESC.includes(e.key) && this.options.dismissible) this.close();
102101
}
103102

104103
_handleFocus = (e) => {

src/timepicker.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -140,15 +140,15 @@ export class Timepicker extends Component {
140140
this.open();
141141
}
142142

143-
_handleInputKeydown = (e) => {
144-
if (e.which === M.keys.ENTER) {
143+
_handleInputKeydown = (e: KeyboardEvent) => {
144+
if (M.keys.ENTER.includes(e.key)) {
145145
e.preventDefault();
146146
this.open();
147147
}
148148
}
149149

150-
_handleTimeInputEnterKey = (e) => {
151-
if (e.which === M.keys.ENTER) {
150+
_handleTimeInputEnterKey = (e: KeyboardEvent) => {
151+
if (M.keys.ENTER.includes(e.key)) {
152152
e.preventDefault();
153153
this._inputFromTextField();
154154
}

0 commit comments

Comments
 (0)