@neovici/cosmoz-autocomplete 4.0.0 → 5.1.0

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/cosmoz-listbox.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { html, component, useEffect } from 'haunted';
2
2
  import { virtualize } from '@lit-labs/virtualizer/virtualize.js';
3
3
  import { tagged as css } from '@neovici/cosmoz-utils';
4
- import { portal } from '@neovici/cosmoz-utils/lib/directives/portal';
5
- import { spreadProps } from '@neovici/cosmoz-utils/lib/directives/spread-props';
6
- import { props } from '@neovici/cosmoz-utils/lib/object';
4
+ import { portal } from '@neovici/cosmoz-utils/directives/portal';
5
+ import { spreadProps } from '@neovici/cosmoz-utils/directives/spread-props';
6
+ import { props } from '@neovici/cosmoz-utils/object';
7
7
  import { useListbox, properties } from './lib/use-listbox';
8
8
  import { scrollIntoViewIfNeeded } from './lib/utils';
9
9
 
@@ -42,7 +42,7 @@ const svg =
42
42
  color: var(--cosmoz-listbox-color, #101010);
43
43
  }
44
44
 
45
- .item[data-index="${index || '0'}"] {
45
+ .item[data-index='${index || '0'}'] {
46
46
  background: var(
47
47
  --cosmoz-listbox-active-color,
48
48
  var(--cosmoz-selection-color, rgba(58, 145, 226, 0.1))
@@ -87,6 +87,15 @@ const svg =
87
87
  :host([multi]) .sizer {
88
88
  padding-left: 33px;
89
89
  }
90
+ .swatch {
91
+ width: 18px;
92
+ height: 18px;
93
+ display: inline-block;
94
+ box-sizing: border-box;
95
+ vertical-align: middle;
96
+ border-radius: 50%;
97
+ border: 2px solid #eee;
98
+ }
90
99
  `,
91
100
  Listbox = (host) => {
92
101
  const { index, items, renderItem, height, itemHeight } = useListbox(host);
@@ -1,9 +1,10 @@
1
1
  import { html, nothing } from 'lit-html'; // eslint-disable-line object-curly-newline
2
2
  import { live } from 'lit-html/directives/live.js';
3
3
  import { until } from 'lit-html/directives/until.js';
4
+ import { when } from 'lit-html/directives/when.js';
4
5
  import { useCallback } from 'haunted';
5
- import { useHost } from '@neovici/cosmoz-utils/lib/hooks/use-host';
6
- import { array } from '@neovici/cosmoz-utils/lib/array';
6
+ import { useHost } from '@neovici/cosmoz-utils/hooks/use-host';
7
+ import { array } from '@neovici/cosmoz-utils/array';
7
8
  import '@neovici/cosmoz-input';
8
9
  import { useAutocomplete } from './use-autocomplete';
9
10
  import { listbox } from '../cosmoz-listbox';
@@ -43,33 +44,36 @@ const blank = () => nothing,
43
44
  ?data-one=${isOne}
44
45
  >
45
46
  <span class="chip-text" part="chip-text">${text}</span>
46
- ${(!disabled &&
47
- html` <span class="chip-clear" part="chip-clear" @click=${onClear}>
48
- ${clear}
49
- </span>`) ||
50
- nothing}
47
+ ${when(
48
+ !disabled,
49
+ () =>
50
+ html` <span class="chip-clear" part="chip-clear" @click=${onClear}>
51
+ ${clear}
52
+ </span>`
53
+ )}
51
54
  </div>
52
55
  `,
53
56
  renderBadge = ({ value, onDeselect }) => {
54
57
  const len = value?.length;
55
- return len > 0
56
- ? html`<div class="badge" slot="suffix" part="badge">
57
- ${len}
58
- <span
59
- class="badge-clear"
60
- part="chip-clear"
61
- @click=${() => onDeselect(value)}
62
- >${clear}</span
63
- >
64
- </div>`
65
- : nothing;
58
+ return when(
59
+ len > 0,
60
+ () => html`<div class="badge" slot="suffix" part="badge">
61
+ ${len}
62
+ <span
63
+ class="badge-clear"
64
+ part="chip-clear"
65
+ @click=${() => onDeselect(value)}
66
+ >${clear}</span
67
+ >
68
+ </div>`
69
+ );
66
70
  },
67
71
  renderSelection = (value, isOne, onDeselect, textual, disabled) => {
68
72
  if (isOne || value.length === 1) {
69
73
  const val = value[0];
70
- return val
71
- ? renderChip(textual(val), () => onDeselect(val), disabled, isOne)
72
- : nothing;
74
+ return when(val, () =>
75
+ renderChip(textual(val), () => onDeselect(val), disabled, isOne)
76
+ );
73
77
  }
74
78
  return renderBadge({ value, onDeselect });
75
79
  },
@@ -105,17 +109,15 @@ const blank = () => nothing,
105
109
  [host, value]
106
110
  ),
107
111
  suggestions = until(
108
- items$.then(
109
- (items) =>
110
- ((!isSingle || showSingle) &&
111
- items.length &&
112
- listbox({
113
- ...props,
114
- anchor,
115
- items,
116
- multi: !isOne,
117
- })) ||
118
- nothing
112
+ items$.then((items) =>
113
+ when((!isSingle || showSingle) && items.length, () =>
114
+ listbox({
115
+ ...props,
116
+ anchor,
117
+ items,
118
+ multi: !isOne,
119
+ })
120
+ )
119
121
  )
120
122
  );
121
123
 
@@ -1,27 +1,25 @@
1
1
  import { html } from 'haunted';
2
2
  import { mark, identity } from './utils';
3
- export default (
4
- item,
5
- i,
6
- {
7
- highlight,
8
- select,
9
- textual = identity,
10
- query,
11
- isSelected
12
- }
13
- ) => {
14
- const text = textual(item),
15
- content = mark(text, query);
3
+ export const itemRenderer =
4
+ (render = identity) =>
5
+ (item, i, { highlight, select, textual = identity, query, isSelected }) => {
6
+ const text = textual(item),
7
+ content = mark(text, query);
16
8
 
17
- return html`
18
- <div class="item"
19
- role="option" part="option" ?aria-selected=${ isSelected(item) }
20
- data-index=${ i }
21
- @mouseenter=${ () => highlight(i) }
22
- @click=${ () => select(item) }
23
- @mousedown=${ e => e.preventDefault() }
24
- title=${ text }
25
- >${ content }</div>
26
- <div class="sizer" virtualizer-sizer>${ content }</div>`;
27
- };
9
+ return html` <div
10
+ class="item"
11
+ role="option"
12
+ part="option"
13
+ ?aria-selected=${isSelected(item)}
14
+ data-index=${i}
15
+ @mouseenter=${() => highlight(i)}
16
+ @click=${() => select(item)}
17
+ @mousedown=${(e) => e.preventDefault()}
18
+ title=${text}
19
+ >
20
+ ${render(content, item, i)}
21
+ </div>
22
+ <div class="sizer" virtualizer-sizer>${content}</div>`;
23
+ };
24
+
25
+ export default itemRenderer();
@@ -4,8 +4,8 @@ import {
4
4
  import {
5
5
  without, search, strProp, prop, array
6
6
  } from './utils';
7
- import { useHost } from '@neovici/cosmoz-utils/lib/hooks/use-host';
8
- import { useMeta } from '@neovici/cosmoz-utils/lib/hooks/use-meta';
7
+ import { useHost } from '@neovici/cosmoz-utils/hooks/use-host';
8
+ import { useMeta } from '@neovici/cosmoz-utils/hooks/use-meta';
9
9
  import { useFocus } from '@neovici/cosmoz-dropdown/src/use-focus.js';
10
10
  import { useKeys } from './use-keys';
11
11
 
@@ -1,5 +1,5 @@
1
1
  import { useEffect } from 'haunted';
2
- import { useMeta } from '@neovici/cosmoz-utils/lib/hooks/use-meta';
2
+ import { useMeta } from '@neovici/cosmoz-utils/hooks/use-meta';
3
3
 
4
4
  export const useKeyboard = handlers => {
5
5
  const listeners = useMeta(handlers);
package/lib/use-keys.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { useEffect } from 'haunted';
2
2
  import { array } from './utils';
3
- import { useMeta } from '@neovici/cosmoz-utils/lib/hooks/use-meta';
3
+ import { useMeta } from '@neovici/cosmoz-utils/hooks/use-meta';
4
4
 
5
5
  const useKeys = ({
6
6
  active,
@@ -1,15 +1,11 @@
1
1
  import { useCallback, useEffect, useState, useMemo } from 'haunted';
2
- import { useMeta } from '@neovici/cosmoz-utils/lib/hooks/use-meta';
2
+ import { useMeta } from '@neovici/cosmoz-utils/hooks/use-meta';
3
3
  import { usePosition } from '@neovici/cosmoz-dropdown/src/use-position.js';
4
4
  import { useKeyboard } from './use-keyboard';
5
5
  import defaultItemRenderer from './item-renderer';
6
6
  import { byValue } from './utils';
7
7
 
8
- const useItems = ({
9
- items,
10
- onSelect,
11
- defaultIndex = 0
12
- }) => {
8
+ const useItems = ({ items, onSelect, defaultIndex = 0 }) => {
13
9
  const [index, setIndex] = useState(defaultIndex),
14
10
  { length } = items;
15
11
 
@@ -18,29 +14,34 @@ const useItems = ({
18
14
  }, [items, defaultIndex]);
19
15
 
20
16
  useKeyboard({
21
- onUp: useCallback(() => setIndex(index => index > 0 ? index - 1 : length - 1), [length]),
22
- onDown: useCallback(() => setIndex(index => index < length - 1 ? index + 1 : 0), [length]),
23
- onEnter: useCallback(() => index > -1 && index < length && onSelect?.(items[index], index), [
24
- index,
25
- items,
26
- onSelect
27
- ])
17
+ onUp: useCallback(
18
+ () => setIndex((index) => (index > 0 ? index - 1 : length - 1)),
19
+ [length]
20
+ ),
21
+ onDown: useCallback(
22
+ () => setIndex((index) => (index < length - 1 ? index + 1 : 0)),
23
+ [length]
24
+ ),
25
+ onEnter: useCallback(
26
+ () => index > -1 && index < length && onSelect?.(items[index], index),
27
+ [index, items, onSelect]
28
+ ),
28
29
  });
29
30
 
30
31
  return {
31
32
  index,
32
33
  highlight: setIndex,
33
- select: useCallback(item => onSelect?.(item), [onSelect])
34
+ select: useCallback((item) => onSelect?.(item), [onSelect]),
34
35
  };
35
36
  },
36
-
37
- useRenderItem = ({ itemRenderer = defaultItemRenderer, ...meta }) => {
37
+ useRenderItem = ({ itemRenderer, ...meta }) => {
38
38
  const info = useMeta(meta);
39
- return useCallback((item, i) => itemRenderer(item, i, info), [info, itemRenderer]);
39
+ return useCallback(
40
+ (item, i) => (itemRenderer || defaultItemRenderer)(item, i, info),
41
+ [info, itemRenderer]
42
+ );
40
43
  },
41
-
42
-
43
- useListbox = host => {
44
+ useListbox = (host) => {
44
45
  const {
45
46
  value,
46
47
  valueProperty,
@@ -54,18 +55,17 @@ const useItems = ({
54
55
  itemLimit = 5,
55
56
  anchor,
56
57
  confinement,
57
- placement
58
+ placement,
58
59
  } = host,
59
- isSelected = useMemo(() => byValue(value, valueProperty), [value, valueProperty]),
60
+ isSelected = useMemo(
61
+ () => byValue(value, valueProperty),
62
+ [value, valueProperty]
63
+ ),
60
64
  items = useMemo(() => _items.slice(), [_items, isSelected]),
61
- {
62
- index,
63
- highlight,
64
- select
65
- } = useItems({
65
+ { index, highlight, select } = useItems({
66
66
  items,
67
67
  onSelect,
68
- defaultIndex: isNaN(defaultIndex) ? undefined : Number(defaultIndex)
68
+ defaultIndex: isNaN(defaultIndex) ? undefined : Number(defaultIndex),
69
69
  });
70
70
 
71
71
  usePosition({
@@ -73,7 +73,7 @@ const useItems = ({
73
73
  host,
74
74
  confinement,
75
75
  placement,
76
- limit: true
76
+ limit: true,
77
77
  });
78
78
 
79
79
  return {
@@ -89,14 +89,24 @@ const useItems = ({
89
89
  select,
90
90
  textual,
91
91
  query,
92
- isSelected
93
- })
92
+ isSelected,
93
+ }),
94
94
  };
95
95
  },
96
- properties = ['query', 'items', 'onSelect', 'textual', 'anchor', 'confinement', 'placement', 'itemHeight', 'itemLimit', 'defaultIndex', 'value', 'styles'];
96
+ properties = [
97
+ 'query',
98
+ 'items',
99
+ 'onSelect',
100
+ 'textual',
101
+ 'anchor',
102
+ 'confinement',
103
+ 'placement',
104
+ 'itemHeight',
105
+ 'itemLimit',
106
+ 'itemRenderer',
107
+ 'defaultIndex',
108
+ 'value',
109
+ 'styles',
110
+ ];
97
111
 
98
- export {
99
- useListbox,
100
- useRenderItem,
101
- properties
102
- };
112
+ export { useListbox, useRenderItem, properties };
package/lib/utils.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { html } from 'lit-html';
2
2
 
3
- import { identity } from '@neovici/cosmoz-utils/lib/function';
4
- import { array, without } from '@neovici/cosmoz-utils/lib/array';
5
- import { prop, strProp } from '@neovici/cosmoz-utils/lib/object';
3
+ import { identity } from '@neovici/cosmoz-utils/function';
4
+ import { array, without } from '@neovici/cosmoz-utils/array';
5
+ import { prop, strProp } from '@neovici/cosmoz-utils/object';
6
6
 
7
7
  const mark = (text, query) => {
8
8
  if (!query || !text) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neovici/cosmoz-autocomplete",
3
- "version": "4.0.0",
3
+ "version": "5.1.0",
4
4
  "description": "A autocomplete input web component",
5
5
  "keywords": [
6
6
  "lit-html",
@@ -63,9 +63,9 @@
63
63
  },
64
64
  "dependencies": {
65
65
  "@lit-labs/virtualizer": "^0.7.0",
66
- "@neovici/cosmoz-dropdown": "^2.0.0",
67
- "@neovici/cosmoz-input": "^2.0.0",
68
- "@neovici/cosmoz-utils": "^4.0.0",
66
+ "@neovici/cosmoz-dropdown": "^3.0.0",
67
+ "@neovici/cosmoz-input": "^3.0.0",
68
+ "@neovici/cosmoz-utils": "^5.0.0",
69
69
  "haunted": "^5.0.0",
70
70
  "lit-html": "^2.0.0",
71
71
  "position.js": "^0.3.0"
@@ -81,7 +81,7 @@
81
81
  "@web/dev-server-storybook": "^0.5.1",
82
82
  "husky": "^8.0.0",
83
83
  "semantic-release": "^19.0.0",
84
- "sinon": "^14.0.0",
84
+ "sinon": "^15.0.0",
85
85
  "typescript": "^4.6.0"
86
86
  }
87
87
  }