svelte-multiselect 8.4.0 → 8.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.
@@ -1,12 +1,18 @@
1
- <script>import { tick } from 'svelte/internal';
1
+ <script>/* eslint-disable no-undef */ // TODO: remove when fixed
2
+ // https://github.com/sveltejs/eslint-plugin-svelte3/issues/201
3
+ import { tick } from 'svelte';
2
4
  import { fade } from 'svelte/transition';
3
5
  import Select from '.';
4
6
  export let actions;
5
7
  export let trigger = `k`;
6
8
  export let fade_duration = 200; // in ms
7
- let open = false;
8
- let dialog;
9
- let input;
9
+ export let style = ``; // for dialog
10
+ // for span in option slot, has no effect when passing slot="option"
11
+ export let span_style = ``;
12
+ export let open = false;
13
+ export let dialog;
14
+ export let input;
15
+ export let placeholder = `Filter actions...`;
10
16
  async function toggle(event) {
11
17
  if (event.key === trigger && event.metaKey && !open) {
12
18
  // open on cmd+trigger
@@ -24,7 +30,7 @@ function close_if_outside(event) {
24
30
  open = false;
25
31
  }
26
32
  }
27
- function move(event) {
33
+ function run_and_close(event) {
28
34
  event.detail.option.action();
29
35
  open = false;
30
36
  }
@@ -33,14 +39,25 @@ function move(event) {
33
39
  <svelte:window on:keydown={toggle} on:click={close_if_outside} />
34
40
 
35
41
  {#if open}
36
- <dialog class:open bind:this={dialog} transition:fade={{ duration: fade_duration }}>
42
+ <dialog
43
+ class:open
44
+ bind:this={dialog}
45
+ transition:fade={{ duration: fade_duration }}
46
+ {style}
47
+ >
37
48
  <Select
38
49
  options={actions}
39
50
  bind:input
40
- placeholder="Go to..."
41
- on:add={move}
51
+ {placeholder}
52
+ on:add={run_and_close}
42
53
  on:keydown={toggle}
43
- />
54
+ {...$$props}
55
+ >
56
+ <!-- wait for https://github.com/sveltejs/svelte/pull/8304 -->
57
+ <slot slot="option" name="option" let:option>
58
+ <span style={span_style}>{option.label}</span>
59
+ </slot>
60
+ </Select>
44
61
  </dialog>
45
62
  {/if}
46
63
 
@@ -1,17 +1,28 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
2
  declare const __propDef: {
3
3
  props: {
4
+ [x: string]: any;
4
5
  actions: {
5
6
  label: string;
6
7
  action: () => void;
7
8
  }[];
8
9
  trigger?: string | undefined;
9
10
  fade_duration?: number | undefined;
11
+ style?: string | undefined;
12
+ span_style?: string | undefined;
13
+ open?: boolean | undefined;
14
+ dialog: HTMLDialogElement;
15
+ input: HTMLInputElement;
16
+ placeholder?: string | undefined;
10
17
  };
11
18
  events: {
12
19
  [evt: string]: CustomEvent<any>;
13
20
  };
14
- slots: {};
21
+ slots: {
22
+ option: {
23
+ slot: string;
24
+ };
25
+ };
15
26
  };
16
27
  export type CmdPaletteProps = typeof __propDef.props;
17
28
  export type CmdPaletteEvents = typeof __propDef.events;
@@ -287,10 +287,10 @@ async function handle_keydown(event) {
287
287
  }
288
288
  }
289
289
  function remove_all() {
290
- dispatch(`removeAll`, { options: selected });
291
- dispatch(`change`, { options: selected, type: `removeAll` });
292
290
  selected = [];
293
291
  searchText = ``;
292
+ dispatch(`removeAll`, { options: selected });
293
+ dispatch(`change`, { options: selected, type: `removeAll` });
294
294
  }
295
295
  $: is_selected = (label) => selected.map(get_label).includes(label);
296
296
  const if_enter_or_space = (handler) => (event) => {
@@ -344,13 +344,10 @@ const dragstart = (idx) => (event) => {
344
344
  class:disabled
345
345
  class:single={maxSelect === 1}
346
346
  class:open
347
- aria-expanded={open}
348
- aria-multiselectable={maxSelect === null || maxSelect > 1}
349
347
  class:invalid
350
348
  class="multiselect {outerDivClass}"
351
349
  on:mouseup|stopPropagation={open_dropdown}
352
350
  title={disabled ? disabledInputTitle : null}
353
- aria-disabled={disabled ? `true` : null}
354
351
  data-id={id}
355
352
  >
356
353
  <!-- bind:value={selected} prevents form submission if required prop is true and no options are selected -->
@@ -379,10 +376,16 @@ const dragstart = (idx) => (event) => {
379
376
  <slot name="expand-icon" {open}>
380
377
  <ExpandIcon width="15px" style="min-width: 1em; padding: 0 1pt; cursor: pointer;" />
381
378
  </slot>
382
- <ul class="selected {ulSelectedClass}">
379
+ <ul
380
+ class="selected {ulSelectedClass}"
381
+ role="listbox"
382
+ aria-multiselectable={maxSelect === null || maxSelect > 1}
383
+ aria-label="selected options"
384
+ >
383
385
  {#each selected as option, idx (get_label(option))}
384
386
  <li
385
387
  class={liSelectedClass}
388
+ role="option"
386
389
  aria-selected="true"
387
390
  animate:flip={{ duration: 100 }}
388
391
  draggable={selectedOptionsDraggable && !disabled && selected.length > 1}
@@ -397,8 +400,7 @@ const dragstart = (idx) => (event) => {
397
400
  {#if parseLabelsAsHtml}
398
401
  {@html get_label(option)}
399
402
  {:else}
400
- {get_label(option)}
401
- {/if}
403
+ {get_label(option)}{/if}
402
404
  </slot>
403
405
  {#if !disabled && (minSelect === null || selected.length > minSelect)}
404
406
  <button
@@ -415,38 +417,36 @@ const dragstart = (idx) => (event) => {
415
417
  {/if}
416
418
  </li>
417
419
  {/each}
418
- <li style="display: contents;">
419
- <input
420
- class={inputClass}
421
- bind:this={input}
422
- bind:value={searchText}
423
- on:mouseup|self|stopPropagation={open_dropdown}
424
- on:keydown|stopPropagation={handle_keydown}
425
- on:focus
426
- on:focus={open_dropdown}
427
- {id}
428
- {disabled}
429
- {autocomplete}
430
- {inputmode}
431
- {pattern}
432
- placeholder={selected.length == 0 ? placeholder : null}
433
- aria-invalid={invalid ? `true` : null}
434
- ondrop="return false"
435
- on:blur
436
- on:change
437
- on:click
438
- on:keydown
439
- on:keyup
440
- on:mousedown
441
- on:mouseenter
442
- on:mouseleave
443
- on:touchcancel
444
- on:touchend
445
- on:touchmove
446
- on:touchstart
447
- />
448
- <!-- the above on:* lines forward potentially useful DOM events -->
449
- </li>
420
+ <input
421
+ class={inputClass}
422
+ bind:this={input}
423
+ bind:value={searchText}
424
+ on:mouseup|self|stopPropagation={open_dropdown}
425
+ on:keydown|stopPropagation={handle_keydown}
426
+ on:focus
427
+ on:focus={open_dropdown}
428
+ {id}
429
+ {disabled}
430
+ {autocomplete}
431
+ {inputmode}
432
+ {pattern}
433
+ placeholder={selected.length == 0 ? placeholder : null}
434
+ aria-invalid={invalid ? `true` : null}
435
+ ondrop="return false"
436
+ on:blur
437
+ on:change
438
+ on:click
439
+ on:keydown
440
+ on:keyup
441
+ on:mousedown
442
+ on:mouseenter
443
+ on:mouseleave
444
+ on:touchcancel
445
+ on:touchend
446
+ on:touchmove
447
+ on:touchstart
448
+ />
449
+ <!-- the above on:* lines forward potentially useful DOM events -->
450
450
  </ul>
451
451
  {#if loading}
452
452
  <slot name="spinner">
@@ -482,7 +482,14 @@ const dragstart = (idx) => (event) => {
482
482
 
483
483
  <!-- only render options dropdown if options or searchText is not empty needed to avoid briefly flashing empty dropdown -->
484
484
  {#if (searchText && noMatchingOptionsMsg) || options?.length > 0}
485
- <ul class:hidden={!open} class="options {ulOptionsClass}">
485
+ <ul
486
+ class:hidden={!open}
487
+ class="options {ulOptionsClass}"
488
+ role="listbox"
489
+ aria-multiselectable={maxSelect === null || maxSelect > 1}
490
+ aria-expanded={open}
491
+ aria-disabled={disabled ? `true` : null}
492
+ >
486
493
  {#each matchingOptions as option, idx}
487
494
  {@const {
488
495
  label,
@@ -512,6 +519,7 @@ const dragstart = (idx) => (event) => {
512
519
  }}
513
520
  on:mouseout={() => (activeIndex = null)}
514
521
  on:blur={() => (activeIndex = null)}
522
+ role="option"
515
523
  aria-selected="false"
516
524
  >
517
525
  <slot name="option" {option} {idx}>
@@ -627,7 +635,7 @@ const dragstart = (idx) => (event) => {
627
635
  margin: auto 0; /* CSS reset */
628
636
  padding: 0; /* CSS reset */
629
637
  }
630
- :where(div.multiselect > ul.selected > li > input) {
638
+ :where(div.multiselect > ul.selected > input) {
631
639
  border: none;
632
640
  outline: none;
633
641
  background: none;
@@ -640,7 +648,7 @@ const dragstart = (idx) => (event) => {
640
648
  border-radius: 0; /* reset ul.selected > li */
641
649
  }
642
650
  /* don't wrap ::placeholder rules in :where() as it seems to be overpowered by browser defaults i.t.o. specificity */
643
- div.multiselect > ul.selected > li > input::placeholder {
651
+ div.multiselect > ul.selected > input::placeholder {
644
652
  padding-left: 5pt;
645
653
  color: var(--sms-placeholder-color);
646
654
  opacity: var(--sms-placeholder-opacity);
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.4.0",
8
+ "version": "8.5.0",
9
9
  "type": "module",
10
10
  "svelte": "./dist/index.js",
11
11
  "bugs": "https://github.com/janosh/svelte-multiselect/issues",
@@ -23,17 +23,17 @@
23
23
  "update-coverage": "vitest tests/unit --run --coverage && npx istanbul-badges-readme"
24
24
  },
25
25
  "dependencies": {
26
- "svelte": "^3.55.1"
26
+ "svelte": "^3.56.0"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@iconify/svelte": "^3.1.0",
30
- "@playwright/test": "^1.31.1",
30
+ "@playwright/test": "^1.31.2",
31
31
  "@sveltejs/adapter-static": "^2.0.1",
32
- "@sveltejs/kit": "^1.9.2",
32
+ "@sveltejs/kit": "^1.11.0",
33
33
  "@sveltejs/package": "2.0.2",
34
34
  "@sveltejs/vite-plugin-svelte": "^2.0.3",
35
- "@typescript-eslint/eslint-plugin": "^5.54.0",
36
- "@typescript-eslint/parser": "^5.54.0",
35
+ "@typescript-eslint/eslint-plugin": "^5.54.1",
36
+ "@typescript-eslint/parser": "^5.54.1",
37
37
  "@vitest/coverage-c8": "^0.29.2",
38
38
  "eslint": "^8.35.0",
39
39
  "eslint-plugin-svelte3": "^4.0.0",
@@ -46,11 +46,11 @@
46
46
  "prettier-plugin-svelte": "^2.9.0",
47
47
  "rehype-autolink-headings": "^6.1.1",
48
48
  "rehype-slug": "^5.1.0",
49
- "svelte-check": "^3.0.4",
49
+ "svelte-check": "^3.1.0",
50
50
  "svelte-preprocess": "^5.0.1",
51
51
  "svelte-toc": "^0.5.2",
52
52
  "svelte-zoo": "^0.3.4",
53
- "svelte2tsx": "^0.6.2",
53
+ "svelte2tsx": "^0.6.3",
54
54
  "typescript": "^4.9.5",
55
55
  "vite": "^4.1.4",
56
56
  "vitest": "^0.29.2"
package/readme.md CHANGED
@@ -8,7 +8,7 @@
8
8
  [![Tests](https://github.com/janosh/svelte-multiselect/actions/workflows/test.yml/badge.svg)](https://github.com/janosh/svelte-multiselect/actions/workflows/test.yml)
9
9
  [![GitHub Pages](https://github.com/janosh/svelte-multiselect/actions/workflows/gh-pages.yml/badge.svg)](https://github.com/janosh/svelte-multiselect/actions/workflows/gh-pages.yml)
10
10
  [![NPM version](https://img.shields.io/npm/v/svelte-multiselect?logo=NPM&color=purple)](https://npmjs.com/package/svelte-multiselect)
11
- [![Needs Svelte version](https://img.shields.io/npm/dependency-version/svelte-multiselect/dev/svelte?color=teal&logo=Svelte&label=Svelte)](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md)
11
+ [![Needs Svelte version](https://img.shields.io/npm/dependency-version/svelte-multiselect/svelte?color=teal&logo=Svelte&label=Svelte)](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md)
12
12
  [![REPL](https://img.shields.io/badge/Svelte-REPL-blue?label=Try%20it!)](https://svelte.dev/repl/a5a14b8f15d64cb083b567292480db05)
13
13
  [![Open in StackBlitz](https://img.shields.io/badge/Open%20in-StackBlitz-darkblue?logo=stackblitz)](https://stackblitz.com/github/janosh/svelte-multiselect)
14
14
 
@@ -611,7 +611,7 @@ Odd as it may seem, you get the most fine-grained control over the styling of ev
611
611
  :global(div.multiselect > ul.selected > li button, button.remove-all) {
612
612
  /* buttons to remove a single or all selected options at once */
613
613
  }
614
- :global(div.multiselect > ul.selected > li > input) {
614
+ :global(div.multiselect > input[autocomplete]) {
615
615
  /* input inside the top-level wrapper div */
616
616
  }
617
617
  :global(div.multiselect > ul.options) {