svelte-multiselect 10.3.0 → 11.0.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/utils.js CHANGED
@@ -1,4 +1,8 @@
1
- // get the label key from an option object or the option itself if it's a string or number
1
+ /**
2
+ * Get the label key from an option object or the option itself if it's a string or number
3
+ * @param opt Option
4
+ * @returns Label
5
+ */
2
6
  export const get_label = (opt) => {
3
7
  if (opt instanceof Object) {
4
8
  if (opt.label === undefined) {
@@ -8,8 +12,13 @@ export const get_label = (opt) => {
8
12
  }
9
13
  return `${opt}`;
10
14
  };
11
- // this function is used extract CSS strings from a {selected, option} style object to be used in the style attribute of the option
12
- // if the style is a string, it will be returned as is
15
+ /**
16
+ * This function is used extract CSS strings from a {selected, option} style 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
+ * @param option Option
19
+ * @param key
20
+ * @returns CSS string
21
+ */
13
22
  export function get_style(option, key = null) {
14
23
  let css_str = ``;
15
24
  if (![`selected`, `option`, null].includes(key)) {
@@ -32,3 +41,51 @@ export function get_style(option, key = null) {
32
41
  css_str += `;`;
33
42
  return css_str;
34
43
  }
44
+ /**
45
+ * Highlights text nodes that matching the string query
46
+ * @param element Parent element
47
+ * @param query Search query
48
+ * @param noMatchingOptionsMsg Text for empty node
49
+ */
50
+ export function highlight_matching_nodes(element, query, noMatchingOptionsMsg) {
51
+ if (typeof CSS == `undefined` || !CSS.highlights || !query)
52
+ return; // abort if CSS highlight API not supported
53
+ // clear previous ranges from HighlightRegistry
54
+ CSS.highlights.clear();
55
+ const tree_walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, {
56
+ acceptNode: (node) => {
57
+ // don't highlight text in the "no matching options" message
58
+ if (node?.textContent === noMatchingOptionsMsg)
59
+ return NodeFilter.FILTER_REJECT;
60
+ return NodeFilter.FILTER_ACCEPT;
61
+ },
62
+ });
63
+ const text_nodes = [];
64
+ let current_node = tree_walker.nextNode();
65
+ while (current_node) {
66
+ text_nodes.push(current_node);
67
+ current_node = tree_walker.nextNode();
68
+ }
69
+ // iterate over all text nodes and find matches
70
+ const ranges = text_nodes.map((el) => {
71
+ const text = el.textContent?.toLowerCase();
72
+ const indices = [];
73
+ let start_pos = 0;
74
+ while (text && start_pos < text.length) {
75
+ const index = text.indexOf(query, start_pos);
76
+ if (index === -1)
77
+ break;
78
+ indices.push(index);
79
+ start_pos = index + query.length;
80
+ }
81
+ // create range object for each str found in the text node
82
+ return indices.map((index) => {
83
+ const range = new Range();
84
+ range.setStart(el, index);
85
+ range.setEnd(el, index + query.length);
86
+ return range;
87
+ });
88
+ });
89
+ // create Highlight object from ranges and add to registry
90
+ CSS.highlights.set(`sms-search-matches`, new Highlight(...ranges.flat()));
91
+ }
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.3.0",
8
+ "version": "11.0.0",
9
9
  "type": "module",
10
10
  "svelte": "./dist/index.js",
11
11
  "bugs": "https://github.com/janosh/svelte-multiselect/issues",
@@ -15,46 +15,49 @@
15
15
  "preview": "vite preview",
16
16
  "package": "svelte-package",
17
17
  "serve": "vite build && vite preview",
18
- "check": "svelte-check --ignore dist",
19
- "test": "vitest --run --coverage tests/unit/*.ts && playwright test tests/*.test.ts",
18
+ "check": "svelte-check src",
19
+ "test": "vitest --run --coverage tests/unit/*.ts && npm run test:e2e",
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",
23
23
  "update-coverage": "vitest tests/unit --run --coverage && npx istanbul-badges-readme"
24
24
  },
25
- "dependencies": {
26
- "svelte": "4.2.12"
25
+ "peerDependencies": {
26
+ "svelte": "^5.8.0"
27
27
  },
28
28
  "devDependencies": {
29
- "@iconify/svelte": "^3.1.6",
30
- "@playwright/test": "^1.43.0",
31
- "@sveltejs/adapter-static": "^3.0.1",
32
- "@sveltejs/kit": "^2.5.5",
33
- "@sveltejs/package": "2.3.1",
34
- "@sveltejs/vite-plugin-svelte": "3.0.2",
35
- "@vitest/coverage-v8": "^1.4.0",
36
- "eslint": "^9.0.0",
37
- "eslint-plugin-svelte": "^2.36.0",
38
- "globals": "^15.0.0",
39
- "hastscript": "^9.0.0",
40
- "highlight.js": "^11.9.0",
41
- "jsdom": "^24.0.0",
42
- "mdsvex": "^0.11.0",
43
- "mdsvexamples": "^0.4.1",
44
- "prettier": "^3.2.5",
45
- "prettier-plugin-svelte": "^3.2.2",
29
+ "@iconify/svelte": "^5.0.0",
30
+ "@playwright/test": "^1.52.0",
31
+ "@stylistic/eslint-plugin": "^4.2.0",
32
+ "@sveltejs/adapter-static": "^3.0.8",
33
+ "@sveltejs/kit": "^2.21.0",
34
+ "@sveltejs/package": "2.3.11",
35
+ "@sveltejs/vite-plugin-svelte": "^5.0.3",
36
+ "@types/node": "^22.15.18",
37
+ "@vitest/coverage-v8": "^3.1.3",
38
+ "eslint": "^9.26.0",
39
+ "eslint-plugin-svelte": "^3.6.0",
40
+ "globals": "^16.1.0",
41
+ "hastscript": "^9.0.1",
42
+ "highlight.js": "^11.11.1",
43
+ "jsdom": "^26.1.0",
44
+ "mdsvex": "^0.12.6",
45
+ "mdsvexamples": "^0.5.0",
46
+ "prettier": "^3.5.3",
47
+ "prettier-plugin-svelte": "^3.4.0",
46
48
  "rehype-autolink-headings": "^7.1.0",
47
49
  "rehype-slug": "^6.0.0",
48
- "svelte-check": "^3.6.9",
49
- "svelte-multiselect": "^10.2.0",
50
- "svelte-preprocess": "^5.1.3",
51
- "svelte-toc": "^0.5.8",
52
- "svelte-zoo": "^0.4.10",
53
- "svelte2tsx": "^0.7.6",
54
- "typescript": "5.4.4",
55
- "typescript-eslint": "^7.5.0",
56
- "vite": "^5.1.5",
57
- "vitest": "^1.4.0"
50
+ "svelte": "^5.30.1",
51
+ "svelte-check": "^4.2.1",
52
+ "svelte-multiselect": "11.0.0-rc.1",
53
+ "svelte-preprocess": "^6.0.3",
54
+ "svelte-toc": "^0.6.0",
55
+ "svelte-zoo": "^0.4.18",
56
+ "svelte2tsx": "^0.7.39",
57
+ "typescript": "5.8.3",
58
+ "typescript-eslint": "^8.32.1",
59
+ "vite": "^6.3.5",
60
+ "vitest": "^3.1.3"
58
61
  },
59
62
  "keywords": [
60
63
  "svelte",
package/readme.md CHANGED
@@ -40,34 +40,6 @@
40
40
  | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | -------------------------------------------------------------------------------- |
41
41
  | ![Statements](https://img.shields.io/badge/statements-97.94%25-brightgreen.svg?style=flat) | ![Branches](https://img.shields.io/badge/branches-79.39%25-red.svg?style=flat) | ![Lines](https://img.shields.io/badge/lines-97.94%25-brightgreen.svg?style=flat) |
42
42
 
43
- ## 📜 &thinsp; Breaking changes
44
-
45
- - **8.0.0** (2022-10-22)&nbsp;
46
- - Props `selectedLabels` and `selectedValues` were removed. If you were using them, they were equivalent to assigning `bind:selected` to a local variable and then running `selectedLabels = selected.map(option => option.label)` and `selectedValues = selected.map(option => option.value)` if your options were objects with `label` and `value` keys. If they were simple strings/numbers, there was no point in using `selected{Labels,Values}` anyway. [PR 138](https://github.com/janosh/svelte-multiselect/pull/138)
47
- - Prop `noOptionsMsg` was renamed to `noMatchingOptionsMsg`. [PR 133](https://github.com/janosh/svelte-multiselect/pull/133).
48
- - **v8.3.0** (2023-01-25)&nbsp; `addOptionMsg` was renamed to `createOptionMsg` (no major since version since it's rarely used) [sha](https://github.com/janosh/svelte-multiselect/commits).
49
- - **v9.0.0** (2023-06-01)&nbsp; Svelte bumped from v3 to v4. Also, not breaking but noteworthy: MultiSelect received a default slot that functions as both `"option"` and `"selected"`. If you previously had two identical slots for `"option"` and `"selected"`, you can now remove the `name` from one of them and drop the other:
50
-
51
- ```diff
52
- <MultiSelect
53
- {options}
54
- + let:option
55
- >
56
- - <SlotComponent let:option {option} slot="selected" />
57
- - <SlotComponent let:option {option} slot="option" />
58
- + <SlotComponent {option} />
59
- </MultiSelect>
60
- ```
61
-
62
- - **v10.0.0** (2023-06-23)&nbsp; `duplicateFunc()` renamed to `key` in [#238](https://github.com/janosh/svelte-multiselect/pull/238). Signature changed:
63
-
64
- ```diff
65
- - duplicateFunc: (op1: T, op2: T) => boolean = (op1, op2) => `${get_label(op1)}`.toLowerCase() === `${get_label(op2)}`.toLowerCase()
66
- + key: (opt: T) => unknown = (opt) => `${get_label(opt)}`.toLowerCase()
67
- ```
68
-
69
- Rather than implementing custom equality in `duplicateFunc`, the `key` function is now expected to map options to a unique identifier. `key(op1) === key(op2)` should mean `op1` and `op2` are the same option. `key` can return any type but usually best to return primitives (`string`, `number`, ...) for Svelte keyed each blocks (see [#217](https://github.com/janosh/svelte-multiselect/pull/217)).
70
-
71
43
  ## 🔨 &thinsp; Installation
72
44
 
73
45
  ```sh
@@ -84,7 +56,7 @@ yarn add --dev svelte-multiselect
84
56
 
85
57
  const ui_libs = [`Svelte`, `React`, `Vue`, `Angular`, `...`]
86
58
 
87
- let selected = []
59
+ let selected = $state([])
88
60
  </script>
89
61
 
90
62
  Favorite Frontend Tools?
@@ -123,7 +95,7 @@ Full list of props/bindable variables for this component. The `Option` type you
123
95
  Whether to `console.error` if dropdown list of options is empty. `allowEmpty={false}` will suppress errors. `allowEmpty={true}` will report a console error if component is not `disabled`, not in `loading` state and doesn't `allowUserOptions`.
124
96
 
125
97
  1. ```ts
126
- allowUserOptions: boolean | 'append' = false
98
+ allowUserOptions: boolean | `append` = false
127
99
  ```
128
100
 
129
101
  Whether users can enter values that are not in the dropdown list. `true` means add user-defined options to the selected list only, `'append'` means add to both options and selected.
@@ -194,7 +166,7 @@ Full list of props/bindable variables for this component. The `Option` type you
194
166
  Customize how dropdown options are filtered when user enters search string into `<MultiSelect />`. Defaults to:
195
167
 
196
168
  1. ```ts
197
- closeDropdownOnSelect: boolean | 'desktop' = `desktop`
169
+ closeDropdownOnSelect: boolean | `desktop` = `desktop`
198
170
  ```
199
171
 
200
172
  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.
@@ -257,7 +229,7 @@ Full list of props/bindable variables for this component. The `Option` type you
257
229
  loading: boolean = false
258
230
  ```
259
231
 
260
- Whether the component should display a spinner to indicate it's in loading state. Use `<slot name='spinner'>` to specify a custom spinner.
232
+ Whether the component should display a spinner to indicate it's in loading state. Use `{#snippet spinner()} ... {/snippet}` to specify a custom spinner.
261
233
 
262
234
  1. ```ts
263
235
  matchingOptions: Option[] = []
@@ -334,7 +306,7 @@ Full list of props/bindable variables for this component. The `Option` type you
334
306
  parseLabelsAsHtml: boolean = false
335
307
  ```
336
308
 
337
- Whether option labels should be passed to [Svelte's `@html` directive](https://svelte.dev/tutorial/html-tags) or inserted into the DOM as plain text. `true` will raise an error if `allowUserOptions` is also truthy as it makes your site susceptible to [cross-site scripting (XSS) attacks](https://wikipedia.org/wiki/Cross-site_scripting).
309
+ Whether option labels should be passed to [Svelte's `@html` directive](https://svelte.dev/tutorial/svelte/html-tags) or inserted into the DOM as plain text. `true` will raise an error if `allowUserOptions` is also truthy as it makes your site susceptible to [cross-site scripting (XSS) attacks](https://wikipedia.org/wiki/Cross-site_scripting).
338
310
 
339
311
  1. ```ts
340
312
  pattern: string | null = null
@@ -423,35 +395,42 @@ Full list of props/bindable variables for this component. The `Option` type you
423
395
 
424
396
  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!
425
397
 
426
- ## 🎰 &thinsp; Slots
398
+ ## 🎰 &thinsp; Snippets
427
399
 
428
- `MultiSelect.svelte` accepts the following named slots:
400
+ `MultiSelect.svelte` accepts the following named snippets:
429
401
 
430
- 1. `slot="option"`: Customize rendering of dropdown options. Receives as props an `option` and the zero-indexed position (`idx`) it has in the dropdown.
431
- 1. `slot="selected"`: Customize rendering of selected items. Receives as props an `option` and the zero-indexed position (`idx`) it has in the list of selected items.
432
- 1. `slot="spinner"`: Custom spinner component to display when in `loading` state. Receives no props.
433
- 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.
434
- 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.
435
- 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.
436
- 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:
402
+ 1. `#snippet option({ option, idx })`: Customize rendering of dropdown options. Receives as props an `option` and the zero-indexed position (`idx`) it has in the dropdown.
403
+ 1. `#snippet selectedItem({ option, idx })`: Customize rendering of selected items. Receives as props an `option` and the zero-indexed position (`idx`) it has in the list of selected items.
404
+ 1. `#snippet spinner()`: Custom spinner component to display when in `loading` state. Receives no props.
405
+ 1. `#snippet disabledIcon()`: Custom icon to display inside the input when in `disabled` state. Receives no props. Use an empty `{#snippet disabledIcon()}{/snippet}` to remove the default disabled icon.
406
+ 1. `#snippet expandIcon()`: 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.
407
+ 1. `#snippet removeIcon()`: 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.
408
+ 1. `#snippet userMsg({ searchText, msgType, 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:
437
409
  - `searchText`: The text user typed into search input.
438
410
  - `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.
439
- - `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).
440
- 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.
411
+ - `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 snippet replaces the default UI for displaying these messages so the snippet needs to render them instead (unless purposely not showing a message).
412
+ 1. `snippet='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.
441
413
 
442
- Example using several slots:
414
+ Example using several snippets:
443
415
 
444
416
  ```svelte
445
- <MultiSelect options={[`Red`, `Green`, `Blue`, `Yellow`, `Purple`]} let:idx let:option>
446
- <!-- default slot overrides rendering of both dropdown-listed and selected options -->
447
- <span>
448
- {idx + 1}
449
- {option.label}
450
- <span style:background={option.label} style=" width: 1em; height: 1em;" />
451
- </span>
452
-
453
- <CustomSpinner slot="spinner">
454
- <strong slot="remove-icon">X</strong>
417
+ <MultiSelect options={[`Red`, `Green`, `Blue`, `Yellow`, `Purple`]}>
418
+ {#snippet children({ idx, option })}
419
+ <span style="display: flex; align-items: center; gap: 6pt;">
420
+ <span
421
+ style:background={`${option}`}
422
+ style="border-radius: 50%; width: 1em; height: 1em;"
423
+ ></span>
424
+ {idx + 1}
425
+ {option}
426
+ </span>
427
+ {/snippet}
428
+ {#snippet spinner()}
429
+ <CustomSpinner />
430
+ {/snippet}
431
+ {#snippet removeIcon()}
432
+ <strong>X</strong>
433
+ {/snippet}
455
434
  </MultiSelect>
456
435
  ```
457
436
 
@@ -460,37 +439,37 @@ Example using several slots:
460
439
  `MultiSelect.svelte` dispatches the following events:
461
440
 
462
441
  1. ```ts
463
- on:add={(event) => console.log(event.detail.option)}
442
+ onadd={(event) => console.log(event.detail.option)}
464
443
  ```
465
444
 
466
445
  Triggers when a new option is selected. The newly selected option is provided as `event.detail.option`.
467
446
 
468
447
  1. ```ts
469
- on:remove={(event) => console.log(event.detail.option)}`
448
+ onremove={(event) => console.log(event.detail.option)}`
470
449
  ```
471
450
 
472
451
  Triggers when a single selected option is removed. The removed option is provided as `event.detail.option`.
473
452
 
474
453
  1. ```ts
475
- on:removeAll={(event) => console.log(event.detail.options)}`
454
+ onremoveAll={(event) => console.log(event.detail.options)}`
476
455
  ```
477
456
 
478
457
  Triggers when all selected options are removed. The payload `event.detail.options` gives the options that were previously selected.
479
458
 
480
459
  1. ```ts
481
- on:change={(event) => console.log(`${event.detail.type}: '${event.detail.option}'`)}
460
+ onchange={(event) => console.log(`${event.detail.type}: '${event.detail.option}'`)}
482
461
  ```
483
462
 
484
463
  Triggers when an option is either added (selected) or removed from selected, or all selected options are removed at once. `type` is one of `'add' | 'remove' | 'removeAll'` and payload will be `option: Option` or `options: Option[]`, respectively.
485
464
 
486
465
  1. ```ts
487
- on:open={(event) => console.log(`Multiselect dropdown was opened by ${event}`)}
466
+ onopen={(event) => console.log(`Multiselect dropdown was opened by ${event}`)}
488
467
  ```
489
468
 
490
469
  Triggers when the dropdown list of options appears. Event is the DOM's `FocusEvent`,`KeyboardEvent` or `ClickEvent` that initiated this Svelte `dispatch` event.
491
470
 
492
471
  1. ```ts
493
- on:close={(event) => console.log(`Multiselect dropdown was closed by ${event}`)}
472
+ onclose={(event) => console.log(`Multiselect dropdown was closed by ${event}`)}
494
473
  ```
495
474
 
496
475
  Triggers when the dropdown list of options disappears. Event is the DOM's `FocusEvent`, `KeyboardEvent` or `ClickEvent` that initiated this Svelte `dispatch` event.
@@ -499,7 +478,7 @@ For example, here's how you might annoy your users with an alert every time one
499
478
 
500
479
  ```svelte
501
480
  <MultiSelect
502
- on:change={(e) => {
481
+ onchange={(e) => {
503
482
  if (e.detail.type === 'add') alert(`You added ${e.detail.option}`)
504
483
  if (e.detail.type === 'remove') alert(`You removed ${e.detail.option}`)
505
484
  if (e.detail.type === 'removeAll') alert(`You removed ${e.detail.options}`)
@@ -509,12 +488,12 @@ For example, here's how you might annoy your users with an alert every time one
509
488
 
510
489
  > Note: Depending on the data passed to the component the `options(s)` payload will either be objects or simple strings/numbers.
511
490
 
512
- The above list of events are [Svelte `dispatch` events](https://svelte.dev/tutorial/component-events). This component also forwards many DOM events from the `<input>` node: `blur`, `change`, `click`, `keydown`, `keyup`, `mousedown`, `mouseenter`, `mouseleave`, `touchcancel`, `touchend`, `touchmove`, `touchstart`. Registering listeners for these events works the same:
491
+ The above list of events are [Svelte `dispatch` events](https://svelte.dev/tutorial/svelte/component-events). This component also forwards many DOM events from the `<input>` node: `blur`, `change`, `click`, `keydown`, `keyup`, `mousedown`, `mouseenter`, `mouseleave`, `touchcancel`, `touchend`, `touchmove`, `touchstart`. Registering listeners for these events works the same:
513
492
 
514
493
  ```svelte
515
494
  <MultiSelect
516
495
  options={[1, 2, 3]}
517
- on:keyup={(event) => console.log('key', event.target.value)}
496
+ onkeyup={(event) => console.log('key', event.target.value)}
518
497
  />
519
498
  ```
520
499
 
@@ -534,7 +513,7 @@ const options = [42, 69]
534
513
  // type Option = number
535
514
  ```
536
515
 
537
- The inferred type of `Option` is used to enforce type-safety on derived props like `selected` as well as slot components. E.g. you'll get an error when trying to use a slot component that expects a string if your options are objects (see [this comment](https://github.com/janosh/svelte-multiselect/pull/189/files#r1058853697) for example screenshots).
516
+ The inferred type of `Option` is used to enforce type-safety on derived props like `selected` as well as snippets. E.g. you'll get an error when trying to use a snippet that expects a string if your options are objects (see [this comment](https://github.com/janosh/svelte-multiselect/pull/189/files#r1058853697) for example screenshots).
538
517
 
539
518
  You can also import [the types this component uses](https://github.com/janosh/svelte-multiselect/blob/main/src/lib/index.ts) for downstream applications:
540
519