forked from erwinheldy/tagin
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This commit also makes it possible to import the source SCSS styles from dependent code. Caveats/differences from previous setup: - `dist/tagin.module.min.js` isn't actually minified - see vitejs/vite#6555. - no css sourcemap are generated - see vitejs/vite#2830.
- Loading branch information
Showing
15 changed files
with
558 additions
and
408 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
import './tagin.scss'; | ||
declare class Tagin { | ||
private classElement; | ||
private classWrapper; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,165 +1,160 @@ | ||
var __defProp = Object.defineProperty; | ||
var __defNormalProp = (obj, key, value2) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value: value2 }) : obj[key] = value2; | ||
var __publicField = (obj, key, value2) => { | ||
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value2); | ||
return value2; | ||
}; | ||
/*! | ||
* Tagin v2.0.2 (https://tagin.netlify.app/) | ||
* Copyright 2020-2021 Erwin Heldy G | ||
* Copyright 2020-2022 Erwin Heldy G | ||
* Licensed under MIT (https://github.com/erwinheldy/tagin/blob/master/LICENSE) | ||
*/ | ||
(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.Tagin = factory()); | ||
})(this, (function () { 'use strict'; | ||
|
||
class Tagin { | ||
classElement = 'tagin'; | ||
classWrapper = 'tagin-wrapper'; | ||
classTag = 'tagin-tag'; | ||
classRemove = 'tagin-tag-remove'; | ||
classInput = 'tagin-input'; | ||
classInputHidden = 'tagin-input-hidden'; | ||
target; | ||
wrapper; | ||
input; | ||
separator; | ||
placeholder; | ||
duplicate; | ||
transform; | ||
enter; | ||
constructor(inputElement, options) { | ||
this.target = inputElement; | ||
this.separator = options?.separator || inputElement.dataset.taginSeparator || ','; | ||
this.placeholder = options?.placeholder || inputElement.dataset.taginPlaceholder || ''; | ||
this.duplicate = options?.duplicate || inputElement.dataset.taginDuplicate !== undefined; | ||
this.transform = options?.transform || inputElement.dataset.taginTransform || 'input => input'; | ||
this.enter = options?.enter || inputElement.dataset.taginEnter !== undefined; | ||
this.createWrapper(); | ||
this.autowidth(); | ||
this.addEventListener(); | ||
} | ||
createWrapper() { | ||
const tags = this.getValue() === '' ? '' : this.getValues().map(val => this.createTag(val)).join(''); | ||
const input = document.createElement('input'); | ||
input.type = 'text'; | ||
input.className = this.classInput; | ||
input.placeholder = this.placeholder; | ||
const wrapper = document.createElement('div'); | ||
wrapper.className = `${this.classWrapper} ${this.target.className}`; | ||
wrapper.classList.remove(this.classElement); | ||
wrapper.insertAdjacentHTML('afterbegin', tags); | ||
wrapper.insertAdjacentElement('beforeend', input); | ||
this.target.insertAdjacentElement('afterend', wrapper); // insert wrapper after input | ||
this.wrapper = wrapper; | ||
this.input = input; | ||
} | ||
createTag(value) { | ||
const onclick = `this.closest('div').dispatchEvent(new CustomEvent('tagin:remove', { detail: this }))`; | ||
return `<span class="${this.classTag}">${value}<span onclick="${onclick}" class="${this.classRemove}"></span></span>`; | ||
} | ||
getValue() { | ||
return this.target.value.trim(); | ||
} | ||
getValues() { | ||
return this.getValue().split(this.separator); | ||
} | ||
getTags() { | ||
return Array.from(this.wrapper.getElementsByClassName(this.classTag)).map(tag => tag.textContent); | ||
} | ||
getTag() { | ||
return this.getTags().join(this.separator); | ||
} | ||
updateValue() { | ||
this.target.value = this.getTag(); | ||
this.target.dispatchEvent(new Event('change')); | ||
} | ||
autowidth() { | ||
const fakeEl = document.createElement('div'); | ||
fakeEl.classList.add(this.classInput, this.classInputHidden); | ||
const string = this.input.value || this.input.placeholder || ''; | ||
fakeEl.innerHTML = string.replace(/ /g, ' '); | ||
document.body.appendChild(fakeEl); | ||
this.input.style.setProperty('width', Math.ceil(parseInt(window.getComputedStyle(fakeEl).width.replace('px', ''))) + 1 + 'px'); | ||
fakeEl.remove(); | ||
} | ||
addEventListener() { | ||
const wrapper = this.wrapper; | ||
const input = this.input; | ||
// Focus to input | ||
wrapper.addEventListener('click', () => input.focus()); | ||
// Toggle focus class | ||
input.addEventListener('focus', () => wrapper.classList.add('focus')); | ||
input.addEventListener('blur', () => wrapper.classList.remove('focus')); | ||
// Add tag when input | ||
input.addEventListener('input', () => { | ||
this.appendTag(); | ||
this.autowidth(); | ||
}); | ||
// Add tag when blur | ||
input.addEventListener('blur', () => { | ||
this.appendTag(true); | ||
this.autowidth(); | ||
}); | ||
input.addEventListener('keydown', (e) => { | ||
// Remove with backspace | ||
if (input.value === '' && e.key === 'Backspace' && wrapper.getElementsByClassName(this.classTag).length) { | ||
wrapper.querySelector(`.${this.classTag}:last-of-type`).remove(); | ||
this.updateValue(); | ||
} | ||
// Add with Enter | ||
if (input.value !== '' && e.key === 'Enter' && this.enter) { | ||
this.appendTag(true); | ||
this.autowidth(); | ||
e.preventDefault(); | ||
} | ||
}); | ||
wrapper.addEventListener('tagin:remove', (e) => { | ||
if (e['detail'] instanceof HTMLSpanElement) { | ||
e['detail'].parentElement.remove(); | ||
this.updateValue(); | ||
} | ||
}); | ||
this.target.addEventListener('change', () => this.updateTag()); | ||
} | ||
appendTag(force = false) { | ||
const input = this.input; | ||
const value = eval(this.transform)(input.value.trim()); | ||
if (value === '') | ||
input.value = ''; | ||
if (input.value.includes(this.separator) || (force && input.value !== '')) { | ||
value | ||
.split(this.separator) | ||
.filter((i) => i !== '') | ||
.forEach((val) => { | ||
if (this.getTags().includes(val) && this.duplicate === false) { | ||
this.alertExist(val); | ||
} | ||
else { | ||
input.insertAdjacentHTML('beforebegin', this.createTag(val)); | ||
this.updateValue(); | ||
} | ||
}); | ||
input.value = ''; | ||
input.removeAttribute('style'); | ||
} | ||
(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.Tagin = factory()); | ||
})(this, function() { | ||
"use strict"; | ||
var tagin = ""; | ||
class Tagin { | ||
constructor(inputElement, options) { | ||
__publicField(this, "classElement", "tagin"); | ||
__publicField(this, "classWrapper", "tagin-wrapper"); | ||
__publicField(this, "classTag", "tagin-tag"); | ||
__publicField(this, "classRemove", "tagin-tag-remove"); | ||
__publicField(this, "classInput", "tagin-input"); | ||
__publicField(this, "classInputHidden", "tagin-input-hidden"); | ||
__publicField(this, "target"); | ||
__publicField(this, "wrapper"); | ||
__publicField(this, "input"); | ||
__publicField(this, "separator"); | ||
__publicField(this, "placeholder"); | ||
__publicField(this, "duplicate"); | ||
__publicField(this, "transform"); | ||
__publicField(this, "enter"); | ||
this.target = inputElement; | ||
this.separator = (options == null ? void 0 : options.separator) || inputElement.dataset.taginSeparator || ","; | ||
this.placeholder = (options == null ? void 0 : options.placeholder) || inputElement.dataset.taginPlaceholder || ""; | ||
this.duplicate = (options == null ? void 0 : options.duplicate) || inputElement.dataset.taginDuplicate !== void 0; | ||
this.transform = (options == null ? void 0 : options.transform) || inputElement.dataset.taginTransform || "input => input"; | ||
this.enter = (options == null ? void 0 : options.enter) || inputElement.dataset.taginEnter !== void 0; | ||
this.createWrapper(); | ||
this.autowidth(); | ||
this.addEventListener(); | ||
} | ||
createWrapper() { | ||
const tags = this.getValue() === "" ? "" : this.getValues().map((val) => this.createTag(val)).join(""); | ||
const input2 = document.createElement("input"); | ||
input2.type = "text"; | ||
input2.className = this.classInput; | ||
input2.placeholder = this.placeholder; | ||
const wrapper = document.createElement("div"); | ||
wrapper.className = `${this.classWrapper} ${this.target.className}`; | ||
wrapper.classList.remove(this.classElement); | ||
wrapper.insertAdjacentHTML("afterbegin", tags); | ||
wrapper.insertAdjacentElement("beforeend", input2); | ||
this.target.insertAdjacentElement("afterend", wrapper); | ||
this.wrapper = wrapper; | ||
this.input = input2; | ||
} | ||
createTag(value2) { | ||
const onclick = `this.closest('div').dispatchEvent(new CustomEvent('tagin:remove', { detail: this }))`; | ||
return `<span class="${this.classTag}">${value2}<span onclick="${onclick}" class="${this.classRemove}"></span></span>`; | ||
} | ||
getValue() { | ||
return this.target.value.trim(); | ||
} | ||
getValues() { | ||
return this.getValue().split(this.separator); | ||
} | ||
getTags() { | ||
return Array.from(this.wrapper.getElementsByClassName(this.classTag)).map((tag) => tag.textContent); | ||
} | ||
getTag() { | ||
return this.getTags().join(this.separator); | ||
} | ||
updateValue() { | ||
this.target.value = this.getTag(); | ||
this.target.dispatchEvent(new Event("change")); | ||
} | ||
autowidth() { | ||
const fakeEl = document.createElement("div"); | ||
fakeEl.classList.add(this.classInput, this.classInputHidden); | ||
const string = this.input.value || this.input.placeholder || ""; | ||
fakeEl.innerHTML = string.replace(/ /g, " "); | ||
document.body.appendChild(fakeEl); | ||
this.input.style.setProperty("width", Math.ceil(parseInt(window.getComputedStyle(fakeEl).width.replace("px", ""))) + 1 + "px"); | ||
fakeEl.remove(); | ||
} | ||
addEventListener() { | ||
const wrapper = this.wrapper; | ||
const input2 = this.input; | ||
wrapper.addEventListener("click", () => input2.focus()); | ||
input2.addEventListener("focus", () => wrapper.classList.add("focus")); | ||
input2.addEventListener("blur", () => wrapper.classList.remove("focus")); | ||
input2.addEventListener("input", () => { | ||
this.appendTag(); | ||
this.autowidth(); | ||
}); | ||
input2.addEventListener("blur", () => { | ||
this.appendTag(true); | ||
this.autowidth(); | ||
}); | ||
input2.addEventListener("keydown", (e) => { | ||
if (input2.value === "" && e.key === "Backspace" && wrapper.getElementsByClassName(this.classTag).length) { | ||
wrapper.querySelector(`.${this.classTag}:last-of-type`).remove(); | ||
this.updateValue(); | ||
} | ||
alertExist(value) { | ||
for (const el of this.wrapper.getElementsByClassName(this.classTag)) { | ||
if (el.textContent === value && el instanceof HTMLSpanElement) { | ||
el.style.transform = 'scale(1.09)'; | ||
setTimeout(() => { el.removeAttribute('style'); }, 150); | ||
} | ||
} | ||
if (input2.value !== "" && e.key === "Enter" && this.enter) { | ||
this.appendTag(true); | ||
this.autowidth(); | ||
e.preventDefault(); | ||
} | ||
updateTag() { | ||
if (this.getValue() !== this.getTag()) { | ||
[...this.wrapper.getElementsByClassName(this.classTag)].map(tag => tag.remove()); | ||
this.getValue().trim() !== '' && this.input.insertAdjacentHTML('beforebegin', this.getValues().map(val => this.createTag(val)).join('')); | ||
} | ||
}); | ||
wrapper.addEventListener("tagin:remove", (e) => { | ||
if (e["detail"] instanceof HTMLSpanElement) { | ||
e["detail"].parentElement.remove(); | ||
this.updateValue(); | ||
} | ||
addTag(tag) { | ||
this.input.value = (Array.isArray(tag) ? tag.join(this.separator) : tag) + this.separator; | ||
this.input.dispatchEvent(new Event('input')); | ||
}); | ||
this.target.addEventListener("change", () => this.updateTag()); | ||
} | ||
appendTag(force = false) { | ||
const input = this.input; | ||
const value = eval(this.transform)(input.value.trim()); | ||
if (value === "") | ||
input.value = ""; | ||
if (input.value.includes(this.separator) || force && input.value !== "") { | ||
value.split(this.separator).filter((i) => i !== "").forEach((val) => { | ||
if (this.getTags().includes(val) && this.duplicate === false) { | ||
this.alertExist(val); | ||
} else { | ||
input.insertAdjacentHTML("beforebegin", this.createTag(val)); | ||
this.updateValue(); | ||
} | ||
}); | ||
input.value = ""; | ||
input.removeAttribute("style"); | ||
} | ||
} | ||
alertExist(value2) { | ||
for (const el of this.wrapper.getElementsByClassName(this.classTag)) { | ||
if (el.textContent === value2 && el instanceof HTMLSpanElement) { | ||
el.style.transform = "scale(1.09)"; | ||
setTimeout(() => { | ||
el.removeAttribute("style"); | ||
}, 150); | ||
} | ||
} | ||
} | ||
updateTag() { | ||
if (this.getValue() !== this.getTag()) { | ||
[...this.wrapper.getElementsByClassName(this.classTag)].map((tag) => tag.remove()); | ||
this.getValue().trim() !== "" && this.input.insertAdjacentHTML("beforebegin", this.getValues().map((val) => this.createTag(val)).join("")); | ||
} | ||
} | ||
addTag(tag) { | ||
this.input.value = (Array.isArray(tag) ? tag.join(this.separator) : tag) + this.separator; | ||
this.input.dispatchEvent(new Event("input")); | ||
} | ||
|
||
return Tagin; | ||
|
||
})); | ||
} | ||
return Tagin; | ||
}); |
Oops, something went wrong.