wip file field
This commit is contained in:
@@ -1,3 +1,46 @@
|
||||
export function init(){
|
||||
import {onClickOutside} from "./../helpers/clickOutside.js";
|
||||
|
||||
export function dropdown() {
|
||||
document.querySelectorAll(".dropdown").forEach(el => {
|
||||
dropdownInit(el);
|
||||
})
|
||||
}
|
||||
|
||||
function dropdownInit(el) {
|
||||
const button = el.querySelector("button");
|
||||
const menu = el.querySelector(".dropdown-menu");
|
||||
button.addEventListener('click', function () {
|
||||
if (menu.hasAttribute('hidden')) {
|
||||
this.setAttribute('aria-expanded', 'true');
|
||||
menu.removeAttribute('hidden');
|
||||
|
||||
// Set focus on first link
|
||||
// will be highlighted for keyboard users
|
||||
menu.querySelector(".dropdown-item:first-child")?.focus();
|
||||
} else {
|
||||
menu.setAttribute('hidden', 'true');
|
||||
this.setAttribute('aria-expanded', 'false');
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', (event) => {
|
||||
// Ignore IME composition
|
||||
if (event.isComposing || event.key === "esc") {
|
||||
return;
|
||||
}
|
||||
|
||||
// Close menu with ESC key
|
||||
if (event.keyCode === 27) {
|
||||
if (!menu.hasAttribute('hidden')) {
|
||||
menu.setAttribute('aria-expanded', 'false');
|
||||
menu.setAttribute('hidden', 'true');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
onClickOutside(menu, ".dropdown", () => menu.hidden = true);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export function onClickOutside(ele, closest, cb) {
|
||||
document.addEventListener('click', function (event) {
|
||||
if (!event.target.closest(closest)) {
|
||||
cb(event)
|
||||
}
|
||||
}, false);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
export function throttle(delay, callback, options) {
|
||||
const {
|
||||
noTrailing = false,
|
||||
noLeading = false,
|
||||
debounceMode = undefined
|
||||
} = options || {};
|
||||
|
||||
let timeoutID;
|
||||
let cancelled = false;
|
||||
let lastExec = 0;
|
||||
|
||||
function clearExistingTimeout() {
|
||||
if (timeoutID) {
|
||||
clearTimeout(timeoutID);
|
||||
}
|
||||
}
|
||||
|
||||
function cancel(options) {
|
||||
const {upcomingOnly = false} = options || {};
|
||||
clearExistingTimeout();
|
||||
cancelled = !upcomingOnly;
|
||||
}
|
||||
|
||||
function wrapper(...arguments_) {
|
||||
let self = this;
|
||||
let elapsed = Date.now() - lastExec;
|
||||
|
||||
if (cancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
function exec() {
|
||||
lastExec = Date.now();
|
||||
callback.apply(self, arguments_);
|
||||
}
|
||||
|
||||
function clear() {
|
||||
timeoutID = undefined;
|
||||
}
|
||||
|
||||
if (!noLeading && debounceMode && !timeoutID) {
|
||||
exec();
|
||||
}
|
||||
|
||||
clearExistingTimeout();
|
||||
|
||||
if (debounceMode === undefined && elapsed > delay) {
|
||||
if (noLeading) {
|
||||
lastExec = Date.now();
|
||||
if (!noTrailing) {
|
||||
timeoutID = setTimeout(debounceMode ? clear : exec, delay);
|
||||
}
|
||||
} else {
|
||||
exec();
|
||||
}
|
||||
} else if (noTrailing !== true) {
|
||||
timeoutID = setTimeout(
|
||||
debounceMode ? clear : exec,
|
||||
debounceMode === undefined ? delay - elapsed : delay
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
wrapper.cancel = cancel;
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
|
||||
export function debounce(delay, callback, options) {
|
||||
const {atBegin = false} = options || {};
|
||||
return throttle(delay, callback, {debounceMode: atBegin !== false});
|
||||
}
|
||||
@@ -4,6 +4,13 @@ import Account from "./svelte/Account.svelte";
|
||||
import Channel from "./svelte/Channel.svelte";
|
||||
import Mustache from "mustache";
|
||||
import 'htmx.org';
|
||||
import {dropdown} from "./components/dropdown.js";
|
||||
import {colorPicker} from "./recordEditor/colorPicker.js";
|
||||
|
||||
addEventListener("load", (event) => {
|
||||
dropdown()
|
||||
colorPicker()
|
||||
});
|
||||
|
||||
Mustache.escape = function (value) {
|
||||
return value;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
export function colorPicker() {
|
||||
document.querySelectorAll(".color-picker").forEach(el => {
|
||||
colorPickerInit(el);
|
||||
})
|
||||
}
|
||||
|
||||
function colorPickerInit(el){
|
||||
const colorInput = el.querySelector("[type=color]");
|
||||
const textInput = el.querySelector("[type=text]");
|
||||
|
||||
colorInput.addEventListener("change",(e) => textInput.value = colorInput.value);
|
||||
textInput.addEventListener("change",(e) => colorInput.value = textInput.value);
|
||||
}
|
||||
Reference in New Issue
Block a user