Up/Down arrow + enter select in directory suggestion; Escape key escape

This commit is contained in:
Christian Bastian
2024-01-25 03:23:02 -05:00
parent 7a0cab8350
commit dd6084ad6d
2 changed files with 110 additions and 42 deletions

View File

@@ -362,7 +362,14 @@
} }
.model-manager .search-dropdown > p { .model-manager .search-dropdown > p {
margin-left: 20px; margin: 0;
padding-left: 20px;
padding-top: 0.85em;
padding-bottom: 0.85em;
}
.model-manager .search-dropdown > p.search-dropdown-selected {
background-color: var(--border-color);
} }
.model-manager .button-success { .model-manager .button-success {

View File

@@ -55,9 +55,8 @@ const modelNodeType = {
* @param {string} modelType * @param {string} modelType
* @param {string} filter * @param {string} filter
*/ */
function updateDirectorySuggestionDropdown(dropdown, directories, modelType, filter) { function updateDirectorySuggestionDropdown(dropdown, directories, modelType, filter, sep) {
let options = []; let options = [];
const sep = "/";
if (filter[0] === sep) { if (filter[0] === sep) {
let cwd = null; let cwd = null;
const root = directories[0]; const root = directories[0];
@@ -134,7 +133,9 @@ function updateDirectorySuggestionDropdown(dropdown, directories, modelType, fil
} }
const innerHtml = options.map((text) => { const innerHtml = options.map((text) => {
return $el("p", [text]); const p = $el("p", [text]);
//p.onclick = (e) => { console.log(e.target); }; // TODO: Click on dropdown elements when input gets blurred?
return p;
}); });
dropdown.innerHTML = ""; dropdown.innerHTML = "";
dropdown.append.apply(dropdown, innerHtml); dropdown.append.apply(dropdown, innerHtml);
@@ -709,44 +710,46 @@ function $radioGroup(attr) {
class ModelManager extends ComfyDialog { class ModelManager extends ComfyDialog {
#el = { #el = {
loadSourceBtn: null, /** @type {HTMLButtonElement} */ loadSourceBtn: null,
loadSourceFromInput: null, /** @type {HTMLInputElement} */ loadSourceFromInput: null,
sourceInstalledFilter: null, /** @type {HTMLSelectElement} */ sourceInstalledFilter: null,
sourceContentFilter: null, /** @type {HTMLInputElement} */ sourceContentFilter: null,
sourceFilterBtn: null,
modelGrid: null, /** @type {HTMLDivElement} */ modelGrid: null,
modelTypeSelect: null, /** @type {HTMLSelectElement} */ modelTypeSelect: null,
modelDirectorySearchOptions: null, /** @type {HTMLDivElement} */ modelDirectorySearchOptions: null,
modelContentFilter: null, /** @type {HTMLInputElement} */ modelContentFilter: null,
sidebarButtons: null, /** @type {HTMLDivElement} */ sidebarButtons: null,
settingsTab: null, /** @type {HTMLDivElement} */ settingsTab: null,
reloadSettingsBtn: null, /** @type {HTMLButtonElement} */ reloadSettingsBtn: null,
saveSettingsBtn: null, /** @type {HTMLButtonElement} */ saveSettingsBtn: null,
settings: { settings: {
"sidebar-default-height": null, //"sidebar-default-height": null,
"sidebar-default-width": null, //"sidebar-default-width": null,
"model-search-always-append": null, /** @type {HTMLTextAreaElement} */ "model-search-always-append": null,
"model-persistent-search": null, /** @type {HTMLInputElement} */ "model-persistent-search": null,
"model-show-label-extensions": null, /** @type {HTMLInputElement} */ "model-show-label-extensions": null,
"model-show-add-button": null, /** @type {HTMLInputElement} */ "model-show-add-button": null,
"model-show-copy-button": null, /** @type {HTMLInputElement} */ "model-show-copy-button": null,
"model-add-embedding-extension": null, /** @type {HTMLInputElement} */ "model-add-embedding-extension": null,
"model-add-drag-strict-on-field": null, /** @type {HTMLInputElement} */ "model-add-drag-strict-on-field": null,
"model-add-offset": null, /** @type {HTMLInputElement} */ "model-add-offset": null,
} }
}; };
#data = { #data = {
sources: [], /** @type {Array} */ sources: [],
models: {}, /** @type {Object} */ models: {},
modelDirectories: null, /** @type {{name: string, childCount: ?int, childIndex: ?int}[]} */ modelDirectories: null,
prevousModelFilters: [], /** @type {Array} */ prevousModelFilters: [],
prevousModelType: undefined, /** @type {string} */ prevousModelType: undefined,
}; };
/** @type {string} */
sep = "/";
/** @type {SourceList} */ /** @type {SourceList} */
#sourceList = null; #sourceList = null;
@@ -830,7 +833,7 @@ class ModelManager extends ComfyDialog {
$el("input.search-text-area", { $el("input.search-text-area", {
$: (el) => (this.#el.sourceContentFilter = el), $: (el) => (this.#el.sourceContentFilter = el),
placeholder: "example: \"sd_xl\" -vae", placeholder: "example: \"sd_xl\" -vae",
onkeyup: (e) => e.key === "Enter" && this.#filterSourceList(), onkeydown: (e) => e.key === "Enter" && this.#filterSourceList(),
}), }),
$el("select", $el("select",
{ {
@@ -938,16 +941,19 @@ class ModelManager extends ComfyDialog {
} }
/** /**
* @returns {HTMLElement} * @returns {HTMLElement[]}
*/ */
#createModelTabHtml() { #createModelTabHtml() {
/** @type {HTMLDivElement} */
const modelGrid = $el("div.comfy-grid"); const modelGrid = $el("div.comfy-grid");
this.#el.modelGrid = modelGrid; this.#el.modelGrid = modelGrid;
/** @type {HTMLDivElement} */
const searchDropdown = $el("div.search-dropdown", { const searchDropdown = $el("div.search-dropdown", {
$: (el) => (this.#el.modelDirectorySearchOptions = el), $: (el) => (this.#el.modelDirectorySearchOptions = el),
style: { display: "none" }, style: { display: "none" },
}); });
const dropdownSelectClass = "search-dropdown-selected";
return [ return [
$el("div.row.tab-header", [ $el("div.row.tab-header", [
@@ -968,17 +974,71 @@ class ModelManager extends ComfyDialog {
$el("input.search-text-area", { $el("input.search-text-area", {
$: (el) => (this.#el.modelContentFilter = el), $: (el) => (this.#el.modelContentFilter = el),
placeholder: "example: /0/1.5/styles/clothing -.pt", placeholder: "example: /0/1.5/styles/clothing -.pt",
onkeyup: (e) => { onkeydown: (e) => {
if (e.key === "Enter") { const children = searchDropdown.children;
let iChild;
for (iChild = 0; iChild < children.length; iChild++) {
const child = children[iChild];
if (child.classList.contains(dropdownSelectClass)) {
break;
}
}
if (e.key === "Escape") {
e.stopPropagation();
if (iChild < children.length) {
const child = children[iChild];
child.classList.remove(dropdownSelectClass);
}
else {
e.target.blur();
}
}
else if (e.key === "Enter") {
e.stopPropagation();
if (iChild < children.length) {
const child = children[iChild];
child.classList.remove(dropdownSelectClass);
const selectedText = child.innerText;
const filterText = e.target.value;
const iSep = filterText.lastIndexOf(this.sep);
const previousPath = filterText.substring(0, iSep + 1);
e.target.value = previousPath + selectedText;
this.#modelUpdateFilterDropdown();
}
this.#modelGridUpdate(); this.#modelGridUpdate();
searchDropdown.style.display = "none"; searchDropdown.style.display = "none";
e.stopPropagation();
} }
}, else if (e.key === "ArrowDown" || e.key === "ArrowUp") {
onkeydown: (e) => {
if (e.key === "Escape") {
e.target.blur();
e.stopPropagation(); e.stopPropagation();
let iNext = children.length;
if (iChild < children.length) {
const child = children[iChild];
child.classList.remove(dropdownSelectClass);
const delta = e.key === "ArrowDown" ? 1 : -1;
iNext = iChild + delta;
if (0 <= iNext && iNext < children.length) {
const nextChild = children[iNext];
nextChild.classList.add(dropdownSelectClass);
}
}
else if (iChild === children.length) {
iNext = e.key === "ArrowDown" ? 0 : children.length-1;
const nextChild = children[iNext]
nextChild.classList.add(dropdownSelectClass);
}
if (0 <= iNext && iNext < children.length) {
let scrollTop = searchDropdown.scrollTop;
const dropdownHeight = searchDropdown.offsetHeight;
const child = children[iNext];
const childHeight = child.offsetHeight;
const childTop = child.offsetTop;
scrollTop = Math.max(scrollTop, childTop - dropdownHeight + childHeight);
scrollTop = Math.min(scrollTop, childTop);
searchDropdown.scrollTop = scrollTop;
}
else {
searchDropdown.scrollTop = 0;
}
} }
}, },
oninput: () => this.#modelUpdateFilterDropdown(), oninput: () => this.#modelUpdateFilterDropdown(),
@@ -1055,7 +1115,8 @@ class ModelManager extends ComfyDialog {
this.#el.modelDirectorySearchOptions, this.#el.modelDirectorySearchOptions,
this.#data.modelDirectories, this.#data.modelDirectories,
modelType, modelType,
filter filter,
this.sep
); );
this.#data.prevousModelFilters[modelType] = filter; this.#data.prevousModelFilters[modelType] = filter;
} }