svelte-multiselect 8.2.1 → 8.2.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.
@@ -55,8 +55,8 @@ export let searchText = ``;
55
55
  export let selected = options
56
56
  ?.filter((op) => op?.preselected)
57
57
  .slice(0, maxSelect ?? undefined) ?? [];
58
- export let selectedOptionsDraggable = true;
59
58
  export let sortSelected = false;
59
+ export let selectedOptionsDraggable = !sortSelected;
60
60
  export let ulOptionsClass = ``;
61
61
  export let ulSelectedClass = ``;
62
62
  export let value = null;
@@ -89,6 +89,9 @@ if (!Array.isArray(selected)) {
89
89
  if (maxSelect && typeof required === `number` && required > maxSelect) {
90
90
  console.error(`MultiSelect maxSelect=${maxSelect} < required=${required}, makes it impossible for users to submit a valid form`);
91
91
  }
92
+ if (sortSelected && selectedOptionsDraggable) {
93
+ console.warn(`MultiSelect's sortSelected and selectedOptionsDraggable should not be combined as any user re-orderings of selected options will be undone by sortSelected on component re-renders.`);
94
+ }
92
95
  const dispatch = createEventDispatcher();
93
96
  let add_option_msg_is_active = false; // controls active state of <li>{addOptionMsg}</li>
94
97
  let window_width;
@@ -359,7 +362,9 @@ const dragstart = (idx) => (event) => {
359
362
  form_input?.setCustomValidity(msg)
360
363
  }}
361
364
  />
362
- <ExpandIcon width="15px" style="min-width: 1em; padding: 0 1pt;" />
365
+ <slot name="expand-icon" {open}>
366
+ <ExpandIcon width="15px" style="min-width: 1em; padding: 0 1pt; cursor: pointer;" />
367
+ </slot>
363
368
  <ul class="selected {ulSelectedClass}">
