Skip to content

Commit

Permalink
Replaced rollup with vite
Browse files Browse the repository at this point in the history
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
ohmree committed Feb 8, 2022
1 parent 74bd078 commit 4c32ec7
Show file tree
Hide file tree
Showing 15 changed files with 558 additions and 408 deletions.
11 changes: 8 additions & 3 deletions dist/tagin.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,27 @@
flex-wrap: wrap;
padding: calc(0.375rem - 2px) calc(0.75rem - 2px);
}

.tagin-wrapper.focus {
color: #212529;
outline: 0;
border-color: #86b7fe;
background-color: #fff;
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
}

.tagin.is-valid + .tagin-wrapper, .was-validated .tagin:valid + .tagin-wrapper {
border-color: #198754;
}

.tagin.is-valid + .tagin-wrapper.focus, .was-validated .tagin:valid + .tagin-wrapper.focus {
box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25);
}

.tagin.is-invalid + .tagin-wrapper, .was-validated .tagin:invalid + .tagin-wrapper {
border-color: #dc3545;
}

.tagin.is-invalid + .tagin-wrapper.focus, .was-validated .tagin:invalid + .tagin-wrapper.focus {
box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);
}
Expand All @@ -52,6 +57,7 @@
margin-left: 2px;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23a0aec0' width='18px' height='18px'%3E%3Cpath d='M0 0h24v24H0z' fill='none'/%3E%3Cpath d='M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z'/%3E%3C/svg%3E");
}

.tagin-tag-remove:hover {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white' width='18px' height='18px'%3E%3Cpath d='M0 0h24v24H0z' fill='none'/%3E%3Cpath d='M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z'/%3E%3C/svg%3E");
}
Expand All @@ -65,6 +71,7 @@
border-color: transparent;
border-width: 1px 0;
}

.tagin-input:not(.tagin-input-hidden) {
width: 4px;
min-width: 4px;
Expand All @@ -77,6 +84,4 @@
overflow: hidden;
visibility: hidden;
white-space: nowrap;
}

/*# sourceMappingURL=tagin.css.map */
}
1 change: 0 additions & 1 deletion dist/tagin.css.map

This file was deleted.

1 change: 1 addition & 0 deletions dist/tagin.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import './tagin.scss';
declare class Tagin {
private classElement;
private classWrapper;
Expand Down
307 changes: 151 additions & 156 deletions dist/tagin.js
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, '&nbsp;');
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, "&nbsp;");
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;
});
Loading

0 comments on commit 4c32ec7

Please sign in to comment.