Launch Week Day 5: Introducing Reachability for PHP.Learn More
Socket
Book a DemoSign in
Socket

svelte-multiselect

Package Overview
Dependencies
Maintainers
1
Versions
95
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

svelte-multiselect - npm Package Compare versions

Comparing version
3.2.1
to
3.2.2
+29
-29
MultiSelect.svelte

@@ -19,2 +19,7 @@ <script >import { createEventDispatcher, onMount } from 'svelte';

export let activeOption = null;
export let filterFunc = (op, searchText) => {
if (!searchText)
return true;
return `${op.label}`.toLowerCase().includes(searchText.toLowerCase());
};
export let outerDivClass = ``;

@@ -70,7 +75,3 @@ export let ulSelectedClass = ``;

// options matching the current search text
$: matchingOptions = _options.filter((op) => {
if (!searchText)
return true;
return `${op.label}`.toLowerCase().includes(searchText.toLowerCase());
});
$: matchingOptions = _options.filter((op) => filterFunc(op, searchText));
$: matchingEnabledOptions = matchingOptions.filter((op) => !op.disabled);

@@ -299,6 +300,2 @@ $: if (

margin: 1em 0;
border: var(--sms-border, 1pt solid lightgray);
border-radius: var(--sms-border-radius, 5pt);
background: var(--sms-input-bg);
height: var(--sms-input-height, 2em);
align-items: center;

@@ -309,2 +306,6 @@ min-height: 18pt;

padding: 0 3pt;
border: var(--sms-border, 1pt solid lightgray);
border-radius: var(--sms-border-radius, 5pt);
background: var(--sms-input-bg);
height: var(--sms-input-height, 2em);
}

