@itrocks/autocomplete 0.1.3 → 0.1.5

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
@@ -1,30 +1,26 @@
1
- .combobox input[data-type=object] {
2
- display: block;
3
- }
4
- .combobox .suggestions {
1
+ .autocomplete + .suggestions {
5
2
  background: white;
6
3
  border: 1px solid #ddd;
7
4
  margin-top: -1px;
8
5
  padding: 0;
9
6
  position: absolute;
10
- top: 100%;
11
7
  z-index: 1;
12
8
  }
13
- .combobox .suggestions:empty {
9
+ .autocomplete + .suggestions:empty {
14
10
  height: 2em;
15
11
  width: 50px;
16
12
  }
17
- .combobox .suggestions > * {
13
+ .autocomplete + .suggestions > * {
18
14
  cursor: pointer;
19
15
  list-style: none;
20
16
  padding: 0.5em 1em;
21
17
  }
22
- .combobox .suggestions > *:hover {
18
+ .autocomplete + .suggestions > *:hover {
23
19
  background: #efe;
24
20
  }
25
- .combobox .suggestions > *.selected {
21
+ .autocomplete + .suggestions > *.selected {
26
22
  background: #edf;
27
23
  }
28
- .combobox .suggestions > *.selected:hover {
24
+ .autocomplete + .suggestions > *.selected:hover {
29
25
  background: #dce;
30
26
  }
package/autocomplete.d.ts CHANGED
@@ -15,6 +15,7 @@ export declare class AutoComplete {
15
15
  fetch(): void;
16
16
  initIdInput(): HTMLInputElement | undefined;
17
17
  initInput(input: HTMLInputElement): HTMLInputElement;
18
+ initParent(): void;
18
19
  keyDown(event: Event): void;
19
20
  keyEnter(event: Event): void;
20
21
  keyEscape(event: Event): void;
@@ -23,6 +24,8 @@ export declare class AutoComplete {
23
24
  onInput(event: Event): void;
24
25
  onInputValueChange(): void;
25
26
  onKeyDown(event: KeyboardEvent): void;
27
+ onTouchStart(event: Event): void;
28
+ openSuggestions(event: Event): boolean;
26
29
  select(): void;
27
30
  suggest(value?: string): void;
28
31
  }
package/autocomplete.js CHANGED
@@ -11,9 +11,11 @@ export class AutoComplete {
11
11
  this.input = this.initInput(input);
12
12
  this.idInput = this.initIdInput();
13
13
  this.suggestions = new Suggestions(this);
14
+ this.initParent();
14
15
  input.addEventListener('blur', event => this.onBlur(event));
15
16
  input.addEventListener('keydown', event => this.onKeyDown(event));
16
17
  input.addEventListener('input', event => this.onInput(event));
18
+ input.addEventListener('touchstart', event => this.onTouchStart(event));
17
19
  }
18
20
  autoComplete() {
19
21
  if (DEBUG)
@@ -112,25 +114,20 @@ export class AutoComplete {
112
114
  input.dataset.lastValue = input.value;
113
115
  return input;
114
116
  }
117
+ initParent() {
118
+ const parent = this.input.parentElement;
119
+ if (!parent)
120
+ return;
121
+ parent.style.position = 'relative';
122
+ }
115
123
  keyDown(event) {
116
124
  if (DEBUG)
117
125
  console.log('keyDown()');
118
- const suggestions = this.suggestions;
119
- if (!suggestions.length) {
120
- this.fetch();
121
- }
122
- if (!suggestions.isVisible()) {
123
- if (suggestions.length > 1) {
124
- event.preventDefault();
125
- suggestions.show();
126
- }
126
+ if (this.openSuggestions(event))
127
127
  return;
128
- }
129
- event.preventDefault();
130
- if (suggestions.isLastSelected()) {
128
+ if (this.suggestions.isLastSelected())
131
129
  return;
132
- }
133
- this.suggest(suggestions.selectNext()?.caption);
130
+ this.suggest(this.suggestions.selectNext()?.caption);
134
131
  }
135
132
  keyEnter(event) {
136
133
  if (DEBUG)
@@ -216,7 +213,26 @@ export class AutoComplete {
216
213
  return this.keyEnter(event);
217
214
  }
218
215
  }
216
+ onTouchStart(event) {
217
+ this.openSuggestions(event);
218
+ }
219
+ openSuggestions(event) {
220
+ const suggestions = this.suggestions;
221
+ if (!suggestions.length) {
222
+ this.fetch();
223
+ }
224
+ if (suggestions.isVisible()) {
225
+ return false;
226
+ }
227
+ if ((suggestions.length > 1) || (!this.input.value.length && suggestions.length)) {
228
+ event.preventDefault();
229
+ suggestions.show();
230
+ }
231
+ return true;
232
+ }
219
233
  select() {
234
+ if (DEBUG)
235
+ console.log('select()');
220
236
  const suggestions = this.suggestions;
221
237
  const suggestion = suggestions.selected();
222
238
  if (!suggestion)
@@ -254,29 +270,22 @@ class Suggestions {
254
270
  }
255
271
  createList() {
256
272
  if (DEBUG)
257
- console.log('Suggestions.createList()');
273
+ console.log('createList()');
258
274
  const list = this.list = document.createElement('ul');
259
275
  list.classList.add('suggestions');
260
- let input = this.combo.input;
261
- const idInput = input.nextElementSibling;
262
- if ((idInput instanceof HTMLInputElement) && (idInput.type === 'hidden')) {
263
- input = idInput;
264
- }
265
- input.insertAdjacentElement('afterend', list);
266
- if (DEBUG)
267
- console.log('Suggestions.prepareClic');
276
+ this.combo.input.insertAdjacentElement('afterend', list);
268
277
  list.addEventListener('pointerdown', event => this.onPointerDown(event));
269
278
  return list;
270
279
  }
271
280
  first() {
272
281
  if (DEBUG)
273
- console.log('Suggestions.first()');
282
+ console.log('first()');
274
283
  const item = this.list?.firstElementChild ?? null;
275
284
  return item && { caption: item.innerText, id: +(item.dataset.id ?? 0) };
276
285
  }
277
286
  hide() {
278
287
  if (DEBUG)
279
- console.log('Suggestions.hide()');
288
+ console.log('hide()');
280
289
  const list = this.list;
281
290
  if (!list)
282
291
  return;
@@ -297,7 +306,7 @@ class Suggestions {
297
306
  }
298
307
  onPointerDown(event) {
299
308
  if (DEBUG)
300
- console.log('Suggestions.onPointerDown()', event.button);
309
+ console.log('onPointerDown()', event.button);
301
310
  if (event.button !== 0)
302
311
  return;
303
312
  if (!(event.target instanceof Element))
@@ -317,16 +326,17 @@ class Suggestions {
317
326
  }
318
327
  removeList() {
319
328
  if (DEBUG)
320
- console.log('Suggestions.removeList()');
329
+ console.log('removeList()');
321
330
  if (!this.list)
322
331
  return;
332
+ this.length = 0;
323
333
  this.list.remove();
324
334
  this.list = undefined;
325
335
  }
326
336
  selected(item = null) {
327
337
  item ??= this.list?.querySelector('li.selected') ?? null;
328
338
  if (DEBUG)
329
- console.log('Suggestions.selected()', item && { caption: item.innerText, id: +(item.dataset.id ?? 0) });
339
+ console.log('selected()', item && { caption: item.innerText, id: +(item.dataset.id ?? 0) });
330
340
  return item && { caption: item.innerText, id: +(item.dataset.id ?? 0) };
331
341
  }
332
342
  selectFirst() {
@@ -369,11 +379,16 @@ class Suggestions {
369
379
  console.log('show()');
370
380
  if (this.list) {
371
381
  this.list.style.removeProperty('display');
382
+ if (!this.list.getAttribute('style')?.length) {
383
+ this.list.removeAttribute('style');
384
+ }
372
385
  return this.list;
373
386
  }
374
387
  return this.createList();
375
388
  }
376
389
  unselect(item = this.list?.querySelector('li.selected')) {
390
+ if (DEBUG)
391
+ console.log('unselect()');
377
392
  if (!item)
378
393
  return;
379
394
  const classList = item.classList;
package/package.json CHANGED
@@ -40,5 +40,5 @@
40
40
  },
41
41
  "type": "module",
42
42
  "types": "./autocomplete.d.ts",
43
- "version": "0.1.3"
43
+ "version": "0.1.5"
44
44
  }