diff --git a/assets/controllers/elements/tagsinput_controller.js b/assets/controllers/elements/tagsinput_controller.js index 779e82da..4454089f 100644 --- a/assets/controllers/elements/tagsinput_controller.js +++ b/assets/controllers/elements/tagsinput_controller.js @@ -1,13 +1,47 @@ import {Controller} from "@hotwired/stimulus"; -import Bloodhound from "corejs-typeahead/dist/bloodhound"; -import 'corejs-typeahead'; -import '../../js/lib/tagsinput'; -import '../../css/tagsinput.css' +import "tom-select/dist/css/tom-select.bootstrap5.css"; +import '../../css/tom-select_extensions.css'; +import TomSelect from "tom-select"; export default class extends Controller { + _tomSelect; + connect() { + + let settings = { + plugins: { + remove_button:{ + } + }, + persistent: false, + createOnBlur: true, + create: true, + }; + if(this.element.dataset.autocomplete) { + const base_url = this.element.dataset.autocomplete; + settings.load = (query, callback) => { + if(query.length < 2){ + callback(); + return; + } + const url = base_url.replace('__QUERY__', encodeURIComponent(query)); + + fetch(url) + .then(response => response.json()) + .then(json => { + const data = json.map(x => {return {"value": x, "text": x}}); + callback(data); + }).catch(()=>{ + callback(); + }); + } + } + + this._tomSelect = new TomSelect(this.element, settings); + + /*if(this.element.dataset.autocomplete) { const engine = new Bloodhound({ //@ts-ignore datumTokenizer: Bloodhound.tokenizers.obj.whitespace(''), @@ -27,6 +61,8 @@ export default class extends Controller { }); } else { // Init tagsinput without typeahead $(this.element).tagsinput(); - } + }*/ + + } } \ No newline at end of file diff --git a/assets/css/tagsinput.css b/assets/css/tagsinput.css deleted file mode 100644 index e3ff2c34..00000000 --- a/assets/css/tagsinput.css +++ /dev/null @@ -1,64 +0,0 @@ -/* - * bootstrap-tagsinput v0.8.0 - * Modified by Jan Böhmer 2019 - * (Added some margin between the tags. - */ - -.bootstrap-tagsinput { - background-color: #fff; - border: 1px solid #ccc; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - display: inline-block; - padding: 4px 6px; - color: #555; - vertical-align: middle; - border-radius: 4px; - width: 100%; - line-height: 22px; - cursor: text; -} -.bootstrap-tagsinput input { - border: none; - box-shadow: none; - outline: none; - background-color: transparent; - padding: 0 6px; - margin: 0; - width: auto; - max-width: inherit; -} -.bootstrap-tagsinput.form-control input::-moz-placeholder { - color: #777; - opacity: 1; -} -.bootstrap-tagsinput.form-control input:-ms-input-placeholder { - color: #777; -} -.bootstrap-tagsinput.form-control input::-webkit-input-placeholder { - color: #777; -} -.bootstrap-tagsinput input:focus { - border: none; - box-shadow: none; -} -.bootstrap-tagsinput .badge { - margin: 2px 0.2em; - padding:5px 8px; -} -.bootstrap-tagsinput .badge [data-role="remove"] { - margin-left: 8px; - cursor: pointer; -} -.bootstrap-tagsinput .badge [data-role="remove"]:after { - content: "×"; - padding: 0px 4px; - background-color:rgba(0, 0, 0, 0.1); - border-radius:50%; - font-size:13px -} -.bootstrap-tagsinput .badge [data-role="remove"]:hover:after { - - background-color:rgba(0, 0, 0, 0.62);} -.bootstrap-tagsinput .badge [data-role="remove"]:hover:active { - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); -} diff --git a/assets/css/tom-select_extensions.css b/assets/css/tom-select_extensions.css new file mode 100644 index 00000000..6b57888c --- /dev/null +++ b/assets/css/tom-select_extensions.css @@ -0,0 +1,4 @@ +.tagsinput.ts-wrapper.multi .ts-control > div { + background: var(--bs-secondary); + color: var(--bs-white); +} \ No newline at end of file diff --git a/assets/js/lib/tagsinput.js b/assets/js/lib/tagsinput.js deleted file mode 100644 index 71a9015c..00000000 --- a/assets/js/lib/tagsinput.js +++ /dev/null @@ -1,687 +0,0 @@ -/* - * bootstrap-tagsinput v0.8.0 - * - */ - -(function ($) { - "use strict"; - - var defaultOptions = { - tagClass: function(item) { - return 'badge bg-info'; - }, - focusClass: 'focus', - itemValue: function(item) { - return item ? item.toString() : item; - }, - itemText: function(item) { - return this.itemValue(item); - }, - itemTitle: function(item) { - return null; - }, - freeInput: true, - addOnBlur: true, - maxTags: undefined, - maxChars: undefined, - confirmKeys: [13, 44], - delimiter: ',', - delimiterRegex: null, - cancelConfirmKeysOnEmpty: false, - onTagExists: function(item, $tag) { - $tag.hide().fadeIn(); - }, - trimValue: false, - allowDuplicates: false, - triggerChange: true - }; - - /** - * Constructor function - */ - function TagsInput(element, options) { - this.isInit = true; - this.itemsArray = []; - - this.$element = $(element); - this.$element.addClass('sr-only'); - - this.isSelect = (element.tagName === 'SELECT'); - this.multiple = (this.isSelect && element.hasAttribute('multiple')); - this.objectItems = options && options.itemValue; - this.placeholderText = element.hasAttribute('placeholder') ? this.$element.attr('placeholder') : ''; - this.inputSize = Math.max(1, this.placeholderText.length); - - this.$container = $('
'); - this.$input = $('').appendTo(this.$container); - - this.$element.before(this.$container); - - this.build(options); - this.isInit = false; - } - - TagsInput.prototype = { - constructor: TagsInput, - - /** - * Adds the given item as a new tag. Pass true to dontPushVal to prevent - * updating the elements val() - */ - add: function(item, dontPushVal, options) { - var self = this; - - if (self.options.maxTags && self.itemsArray.length >= self.options.maxTags) - return; - - // Ignore falsey values, except false - if (item !== false && !item) - return; - - // Trim value - if (typeof item === "string" && self.options.trimValue) { - item = $.trim(item); - } - - // Throw an error when trying to add an object while the itemValue option was not set - if (typeof item === "object" && !self.objectItems) - throw("Can't add objects when itemValue option is not set"); - - // Ignore strings only containg whitespace - if (item.toString().match(/^\s*$/)) - return; - - // If SELECT but not multiple, remove current tag - if (self.isSelect && !self.multiple && self.itemsArray.length > 0) - self.remove(self.itemsArray[0]); - - if (typeof item === "string" && this.$element[0].tagName === 'INPUT') { - var delimiter = (self.options.delimiterRegex) ? self.options.delimiterRegex : self.options.delimiter; - var items = item.split(delimiter); - if (items.length > 1) { - for (var i = 0; i < items.length; i++) { - this.add(items[i], true); - } - - if (!dontPushVal) - self.pushVal(self.options.triggerChange); - return; - } - } - - var itemValue = self.options.itemValue(item), - itemText = self.options.itemText(item), - tagClass = self.options.tagClass(item), - itemTitle = self.options.itemTitle(item); - - // Ignore items allready added - var existing = $.grep(self.itemsArray, function(item) { return self.options.itemValue(item) === itemValue; } )[0]; - if (existing && !self.options.allowDuplicates) { - // Invoke onTagExists - if (self.options.onTagExists) { - var $existingTag = $(".badge", self.$container).filter(function() { return $(this).data("item") === existing; }); - self.options.onTagExists(item, $existingTag); - } - return; - } - - // if length greater than limit - if (self.items().toString().length + item.length + 1 > self.options.maxInputLength) - return; - - // raise beforeItemAdd arg - var beforeItemAddEvent = $.Event('beforeItemAdd', { item: item, cancel: false, options: options}); - self.$element.trigger(beforeItemAddEvent); - if (beforeItemAddEvent.cancel) - return; - - // register item in internal array and map - self.itemsArray.push(item); - - // add a tag element - - var $tag = $('' + htmlEncode(itemText) + ''); - $tag.data('item', item); - self.findInputWrapper().before($tag); - - // Check to see if the tag exists in its raw or uri-encoded form - var optionExists = ( - $('option[value="' + encodeURIComponent(itemValue) + '"]', self.$element).length || - $('option[value="' + htmlEncode(itemValue) + '"]', self.$element).length - ); - - // add if item represents a value not present in one of the 's options - if (self.isSelect && !optionExists) { - var $option = $(''); - $option.data('item', item); - $option.attr('value', itemValue); - self.$element.append($option); - } - - if (!dontPushVal) - self.pushVal(self.options.triggerChange); - - // Add class when reached maxTags - if (self.options.maxTags === self.itemsArray.length || self.items().toString().length === self.options.maxInputLength) - self.$container.addClass('bootstrap-tagsinput-max'); - - // If using typeahead, once the tag has been added, clear the typeahead value so it does not stick around in the input. - if ($('.typeahead, .twitter-typeahead', self.$container).length) { - self.$input.typeahead('val', ''); - } - - if (this.isInit) { - self.$element.trigger($.Event('itemAddedOnInit', { item: item, options: options })); - } else { - self.$element.trigger($.Event('itemAdded', { item: item, options: options })); - } - }, - - /** - * Removes the given item. Pass true to dontPushVal to prevent updating the - * elements val() - */ - remove: function(item, dontPushVal, options) { - var self = this; - - if (self.objectItems) { - if (typeof item === "object") - item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) == self.options.itemValue(item); } ); - else - item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) == item; } ); - - item = item[item.length-1]; - } - - if (item) { - var beforeItemRemoveEvent = $.Event('beforeItemRemove', { item: item, cancel: false, options: options }); - self.$element.trigger(beforeItemRemoveEvent); - if (beforeItemRemoveEvent.cancel) - return; - - $('.badge', self.$container).filter(function() { return $(this).data('item') === item; }).remove(); - $('option', self.$element).filter(function() { return $(this).data('item') === item; }).remove(); - if($.inArray(item, self.itemsArray) !== -1) - self.itemsArray.splice($.inArray(item, self.itemsArray), 1); - } - - if (!dontPushVal) - self.pushVal(self.options.triggerChange); - - // Remove class when reached maxTags - if (self.options.maxTags > self.itemsArray.length) - self.$container.removeClass('bootstrap-tagsinput-max'); - - self.$element.trigger($.Event('itemRemoved', { item: item, options: options })); - }, - - /** - * Removes all items - */ - removeAll: function() { - var self = this; - - $('.badge', self.$container).remove(); - $('option', self.$element).remove(); - - while(self.itemsArray.length > 0) - self.itemsArray.pop(); - - self.pushVal(self.options.triggerChange); - }, - - /** - * Refreshes the tags so they match the text/value of their corresponding - * item. - */ - refresh: function() { - var self = this; - $('.badge', self.$container).each(function() { - var $tag = $(this), - item = $tag.data('item'), - itemValue = self.options.itemValue(item), - itemText = self.options.itemText(item), - tagClass = self.options.tagClass(item); - - // Update tag's class and inner text - $tag.attr('class', null); - $tag.addClass('badge ' + htmlEncode(tagClass)); - $tag.contents().filter(function() { - return this.nodeType == 3; - })[0].nodeValue = htmlEncode(itemText); - - if (self.isSelect) { - var option = $('option', self.$element).filter(function() { return $(this).data('item') === item; }); - option.attr('value', itemValue); - } - }); - }, - - /** - * Returns the items added as tags - */ - items: function() { - return this.itemsArray; - }, - - /** - * Assembly value by retrieving the value of each item, and set it on the - * element. - */ - pushVal: function() { - var self = this, - val = $.map(self.items(), function(item) { - return self.options.itemValue(item).toString(); - }); - - self.$element.val( val.join(self.options.delimiter) ); - - if (self.options.triggerChange) - self.$element.trigger('change'); - }, - - /** - * Initializes the tags input behaviour on the element - */ - build: function(options) { - var self = this; - - self.options = $.extend({}, defaultOptions, options); - // When itemValue is set, freeInput should always be false - if (self.objectItems) - self.options.freeInput = false; - - makeOptionItemFunction(self.options, 'itemValue'); - makeOptionItemFunction(self.options, 'itemText'); - makeOptionFunction(self.options, 'tagClass'); - - // Typeahead Bootstrap version 2.3.2 - if (self.options.typeahead) { - var typeahead = self.options.typeahead || {}; - - makeOptionFunction(typeahead, 'source'); - - self.$input.typeahead($.extend({}, typeahead, { - source: function (query, process) { - function processItems(items) { - var texts = []; - - for (var i = 0; i < items.length; i++) { - var text = self.options.itemText(items[i]); - map[text] = items[i]; - texts.push(text); - } - process(texts); - } - - this.map = {}; - var map = this.map, - data = typeahead.source(query); - - if ($.isFunction(data.success)) { - // support for Angular callbacks - data.success(processItems); - } else if ($.isFunction(data.then)) { - // support for Angular promises - data.then(processItems); - } else { - // support for functions and jquery promises - $.when(data) - .then(processItems); - } - }, - updater: function (text) { - self.add(this.map[text]); - return this.map[text]; - }, - matcher: function (text) { - return (text.toLowerCase().indexOf(this.query.trim().toLowerCase()) !== -1); - }, - sorter: function (texts) { - return texts.sort(); - }, - highlighter: function (text) { - var regex = new RegExp( '(' + this.query + ')', 'gi' ); - return text.replace( regex, "$1" ); - } - })); - } - - // typeahead.js - if (self.options.typeaheadjs) { - // Determine if main configurations were passed or simply a dataset - var typeaheadjs = self.options.typeaheadjs; - if (!$.isArray(typeaheadjs)) { - typeaheadjs = [null, typeaheadjs]; - } - - $.fn.typeahead.apply(self.$input, typeaheadjs).on('typeahead:selected', $.proxy(function (obj, datum, name) { - var index = 0; - typeaheadjs.some(function(dataset, _index) { - if (dataset.name === name) { - index = _index; - return true; - } - return false; - }); - - // @TODO Dep: https://github.com/corejavascript/typeahead.js/issues/89 - if (typeaheadjs[index].valueKey) { - self.add(datum[typeaheadjs[index].valueKey]); - } else { - self.add(datum); - } - - self.$input.typeahead('val', ''); - }, self)); - } - - self.$container.on('click', $.proxy(function(event) { - if (! self.$element.attr('disabled')) { - self.$input.removeAttr('disabled'); - } - self.$input.focus(); - }, self)); - - if (self.options.addOnBlur && self.options.freeInput) { - self.$input.on('focusout', $.proxy(function(event) { - // HACK: only process on focusout when no typeahead opened, to - // avoid adding the typeahead text as tag - if ($('.typeahead, .twitter-typeahead', self.$container).length === 0) { - self.add(self.$input.val()); - self.$input.val(''); - } - }, self)); - } - - // Toggle the 'focus' css class on the container when it has focus - self.$container.on({ - focusin: function() { - self.$container.addClass(self.options.focusClass); - }, - focusout: function() { - self.$container.removeClass(self.options.focusClass); - }, - }); - - self.$container.on('keydown', 'input', $.proxy(function(event) { - var $input = $(event.target), - $inputWrapper = self.findInputWrapper(); - - if (self.$element.attr('disabled')) { - self.$input.attr('disabled', 'disabled'); - return; - } - - switch (event.which) { - // BACKSPACE - case 8: - if (doGetCaretPosition($input[0]) === 0) { - var prev = $inputWrapper.prev(); - if (prev.length) { - self.remove(prev.data('item')); - } - } - break; - - // DELETE - case 46: - if (doGetCaretPosition($input[0]) === 0) { - var next = $inputWrapper.next(); - if (next.length) { - self.remove(next.data('item')); - } - } - break; - - // LEFT ARROW - case 37: - // Try to move the input before the previous tag - var $prevTag = $inputWrapper.prev(); - if ($input.val().length === 0 && $prevTag[0]) { - $prevTag.before($inputWrapper); - $input.focus(); - } - break; - // RIGHT ARROW - case 39: - // Try to move the input after the next tag - var $nextTag = $inputWrapper.next(); - if ($input.val().length === 0 && $nextTag[0]) { - $nextTag.after($inputWrapper); - $input.focus(); - } - break; - default: - // ignore - } - - // Reset internal input's size - var textLength = $input.val().length, - wordSpace = Math.ceil(textLength / 5), - size = textLength + wordSpace + 1; - $input.attr('size', Math.max(this.inputSize, size)); - }, self)); - - self.$container.on('keypress', 'input', $.proxy(function(event) { - var $input = $(event.target); - - if (self.$element.attr('disabled')) { - self.$input.attr('disabled', 'disabled'); - return; - } - - var text = $input.val(), - maxLengthReached = self.options.maxChars && text.length >= self.options.maxChars; - if (self.options.freeInput && (keyCombinationInList(event, self.options.confirmKeys) || maxLengthReached)) { - // Only attempt to add a tag if there is data in the field - if (text.length !== 0) { - self.add(maxLengthReached ? text.substr(0, self.options.maxChars) : text); - $input.val(''); - } - - // If the field is empty, let the event triggered fire as usual - if (self.options.cancelConfirmKeysOnEmpty === false) { - event.preventDefault(); - } - } - - // Reset internal input's size - var textLength = $input.val().length, - wordSpace = Math.ceil(textLength / 5), - size = textLength + wordSpace + 1; - $input.attr('size', Math.max(this.inputSize, size)); - }, self)); - - // Remove icon clicked - self.$container.on('click', '[data-role=remove]', $.proxy(function(event) { - if (self.$element.attr('disabled')) { - return; - } - self.remove($(event.target).closest('.badge').data('item')); - }, self)); - - // Only add existing value as tags when using strings as tags - if (self.options.itemValue === defaultOptions.itemValue) { - if (self.$element[0].tagName === 'INPUT') { - self.add(self.$element.val()); - } else { - $('option', self.$element).each(function() { - self.add($(this).attr('value'), true); - }); - } - } - }, - - /** - * Removes all tagsinput behaviour and unregsiter all event handlers - */ - destroy: function() { - var self = this; - - // Unbind events - self.$container.off('keypress', 'input'); - self.$container.off('click', '[role=remove]'); - - self.$container.remove(); - self.$element.removeData('tagsinput'); - self.$element.show(); - }, - - /** - * Sets focus on the tagsinput - */ - focus: function() { - this.$input.focus(); - }, - - /** - * Returns the internal input element - */ - input: function() { - return this.$input; - }, - - /** - * Returns the element which is wrapped around the internal input. This - * is normally the $container, but typeahead.js moves the $input element. - */ - findInputWrapper: function() { - var elt = this.$input[0], - container = this.$container[0]; - while(elt && elt.parentNode !== container) - elt = elt.parentNode; - - return $(elt); - } - }; - - /** - * Register JQuery plugin - */ - $.fn.tagsinput = function(arg1, arg2, arg3) { - var results = []; - - this.each(function() { - var tagsinput = $(this).data('tagsinput'); - // Initialize a new tags input - if (!tagsinput) { - tagsinput = new TagsInput(this, arg1); - $(this).data('tagsinput', tagsinput); - results.push(tagsinput); - - if (this.tagName === 'SELECT') { - $('option', $(this)).attr('selected', 'selected'); - } - - // Init tags from $(this).val() - $(this).val($(this).val()); - } else if (!arg1 && !arg2) { - // tagsinput already exists - // no function, trying to init - results.push(tagsinput); - } else if(tagsinput[arg1] !== undefined) { - // Invoke function on existing tags input - if(tagsinput[arg1].length === 3 && arg3 !== undefined){ - var retVal = tagsinput[arg1](arg2, null, arg3); - }else{ - var retVal = tagsinput[arg1](arg2); - } - if (retVal !== undefined) - results.push(retVal); - } - }); - - if ( typeof arg1 == 'string') { - // Return the results from the invoked function calls - return results.length > 1 ? results : results[0]; - } else { - return results; - } - }; - - $.fn.tagsinput.Constructor = TagsInput; - - /** - * Most options support both a string or number as well as a function as - * option value. This function makes sure that the option with the given - * key in the given options is wrapped in a function - */ - function makeOptionItemFunction(options, key) { - if (typeof options[key] !== 'function') { - var propertyName = options[key]; - options[key] = function(item) { return item[propertyName]; }; - } - } - function makeOptionFunction(options, key) { - if (typeof options[key] !== 'function') { - var value = options[key]; - options[key] = function() { return value; }; - } - } - /** - * HtmlEncodes the given value - */ - var htmlEncodeContainer = $(''); - function htmlEncode(value) { - if (value) { - return htmlEncodeContainer.text(value).html(); - } else { - return ''; - } - } - - /** - * Returns the position of the caret in the given input field - * http://flightschool.acylt.com/devnotes/caret-position-woes/ - */ - function doGetCaretPosition(oField) { - var iCaretPos = 0; - if (document.selection) { - oField.focus (); - var oSel = document.selection.createRange(); - oSel.moveStart ('character', -oField.value.length); - iCaretPos = oSel.text.length; - } else if (oField.selectionStart || oField.selectionStart == '0') { - iCaretPos = oField.selectionStart; - } - return (iCaretPos); - } - - /** - * Returns boolean indicates whether user has pressed an expected key combination. - * @param object keyPressEvent: JavaScript event object, refer - * http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html - * @param object lookupList: expected key combinations, as in: - * [13, {which: 188, shiftKey: true}] - */ - function keyCombinationInList(keyPressEvent, lookupList) { - var found = false; - $.each(lookupList, function (index, keyCombination) { - if (typeof (keyCombination) === 'number' && keyPressEvent.which === keyCombination) { - found = true; - return false; - } - - if (keyPressEvent.which === keyCombination.which) { - var alt = !keyCombination.hasOwnProperty('altKey') || keyPressEvent.altKey === keyCombination.altKey, - shift = !keyCombination.hasOwnProperty('shiftKey') || keyPressEvent.shiftKey === keyCombination.shiftKey, - ctrl = !keyCombination.hasOwnProperty('ctrlKey') || keyPressEvent.ctrlKey === keyCombination.ctrlKey; - if (alt && shift && ctrl) { - found = true; - return false; - } - } - }); - - return found; - } - - /** - * Initialize tagsinput behaviour on inputs and selects which have - * data-role=tagsinput - */ - $(function() { - $("input[data-role=tagsinput], select[multiple][data-role=tagsinput]").tagsinput(); - }); -})(window.jQuery); diff --git a/package.json b/package.json index 7e5bc622..edcb3331 100644 --- a/package.json +++ b/package.json @@ -83,6 +83,7 @@ "patternfly-bootstrap-treeview": "^2.1.8", "pdfmake": "^0.2.2", "stimulus-use": "^0.50.0", + "tom-select": "^2.1.0", "ts-loader": "^9.2.6", "typescript": "^4.0.2", "u2f-api": "^1.1.1" diff --git a/src/Controller/TypeaheadController.php b/src/Controller/TypeaheadController.php index 6d627408..f69f137e 100644 --- a/src/Controller/TypeaheadController.php +++ b/src/Controller/TypeaheadController.php @@ -112,6 +112,7 @@ class TypeaheadController extends AbstractController $encoders = [ new JsonEncoder(), ]; + $serializer = new Serializer($normalizers, $encoders); $data = $serializer->serialize($array, 'json'); diff --git a/src/Form/Part/PartBaseType.php b/src/Form/Part/PartBaseType.php index 31eca1d9..64df35b6 100644 --- a/src/Form/Part/PartBaseType.php +++ b/src/Form/Part/PartBaseType.php @@ -148,7 +148,7 @@ class PartBaseType extends AbstractType 'attr' => [ 'class' => 'tagsinput', 'data-controller' => 'elements--tagsinput', - 'data-autocomplete' => $this->urlGenerator->generate('typeahead_tags', ['query' => 'QUERY']), + 'data-autocomplete' => $this->urlGenerator->generate('typeahead_tags', ['query' => '__QUERY__']), ], 'disabled' => !$this->security->isGranted('tags.edit', $part), ]); diff --git a/src/Services/TagFinder.php b/src/Services/TagFinder.php index 27743f59..0292304b 100644 --- a/src/Services/TagFinder.php +++ b/src/Services/TagFinder.php @@ -108,8 +108,8 @@ class TagFinder { $resolver->setDefaults([ 'query_limit' => 75, - 'return_limit' => 25, - 'min_keyword_length' => 3, + 'return_limit' => 75, + 'min_keyword_length' => 2, ]); } } diff --git a/yarn.lock b/yarn.lock index b820f832..afc378d0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1440,6 +1440,11 @@ error-stack-parser "^2.0.0" string-width "^4.2.3" +"@orchidjs/sifter@^0.9.2": + version "0.9.3" + resolved "https://registry.yarnpkg.com/@orchidjs/sifter/-/sifter-0.9.3.tgz#6eec2c9649721205130a87f137cc1ab80cdf0c5c" + integrity sha512-9XGiAJcWvEektxjR9X+dYeG+kg8GdojM6ZCmrnuDaWoVew+GAKxiesvYxyY+RLUgWTv8B1qpLIVYlswxKcW5XQ== + "@polka/url@^1.0.0-next.20": version "1.0.0-next.21" resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1" @@ -6123,6 +6128,13 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== +tom-select@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tom-select/-/tom-select-2.1.0.tgz#93316cf042a69d9462027b8d6380f18f2a002e9d" + integrity sha512-NtE8kACBlMv4QaDakYfnXtEAgM/AVmM7Hw5FNQmij0uwgRgyXC/2kpNJPD1AdT5q/l6mUNkTnInQpTmrwX/tWQ== + dependencies: + "@orchidjs/sifter" "^0.9.2" + totalist@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df"