svelte-multiselect 8.6.1 → 8.6.2

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.
@@ -1,6 +1,7 @@
1
1
  <script>import { createEventDispatcher, tick } from 'svelte';
2
2
  import { flip } from 'svelte/animate';
3
- import { CircleSpinner, Wiggle } from '.';
3
+ import CircleSpinner from './CircleSpinner.svelte';
4
+ import Wiggle from './Wiggle.svelte';
4
5
  import { CrossIcon, DisabledIcon, ExpandIcon } from './icons';
5
6
  export let activeIndex = null;
6
7
  export let activeOption = null;
@@ -63,7 +64,7 @@ export let ulOptionsClass = ``;
63
64
  export let ulSelectedClass = ``;
64
65
  export let value = null;
65
66
  // get the label key from an option object or the option itself if it's a string or number
66
- const get_label = (op) => {
67
+ export const get_label = (op) => {
67
68
  if (op instanceof Object) {
68
69
  if (op.label === undefined) {
69
70
  console.error(`MultiSelect option ${JSON.stringify(op)} is an object but has no label key`);
@@ -103,8 +104,8 @@ if (sortSelected && selectedOptionsDraggable) {
103
104
  console.warn(`MultiSelect's sortSelected and selectedOptionsDraggable should not be combined as any ` +
104
105
  `user re-orderings of selected options will be undone by sortSelected on component re-renders.`);
105
106
  }
106
- if (allowUserOptions && !createOptionMsg) {
107
- console.error(`MultiSelect's allowUserOptions=${allowUserOptions} but createOptionMsg=${createOptionMsg} is falsy. ` +
107
+ if (allowUserOptions && !createOptionMsg && createOptionMsg !== null) {
108
+ console.error(`MultiSelect has allowUserOptions=${allowUserOptions} but createOptionMsg=${createOptionMsg} is falsy. ` +
108
109
  `This prevents the "Add option" <span> from showing up, resulting in a confusing user experience.`);
109
110
  }
110
111
  const dispatch = createEventDispatcher();
@@ -190,20 +191,22 @@ function add(option, event) {
190
191
  }
191
192
  }
192
193
  // remove an option from selected list
193
- function remove(label) {
194
+ function remove(to_remove) {
194
195
  if (selected.length === 0)
195
196
  return;
196
- let option = selected.find((op) => get_label(op) === label);
197
+ const idx = selected.findIndex((op) => JSON.stringify(op) === JSON.stringify(to_remove));
198
+ let [option] = selected.splice(idx, 1); // remove option from selected list
197
199
  if (option === undefined && allowUserOptions) {
198
200
  // if option with label could not be found but allowUserOptions is truthy,
199
201
  // assume it was created by user and create corresponding option object
200
202
  // on the fly for use as event payload
201
- option = (typeof options[0] == `object` ? { label } : label);
203
+ const other_ops_type = typeof options[0];
204
+ option = (other_ops_type ? { label: to_remove } : to_remove);
202
205
  }
203
206
  if (option === undefined) {
204
- return console.error(`Multiselect can't remove selected option ${label}, not found in selected list`);
207
+ return console.error(`Multiselect can't remove selected option ${JSON.stringify(to_remove)}, not found in selected list`);
205
208
  }
206
- selected = selected.filter((op) => get_label(op) !== label); // remove option from selected list
209
+ selected = [...selected]; // trigger Svelte rerender
207
210
  invalid = false; // reset error status whenever items are removed
208
211
  form_input?.setCustomValidity(``);
209
212
  dispatch(`remove`, { option });
@@ -1,10 +1,10 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
- import type { Option as GenericOption, MultiSelectEvents } from './';
3
- declare class __sveltets_Render<Option extends GenericOption> {
2
+ import type { MultiSelectEvents, Option as T } from './types';
3
+ declare class __sveltets_Render<Option extends T> {
4
4
  props(): {
5
5
  activeIndex?: number | null | undefined;
6
6
  activeOption?: Option | null | undefined;
7
- createOptionMsg?: string | undefined;
7
+ createOptionMsg?: string | null | undefined;
8
8
  allowUserOptions?: boolean | "append" | undefined;
9
9
  allowEmpty?: boolean | undefined;
10
10
  autocomplete?: string | undefined;
@@ -13,7 +13,7 @@ declare class __sveltets_Render<Option extends GenericOption> {
13
13
  defaultDisabledTitle?: string | undefined;
14
14
  disabled?: boolean | undefined;
15
15
  disabledInputTitle?: string | undefined;
16
- duplicateFunc?: ((op1: GenericOption, op2: GenericOption) => boolean) | undefined;
16
+ duplicateFunc?: ((op1: T, op2: T) => boolean) | undefined;
17
17
  duplicateOptionMsg?: string | undefined;
18
18
  duplicates?: boolean | undefined;
19
19
  filterFunc?: ((op: Option, searchText: string) => boolean) | undefined;
@@ -54,6 +54,7 @@ declare class __sveltets_Render<Option extends GenericOption> {
54
54
  ulOptionsClass?: string | undefined;
55
55
  ulSelectedClass?: string | undefined;
56
56
  value?: Option | Option[] | null | undefined;
57
+ get_label?: ((op: T) => string | number) | undefined;
57
58
  };
58
59
  events(): MultiSelectEvents;
59
60
  slots(): {
@@ -73,9 +74,10 @@ declare class __sveltets_Render<Option extends GenericOption> {
73
74
  };
74
75
  };
75
76
  }
76
- export type MultiSelectProps<Option extends GenericOption> = ReturnType<__sveltets_Render<Option>['props']>;
77
- export type MultiSelectEvents<Option extends GenericOption> = ReturnType<__sveltets_Render<Option>['events']>;
78
- export type MultiSelectSlots<Option extends GenericOption> = ReturnType<__sveltets_Render<Option>['slots']>;
79
- export default class MultiSelect<Option extends GenericOption> extends SvelteComponentTyped<MultiSelectProps<Option>, MultiSelectEvents<Option>, MultiSelectSlots<Option>> {
77
+ export type MultiSelectProps<Option extends T> = ReturnType<__sveltets_Render<Option>['props']>;
78
+ export type MultiSelectEvents<Option extends T> = ReturnType<__sveltets_Render<Option>['events']>;
79
+ export type MultiSelectSlots<Option extends T> = ReturnType<__sveltets_Render<Option>['slots']>;
80
+ export default class MultiSelect<Option extends T> extends SvelteComponentTyped<MultiSelectProps<Option>, MultiSelectEvents<Option>, MultiSelectSlots<Option>> {
81
+ get get_label(): (op: T) => string | number;
80
82
  }
81
83
  export {};
package/dist/index.d.ts CHANGED
@@ -2,55 +2,5 @@ export { default as CircleSpinner } from './CircleSpinner.svelte';
2
2
  export { default as CmdPalette } from './CmdPalette.svelte';
3
3
  export { default as MultiSelect, default } from './MultiSelect.svelte';
4
4
  export { default as Wiggle } from './Wiggle.svelte';
5
- export type Option = string | number | ObjectOption;
6
- export type ObjectOption = {
7
- label: string | number;
8
- value?: unknown;
9
- title?: string;
10
- disabled?: boolean;
11
- preselected?: boolean;
12
- disabledTitle?: string;
13
- selectedTitle?: string;
14
- [key: string]: unknown;
15
- };
16
- export type DispatchEvents<T = Option> = {
17
- add: {
18
- option: T;
19
- };
20
- create: {
21
- option: T;
22
- };
23
- remove: {
24
- option: T;
25
- };
26
- removeAll: {
27
- options: T[];
28
- };
29
- change: {
30
- option?: T;
31
- options?: T[];
32
- type: 'add' | 'remove' | 'removeAll';
33
- };
34
- open: {
35
- event: Event;
36
- };
37
- close: {
38
- event: Event;
39
- };
40
- };
41
- export type MultiSelectEvents = {
42
- [key in keyof DispatchEvents]: CustomEvent<DispatchEvents[key]>;
43
- } & {
44
- blur: FocusEvent;
45
- click: MouseEvent;
46
- focus: FocusEvent;
47
- keydown: KeyboardEvent;
48
- keyup: KeyboardEvent;
49
- mouseenter: MouseEvent;
50
- mouseleave: MouseEvent;
51
- touchcancel: TouchEvent;
52
- touchend: TouchEvent;
53
- touchmove: TouchEvent;
54
- touchstart: TouchEvent;
55
- };
5
+ export * from './types';
56
6
  export declare function scroll_into_view_if_needed_polyfill(centerIfNeeded?: boolean): IntersectionObserver;
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ export { default as CircleSpinner } from './CircleSpinner.svelte';
2
2
  export { default as CmdPalette } from './CmdPalette.svelte';
3
3
  export { default as MultiSelect, default } from './MultiSelect.svelte';
4
4
  export { default as Wiggle } from './Wiggle.svelte';
5
+ export * from './types';
5
6
  // Firefox lacks support for scrollIntoViewIfNeeded (https://caniuse.com/scrollintoviewifneeded).
6
7
  // See https://github.com/janosh/svelte-multiselect/issues/87
7
8
  // Polyfill copied from
@@ -0,0 +1,51 @@
1
+ export type Option = string | number | ObjectOption;
2
+ export type ObjectOption = {
3
+ label: string | number;
4
+ value?: unknown;
5
+ title?: string;
6
+ disabled?: boolean;
7
+ preselected?: boolean;
8
+ disabledTitle?: string;
9
+ selectedTitle?: string;
10
+ [key: string]: unknown;
11
+ };
12
+ export type DispatchEvents<T = Option> = {
13
+ add: {
14
+ option: T;
15
+ };
16
+ create: {
17
+ option: T;
18
+ };
19
+ remove: {
20
+ option: T;
21
+ };
22
+ removeAll: {
23
+ options: T[];
24
+ };
25
+ change: {
26
+ option?: T;
27
+ options?: T[];
28
+ type: 'add' | 'remove' | 'removeAll';
29
+ };
30
+ open: {
31
+ event: Event;
32
+ };
33
+ close: {
34
+ event: Event;
35
+ };
36
+ };
37
+ export type MultiSelectEvents = {
38
+ [key in keyof DispatchEvents]: CustomEvent<DispatchEvents[key]>;
39
+ } & {
40
+ blur: FocusEvent;
41
+ click: MouseEvent;
42
+ focus: FocusEvent;
43
+ keydown: KeyboardEvent;
44
+ keyup: KeyboardEvent;
45
+ mouseenter: MouseEvent;
46
+ mouseleave: MouseEvent;
47
+ touchcancel: TouchEvent;
48
+ touchend: TouchEvent;
49
+ touchmove: TouchEvent;
50
+ touchstart: TouchEvent;
51
+ };
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
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": "8.6.1",
8
+ "version": "8.6.2",
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": "^3.58.0"
26
+ "svelte": "^3.59.1"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@iconify/svelte": "^3.1.3",
30
30
  "@playwright/test": "^1.33.0",
31
31
  "@sveltejs/adapter-static": "^2.0.2",
32
- "@sveltejs/kit": "^1.15.9",
32
+ "@sveltejs/kit": "^1.16.3",
33
33
  "@sveltejs/package": "2.0.2",
34
- "@sveltejs/vite-plugin-svelte": "^2.1.1",
35
- "@typescript-eslint/eslint-plugin": "^5.59.1",
36
- "@typescript-eslint/parser": "^5.59.1",
37
- "@vitest/coverage-c8": "^0.30.1",
38
- "eslint": "^8.39.0",
34
+ "@sveltejs/vite-plugin-svelte": "^2.2.0",
35
+ "@typescript-eslint/eslint-plugin": "^5.59.5",
36
+ "@typescript-eslint/parser": "^5.59.5",
37
+ "@vitest/coverage-c8": "^0.31.0",
38
+ "eslint": "^8.40.0",
39
39
  "eslint-plugin-svelte3": "^4.0.0",
40
40
  "hastscript": "^7.2.0",
41
41
  "highlight.js": "^11.8.0",
42
- "jsdom": "^21.1.1",
42
+ "jsdom": "^22.0.0",
43
43
  "mdsvex": "^0.10.6",
44
44
  "mdsvexamples": "^0.3.3",
45
45
  "prettier": "^2.8.8",
46
46
  "prettier-plugin-svelte": "^2.10.0",
47
47
  "rehype-autolink-headings": "^6.1.1",
48
48
  "rehype-slug": "^5.1.0",
49
- "svelte-check": "^3.2.0",
49
+ "svelte-check": "^3.3.2",
50
50
  "svelte-preprocess": "^5.0.3",
51
51
  "svelte-toc": "^0.5.5",
52
52
  "svelte-zoo": "^0.4.5",
53
- "svelte2tsx": "^0.6.11",
53
+ "svelte2tsx": "^0.6.14",
54
54
  "typescript": "5.0.4",
55
- "vite": "^4.3.3",
56
- "vitest": "^0.30.1"
55
+ "vite": "^4.3.6",
56
+ "vitest": "^0.31.0"
57
57
  },
58
58
  "keywords": [
59
59
  "svelte",
package/readme.md CHANGED
@@ -51,7 +51,7 @@
51
51
 
52
52
  ```sh
53
53
  npm install --dev svelte-multiselect
54
- pnpm add --dev svelte-multiselect
54
+ pnpm add -D svelte-multiselect
55
55
  yarn add --dev svelte-multiselect
56
56
  ```
57
57
 
@@ -90,10 +90,10 @@ Full list of props/bindable variables for this component. The `Option` type you
90
90
  Currently active option, i.e. the one the user currently hovers or navigated to with arrow keys.
91
91
 
92
92
  1. ```ts
93
- createOptionMsg: string = `Create this option...`
93
+ createOptionMsg: string | null = `Create this option...`
94
94
  ```
95
95
 
96
- Message shown to users after entering text when no options match their query and `allowUserOptions` is truthy.
96
+ The message shown to users when `allowUserOptions` is truthy and they entered text that doesn't match any existing options to suggest creating a new option from the entered text. Emits `console.error` if `allowUserOptions` is `true` or `'append'` and `createOptionMsg=''` to since users might be unaware they can create new option. The error can be silenced by setting `createOptionMsg=null` indicating developer intent is to e.g. use MultiSelect as a tagging component where a user message might be unwanted.
97
97
 
98
98
  1. ```ts
99
99
  allowEmpty: boolean = false
@@ -146,7 +146,7 @@ Full list of props/bindable variables for this component. The `Option` type you
146
146
 
147
147
  <!-- prettier-ignore -->
148
148
  1. ```ts
149
- duplicateFunc: (op1: GenericOption, op2: GenericOption) => boolean = (op1, op2) =>
149
+ duplicateFunc: (op1: T, op2: T) => boolean = (op1, op2) =>
150
150
  `${get_label(op1)}`.toLowerCase() === `${get_label(op2)}`.toLowerCase()
151
151
  ```
152
152