svelte-multiselect 10.0.0 → 10.2.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/CircleSpinner.svelte.d.ts +2 -2
- package/dist/CmdPalette.svelte.d.ts +2 -2
- package/dist/MultiSelect.svelte +47 -38
- package/dist/MultiSelect.svelte.d.ts +4 -8
- package/dist/Wiggle.svelte.d.ts +2 -2
- package/dist/icons/ChevronExpand.svelte.d.ts +2 -2
- package/dist/icons/Cross.svelte.d.ts +2 -2
- package/dist/icons/Disabled.svelte.d.ts +2 -2
- package/dist/icons/Octocat.svelte.d.ts +2 -2
- package/dist/types.d.ts +5 -0
- package/dist/utils.d.ts +6 -0
- package/dist/utils.js +30 -0
- package/package.json +25 -25
- package/readme.md +8 -10
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
2
|
declare const __propDef: {
|
|
3
3
|
props: {
|
|
4
4
|
color?: string | undefined;
|
|
@@ -13,6 +13,6 @@ declare const __propDef: {
|
|
|
13
13
|
export type CircleSpinnerProps = typeof __propDef.props;
|
|
14
14
|
export type CircleSpinnerEvents = typeof __propDef.events;
|
|
15
15
|
export type CircleSpinnerSlots = typeof __propDef.slots;
|
|
16
|
-
export default class CircleSpinner extends
|
|
16
|
+
export default class CircleSpinner extends SvelteComponent<CircleSpinnerProps, CircleSpinnerEvents, CircleSpinnerSlots> {
|
|
17
17
|
}
|
|
18
18
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
2
|
declare const __propDef: {
|
|
3
3
|
props: {
|
|
4
4
|
[x: string]: any;
|
|
@@ -26,6 +26,6 @@ declare const __propDef: {
|
|
|
26
26
|
export type CmdPaletteProps = typeof __propDef.props;
|
|
27
27
|
export type CmdPaletteEvents = typeof __propDef.events;
|
|
28
28
|
export type CmdPaletteSlots = typeof __propDef.slots;
|
|
29
|
-
export default class CmdPalette extends
|
|
29
|
+
export default class CmdPalette extends SvelteComponent<CmdPaletteProps, CmdPaletteEvents, CmdPaletteSlots> {
|
|
30
30
|
}
|
|
31
31
|
export {};
|
package/dist/MultiSelect.svelte
CHANGED
|
@@ -3,6 +3,7 @@ import { flip } from 'svelte/animate';
|
|
|
3
3
|
import CircleSpinner from './CircleSpinner.svelte';
|
|
4
4
|
import Wiggle from './Wiggle.svelte';
|
|
5
5
|
import { CrossIcon, DisabledIcon, ExpandIcon } from './icons';
|
|
6
|
+
import { get_label, get_style } from './utils';
|
|
6
7
|
export let activeIndex = null;
|
|
7
8
|
export let activeOption = null;
|
|
8
9
|
export let createOptionMsg = `Create this option...`;
|
|
@@ -25,7 +26,7 @@ export let filterFunc = (opt, searchText) => {
|
|
|
25
26
|
return true;
|
|
26
27
|
return `${get_label(opt)}`.toLowerCase().includes(searchText.toLowerCase());
|
|
27
28
|
};
|
|
28
|
-
export let
|
|
29
|
+
export let closeDropdownOnSelect = `desktop`;
|
|
29
30
|
export let form_input = null;
|
|
30
31
|
export let highlightMatches = true;
|
|
31
32
|
export let id = null;
|
|
@@ -59,26 +60,26 @@ export let resetFilterOnAdd = true;
|
|
|
59
60
|
export let searchText = ``;
|
|
60
61
|
export let selected = options
|
|
61
62
|
?.filter((opt) => opt instanceof Object && opt?.preselected)
|
|
62
|
-
.slice(0, maxSelect ?? undefined) ?? [];
|
|
63
|
+
.slice(0, maxSelect ?? undefined) ?? []; // don't allow more than maxSelect preselected options
|
|
63
64
|
export let sortSelected = false;
|
|
64
65
|
export let selectedOptionsDraggable = !sortSelected;
|
|
65
66
|
export let ulOptionsClass = ``;
|
|
66
67
|
export let ulSelectedClass = ``;
|
|
67
68
|
export let value = null;
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
return `${opt}`;
|
|
69
|
+
const selected_to_value = (selected) => {
|
|
70
|
+
value = maxSelect === 1 ? selected[0] ?? null : selected;
|
|
71
|
+
};
|
|
72
|
+
const value_to_selected = (value) => {
|
|
73
|
+
if (maxSelect === 1)
|
|
74
|
+
selected = value ? [value] : [];
|
|
75
|
+
else
|
|
76
|
+
selected = value ?? [];
|
|
77
77
|
};
|
|
78
78
|
// if maxSelect=1, value is the single item in selected (or null if selected is empty)
|
|
79
79
|
// this solves both https://github.com/janosh/svelte-multiselect/issues/86 and
|
|
80
80
|
// https://github.com/janosh/svelte-multiselect/issues/136
|
|
81
|
-
$:
|
|
81
|
+
$: selected_to_value(selected);
|
|
82
|
+
$: value_to_selected(value);
|
|
82
83
|
let wiggle = false; // controls wiggle animation when user tries to exceed maxSelect
|
|
83
84
|
if (!(options?.length > 0)) {
|
|
84
85
|
if (allowUserOptions || loading || disabled || allowEmpty) {
|
|
@@ -185,10 +186,13 @@ function add(option, event) {
|
|
|
185
186
|
selected = selected.sort(sortSelected);
|
|
186
187
|
}
|
|
187
188
|
}
|
|
188
|
-
|
|
189
|
+
const reached_max_select = selected.length === maxSelect;
|
|
190
|
+
const dropdown_should_close = closeDropdownOnSelect === true ||
|
|
191
|
+
(closeDropdownOnSelect === `desktop` && window_width < breakpoint);
|
|
192
|
+
if (reached_max_select || dropdown_should_close) {
|
|
189
193
|
close_dropdown(event);
|
|
190
|
-
|
|
191
|
-
|
|
194
|
+
}
|
|
195
|
+
else if (!dropdown_should_close) {
|
|
192
196
|
input?.focus();
|
|
193
197
|
}
|
|
194
198
|
dispatch(`add`, { option });
|
|
@@ -301,10 +305,10 @@ async function handle_keydown(event) {
|
|
|
301
305
|
}
|
|
302
306
|
}
|
|
303
307
|
function remove_all() {
|
|
304
|
-
selected = [];
|
|
305
|
-
searchText = ``;
|
|
306
308
|
dispatch(`removeAll`, { options: selected });
|
|
307
309
|
dispatch(`change`, { options: selected, type: `removeAll` });
|
|
310
|
+
selected = [];
|
|
311
|
+
searchText = ``;
|
|
308
312
|
}
|
|
309
313
|
$: is_selected = (label) => selected.map(get_label).includes(label);
|
|
310
314
|
const if_enter_or_space = (handler) => (event) => {
|
|
@@ -455,6 +459,7 @@ function highlight_matching_options(event) {
|
|
|
455
459
|
on:dragenter={() => (drag_idx = idx)}
|
|
456
460
|
on:dragover|preventDefault
|
|
457
461
|
class:active={drag_idx === idx}
|
|
462
|
+
style={get_style(option, `selected`)}
|
|
458
463
|
>
|
|
459
464
|
<!-- on:dragover|preventDefault needed for the drop to succeed https://stackoverflow.com/a/31085796 -->
|
|
460
465
|
<slot name="selected" {option} {idx}>
|
|
@@ -597,6 +602,7 @@ function highlight_matching_options(event) {
|
|
|
597
602
|
on:blur={() => (activeIndex = null)}
|
|
598
603
|
role="option"
|
|
599
604
|
aria-selected="false"
|
|
605
|
+
style={get_style(option, `option`)}
|
|
600
606
|
>
|
|
601
607
|
<slot name="option" {option} {idx}>
|
|
602
608
|
<slot {option} {idx}>
|
|
@@ -608,16 +614,25 @@ function highlight_matching_options(event) {
|
|
|
608
614
|
</slot>
|
|
609
615
|
</slot>
|
|
610
616
|
</li>
|
|
611
|
-
{
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
{@const
|
|
616
|
-
|
|
617
|
-
|
|
617
|
+
{/each}
|
|
618
|
+
{#if searchText}
|
|
619
|
+
{@const text_input_is_duplicate = selected.map(get_label).includes(searchText)}
|
|
620
|
+
{@const is_dupe = !duplicates && text_input_is_duplicate && `dupe`}
|
|
621
|
+
{@const can_create = Boolean(allowUserOptions && createOptionMsg) && `create`}
|
|
622
|
+
{@const no_match =
|
|
623
|
+
Boolean(matchingOptions?.length == 0 && noMatchingOptionsMsg) && `no-match`}
|
|
624
|
+
{@const msgType = is_dupe || can_create || no_match}
|
|
625
|
+
{#if msgType}
|
|
626
|
+
{@const msg = {
|
|
627
|
+
dupe: duplicateOptionMsg,
|
|
628
|
+
create: createOptionMsg,
|
|
629
|
+
'no-match': noMatchingOptionsMsg,
|
|
630
|
+
}[msgType]}
|
|
618
631
|
<li
|
|
619
632
|
on:mousedown|stopPropagation
|
|
620
|
-
on:mouseup|stopPropagation={(event) =>
|
|
633
|
+
on:mouseup|stopPropagation={(event) => {
|
|
634
|
+
if (allowUserOptions) add(searchText, event)
|
|
635
|
+
}}
|
|
621
636
|
title={createOptionMsg}
|
|
622
637
|
class:active={option_msg_is_active}
|
|
623
638
|
on:mouseover={() => (option_msg_is_active = true)}
|
|
@@ -627,24 +642,18 @@ function highlight_matching_options(event) {
|
|
|
627
642
|
role="option"
|
|
628
643
|
aria-selected="false"
|
|
629
644
|
class="user-msg"
|
|
645
|
+
style:cursor={{
|
|
646
|
+
dupe: `not-allowed`,
|
|
647
|
+
create: `pointer`,
|
|
648
|
+
'no-match': `default`,
|
|
649
|
+
}[msgType]}
|
|
630
650
|
>
|
|
631
|
-
<slot
|
|
632
|
-
name="user-msg"
|
|
633
|
-
{duplicateOptionMsg}
|
|
634
|
-
{createOptionMsg}
|
|
635
|
-
{textInputIsDuplicate}
|
|
636
|
-
{searchText}
|
|
637
|
-
{msg}
|
|
638
|
-
>
|
|
651
|
+
<slot name="user-msg" {searchText} {msgType} {msg}>
|
|
639
652
|
{msg}
|
|
640
653
|
</slot>
|
|
641
654
|
</li>
|
|
642
|
-
{:else if noMatchingOptionsMsg}
|
|
643
|
-
<!-- use span to not have cursor: pointer -->
|
|
644
|
-
<span class="user-msg">{noMatchingOptionsMsg}</span>
|
|
645
655
|
{/if}
|
|
646
|
-
|
|
647
|
-
{/each}
|
|
656
|
+
{/if}
|
|
648
657
|
</ul>
|
|
649
658
|
{/if}
|
|
650
659
|
</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
2
|
import type { MultiSelectEvents, Option as T } from './types';
|
|
3
3
|
declare class __sveltets_Render<Option extends T> {
|
|
4
4
|
props(): {
|
|
@@ -17,7 +17,7 @@ declare class __sveltets_Render<Option extends T> {
|
|
|
17
17
|
duplicates?: boolean | undefined;
|
|
18
18
|
key?: ((opt: T) => unknown) | undefined;
|
|
19
19
|
filterFunc?: ((opt: Option, searchText: string) => boolean) | undefined;
|
|
20
|
-
|
|
20
|
+
closeDropdownOnSelect?: boolean | "desktop" | undefined;
|
|
21
21
|
form_input?: HTMLInputElement | null | undefined;
|
|
22
22
|
highlightMatches?: boolean | undefined;
|
|
23
23
|
id?: string | null | undefined;
|
|
@@ -55,7 +55,6 @@ declare class __sveltets_Render<Option extends T> {
|
|
|
55
55
|
ulOptionsClass?: string | undefined;
|
|
56
56
|
ulSelectedClass?: string | undefined;
|
|
57
57
|
value?: Option | Option[] | null | undefined;
|
|
58
|
-
get_label?: ((opt: T) => string | number) | undefined;
|
|
59
58
|
};
|
|
60
59
|
events(): MultiSelectEvents;
|
|
61
60
|
slots(): {
|
|
@@ -87,10 +86,8 @@ declare class __sveltets_Render<Option extends T> {
|
|
|
87
86
|
idx: any;
|
|
88
87
|
};
|
|
89
88
|
'user-msg': {
|
|
90
|
-
duplicateOptionMsg: string;
|
|
91
|
-
createOptionMsg: string | null;
|
|
92
|
-
textInputIsDuplicate: any;
|
|
93
89
|
searchText: string;
|
|
90
|
+
msgType: any;
|
|
94
91
|
msg: any;
|
|
95
92
|
};
|
|
96
93
|
};
|
|
@@ -98,7 +95,6 @@ declare class __sveltets_Render<Option extends T> {
|
|
|
98
95
|
export type MultiSelectProps<Option extends T> = ReturnType<__sveltets_Render<Option>['props']>;
|
|
99
96
|
export type MultiSelectEvents<Option extends T> = ReturnType<__sveltets_Render<Option>['events']>;
|
|
100
97
|
export type MultiSelectSlots<Option extends T> = ReturnType<__sveltets_Render<Option>['slots']>;
|
|
101
|
-
export default class MultiSelect<Option extends T> extends
|
|
102
|
-
get get_label(): (opt: T) => string | number;
|
|
98
|
+
export default class MultiSelect<Option extends T> extends SvelteComponent<MultiSelectProps<Option>, MultiSelectEvents<Option>, MultiSelectSlots<Option>> {
|
|
103
99
|
}
|
|
104
100
|
export {};
|
package/dist/Wiggle.svelte.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
2
|
declare const __propDef: {
|
|
3
3
|
props: {
|
|
4
4
|
wiggle?: boolean | undefined;
|
|
@@ -20,6 +20,6 @@ declare const __propDef: {
|
|
|
20
20
|
export type WiggleProps = typeof __propDef.props;
|
|
21
21
|
export type WiggleEvents = typeof __propDef.events;
|
|
22
22
|
export type WiggleSlots = typeof __propDef.slots;
|
|
23
|
-
export default class Wiggle extends
|
|
23
|
+
export default class Wiggle extends SvelteComponent<WiggleProps, WiggleEvents, WiggleSlots> {
|
|
24
24
|
}
|
|
25
25
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** @typedef {typeof __propDef.props} ChevronExpandProps */
|
|
2
2
|
/** @typedef {typeof __propDef.events} ChevronExpandEvents */
|
|
3
3
|
/** @typedef {typeof __propDef.slots} ChevronExpandSlots */
|
|
4
|
-
export default class ChevronExpand extends
|
|
4
|
+
export default class ChevronExpand extends SvelteComponent<{
|
|
5
5
|
[x: string]: any;
|
|
6
6
|
}, {
|
|
7
7
|
[evt: string]: CustomEvent<any>;
|
|
@@ -10,7 +10,7 @@ export default class ChevronExpand extends SvelteComponentTyped<{
|
|
|
10
10
|
export type ChevronExpandProps = typeof __propDef.props;
|
|
11
11
|
export type ChevronExpandEvents = typeof __propDef.events;
|
|
12
12
|
export type ChevronExpandSlots = typeof __propDef.slots;
|
|
13
|
-
import {
|
|
13
|
+
import { SvelteComponent } from "svelte";
|
|
14
14
|
declare const __propDef: {
|
|
15
15
|
props: {
|
|
16
16
|
[x: string]: any;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** @typedef {typeof __propDef.props} CrossProps */
|
|
2
2
|
/** @typedef {typeof __propDef.events} CrossEvents */
|
|
3
3
|
/** @typedef {typeof __propDef.slots} CrossSlots */
|
|
4
|
-
export default class Cross extends
|
|
4
|
+
export default class Cross extends SvelteComponent<{
|
|
5
5
|
[x: string]: any;
|
|
6
6
|
}, {
|
|
7
7
|
[evt: string]: CustomEvent<any>;
|
|
@@ -10,7 +10,7 @@ export default class Cross extends SvelteComponentTyped<{
|
|
|
10
10
|
export type CrossProps = typeof __propDef.props;
|
|
11
11
|
export type CrossEvents = typeof __propDef.events;
|
|
12
12
|
export type CrossSlots = typeof __propDef.slots;
|
|
13
|
-
import {
|
|
13
|
+
import { SvelteComponent } from "svelte";
|
|
14
14
|
declare const __propDef: {
|
|
15
15
|
props: {
|
|
16
16
|
[x: string]: any;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** @typedef {typeof __propDef.props} DisabledProps */
|
|
2
2
|
/** @typedef {typeof __propDef.events} DisabledEvents */
|
|
3
3
|
/** @typedef {typeof __propDef.slots} DisabledSlots */
|
|
4
|
-
export default class Disabled extends
|
|
4
|
+
export default class Disabled extends SvelteComponent<{
|
|
5
5
|
[x: string]: any;
|
|
6
6
|
}, {
|
|
7
7
|
[evt: string]: CustomEvent<any>;
|
|
@@ -10,7 +10,7 @@ export default class Disabled extends SvelteComponentTyped<{
|
|
|
10
10
|
export type DisabledProps = typeof __propDef.props;
|
|
11
11
|
export type DisabledEvents = typeof __propDef.events;
|
|
12
12
|
export type DisabledSlots = typeof __propDef.slots;
|
|
13
|
-
import {
|
|
13
|
+
import { SvelteComponent } from "svelte";
|
|
14
14
|
declare const __propDef: {
|
|
15
15
|
props: {
|
|
16
16
|
[x: string]: any;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** @typedef {typeof __propDef.props} OctocatProps */
|
|
2
2
|
/** @typedef {typeof __propDef.events} OctocatEvents */
|
|
3
3
|
/** @typedef {typeof __propDef.slots} OctocatSlots */
|
|
4
|
-
export default class Octocat extends
|
|
4
|
+
export default class Octocat extends SvelteComponent<{
|
|
5
5
|
[x: string]: any;
|
|
6
6
|
}, {
|
|
7
7
|
[evt: string]: CustomEvent<any>;
|
|
@@ -10,7 +10,7 @@ export default class Octocat extends SvelteComponentTyped<{
|
|
|
10
10
|
export type OctocatProps = typeof __propDef.props;
|
|
11
11
|
export type OctocatEvents = typeof __propDef.events;
|
|
12
12
|
export type OctocatSlots = typeof __propDef.slots;
|
|
13
|
-
import {
|
|
13
|
+
import { SvelteComponent } from "svelte";
|
|
14
14
|
declare const __propDef: {
|
|
15
15
|
props: {
|
|
16
16
|
[x: string]: any;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export type Option = string | number | ObjectOption;
|
|
2
|
+
export type OptionStyle = string | {
|
|
3
|
+
option: string;
|
|
4
|
+
selected: string;
|
|
5
|
+
};
|
|
2
6
|
export type ObjectOption = {
|
|
3
7
|
label: string | number;
|
|
4
8
|
value?: unknown;
|
|
@@ -7,6 +11,7 @@ export type ObjectOption = {
|
|
|
7
11
|
preselected?: boolean;
|
|
8
12
|
disabledTitle?: string;
|
|
9
13
|
selectedTitle?: string;
|
|
14
|
+
style?: OptionStyle;
|
|
10
15
|
[key: string]: unknown;
|
|
11
16
|
};
|
|
12
17
|
export type DispatchEvents<T = Option> = {
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Option, OptionStyle } from './types';
|
|
2
|
+
export declare const get_label: (opt: Option) => string | number;
|
|
3
|
+
export declare function get_style(option: {
|
|
4
|
+
style?: OptionStyle;
|
|
5
|
+
[key: string]: unknown;
|
|
6
|
+
} | string | number, key?: 'selected' | 'option' | null): string | null | undefined;
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// get the label key from an option object or the option itself if it's a string or number
|
|
2
|
+
export const get_label = (opt) => {
|
|
3
|
+
if (opt instanceof Object) {
|
|
4
|
+
if (opt.label === undefined) {
|
|
5
|
+
console.error(`MultiSelect option ${JSON.stringify(opt)} is an object but has no label key`);
|
|
6
|
+
}
|
|
7
|
+
return opt.label;
|
|
8
|
+
}
|
|
9
|
+
return `${opt}`;
|
|
10
|
+
};
|
|
11
|
+
export function get_style(option, key = null) {
|
|
12
|
+
if (!option?.style)
|
|
13
|
+
return null;
|
|
14
|
+
if (![`selected`, `option`, null].includes(key)) {
|
|
15
|
+
console.error(`MultiSelect: Invalid key=${key} for get_style`);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (typeof option == `object` && option.style) {
|
|
19
|
+
if (typeof option.style == `string`) {
|
|
20
|
+
return option.style;
|
|
21
|
+
}
|
|
22
|
+
if (typeof option.style == `object`) {
|
|
23
|
+
if (key && key in option.style)
|
|
24
|
+
return option.style[key];
|
|
25
|
+
else {
|
|
26
|
+
console.error(`Invalid style object for option=${JSON.stringify(option)}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
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": "10.
|
|
8
|
+
"version": "10.2.0",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"svelte": "./dist/index.js",
|
|
11
11
|
"bugs": "https://github.com/janosh/svelte-multiselect/issues",
|
|
@@ -23,37 +23,37 @@
|
|
|
23
23
|
"update-coverage": "vitest tests/unit --run --coverage && npx istanbul-badges-readme"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"svelte": "^4.0
|
|
26
|
+
"svelte": "^4.2.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@iconify/svelte": "^3.1.4",
|
|
30
|
-
"@playwright/test": "^1.
|
|
31
|
-
"@sveltejs/adapter-static": "^2.0.
|
|
32
|
-
"@sveltejs/kit": "^1.
|
|
33
|
-
"@sveltejs/package": "2.
|
|
34
|
-
"@sveltejs/vite-plugin-svelte": "2.4.
|
|
35
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
36
|
-
"@typescript-eslint/parser": "^
|
|
37
|
-
"@vitest/coverage-v8": "^0.
|
|
38
|
-
"eslint": "^8.
|
|
39
|
-
"eslint-plugin-svelte": "^2.
|
|
40
|
-
"hastscript": "^
|
|
30
|
+
"@playwright/test": "^1.37.1",
|
|
31
|
+
"@sveltejs/adapter-static": "^2.0.3",
|
|
32
|
+
"@sveltejs/kit": "^1.24.1",
|
|
33
|
+
"@sveltejs/package": "2.2.2",
|
|
34
|
+
"@sveltejs/vite-plugin-svelte": "2.4.5",
|
|
35
|
+
"@typescript-eslint/eslint-plugin": "^6.7.0",
|
|
36
|
+
"@typescript-eslint/parser": "^6.7.0",
|
|
37
|
+
"@vitest/coverage-v8": "^0.34.4",
|
|
38
|
+
"eslint": "^8.49.0",
|
|
39
|
+
"eslint-plugin-svelte": "^2.33.1",
|
|
40
|
+
"hastscript": "^8.0.0",
|
|
41
41
|
"highlight.js": "^11.8.0",
|
|
42
42
|
"jsdom": "^22.1.0",
|
|
43
43
|
"mdsvex": "^0.11.0",
|
|
44
|
-
"mdsvexamples": "^0.
|
|
45
|
-
"prettier": "^
|
|
46
|
-
"prettier-plugin-svelte": "^
|
|
47
|
-
"rehype-autolink-headings": "^
|
|
48
|
-
"rehype-slug": "^
|
|
49
|
-
"svelte-check": "^3.
|
|
44
|
+
"mdsvexamples": "^0.4.1",
|
|
45
|
+
"prettier": "^3.0.3",
|
|
46
|
+
"prettier-plugin-svelte": "^3.0.3",
|
|
47
|
+
"rehype-autolink-headings": "^7.0.0",
|
|
48
|
+
"rehype-slug": "^6.0.0",
|
|
49
|
+
"svelte-check": "^3.5.1",
|
|
50
50
|
"svelte-preprocess": "^5.0.4",
|
|
51
|
-
"svelte-toc": "^0.5.
|
|
52
|
-
"svelte-zoo": "^0.4.
|
|
53
|
-
"svelte2tsx": "^0.6.
|
|
54
|
-
"typescript": "5.
|
|
55
|
-
"vite": "^4.
|
|
56
|
-
"vitest": "^0.
|
|
51
|
+
"svelte-toc": "^0.5.6",
|
|
52
|
+
"svelte-zoo": "^0.4.9",
|
|
53
|
+
"svelte2tsx": "^0.6.21",
|
|
54
|
+
"typescript": "5.2.2",
|
|
55
|
+
"vite": "^4.4.9",
|
|
56
|
+
"vitest": "^0.34.4"
|
|
57
57
|
},
|
|
58
58
|
"keywords": [
|
|
59
59
|
"svelte",
|
package/readme.md
CHANGED
|
@@ -194,10 +194,10 @@ Full list of props/bindable variables for this component. The `Option` type you
|
|
|
194
194
|
Customize how dropdown options are filtered when user enters search string into `<MultiSelect />`. Defaults to:
|
|
195
195
|
|
|
196
196
|
1. ```ts
|
|
197
|
-
|
|
197
|
+
closeDropdownOnSelect: boolean | 'desktop' = `desktop`
|
|
198
198
|
```
|
|
199
199
|
|
|
200
|
-
One of `true`, `false` or `'desktop'`. Whether to
|
|
200
|
+
One of `true`, `false` or `'desktop'`. Whether to close the dropdown list after selecting a dropdown item. If `true`, component will loose focus and `dropdown` is closed. `'desktop'` means `false` if current window width is larger than the current value of `breakpoint` prop (default is 800, meaning screen width in pixels). This is to align with the default behavior of many mobile browsers like Safari which close dropdowns after selecting an option while desktop browsers facilitate multi-selection by leaving dropdowns open.
|
|
201
201
|
|
|
202
202
|
1. ```ts
|
|
203
203
|
form_input: HTMLInputElement | null = null
|
|
@@ -385,7 +385,7 @@ Full list of props/bindable variables for this component. The `Option` type you
|
|
|
385
385
|
value: Option | Option[] | null = null
|
|
386
386
|
```
|
|
387
387
|
|
|
388
|
-
If `maxSelect={1}`, `value` will be the single item in `selected` (or `null` if `selected` is empty). If `maxSelect != 1`, `maxSelect` and `selected` are equal. Warning: `value`
|
|
388
|
+
If `maxSelect={1}`, `value` will be the single item in `selected` (or `null` if `selected` is empty). If `maxSelect != 1`, `maxSelect` and `selected` are equal. Warning: Setting `value` does not rendered state on initial mount, meaning `bind:value` will update local variable `value` whenever internal component state changes but passing a `value` when component first mounts won't be reflected in UI. This is because the source of truth for rendering is `bind:selected`. `selected` is reactive to `value` internally but only on reassignment from initial value. Suggestions for better solutions than [#249](https://github.com/janosh/svelte-multiselect/issues/249) welcome!
|
|
389
389
|
|
|
390
390
|
## 🎰   Slots
|
|
391
391
|
|
|
@@ -397,13 +397,11 @@ Full list of props/bindable variables for this component. The `Option` type you
|
|
|
397
397
|
1. `slot="disabled-icon"`: Custom icon to display inside the input when in `disabled` state. Receives no props. Use an empty `<span slot="disabled-icon" />` or `div` to remove the default disabled icon.
|
|
398
398
|
1. `slot="expand-icon"`: Allows setting a custom icon to indicate to users that the Multiselect text input field is expandable into a dropdown list. Receives prop `open: boolean` which is true if the Multiselect dropdown is visible and false if it's hidden.
|
|
399
399
|
1. `slot="remove-icon"`: Custom icon to display as remove button. Will be used both by buttons to remove individual selected options and the 'remove all' button that clears all options at once. Receives no props.
|
|
400
|
-
1. `slot="user-msg"`: Displayed like a dropdown item when the list is empty and user is allowed to create custom options based on text input (or if the user's text input clashes with an existing option).
|
|
401
|
-
- `
|
|
402
|
-
- `
|
|
403
|
-
- `
|
|
404
|
-
|
|
405
|
-
- `msg: string`: `duplicateOptionMsg` if user input is a duplicate else `createOptionMsg`.
|
|
406
|
-
1. `slot='after-input'`: ForPlaced after the search input. For arbitrary content like icons or temporary messages. Receives props `selected`, `disabled`, `invalid`, `id`, `placeholder`, `open`, `required`.
|
|
400
|
+
1. `slot="user-msg"`: Displayed like a dropdown item when the list is empty and user is allowed to create custom options based on text input (or if the user's text input clashes with an existing option). Receives props:
|
|
401
|
+
- `searchText`: The text user typed into search input.
|
|
402
|
+
- `msgType: false | 'create' | 'dupe' | 'no-match'`: `'dupe'` means user input is a duplicate of an existing option. `'create'` means user is allowed to convert their input into a new option not previously in the dropdown. `'no-match'` means user input doesn't match any dropdown items and users are not allowed to create new options. `false` means none of the above.
|
|
403
|
+
- `msg`: Will be `duplicateOptionMsg` or `createOptionMsg` (see [props](#🔣-props)) based on whether user input is a duplicate or can be created as new option. Note this slot replaces the default UI for displaying these messages so the slot needs to render them instead (unless purposely not showing a message).
|
|
404
|
+
1. `slot='after-input'`: Placed after the search input. For arbitrary content like icons or temporary messages. Receives props `selected: Option[]`, `disabled: boolean`, `invalid: boolean`, `id: string | null`, `placeholder: string`, `open: boolean`, `required: boolean`. Can serve as a more dynamic, more customizable alternative to the `placeholder` prop.
|
|
407
405
|
|
|
408
406
|
Example using several slots:
|
|
409
407
|
|