@itrocks/autocomplete 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/autocomplete.css CHANGED
@@ -4,6 +4,7 @@
4
4
  margin-top: -1px;
5
5
  padding: 0;
6
6
  position: absolute;
7
+ user-select: none;
7
8
  z-index: 1;
8
9
  }
9
10
  .autocomplete + .suggestions:empty {
package/autocomplete.d.ts CHANGED
@@ -24,21 +24,32 @@ export declare class AutoComplete {
24
24
  onInput(event: Event): void;
25
25
  onInputValueChange(): void;
26
26
  onKeyDown(event: KeyboardEvent): void;
27
+ onTouchStart(event: Event): void;
28
+ openSuggestions(event: Event): boolean;
27
29
  select(): void;
28
30
  suggest(value?: string): void;
29
31
  }
30
32
  declare class Suggestions {
31
- combo: AutoComplete;
33
+ autoComplete: AutoComplete;
32
34
  length: number;
33
35
  list?: HTMLUListElement;
34
- constructor(combo: AutoComplete);
36
+ pointerStart?: {
37
+ id: number;
38
+ item: HTMLLIElement;
39
+ x: number;
40
+ y: number;
41
+ };
42
+ constructor(autoComplete: AutoComplete);
35
43
  createList(): HTMLUListElement;
36
44
  first(): Item | null;
37
45
  hide(): void;
38
46
  isFirstSelected(): boolean | null | undefined;
39
47
  isLastSelected(): boolean | null | undefined;
40
48
  isVisible(): boolean | undefined;
41
- onPointerDown(event: MouseEvent): void;
49
+ onPointerDown(event: PointerEvent): void;
50
+ onPointerCancel(_event: PointerEvent): void;
51
+ onPointerMove(event: PointerEvent): void;
52
+ onPointerUp(event: PointerEvent): void;
42
53
  removeList(): void;
43
54
  selected(item?: HTMLLIElement | null): Item | null;
44
55
  selectFirst(): void;
package/autocomplete.js CHANGED
@@ -15,6 +15,7 @@ export class AutoComplete {
15
15
  input.addEventListener('blur', event => this.onBlur(event));
16
16
  input.addEventListener('keydown', event => this.onKeyDown(event));
17
17
  input.addEventListener('input', event => this.onInput(event));
18
+ input.addEventListener('touchstart', event => this.onTouchStart(event));
18
19
  }
19
20
  autoComplete() {
20
21
  if (DEBUG)
@@ -122,22 +123,11 @@ export class AutoComplete {
122
123
  keyDown(event) {
123
124
  if (DEBUG)
124
125
  console.log('keyDown()');
125
- const suggestions = this.suggestions;
126
- if (!suggestions.length) {
127
- this.fetch();
128
- }
129
- if (!suggestions.isVisible()) {
130
- if (suggestions.length > 1) {
131
- event.preventDefault();
132
- suggestions.show();
133
- }
126
+ if (this.openSuggestions(event))
134
127
  return;
135
- }
136
- event.preventDefault();
137
- if (suggestions.isLastSelected()) {
128
+ if (this.suggestions.isLastSelected())
138
129
  return;
139
- }
140
- this.suggest(suggestions.selectNext()?.caption);
130
+ this.suggest(this.suggestions.selectNext()?.caption);
141
131
  }
142
132
  keyEnter(event) {
143
133
  if (DEBUG)
@@ -147,6 +137,7 @@ export class AutoComplete {
147
137
  return;
148
138
  event.preventDefault();
149
139
  this.select();
140
+ suggestions.hide();
150
141
  }
151
142
  keyEscape(event) {
152
143
  if (DEBUG)
@@ -223,6 +214,23 @@ export class AutoComplete {
223
214
  return this.keyEnter(event);
224
215
  }
225
216
  }
217
+ onTouchStart(event) {
218
+ this.openSuggestions(event);
219
+ }
220
+ openSuggestions(event) {
221
+ const suggestions = this.suggestions;
222
+ if (!suggestions.length) {
223
+ this.fetch();
224
+ }
225
+ if (suggestions.isVisible()) {
226
+ return false;
227
+ }
228
+ if ((suggestions.length > 1) || (!this.input.value.length && suggestions.length)) {
229
+ event.preventDefault();
230
+ suggestions.show();
231
+ }
232
+ return true;
233
+ }
226
234
  select() {
227
235
  if (DEBUG)
228
236
  console.log('select()');
@@ -235,7 +243,6 @@ export class AutoComplete {
235
243
  this.input.value = suggestion.caption;
236
244
  this.onInputValueChange();
237
245
  this.autoIdInputValue();
238
- suggestions.hide();
239
246
  }
240
247
  suggest(value) {
241
248
  if (DEBUG)
@@ -255,19 +262,23 @@ export class AutoComplete {
255
262
  }
256
263
  }
257
264
  class Suggestions {
258
- combo;
265
+ autoComplete;
259
266
  length = 0;
260
267
  list;
261
- constructor(combo) {
262
- this.combo = combo;
268
+ pointerStart;
269
+ constructor(autoComplete) {
270
+ this.autoComplete = autoComplete;
263
271
  }
264
272
  createList() {
265
273
  if (DEBUG)
266
274
  console.log('createList()');
267
275
  const list = this.list = document.createElement('ul');
268
276
  list.classList.add('suggestions');
269
- this.combo.input.insertAdjacentElement('afterend', list);
277
+ this.autoComplete.input.insertAdjacentElement('afterend', list);
270
278
  list.addEventListener('pointerdown', event => this.onPointerDown(event));
279
+ list.addEventListener('pointercancel', event => this.onPointerCancel(event));
280
+ list.addEventListener('pointermove', event => this.onPointerMove(event));
281
+ list.addEventListener('pointerup', event => this.onPointerUp(event));
271
282
  return list;
272
283
  }
273
284
  first() {
@@ -300,7 +311,7 @@ class Suggestions {
300
311
  onPointerDown(event) {
301
312
  if (DEBUG)
302
313
  console.log('onPointerDown()', event.button);
303
- if (event.button !== 0)
314
+ if ((event.pointerType === 'mouse') && (event.button !== 0))
304
315
  return;
305
316
  if (!(event.target instanceof Element))
306
317
  return;
@@ -312,16 +323,40 @@ class Suggestions {
312
323
  return;
313
324
  if (DEBUG)
314
325
  console.log(' select', item);
326
+ if (event.pointerType !== 'mouse') {
327
+ this.pointerStart = { id: event.pointerId, item, x: event.clientX, y: event.clientY };
328
+ return;
329
+ }
315
330
  this.unselect();
316
331
  item.classList.add('selected');
317
- this.combo.select();
318
- event.preventDefault();
332
+ this.autoComplete.select();
333
+ this.pointerStart = undefined;
334
+ }
335
+ onPointerCancel(_event) {
336
+ this.pointerStart = undefined;
337
+ }
338
+ onPointerMove(event) {
339
+ if (!this.pointerStart || (event.pointerId !== this.pointerStart.id))
340
+ return;
341
+ const distance = Math.abs(event.clientX - this.pointerStart.x) + Math.abs(event.clientY - this.pointerStart.y);
342
+ if (distance < 8)
343
+ return;
344
+ this.pointerStart = undefined;
345
+ }
346
+ onPointerUp(event) {
347
+ if (!this.pointerStart || (event.pointerId !== this.pointerStart.id))
348
+ return;
349
+ this.unselect();
350
+ this.pointerStart.item.classList.add('selected');
351
+ this.autoComplete.select();
352
+ this.pointerStart = undefined;
319
353
  }
320
354
  removeList() {
321
355
  if (DEBUG)
322
356
  console.log('removeList()');
323
357
  if (!this.list)
324
358
  return;
359
+ this.length = 0;
325
360
  this.list.remove();
326
361
  this.list = undefined;
327
362
  }
package/package.json CHANGED
@@ -40,5 +40,5 @@
40
40
  },
41
41
  "type": "module",
42
42
  "types": "./autocomplete.d.ts",
43
- "version": "0.1.4"
43
+ "version": "0.1.6"
44
44
  }