svelte-multiselect 11.4.0 → 11.5.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/index.js DELETED
@@ -1,42 +0,0 @@
1
- export * from './attachments';
2
- export { default as CircleSpinner } from './CircleSpinner.svelte';
3
- export { default as CmdPalette } from './CmdPalette.svelte';
4
- export { default as CodeExample } from './CodeExample.svelte';
5
- export { default as CopyButton } from './CopyButton.svelte';
6
- export { default as FileDetails } from './FileDetails.svelte';
7
- export { default as GitHubCorner } from './GitHubCorner.svelte';
8
- export { default as Icon } from './Icon.svelte';
9
- export { default, default as MultiSelect } from './MultiSelect.svelte';
10
- export { default as Nav } from './Nav.svelte';
11
- export { default as PrevNext } from './PrevNext.svelte';
12
- export { default as Toggle } from './Toggle.svelte';
13
- export * from './types';
14
- export * from './utils';
15
- export { default as Wiggle } from './Wiggle.svelte';
16
- // Firefox lacks support for scrollIntoViewIfNeeded (https://caniuse.com/scrollintoviewifneeded).
17
- // See https://github.com/janosh/svelte-multiselect/issues/87
18
- // Polyfill copied from
19
- // https://github.com/nuxodin/lazyfill/blob/a8e63/polyfills/Element/prototype/scrollIntoViewIfNeeded.js
20
- // exported for testing
21
- export function scroll_into_view_if_needed_polyfill(element, centerIfNeeded = true) {
22
- const observer = new IntersectionObserver(([entry], obs) => {
23
- const ratio = entry.intersectionRatio;
24
- if (ratio < 1) {
25
- const place = ratio <= 0 && centerIfNeeded ? `center` : `nearest`;
26
- element.scrollIntoView({
27
- block: place,
28
- inline: place,
29
- });
30
- }
31
- obs.disconnect();
32
- });
33
- observer.observe(element);
34
- return observer; // return for testing
35
- }
36
- if (typeof Element !== `undefined` &&
37
- !Element.prototype?.scrollIntoViewIfNeeded &&
38
- typeof IntersectionObserver !== `undefined`) {
39
- Element.prototype.scrollIntoViewIfNeeded = function scrollIntoViewIfNeeded() {
40
- scroll_into_view_if_needed_polyfill(this);
41
- };
42
- }
package/dist/types.d.ts DELETED
@@ -1,171 +0,0 @@
1
- import type { FlipParams } from 'svelte/animate';
2
- import type { Snippet } from 'svelte';
3
- import type { HTMLAttributes, HTMLInputAttributes } from 'svelte/elements';
4
- export type Option = string | number | ObjectOption;
5
- export type OptionStyle = string | {
6
- option: string;
7
- selected: string;
8
- };
9
- export type ObjectOption = {
10
- label: string | number;
11
- value?: unknown;
12
- title?: string;
13
- disabled?: boolean;
14
- preselected?: boolean;
15
- disabledTitle?: string;
16
- selectedTitle?: string;
17
- style?: OptionStyle;
18
- [key: string]: unknown;
19
- };
20
- export type PlaceholderConfig = {
21
- text: string;
22
- persistent?: boolean;
23
- };
24
- export interface MultiSelectEvents<T extends Option = Option> {
25
- onadd?: (data: {
26
- option: T;
27
- }) => unknown;
28
- oncreate?: (data: {
29
- option: T;
30
- }) => unknown;
31
- onremove?: (data: {
32
- option: T;
33
- }) => unknown;
34
- onremoveAll?: (data: {
35
- options: T[];
36
- }) => unknown;
37
- onselectAll?: (data: {
38
- options: T[];
39
- }) => unknown;
40
- onchange?: (data: {
41
- option?: T;
42
- options?: T[];
43
- type: `add` | `remove` | `removeAll` | `selectAll`;
44
- }) => unknown;
45
- onopen?: (data: {
46
- event: Event;
47
- }) => unknown;
48
- onclose?: (data: {
49
- event: Event;
50
- }) => unknown;
51
- }
52
- export interface LoadOptionsParams {
53
- search: string;
54
- offset: number;
55
- limit: number;
56
- }
57
- export interface LoadOptionsResult<T extends Option = Option> {
58
- options: T[];
59
- hasMore: boolean;
60
- }
61
- export type LoadOptionsFn<T extends Option = Option> = (params: LoadOptionsParams) => Promise<LoadOptionsResult<T>>;
62
- export interface LoadOptionsConfig<T extends Option = Option> {
63
- fetch: LoadOptionsFn<T>;
64
- debounceMs?: number;
65
- batchSize?: number;
66
- onOpen?: boolean;
67
- }
68
- export type LoadOptions<T extends Option = Option> = LoadOptionsFn<T> | LoadOptionsConfig<T>;
69
- type AfterInputProps = Pick<MultiSelectProps, `selected` | `disabled` | `invalid` | `id` | `placeholder` | `open` | `required`>;
70
- type UserMsgProps = {
71
- searchText: string;
72
- msgType: false | `dupe` | `create` | `no-match`;
73
- msg: null | string;
74
- };
75
- export interface MultiSelectSnippets<T extends Option = Option> {
76
- expandIcon?: Snippet<[{
77
- open: boolean;
78
- }]>;
79
- selectedItem?: Snippet<[{
80
- option: T;
81
- idx: number;
82
- }]>;
83
- children?: Snippet<[{
84
- option: T;
85
- idx: number;
86
- }]>;
87
- removeIcon?: Snippet;
88
- afterInput?: Snippet<[AfterInputProps]>;
89
- spinner?: Snippet;
90
- disabledIcon?: Snippet;
91
- option?: Snippet<[{
92
- option: T;
93
- idx: number;
94
- }]>;
95
- userMsg?: Snippet<[UserMsgProps]>;
96
- }
97
- export interface PortalParams {
98
- target_node?: HTMLElement | null;
99
- active?: boolean;
100
- }
101
- export interface MultiSelectProps<T extends Option = Option> extends MultiSelectEvents<T>, MultiSelectSnippets<T>, Omit<HTMLAttributes<HTMLDivElement>, `children` | `onchange` | `onclose` | `placeholder`> {
102
- activeIndex?: number | null;
103
- activeOption?: T | null;
104
- createOptionMsg?: string | null;
105
- allowUserOptions?: boolean | `append`;
106
- allowEmpty?: boolean;
107
- autocomplete?: HTMLInputAttributes[`autocomplete`];
108
- autoScroll?: boolean;
109
- breakpoint?: number;
110
- defaultDisabledTitle?: string;
111
- disabled?: boolean;
112
- disabledInputTitle?: string;
113
- duplicateOptionMsg?: string;
114
- duplicates?: boolean;
115
- keepSelectedInDropdown?: false | `plain` | `checkboxes`;
116
- key?: (opt: T) => unknown;
117
- filterFunc?: (opt: T, searchText: string) => boolean;
118
- fuzzy?: boolean;
119
- closeDropdownOnSelect?: boolean | `if-mobile` | `retain-focus`;
120
- form_input?: HTMLInputElement | null;
121
- highlightMatches?: boolean;
122
- id?: string | null;
123
- input?: HTMLInputElement | null;
124
- inputClass?: string;
125
- inputStyle?: string | null;
126
- inputmode?: HTMLInputAttributes[`inputmode`] | null;
127
- invalid?: boolean;
128
- liActiveOptionClass?: string;
129
- liActiveUserMsgClass?: string;
130
- liOptionClass?: string;
131
- liOptionStyle?: string | null;
132
- liSelectedClass?: string;
133
- liSelectedStyle?: string | null;
134
- liUserMsgClass?: string;
135
- loading?: boolean;
136
- matchingOptions?: T[];
137
- maxOptions?: number | undefined;
138
- maxSelect?: number | null;
139
- maxSelectMsg?: ((current: number, max: number) => string) | null;
140
- maxSelectMsgClass?: string;
141
- name?: string | null;
142
- noMatchingOptionsMsg?: string;
143
- open?: boolean;
144
- options?: T[];
145
- outerDiv?: HTMLDivElement | null;
146
- outerDivClass?: string;
147
- parseLabelsAsHtml?: boolean;
148
- pattern?: string | null;
149
- placeholder?: string | PlaceholderConfig | null;
150
- removeAllTitle?: string;
151
- removeBtnTitle?: string;
152
- minSelect?: number | null;
153
- required?: boolean | number;
154
- resetFilterOnAdd?: boolean;
155
- searchText?: string;
156
- selected?: T[];
157
- sortSelected?: boolean | ((op1: T, op2: T) => number);
158
- selectedOptionsDraggable?: boolean;
159
- style?: string | null;
160
- ulOptionsClass?: string;
161
- ulSelectedClass?: string;
162
- ulSelectedStyle?: string | null;
163
- ulOptionsStyle?: string | null;
164
- value?: T | T[] | null;
165
- portal?: PortalParams;
166
- selectAllOption?: boolean | string;
167
- liSelectAllClass?: string;
168
- loadOptions?: LoadOptions<T>;
169
- selectedFlipParams?: FlipParams;
170
- }
171
- export {};
package/dist/types.js DELETED
@@ -1 +0,0 @@
1
- export {};
package/dist/utils.d.ts DELETED
@@ -1,5 +0,0 @@
1
- import type { Option } from './types';
2
- export declare const is_object: (val: unknown) => val is Record<string, unknown>;
3
- export declare const get_label: (opt: Option) => string | number;
4
- export declare function get_style(option: Option, key?: `selected` | `option` | null | undefined): string;
5
- export declare function fuzzy_match(search_text: string, target_text: string): boolean;
package/dist/utils.js DELETED
@@ -1,61 +0,0 @@
1
- // Type guard for checking if a value is a non-null object
2
- export const is_object = (val) => typeof val === `object` && val !== null;
3
- // Get the label key from an option object or the option itself
4
- // if it's a string or number
5
- export const get_label = (opt) => {
6
- if (is_object(opt)) {
7
- if (opt.label === undefined) {
8
- const opt_str = JSON.stringify(opt);
9
- console.error(`MultiSelect: option is an object but has no label key`, opt_str);
10
- }
11
- return opt.label;
12
- }
13
- return `${opt}`;
14
- };
15
- // This function is used extract CSS strings from a {selected, option} style
16
- // object to be used in the style attribute of the option.
17
- // If the style is a string, it will be returned as is
18
- export function get_style(option, key = null) {
19
- if (key === undefined)
20
- key = null;
21
- let css_str = ``;
22
- const valid_key = key === null || key === `selected` || key === `option`;
23
- if (!valid_key)
24
- console.error(`MultiSelect: Invalid key=${key} for get_style`);
25
- if (typeof option === `object` && option.style) {
26
- if (typeof option.style === `string`)
27
- css_str = option.style;
28
- if (typeof option.style === `object`) {
29
- if (key && key in option.style)
30
- return option.style[key] ?? ``;
31
- else {
32
- console.error(`MultiSelect: invalid style object for option`, option);
33
- }
34
- }
35
- }
36
- // ensure css_str ends with a semicolon
37
- if (css_str.trim() && !css_str.trim().endsWith(`;`))
38
- css_str += `;`;
39
- return css_str;
40
- }
41
- // Fuzzy string matching function
42
- // Returns true if the search string can be found as a subsequence in the target string
43
- // e.g., "tageoo" matches "tasks/geo-opt" because t-a-g-e-o-o appears in order
44
- export function fuzzy_match(search_text, target_text) {
45
- // Handle null/undefined inputs first
46
- if (search_text === null || search_text === undefined || target_text === null ||
47
- target_text === undefined)
48
- return false;
49
- if (!search_text)
50
- return true;
51
- if (!target_text)
52
- return false;
53
- const [search, target] = [search_text.toLowerCase(), target_text.toLowerCase()];
54
- let [search_idx, target_idx] = [0, 0];
55
- while (search_idx < search.length && target_idx < target.length) {
56
- if (search[search_idx] === target[target_idx])
57
- search_idx++;
58
- target_idx++;
59
- }
60
- return search_idx === search.length;
61
- }