/
githubmirror
/
pocketbase
Обзор
Документация
Войти
/
githubmirror
/
pocketbase
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
ui/src/base/colorPicker.js
143 строки
4 KB
Gani Georgiev
update example code
04 июн 2026, 15:57
04 июн 2026, 15:57
4752ed8
Код
Авторство
О чём код?
window.app = window.app || {}; window.app.components = window.app.components || {}; /** * Color picker component (with predefined colors support). * * @example * ```js * app.components.colorPicker({ * predefinedColors: ["#ff0000", "#123456"], * value: () => data.color, * onchange: (newColor) => data.color = newColor, * }) * ``` * * @param {Object} [propsArg] * @return {Element} */ window.app.components.colorPicker = function(propsArg = {}) { const uniqueId = "picker_" + app.utils.randomString(); const props = store({ rid: undefined, id: undefined, hidden: undefined, inert: undefined, className: "", name: "", required: false, disabled: false, value: "", predefinedColors: [], // --- onchange: (newColor) => {}, onmount: (el) => {}, onunmount: (el) => {}, }); const watchers = app.utils.extendStore(props, propsArg); const local = store({ inputValue: "#ffffff", }); function handleOnchange(val) { val = val?.toLowerCase() || ""; props.onchange?.(val); } let inputTimeoutId; let input = t.input({ type: "color", className: "color-picker-input", id: () => props.id, name: () => props.name, required: () => props.required, disabled: () => props.disabled, value: () => { local.inputValue = props.value || "#ffffff"; return props.value || undefined; }, oninput: (e) => { local.inputValue = e.target.value; clearTimeout(inputTimeoutId); inputTimeoutId = setTimeout(() => { handleOnchange(e.target.value); }, 50); }, }); return t.div( { rid: props.rid, hidden: () => props.hidden, inert: () => props.inert, className: () => `color-picker ${props.className}`, onmount: (el) => { props.onmount?.(el); }, onunmount: (el) => { clearTimeout(inputTimeoutId); props.onunmount?.(el); watchers.forEach((w) => w?.unwatch()); }, }, t.div( { className: "color-picker-input-wrapper" }, input, t.output({ className: "result", // black or white text (https://developer.chrome.com/blog/css-relative-color-syntax) // @todo replace with contrast-color once there is better support? style: () => `color: lch(from ${local.inputValue || "#ffffff"} calc((49 - l) * infinity) 0 0);`, textContent: () => local.inputValue, }), ), t.button( { hidden: () => !props.predefinedColors.length, type: "button", title: "Predefined colors", className: "link-hint predefined-colors-btn", "html-popovertarget": uniqueId + "predefined-colors-dropdown", }, t.i({ className: "ri-arrow-down-s-line", ariaHidden: true }), ), t.div( { pbEvent: "predefinedColorsDropdown", id: uniqueId + "predefined-colors-dropdown", className: "dropdown predefined-colors-dropdown", popover: "auto", }, t.div( { className: "predefined-colors-list", }, () => { return props.predefinedColors?.map((color) => { return t.button({ type: "button", className: () => `color ${props.value == color ? "active" : ""}`, style: `background:${color}`, onclick: (e) => { if (!input) { return; } e.target.closest(".dropdown")?.hidePopover(); input.value = color || undefined; input.dispatchEvent(new Event("input", { bubbles: true })); }, }); }); }, ), ), ); };