Fully implemented the Manage Time functionality
This commit is contained in:
@@ -6,7 +6,7 @@ function createSearchableSelect({ environment }) {
|
||||
if (text !== undefined) node.textContent = text;
|
||||
return node;
|
||||
}
|
||||
function searchableSelect(select, field, onChange, { floating = false, tooltipContent } = {}) {
|
||||
function searchableSelect(select, field, onChange, { floating = false, tooltipContent, listWidth = 0, listMaxHeight = 180 } = {}) {
|
||||
const box = element("div", "opportunities-extension-action-combobox");
|
||||
const input = element("input");
|
||||
input.type = "text";
|
||||
@@ -79,11 +79,11 @@ function createSearchableSelect({ environment }) {
|
||||
input.value = options().find(item => item.value === select.value)?.textContent || "";
|
||||
input.title = tooltipContent ? "" : input.value;
|
||||
}
|
||||
function highlight() {
|
||||
function highlight(withTooltip = true) {
|
||||
Array.from(list.children).forEach((node, i) => node.setAttribute("aria-selected", String(i === index)));
|
||||
input.setAttribute("aria-activedescendant", matches[index] ? `${list.id}-${index}` : "");
|
||||
list.children[index]?.scrollIntoView?.({ block: "nearest" });
|
||||
if (matches[index]) showTooltip(matches[index].value, list.children[index]);
|
||||
if (withTooltip && matches[index]) showTooltip(matches[index].value, list.children[index]);
|
||||
}
|
||||
function choose(i) {
|
||||
if (!matches[i]) return;
|
||||
@@ -93,18 +93,22 @@ function createSearchableSelect({ environment }) {
|
||||
if (changed) onChange?.();
|
||||
}
|
||||
function positionList() {
|
||||
const bounds = input.closest?.(".opportunities-extension-action-form-dialog")?.getBoundingClientRect();
|
||||
let bounds = input.closest?.(".opportunities-extension-action-form-dialog")?.getBoundingClientRect();
|
||||
const anchor = input.getBoundingClientRect?.();
|
||||
if (!bounds || !anchor) return;
|
||||
if (floating && listWidth && document.documentElement?.clientWidth) {
|
||||
bounds = { top: 0, left: 0, right: document.documentElement.clientWidth, bottom: document.documentElement.clientHeight };
|
||||
}
|
||||
const below = Math.max(0, bounds.bottom - anchor.bottom - 8);
|
||||
const above = Math.max(0, anchor.top - bounds.top - 8);
|
||||
const opensAbove = below < 180 && above > below;
|
||||
const opensAbove = below < listMaxHeight && above > below;
|
||||
list.setAttribute("data-placement", opensAbove ? "above" : "below");
|
||||
list.style.maxHeight = `${Math.min(180, opensAbove ? above : below)}px`;
|
||||
list.style.maxHeight = `${Math.min(listMaxHeight, opensAbove ? above : below)}px`;
|
||||
if (floating) {
|
||||
const width = listWidth ? Math.min(Math.max(anchor.width, listWidth), bounds.right - bounds.left - 16) : anchor.width;
|
||||
list.style.position = "fixed";
|
||||
list.style.left = `${anchor.left}px`;
|
||||
list.style.width = `${anchor.width}px`;
|
||||
list.style.left = `${listWidth ? Math.max(bounds.left + 8, Math.min(anchor.left, bounds.right - width - 8)) : anchor.left}px`;
|
||||
list.style.width = `${width}px`;
|
||||
list.style.right = "auto";
|
||||
list.style.bottom = "auto";
|
||||
list.style.top = `${opensAbove ? anchor.top - 4 : anchor.bottom + 4}px`;
|
||||
@@ -115,7 +119,7 @@ function createSearchableSelect({ environment }) {
|
||||
if (input.disabled) return;
|
||||
hideTooltip();
|
||||
matches = options().filter(item => normalize(`${item.textContent} ${item.getAttribute?.("data-description") || ""} ${item.value}`).includes(normalize(query)));
|
||||
index = -1;
|
||||
index = matches.findIndex(item => item.value === select.value);
|
||||
list.textContent = "";
|
||||
matches.forEach((item, i) => {
|
||||
const row = element("div", "opportunities-extension-action-option", item.textContent);
|
||||
@@ -140,7 +144,7 @@ function createSearchableSelect({ environment }) {
|
||||
positionList();
|
||||
list.hidden = false;
|
||||
input.setAttribute("aria-expanded", "true");
|
||||
input.setAttribute("aria-activedescendant", "");
|
||||
highlight(false);
|
||||
}
|
||||
input.addEventListener("click", () => { render(); input.select?.(); });
|
||||
input.addEventListener("input", () => render(input.value));
|
||||
|
||||
Reference in New Issue
Block a user