{"_id":"@barglm/vueform-multiselect-search","_rev":"1-065496445e7ee13d5fd0af9637dbf9fd","name":"@barglm/vueform-multiselect-search","dist-tags":{"latest":"2.2.2"},"versions":{"2.2.2":{"name":"@barglm/vueform-multiselect-search","version":"2.2.2","private":false,"description":"Vue 3 multiselect component with single select, multiselect and tagging options.","license":"MIT","author":{"name":"Adam Berecz","email":"adam@vueform.com"},"main":"./dist/multiselect.js","types":"./src/index.d.ts","module":"./dist/multiselect.js","unpkg":"./dist/multiselect.global.js","style":"./themes/default.css","repository":{"type":"git","url":"git+https://github.com/barglm/multiselect.git"},"bugs":{"url":"https://github.com/barglm/multiselect/issues"},"scripts":{"build":"npm run build:vue2; npm run build:vue3; npm run build:themes","build:vue2":"rollup --config build/vue2.rollup.config.js","build:vue3":"rollup --config build/vue3.rollup.config.js","build:themes":"rollup --config build/themes.rollup.config.js","test":"jest --config=jest/jest.config.vue3.js; jest --config=jest/jest.config.vue2.js;","test:vue2":"jest --verbose --config=jest/jest.config.vue2.js","test:vue3":"jest --verbose --config=jest/jest.config.vue3.js"},"devDependencies":{"@babel/core":"^7.12.10","@babel/plugin-transform-modules-umd":"^7.12.1","@babel/preset-env":"^7.12.10","@rollup/plugin-alias":"^3.1.1","@rollup/plugin-babel":"^5.2.2","@testing-library/jest-dom":"^5.11.5","@vue/compiler-sfc":"^3.0.4","autoprefixer":"^10.3.1","babel-core":"^7.0.0-bridge.0","babel-jest":"^26.6.1","babel-plugin-rename-umd-globals":"^1.0.0","flush-promises":"^1.0.2","fraction.js":"^4.1.1","jest":"^26.6.1","jest-environment-jsdom-sixteen":"^1.0.3","node-sass":"^5.0.0","postcss":"^8.2.1","rollup":"^2.34.2","rollup-plugin-postcss":"^4.0.0","rollup-plugin-terser":"^7.0.2","typescript":"^4.1.2","vue-next":"npm:vue@^3.0.4","vue-next-jest":"npm:vue-jest@^5.0.0-alpha.4","vue-next-rollup-plugin-vue":"npm:rollup-plugin-vue@^6.0.0","vue-next-test-utils":"npm:@vue/test-utils@^2.0.0-beta.6","vue-prev":"npm:vue@^2.6.12","vue-prev-composition-api":"npm:@vue/composition-api@^1.0.0-beta.17","vue-prev-jest":"npm:vue-jest@^3.0.7","vue-prev-rollup-plugin-vue":"npm:rollup-plugin-vue@^5.1.9","vue-prev-test-utils":"npm:@vue/test-utils@^1.1.0","vue-template-compiler":"^2.6.12"},"browserslist":["> 1%","last 2 versions","not dead"],"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2020-2021 Adam Berecz <adam@vueform.com>.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.","_id":"@barglm/vueform-multiselect-search@2.2.2","dist":{"shasum":"a0e89fba1acd5195ea771205ca539c3f73dee0d9","integrity":"sha512-w16quVXXEmve5oQUX4nut33psZ6w8zJpj8cu4z81c4WC7IPBQ2H1BX1aTPD2VpcQdUH5Ibn10xiRDM1BN0gBLA==","tarball":"https://registry.npmjs.org/@barglm/vueform-multiselect-search/-/vueform-multiselect-search-2.2.2.tgz","fileCount":46,"unpackedSize":772352,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGqcY5Py1iUV/yfvAZp27qi47bzlaKkYH+2qbr0YzQQRAiEA9/O5YTcdWSLPSt12QlifBgYUpWM0zhdVaYdRXQC9anA="}]},"_npmUser":{"name":"barglm","email":"bargl@webwings.cz"},"directories":{},"maintainers":[{"name":"barglm","email":"bargl@webwings.cz"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/vueform-multiselect-search_2.2.2_1631892792104_0.11289408094343734"},"_hasShrinkwrap":false}},"time":{"created":"2021-09-17T15:33:12.061Z","2.2.2":"2021-09-17T15:33:12.274Z","modified":"2022-04-04T17:44:00.582Z"},"maintainers":[{"name":"barglm","email":"bargl@webwings.cz"}],"description":"Vue 3 multiselect component with single select, multiselect and tagging options.","repository":{"type":"git","url":"git+https://github.com/barglm/multiselect.git"},"author":{"name":"Adam Berecz","email":"adam@vueform.com"},"bugs":{"url":"https://github.com/barglm/multiselect/issues"},"license":"MIT","readme":"<div align=\"center\">\n\n  <a href=\"https://www.npmjs.com/package/@vueform/multiselect\" target=\"_blank\">\n    <img alt=\"npm\" src=\"https://img.shields.io/npm/dm/@vueform/multiselect?color=%2353ca2f\">\n  </a>\n\n  <img alt=\"CircleCI\" src=\"https://img.shields.io/circleci/build/github/vueform/multiselect\">\n\n  <a href=\"https://codecov.io/gh/vueform/multiselect\" target=\"_blank\">\n    <img src=\"https://img.shields.io/codecov/c/github/vueform/multiselect\"/>\n  </a>\n\n  <a href=\"https://www.npmjs.com/package/@vueform/multiselect\" target=\"_blank\">\n    <img alt=\"npm bundle size (scoped version)\" src=\"https://img.shields.io/bundlephobia/minzip/@vueform/multiselect?color=53ca2f\">\n  </a>\n\n  <a href=\"https://discord.gg/WhX2nG6GTQ\" target=\"_blank\">\n    <img alt=\"Discord\" src=\"https://img.shields.io/discord/787237947635793940\">\n  </a>\n\n  <a href=\"https://www.npmjs.com/package/@vueform/multiselect\" target=\"_blank\">\n    <img alt=\"npm\" src=\"https://img.shields.io/npm/v/@vueform/multiselect\">\n  </a>\n\n  <h1>Vue 3 Multiselect</h1>\n  \n  <a href=\"https://vueform.com?ref=github\" target=\"_blank\">\n    <br>\n    <img align=\"center\" src=\"https://github.com/vueform/multiselect/raw/main/assets/logo.svg\" width=\"110\">\n    <br>\n  </a>\n\n  <br>\n  <br>\n\n  <a href=\"https://www.npmjs.com/package/@vueform/multiselect\" target=\"_blank\">\n    <img align=\"center\" src=\"https://github.com/vueform/multiselect/raw/main/assets/screenshot-1.png\">\n  </a>\n  <br>\n\n</div>\n\n## Sponsors\n\n<div align=\"center\"><br>\n  <a href=\"https://vueform.com?ref=github\"><img src=\"https://github.com/vueform/multiselect/raw/main/assets/logo-horizontal.svg\" width=\"200\"></a>\n</div>\n\n## Other libraries\n\n* [@vueform/slider](https://github.com/vueform/slider) - Vue 3 slider component with multihandles, tooltips merging and formatting.\n* [@vueform/toggle](https://github.com/vueform/toggle) - Vue 3 toggle component with labels, custom slots and styling options.\n\n## Multiselect features\n\n* Vue 2 & 3 support\n* No dependencies\n* 100% coverage\n* TypeScript support\n* ESM support\n* Single select options\n* Multiple select options\n* Tags\n* Option groups\n* Async options\n* Search & filtering\n* Custom slots\n* Events\n* CSS vars support\n* Tailwind & utility class support\n* Fully configurable\n* CSP compilant\n\n## Demo\n\nCheck out our <a href=\"https://jsfiddle.net/4q3oauy6/6/\" target=\"_blank\">demo</a>.\n\n## Installation\n\n```\nnpm install @vueform/multiselect\n```\n\n## Using with Vue 3\n\n``` vue\n<template>\n  <div>\n    <Multiselect\n      v-model=\"value\"\n      :options=\"options\"\n    />\n  </div>\n</template>\n\n<script>\n  import Multiselect from '@vueform/multiselect'\n\n  export default {\n    components: {\n      Multiselect,\n    },\n    data() {\n      return {\n        value: null,\n        options: [\n          'Batman',\n          'Robin',\n          'Joker',\n        ]\n      }\n    }\n  }\n</script>\n\n<style src=\"@vueform/multiselect/themes/default.css\"></style>\n```\n\n## Using with Vue 2\n\nWhen using Vue 2 install [@vue/composition-api](https://github.com/vuejs/composition-api#npm) via npm/yarn first:\n\n``` bash\nnpm i @vue/composition-api --save-dev\n```\n\nThen install the plugin for Vue:\n\n``` js\nimport Vue from 'vue'\nimport VueCompositionAPI from '@vue/composition-api'\n\nVue.use(VueCompositionAPI)\n```\n\nAfter that make sure to change the imported Multiselect module to:\n\n``` js\nimport Multiselect from '@vueform/multiselect/dist/multiselect.vue2.js'\n```\n\n## Using with Nuxt.js\n\nFirst you need install [@nuxtjs/composition-api](https://composition-api.nuxtjs.org/getting-started/setup):\n\n``` bash\nnpm i @nuxtjs/composition-api --save\n```\n\nThen you need to enable it as a module in `nuxt.config.js`:\n\n``` js\n{\n  buildModules: [\n    '@nuxtjs/composition-api/module'\n  ]\n}\n```\n\nAfter that make sure to change the imported module to Vue 2 version of Multiselect:\n\n``` js\nimport Multiselect from '@vueform/multiselect/dist/multiselect.vue2'\n```\n\nFor more information on using `@nuxtjs/composition-api` read [their documentation](https://composition-api.nuxtjs.org/).\n\n## Support\n\nJoin our [Discord channel](https://discord.gg/WhX2nG6GTQ) or [open an issue](https://github.com/vueform/multiselect/issues).\n\n## Basic props\n\n| Name | Type | Default | Description |\n| --- | --- | --- | --- |\n| **mode** | `string` | `single` | Possible values: `single\\|multiple\\|tags`. |\n| **options** | `array\\|object\\|function` | `[]` | List of options. Can be:<br>- an array (eg. `[1,2,3]`)<br>- an object (eg. `{a:1,b:2,c:3}`)<br>- an array of objects:<br>`[`<br>&nbsp;&nbsp;`{`<br>&nbsp;&nbsp;&nbsp;&nbsp;`[valueProp]: 1,`<br>&nbsp;&nbsp;&nbsp;&nbsp;`[label]: 'v1',`<br>&nbsp;&nbsp;&nbsp;&nbsp;`disabled:true\\|false`<br>&nbsp;&nbsp;`},`<br>&nbsp;&nbsp;`//...`<br>`]`<br>- a function returning a Promise (async function) with `query` input param. The promise should return options as an **object** or as an **array of objects**.<br>When an array of objects is provided it **must** have properties that equal to `:valueProp`'s, `:trackBy`'s and `:label`'s value. |\n| **groups** | `boolean` | `false` | Whether options should be groupped. Example:<br>`{`<br>&nbsp;&nbsp;`groups: true,`<br>&nbsp;&nbsp;`options: [`<br>&nbsp;&nbsp;&nbsp;&nbsp;`{`<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`[groupLabel]: 'Group label',`<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`[groupOptions]: {options},`<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`disabled: true\\|false,`<br>&nbsp;&nbsp;&nbsp;&nbsp;`}`<br>&nbsp;&nbsp;&nbsp;&nbsp;`//...`<Br>&nbsp;&nbsp;`]`<br>`}`<br>The `{options}` should equal to regular `options` definition. |\n| **groupLabel** | `string` | `label` | The name of the property that contains the label of a group when `options` are provided in group format and `groups` is `true`. |\n| **groupOptions** | `string` | `options` | The name of the property that contains the options of a group when `options` are provided in group format and `groups` is `true`. |\n| **groupSelect** | `boolean` | `true` | Whether groups can be selected when using `multiple` or `tags` mode. |\n| **groupHideEmpty** | `boolean` | `false` | Whether groups that have no `options` by default should be hidden. |\n| **required** | `boolean` | `false` | Whether the HTML5 required attribute should be used for multiselect (using an invisible fake input). |\n| **searchable** | `boolean` | `false` | Whether the options should be searchable. |\n| **valueProp** | `string` | `'value'` | If you provide an array of objects as `options` this property should be used as the value of the option. |\n| **trackBy** | `string` | `'label'` | The name of the property that should be searched when `searchable` is `true` and an array of objects are provided as `options`. |\n| **label** | `string` | `'label'` | If you provide an array of objects as `options` the value of this property will be displayed as selected option. |\n| **placeholder** | `string` | `null` | The text that should be displayed before any option is selected. |\n| **multipleLabel** | `function` |  | A function that returns the label to be displayed for selected options when using `multiple` mode. It receives `value` as an argument. By default it renders `1 option selected` and `[n] options selected` based on `value` length. |\n| **disabled** | `boolean` | `false` | Whether the input should be disabled for the user (API can still be used programmatically). |\n| **inputType** | `string` | `text` | The `type` attribute of the search input. |\n| **autocomplete** | `string` | `undefined` | The `autocomplete` attribute of the search input. |\n| **max** | `number` | `-1` | The maximum number of options that **can be selected** when using `multiple` or `tags` mode. If `-1` the number of options won't be limited. |\n| **limit** | `number` | `-1` | The maximum number of options that **should be displayed**. If `-1` the number of options won't be limited. |\n| **loading** | `boolean` | `false` | Whether a loading spinner should be shown. |\n| **id** | `string` | `'multiselect'` | The `id` of the multiselect container DOM. |\n| **caret** | `boolean` | `true` | Whether should display the caret symbol on the right. |\n| **noOptionsText** | `string` | `'The list is empty'` | The text that should be displayed when options list is empty. |\n| **noResultsText** | `string` | `'No results found'` | The text that should be displayed when there are no search results. |\n| **openDirection** | `string` | `bottom` | Whether the option list should be displayed above or below the multiselect. Possible values: `top\\|bottom` |\n| **strict** | `boolean` | `true` | Whether should regard accents/diacritics in search. |\n| **classes** | `object` | | An object of class names that gets merged with the default values. Default: `{`<br>&nbsp;&nbsp;`container: 'multiselect',`<br>&nbsp;&nbsp;`containerDisabled: 'is-disabled',`<br>&nbsp;&nbsp;`containerOpen: 'is-open',`<br>&nbsp;&nbsp;`containerOpenTop: 'is-open-top',`<br>&nbsp;&nbsp;`containerActive: 'is-active',`<br>&nbsp;&nbsp;`singleLabel: 'multiselect-single-label',`<br>&nbsp;&nbsp;`multipleLabel: 'multiselect-multiple-label',`<br>&nbsp;&nbsp;`search: 'multiselect-search',`<br>&nbsp;&nbsp;`tags: 'multiselect-tags',`<br>&nbsp;&nbsp;`tag: 'multiselect-tag',`<br>&nbsp;&nbsp;`tagDisabled: 'is-disabled',`<br>&nbsp;&nbsp;`tagRemove: 'multiselect-tag-remove',`<br>&nbsp;&nbsp;`tagRemoveIcon: 'multiselect-tag-remove-icon',`<br>&nbsp;&nbsp;`tagsSearchWrapper: 'multiselect-tags-search-wrapper',`<br>&nbsp;&nbsp;`tagsSearch: 'multiselect-tags-search',`<br>&nbsp;&nbsp;`tagsSearchCopy: 'multiselect-tags-search-copy',`<br>&nbsp;&nbsp;`placeholder: 'multiselect-placeholder',`<br>&nbsp;&nbsp;`caret: 'multiselect-caret',`<br>&nbsp;&nbsp;`caretOpen: 'is-open',`<br>&nbsp;&nbsp;`clear: 'multiselect-clear',`<br>&nbsp;&nbsp;`clearIcon: 'multiselect-clear-icon',`<br>&nbsp;&nbsp;`spinner: 'multiselect-spinner',`<br>&nbsp;&nbsp;`dropdown: 'multiselect-dropdown',`<br>&nbsp;&nbsp;`dropdownTop: 'is-top',`<br>&nbsp;&nbsp;`dropdownHidden: 'is-hidden',`<br>&nbsp;&nbsp;`options: 'multiselect-options',`<br>&nbsp;&nbsp;`optionsTop: 'is-top',`<br>&nbsp;&nbsp;`group: 'multiselect-group',`<br>&nbsp;&nbsp;`groupLabel: 'multiselect-group-label',`<br>&nbsp;&nbsp;`groupLabelPointable: 'is-pointable',`<br>&nbsp;&nbsp;`groupLabelPointed: 'is-pointed',`<br>&nbsp;&nbsp;`groupLabelSelected: 'is-selected',`<br>&nbsp;&nbsp;`groupLabelDisabled: 'is-disabled',`<br>&nbsp;&nbsp;`groupLabelSelectedPointed: 'is-selected is-pointed',`<br>&nbsp;&nbsp;`groupLabelSelectedDisabled: 'is-selected is-disabled',`<br>&nbsp;&nbsp;`groupOptions: 'multiselect-group-options',`<br>&nbsp;&nbsp;`option: 'multiselect-option',`<br>&nbsp;&nbsp;`optionPointed: 'is-pointed',`<br>&nbsp;&nbsp;`optionSelected: 'is-selected',`<br>&nbsp;&nbsp;`optionDisabled: 'is-disabled',`<br>&nbsp;&nbsp;`optionSelectedPointed: 'is-selected is-pointed',`<br>&nbsp;&nbsp;`optionSelectedDisabled: 'is-selected is-disabled',`<br>&nbsp;&nbsp;`noOptions: 'multiselect-no-options',`<br>&nbsp;&nbsp;`noResults: 'multiselect-no-results',`<br>&nbsp;&nbsp;`fakeInput: 'multiselect-fake-input',`<br>&nbsp;&nbsp;`spacer: 'multiselect-spacer'`<br>`}` |\n\n### Advanced Props\n\n| Name | Type | Default | Description |\n| --- | --- | --- | --- |\n| **canDeselect** | `boolean` | `true` | Whether a selected option can be deselected when using `single` mode. |\n| **canClear** | `boolean` | `true` | Whether option(s) can be cleared. |\n| **clearOnSearch** | `boolean` | `false` | Whether the option list should be cleared when a new character is typed before loading new options list, when using async options. |\n| **clearOnSelect** | `boolean` | `true` | Whether the option list should be cleared upon selecting an option when using async options. |\n| **closeOnSelect** | `boolean` | `true` | Whether the option list should be hidden upon selecting an option. |\n| **delay** | `number` | `-1` | The delay in milliseconds that should occur between the last typed character and refreshing an async option list. If `-1` the option list will not refresh when the search query changes. If `0` it will refresh without delay. |\n| **filterResults** | `boolean` | `true` | Whether option list should be filtered by search query. This may be set to `false` if you are handling filtering manually when returning async options. |\n| **minChars** | `number` | `0` | The minimum number of characters that should be typed to refresh async option list. If `0` it will refresh even when the search field becomes empty. |\n| **resolveOnLoad** | `boolean` | `true` | Whether async options should be loaded initially (with an empty query). This should be `true` if you are planning to load non-object value(s) initially while using async options (to fetch matching objects for values). |\n| **appendNewTag** | `boolean` | `true` | Whether it should append new tag automatically to option list when using `tags` mode with `createTag`. If set to `false` you need to take care of appending a new tag to the provided `:options` list upon `@tag` event. |\n| **createTag** | `boolean` | `false` | Whether it should allow creating new tag based on search query when using `tags` mode. |\n| **addTagOn** | `array` | `['enter']` | The list of keys that creates a new tag while typing in the search field when having `createTag` enabled. Possible values: `'enter'\\|'space'\\|'tab'\\|';'\\|','`. |\n| **hideSelected** | `boolean` | `true` | Whether selected options should be excluded from the option list when using `multiple` or `tags` mode. |\n| **showOptions** | `boolean` | `true` | Whether option list should be displayed. Can be used to create free-typed tags. |\n| **object** | `boolean` | `false` | Whether the value should be stored as an object.<br>If **false**:<br>`value: ['js','jsx','ts']`<br>If **true**:<br> `value: [`<br>&nbsp;&nbsp;`{value:'js',label:'Javascript'},`<br>&nbsp;&nbsp;`{value:'jsx',label:'JSX'},`<br>&nbsp;&nbsp;`{value:'ts',label:'Typescript'}`<br>`]` |\n| **nativeSupport** | `boolean` | `false` | Whether hidden input fields should be appended to achieve native data handling. |\n\n## API\n\n| Name | Params | Description |\n| --- | --- | --- |\n| **open** |  | Opens the options list and focuses the multiselect. |\n| **close** |  | Closes the options list and blurs the multiselect. |\n| **select** | `option` | Selects an option based on its value. |\n| **deselect** | `option` | Deselects an option based on its value. |\n| **remove** | `option` | Alias for `deselect`. |\n| **clear** |  | Deselects all selected options. |\n| **clearSearch** |  | Clears current search query. |\n| **refreshOptions** | `callback` | Refreshes async options list. |\n\n\nTo access API use `ref` on `Multiselect` component:\n``` html\n<Multiselect\n  v-model=\"value\"\n  :options=\"options\"\n  ref=\"multiselect\"\n/>\n```\n\n``` js\n// eg:\nmounted() {\n  this.$refs.multiselect.open()\n}\n```\n\n\n## Events\n\n| Event | Attributes | Description |\n| --- | --- | --- |\n| **@change** | `value` | Emitted after the value is changed. |\n| **@close** |  | Emitted after closing the option list. |\n| **@deselect** | `option` | Emitted after an option is deselected or a tag is removed. |\n| **@open** | | Emitted after opening the option list. |\n| **@search-change** | `query` | Emitted after a character is typed. |\n| **@select** | `option` | Emitted after an option or tag is selected. |\n| **@tag** | `query` | Emitted after enter is hit when a new tag is being created. |\n| **@clear** |  | Emitted when the options are cleared. |\n| **@paste** | `Event` | Emitted when value is pasted into the search field. |\n\n## Slots\n\n| Slot | Attributes | Description |\n| --- | --- | --- |\n| **placeholder** | | Rendered as placeholder when the multiselect does not have value and `placeholder` prop is defined. |\n| **afterlist** | | Rendered after the options list. |\n| **beforelist** | | Rendered before the options list. |\n| **multiplelabel** | `values` | Rendered when using `multiple` mode and options are selected. By default it renders the return value of `multipleLabel` function. |\n| **nooptions** |  | Rendered when the options list is empty. By default renders `noOptionsText`. |\n| **noresults** |  | Rendered when there are no search results. By default renders `noResultsText`. |\n| **grouplabel** | `group` | Renders an option group label. |\n| **option** | `option, search` | Renders an option in options list. |\n| **singlelabel** | `value` | Rendered when using `single` mode and an option is selected. By default it renders the `:label` if the selected option. |\n| **tag** | `option, handleTagRemove, disabled` | Renders a tag when using `tags` mode. When `disabled` the remove icon should not be displayed. The `handleTagRemove` prop should be used to trigger the removal of the tag. |\n| **caret** | | Renders a small triangle on the right side of the multiselect. |\n| **clear** | `clear` | Renders a remove icon if the multiselect has any value. The `clear` method should be used on `mousedown` event. |\n| **spinner** | | Renders a loader icon when async options are being fetched. |\n\n> Note: we don't use camelCase because they are [normalized back to lowercase](https://github.com/vuejs/vue/issues/9449#issuecomment-461170017) when written in DOM.\n\n## Styling with CSS vars\n\nThe following CSS variables can be used to customize multiselect when using `default.css`:\n\n``` css\n--ms-font-size: 1rem;\n--ms-line-height: 1.375;\n--ms-bg: #FFFFFF;\n--ms-bg-disabled: #F3F4F6;\n--ms-border-color: #D1D5DB;\n--ms-border-width: 1px;\n--ms-radius: 4px;\n--ms-py: 0.5rem;\n--ms-px: 0.875rem;\n--ms-ring-width: 3px;\n--ms-ring-color: #10B98130;\n--ms-placeholder-color: #9CA3AF;\n--ms-max-height: 10rem;\n\n--ms-spinner-color: #10B981;\n--ms-caret-color: #999999;\n--ms-clear-color: #999999;\n--ms-clear-color-hover: #000000;\n  \n--ms-tag-font-size: 0.875rem;\n--ms-tag-line-height: 1.25rem;\n--ms-tag-font-weight: 600;\n--ms-tag-bg: #10B981;\n--ms-tag-bg-disabled: #9CA3AF;\n--ms-tag-color: #FFFFFF;\n--ms-tag-color-disabled: #FFFFFF;\n--ms-tag-radius: 4px;\n--ms-tag-py: 0.125rem;\n--ms-tag-px: 0.5rem;\n--ms-tag-my: 0.25rem;\n--ms-tag-mx: 0.25rem;\n\n--ms-tag-remove-radius: 4px;\n--ms-tag-remove-py: 0.25rem;\n--ms-tag-remove-px: 0.25rem;\n--ms-tag-remove-my: 0rem;\n--ms-tag-remove-mx: 0.125rem;\n\n--ms-dropdown-bg: #FFFFFF;\n--ms-dropdown-border-color: #D1D5DB;\n--ms-dropdown-border-width: 1px;\n--ms-dropdown-radius: 4px;\n\n--ms-group-label-py: 0.3rem;\n--ms-group-label-px: 0.75rem;\n--ms-group-label-line-height: 1.375;\n--ms-group-label-bg-pointed: #D1D5DB;\n--ms-group-label-color-pointed: #374151;\n--ms-group-label-bg-disabled: #F3F4F6;\n--ms-group-label-color-disabled: #D1D5DB;\n--ms-group-label-bg-selected: #059669;\n--ms-group-label-color-selected: #FFFFFF;\n--ms-group-label-bg-selected-pointed: #0c9e70;\n--ms-group-label-color-selected-pointed: #FFFFFF;\n--ms-group-label-bg-selected-disabled: #75cfb1;\n--ms-group-label-color-selected-disabled: #D1FAE5;\n\n--ms-option-font-size: 1rem;\n--ms-option-line-height: 1.375;\n--ms-option-bg-pointed: #FFFFFF;\n--ms-option-bg-selected: #10B981;\n--ms-option-bg-disabled: #FFFFFF;\n--ms-option-bg-selected-pointed: #26C08E;\n--ms-option-bg-selected-disabled: #FFFFFF;\n--ms-option-color-pointed: #1F2937;\n--ms-option-color-selected: #FFFFFF;\n--ms-option-color-disabled: #D1D5DB;\n--ms-option-color-selected-pointed: #FFFFFF;\n--ms-option-color-selected-disabled: #D1FAE5;\n--ms-option-py: 0.5rem;\n--ms-option-px: 0.75rem;\n\n--ms-empty-color: #4B5563;\n```\n\nOverride them globally:\n\n``` css\n:root {\n  --ms-tag-bg: #059669;\n  --ms-tag-color: #D1FAE5;\n  --ms-tag-radius: 9999px;\n  --ms-tag-font-weight: 400;\n}\n```\n\nOr on an instance level:\n\n``` vue\n<Multiselect\n  v-model=\"value\"\n  :options=\"options\"\n  class=\"multiselect-green\"\n/>\n\n<Multiselect\n  v-model=\"value\"\n  :options=\"options\"\n  class=\"multiselect-blue\"\n/>\n```\n\n``` css\n.multiselect-green {\n  --ms-tag-bg: #D1FAE5;\n  --ms-tag-color: #059669;\n}\n\n.multiselect-blue {\n  --ms-tag-bg: #DBEAFE;\n  --ms-tag-color: #2563EB;\n}\n```\n\n## Styling with Tailwind CSS\n\nTo use `Multiselect` with Tailwind CSS first you need to add background images to `tailwind.config.js`:\n\n``` js\n// tailwind.config.js\n\nconst svgToDataUri = require('mini-svg-data-uri')\n\nmodule.exports = {\n  theme: {\n    extend: {\n      backgroundImage: (theme) => ({\n        'multiselect-caret': `url(\"${svgToDataUri(\n          `<svg viewBox=\"0 0 320 512\" fill=\"currentColor\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z\"></path></svg>`,\n        )}\")`,\n        'multiselect-spinner': `url(\"${svgToDataUri(\n          `<svg viewBox=\"0 0 512 512\" fill=\"${theme('colors.green.500')}\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M456.433 371.72l-27.79-16.045c-7.192-4.152-10.052-13.136-6.487-20.636 25.82-54.328 23.566-118.602-6.768-171.03-30.265-52.529-84.802-86.621-144.76-91.424C262.35 71.922 256 64.953 256 56.649V24.56c0-9.31 7.916-16.609 17.204-15.96 81.795 5.717 156.412 51.902 197.611 123.408 41.301 71.385 43.99 159.096 8.042 232.792-4.082 8.369-14.361 11.575-22.424 6.92z\"></path></svg>`,\n        )}\")`,\n        'multiselect-remove': `url(\"${svgToDataUri(\n          `<svg viewBox=\"0 0 320 512\" fill=\"currentColor\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z\"></path></svg>`,\n        )}\")`,\n      })\n    },\n  }\n}\n```\n\nThen you need to import `themes/tailwind.scss` to you main component:\n\n``` vue\n<template>\n  <div id=\"app\">\n    <Multiselect ... />\n  </div>\n</template>\n\n<script>\n  // ...\n</script>\n\n<script lang=\"scss\">\n  @import 'path/to/node_modules/@vueform/multiselect/themes/tailwind.scss'\n</script>\n```\n\n### Using `:classes` prop\n\nAlternatively you can define class names directly by passing them to the `Multiselect` component via `classes` property. When using this approach you don't need to import `tailwind.scss`. Here's a default styling for Tailwind CSS (the same included in `tailwind.scss`):\n\n``` vue\n<Multiselect ... :classes=\"{\n  container: 'relative mx-auto w-full flex items-center justify-end box-border cursor-pointer border border-gray-300 rounded bg-white text-base leading-snug outline-none',\n  containerDisabled: 'cursor-default bg-gray-100',\n  containerOpen: 'rounded-b-none',\n  containerOpenTop: 'rounded-t-none',\n  containerActive: 'ring ring-green-500 ring-opacity-30',\n  singleLabel: 'flex items-center h-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5',\n  multipleLabel: 'flex items-center h-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5',\n  search: 'w-full absolute inset-0 outline-none appearance-none box-border border-0 text-base font-sans bg-white rounded pl-3.5',\n  tags: 'flex-grow flex-shrink flex flex-wrap items-center mt-1 pl-2',\n  tag: 'bg-green-500 text-white text-sm font-semibold py-0.5 pl-2 rounded mr-1 mb-1 flex items-center whitespace-nowrap',\n  tagDisabled: 'pr-2 opacity-50',\n  tagRemove: 'flex items-center justify-center p-1 mx-0.5 rounded-sm hover:bg-black hover:bg-opacity-10 group',\n  tagRemoveIcon: 'bg-multiselect-remove bg-center bg-no-repeat opacity-30 inline-block w-3 h-3 group-hover:opacity-60',\n  tagsSearchWrapper: 'inline-block relative mx-1 mb-1 flex-grow flex-shrink h-full',\n  tagsSearch: 'absolute inset-0 border-0 outline-none appearance-none p-0 text-base font-sans box-border w-full',\n  tagsSearchCopy: 'invisible whitespace-pre-wrap inline-block h-px',\n  placeholder: 'flex items-center h-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5 text-gray-400',\n  caret: 'bg-multiselect-caret bg-center bg-no-repeat w-2.5 h-4 py-px box-content mr-3.5 relative z-10 opacity-40 flex-shrink-0 flex-grow-0 transition-transform transform pointer-events-none',\n  caretOpen: 'rotate-180 pointer-events-auto',\n  clear: 'pr-3.5 relative z-10 opacity-40 transition duration-300 flex-shrink-0 flex-grow-0 flex hover:opacity-80',\n  clearIcon: 'bg-multiselect-remove bg-center bg-no-repeat w-2.5 h-4 py-px box-content inline-block',\n  spinner: 'bg-multiselect-spinner bg-center bg-no-repeat w-4 h-4 z-10 mr-3.5 animate-spin flex-shrink-0 flex-grow-0',\n  dropdown: 'max-h-60 absolute -left-px -right-px bottom-0 transform translate-y-full border border-gray-300 -mt-px overflow-y-scroll z-50 bg-white flex flex-col rounded-b',\n  dropdownTop: '-translate-y-full top-px bottom-auto flex-col-reverse rounded-b-none rounded-t',\n  dropdownHidden: 'hidden',\n  options: 'flex flex-col p-0 m-0 list-none',\n  optionsTop: 'flex-col-reverse',\n  group: 'p-0 m-0',\n  groupLabel: 'flex text-sm box-border items-center justify-start text-left py-1 px-3 font-semibold bg-gray-200 cursor-default leading-normal',\n  groupLabelPointable: 'cursor-pointer',\n  groupLabelPointed: 'bg-gray-300 text-gray-700',\n  groupLabelSelected: 'bg-green-600 text-white',\n  groupLabelDisabled: 'bg-gray-100 text-gray-300 cursor-not-allowed',\n  groupLabelSelectedPointed: 'bg-green-600 text-white opacity-90',\n  groupLabelSelectedDisabled: 'text-green-100 bg-green-600 bg-opacity-50 cursor-not-allowed',\n  groupOptions: 'p-0 m-0',\n  option: 'flex items-center justify-start box-border text-left cursor-pointer text-base leading-snug py-2 px-3',\n  optionPointed: 'text-gray-800 bg-gray-100',\n  optionSelected: 'text-white bg-green-500',\n  optionDisabled: 'text-gray-300 cursor-not-allowed',\n  optionSelectedPointed: 'text-white bg-green-500 opacity-90',\n  optionSelectedDisabled: 'text-green-100 bg-green-500 bg-opacity-50 cursor-not-allowed',\n  noOptions: 'py-2 px-3 text-gray-600 bg-white',\n  noResults: 'py-2 px-3 text-gray-600 bg-white',\n  fakeInput: 'bg-transparent absolute left-0 right-0 -bottom-px w-full h-px border-0 p-0 appearance-none outline-none text-transparent',\n  spacer: 'h-9 py-px box-content',\n}\" />\n```\n\nCertain classes has different states which are merged to the base class when the state is active. For example `dropdown` will be merged with `dropdownTop` when `open-direction: 'top'` resulting in the following classes:\n```absolute -left-px -right-px bottom-0 transform translate-y-full border border-gray-300 -mt-px overflow-y-scroll z-50 bg-white flex flex-col rounded-b -translate-y-full top-px bottom-auto flex-col-reverse rounded-b-none rounded-t```\n\nThe same is true for `container`, `tag`, `options`, `groupLabel` and `option` classes.\n\nIn case you need to override the same type of utility you might use [@neojp/tailwind-important-variant](https://www.npmjs.com/package/@neojp/tailwindcss-important-variant) for eg. `bg-green-500!`.\n\n## Examples\n\n* [Single select](#single-select)\n* [Multiselect with object options](#multiselect-with-object-options)\n* [Multiselect with disabled options](#multiselect-with-disabled-options)\n* [Multiselect with groups](#multiselect-with-groups)\n* [Tags with search, create and array of objects options](#tags-with-search-create-and-array-of-objects-options)\n* [Autocomplete with async options](#autocomplete-with-async-options)\n* [Tags with async options](#tags-with-async-options)\n* [Select with custom options slot](#select-with-custom-options-slot)\n* [Multiselect with custom label slot](#multiselect-with-custom-label-slot)\n* [Tags with custom tags slot](#tags-with-custom-tags-slot)\n\n### Single select\n\n``` vue\n<Multiselect\n  v-model=\"value\"\n  :options=\"['Batman', 'Robin', 'Joker']\"\n/>\n```\n\n<a href=\"https://jsfiddle.net/4q3oauy6/6/\" target=\"_blank\">JSFiddle - Example #1</a>\n\n### Multiselect with object options\n\n``` vue\n<Multiselect\n  v-model=\"value\"\n  mode=\"multiple\"\n  :closeOnSelect=\"false\"\n  :options=\"{\n    batman: 'Batman',\n    robin: 'Robin',\n    joker: 'Joker'\n  }\"\n/>\n```\n\n<a href=\"https://jsfiddle.net/4q3oauy6/6/\" target=\"_blank\">JSFiddle - Example #2</a>\n\n### Multiselect with disabled options\n\n``` vue\n<Multiselect\n  v-model=\"value\"\n  mode=\"multiple\"\n  :closeOnSelect=\"false\"\n  :options=\"[\n    { value: 'batman', label: 'Batman' },\n    { value: 'robin', label: 'Robin', disabled: true },\n    { value: 'joker', label: 'Joker' },\n  ]\"\n/>\n```\n\n<a href=\"https://jsfiddle.net/4q3oauy6/6/\" target=\"_blank\">JSFiddle - Example #3</a>\n\n### Multiselect with groups\n\n``` vue\n<Multiselect\n  v-model=\"value\"\n  mode=\"multiple\"\n  :closeOnSelect=\"false\"\n  :groups=\"true\"\n  :options=\"[\n    {\n      label: 'DC',\n      options: ['Batman', 'Robin', 'Joker'],\n    },\n    {\n      label: 'Marvel',\n      options: ['Spiderman', 'Iron Man', 'Captain America'],\n    },\n  ]\"\n/>\n```\n\n<a href=\"https://jsfiddle.net/4q3oauy6/6/\" target=\"_blank\">JSFiddle - Example #4</a>\n\n### Tags with search, create and array of objects options\n\n``` vue\n<Multiselect\n  v-model=\"value\"\n  mode=\"tags\"\n  :closeOnSelect=\"false\"\n  :searchable=\"true\"\n  :createTag=\"true\"\n  :options=\"[\n    { value: 'batman', label: 'Batman' },\n    { value: 'robin', label: 'Robin' },\n    { value: 'joker', label: 'Joker' },\n  ]\"\n/>\n```\n\n<a href=\"https://jsfiddle.net/4q3oauy6/6/\" target=\"_blank\">JSFiddle - Example #5</a>\n\n### Autocomplete with async options\n\n``` vue\n<Multiselect\n  v-model=\"value\"\n  placeholder=\"Choose a programming language\"\n  :filterResults=\"false\"\n  :minChars=\"1\"\n  :resolveOnLoad=\"false\"\n  :delay=\"0\"\n  :searchable=\"true\"\n  :options=\"async function(query) {\n    return await fetchLanguages(query) // check JS block in JSFiddle for implementation\n  }\"\n/>\n```\n\n<a href=\"https://jsfiddle.net/4q3oauy6/6/\" target=\"_blank\">JSFiddle - Example #6</a>\n\n### Tags with async options\n\n``` vue\n<Multiselect\n  v-model=\"value\"\n  mode=\"tags\"\n  placeholder=\"Choose your stack\"\n  :closeOnSelect=\"false\"\n  :filterResults=\"false\"\n  :minChars=\"1\"\n  :resolveOnLoad=\"false\"\n  :delay=\"0\"\n  :searchable=\"true\"\n  :options=\"async function(query) {\n    return await fetchLanguages(query) // check JS block in JSFiddle for implementation\n  }\"\n/>\n```\n\n<a href=\"https://jsfiddle.net/4q3oauy6/6/\" target=\"_blank\">JSFiddle - Example #7</a>\n\n### Select with custom options slot\n\n``` vue\n<Multiselect\n  v-model=\"value\"\n  placeholder=\"Select your character\"\n  label=\"name\"\n  :options=\"[\n    { value: 'captainamerica', name: 'Captain America', icon: 'https://cdn2.iconfinder.com/data/icons/avengers-filled/48/03_-_Captain_America_-_infinity_war_-_end_game_-_marvel_-_avengers_-_super_hero-512.png' },\n    { value: 'spiderman', name: 'Spiderman', icon: 'https://cdn2.iconfinder.com/data/icons/avengers-filled/48/12_-_Spiderman_-_infinity_war_-_end_game_-_marvel_-_avengers_-_super_hero-512.png' },\n    { value: 'ironman', name: 'Iron Man', icon: 'https://cdn2.iconfinder.com/data/icons/avengers-filled/48/02_-_IRONMAN_-_infinity_war_-_end_game_-_marvel_-_avengers_-_super_hero-512.png' },\n  ]\"\n>\n  <template v-slot:singlelabel=\"{ value }\">\n    <div class=\"multiselect-single-label\">\n      <img class=\"character-label-icon\" :src=\"value.icon\"> {{ value.name }}\n    </div>\n  </template>\n\n  <template v-slot:option=\"{ option }\">\n    <img class=\"character-option-icon\" :src=\"option.icon\"> {{ option.name }}\n  </template>\n</Multiselect>\n\n```\n\n<a href=\"https://jsfiddle.net/4q3oauy6/6/\" target=\"_blank\">JSFiddle - Example #8</a>\n\n### Multiselect with custom label slot\n\n``` vue\n<Multiselect\n  v-model=\"value\"\n  mode=\"multiple\"\n  placeholder=\"Select your characters\"\n  :closeOnSelect=\"false\"\n  :options=\"{\n    batman: 'Batman',\n    robin: 'Robin',\n    joker: 'Joker'\n  }\"\n>\n  <template v-slot:multiplelabel=\"{ values }\">\n    <div class=\"multiselect-multiple-label\">\n      {{ values.length }} characters selected\n    </div>\n  </template>\n</Multiselect>\n\n```\n\n<a href=\"https://jsfiddle.net/4q3oauy6/6/\" target=\"_blank\">JSFiddle - Example #9</a>\n\n### Tags with custom tags slot\n\n``` vue\n<template>\n  <Multiselect\n    v-model=\"value\"\n    mode=\"tags\"\n    placeholder=\"Select employees\"\n    trackBy=\"name\"\n    label=\"name\"\n    :closeOnSelect=\"false\"\n    :search=\"true\"\n    :options=\"[\n      { value: 'judy', name: 'Judy', image: 'https://randomuser.me/api/portraits/med/women/1.jpg' },\n      { value: 'jane', name: 'Jane', image: 'https://randomuser.me/api/portraits/med/women/2.jpg' },\n      { value: 'john', name: 'John', image: 'https://randomuser.me/api/portraits/med/men/1.jpg' },\n      { value: 'joe', name: 'Joe', image: 'https://randomuser.me/api/portraits/med/men/2.jpg' }\n    ]\"\n  >\n      <template v-slot:tag=\"{ option, handleTagRemove, disabled }\">\n        <div class=\"multiselect-tag is-user\">\n          <img :src=\"option.image\">\n          {{ option.name }}\n          <span\n            v-if=\"!disabled\"\n            class=\"multiselect-tag-remove\"\n            @mousedown.prevent=\"handleTagRemove(option, $event)\"\n          >\n            <span class=\"multiselect-tag-remove-icon\"></span>\n          </span>\n        </div>\n      </template>\n  </Multiselect>\n</template>\n\n<style>\n  .multiselect-tag.is-user {\n    padding: 5px 8px;\n    border-radius: 22px;\n    background: #35495e;\n    margin: 3px 3px 8px;\n  }\n\n  .multiselect-tag.is-user img {\n    width: 18px;\n    border-radius: 50%;\n    height: 18px;\n    margin-right: 8px;\n    border: 2px solid #ffffffbf;\n  }\n\n  .multiselect-tag.is-user i:before {\n    color: #ffffff;\n    border-radius: 50%;;\n  }\n\n  .user-image {\n    margin: 0 6px 0 0;\n    border-radius: 50%;\n    height: 22px;\n  }\n</style>\n```\n\n<a href=\"https://jsfiddle.net/4q3oauy6/6/\" target=\"_blank\">JSFiddle - Example #10</a>\n\n## About Vueform\n\n[Vueform](https://vueform.com?ref=github) streamlines the entire form building process in Vue 2 & 3. It comes with 30+ elements, file uploads, element nesting, 50+ validators, conditions, form steps, i18n including reactive configuration, API access, ESM modules and many more. Check out our [live demos](https://vueform.com?ref=github#demo) or see [all the features](https://vueform.com?ref=github#features) and [sign up for beta](https://vueform.com?ref=github#beta) to get early access.\n\n\n## License\n\n[MIT](https://github.com/vueform/multiselect/blob/main/LICENSE.md)","readmeFilename":"README.md"}