├── .gitignore ├── src ├── index.js └── Tags.svelte ├── .prettierrc ├── .editorconfig ├── rollup.config.js ├── package.json ├── LICENSE ├── README.md └── CHANGELOG.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | .npmignore 4 | types/ 5 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import Tags from './Tags.svelte'; 2 | 3 | export default Tags; -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 4, 4 | "semi": true, 5 | "singleQuote": false, 6 | "arrowParens": "avoid", 7 | "printWidth": 120, 8 | "singleAttributePerLine": true 9 | } 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | editorconfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Default settings: 7 | # A newline ending every file 8 | # Use 4 tabs as indentation 9 | 10 | [*] 11 | end_of_line = lf 12 | insert_final_newline = true 13 | indent_style = tab 14 | indent_size = 4 15 | charset = utf-8 16 | trim_trailing_whitespace = true 17 | 18 | [*.md] 19 | insert_final_newline = true 20 | trim_trailing_whitespace = false # Avoid editor remove two spaces at end of line. -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import svelte from "rollup-plugin-svelte" 2 | import resolve from "rollup-plugin-node-resolve" 3 | import css from "rollup-plugin-css-only" 4 | 5 | const pkg = require("./package.json"); 6 | 7 | export default { 8 | input: "src/Tags.svelte", 9 | output: [ 10 | { file: pkg.module, format: "es" }, 11 | { file: pkg.main, format: "umd", name: "Tags" }, 12 | ], 13 | plugins: [svelte(), css({ output: 'tags.css' }), resolve()], 14 | }; 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelte-tags-input", 3 | "version": "6.0.2", 4 | "description": "Fully customizable Svelte component to enter tags.", 5 | "main": "dist/index.js", 6 | "module": "dist/index.mjs", 7 | "svelte": "src/Tags.svelte", 8 | "exports": { 9 | ".": { 10 | "svelte": "src/Tags.svelte" 11 | } 12 | }, 13 | "scripts": { 14 | "build": "rollup -c", 15 | "prepare": "npm run build", 16 | "dev": "rollup -c -w" 17 | }, 18 | "keywords": [ 19 | "svelte", 20 | "tags", 21 | "input" 22 | ], 23 | "repository": { 24 | "type": "git", 25 | "url": "https://github.com/agustinl/svelte-tags-input" 26 | }, 27 | "author": "Agustin Lautaro ", 28 | "license": "MIT", 29 | "devDependencies": { 30 | "@rollup/plugin-commonjs": "^18.0.0", 31 | "rollup": "^2.45.2", 32 | "rollup-plugin-css-only": "^3.1.0", 33 | "rollup-plugin-node-resolve": "^5.2.0", 34 | "rollup-plugin-svelte": "^7.1.0", 35 | "svelte": "^3.37.0" 36 | }, 37 | "homepage": "https://svelte-tags-input.vercel.app/", 38 | "bugs": { 39 | "url": "https://github.com/agustinl/svelte-tags-input/issues" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Agustín 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Svelte Tags Input

2 |

3 | svelte-tags-input 4 |

5 |
Svelte tags input is a component to use with Svelte and easily enter tags and customize some options
6 |
7 |

8 | 9 | 10 | 11 |

