svelte-multiselect 11.0.0 → 11.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/dist/CmdPalette.svelte +14 -27
- package/dist/CmdPalette.svelte.d.ts +0 -3
- package/dist/MultiSelect.svelte +99 -39
- package/dist/props.d.ts +5 -0
- package/package.json +2 -2
- package/readme.md +1 -1
package/dist/CmdPalette.svelte
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
<script lang="ts">import {
|
|
2
|
-
import { fade } from 'svelte/transition';
|
|
1
|
+
<script lang="ts">import { fade } from 'svelte/transition';
|
|
3
2
|
import Select from './MultiSelect.svelte';
|
|
4
|
-
let { actions, triggers = [`k`], close_keys = [`Escape`], fade_duration = 200, style = ``,
|
|
3
|
+
let { actions, triggers = [`k`], close_keys = [`Escape`], fade_duration = 200, style = ``, open = $bindable(false), dialog = $bindable(null), input = $bindable(null), placeholder = `Filter actions...`, ...rest } = $props();
|
|
4
|
+
$effect(() => {
|
|
5
|
+
if (open && input)
|
|
6
|
+
input?.focus(); // focus input when palette is opened
|
|
7
|
+
});
|
|
5
8
|
async function toggle(event) {
|
|
6
9
|
if (triggers.includes(event.key) && event.metaKey && !open) {
|
|
7
|
-
// open on cmd+trigger
|
|
8
10
|
open = true;
|
|
9
|
-
await tick(); // wait for dialog to open and input to be mounted
|
|
10
|
-
input?.focus();
|
|
11
11
|
}
|
|
12
12
|
else if (close_keys.includes(event.key) && open) {
|
|
13
13
|
open = false;
|
|
@@ -22,7 +22,6 @@ function trigger_action_and_close({ option }) {
|
|
|
22
22
|
option.action(option.label);
|
|
23
23
|
open = false;
|
|
24
24
|
}
|
|
25
|
-
const children_render = $derived(children);
|
|
26
25
|
</script>
|
|
27
26
|
|
|
28
27
|
<svelte:window onkeydown={toggle} onclick={close_if_outside} />
|
|
@@ -36,22 +35,18 @@ const children_render = $derived(children);
|
|
|
36
35
|
onadd={trigger_action_and_close}
|
|
37
36
|
onkeydown={toggle}
|
|
38
37
|
{...rest}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
{/if}
|
|
47
|
-
{/snippet}
|
|
48
|
-
</Select>
|
|
38
|
+
--sms-bg="var(--sms-options-bg)"
|
|
39
|
+
--sms-width="min(20em, 90vw)"
|
|
40
|
+
--sms-max-width="none"
|
|
41
|
+
--sms-placeholder-color="lightgray"
|
|
42
|
+
--sms-options-margin="1px 0"
|
|
43
|
+
--sms-options-border-radius="0 0 1ex 1ex"
|
|
44
|
+
/>
|
|
49
45
|
</dialog>
|
|
50
46
|
{/if}
|
|
51
47
|
|
|
52
48
|
<style>
|
|
53
|
-
|
|
54
|
-
:where(:global(dialog)) {
|
|
49
|
+
:where(dialog) {
|
|
55
50
|
position: fixed;
|
|
56
51
|
top: 30%;
|
|
57
52
|
border: none;
|
|
@@ -62,12 +57,4 @@ const children_render = $derived(children);
|
|
|
62
57
|
z-index: 10;
|
|
63
58
|
font-size: 2.4ex;
|
|
64
59
|
}
|
|
65
|
-
dialog :global(div.multiselect) {
|
|
66
|
-
--sms-bg: var(--sms-options-bg);
|
|
67
|
-
--sms-width: min(20em, 90vw);
|
|
68
|
-
--sms-max-width: none;
|
|
69
|
-
--sms-placeholder-color: lightgray;
|
|
70
|
-
--sms-options-margin: 1px 0;
|
|
71
|
-
--sms-options-border-radius: 0 0 1ex 1ex;
|
|
72
|
-
}
|
|
73
60
|
</style>
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type Snippet } from 'svelte';
|
|
2
1
|
import type { MultiSelectProps } from './props';
|
|
3
2
|
import type { ObjectOption } from './types';
|
|
4
3
|
interface Action extends ObjectOption {
|
|
@@ -11,12 +10,10 @@ interface Props extends Omit<MultiSelectProps<Action>, `options` | `onadd` | `on
|
|
|
11
10
|
close_keys?: string[];
|
|
12
11
|
fade_duration?: number;
|
|
13
12
|
style?: string;
|
|
14
|
-
span_style?: string;
|
|
15
13
|
open?: boolean;
|
|
16
14
|
dialog?: HTMLDialogElement | null;
|
|
17
15
|
input?: HTMLInputElement | null;
|
|
18
16
|
placeholder?: string;
|
|
19
|
-
children?: Snippet;
|
|
20
17
|
}
|
|
21
18
|
declare const CmdPalette: import("svelte").Component<Props, {}, "open" | "input" | "dialog">;
|
|
22
19
|
type CmdPalette = ReturnType<typeof CmdPalette>;
|
package/dist/MultiSelect.svelte
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
<script lang="ts">import {
|
|
1
|
+
<script lang="ts">import { browser } from '$app/environment';
|
|
2
|
+
import { tick } from 'svelte';
|
|
2
3
|
import { flip } from 'svelte/animate';
|
|
3
4
|
import CircleSpinner from './CircleSpinner.svelte';
|
|
4
5
|
import Wiggle from './Wiggle.svelte';
|
|
@@ -10,7 +11,7 @@ let { activeIndex = $bindable(null), activeOption = $bindable(null), createOptio
|
|
|
10
11
|
return `${get_label(opt)}`.toLowerCase().includes(searchText.toLowerCase());
|
|
11
12
|
}, closeDropdownOnSelect = `desktop`, form_input = $bindable(null), highlightMatches = true, id = null, input = $bindable(null), inputClass = ``, inputStyle = null, inputmode = null, invalid = $bindable(false), liActiveOptionClass = ``, liActiveUserMsgClass = ``, liOptionClass = ``, liOptionStyle = null, liSelectedClass = ``, liSelectedStyle = null, liUserMsgClass = ``, loading = false, matchingOptions = $bindable([]), maxOptions = undefined, maxSelect = null, maxSelectMsg = (current, max) => (max > 1 ? `${current}/${max}` : ``), maxSelectMsgClass = ``, name = null, noMatchingOptionsMsg = `No matching options`, open = $bindable(false), options = $bindable(), outerDiv = $bindable(null), outerDivClass = ``, parseLabelsAsHtml = false, pattern = null, placeholder = null, removeAllTitle = `Remove all`, removeBtnTitle = `Remove`, minSelect = null, required = false, resetFilterOnAdd = true, searchText = $bindable(``), selected = $bindable(options
|
|
12
13
|
?.filter((opt) => opt instanceof Object && opt?.preselected)
|
|
13
|
-
.slice(0, maxSelect ?? undefined) ?? []), sortSelected = false, selectedOptionsDraggable = !sortSelected, style = null, ulOptionsClass = ``, ulSelectedClass = ``, ulSelectedStyle = null, ulOptionsStyle = null, value = $bindable(null), expandIcon, selectedItem, children, removeIcon, afterInput, spinner, disabledIcon, option, userMsg, onblur, onclick, onfocus, onkeydown, onkeyup, onmousedown, onmouseenter, onmouseleave, ontouchcancel, ontouchend, ontouchmove, ontouchstart, onadd, oncreate, onremove, onremoveAll, onchange, onopen, onclose, ...rest } = $props();
|
|
14
|
+
.slice(0, maxSelect ?? undefined) ?? []), sortSelected = false, selectedOptionsDraggable = !sortSelected, style = null, ulOptionsClass = ``, ulSelectedClass = ``, ulSelectedStyle = null, ulOptionsStyle = null, value = $bindable(null), expandIcon, selectedItem, children, removeIcon, afterInput, spinner, disabledIcon, option, userMsg, onblur, onclick, onfocus, onkeydown, onkeyup, onmousedown, onmouseenter, onmouseleave, ontouchcancel, ontouchend, ontouchmove, ontouchstart, onadd, oncreate, onremove, onremoveAll, onchange, onopen, onclose, portal: portal_params = {}, ...rest } = $props();
|
|
14
15
|
$effect.pre(() => {
|
|
15
16
|
// if maxSelect=1, value is the single item in selected (or null if selected is empty)
|
|
16
17
|
// this solves both https://github.com/janosh/svelte-multiselect/issues/86 and
|
|
@@ -75,17 +76,17 @@ $effect(() => {
|
|
|
75
76
|
activeOption = matchingOptions[activeIndex ?? -1] ?? null;
|
|
76
77
|
});
|
|
77
78
|
// add an option to selected list
|
|
78
|
-
function add(
|
|
79
|
+
function add(option_to_add, event) {
|
|
79
80
|
event.stopPropagation();
|
|
80
|
-
if (maxSelect
|
|
81
|
+
if (maxSelect !== null && selected.length >= maxSelect)
|
|
81
82
|
wiggle = true;
|
|
82
|
-
if (!isNaN(Number(
|
|
83
|
-
|
|
83
|
+
if (!isNaN(Number(option_to_add)) && typeof selected.map(get_label)[0] === `number`) {
|
|
84
|
+
option_to_add = Number(option_to_add); // convert to number if possible
|
|
84
85
|
}
|
|
85
|
-
const is_duplicate = selected.map(key).includes(key(
|
|
86
|
+
const is_duplicate = selected.map(key).includes(key(option_to_add));
|
|
86
87
|
if ((maxSelect === null || maxSelect === 1 || selected.length < maxSelect) &&
|
|
87
88
|
(duplicates || !is_duplicate)) {
|
|
88
|
-
if (!options.includes(
|
|
89
|
+
if (!options.includes(option_to_add) && // first check if we find option in the options list
|
|
89
90
|
// this has the side-effect of not allowing to user to add the same
|
|
90
91
|
// custom option twice in append mode
|
|
91
92
|
[true, `append`].includes(allowUserOptions) &&
|
|
@@ -94,34 +95,34 @@ function add(option, event) {
|
|
|
94
95
|
// a new option from the user-entered text
|
|
95
96
|
if (typeof options[0] === `object`) {
|
|
96
97
|
// if 1st option is an object, we create new option as object to keep type homogeneity
|
|
97
|
-
|
|
98
|
+
option_to_add = { label: searchText };
|
|
98
99
|
}
|
|
99
100
|
else {
|
|
100
101
|
if ([`number`, `undefined`].includes(typeof options[0]) &&
|
|
101
102
|
!isNaN(Number(searchText))) {
|
|
102
103
|
// create new option as number if it parses to a number and 1st option is also number or missing
|
|
103
|
-
|
|
104
|
+
option_to_add = Number(searchText);
|
|
104
105
|
}
|
|
105
106
|
else {
|
|
106
|
-
|
|
107
|
+
option_to_add = searchText; // else create custom option as string
|
|
107
108
|
}
|
|
108
|
-
oncreate?.({ option });
|
|
109
|
+
oncreate?.({ option: option_to_add });
|
|
109
110
|
}
|
|
110
111
|
if (allowUserOptions === `append`)
|
|
111
|
-
options = [...options,
|
|
112
|
+
options = [...options, option_to_add];
|
|
112
113
|
}
|
|
113
114
|
if (resetFilterOnAdd)
|
|
114
115
|
searchText = ``; // reset search string on selection
|
|
115
|
-
if ([``, undefined, null].includes(
|
|
116
|
-
console.error(`MultiSelect: encountered falsy option ${
|
|
116
|
+
if ([``, undefined, null].includes(option_to_add)) {
|
|
117
|
+
console.error(`MultiSelect: encountered falsy option ${option_to_add}`);
|
|
117
118
|
return;
|
|
118
119
|
}
|
|
119
120
|
if (maxSelect === 1) {
|
|
120
121
|
// for maxSelect = 1 we always replace current option with new one
|
|
121
|
-
selected = [
|
|
122
|
+
selected = [option_to_add];
|
|
122
123
|
}
|
|
123
124
|
else {
|
|
124
|
-
selected = [...selected,
|
|
125
|
+
selected = [...selected, option_to_add];
|
|
125
126
|
if (sortSelected === true) {
|
|
126
127
|
selected = selected.sort((op1, op2) => {
|
|
127
128
|
const [label1, label2] = [get_label(op1), get_label(op2)];
|
|
@@ -142,34 +143,34 @@ function add(option, event) {
|
|
|
142
143
|
else if (!dropdown_should_close) {
|
|
143
144
|
input?.focus();
|
|
144
145
|
}
|
|
145
|
-
onadd?.({ option });
|
|
146
|
-
onchange?.({ option, type: `add` });
|
|
146
|
+
onadd?.({ option: option_to_add });
|
|
147
|
+
onchange?.({ option: option_to_add, type: `add` });
|
|
147
148
|
invalid = false; // reset error status whenever new items are selected
|
|
148
149
|
form_input?.setCustomValidity(``);
|
|
149
150
|
}
|
|
150
151
|
}
|
|
151
152
|
// remove an option from selected list
|
|
152
|
-
function remove(
|
|
153
|
+
function remove(option_to_drop, event) {
|
|
153
154
|
event.stopPropagation();
|
|
154
155
|
if (selected.length === 0)
|
|
155
156
|
return;
|
|
156
|
-
const idx = selected.findIndex((opt) => key(opt) === key(
|
|
157
|
-
let [
|
|
158
|
-
if (
|
|
157
|
+
const idx = selected.findIndex((opt) => key(opt) === key(option_to_drop));
|
|
158
|
+
let [option_removed] = selected.splice(idx, 1); // remove option from selected list
|
|
159
|
+
if (option_removed === undefined && allowUserOptions) {
|
|
159
160
|
// if option with label could not be found but allowUserOptions is truthy,
|
|
160
161
|
// assume it was created by user and create corresponding option object
|
|
161
162
|
// on the fly for use as event payload
|
|
162
163
|
const other_ops_type = typeof options[0];
|
|
163
|
-
|
|
164
|
+
option_removed = (other_ops_type ? { label: option_to_drop } : option_to_drop);
|
|
164
165
|
}
|
|
165
|
-
if (
|
|
166
|
-
return console.error(`Multiselect can't remove selected option ${JSON.stringify(
|
|
166
|
+
if (option_removed === undefined) {
|
|
167
|
+
return console.error(`Multiselect can't remove selected option ${JSON.stringify(option_to_drop)}, not found in selected list`);
|
|
167
168
|
}
|
|
168
169
|
selected = [...selected]; // trigger Svelte rerender
|
|
169
170
|
invalid = false; // reset error status whenever items are removed
|
|
170
171
|
form_input?.setCustomValidity(``);
|
|
171
|
-
onremove?.({ option });
|
|
172
|
-
onchange?.({ option, type: `remove` });
|
|
172
|
+
onremove?.({ option: option_removed });
|
|
173
|
+
onchange?.({ option: option_removed, type: `remove` });
|
|
173
174
|
}
|
|
174
175
|
function open_dropdown(event) {
|
|
175
176
|
event.stopPropagation();
|
|
@@ -287,7 +288,6 @@ function on_click_outside(event) {
|
|
|
287
288
|
let drag_idx = $state(null);
|
|
288
289
|
// event handlers enable dragging to reorder selected options
|
|
289
290
|
const drop = (target_idx) => (event) => {
|
|
290
|
-
event.preventDefault();
|
|
291
291
|
if (!event.dataTransfer)
|
|
292
292
|
return;
|
|
293
293
|
event.dataTransfer.dropEffect = `move`;
|
|
@@ -339,6 +339,51 @@ $effect.pre(() => {
|
|
|
339
339
|
required = required; // trigger effect when required changes
|
|
340
340
|
form_input?.setCustomValidity(``);
|
|
341
341
|
});
|
|
342
|
+
function portal(node, params) {
|
|
343
|
+
let { target_node, active } = params;
|
|
344
|
+
if (!active)
|
|
345
|
+
return;
|
|
346
|
+
let render_in_place = !browser || !document.body.contains(node);
|
|
347
|
+
if (!render_in_place) {
|
|
348
|
+
document.body.appendChild(node);
|
|
349
|
+
node.style.position = `fixed`;
|
|
350
|
+
const update_position = () => {
|
|
351
|
+
if (!target_node || !open)
|
|
352
|
+
return (node.hidden = true);
|
|
353
|
+
const rect = target_node.getBoundingClientRect();
|
|
354
|
+
node.style.left = `${rect.left}px`;
|
|
355
|
+
node.style.top = `${rect.bottom}px`;
|
|
356
|
+
node.style.width = `${rect.width}px`;
|
|
357
|
+
node.hidden = false;
|
|
358
|
+
};
|
|
359
|
+
if (open)
|
|
360
|
+
tick().then(update_position);
|
|
361
|
+
window.addEventListener(`scroll`, update_position, true);
|
|
362
|
+
window.addEventListener(`resize`, update_position);
|
|
363
|
+
$effect.pre(() => {
|
|
364
|
+
if (open && target_node)
|
|
365
|
+
update_position();
|
|
366
|
+
else
|
|
367
|
+
node.hidden = true;
|
|
368
|
+
});
|
|
369
|
+
return {
|
|
370
|
+
update(params) {
|
|
371
|
+
target_node = params.target_node;
|
|
372
|
+
render_in_place = !browser || !document.body.contains(node);
|
|
373
|
+
if (open && !render_in_place && target_node)
|
|
374
|
+
tick().then(update_position);
|
|
375
|
+
else if (!open || !target_node)
|
|
376
|
+
node.hidden = true;
|
|
377
|
+
},
|
|
378
|
+
destroy() {
|
|
379
|
+
if (!render_in_place)
|
|
380
|
+
node.remove();
|
|
381
|
+
window.removeEventListener(`scroll`, update_position, true);
|
|
382
|
+
window.removeEventListener(`resize`, update_position);
|
|
383
|
+
},
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
}
|
|
342
387
|
</script>
|
|
343
388
|
|
|
344
389
|
<svelte:window
|
|
@@ -353,7 +398,7 @@ $effect.pre(() => {
|
|
|
353
398
|
class:single={maxSelect === 1}
|
|
354
399
|
class:open
|
|
355
400
|
class:invalid
|
|
356
|
-
class="multiselect {outerDivClass}"
|
|
401
|
+
class="multiselect {outerDivClass} {rest.class ?? ``}"
|
|
357
402
|
onmouseup={open_dropdown}
|
|
358
403
|
title={disabled ? disabledInputTitle : null}
|
|
359
404
|
data-id={id}
|
|
@@ -406,6 +451,9 @@ $effect.pre(() => {
|
|
|
406
451
|
animate:flip={{ duration: 100 }}
|
|
407
452
|
draggable={selectedOptionsDraggable && !disabled && selected.length > 1}
|
|
408
453
|
ondragstart={dragstart(idx)}
|
|
454
|
+
ondragover={(event) => {
|
|
455
|
+
event.preventDefault() // needed for ondrop to fire
|
|
456
|
+
}}
|
|
409
457
|
ondrop={drop(idx)}
|
|
410
458
|
ondragenter={() => (drag_idx = idx)}
|
|
411
459
|
class:active={drag_idx === idx}
|
|
@@ -524,6 +572,7 @@ $effect.pre(() => {
|
|
|
524
572
|
<!-- only render options dropdown if options or searchText is not empty (needed to avoid briefly flashing empty dropdown) -->
|
|
525
573
|
{#if (searchText && noMatchingOptionsMsg) || options?.length > 0}
|
|
526
574
|
<ul
|
|
575
|
+
use:portal={{ target_node: outerDiv, ...portal_params }}
|
|
527
576
|
class:hidden={!open}
|
|
528
577
|
class="options {ulOptionsClass}"
|
|
529
578
|
role="listbox"
|
|
@@ -760,14 +809,19 @@ $effect.pre(() => {
|
|
|
760
809
|
pointer-events: none;
|
|
761
810
|
}
|
|
762
811
|
|
|
763
|
-
|
|
812
|
+
ul.options {
|
|
764
813
|
list-style: none;
|
|
814
|
+
/* top, left, width, position are managed by portal when active */
|
|
815
|
+
/* but provide defaults for non-portaled or initial state */
|
|
816
|
+
position: absolute; /* Default, overridden by portal to fixed when open */
|
|
765
817
|
top: 100%;
|
|
766
818
|
left: 0;
|
|
767
819
|
width: 100%;
|
|
768
|
-
|
|
820
|
+
/* Default z-index if not portaled/overridden by portal */
|
|
821
|
+
z-index: var(--sms-options-z-index, 3);
|
|
822
|
+
|
|
769
823
|
overflow: auto;
|
|
770
|
-
transition: all 0.2s;
|
|
824
|
+
transition: all 0.2s; /* Consider if this transition is desirable with portal positioning */
|
|
771
825
|
box-sizing: border-box;
|
|
772
826
|
background: var(--sms-options-bg, white);
|
|
773
827
|
max-height: var(--sms-options-max-height, 50vh);
|
|
@@ -779,29 +833,35 @@ $effect.pre(() => {
|
|
|
779
833
|
padding: var(--sms-options-padding);
|
|
780
834
|
margin: var(--sms-options-margin, inherit);
|
|
781
835
|
}
|
|
782
|
-
:is(div.multiselect
|
|
836
|
+
:is(div.multiselect.open) {
|
|
837
|
+
/* increase z-index when open to ensure the dropdown of one <MultiSelect />
|
|
838
|
+
displays above that of another slightly below it on the page */
|
|
839
|
+
/* This z-index is for the div.multiselect itself, portal has its own higher z-index */
|
|
840
|
+
z-index: var(--sms-open-z-index, 4);
|
|
841
|
+
}
|
|
842
|
+
ul.options.hidden {
|
|
783
843
|
visibility: hidden;
|
|
784
844
|
opacity: 0;
|
|
785
845
|
transform: translateY(50px);
|
|
786
846
|
}
|
|
787
|
-
|
|
847
|
+
ul.options > li {
|
|
788
848
|
padding: 3pt 2ex;
|
|
789
849
|
cursor: pointer;
|
|
790
850
|
scroll-margin: var(--sms-options-scroll-margin, 100px);
|
|
791
851
|
}
|
|
792
|
-
|
|
852
|
+
ul.options .user-msg {
|
|
793
853
|
/* block needed so vertical padding applies to span */
|
|
794
854
|
display: block;
|
|
795
855
|
padding: 3pt 2ex;
|
|
796
856
|
}
|
|
797
|
-
|
|
857
|
+
ul.options > li.selected {
|
|
798
858
|
background: var(--sms-li-selected-bg);
|
|
799
859
|
color: var(--sms-li-selected-color);
|
|
800
860
|
}
|
|
801
|
-
|
|
861
|
+
ul.options > li.active {
|
|
802
862
|
background: var(--sms-li-active-bg, var(--sms-active-color, rgba(0, 0, 0, 0.15)));
|
|
803
863
|
}
|
|
804
|
-
|
|
864
|
+
ul.options > li.disabled {
|
|
805
865
|
cursor: not-allowed;
|
|
806
866
|
background: var(--sms-li-disabled-bg, #f5f5f6);
|
|
807
867
|
color: var(--sms-li-disabled-text, #b8b8b8);
|
package/dist/props.d.ts
CHANGED
|
@@ -70,6 +70,10 @@ export interface MultiSelectSnippets<T extends Option = Option> {
|
|
|
70
70
|
}
|
|
71
71
|
]>;
|
|
72
72
|
}
|
|
73
|
+
export interface PortalParams {
|
|
74
|
+
target_node?: HTMLElement | null;
|
|
75
|
+
active?: boolean;
|
|
76
|
+
}
|
|
73
77
|
export interface MultiSelectParameters<T extends Option = Option> {
|
|
74
78
|
activeIndex?: number | null;
|
|
75
79
|
activeOption?: T | null;
|
|
@@ -132,6 +136,7 @@ export interface MultiSelectParameters<T extends Option = Option> {
|
|
|
132
136
|
ulSelectedStyle?: string | null;
|
|
133
137
|
ulOptionsStyle?: string | null;
|
|
134
138
|
value?: T | T[] | null;
|
|
139
|
+
portal?: PortalParams;
|
|
135
140
|
[key: string]: unknown;
|
|
136
141
|
}
|
|
137
142
|
export interface MultiSelectProps<T extends Option = Option> extends MultiSelectNativeEvents, MultiSelectComponentEvents<T>, MultiSelectSnippets<T>, MultiSelectParameters<T> {
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"homepage": "https://janosh.github.io/svelte-multiselect",
|
|
6
6
|
"repository": "https://github.com/janosh/svelte-multiselect",
|
|
7
7
|
"license": "MIT",
|
|
8
|
-
"version": "11.
|
|
8
|
+
"version": "11.1.0",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"svelte": "./dist/index.js",
|
|
11
11
|
"bugs": "https://github.com/janosh/svelte-multiselect/issues",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"package": "svelte-package",
|
|
17
17
|
"serve": "vite build && vite preview",
|
|
18
18
|
"check": "svelte-check src",
|
|
19
|
-
"test": "vitest
|
|
19
|
+
"test": "vitest run && playwright test",
|
|
20
20
|
"test:unit": "vitest tests/unit/*.ts",
|
|
21
21
|
"test:e2e": "playwright test tests/*.test.ts",
|
|
22
22
|
"changelog": "npx auto-changelog --package --output changelog.md --hide-empty-releases --hide-credit --commit-limit false",
|
package/readme.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
[](https://github.com/janosh/svelte-multiselect/actions/workflows/test.yml)
|
|
9
9
|
[](https://github.com/janosh/svelte-multiselect/actions/workflows/gh-pages.yml)
|
|
10
10
|
[](https://npmjs.com/package/svelte-multiselect)
|
|
11
|
-
[](https://github.com/sveltejs/svelte/blob/master/packages/svelte/CHANGELOG.md)
|
|
11
|
+
[](https://github.com/sveltejs/svelte/blob/master/packages/svelte/CHANGELOG.md)
|
|
12
12
|
[](https://svelte.dev/repl/a5a14b8f15d64cb083b567292480db05)
|
|
13
13
|
[](https://stackblitz.com/github/janosh/svelte-multiselect)
|
|
14
14
|
|