- Added tabs and upload component
This commit is contained in:
parent
c944b8569f
commit
3a85d74e4f
@ -1,17 +1,20 @@
|
|||||||
|
|
||||||
import { UiTabs } from "./module/ui-tabs.js";
|
import { UiTabs } from "./module/ui-tabs.js";
|
||||||
window.customElements.define("ui-tabs", UiTabs);
|
window.customElements.get("ui-tabs") || window.customElements.define("ui-tabs", UiTabs);
|
||||||
|
|
||||||
import { UiPopup } from "./module/ui-popup.js";
|
import { UiPopup } from "./module/ui-popup.js";
|
||||||
window.customElements.define("ui-popup", UiPopup);
|
window.customElements.get("ui-popup") || window.customElements.define("ui-popup", UiPopup);
|
||||||
|
|
||||||
import { UiTextarea } from "./module/ui-textarea.js";
|
import { UiTextarea } from "./module/ui-textarea.js";
|
||||||
window.customElements.define("ui-textarea", UiTextarea);
|
window.customElements.get("ui-textarea") || window.customElements.define("ui-textarea", UiTextarea);
|
||||||
|
|
||||||
import { UiSelect } from "./module/ui-select.js";
|
import { UiSelect } from "./module/ui-select.js";
|
||||||
window.customElements.define("ui-select", UiSelect);
|
window.customElements.get("ui-select") || window.customElements.define("ui-select", UiSelect);
|
||||||
|
|
||||||
|
import { UiUpload, UiUploadMedia } from "./module/ui-upload.js";
|
||||||
|
window.customElements.get("ui-upload") || window.customElements.define("ui-upload", UiUpload);
|
||||||
|
window.customElements.get("ui-upload-media") || window.customElements.define("ui-upload-media", UiUploadMedia);
|
||||||
|
|
||||||
import { UiNotification } from "./module/ui-notification.js";
|
import { UiNotification } from "./module/ui-notification.js";
|
||||||
window.customElements.define("ui-notification", UiNotification);
|
window.customElements.get("ui-notification") || window.customElements.define("ui-notification", UiNotification);
|
||||||
|
|
||||||
import './module/input.js';
|
import './module/input.js';
|
||||||
@ -6,6 +6,9 @@ const config = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class UiPopup extends Webcomponent {
|
class UiPopup extends Webcomponent {
|
||||||
|
#scrollPosition;
|
||||||
|
#options = {};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
@ -25,15 +28,13 @@ class UiPopup extends Webcomponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleOptions() {
|
handleOptions() {
|
||||||
if ( this.options ) {
|
if ( this.options['skip-keys'] === undefined ) {
|
||||||
if ( ! this.options['skip-keys'] ) {
|
|
||||||
document.addEventListener('keyup', function(e) {
|
document.addEventListener('keyup', function(e) {
|
||||||
if ( this.visible() ) {
|
if ( this.visible() ) {
|
||||||
|
|
||||||
let trigger, ev;
|
let trigger, ev;
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
console.log(this.visible());
|
|
||||||
|
|
||||||
switch ( e.keyCode ) {
|
switch ( e.keyCode ) {
|
||||||
case 13:
|
case 13:
|
||||||
@ -53,7 +54,7 @@ class UiPopup extends Webcomponent {
|
|||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
attach() {
|
attach() {
|
||||||
let triggers = document.querySelectorAll('[ui-popup]');
|
let triggers = document.querySelectorAll('[ui-popup]');
|
||||||
@ -78,10 +79,19 @@ class UiPopup extends Webcomponent {
|
|||||||
element.addEventListener("click", this.action.bind(this, element), false);
|
element.addEventListener("click", this.action.bind(this, element), false);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
|
if ( this.classList.contains("show") ) {
|
||||||
|
this.classList.remove("show");
|
||||||
|
|
||||||
|
setTimeout(() => this.show(), 100);
|
||||||
|
}
|
||||||
|
else {
|
||||||
this.hide();
|
this.hide();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
action(element, e) {
|
action(element, e) {
|
||||||
|
let retval;
|
||||||
|
|
||||||
if ( ! element.attributes.action ) {
|
if ( ! element.attributes.action ) {
|
||||||
throw "A button was clicked onto which no action was bound.";
|
throw "A button was clicked onto which no action was bound.";
|
||||||
}
|
}
|
||||||
@ -90,7 +100,7 @@ class UiPopup extends Webcomponent {
|
|||||||
case "confirm":
|
case "confirm":
|
||||||
case "yes":
|
case "yes":
|
||||||
case "ok":
|
case "ok":
|
||||||
let retval = this.actionFollowLink(element) ||
|
retval = this.actionFollowLink(element) ||
|
||||||
this.actionClickButton(element);
|
this.actionClickButton(element);
|
||||||
|
|
||||||
if (! retval) {
|
if (! retval) {
|
||||||
@ -114,8 +124,13 @@ class UiPopup extends Webcomponent {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Disable multiple clicks
|
||||||
|
if (retval !== undefined) {
|
||||||
|
element.setAttribute('disabled', 'disabled');
|
||||||
|
}
|
||||||
|
|
||||||
this.dispatchEvent(new CustomEvent('action:' + element.attributes.action.value));
|
this.dispatchEvent(new CustomEvent('action:' + element.attributes.action.value));
|
||||||
this.trigger.dispatchEvent(new CustomEvent('action:' + element.attributes.action.value));
|
this.trigger && this.trigger.dispatchEvent(new CustomEvent('action:' + element.attributes.action.value));
|
||||||
|
|
||||||
if ( element.getAttribute("action") ) {
|
if ( element.getAttribute("action") ) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -126,10 +141,15 @@ class UiPopup extends Webcomponent {
|
|||||||
|
|
||||||
hide() {
|
hide() {
|
||||||
this.classList.remove('visible');
|
this.classList.remove('visible');
|
||||||
|
|
||||||
|
window.scrollTo(window.scrollX, this.scrollPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
show() {
|
show() {
|
||||||
|
this.scrollPosition = window.scrollY;
|
||||||
this.classList.add('visible');
|
this.classList.add('visible');
|
||||||
|
|
||||||
|
window.scrollTo(window.scrollX, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
visible() {
|
visible() {
|
||||||
@ -140,8 +160,8 @@ class UiPopup extends Webcomponent {
|
|||||||
|
|
||||||
//if ( element.getAttribute('follow-link') !== null ) {
|
//if ( element.getAttribute('follow-link') !== null ) {
|
||||||
// Automatically redirect to given location if it exists.
|
// Automatically redirect to given location if it exists.
|
||||||
if ( this.trigger.tagName === "A" ) {
|
if ( this.trigger && this.trigger.tagName === "A" ) {
|
||||||
let href = this.trigger.getAttribute('href');
|
const href = this.trigger.getAttribute('href');
|
||||||
|
|
||||||
if ( href ) {
|
if ( href ) {
|
||||||
window.location = href;
|
window.location = href;
|
||||||
@ -155,12 +175,11 @@ class UiPopup extends Webcomponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
actionClickButton(element) {
|
actionClickButton(element) {
|
||||||
|
if (this.trigger) {
|
||||||
//if ( element.getAttribute('button-click') !== null ) {
|
const tag = this.trigger.tagName.toLowerCase();
|
||||||
let tag = this.trigger.tagName.toLowerCase();
|
|
||||||
|
|
||||||
// Automatically redirect to given location if it exists.
|
// Automatically redirect to given location if it exists.
|
||||||
if ( ( tag === "button" || tag === "input" ) && this.trigger.getAttribute("type").toLowerCase() === "submit") {
|
if ((tag === "button" || tag === "input") && this.trigger.getAttribute("type").toLowerCase() === "submit") {
|
||||||
this.pause = true;
|
this.pause = true;
|
||||||
|
|
||||||
this.trigger.click();
|
this.trigger.click();
|
||||||
@ -169,6 +188,7 @@ class UiPopup extends Webcomponent {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//}
|
//}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -179,8 +199,6 @@ class UiPopup extends Webcomponent {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if ( element.getAttribute('send-form') !== null ) {
|
|
||||||
//let form = this.trigger.tagName === "FORM" ? this.trigger : this.trigger.closest('FORM');
|
|
||||||
let form = element.tagName === "FORM" ? element : element.closest('FORM');
|
let form = element.tagName === "FORM" ? element : element.closest('FORM');
|
||||||
|
|
||||||
if ( form ) {
|
if ( form ) {
|
||||||
@ -192,7 +210,7 @@ class UiPopup extends Webcomponent {
|
|||||||
submitBtn.click();
|
submitBtn.click();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
form.submit();
|
form.requestSubmit();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -234,7 +252,6 @@ class UiPopup extends Webcomponent {
|
|||||||
|
|
||||||
args.options['input'] && Object.keys(args.options['input']).forEach(
|
args.options['input'] && Object.keys(args.options['input']).forEach(
|
||||||
key => this.querySelectorAll(`[name="${key}"]`).forEach(function(f) {
|
key => this.querySelectorAll(`[name="${key}"]`).forEach(function(f) {
|
||||||
console.log(f);
|
|
||||||
f.value = args.options['input'][key];
|
f.value = args.options['input'][key];
|
||||||
f.dispatchEvent(new Event("change"));
|
f.dispatchEvent(new Event("change"));
|
||||||
})
|
})
|
||||||
@ -244,6 +261,8 @@ class UiPopup extends Webcomponent {
|
|||||||
key => {
|
key => {
|
||||||
let form = this.querySelector(`form${key}`);
|
let form = this.querySelector(`form${key}`);
|
||||||
|
|
||||||
|
form = form ? form : this.closest(`form${key}`);
|
||||||
|
|
||||||
if (form) {
|
if (form) {
|
||||||
form.setAttribute('action', args.options['form_url'][key]);
|
form.setAttribute('action', args.options['form_url'][key]);
|
||||||
}
|
}
|
||||||
@ -298,6 +317,22 @@ class UiPopup extends Webcomponent {
|
|||||||
return this._message = value;
|
return this._message = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get options() {
|
||||||
|
return this.#options;
|
||||||
|
}
|
||||||
|
|
||||||
|
set options(value) {
|
||||||
|
return this.#options = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get scrollPosition() {
|
||||||
|
return this.#scrollPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
set scrollPosition(value) {
|
||||||
|
return this.#scrollPosition = value;
|
||||||
|
}
|
||||||
|
|
||||||
get title() {
|
get title() {
|
||||||
return this._title;
|
return this._title;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,11 +13,9 @@ const config = {
|
|||||||
class UiTabs extends Webcomponent {
|
class UiTabs extends Webcomponent {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(config);
|
super(config);
|
||||||
|
|
||||||
this.init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
connectedCallback() {
|
||||||
window.addEventListener("hashchange", this.hashChange.bind(this), false);
|
window.addEventListener("hashchange", this.hashChange.bind(this), false);
|
||||||
|
|
||||||
//this.querySelectorAll(this.config.item).forEach(ele => ele.addEventListener("click", this.clickTab.bind(this)));
|
//this.querySelectorAll(this.config.item).forEach(ele => ele.addEventListener("click", this.clickTab.bind(this)));
|
||||||
@ -32,7 +30,7 @@ class UiTabs extends Webcomponent {
|
|||||||
hashChange(e) {
|
hashChange(e) {
|
||||||
let anchor = e.newURL.split('#')[1];
|
let anchor = e.newURL.split('#')[1];
|
||||||
|
|
||||||
document.querySelectorAll("#" + anchor + this.config.content).forEach(function(content) {
|
document.querySelectorAll(`[id='${anchor}']${this.config.content}`).forEach(function(content) {
|
||||||
content.parentNode.querySelectorAll(this.config.content + "." + this.config.activeClass).forEach(ele => ele.classList.remove(this.config.activeClass));
|
content.parentNode.querySelectorAll(this.config.content + "." + this.config.activeClass).forEach(ele => ele.classList.remove(this.config.activeClass));
|
||||||
content.classList.add(this.config.activeClass);
|
content.classList.add(this.config.activeClass);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|||||||
67
asset/webcomponent/module/ui-upload.js
Normal file
67
asset/webcomponent/module/ui-upload.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
|
||||||
|
import { Webcomponent } from './webcomponent.js';
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
content: {
|
||||||
|
wrapper: ".wrapper",
|
||||||
|
list: ".item-list"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class UiUpload extends Webcomponent {
|
||||||
|
#input;
|
||||||
|
#uploadmedia;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
this.attachInput();
|
||||||
|
|
||||||
|
this.#uploadmedia = document.querySelector(`ui-upload-media[data-name="${this.name}"]`)
|
||||||
|
}
|
||||||
|
|
||||||
|
attachInput() {
|
||||||
|
this.#input = this.querySelector('input:not([type="hidden"])');
|
||||||
|
this.addEventListener('click', () => this.#input.click());
|
||||||
|
this.#input.addEventListener('change', this.changeMedia.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
changeMedia(e) {
|
||||||
|
let inputHtml = this.#input.outerHTML;
|
||||||
|
|
||||||
|
Array.from(this.#input.files).forEach(file => {
|
||||||
|
const base64Res = new FileReader();
|
||||||
|
this.#uploadmedia.addThumbnail(base64Res, this.#input);
|
||||||
|
base64Res.readAsDataURL(file)
|
||||||
|
});
|
||||||
|
|
||||||
|
this.getSlot("input").insertAdjacentHTML('beforeend', inputHtml);
|
||||||
|
this.attachInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return this.dataset['name'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UiUploadMedia extends Webcomponent {
|
||||||
|
addThumbnail(media, input) {
|
||||||
|
const wrapper = this.shadowRoot.querySelector(".new-media-wrapper"),
|
||||||
|
mediaItem = this.shadowRoot.querySelector(".new-media-item[hidden]").cloneNode(true);
|
||||||
|
|
||||||
|
mediaItem.removeAttribute('hidden');
|
||||||
|
wrapper.append(mediaItem);
|
||||||
|
this.getSlot("input").append(input);
|
||||||
|
|
||||||
|
media.onload = f => {
|
||||||
|
mediaItem.querySelector('img').setAttribute('src', media.result);
|
||||||
|
// mediaItem.querySelector('.name-input').value = file.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export { UiUpload, UiUploadMedia }
|
||||||
@ -1,14 +1,16 @@
|
|||||||
<style>
|
<style>
|
||||||
ui-popup:not(.modal) {box-shadow:0px 0px 0px 9999px rgba(0, 0, 0, 0.5);z-index:9999;transition:all 0.3s ease-out;background:#fff;position:absolute!important;top:0;left: 50%;transform:translate(-50%, 5vh);}
|
ui-popup:not(.modal) {box-shadow:0px 0px 0px 9999px rgba(0, 0, 0, 0.5);z-index:9999;transition:all 0.3s ease-out;background:#fff;position:absolute!important;top:0;left: 50%;transform:translate(-50%, 5vh);border: 2px solid #ddd;}
|
||||||
ui-popup:not(.visible) {transform: translate(-50%, -100%);transition-timing-function: ease-in;translate(-50%, -100%);box-shadow:none;}
|
ui-popup:not(.visible) {transform: translate(-50%, -100%);transition-timing-function: ease-in;translate(-50%, -100%);box-shadow:none;}
|
||||||
ui-popup.modal.visible {display:flex}
|
ui-popup.modal.visible {display:flex}
|
||||||
ui-popup > * {padding:1.5rem}
|
ui-popup > * {padding:1rem 1.4rem}
|
||||||
ui-popup .button-list {text-align:right;}
|
ui-popup .button-list {text-align:right;}
|
||||||
ui-popup .button-list .button {padding: 0px 7%;}
|
ui-popup .button-list .button {padding: 0px 7%;}
|
||||||
ui-popup [slot="title"] {font-size:1.5rem;display:flex;justify-content: space-between;background:rgba(120,120,120,0.12);color:#464646}
|
ui-popup [slot="title"] {font-size:1.5rem;display:flex;justify-content: space-between;background:rgba(120,120,120,0.12);color:#464646}
|
||||||
|
ui-popup [slot="title"]:empty {display:none}
|
||||||
ui-popup [slot="message"] {background: transparent;padding:1.2rem 1.5rem!important}
|
ui-popup [slot="message"] {background: transparent;padding:1.2rem 1.5rem!important}
|
||||||
ui-popup [slot="buttons"] {background:rgba(120,120,120,0.07)}
|
ui-popup [slot="buttons"] {background:rgba(120,120,120,0.07)}
|
||||||
ui-popup::before {left:0;right:0;top:0;bottom:0;background:rgba(0,0,0,0.1);content:" ";}
|
ui-popup [slot="buttons"]:empty {display:none}
|
||||||
|
ui-popup::before {left:0;right:0;top:0;bottom:0;background:rgba(0,0,0,0.1);content:" ";pointer-events: none}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<template id="ui-popup">
|
<template id="ui-popup">
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
<template id="ui-textarea">
|
<template id="ui-textarea">
|
||||||
<style>
|
<style>
|
||||||
.wrapper {position:relative;max-width:100%;}
|
.wrapper {position:relative;max-width:100%;}
|
||||||
|
|||||||
30
view/webcomponent/ui-upload.phtml
Normal file
30
view/webcomponent/ui-upload.phtml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<template id="ui-upload">
|
||||||
|
<style>
|
||||||
|
[hidden] {display:none !important}
|
||||||
|
.image-drop {display:flex;border-radius:4px;cursor:pointer;height:30vh;background:#fff;margin:5vh auto;text-align:center;border:1px dashed #909599;font-size:3rem;justify-content:center;align-items:center;}
|
||||||
|
.image-drop:hover {border-color:#676565}
|
||||||
|
.image-drop:hover span {text-decoration: underline;}
|
||||||
|
.image-drop.ui-dragdrop-over {opacity:0.66;}
|
||||||
|
.image-drop .drop-file {display:inline-block;line-height:20vh;color:#888;font-size:1.5em;}
|
||||||
|
.image-drop i {opacity:0.7}
|
||||||
|
.image-drop:hover i {opacity:1.0}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<label class="image-drop">
|
||||||
|
<slot style="display:none" name="input"></slot>
|
||||||
|
<slot name="icon"></slot>
|
||||||
|
</label>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="ui-upload-media">
|
||||||
|
<style>
|
||||||
|
* {box-sizing: border-box}
|
||||||
|
img {max-height: 15vh;max-width:100%}
|
||||||
|
.new-media-wrapper {display:flex;flex-flow:wrap;align-items:center;background: #e3e3e3;border: 1px solid #ccc;}
|
||||||
|
.new-media-item {width:33.33%;padding:2%}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="new-media-item" hidden><div><img></div></div>
|
||||||
|
|
||||||
|
<div class="new-media-wrapper"></div>
|
||||||
|
</template>
|
||||||
Loading…
x
Reference in New Issue
Block a user