svelte-tags-input
Version:
Fully customizable Svelte component to enter tags.
1,455 lines (1,296 loc) • 45.8 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Tags = factory());
})(this, (function () { 'use strict';
function noop() { }
function run(fn) {
return fn();
}
function blank_object() {
return Object.create(null);
}
function run_all(fns) {
fns.forEach(run);
}
function is_function(thing) {
return typeof thing === 'function';
}
function safe_not_equal(a, b) {
return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');
}
function is_empty(obj) {
return Object.keys(obj).length === 0;
}
function null_to_empty(value) {
return value == null ? '' : value;
}
function append(target, node) {
target.appendChild(node);
}
function insert(target, node, anchor) {
target.insertBefore(node, anchor || null);
}
function detach(node) {
node.parentNode.removeChild(node);
}
function destroy_each(iterations, detaching) {
for (let i = 0; i < iterations.length; i += 1) {
if (iterations[i])
iterations[i].d(detaching);
}
}
function element(name) {
return document.createElement(name);
}
function svg_element(name) {
return document.createElementNS('http://www.w3.org/2000/svg', name);
}
function text(data) {
return document.createTextNode(data);
}
function space() {
return text(' ');
}
function empty() {
return text('');
}
function listen(node, event, handler, options) {
node.addEventListener(event, handler, options);
return () => node.removeEventListener(event, handler, options);
}
function prevent_default(fn) {
return function (event) {
event.preventDefault();
// @ts-ignore
return fn.call(this, event);
};
}
function attr(node, attribute, value) {
if (value == null)
node.removeAttribute(attribute);
else if (node.getAttribute(attribute) !== value)
node.setAttribute(attribute, value);
}
function children(element) {
return Array.from(element.childNodes);
}
function set_data(text, data) {
data = '' + data;
if (text.wholeText !== data)
text.data = data;
}
function set_input_value(input, value) {
input.value = value == null ? '' : value;
}
function toggle_class(element, name, toggle) {
element.classList[toggle ? 'add' : 'remove'](name);
}
class HtmlTag {
constructor(is_svg = false) {
this.is_svg = false;
this.is_svg = is_svg;
this.e = this.n = null;
}
c(html) {
this.h(html);
}
m(html, target, anchor = null) {
if (!this.e) {
if (this.is_svg)
this.e = svg_element(target.nodeName);
else
this.e = element(target.nodeName);
this.t = target;
this.c(html);
}
this.i(anchor);
}
h(html) {
this.e.innerHTML = html;
this.n = Array.from(this.e.childNodes);
}
i(anchor) {
for (let i = 0; i < this.n.length; i += 1) {
insert(this.t, this.n[i], anchor);
}
}
p(html) {
this.d();
this.h(html);
this.i(this.a);
}
d() {
this.n.forEach(detach);
}
}
let current_component;
function set_current_component(component) {
current_component = component;
}
const dirty_components = [];
const binding_callbacks = [];
const render_callbacks = [];
const flush_callbacks = [];
const resolved_promise = Promise.resolve();
let update_scheduled = false;
function schedule_update() {
if (!update_scheduled) {
update_scheduled = true;
resolved_promise.then(flush);
}
}
function add_render_callback(fn) {
render_callbacks.push(fn);
}
// flush() calls callbacks in this order:
// 1. All beforeUpdate callbacks, in order: parents before children
// 2. All bind:this callbacks, in reverse order: children before parents.
// 3. All afterUpdate callbacks, in order: parents before children. EXCEPT
// for afterUpdates called during the initial onMount, which are called in
// reverse order: children before parents.
// Since callbacks might update component values, which could trigger another
// call to flush(), the following steps guard against this:
// 1. During beforeUpdate, any updated components will be added to the
// dirty_components array and will cause a reentrant call to flush(). Because
// the flush index is kept outside the function, the reentrant call will pick
// up where the earlier call left off and go through all dirty components. The
// current_component value is saved and restored so that the reentrant call will
// not interfere with the "parent" flush() call.
// 2. bind:this callbacks cannot trigger new flush() calls.
// 3. During afterUpdate, any updated components will NOT have their afterUpdate
// callback called a second time; the seen_callbacks set, outside the flush()
// function, guarantees this behavior.
const seen_callbacks = new Set();
let flushidx = 0; // Do *not* move this inside the flush() function
function flush() {
const saved_component = current_component;
do {
// first, call beforeUpdate functions
// and update components
while (flushidx < dirty_components.length) {
const component = dirty_components[flushidx];
flushidx++;
set_current_component(component);
update(component.$$);
}
set_current_component(null);
dirty_components.length = 0;
flushidx = 0;
while (binding_callbacks.length)
binding_callbacks.pop()();
// then, once components are updated, call
// afterUpdate functions. This may cause
// subsequent updates...
for (let i = 0; i < render_callbacks.length; i += 1) {
const callback = render_callbacks[i];
if (!seen_callbacks.has(callback)) {
// ...so guard against infinite loops
seen_callbacks.add(callback);
callback();
}
}
render_callbacks.length = 0;
} while (dirty_components.length);
while (flush_callbacks.length) {
flush_callbacks.pop()();
}
update_scheduled = false;
seen_callbacks.clear();
set_current_component(saved_component);
}
function update($$) {
if ($$.fragment !== null) {
$$.update();
run_all($$.before_update);
const dirty = $$.dirty;
$$.dirty = [-1];
$$.fragment && $$.fragment.p($$.ctx, dirty);
$$.after_update.forEach(add_render_callback);
}
}
const outroing = new Set();
function transition_in(block, local) {
if (block && block.i) {
outroing.delete(block);
block.i(local);
}
}
function mount_component(component, target, anchor, customElement) {
const { fragment, on_mount, on_destroy, after_update } = component.$$;
fragment && fragment.m(target, anchor);
if (!customElement) {
// onMount happens before the initial afterUpdate
add_render_callback(() => {
const new_on_destroy = on_mount.map(run).filter(is_function);
if (on_destroy) {
on_destroy.push(...new_on_destroy);
}
else {
// Edge case - component was destroyed immediately,
// most likely as a result of a binding initialising
run_all(new_on_destroy);
}
component.$$.on_mount = [];
});
}
after_update.forEach(add_render_callback);
}
function destroy_component(component, detaching) {
const $$ = component.$$;
if ($$.fragment !== null) {
run_all($$.on_destroy);
$$.fragment && $$.fragment.d(detaching);
// TODO null out other refs, including component.$$ (but need to
// preserve final state?)
$$.on_destroy = $$.fragment = null;
$$.ctx = [];
}
}
function make_dirty(component, i) {
if (component.$$.dirty[0] === -1) {
dirty_components.push(component);
schedule_update();
component.$$.dirty.fill(0);
}
component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));
}
function init(component, options, instance, create_fragment, not_equal, props, append_styles, dirty = [-1]) {
const parent_component = current_component;
set_current_component(component);
const $$ = component.$$ = {
fragment: null,
ctx: null,
// state
props,
update: noop,
not_equal,
bound: blank_object(),
// lifecycle
on_mount: [],
on_destroy: [],
on_disconnect: [],
before_update: [],
after_update: [],
context: new Map(options.context || (parent_component ? parent_component.$$.context : [])),
// everything else
callbacks: blank_object(),
dirty,
skip_bound: false,
root: options.target || parent_component.$$.root
};
append_styles && append_styles($$.root);
let ready = false;
$$.ctx = instance
? instance(component, options.props || {}, (i, ret, ...rest) => {
const value = rest.length ? rest[0] : ret;
if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {
if (!$$.skip_bound && $$.bound[i])
$$.bound[i](value);
if (ready)
make_dirty(component, i);
}
return ret;
})
: [];
$$.update();
ready = true;
run_all($$.before_update);
// `false` as a special case of no DOM component
$$.fragment = create_fragment ? create_fragment($$.ctx) : false;
if (options.target) {
if (options.hydrate) {
const nodes = children(options.target);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
$$.fragment && $$.fragment.l(nodes);
nodes.forEach(detach);
}
else {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
$$.fragment && $$.fragment.c();
}
if (options.intro)
transition_in(component.$$.fragment);
mount_component(component, options.target, options.anchor, options.customElement);
flush();
}
set_current_component(parent_component);
}
/**
* Base class for Svelte components. Used when dev=false.
*/
class SvelteComponent {
$destroy() {
destroy_component(this, 1);
this.$destroy = noop;
}
$on(type, callback) {
const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));
callbacks.push(callback);
return () => {
const index = callbacks.indexOf(callback);
if (index !== -1)
callbacks.splice(index, 1);
};
}
$set($$props) {
if (this.$$set && !is_empty($$props)) {
this.$$.skip_bound = true;
this.$$set($$props);
this.$$.skip_bound = false;
}
}
}
/* src\Tags.svelte generated by Svelte v3.49.0 */
function get_each_context(ctx, list, i) {
const child_ctx = ctx.slice();
child_ctx[54] = list[i];
child_ctx[56] = i;
return child_ctx;
}
function get_each_context_1(ctx, list, i) {
const child_ctx = ctx.slice();
child_ctx[14] = list[i];
child_ctx[58] = i;
return child_ctx;
}
// (377:4) {#if tags.length > 0}
function create_if_block_1(ctx) {
let each_1_anchor;
let each_value_1 = /*tags*/ ctx[0];
let each_blocks = [];
for (let i = 0; i < each_value_1.length; i += 1) {
each_blocks[i] = create_each_block_1(get_each_context_1(ctx, each_value_1, i));
}
return {
c() {
for (let i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].c();
}
each_1_anchor = empty();
},
m(target, anchor) {
for (let i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].m(target, anchor);
}
insert(target, each_1_anchor, anchor);
},
p(ctx, dirty) {
if (dirty[0] & /*onTagClick, tags, removeTag, disable, readonly, autoCompleteShowKey*/ 132897) {
each_value_1 = /*tags*/ ctx[0];
let i;
for (i = 0; i < each_value_1.length; i += 1) {
const child_ctx = get_each_context_1(ctx, each_value_1, i);
if (each_blocks[i]) {
each_blocks[i].p(child_ctx, dirty);
} else {
each_blocks[i] = create_each_block_1(child_ctx);
each_blocks[i].c();
each_blocks[i].m(each_1_anchor.parentNode, each_1_anchor);
}
}
for (; i < each_blocks.length; i += 1) {
each_blocks[i].d(1);
}
each_blocks.length = each_value_1.length;
}
},
d(detaching) {
destroy_each(each_blocks, detaching);
if (detaching) detach(each_1_anchor);
}
};
}
// (382:16) {:else}
function create_else_block(ctx) {
let t_value = /*tag*/ ctx[14][/*autoCompleteShowKey*/ ctx[10]] + "";
let t;
return {
c() {
t = text(t_value);
},
m(target, anchor) {
insert(target, t, anchor);
},
p(ctx, dirty) {
if (dirty[0] & /*tags, autoCompleteShowKey*/ 1025 && t_value !== (t_value = /*tag*/ ctx[14][/*autoCompleteShowKey*/ ctx[10]] + "")) set_data(t, t_value);
},
d(detaching) {
if (detaching) detach(t);
}
};
}
// (380:16) {#if typeof tag === 'string'}
function create_if_block_3(ctx) {
let t_value = /*tag*/ ctx[14] + "";
let t;
return {
c() {
t = text(t_value);
},
m(target, anchor) {
insert(target, t, anchor);
},
p(ctx, dirty) {
if (dirty[0] & /*tags*/ 1 && t_value !== (t_value = /*tag*/ ctx[14] + "")) set_data(t, t_value);
},
d(detaching) {
if (detaching) detach(t);
}
};
}
// (385:16) {#if !disable && !readonly}
function create_if_block_2(ctx) {
let span;
let mounted;
let dispose;
function pointerdown_handler() {
return /*pointerdown_handler*/ ctx[43](/*i*/ ctx[58]);
}
return {
c() {
span = element("span");
span.textContent = "×";
attr(span, "class", "svelte-tags-input-tag-remove svelte-b5mxss");
},
m(target, anchor) {
insert(target, span, anchor);
if (!mounted) {
dispose = listen(span, "pointerdown", pointerdown_handler);
mounted = true;
}
},
p(new_ctx, dirty) {
ctx = new_ctx;
},
d(detaching) {
if (detaching) detach(span);
mounted = false;
dispose();
}
};
}
// (378:8) {#each tags as tag, i}
function create_each_block_1(ctx) {
let button;
let t0;
let t1;
let mounted;
let dispose;
function select_block_type(ctx, dirty) {
if (typeof /*tag*/ ctx[14] === 'string') return create_if_block_3;
return create_else_block;
}
let current_block_type = select_block_type(ctx);
let if_block0 = current_block_type(ctx);
let if_block1 = !/*disable*/ ctx[5] && !/*readonly*/ ctx[8] && create_if_block_2(ctx);
function click_handler() {
return /*click_handler*/ ctx[44](/*tag*/ ctx[14]);
}
return {
c() {
button = element("button");
if_block0.c();
t0 = space();
if (if_block1) if_block1.c();
t1 = space();
attr(button, "type", "button");
attr(button, "class", "svelte-tags-input-tag svelte-b5mxss");
},
m(target, anchor) {
insert(target, button, anchor);
if_block0.m(button, null);
append(button, t0);
if (if_block1) if_block1.m(button, null);
append(button, t1);
if (!mounted) {
dispose = listen(button, "click", click_handler);
mounted = true;
}
},
p(new_ctx, dirty) {
ctx = new_ctx;
if (current_block_type === (current_block_type = select_block_type(ctx)) && if_block0) {
if_block0.p(ctx, dirty);
} else {
if_block0.d(1);
if_block0 = current_block_type(ctx);
if (if_block0) {
if_block0.c();
if_block0.m(button, t0);
}
}
if (!/*disable*/ ctx[5] && !/*readonly*/ ctx[8]) {
if (if_block1) {
if_block1.p(ctx, dirty);
} else {
if_block1 = create_if_block_2(ctx);
if_block1.c();
if_block1.m(button, t1);
}
} else if (if_block1) {
if_block1.d(1);
if_block1 = null;
}
},
d(detaching) {
if (detaching) detach(button);
if_block0.d();
if (if_block1) if_block1.d();
mounted = false;
dispose();
}
};
}
// (410:0) {#if autoComplete && arrelementsmatch.length > 0}
function create_if_block(ctx) {
let div;
let ul;
let ul_id_value;
let each_value = /*arrelementsmatch*/ ctx[11];
let each_blocks = [];
for (let i = 0; i < each_value.length; i += 1) {
each_blocks[i] = create_each_block(get_each_context(ctx, each_value, i));
}
return {
c() {
div = element("div");
ul = element("ul");
for (let i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].c();
}
attr(ul, "id", ul_id_value = "" + (/*id*/ ctx[4] + "_matchs"));
attr(ul, "class", "svelte-tags-input-matchs svelte-b5mxss");
attr(div, "class", "svelte-tags-input-matchs-parent svelte-b5mxss");
},
m(target, anchor) {
insert(target, div, anchor);
append(div, ul);
for (let i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].m(ul, null);
}
},
p(ctx, dirty) {
if (dirty[0] & /*autoCompleteIndex, addTag, arrelementsmatch*/ 75776) {
each_value = /*arrelementsmatch*/ ctx[11];
let i;
for (i = 0; i < each_value.length; i += 1) {
const child_ctx = get_each_context(ctx, each_value, i);
if (each_blocks[i]) {
each_blocks[i].p(child_ctx, dirty);
} else {
each_blocks[i] = create_each_block(child_ctx);
each_blocks[i].c();
each_blocks[i].m(ul, null);
}
}
for (; i < each_blocks.length; i += 1) {
each_blocks[i].d(1);
}
each_blocks.length = each_value.length;
}
if (dirty[0] & /*id*/ 16 && ul_id_value !== (ul_id_value = "" + (/*id*/ ctx[4] + "_matchs"))) {
attr(ul, "id", ul_id_value);
}
},
d(detaching) {
if (detaching) detach(div);
destroy_each(each_blocks, detaching);
}
};
}
// (413:12) {#each arrelementsmatch as element, index}
function create_each_block(ctx) {
let li;
let html_tag;
let raw_value = /*element*/ ctx[54].search + "";
let t;
let mounted;
let dispose;
function pointerdown_handler_1() {
return /*pointerdown_handler_1*/ ctx[48](/*element*/ ctx[54]);
}
return {
c() {
li = element("li");
html_tag = new HtmlTag(false);
t = space();
html_tag.a = t;
attr(li, "tabindex", "-1");
attr(li, "class", "svelte-b5mxss");
toggle_class(li, "focus", /*index*/ ctx[56] === /*autoCompleteIndex*/ ctx[13]);
},
m(target, anchor) {
insert(target, li, anchor);
html_tag.m(raw_value, li);
append(li, t);
if (!mounted) {
dispose = listen(li, "pointerdown", prevent_default(pointerdown_handler_1));
mounted = true;
}
},
p(new_ctx, dirty) {
ctx = new_ctx;
if (dirty[0] & /*arrelementsmatch*/ 2048 && raw_value !== (raw_value = /*element*/ ctx[54].search + "")) html_tag.p(raw_value);
if (dirty[0] & /*autoCompleteIndex*/ 8192) {
toggle_class(li, "focus", /*index*/ ctx[56] === /*autoCompleteIndex*/ ctx[13]);
}
},
d(detaching) {
if (detaching) detach(li);
mounted = false;
dispose();
}
};
}
function create_fragment(ctx) {
let div;
let label;
let t0;
let label_class_value;
let t1;
let t2;
let input;
let input_disabled_value;
let t3;
let if_block1_anchor;
let mounted;
let dispose;
let if_block0 = /*tags*/ ctx[0].length > 0 && create_if_block_1(ctx);
let if_block1 = /*autoComplete*/ ctx[2] && /*arrelementsmatch*/ ctx[11].length > 0 && create_if_block(ctx);
return {
c() {
div = element("div");
label = element("label");
t0 = text(/*labelText*/ ctx[6]);
t1 = space();
if (if_block0) if_block0.c();
t2 = space();
input = element("input");
t3 = space();
if (if_block1) if_block1.c();
if_block1_anchor = empty();
attr(label, "for", /*id*/ ctx[4]);
attr(label, "class", label_class_value = "" + (null_to_empty(/*labelShow*/ ctx[7] ? "" : "sr-only") + " svelte-b5mxss"));
attr(input, "type", "text");
attr(input, "id", /*id*/ ctx[4]);
attr(input, "name", /*name*/ ctx[3]);
attr(input, "class", "svelte-tags-input svelte-b5mxss");
attr(input, "placeholder", /*placeholder*/ ctx[1]);
input.disabled = input_disabled_value = /*disable*/ ctx[5] || /*readonly*/ ctx[8];
attr(input, "autocomplete", "off");
attr(div, "class", "svelte-tags-input-layout svelte-b5mxss");
toggle_class(div, "sti-layout-disable", /*disable*/ ctx[5]);
toggle_class(div, "sti-layout-readonly", /*readonly*/ ctx[8]);
},
m(target, anchor) {
insert(target, div, anchor);
append(div, label);
append(label, t0);
append(div, t1);
if (if_block0) if_block0.m(div, null);
append(div, t2);
append(div, input);
set_input_value(input, /*tag*/ ctx[14]);
/*div_binding*/ ctx[47](div);
insert(target, t3, anchor);
if (if_block1) if_block1.m(target, anchor);
insert(target, if_block1_anchor, anchor);
if (!mounted) {
dispose = [
listen(input, "input", /*input_input_handler*/ ctx[45]),
listen(input, "keydown", /*setTag*/ ctx[15]),
listen(input, "keyup", /*getMatchElements*/ ctx[23]),
listen(input, "paste", /*onPaste*/ ctx[18]),
listen(input, "drop", /*onDrop*/ ctx[19]),
listen(input, "focus", /*onFocus*/ ctx[20]),
listen(input, "blur", /*blur_handler*/ ctx[46]),
listen(input, "pointerdown", /*onClick*/ ctx[22])
];
mounted = true;
}
},
p(ctx, dirty) {
if (dirty[0] & /*labelText*/ 64) set_data(t0, /*labelText*/ ctx[6]);
if (dirty[0] & /*id*/ 16) {
attr(label, "for", /*id*/ ctx[4]);
}
if (dirty[0] & /*labelShow*/ 128 && label_class_value !== (label_class_value = "" + (null_to_empty(/*labelShow*/ ctx[7] ? "" : "sr-only") + " svelte-b5mxss"))) {
attr(label, "class", label_class_value);
}
if (/*tags*/ ctx[0].length > 0) {
if (if_block0) {
if_block0.p(ctx, dirty);
} else {
if_block0 = create_if_block_1(ctx);
if_block0.c();
if_block0.m(div, t2);
}
} else if (if_block0) {
if_block0.d(1);
if_block0 = null;
}
if (dirty[0] & /*id*/ 16) {
attr(input, "id", /*id*/ ctx[4]);
}
if (dirty[0] & /*name*/ 8) {
attr(input, "name", /*name*/ ctx[3]);
}
if (dirty[0] & /*placeholder*/ 2) {
attr(input, "placeholder", /*placeholder*/ ctx[1]);
}
if (dirty[0] & /*disable, readonly*/ 288 && input_disabled_value !== (input_disabled_value = /*disable*/ ctx[5] || /*readonly*/ ctx[8])) {
input.disabled = input_disabled_value;
}
if (dirty[0] & /*tag*/ 16384 && input.value !== /*tag*/ ctx[14]) {
set_input_value(input, /*tag*/ ctx[14]);
}
if (dirty[0] & /*disable*/ 32) {
toggle_class(div, "sti-layout-disable", /*disable*/ ctx[5]);
}
if (dirty[0] & /*readonly*/ 256) {
toggle_class(div, "sti-layout-readonly", /*readonly*/ ctx[8]);
}
if (/*autoComplete*/ ctx[2] && /*arrelementsmatch*/ ctx[11].length > 0) {
if (if_block1) {
if_block1.p(ctx, dirty);
} else {
if_block1 = create_if_block(ctx);
if_block1.c();
if_block1.m(if_block1_anchor.parentNode, if_block1_anchor);
}
} else if (if_block1) {
if_block1.d(1);
if_block1 = null;
}
},
i: noop,
o: noop,
d(detaching) {
if (detaching) detach(div);
if (if_block0) if_block0.d();
/*div_binding*/ ctx[47](null);
if (detaching) detach(t3);
if (if_block1) if_block1.d(detaching);
if (detaching) detach(if_block1_anchor);
mounted = false;
run_all(dispose);
}
};
}
function getClipboardData(e) {
if (window.clipboardData) {
return window.clipboardData.getData('Text');
}
if (e.clipboardData) {
return e.clipboardData.getData('text/plain');
}
return '';
}
function escapeHTML(string) {
const htmlEscapes = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
'/': '/'
};
return ('' + string).replace(/[&<>"'\/]/g, match => htmlEscapes[match]);
}
function uniqueID() {
return 'sti_' + Math.random().toString(36).substring(2, 11);
}
function instance($$self, $$props, $$invalidate) {
let autoCompleteIndexStart;
let autoCompleteIndex;
let matchsID;
let tag = "";
let arrelementsmatch = [];
let regExpEscape = s => {
return s.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&");
};
let { tags } = $$props;
let { addKeys } = $$props;
let { maxTags } = $$props;
let { onlyUnique } = $$props;
let { removeKeys } = $$props;
let { placeholder } = $$props;
let { allowPaste } = $$props;
let { allowDrop } = $$props;
let { splitWith } = $$props;
let { autoComplete } = $$props;
let { autoCompleteFilter } = $$props;
let { autoCompleteKey } = $$props;
let { autoCompleteMarkupKey } = $$props;
let { autoCompleteStartFocused } = $$props;
let { name } = $$props;
let { id } = $$props;
let { allowBlur } = $$props;
let { disable } = $$props;
let { minChars } = $$props;
let { onlyAutocomplete } = $$props;
let { labelText } = $$props;
let { labelShow } = $$props;
let { readonly } = $$props;
let { onTagClick } = $$props;
let { autoCompleteShowKey } = $$props;
let { onTagAdded } = $$props;
let { onTagRemoved } = $$props;
let { cleanOnBlur } = $$props;
let { customValidation } = $$props;
let layoutElement;
let storePlaceholder = placeholder;
function setTag(e) {
const matches = document.getElementById(matchsID);
// Get the focused tag from the autocomplete list, if there is one
const focusedElement = matches?.querySelector('li.focus')?.textContent;
// Set the current tag to the focused tag if there is one, otherwise use the input value
const currentTag = focusedElement ?? e.target.value;
if (addKeys) {
addKeys.forEach(function (key) {
if (key === e.keyCode) {
if (currentTag) e.preventDefault();
/* switch (input.keyCode) {
case 9:
// TAB add first element on the autoComplete list
if (autoComplete && document.getElementById(matchsID)) {
addTag(document.getElementById(matchsID).querySelectorAll("li")[0].textContent);
} else {
addTag(currentTag);
}
break;
default:
addTag(currentTag);
break;
} */
/*
* Fix https://github.com/agustinl/svelte-tags-input/issues/87
* If autocomplete = true
* If onlyAutocomplete = true: You cannot add random tags
* If input element with ID
*/
if (autoComplete && onlyAutocomplete && document.getElementById(matchsID)) {
addTag(arrelementsmatch?.[autoCompleteIndex]?.label);
} else {
addTag(currentTag);
}
}
});
}
if (removeKeys) {
removeKeys.forEach(function (key) {
if (key === e.keyCode && tag === "") {
tags.pop();
$$invalidate(0, tags);
$$invalidate(11, arrelementsmatch = []);
document.getElementById(id).readOnly = false;
$$invalidate(1, placeholder = storePlaceholder);
document.getElementById(id).focus();
}
});
}
// ArrowDown : focus on first element of the autocomplete
if (e.keyCode === 40 && autoComplete && document.getElementById(matchsID)) {
$$invalidate(13, autoCompleteIndex++, autoCompleteIndex);
// Went off the list ? Go to the first
if (autoCompleteIndex >= arrelementsmatch.length || autoCompleteIndex < 0) {
$$invalidate(13, autoCompleteIndex = 0);
}
} else if (e.keyCode === 38) {
// ArrowUp
$$invalidate(13, autoCompleteIndex--, autoCompleteIndex);
// Went off the list ? Go to the last
if (autoCompleteIndex < 0 || autoCompleteIndex >= arrelementsmatch.length) {
$$invalidate(13, autoCompleteIndex = arrelementsmatch.length - 1);
}
} else if (e.keyCode === 27) {
// Escape
$$invalidate(11, arrelementsmatch = []);
document.getElementById(id).focus();
}
}
function addTag(currentTag) {
if (typeof currentTag === 'object' && currentTag !== null) {
if (!autoCompleteKey) {
return console.error("'autoCompleteKey' is necessary if 'autoComplete' result is an array of objects");
}
if (onlyUnique) {
let found = tags?.find(elem => elem[autoCompleteKey] === currentTag[autoCompleteKey]);
if (found) return;
}
var currentObjTags = currentTag;
currentTag = currentTag[autoCompleteKey].trim();
} else {
currentTag = currentTag.trim();
}
if (currentTag == "") return;
if (maxTags && tags.length == maxTags) return;
if (onlyUnique && tags.includes(currentTag)) return;
if (onlyAutocomplete && arrelementsmatch.length === 0) return;
if (customValidation && !customValidation(currentTag)) return;
tags.push(currentObjTags ? currentObjTags : currentTag);
$$invalidate(0, tags);
$$invalidate(14, tag = "");
onTagAdded(currentTag, tags);
// Hide autocomplete list
// Focus on svelte tags input
$$invalidate(11, arrelementsmatch = []);
$$invalidate(13, autoCompleteIndex = autoCompleteIndexStart);
document.getElementById(id).focus();
if (maxTags && tags.length == maxTags) {
document.getElementById(id).readOnly = true;
$$invalidate(1, placeholder = "");
}
}
function removeTag(i) {
tags.splice(i, 1);
onTagRemoved(tags[i], tags);
$$invalidate(0, tags);
// Hide autocomplete list
// Focus on svelte tags input
$$invalidate(11, arrelementsmatch = []);
document.getElementById(id).readOnly = false;
$$invalidate(1, placeholder = storePlaceholder);
document.getElementById(id).focus();
}
function onPaste(e) {
if (!allowPaste) return;
e.preventDefault();
const data = getClipboardData(e);
splitTags(data).map(tag => addTag(tag));
}
function onDrop(e) {
if (!allowDrop) return;
e.preventDefault();
const data = e.dataTransfer.getData("Text");
splitTags(data).map(tag => addTag(tag));
}
function onFocus() {
layoutElement.classList.add('focus');
}
function onBlur(e, currentTag) {
layoutElement.classList.remove('focus');
if (allowBlur) {
// A match is highlighted
if (arrelementsmatch.length && autoCompleteIndex > -1) {
addTag(arrelementsmatch?.[autoCompleteIndex]?.label);
} else // There is no match, but we may add a new tag
if (!arrelementsmatch.length) {
e.preventDefault();
addTag(currentTag);
}
}
// Clean input on
if (cleanOnBlur) {
$$invalidate(14, tag = "");
}
$$invalidate(11, arrelementsmatch = []);
$$invalidate(13, autoCompleteIndex = autoCompleteIndexStart);
}
function onClick() {
minChars == 0 && getMatchElements();
}
function splitTags(data) {
return data.split(splitWith).map(tag => tag.trim());
}
function buildMatchMarkup(search, value) {
return escapeHTML(value).replace(RegExp(regExpEscape(search.toLowerCase()), 'i'), "<strong>$&</strong>");
}
async function getMatchElements(input) {
if (!autoComplete) return;
if (maxTags && tags.length >= maxTags) return;
let value = input ? input.target.value : "";
let autoCompleteValues = [];
if (Array.isArray(autoComplete)) {
autoCompleteValues = autoComplete;
}
if (typeof autoComplete === 'function') {
if (autoComplete.constructor.name === 'AsyncFunction') {
autoCompleteValues = await autoComplete(value);
} else {
autoCompleteValues = autoComplete(value);
}
}
if (autoCompleteValues.constructor.name === 'Promise') {
autoCompleteValues = await autoCompleteValues;
}
// Escape
if (minChars > 0 && value == "" || input && input.keyCode === 27 || value.length < minChars) {
$$invalidate(11, arrelementsmatch = []);
return;
}
let matchs = autoCompleteValues;
if (typeof autoCompleteValues[0] === 'object' && autoCompleteValues !== null) {
if (!autoCompleteKey) {
return console.error("'autoCompleteValue' is necessary if 'autoComplete' result is an array of objects");
}
if (autoCompleteFilter !== false) {
matchs = autoCompleteValues.filter(e => e[autoCompleteKey].toLowerCase().includes(value.toLowerCase()));
}
matchs = matchs.map(matchTag => {
return {
label: matchTag,
search: autoCompleteMarkupKey
? matchTag[autoCompleteMarkupKey]
: buildMatchMarkup(value, matchTag[autoCompleteKey])
};
});
} else {
if (autoCompleteFilter !== false) {
matchs = autoCompleteValues.filter(e => e.toLowerCase().includes(value.toLowerCase()));
}
matchs = matchs.map(matchTag => {
return {
label: matchTag,
search: buildMatchMarkup(value, matchTag)
};
});
}
if (onlyUnique === true && !autoCompleteKey) {
matchs = matchs.filter(tag => !tags.includes(tag.label));
}
$$invalidate(11, arrelementsmatch = matchs);
}
const pointerdown_handler = i => removeTag(i);
const click_handler = tag => onTagClick(tag);
function input_input_handler() {
tag = this.value;
$$invalidate(14, tag);
}
const blur_handler = e => onBlur(e, tag);
function div_binding($$value) {
binding_callbacks[$$value ? 'unshift' : 'push'](() => {
layoutElement = $$value;
$$invalidate(12, layoutElement);
});
}
const pointerdown_handler_1 = element => addTag(element.label);
$$self.$$set = $$props => {
if ('tags' in $$props) $$invalidate(0, tags = $$props.tags);
if ('addKeys' in $$props) $$invalidate(24, addKeys = $$props.addKeys);
if ('maxTags' in $$props) $$invalidate(25, maxTags = $$props.maxTags);
if ('onlyUnique' in $$props) $$invalidate(26, onlyUnique = $$props.onlyUnique);
if ('removeKeys' in $$props) $$invalidate(27, removeKeys = $$props.removeKeys);
if ('placeholder' in $$props) $$invalidate(1, placeholder = $$props.placeholder);
if ('allowPaste' in $$props) $$invalidate(28, allowPaste = $$props.allowPaste);
if ('allowDrop' in $$props) $$invalidate(29, allowDrop = $$props.allowDrop);
if ('splitWith' in $$props) $$invalidate(30, splitWith = $$props.splitWith);
if ('autoComplete' in $$props) $$invalidate(2, autoComplete = $$props.autoComplete);
if ('autoCompleteFilter' in $$props) $$invalidate(31, autoCompleteFilter = $$props.autoCompleteFilter);
if ('autoCompleteKey' in $$props) $$invalidate(32, autoCompleteKey = $$props.autoCompleteKey);
if ('autoCompleteMarkupKey' in $$props) $$invalidate(33, autoCompleteMarkupKey = $$props.autoCompleteMarkupKey);
if ('autoCompleteStartFocused' in $$props) $$invalidate(41, autoCompleteStartFocused = $$props.autoCompleteStartFocused);
if ('name' in $$props) $$invalidate(3, name = $$props.name);
if ('id' in $$props) $$invalidate(4, id = $$props.id);
if ('allowBlur' in $$props) $$invalidate(34, allowBlur = $$props.allowBlur);
if ('disable' in $$props) $$invalidate(5, disable = $$props.disable);
if ('minChars' in $$props) $$invalidate(35, minChars = $$props.minChars);
if ('onlyAutocomplete' in $$props) $$invalidate(36, onlyAutocomplete = $$props.onlyAutocomplete);
if ('labelText' in $$props) $$invalidate(6, labelText = $$props.labelText);
if ('labelShow' in $$props) $$invalidate(7, labelShow = $$props.labelShow);
if ('readonly' in $$props) $$invalidate(8, readonly = $$props.readonly);
if ('onTagClick' in $$props) $$invalidate(9, onTagClick = $$props.onTagClick);
if ('autoCompleteShowKey' in $$props) $$invalidate(10, autoCompleteShowKey = $$props.autoCompleteShowKey);
if ('onTagAdded' in $$props) $$invalidate(37, onTagAdded = $$props.onTagAdded);
if ('onTagRemoved' in $$props) $$invalidate(38, onTagRemoved = $$props.onTagRemoved);
if ('cleanOnBlur' in $$props) $$invalidate(39, cleanOnBlur = $$props.cleanOnBlur);
if ('customValidation' in $$props) $$invalidate(40, customValidation = $$props.customValidation);
};
$$self.$$.update = () => {
if ($$self.$$.dirty[0] & /*tags*/ 1) {
$$invalidate(0, tags = tags || []);
}
if ($$self.$$.dirty[0] & /*addKeys*/ 16777216) {
$$invalidate(24, addKeys = addKeys || [13]);
}
if ($$self.$$.dirty[0] & /*maxTags*/ 33554432) {
$$invalidate(25, maxTags = maxTags || false);
}
if ($$self.$$.dirty[0] & /*onlyUnique*/ 67108864) {
$$invalidate(26, onlyUnique = onlyUnique || false);
}
if ($$self.$$.dirty[0] & /*removeKeys*/ 134217728) {
$$invalidate(27, removeKeys = removeKeys || [8]);
}
if ($$self.$$.dirty[0] & /*placeholder*/ 2) {
$$invalidate(1, placeholder = placeholder || "");
}
if ($$self.$$.dirty[0] & /*allowPaste*/ 268435456) {
$$invalidate(28, allowPaste = allowPaste || false);
}
if ($$self.$$.dirty[0] & /*allowDrop*/ 536870912) {
$$invalidate(29, allowDrop = allowDrop || false);
}
if ($$self.$$.dirty[0] & /*splitWith*/ 1073741824) {
$$invalidate(30, splitWith = splitWith || ",");
}
if ($$self.$$.dirty[0] & /*autoComplete*/ 4) {
$$invalidate(2, autoComplete = autoComplete || false);
}
if ($$self.$$.dirty[1] & /*autoCompleteFilter*/ 1) {
$$invalidate(31, autoCompleteFilter = typeof autoCompleteFilter == "undefined" ? true : false);
}
if ($$self.$$.dirty[1] & /*autoCompleteKey*/ 2) {
$$invalidate(32, autoCompleteKey = autoCompleteKey || false);
}
if ($$self.$$.dirty[1] & /*autoCompleteMarkupKey*/ 4) {
$$invalidate(33, autoCompleteMarkupKey = autoCompleteMarkupKey || false);
}
if ($$self.$$.dirty[1] & /*autoCompleteStartFocused*/ 1024) {
$$invalidate(42, autoCompleteIndexStart = autoCompleteStartFocused ? 0 : -1);
}
if ($$self.$$.dirty[0] & /*name*/ 8) {
$$invalidate(3, name = name || "svelte-tags-input");
}
if ($$self.$$.dirty[0] & /*id*/ 16) {
$$invalidate(4, id = id || uniqueID());
}
if ($$self.$$.dirty[1] & /*allowBlur*/ 8) {
$$invalidate(34, allowBlur = allowBlur || false);
}
if ($$self.$$.dirty[0] & /*disable*/ 32) {
$$invalidate(5, disable = disable || false);
}
if ($$self.$$.dirty[1] & /*minChars*/ 16) {
$$invalidate(35, minChars = minChars ?? 1);
}
if ($$self.$$.dirty[1] & /*onlyAutocomplete*/ 32) {
$$invalidate(36, onlyAutocomplete = onlyAutocomplete || false);
}
if ($$self.$$.dirty[0] & /*labelText, name*/ 72) {
$$invalidate(6, labelText = labelText || name);
}
if ($$self.$$.dirty[0] & /*labelShow*/ 128) {
$$invalidate(7, labelShow = labelShow || false);
}
if ($$self.$$.dirty[0] & /*readonly*/ 256) {
$$invalidate(8, readonly = readonly || false);
}
if ($$self.$$.dirty[0] & /*onTagClick*/ 512) {
$$invalidate(9, onTagClick = onTagClick || function () {
});
}
if ($$self.$$.dirty[0] & /*autoCompleteShowKey*/ 1024 | $$self.$$.dirty[1] & /*autoCompleteKey*/ 2) {
$$invalidate(10, autoCompleteShowKey = autoCompleteShowKey || autoCompleteKey);
}
if ($$self.$$.dirty[1] & /*onTagAdded*/ 64) {
$$invalidate(37, onTagAdded = onTagAdded || function () {
});
}
if ($$self.$$.dirty[1] & /*onTagRemoved*/ 128) {
$$invalidate(38, onTagRemoved = onTagRemoved || function () {
});
}
if ($$self.$$.dirty[1] & /*cleanOnBlur*/ 256) {
$$invalidate(39, cleanOnBlur = cleanOnBlur || false);
}
if ($$self.$$.dirty[1] & /*customValidation*/ 512) {
$$invalidate(40, customValidation = customValidation || false);
}
if ($$self.$$.dirty[1] & /*autoCompleteIndexStart*/ 2048) {
$$invalidate(13, autoCompleteIndex = autoCompleteIndexStart);
}
if ($$self.$$.dirty[0] & /*id*/ 16) {
matchsID = id + "_matchs";
}
};
return [
tags,
placeholder,
autoComplete,
name,
id,
disable,
labelText,
labelShow,
readonly,
onTagClick,
autoCompleteShowKey,
arrelementsmatch,
layoutElement,
autoCompleteIndex,
tag,
setTag,
addTag,
removeTag,
onPaste,
onDrop,
onFocus,
onBlur,
onClick,
getMatchElements,
addKeys,
maxTags,
onlyUnique,
removeKeys,
allowPaste,
allowDrop,
splitWith,
autoCompleteFilter,
autoCompleteKey,
autoCompleteMarkupKey,
allowBlur,
minChars,
onlyAutocomplete,
onTagAdded,
onTagRemoved,
cleanOnBlur,
customValidation,
autoCompleteStartFocused,
autoCompleteIndexStart,
pointerdown_handler,
click_handler,
input_input_handler,
blur_handler,
div_binding,
pointerdown_handler_1
];
}
class Tags extends SvelteComponent {
constructor(options) {
super();
init(
this,
options,
instance,
create_fragment,
safe_not_equal,
{
tags: 0,
addKeys: 24,
maxTags: 25,
onlyUnique: 26,
removeKeys: 27,
placeholder: 1,
allowPaste: 28,
allowDrop: 29,
splitWith: 30,
autoComplete: 2,
autoCompleteFilter: 31,
autoCompleteKey: 32,
autoCompleteMarkupKey: 33,
autoCompleteStartFocused: 41,
name: 3,
id: 4,
allowBlur: 34,
disable: 5,
minChars: 35,
onlyAutocomplete: 36,
labelText: 6,
labelShow: 7,
readonly: 8,
onTagClick: 9,
autoCompleteShowKey: 10,
onTagAdded: 37,
onTagRemoved: 38,
cleanOnBlur: 39,
customValidation: 40
},
null,
[-1, -1]
);
}
}
return Tags;
}));