svelte-multiselect 8.6.2 โ†’ 9.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.
@@ -2,26 +2,26 @@
2
2
  // https://github.com/sveltejs/eslint-plugin-svelte3/issues/201
3
3
  import { tick } from 'svelte';
4
4
  import { fade } from 'svelte/transition';
5
- import Select from '.';
5
+ import Select from './MultiSelect.svelte';
6
6
  export let actions;
7
- export let trigger = `k`;
7
+ export let triggers = [`k`];
8
+ export let close_keys = [`Escape`];
8
9
  export let fade_duration = 200; // in ms
9
10
  export let style = ``; // for dialog
10
- // for span in option slot, has no effect when passing slot="option"
11
+ // for span in option slot, has no effect when passing a slot
11
12
  export let span_style = ``;
12
13
  export let open = false;
13
14
  export let dialog = null;
14
15
  export let input = null;
15
16
  export let placeholder = `Filter actions...`;
16
17
  async function toggle(event) {
17
- if (event.key === trigger && event.metaKey && !open) {
18
+ if (triggers.includes(event.key) && event.metaKey && !open) {
18
19
  // open on cmd+trigger
19
20
  open = true;
20
21
  await tick(); // wait for dialog to open and input to be mounted
21
22
  input?.focus();
22
23
  }
23
- else if (event.key === `Escape` && open) {
24
- // close on escape
24
+ else if (close_keys.includes(event.key) && open) {
25
25
  open = false;
26
26
  }
27
27
  }
@@ -39,22 +39,18 @@ function run_and_close(event) {
39
39
  <svelte:window on:keydown={toggle} on:click={close_if_outside} />
40
40
 
41
41
  {#if open}
42
- <dialog
43
- class:open
44
- bind:this={dialog}
45
- transition:fade={{ duration: fade_duration }}
46
- {style}
47
- >
42
+ <dialog open bind:this={dialog} transition:fade={{ duration: fade_duration }} {style}>
48
43
  <Select
49
44
  options={actions}
50
45
  bind:input
51
46
  {placeholder}
52
47
  on:add={run_and_close}
53
48
  on:keydown={toggle}
54
- {...$$props}
49
+ {...$$restProps}
50
+ let:option
55
51
  >
56
52
  <!-- wait for https://github.com/sveltejs/svelte/pull/8304 -->
57
- <slot slot="option" name="option" let:option>
53
+ <slot>
58
54
  <span style={span_style}>{option.label}</span>
59
55
  </slot>
60
56
  </Select>
@@ -6,7 +6,8 @@ declare const __propDef: {
6
6
  label: string;
7
7
  action: () => void;
8
8
  }[];
9
- trigger?: string | undefined;
9
+ triggers?: string[] | undefined;
10
+ close_keys?: string[] | undefined;
10
11
  fade_duration?: number | undefined;
11
12
  style?: string | undefined;
12
13
  span_style?: string | undefined;
@@ -19,9 +20,7 @@ declare const __propDef: {
19
20
  [evt: string]: CustomEvent<any>;
20
21
  };
21
22
  slots: {
22
- option: {
23
- slot: string;
24
- };
23
+ default: {};
25
24
  };
26
25
  };
27
26
  export type CmdPaletteProps = typeof __propDef.props;
@@ -339,6 +339,7 @@ const dragstart = (idx) => (event) => {
339
339
  event.dataTransfer.setData(`text/plain`, `${idx}`);
340
340
  };
341
341
  let ul_options;
342
+ // highlight text matching user-entered search text in available options
342
343
  function highlight_matching_options(event) {
343
344
  if (!highlightMatches || typeof CSS == `undefined` || !CSS.highlights)
344
345
  return; // don't try if CSS highlight API not supported
@@ -404,6 +405,8 @@ function highlight_matching_options(event) {
404
405
  on:mouseup|stopPropagation={open_dropdown}
405
406
  title={disabled ? disabledInputTitle : null}
406
407
  data-id={id}
408
+ role="searchbox"
409
+ tabindex="-1"
407
410
  >
408
411
  <!-- bind:value={selected} prevents form submission if required prop is true and no options are selected -->
409
412
  <input
@@ -435,6 +438,8 @@ function highlight_matching_options(event) {
435
438
  {#each selected as option, idx (option)}
436
439
  <li
437
440
  class={liSelectedClass}
441
+ role="option"
442
+ aria-selected="true"
438
443
  animate:flip={{ duration: 100 }}
439
444
  draggable={selectedOptionsDraggable && !disabled && selected.length > 1}
440
445
  on:dragstart={dragstart(idx)}
@@ -445,10 +450,13 @@ function highlight_matching_options(event) {
445
450
  >
446
451
  <!-- on:dragover|preventDefault needed for the drop to succeed https://stackoverflow.com/a/31085796 -->
447
452
  <slot name="selected" {option} {idx}>
448
- {#if parseLabelsAsHtml}
449
- {@html get_label(option)}
450
- {:else}
451
- {get_label(option)}{/if}
453
+ <slot {option} {idx}>
454
+ {#if parseLabelsAsHtml}
455
+ {@html get_label(option)}
456
+ {:else}
457
+ {get_label(option)}
458
+ {/if}
459
+ </slot>
452
460
  </slot>
453
461
  {#if !disabled && (minSelect === null || selected.length > minSelect)}
454
462
  <button
@@ -531,7 +539,15 @@ function highlight_matching_options(event) {
531
539
 
532
540
  <!-- only render options dropdown if options or searchText is not empty needed to avoid briefly flashing empty dropdown -->
533
541
  {#if (searchText && noMatchingOptionsMsg) || options?.length > 0}
534
- <ul class:hidden={!open} class="options {ulOptionsClass}" bind:this={ul_options}>
542
+ <ul
543
+ class:hidden={!open}
544
+ class="options {ulOptionsClass}"
545
+ role="listbox"
546
+ aria-multiselectable={maxSelect === null || maxSelect > 1}
547
+ aria-expanded={open}
548
+ aria-disabled={disabled ? `true` : null}
549
+ bind:this={ul_options}
550
+ >
535
551
  {#each matchingOptions as option, idx}
536
552
  {@const {
537
553
  label,
@@ -561,13 +577,17 @@ function highlight_matching_options(event) {
561
577
  }}
562
578
  on:mouseout={() => (activeIndex = null)}
563
579
  on:blur={() => (activeIndex = null)}
580
+ role="option"
581
+ aria-selected="false"
564
582
  >
565
583
  <slot name="option" {option} {idx}>
566
- {#if parseLabelsAsHtml}
567
- {@html get_label(option)}
568
- {:else}
569
- {get_label(option)}
570
- {/if}
584
+ <slot {option} {idx}>
585
+ {#if parseLabelsAsHtml}
586
+ {@html get_label(option)}
587
+ {:else}
588
+ {get_label(option)}
589
+ {/if}
590
+ </slot>
571
591
  </slot>
572
592
  </li>
573
593
  {:else}
@@ -586,6 +606,8 @@ function highlight_matching_options(event) {
586
606
  on:focus={() => (option_msg_is_active = true)}
587
607
  on:mouseout={() => (option_msg_is_active = false)}
588
608
  on:blur={() => (option_msg_is_active = false)}
609
+ role="option"
610
+ aria-selected="false"
589
611
  class="user-msg"
590
612
  >
591
613
  {msg}
@@ -65,6 +65,10 @@ declare class __sveltets_Render<Option extends T> {
65
65
  option: Option;
66
66
  idx: any;
67
67
  };
68
+ default: {
69
+ option: Option;
70
+ idx: any;
71
+ };
68
72
  'remove-icon': {};
69
73
  spinner: {};
70
74
  'disabled-icon': {};
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.2",
8
+ "version": "9.0.0",
9
9
  "type": "module",
10
10
  "svelte": "./dist/index.js",
11
11
  "bugs": "https://github.com/janosh/svelte-multiselect/issues",
@@ -19,23 +19,23 @@
19
19
  "test": "vitest --run --coverage tests/unit/*.ts && playwright test tests/*.test.ts",
20
20
  "test:unit": "vitest tests/unit/*.ts",
21
21
  "test:e2e": "playwright test tests/*.test.ts",
22
- "changelog": "npx auto-changelog --package --output changelog.md --unreleased-only --hide-credit --commit-limit false",
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
25
  "dependencies": {
26
- "svelte": "^3.59.1"
26
+ "svelte": "^4.0.0-next.0"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@iconify/svelte": "^3.1.3",
30
- "@playwright/test": "^1.33.0",
30
+ "@playwright/test": "^1.34.3",
31
31
  "@sveltejs/adapter-static": "^2.0.2",
32
- "@sveltejs/kit": "^1.16.3",
32
+ "@sveltejs/kit": "^1.19.0",
33
33
  "@sveltejs/package": "2.0.2",
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",
34
+ "@sveltejs/vite-plugin-svelte": "1.0.0-next.29",
35
+ "@typescript-eslint/eslint-plugin": "^5.59.7",
36
+ "@typescript-eslint/parser": "^5.59.7",
37
+ "@vitest/coverage-c8": "^0.31.1",
38
+ "eslint": "^8.41.0",
39
39
  "eslint-plugin-svelte3": "^4.0.0",
40
40
  "hastscript": "^7.2.0",
41
41
  "highlight.js": "^11.8.0",
@@ -46,14 +46,14 @@
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.3.2",
49
+ "svelte-check": "^3.4.2",
50
50
  "svelte-preprocess": "^5.0.3",
51
51
  "svelte-toc": "^0.5.5",
52
- "svelte-zoo": "^0.4.5",
53
- "svelte2tsx": "^0.6.14",
52
+ "svelte-zoo": "^0.4.6",
53
+ "svelte2tsx": "^0.6.15",
54
54
  "typescript": "5.0.4",
55
- "vite": "^4.3.6",
56
- "vitest": "^0.31.0"
55
+ "vite": "^4.3.9",
56
+ "vitest": "^0.31.1"
57
57
  },
58
58
  "keywords": [
59
59
  "svelte",
package/readme.md CHANGED
@@ -36,16 +36,28 @@
36
36
 
37
37
  ## ๐Ÿงช &thinsp; Coverage
38
38
 
39
- | Statements | Branches | Lines |
40
- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------- |
41
- | ![Statements](https://img.shields.io/badge/statements-92.95%25-brightgreen.svg?style=flat) | ![Branches](https://img.shields.io/badge/branches-100%25-brightgreen.svg?style=flat) | ![Lines](https://img.shields.io/badge/lines-92.95%25-brightgreen.svg?style=flat) |
39
+ | Statements | Branches | Lines |
40
+ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | -------------------------------------------------------------------------------- |
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
43
  ## ๐Ÿ“œ &thinsp; Breaking changes
44
44
 
45
- - **8.0.0**&nbsp;
45
+ - **8.0.0** (2022-10-22)&nbsp;
46
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
47
  - Prop `noOptionsMsg` was renamed to `noMatchingOptionsMsg`. [PR 133](https://github.com/janosh/svelte-multiselect/pull/133).
48
- - **v8.3.0**&nbsp; `addOptionMsg` was renamed to `createOptionMsg` (no major since version since it's rarely used) [sha](https://github.com/janosh/svelte-multiselect/commits).
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
+ ```
49
61
 
50
62
  ## ๐Ÿ”จ &thinsp; Installation
51
63
 
@@ -189,7 +201,7 @@ Full list of props/bindable variables for this component. The `Option` type you
189
201
  highlightMatches: boolean = true
190
202
  ```
191
203
 
192
- Whether to highlight text in the dropdown options that matches the current user-entered search query. Uses the [CSS Custom Highlight API](https://developer.mozilla.org/docs/Web/API/CSS_Custom_Highlight_API) with limited browser support and [styling options](https://developer.mozilla.org/docs/Web/CSS/::highlight). See `::highlight(sms-search-matches)` below for available CSS variables.
204
+ Whether to highlight text in the dropdown options that matches the current user-entered search query. Uses the [CSS Custom Highlight API](https://developer.mozilla.org/docs/Web/API/CSS_Custom_Highlight_API) with [limited browser support](https://caniuse.com/mdn-api_css_highlights) (70% as of May 2023) and [styling options](https://developer.mozilla.org/docs/Web/CSS/::highlight). See `::highlight(sms-search-matches)` below for available CSS variables.
193
205
 
194
206
  1. ```ts
195
207
  id: string | null = null
@@ -375,14 +387,9 @@ Full list of props/bindable variables for this component. The `Option` type you
375
387
  Example:
376
388
 
377
389
  ```svelte
378
- <MultiSelect options={[`Red`, `Green`, `Blue`, `Yellow`, `Purple`]}>
379
- <span let:idx let:option slot="option">
380
- {idx + 1}
381
- {option.label}
382
- <span style:background={option.label} style=" width: 1em; height: 1em;" />
383
- </span>
384
-
385
- <span let:idx let:option slot="selected">
390
+ <MultiSelect options={[`Red`, `Green`, `Blue`, `Yellow`, `Purple`]} let:idx let:option>
391
+ <!-- default slot overrides rendering of both dropdown-listed and selected options -->
392
+ <span>
386
393
  {idx + 1}
387
394
  {option.label}
388
395
  <span style:background={option.label} style=" width: 1em; height: 1em;" />