@@ -321,3 +322,3 @@ :where(div.multiselect.open) {

:where(ul.selected) {
:where(div.multiselect > ul.selected) {
display: flex;

@@ -328,4 +329,3 @@ padding: 0;

}
:where(ul.selected > li) {
background: var(--sms-selected-bg, var(--sms-active-color, cornflowerblue));
:where(div.multiselect > ul.selected > li) {
align-items: center;

@@ -335,8 +335,9 @@ border-radius: 4pt;

margin: 2pt;
padding: 0 0 0 1ex;
padding: 0 0 0 5pt;
transition: 0.3s;
white-space: nowrap;
height: 16pt;
background: var(--sms-selected-bg, var(--sms-active-color, cornflowerblue));
height: var(--sms-selected-li-height);
}
:where(ul.selected > li button, button.remove-all) {
:where(div.multiselect > ul.selected > li button, button.remove-all) {
align-items: center;

@@ -348,3 +349,3 @@ border-radius: 50%;

}
:where(button) {
:where(div.multiselect button) {
color: inherit;

@@ -360,3 +361,3 @@ background: transparent;

}
:where(button:focus) {
:where(div.multiselect > button:focus) {
transform: scale(1.04);

@@ -369,3 +370,2 @@ }

background: none;
color: var(--sms-text-color, inherit);
flex: 1; /* this + next line fix issue #12 https://git.io/JiDe3 */

@@ -376,5 +376,6 @@ min-width: 2em;

font-size: calc(16px + 0.1vw);
color: var(--sms-text-color, inherit);
}
:where(ul.options) {
:where(div.multiselect > ul.options) {
list-style: none;

@@ -391,6 +392,6 @@ max-height: 50vh;

}
:where(ul.options.hidden) {
:where(div.multiselect > ul.options.hidden) {
visibility: hidden;
}
:where(ul.options li) {
:where(div.multiselect > ul.options > li) {
padding: 3pt 2ex;

@@ -400,6 +401,6 @@ cursor: pointer;

/* for noOptionsMsg */
:where(ul.options span) {
:where(div.multiselect > ul.options span) {
padding: 3pt 2ex;
}
:where(ul.options li.selected) {
:where(div.multiselect > ul.options > li.selected) {
border-left: var(

@@ -412,3 +413,3 @@ --sms-li-selected-border-left,

}
:where(ul.options li:not(.selected):hover) {
:where(div.multiselect > ul.options > li:not(.selected):hover) {
border-left: var(

@@ -418,15 +419,14 @@ --sms-li-not-selected-hover-border-left,

);
border-left: 3pt solid var(--blue);
}
:where(ul.options li.active) {
:where(div.multiselect > ul.options > li.active) {
background: var(--sms-li-active-bg, var(--sms-active-color, cornflowerblue));
}
:where(ul.options li.disabled) {
:where(div.multiselect > ul.options > li.disabled) {
cursor: not-allowed;
background: var(--sms-li-disabled-bg, #f5f5f6);
color: var(--sms-li-disabled-text, #b8b8b8);
cursor: not-allowed;
}
:where(ul.options li.disabled:hover) {
:where(div.multiselect > ul.options > li.disabled:hover) {
border-left: unset;
}
</style>

@@ -18,2 +18,3 @@ import { SvelteComponentTyped } from "svelte";

activeOption?: Option | null | undefined;
filterFunc?: ((op: Option, searchText: string) => boolean) | undefined;
outerDivClass?: string | undefined;

@@ -20,0 +21,0 @@ ulSelectedClass?: string | undefined;

@@ -8,3 +8,3 @@ {

"license": "MIT",
"version": "3.2.1",
"version": "3.2.2",
"type": "module",

@@ -14,7 +14,7 @@ "svelte": "index.js",

"devDependencies": {
"@sveltejs/adapter-static": "^1.0.0-next.26",
"@sveltejs/kit": "^1.0.0-next.259",
"@typescript-eslint/eslint-plugin": "^5.10.2",
"@typescript-eslint/parser": "^5.10.2",
"eslint": "^8.8.0",
"@sveltejs/adapter-static": "^1.0.0-next.28",
"@sveltejs/kit": "^1.0.0-next.269",
"@typescript-eslint/eslint-plugin": "^5.12.0",
"@typescript-eslint/parser": "^5.12.0",
"eslint": "^8.9.0",
"eslint-plugin-svelte3": "^3.4.0",

@@ -27,11 +27,11 @@ "hastscript": "^7.0.2",

"rehype-slug": "^5.0.1",
"svelte": "^3.46.3",
"svelte-check": "^2.4.2",
"svelte": "^3.46.4",
"svelte-check": "^2.4.3",
"svelte-github-corner": "^0.1.0",
"svelte-preprocess": "^4.10.2",
"svelte-toc": "^0.2.3",
"svelte2tsx": "^0.5.2",
"svelte-preprocess": "^4.10.3",
"svelte-toc": "^0.2.5",
"svelte2tsx": "^0.5.3",
"tslib": "^2.3.1",
"typescript": "^4.5.5",
"vite": "^2.7.13"
"vite": "^2.8.2"
},

@@ -38,0 +38,0 @@ "keywords": [

+78
-49

@@ -25,3 +25,3 @@ <h1 align="center">

## Key Features
## Key features

@@ -92,19 +92,35 @@ - **Single / multiple select:** pass `maxSelect={1}` prop to only allow one selection

<!-- prettier-ignore -->
| name | default | description |
| :--------------- | :--------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `options` | required prop | Array of strings/numbers or `Option` objects that will be listed in the dropdown. See `src/lib/index.ts` for admissible fields. The `label` is the only mandatory one. It must also be unique. |
| `activeOption` | `null` | Currently active option, i.e. the one the user currently hovers or navigated to with arrow keys. |
| `maxSelect` | `null` | Positive integer to limit the number of options users can pick. `null` means no limit. |
| `maxSelectMsg` | ``(current: number, max: number) => `${current}/${max}` `` | Function that returns a string informing the user how many of the maximum allowed options they have currently selected. Return empty string to disable, i.e. `() => ''`. |
| `selected` | `[]` | Array of currently/pre-selected options when binding/passing as props respectively. |
| `selectedLabels` | `[]` | Labels of currently selected options. |
| `selectedValues` | `[]` | Values of currently selected options. |
| `readonly` | `false` | Disable the component. It will still be rendered but users won't be able to interact with it. |
| `placeholder` | `undefined` | String shown in the text input when no option is selected. |
| `input` | `undefined` | Handle to the `<input>` DOM node. |
| `id` | `undefined` | Applied to the `<input>` element for associating HTML form `<label>`s with this component for accessibility. Also, clicking a `<label>` with same `for` attribute as `id` will focus this component. |
| `name` | `id` | Applied to the `<input>` element. If not provided, will be set to the value of `id`. Sets the key of this field in a submitted form data object. Not useful at the moment since the value is stored in Svelte state, not on the `<input>`. |
| name | default | description |
| :--------------- | :------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `options` | required prop | Array of strings/numbers or `Option` objects that will be listed in the dropdown. See `src/lib/index.ts` for admissible fields. The `label` is the only mandatory one. It must also be unique. |
| `activeOption` | `null` | Currently active option, i.e. the one the user currently hovers or navigated to with arrow keys. |
| `maxSelect` | `null` | Positive integer to limit the number of options users can pick. `null` means no limit. |
| `selected` | `[]` | Array of currently/pre-selected options when binding/passing as props respectively. |
| `selectedLabels` | `[]` | Labels of currently selected options. |
| `selectedValues` | `[]` | Values of currently selected options. |
| `readonly` | `false` | Disable the component. It will still be rendered but users won't be able to interact with it. |
| `placeholder` | `undefined` | String shown in the text input when no option is selected. |
| `input` | `undefined` | Handle to the `<input>` DOM node. |
| `id` | `undefined` | Applied to the `<input>` element for associating HTML form `<label>`s with this component for accessibility. Also, clicking a `<label>` with same `for` attribute as `id` will focus this component. |
| `name` | `id` | Applied to the `<input>` element. If not provided, will be set to the value of `id`. Sets the key of this field in a submitted form data object. Not useful at the moment since the value is stored in Svelte state, not on the `<input>`. |
</div>
## Exposed methods
1. `filterFunc = (op: Option, searchText: string) => boolean`: Determine what options are shown when user enters search string to filter dropdown list. Defaults to:
```ts
filterFunc = (op: Option, searchText: string) => {
if (!searchText) return true
return `${op.label}`.toLowerCase().includes(searchText.toLowerCase())
}
```
2. `maxSelectMsg = (current: number, max: number) => string`: Inform the user how many of the maximum allowed options they have currently selected. Return empty string to disable, i.e. `() => ''`. Is automatically disabled when `maxSelect === null`. Defaults to:
```ts
maxSelectMsg = (current: number, max: number) => `${current}/${max}`
```
## Slots

@@ -199,26 +215,32 @@

- `div.multiselect`:
- `div.multiselect`
- `border: var(--sms-border, 1pt solid lightgray)`: Change this to e.g. to `1px solid red` to indicate this form field is in an invalid state.
- `border-radius: var(--sms-border-radius, 5pt)`: Input border radius.
- `background: var(--sms-input-bg)`: Input background.
- `height: var(--sms-input-height, 2em)`: Input height.
- `border: var(--sms-focus-border, 1pt solid var(--sms-active-color, cornflowerblue))`: Border when focused. Falls back to `--sms-active-color` if not set which in turn falls back on `cornflowerblue`.
- `border-radius: var(--sms-border-radius, 5pt)`
- `background: var(--sms-input-bg)`
- `height: var(--sms-input-height, 2em)`
- `div.multiselect.open`
- `z-index: var(--sms-open-z-index, 4)`: Increase this if needed to ensure the dropdown list is displayed atop all other page elements.
- `div.multiselect:focus-within`
- `border: var(--sms-focus-border, 1pt solid var(--sms-active-color, cornflowerblue))`: Border when component has focus. Defaults to `--sms-active-color` if not set which defaults to `cornflowerblue`.
- `div.multiselect.readonly`
- `background: var(--sms-readonly-bg, lightgray)`: Background when in readonly state.
- `div.multiselect.open`:
- `z-index: var(--sms-open-z-index, 4)`: Useful to ensure the dropdown list of options is displayed on top of other page elements of increased `z-index`.
- `div.multiselect > input`
- `color: var(--sms-text-color, inherit)`: Input text color.
- `ul.selected > li`:
- `div.multiselect > ul.selected > li`
- `background: var(--sms-selected-bg, var(--sms-active-color, cornflowerblue))`: Background of selected options.
- `ul.selected > li button:hover, button.remove-all:hover`
- `height: var(--sms-selected-li-height)`: Height of selected options.
- `ul.selected > li button:hover, button.remove-all:hover, button:focus`
- `color: var(--sms-remove-x-hover-focus-color, lightskyblue)`: Color of the cross-icon buttons for removing all or individual selected options when in `:focus` or `:hover` state.
- `ul.options`
- `background: var(--sms-options-bg, white)`: Background of options list.
- `background: var(--sms-options-overscroll, none)`: Whether scroll events bubble to parent elements when reaching the top/bottom of the options dropdown. See [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/overscroll-behavior).
- `ul.options > li.selected`
- `div.multiselect > ul.options`
- `background: var(--sms-options-bg, white)`: Background of dropdown list.
- `overscroll-behavior: var(--sms-options-overscroll, none)`: Whether scroll events bubble to parent elements when reaching the top/bottom of the options dropdown. See [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/overscroll-behavior).
- `div.multiselect > ul.options > li.selected`
- `border-left: var(--sms-li-selected-border-left, 3pt solid var(--sms-selected-color, green))`
- `background: var(--sms-li-selected-bg, inherit)`: Background of selected list items in options pane.
- `color: var(--sms-li-selected-color, inherit)`: Text color of selected list items in options pane.
- `ul.options > li.active`
- `div.multiselect > ul.options > li:not(.selected):hover`
- `border-left: var(--sms-li-not-selected-hover-border-left, 3pt solid var(--sms-active-color, cornflowerblue))`
- `div.multiselect > ul.options > li.active`
- `background: var(--sms-li-active-bg, var(--sms-active-color, cornflowerblue))`: Background of active (currently with arrow keys highlighted) list item.
- `ul.options > li.disabled`
- `div.multiselect > ul.options > li.disabled`
- `background: var(--sms-li-disabled-bg, #f5f5f6)`: Background of disabled options in the dropdown list.

@@ -263,36 +285,43 @@ - `color: var(--sms-li-disabled-text, #b8b8b8)`: Text color of disabled option in the dropdown list.

```css
:global(.multiselect) {
:global(div.multiselect) {
/* top-level wrapper div */
}
:global(.multiselect ul.selected > li) {
/* selected options */
:global(div.multiselect.open) {
/* top-level wrapper div when dropdown open */
}
:global(.multiselect ul.selected > li button),
:global(.multiselect button.remove-all) {
:global(div.multiselect.readonly) {
/* top-level wrapper div when in readonly state */
}
:global(div.multiselect > ul.selected) {
/* selected list */
}
:global(div.multiselect > ul.selected > li) {
/* selected list items */
}
:global(div.multiselect button) {
/* target all buttons in this component */
}
:global(div.multiselect > ul.selected > li button, button.remove-all) {
/* buttons to remove a single or all selected options at once */
}
:global(.multiselect ul.options) {
:global(div.multiselect > input) {
/* input inside the top-level wrapper div */
}
:global(div.multiselect > ul.options) {
/* dropdown options */
}
:global(.multiselect ul.options li) {
/* dropdown list of available options */
:global(div.multiselect > ul.options > li) {
/* dropdown list items */
}
:global(.multiselect ul.options li.selected) {
:global(div.multiselect > ul.options > li.selected) {
/* selected options in the dropdown list */
}
:global(.multiselect ul.options li:not(.selected):hover) {
:global(div.multiselect > ul.options > li:not(.selected):hover) {
/* unselected but hovered options in the dropdown list */
}
:global(.multiselect ul.options li.selected:hover) {
/* selected and hovered options in the dropdown list */
/* probably not necessary to style this state in most cases */
}
:global(.multiselect ul.options li.active) {
:global(div.multiselect > ul.options > li.active) {
/* active means item was navigated to with up/down arrow keys */
/* ready to be selected by pressing enter */
}
:global(.multiselect ul.options li.selected.active) {
/* both active and already selected, pressing enter now will deselect the item */
}
:global(.multiselect ul.options li.disabled) {
:global(div.multiselect > ul.options > li.disabled) {
/* options with disabled key set to true (see props above) */

@@ -299,0 +328,0 @@ }