12 | 13 | ## [Live Demo](https://svelte-tags-input.vercel.app/) 14 | 15 | ## Install & Usage 16 | 17 | ```bash 18 | npm install svelte-tags-input 19 | ``` 20 | 21 | ```javascript 22 | import Tags from "svelte-tags-input"; 23 | 24 | 25 | ``` 26 | 27 | ## Options 28 | 29 | | Option | Type | Default | Description | 30 | | --- | --- | --- | --- | 31 | | bind:tags | `Array` | `[]` | To get the values | 32 | | addKeys | `Array` | ENTER 13 | Set which keys add new values | 33 | | removeKeys | `Array` | BACKSPACE 8 | Set which keys remove new values | 34 | | allowPaste | `Boolean` | `false` | Enable pasting of a tag or tag group | 35 | | allowDrop | `Boolean` | `false` | Enable drag and drop of a tag or tag group | 36 | | splitWith | `String` | , | Choose what character split you group of tags
_Work only if allowDrop or allowPaste are true_ | 37 | | maxTags | `Number` | `false` | Set maximum number of tags | 38 | | onlyUnique | `Boolean` | `false` | Set the entered tags to be unique | 39 | | placeholder | `String` | `false` | Set a placeholder | 40 | | autoComplete | `Array` or `fn()` | `false` | Set an array of elements to create a auto-complete dropdown | 41 | | autoCompleteKey | `String` | `false` | Set a key to search on `autoComplete` array of objects | 42 | | autoCompleteStartFocused | `Boolean` | `false` | Set the autocomplete focus to the first result without user input | 43 | | autoCompleteFilter | `Boolean` | `true` | If `false` disable auto complete filter and return endpoint response without filter | 44 | | onlyAutocomplete | `Boolean` | `false` | Only accept tags inside the auto complete list | 45 | | name | `String` | `svelte-tags-input` | Set a `name` attribute | 46 | | id | `String` | Random Unique ID | Set a `id` attribute | 47 | | allowBlur | `Boolean` | `false` | Enable add tag when input blur | 48 | | disable | `Boolean` | `false` | Disable input | 49 | | minChars | `Number` | `1` | Minimum length of search text to show autoComplete list. If 0, autoComplete list shows all results when click on input | 50 | | labelText | `String` | `svelte-tags-input` | Custom text for input label | 51 | | labelShow | `Boolean` | `false` | If `true` the label will be visible | 52 | | readonly | `Boolean` | `false` | If `true` the input show in display mode | 53 | | onTagClick | `Function` | `empty` | A function to fire when a tag is clicked | 54 | | autoCompleteShowKey | `String` | `autoCompleteKey` | A key string to show a different value from auto complete list object returned | 55 | | onTagAdded | `Function` | `empty` | Get a function to execute when tag added | 56 | | onTagRemoved | `Function` | `empty` | Get a function to execute when tag removed | 57 | | cleanOnBlur | `Boolean` | `false` | Clear input on blur (tags keeped) | 58 | | customValidation | `Function` | `empty` | Create a custom validation when tag is added | 59 | 60 | ##### [A complete list of key codes](https://keycode.info/) 61 | 62 | ## Full example 63 | ### [Live Demo](https://svelte-tags-input.vercel.app/) 64 | 65 | ```javascript 66 | import Tags from "svelte-tags-input"; 67 | 68 | let tags = []; 69 | 70 | const countryList = [ 71 | "Afghanistan", 72 | "Albania", 73 | "Algeria", 74 | "American Samoa", 75 | "Andorra", 76 | "Angola", 77 | "Anguilla", 78 | "Antarctica", 79 | "Antigua and Barbuda", 80 | "Argentina" 81 | ... 82 | ]; 83 | 84 | console.log(tag)} 105 | onTagAdded={(tag, tags) => console.log(tag, tags)} 106 | onTagRemoved={(tag, tags) => console.log(tag, tags)} 107 | cleanOnBlur={true} 108 | customValidation={(tag) => tag === "Argentina" ? true : false } 109 | /> 110 | ``` 111 | 112 | ## Example with `autoComplete` function 113 | ### [Live Demo](https://svelte-tags-input.vercel.app/) 114 | 115 | ```javascript 116 | import Tags from "svelte-tags-input"; 117 | 118 | let tags = []; 119 | 120 | const customAutocomplete = async () => { 121 | const list = await fetch('https://restcountries.com/v2/all?fields=name,alpha3Code,flag'); 122 | const res = await list.json(); 123 | 124 | return res; 125 | } 126 | 127 | 133 | 134 | {#each tags as country, index} 135 |

{index} - {country.name} - {country.alpha3Code}