364
369
  {#each selected as option, idx (get_label(option))}
365
370
  <li
@@ -394,39 +399,36 @@ const dragstart = (idx) => (event) => {
394
399
  {/if}
395
400
  </li>
396
401
  {/each}
397
- <li style="display: contents;">
398
- <input
399
- class={inputClass}
400
- bind:this={input}
401
- {autocomplete}
402
- bind:value={searchText}
403
- on:mouseup|self|stopPropagation={open_dropdown}
404
- on:keydown|stopPropagation={handle_keydown}
405
- on:focus
406
- on:focus={open_dropdown}
407
- {id}
408
- {disabled}
409
- {inputmode}
410
- {pattern}
411
- placeholder={selected.length == 0 ? placeholder : null}
412
- aria-invalid={invalid ? `true` : null}
413
- ondrop="return false"
414
- on:blur
415
- on:change
416
- on:click
417
- on:keydown
418
- on:keyup
419
- on:mousedown
420
- on:mouseenter
421
- on:mouseleave
422
- on:touchcancel
423
- on:touchend
424
- on:touchmove
425
- on:touchstart
426
- />
427
- <!-- the above on:* lines forward potentially useful DOM events -->
428
- </li>
429
402
  </ul>
403
+ <input
404
+ class={inputClass}
405
+ bind:this={input}
406
+ {autocomplete}
407
+ bind:value={searchText}
408
+ on:mouseup|self|stopPropagation={open_dropdown}
409
+ on:keydown|stopPropagation={handle_keydown}
410
+ on:focus
411
+ on:focus={open_dropdown}
412
+ {id}
413
+ {disabled}
414
+ {inputmode}
415
+ {pattern}
416
+ placeholder={selected.length == 0 ? placeholder : null}
417
+ aria-invalid={invalid ? `true` : null}
418
+ on:blur
419
+ on:change
420
+ on:click
421
+ on:keydown
422
+ on:keyup
423
+ on:mousedown
424
+ on:mouseenter
425
+ on:mouseleave
426
+ on:touchcancel
427
+ on:touchend
428
+ on:touchmove
429
+ on:touchstart
430
+ />
431
+ <!-- the above on:* lines forward potentially useful DOM events -->
430
432
  {#if loading}
431
433
  <slot name="spinner">
432
434
  <CircleSpinner />
@@ -536,8 +538,8 @@ const dragstart = (idx) => (event) => {
536
538
  border: var(--sms-border, 1pt solid lightgray);
537
539
  border-radius: var(--sms-border-radius, 3pt);
538
540
  background: var(--sms-bg);
539
- width: var(--sms-width);
540
- max-width: var(--sms-max-width);
541
+ width: var(--sms-width, 100%);
542
+ max-width: var(--sms-max-width, 800px);
541
543
  padding: var(--sms-padding, 0 3pt);
542
544
  color: var(--sms-text-color);
543
545
  font-size: var(--sms-font-size, inherit);
@@ -606,19 +608,23 @@ const dragstart = (idx) => (event) => {
606
608
  margin: auto 0; /* CSS reset */
607
609
  padding: 0; /* CSS reset */
608
610
  }
609
- :where(div.multiselect > ul.selected > li > input) {
611
+ :where(div.multiselect > ul.selected + input) {
610
612
  border: none;
611
613
  outline: none;
612
614
  background: none;
613
- flex: 1; /* this + next line fix issue #12 https://git.io/JiDe3 */
614
- min-width: 2em;
615
615
  /* ensure input uses text color and not --sms-selected-text-color */
616
616
  color: var(--sms-text-color);
617
617
  font-size: inherit;
618
618
  cursor: inherit; /* needed for disabled state */
619
619
  border-radius: 0; /* reset ul.selected > li */
620
+ width: 0;
621
+ visibility: hidden;
622
+ }
623
+ :where(div.multiselect:focus-within > ul.selected + input) {
624
+ visibility: visible;
625
+ width: 3em;
620
626
  }
621
- :where(div.multiselect > ul.selected > li > input::placeholder) {
627
+ :where(div.multiselect > ul.selected + input::placeholder) {
622
628
  padding-left: 5pt;
623
629
  color: var(--sms-placeholder-color);
624
630
  opacity: var(--sms-placeholder-opacity);
@@ -47,13 +47,16 @@ declare const __propDef: {
47
47
  resetFilterOnAdd?: boolean | undefined;
48
48
  searchText?: string | undefined;
49
49
  selected?: Option[] | undefined;
50
- selectedOptionsDraggable?: boolean | undefined;
51
50
  sortSelected?: boolean | ((op1: Option, op2: Option) => number) | undefined;
51
+ selectedOptionsDraggable?: boolean | undefined;
52
52
  ulOptionsClass?: string | undefined;
53
53
  ulSelectedClass?: string | undefined;
54
54
  value?: Option | Option[] | null | undefined;
55
55
  };
56
56
  slots: {
57
+ 'expand-icon': {
58
+ open: boolean;
59
+ };
57
60
  selected: {
58
61
  option: Option;
59
62
  idx: any;
@@ -66,7 +69,6 @@ declare const __propDef: {
66
69
  idx: any;
67
70
  };
68
71
  };
69
- getters: {};
70
72
  events: MultiSelectEvents;
71
73
  };
72
74
  export type MultiSelectProps = typeof __propDef.props;
package/changelog.md CHANGED
@@ -2,8 +2,19 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. Dates are displayed in UTC.
4
4
 
5
+ <!-- auto-changelog-above -->
6
+
7
+ #### [v8.2.2](https://github.com/janosh/svelte-multiselect/compare/v8.2.1...v8.2.2)
8
+
9
+ > 18 December 2022
10
+
11
+ - Issue console warning if `sortSelected && selectedOptionsDraggable` [`#187`](https://github.com/janosh/svelte-multiselect/pull/187)
12
+ - Add new slot named 'expand-icon' [`#186`](https://github.com/janosh/svelte-multiselect/pull/186)
13
+
5
14
  #### [v8.2.1](https://github.com/janosh/svelte-multiselect/compare/v8.2.0...v8.2.1)
6
15
 
16
+ > 10 December 2022
17
+
7
18
  - Fix `allowUserOptions` preventing dropdown list navigation with up/down arrow keys [`#184`](https://github.com/janosh/svelte-multiselect/pull/184)
8
19
  - Mdsvexamples [`#182`](https://github.com/janosh/svelte-multiselect/pull/182)
9
20
  - Add changelog & contributing pages to site [`#181`](https://github.com/janosh/svelte-multiselect/pull/181)
@@ -11,8 +22,6 @@ All notable changes to this project will be documented in this file. Dates are d
11
22
  - fix build error [`b896d36`](https://github.com/janosh/svelte-multiselect/commit/b896d3643a0988b0d0bed832ba46bcad0e2c4494)
12
23
  - fix readme badge for gh-pages.yml status [`906b560`](https://github.com/janosh/svelte-multiselect/commit/906b56024a826ed45263197b1267015d88f0a660)
13
24
 
14
- <!-- auto-changelog-above -->
15
-
16
25
  #### [v8.2.0](https://github.com/janosh/svelte-multiselect/compare/v8.1.0...v8.2.0)
17
26
 
18
27
  > 30 November 2022
@@ -2,7 +2,7 @@
2
2
  /** @typedef {typeof __propDef.events} ChevronExpandEvents */
3
3
  /** @typedef {typeof __propDef.slots} ChevronExpandSlots */
4
4
  export default class ChevronExpand extends SvelteComponentTyped<{
5
- [x: string]: any;
5
+ [x: string]: never;
6
6
  }, {
7
7
  [evt: string]: CustomEvent<any>;
8
8
  }, {}> {
@@ -13,7 +13,7 @@ export type ChevronExpandSlots = typeof __propDef.slots;
13
13
  import { SvelteComponentTyped } from "svelte";
14
14
  declare const __propDef: {
15
15
  props: {
16
- [x: string]: any;
16
+ [x: string]: never;
17
17
  };
18
18
  events: {
19
19
  [evt: string]: CustomEvent<any>;
@@ -2,7 +2,7 @@
2
2
  /** @typedef {typeof __propDef.events} CrossEvents */
3
3
  /** @typedef {typeof __propDef.slots} CrossSlots */
4
4
  export default class Cross extends SvelteComponentTyped<{
5
- [x: string]: any;
5
+ [x: string]: never;
6
6
  }, {
7
7
  [evt: string]: CustomEvent<any>;
8
8
  }, {}> {
@@ -13,7 +13,7 @@ export type CrossSlots = typeof __propDef.slots;
13
13
  import { SvelteComponentTyped } from "svelte";
14
14
  declare const __propDef: {
15
15
  props: {
16
- [x: string]: any;
16
+ [x: string]: never;
17
17
  };
18
18
  events: {
19
19
  [evt: string]: CustomEvent<any>;
@@ -2,7 +2,7 @@
2
2
  /** @typedef {typeof __propDef.events} DisabledEvents */
3
3
  /** @typedef {typeof __propDef.slots} DisabledSlots */
4
4
  export default class Disabled extends SvelteComponentTyped<{
5
- [x: string]: any;
5
+ [x: string]: never;
6
6
  }, {
7
7
  [evt: string]: CustomEvent<any>;
8
8
  }, {}> {
@@ -13,7 +13,7 @@ export type DisabledSlots = typeof __propDef.slots;
13
13
  import { SvelteComponentTyped } from "svelte";
14
14
  declare const __propDef: {
15
15
  props: {
16
- [x: string]: any;
16
+ [x: string]: never;
17
17
  };
18
18
  events: {
19
19
  [evt: string]: CustomEvent<any>;
@@ -2,7 +2,7 @@
2
2
  /** @typedef {typeof __propDef.events} OctocatEvents */
3
3
  /** @typedef {typeof __propDef.slots} OctocatSlots */
4
4
  export default class Octocat extends SvelteComponentTyped<{
5
- [x: string]: any;
5
+ [x: string]: never;
6
6
  }, {
7
7
  [evt: string]: CustomEvent<any>;
8
8
  }, {}> {
@@ -13,7 +13,7 @@ export type OctocatSlots = typeof __propDef.slots;
13
13
  import { SvelteComponentTyped } from "svelte";
14
14
  declare const __propDef: {
15
15
  props: {
16
- [x: string]: any;
16
+ [x: string]: never;
17
17
  };
18
18
  events: {
19
19
  [evt: string]: CustomEvent<any>;
package/package.json CHANGED
@@ -5,42 +5,42 @@
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.2.1",
8
+ "version": "8.2.2",
9
9
  "type": "module",
10
10
  "svelte": "index.js",
11
11
  "main": "index.js",
12
12
  "bugs": "https://github.com/janosh/svelte-multiselect/issues",
13
13
  "devDependencies": {
14
- "@iconify/svelte": "^3.0.0",
15
- "@playwright/test": "^1.28.0",
16
- "@sveltejs/adapter-static": "1.0.0-next.48",
17
- "@sveltejs/kit": "1.0.0-next.553",
18
- "@sveltejs/package": "1.0.0-next.6",
19
- "@sveltejs/vite-plugin-svelte": "^1.2.0",
20
- "@typescript-eslint/eslint-plugin": "^5.43.0",
21
- "@typescript-eslint/parser": "^5.43.0",
22
- "@vitest/coverage-c8": "^0.25.2",
23
- "eslint": "^8.28.0",
14
+ "@iconify/svelte": "^3.0.1",
15
+ "@playwright/test": "^1.29.0",
16
+ "@sveltejs/adapter-static": "1.0.0",
17
+ "@sveltejs/kit": "1.0.1",
18
+ "@sveltejs/package": "1.0.1",
19
+ "@sveltejs/vite-plugin-svelte": "^2.0.2",
20
+ "@typescript-eslint/eslint-plugin": "^5.46.1",
21
+ "@typescript-eslint/parser": "^5.46.1",
22
+ "@vitest/coverage-c8": "^0.25.8",
23
+ "eslint": "^8.30.0",
24
24
  "eslint-plugin-svelte3": "^4.0.0",
25
25
  "hastscript": "^7.1.0",
26
- "highlight.js": "^11.6.0",
27
- "jsdom": "^20.0.2",
26
+ "highlight.js": "^11.7.0",
27
+ "jsdom": "^20.0.3",
28
28
  "mdsvex": "^0.10.6",
29
- "mdsvexamples": "^0.3.2",
30
- "prettier": "^2.7.1",
31
- "prettier-plugin-svelte": "^2.8.1",
29
+ "mdsvexamples": "^0.3.3",
30
+ "prettier": "^2.8.1",
31
+ "prettier-plugin-svelte": "^2.9.0",
32
32
  "rehype-autolink-headings": "^6.1.1",
33
33
  "rehype-slug": "^5.1.0",
34
- "svelte": "^3.53.1",
35
- "svelte-check": "^2.9.2",
34
+ "svelte": "^3.55.0",
35
+ "svelte-check": "^2.10.2",
36
36
  "svelte-github-corner": "^0.1.0",
37
- "svelte-preprocess": "^4.10.7",
38
- "svelte-toc": "^0.4.1",
39
- "svelte2tsx": "^0.5.20",
37
+ "svelte-preprocess": "^5.0.0",
38
+ "svelte-toc": "^0.5.0",
39
+ "svelte2tsx": "^0.5.22",
40
40
  "tslib": "^2.4.1",
41
- "typescript": "^4.9.3",
42
- "vite": "^3.2.4",
43
- "vitest": "^0.25.2"
41
+ "typescript": "^4.9.4",
42
+ "vite": "^4.0.1",
43
+ "vitest": "^0.25.8"
44
44
  },
45
45
  "keywords": [
46
46
  "svelte",
package/readme.md CHANGED
@@ -327,16 +327,16 @@ Full list of props/bindable variables for this component. The `Option` type you
327
327
  Array of currently selected options. Supports 2-way binding `bind:selected={[1, 2, 3]}` to control component state externally. Can be passed as prop to set pre-selected options that will already be populated when component mounts before any user interaction.
328
328
 
329
329
  1. ```ts
330
- selectedOptionsDraggable: boolean = true
330
+ sortSelected: boolean | ((op1: Option, op2: Option) => number) = false
331
331
  ```
332
332
 
333
- Whether selected options are draggable so users can change their order.
333
+ Default behavior is to render selected items in the order they were chosen. `sortSelected={true}` uses default JS array sorting. A compare function enables custom logic for sorting selected options. See the [`/sort-selected`](https://janosh.github.io/svelte-multiselect/sort-selected) example.
334
334
 
335
335
  1. ```ts
336
- sortSelected: boolean | ((op1: Option, op2: Option) => number) = false
336
+ selectedOptionsDraggable: boolean = !sortSelected
337
337
  ```
338
338
 
339
- Default behavior is to render selected items in the order they were chosen. `sortSelected={true}` uses default JS array sorting. A compare function enables custom logic for sorting selected options. See the [`/sort-selected`](https://janosh.github.io/svelte-multiselect/sort-selected) example.
339
+ Whether selected options are draggable so users can change their order.
340
340
 
341
341
  1. ```ts
342
342
  value: Option | Option[] | null = null
@@ -346,13 +346,14 @@ Full list of props/bindable variables for this component. The `Option` type you
346
346
 
347
347
  ## 🎰 &nbsp; Slots
348
348
 
349
- `MultiSelect.svelte` has 3 named slots:
349
+ `MultiSelect.svelte` accepts the following named slots:
350
350
 
351
- - `slot="option"`: Customize rendering of dropdown options. Receives as props an `option` and the zero-indexed position (`idx`) it has in the dropdown.
352
- - `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.
353
- - `slot="spinner"`: Custom spinner component to display when in `loading` state. Receives no props.
354
- - `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.
355
- - `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.
351
+ 1. `slot="option"`: Customize rendering of dropdown options. Receives as props an `option` and the zero-indexed position (`idx`) it has in the dropdown.
352
+ 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.
353
+ 1. `slot="spinner"`: Custom spinner component to display when in `loading` state. Receives no props.
354
+ 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.
355
+ 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.
356
+ 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.
356
357
 
357
358
  Example:
358
359
 
@@ -484,8 +485,8 @@ If you only want to make small adjustments, you can pass the following CSS varia
484
485
  - `background: var(--sms-bg)`
485
486
  - `color: var(--sms-text-color)`
486
487
  - `min-height: var(--sms-min-height, 22pt)`
487
- - `width: var(--sms-width)`
488
- - `max-width: var(--sms-max-width)`
488
+ - `width: var(--sms-width, 100%)`
489
+ - `max-width: var(--sms-max-width, 800px)`
489
490
  - `margin: var(--sms-margin)`
490
491
  - `font-size: var(--sms-font-size, inherit)`
491
492
  - `div.multiselect.open`