@neovici/cosmoz-autocomplete 13.3.1 → 13.4.1

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.
@@ -1,5 +1,6 @@
1
- import type { Activity } from '@neovici/cosmoz-utils/keybindings';
1
+ import { Activity, ANY_KEY } from '@neovici/cosmoz-utils/keybindings';
2
2
  export declare const AUTOCOMPLETE_DESELECT_LAST: Activity;
3
+ export declare const AUTOCOMPLETE_SEARCH_WHEN_SELECTED: Activity;
3
4
  export declare const autocompleteKeybindings: readonly [readonly [{
4
5
  readonly key: "ArrowUp";
5
6
  }, [symbol], {
@@ -28,4 +29,11 @@ export declare const autocompleteKeybindings: readonly [readonly [{
28
29
  readonly description: "Remove the last selected item";
29
30
  }, {
30
31
  readonly allowInEditable: true;
32
+ }], readonly [{
33
+ readonly key: typeof ANY_KEY;
34
+ }, [symbol], {
35
+ readonly title: "Start searching";
36
+ readonly description: "Start searching when you start typing when an item is selected";
37
+ }, {
38
+ readonly allowInEditable: true;
31
39
  }]];
@@ -1,5 +1,7 @@
1
+ import { ANY_KEY, } from '@neovici/cosmoz-utils/keybindings';
1
2
  import { listboxKeybindings } from '../listbox/listbox-keybindings';
2
3
  export const AUTOCOMPLETE_DESELECT_LAST = Symbol('autocomplete.deselect.last');
4
+ export const AUTOCOMPLETE_SEARCH_WHEN_SELECTED = Symbol('autocomplete.search.when.selected');
3
5
  export const autocompleteKeybindings = [
4
6
  ...listboxKeybindings,
5
7
  [
@@ -11,4 +13,13 @@ export const autocompleteKeybindings = [
11
13
  },
12
14
  { allowInEditable: true },
13
15
  ],
16
+ [
17
+ { key: ANY_KEY },
18
+ [AUTOCOMPLETE_SEARCH_WHEN_SELECTED],
19
+ {
20
+ title: 'Start searching',
21
+ description: 'Start searching when you start typing when an item is selected',
22
+ },
23
+ { allowInEditable: true },
24
+ ],
14
25
  ];
@@ -15,6 +15,7 @@ interface Base<I> {
15
15
  interface Meta<I> extends Omit<Base<I>, 'value'> {
16
16
  setOpened: (opened: boolean) => void;
17
17
  value: I[];
18
+ valueProperty?: string;
18
19
  }
19
20
  export interface Props<I> extends Base<I> {
20
21
  text?: string;
@@ -5,7 +5,7 @@ import { usePromise } from '@neovici/cosmoz-utils/hooks/use-promise';
5
5
  import { useActivity } from '@neovici/cosmoz-utils/keybindings';
6
6
  import { prop, strProp } from '@neovici/cosmoz-utils/object';
7
7
  import { useCallback, useEffect, useMemo, useProperty, useState, } from '@pionjs/pion';
8
- import { AUTOCOMPLETE_DESELECT_LAST } from './autocomplete-keybindings';
8
+ import { AUTOCOMPLETE_DESELECT_LAST, AUTOCOMPLETE_SEARCH_WHEN_SELECTED, } from './autocomplete-keybindings';
9
9
  import { EMPTY, normalize, notify, search } from './util';
10
10
  const useNotify = (host, fn, name) => useCallback((val) => {
11
11
  fn?.(val);
@@ -33,6 +33,19 @@ export const useAutocomplete = ({ value: _value, text, onChange: _onChange, onTe
33
33
  check: () => !disabled && empty && host.matches(':focus-within'),
34
34
  element: () => host,
35
35
  }, []);
36
+ useActivity({
37
+ activity: AUTOCOMPLETE_SEARCH_WHEN_SELECTED,
38
+ callback: (ev) => {
39
+ const values = array(value);
40
+ const isOne = limit === 1;
41
+ if (values.length > 0 && isOne && ev.key.length === 1) {
42
+ onChange(values.slice(0, -1));
43
+ }
44
+ },
45
+ allowDefault: true,
46
+ check: () => !disabled && empty && host.matches(':focus-within'),
47
+ element: () => host,
48
+ }, [limit]);
36
49
  // Clear query when popover closes
37
50
  useEffect(() => {
38
51
  if (!opened && !keepQuery)
@@ -52,6 +65,7 @@ export const useAutocomplete = ({ value: _value, text, onChange: _onChange, onTe
52
65
  keepOpened,
53
66
  setOpened,
54
67
  onSelect,
68
+ valueProperty,
55
69
  });
56
70
  const [, , state] = usePromise(source$);
57
71
  return {
@@ -98,22 +112,22 @@ export const useAutocomplete = ({ value: _value, text, onChange: _onChange, onTe
98
112
  if (disabled)
99
113
  return;
100
114
  meta.onSelect?.(newVal, meta);
101
- const { onChange, onText, limit, min, value: val, keepQuery, keepOpened, setOpened, } = meta;
115
+ const { onChange, onText, limit, min, value: val, keepQuery, keepOpened, setOpened, valueProperty, } = meta;
102
116
  if (!keepQuery)
103
117
  onText('');
104
118
  if (!keepOpened)
105
119
  setOpened(false);
106
- const value = array(val), deselect = value.includes(newVal);
120
+ const value = array(val), predicate = prop(valueProperty), deselect = value.some((v) => predicate(v) === predicate(newVal));
107
121
  if (deselect && value.length === min)
108
122
  return;
109
123
  onChange((deselect
110
- ? without(newVal)(value)
124
+ ? without(newVal, predicate)(value)
111
125
  : [...value, newVal]).slice(-limit));
112
126
  }, [disabled, meta]),
113
127
  onDeselect: useCallback((val) => {
114
128
  if (disabled)
115
129
  return;
116
- meta.onChange(without(val)(meta.value));
130
+ meta.onChange(without(val, prop(meta.valueProperty))(meta.value));
117
131
  }, [disabled, meta]),
118
132
  // whenever there is a query, override defaultIndex to 0, so the first result gets selected
119
133
  defaultIndex: query !== undefined && query?.length > 0 ? 0 : defaultIndex,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neovici/cosmoz-autocomplete",
3
- "version": "13.3.1",
3
+ "version": "13.4.1",
4
4
  "type": "module",
5
5
  "description": "A autocomplete input web component",
6
6
  "keywords": [
@@ -81,7 +81,7 @@
81
81
  "@lit-labs/virtualizer": "^2.0.0",
82
82
  "@neovici/cosmoz-dropdown": "^7.5.0",
83
83
  "@neovici/cosmoz-input": "^5.6.0",
84
- "@neovici/cosmoz-utils": "^6.19.0",
84
+ "@neovici/cosmoz-utils": "^6.20.0",
85
85
  "@pionjs/pion": "^2.7.1",
86
86
  "i18next": "^23.16.8",
87
87
  "lit-html": "^2.0.0 || ^3.0.0"