136 | 137 | {/each} 138 | ``` 139 | 140 | ## [FAQs](https://svelte-tags-input.vercel.app) 141 | 142 | ## [CHANGELOG](CHANGELOG.md) 143 | 144 | ## License 145 | 146 | This project is open source and available under the [MIT License](LICENSE). 147 | 148 | ## Author 149 | 150 | [Agustín](https://twitter.com/agustinlautaro) 151 | 152 | ##### 2024 153 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # svelte-tags-input changelog 2 | 3 | ## 6.0.2 4 | 5 | * **Add:** Support for `autoCompleteStartFocused` [#101](https://github.com/agustinl/svelte-tags-input/issues/101) 6 | 7 | ## 6.0.1 8 | 9 | * **Fix:** Keyboard autocomplete selection does not select autocomplete entry [#95](https://github.com/agustinl/svelte-tags-input/issues/95) 10 | 11 | ## 6.0.0 12 | 13 | * **Fix:** [#87](https://github.com/agustinl/svelte-tags-input/issues/87) 14 | * **Add:** `onTagAdded` and `onTagRemoved` events. [#77](https://github.com/agustinl/svelte-tags-input/issues/77) 15 | * **Add:** `cleanOnBlur` prop. [#83](https://github.com/agustinl/svelte-tags-input/issues/83) 16 | * **Add:** `customValidation` prop. [#89](https://github.com/agustinl/svelte-tags-input/issues/89) 17 | * **Fix:** Form submitting when tag clicked [#88](https://github.com/agustinl/svelte-tags-input/pull/88) 18 | * **Fix:** [https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/faq.md#missing-exports-condition](https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/faq.md#missing-exports-condition) [#90](https://github.com/agustinl/svelte-tags-input/pull/90) 19 | 20 | ## 5.0.0 21 | 22 | * **Fix:** Tag a11y events warning. 23 | * **Add:** `autoCompleteShowKey` prop to show a different value form the object returned in auto complete list. [#85](https://github.com/agustinl/svelte-tags-input/issues/85) 24 | * **Fix:** Fix `onlyUnique` if is array of objects. [#80](https://github.com/agustinl/svelte-tags-input/issues/80) 25 | * **Fix:** Fix `minChars` type. [#82](https://github.com/agustinl/svelte-tags-input/issues/82) 26 | 27 | ## 4.0.0 28 | 29 | * **Add:** support for binding values. [#38](https://github.com/agustinl/svelte-tags-input/issues/38) 30 | * **Add:** `readonly` prop for display mode. [#63](https://github.com/agustinl/svelte-tags-input/issues/63) 31 | 32 | ## 3.0.0 33 | 34 | Thanks to [@dnotes](https://github.com/dnotes) 35 | 36 | * **Fix:** Tags input does not have an outline like other fields [#68](https://github.com/agustinl/svelte-tags-input/issues/68) 37 | * **Fix:** Browser's autocomplete can interfere with Tags autocomplete [#67](https://github.com/agustinl/svelte-tags-input/issues/67) 38 | * **Fix:** Cannot tab to choose a tag even if `allowBlur` is true [#66](https://github.com/agustinl/svelte-tags-input/issues/66) 39 | * **Fix:** Matches list opens even when `maxTags` has been reached[#65](https://github.com/agustinl/svelte-tags-input/issues/65) 40 | * **Fix:** matches list stays open on blur [#64](https://github.com/agustinl/svelte-tags-input/issues/64) 41 | * Remove unused `acorn` dependency [#61](https://github.com/agustinl/svelte-tags-input/issues/61) 42 | ## 2.9.2 43 | * **Fix:** keyboard navigation of suggestions broken [#59](https://github.com/agustinl/svelte-tags-input/issues/59) 44 | 45 | ## 2.9.1 46 | * **Fix:** onBlur bug. [#58](https://github.com/agustinl/svelte-tags-input/issues/58) 47 | ## 2.9.0 48 | [#52](https://github.com/agustinl/svelte-tags-input/pull/52) thanks to [@mildred](https://github.com/mildred) 49 | * HTML escape autoComplete results and allow custom HTML 50 | * Add option `autoCompleteFilter` to disable filtering after autoComplete 51 | * Add class when input is focused 52 | * If autoComplete is a function, pass the search value 53 | * If autoComplete function returns a Promise, resolve it 54 | * Add possibility to set `minChars` to 0 to show all autoComplete results without filter on input click. [#55](https://github.com/agustinl/svelte-tags-input/issues/55) 55 | ## 2.7.1 56 | * **Add:** `onlyAutocomplete` prop, to only accept tags inside the auto complete list [#41](https://github.com/agustinl/svelte-tags-input/issues/41) 57 | * Dependencies updated 58 | ## 2.7.0 59 | 60 | * Allow `autoComplete` to handle asynchronous data [#35](https://github.com/agustinl/svelte-tags-input/issues/35) 61 | * **Add:** `autoCompleteKey` option for array of objects, to choose what key search on `autoComplete` results 62 | ## 2.6.5 63 | 64 | * Show input after removing the tag using remove keys [#34](https://github.com/agustinl/svelte-tags-input/pull/34) 65 | 66 | ## 2.6.4 67 | * Allow create a tag with tab, and change the focus if there is no tag [#32](https://github.com/agustinl/svelte-tags-input/issues/32) 68 | 69 | ## 2.6.3 70 | * **Add:** `minChars` option: minimum length of search text to show auto-complete list [#28](https://github.com/agustinl/svelte-tags-input/issues/28) 71 | * Change homepage in package.json 72 | * Prevent writing if the maximum number of tags allowed is reached [#25](https://github.com/agustinl/svelte-tags-input/issues/25) 73 | * Highlight the matching characters in the auto-complete list 74 | * **Fix:** bug [#30](https://github.com/agustinl/svelte-tags-input/issues/30) 75 | 76 | ## 2.5.1 77 | * **Fix:** deleting last tag while input is not empty [#26](https://github.com/agustinl/svelte-tags-input/issues/26) 78 | 79 | ## 2.5.0 80 | * **Add:** the `on:blur` event 81 | * Removed duplicate ENTER and BACKSPACE check 82 | * **Add:** `disable` option 83 | 84 | ## 2.3.1 85 | * Update README 86 | 87 | ## 2.3.0 88 | * **Add:** a unique ID for each auto-complete list 89 | * If `onlyUnique === true` auto-complete list not show tags previously **Add:** 90 | * Enabled navigation with ARROW UP and ARROW DOWN the auto-complete list, and corrected the errors 91 | * Close auto-complete list and focus on tags input with ESC 92 | * Add selected tag in auto-complete list with ENTER 93 | * Enabled infinite scroll in auto-complete list 94 | * Fixed auto-complete list style to appear above content 95 | 96 | ## 2.2.1 97 | * **Add:** a unique ID for each input 98 | 99 | ## 2.2.0 100 | * Improve auto-complete [#10](https://github.com/agustinl/svelte-tags-input/issues/10) 101 | 102 | ## 2.1.0 103 | * **Add:** FAQs 104 | * **Add:** a way to reset the input tags [#7](https://github.com/agustinl/svelte-tags-input/issues/7) 105 | * **Add:** a way to initialize with tags 106 | 107 | ## 2.0.1 108 | * **Add:** CSS override instructions to documentation 109 | * **Add:** link to modify the current list of tags [#5](https://github.com/agustinl/svelte-tags-input/issues/5) to documentation 110 | 111 | ## 2.0.0 112 | * **Add:** auto complete feature [#4](https://github.com/agustinl/svelte-tags-input/issues/4) 113 | * **Add:** vendor prefixes to CSS 114 | 115 | ## 1.0.16 116 | * **Add:** paste or drop tag or group of tags 117 | 118 | ## 1.0.15 119 | * Blocking adding empty tag [#1](https://github.com/agustinl/svelte-tags-input/issues/1) 120 | -------------------------------------------------------------------------------- /src/Tags.svelte: -------------------------------------------------------------------------------- 1 | 373 | 374 |
375 | 376 | 377 | {#if tags.length > 0} 378 | {#each tags as tag, i} 379 | 389 | {/each} 390 | {/if} 391 | onBlur(e, tag)} 402 | on:pointerdown={onClick} 403 | class="svelte-tags-input" 404 | placeholder={placeholder} 405 | disabled={disable || readonly} 406 | autocomplete="off" 407 | > 408 |
409 | 410 | {#if autoComplete && arrelementsmatch.length > 0} 411 |
412 |
    413 | {#each arrelementsmatch as element, index} 414 |
  • addTag(element.label)}> 418 | {@html element.search} 419 |
  • 420 | {/each} 421 |
422 |
423 | {/if} 424 | 425 | 588 | --------------------------------------------------------------------------------