Skip to content

Commit 3f7c9b7

Browse files
committed
modular, filter, logo
1 parent 11f47a0 commit 3f7c9b7

File tree

7 files changed

+92
-49
lines changed

7 files changed

+92
-49
lines changed

.prettierrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"useTabs": false,
33
"singleQuote": true,
44
"tabWidth": 4,
5-
"printWidth": 200,
5+
"printWidth": 120,
66
"bracketSameLine": true,
77
"overrides": [
88
{

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## unreleased
44

5+
* filterMethod changed to filter and added via config
56
* added support for svelte-tiny-virtual-list
67
* removed virtual-list class and css props
78
* moved VirtualList to config

README.md

+4-9
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
<div align="center">
2-
<img src="https://i.imgur.com/2Us5A4j.png" alt="Svelte Select" width="150" />
2+
<img src="https://raw.githubusercontent.com/rob-balfre/svelte-select/feature/v5/svelte-select.png" alt="Svelte Select" width="150" />
3+
<h1>Svelte Select</h1>
34
</div>
45

5-
<br />
6-
76
<div align="center">
87
<a href="https://npmjs.org/package/svelte-select">
98
<img src="https://badgen.now.sh/npm/v/svelte-select" alt="version" />
@@ -12,12 +11,8 @@
1211
<img src="https://badgen.now.sh/npm/dm/svelte-select" alt="downloads" />
1312
</a>
1413
</div>
15-
16-
<br />
17-
18-
# svelte-select
19-
20-
A select/autocomplete component for Svelte apps. With support for grouping, filtering, async and more.
14+
<div align="center">A select/autocomplete/typeahead Svelte component. <br />
15+
Lightweight, feature-rich and modular by design.</div>
2116

2217
## Demos
2318

src/lib/Select.svelte

+38-38
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
44
export let config = {};
55
6-
const { Item, List, Selection, Multi, VirtualList, debounce } = config;
6+
const { Item, List, Selection, Multi, VirtualList, debounce, filter } = config;
77
88
const dispatch = createEventDispatcher();
99
@@ -83,37 +83,6 @@
8383
export let listClass = 'list';
8484
export let itemClass = 'item';
8585
86-
function filterMethod(args) {
87-
if (args.loadOptions && args.filterText.length > 0) return;
88-
if (!args.items) return [];
89-
90-
if (args.items && args.items.length > 0 && typeof args.items[0] !== 'object') {
91-
args.items = convertStringItemsToObjects(args.items);
92-
}
93-
94-
let filterResults = args.items.filter((item) => {
95-
let matchesFilter = itemFilter(getOptionLabel(item, args.filterText), args.filterText, item);
96-
97-
if (matchesFilter && args.isMulti && args.value && Array.isArray(args.value)) {
98-
matchesFilter = !args.value.some((x) => {
99-
return x[args.optionIdentifier] === item[args.optionIdentifier];
100-
});
101-
}
102-
103-
return matchesFilter;
104-
});
105-
106-
if (args.groupBy) {
107-
filterResults = filterGroupedItems(filterResults);
108-
}
109-
110-
if (args.isCreatable) {
111-
filterResults = addCreatableItem(filterResults, args.filterText);
112-
}
113-
114-
return filterResults;
115-
}
116-
11786
function addCreatableItem(_items, _filterText) {
11887
if (_filterText.length === 0) return _items;
11988
const itemToCreate = createItem(_filterText);
@@ -122,15 +91,20 @@
12291
return [..._items, itemToCreate];
12392
}
12493
125-
$: filteredItems = filterMethod({
94+
$: filteredItems = filter({
12695
loadOptions,
12796
filterText,
12897
items,
129-
value,
13098
isMulti,
99+
value,
131100
optionIdentifier,
132101
groupBy,
133102
isCreatable,
103+
itemFilter,
104+
convertStringItemsToObjects,
105+
filterGroupedItems,
106+
addCreatableItem,
107+
getOptionLabel
134108
});
135109
136110
let containerClasses = 'select-container';
@@ -392,7 +366,11 @@
392366
393367
function updateValueDisplay(items) {
394368
if (!items || items.length === 0 || items.some((item) => typeof item !== 'object')) return;
395-
if (!value || (isMulti ? value.some((selection) => !selection || !selection[optionIdentifier]) : !value[optionIdentifier])) return;
369+
if (
370+
!value ||
371+
(isMulti ? value.some((selection) => !selection || !selection[optionIdentifier]) : !value[optionIdentifier])
372+
)
373+
return;
396374
397375
if (Array.isArray(value)) {
398376
value = value.map((selection) => findItem(selection) || selection);
@@ -602,7 +580,15 @@
602580
$: ariaContext = handleAriaContent(filteredItems, hoverItemIndex, isFocused, listOpen);
603581
</script>
604582

605-
<div class={containerClasses} class:error={hasError} class:multi={isMulti} class:disabled={isDisabled} class:focused={isFocused} style={containerStyles} on:click={handleClick} bind:this={container}>
583+
<div
584+
class={containerClasses}
585+
class:error={hasError}
586+
class:multi={isMulti}
587+
class:disabled={isDisabled}
588+
class:focused={isFocused}
589+
style={containerStyles}
590+
on:click={handleClick}
591+
bind:this={container}>
606592
<span aria-live="polite" aria-atomic="false" aria-relevant="additions text" class="a11yText">
607593
{#if isFocused}
608594
<span id="aria-selection">{ariaSelection}</span>
@@ -617,7 +603,15 @@
617603
{/if}
618604

619605
{#if showMultiSelect}
620-
<svelte:component this={Multi} {value} {getSelectionLabel} {activeValue} {isDisabled} {multiFullItemClearable} on:multiItemClear={handleMultiItemClear} on:focus={handleFocus} />
606+
<svelte:component
607+
this={Multi}
608+
{value}
609+
{getSelectionLabel}
610+
{activeValue}
611+
{isDisabled}
612+
{multiFullItemClearable}
613+
on:multiItemClear={handleMultiItemClear}
614+
on:focus={handleFocus} />
621615
{/if}
622616

623617
<input
@@ -657,7 +651,13 @@
657651
</div>
658652

659653
{#if listOpen}
660-
<svelte:component this={List} {...listProps} bind:hoverItemIndex on:itemSelected={itemSelected} on:itemCreated={itemCreated} on:closeList={closeList} />
654+
<svelte:component
655+
this={List}
656+
{...listProps}
657+
bind:hoverItemIndex
658+
on:itemSelected={itemSelected}
659+
on:itemCreated={itemCreated}
660+
on:closeList={closeList} />
661661
{/if}
662662

663663
{#if !isMulti || (isMulti && !showMultiSelect)}

src/lib/filter.js

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
export default function filter({
2+
loadOptions,
3+
filterText,
4+
items,
5+
isMulti,
6+
value,
7+
optionIdentifier,
8+
groupBy,
9+
isCreatable,
10+
itemFilter,
11+
convertStringItemsToObjects,
12+
filterGroupedItems,
13+
addCreatableItem,
14+
getOptionLabel
15+
}) {
16+
if (loadOptions && filterText.length > 0) return;
17+
if (!items) return [];
18+
19+
if (items && items.length > 0 && typeof items[0] !== 'object') {
20+
items = convertStringItemsToObjects(items);
21+
}
22+
23+
24+
let filterResults = items.filter((item) => {
25+
let matchesFilter = itemFilter(getOptionLabel(item, filterText), filterText, item);
26+
27+
if (matchesFilter && isMulti && value && Array.isArray(value)) {
28+
matchesFilter = !value.some((x) => {
29+
return x[optionIdentifier] === item[optionIdentifier];
30+
});
31+
}
32+
33+
return matchesFilter;
34+
});
35+
36+
if (groupBy) {
37+
filterResults = filterGroupedItems(filterResults);
38+
}
39+
40+
if (isCreatable) {
41+
filterResults = addCreatableItem(filterResults, filterText);
42+
}
43+
44+
return filterResults;
45+
}

src/lib/presets/vanilla.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ import List from '../List.svelte';
33
import Item from '../Item.svelte';
44
import Selection from '../Selection.svelte';
55
import debounce from '../debounce';
6+
import filter from '../filter';
67

78
export default {
89
theme: defaultStyles,
910
List,
1011
Item,
1112
Selection,
12-
debounce
13+
debounce,
14+
filter
1315
}

svelte-select.png

-17.9 KB
Loading

0 commit comments

Comments
 (0)