From 251aa899e8d8cb85fc58ac6d1edec987af0e4904 Mon Sep 17 00:00:00 2001 From: Jeff Lindsay Date: Mon, 13 Mar 2023 15:39:59 -0500 Subject: [PATCH] lib: add general curtain for escape and click off of menus, search, palette, etc. closes #48 --- lib/mod.ts | 10 +++++-- lib/ui/app.tsx | 11 ++++++- lib/ui/menu.tsx | 3 +- lib/ui/palette.tsx | 6 ++-- lib/ui/search.tsx | 73 +++++++++++++++++++++++++++++----------------- lib/workspace.ts | 12 ++++++++ 6 files changed, 79 insertions(+), 36 deletions(-) diff --git a/lib/mod.ts b/lib/mod.ts index fb8a12a..93206e7 100644 --- a/lib/mod.ts +++ b/lib/mod.ts @@ -397,11 +397,15 @@ export async function setup(document: Document, target: HTMLElement, backend: Ba workspace.commands.executeCommand(binding.command, workspace.context); e.stopPropagation(); e.preventDefault(); + return; } - }); - document.addEventListener("click", (e) => { - workspace.hideMenu(); + // TODO: find a better way to do this? + if (e.key === "Escape") { + if (workspace.curtain && workspace.curtain.onclick) { + workspace.curtain.onclick(e); + } + } }); diff --git a/lib/ui/app.tsx b/lib/ui/app.tsx index 55b6aec..a49f41a 100644 --- a/lib/ui/app.tsx +++ b/lib/ui/app.tsx @@ -68,7 +68,16 @@ export const App: m.Component = { ))} - + + {workspace.curtain && +
} {workspace.menu && } {workspace.palette && } {workspace.quickadd && } diff --git a/lib/ui/menu.tsx b/lib/ui/menu.tsx index f197833..c801e70 100644 --- a/lib/ui/menu.tsx +++ b/lib/ui/menu.tsx @@ -31,7 +31,8 @@ export const Menu: m.Component = { background: "white", filter: "drop-shadow(2px 2px 4px #5555)", fontSize: "14px", - minWidth: "200px" + minWidth: "200px", + zIndex: "20" })}> {items.filter(i => !i.when || i.when()).map(i => { let title = ""; diff --git a/lib/ui/palette.tsx b/lib/ui/palette.tsx index dd2773b..b977f7e 100644 --- a/lib/ui/palette.tsx +++ b/lib/ui/palette.tsx @@ -40,9 +40,6 @@ export const CommandPalette: m.Component = { } return false; } - if (e.key === "Escape") { - workspace.hidePalette(); - } } const autocomplete = (e) => { state.filter = e.target.value; @@ -59,7 +56,8 @@ export const CommandPalette: m.Component = { padding: "0.5rem", background: "white", fontSize: "14px", - minWidth: "400px" + minWidth: "400px", + zIndex: "20" }}>
{ - let node = workspace.nodes.find(id); - if (!node) { - return undefined; - } - // if component value, get the parent - if (node.getValue()) { - node = node.getParent(); - // parent might not actually exist - if (!node.raw) return; - } - return node; - }).filter(n => n !== undefined); + state.results = (state.results === undefined) ? [] : state.results; + + const clear = () => { + state.query = ""; + state.results = []; + workspace.curtain = null; } const open = (node) => { workspace.open(node); - state.query = ""; + clear(); } const onkeydown = (e) => { @@ -41,50 +30,80 @@ export const Search: m.Component = { state.selected = 0; return; } - state.selected = mod(state.selected+1, results.length); + state.selected = mod(state.selected+1, state.results.length); return false; } if (e.key === "ArrowUp") { if (state.selected === undefined) { state.selected = 0; } - state.selected = mod(state.selected-1, results.length); + state.selected = mod(state.selected-1, state.results.length); return false; } if (e.key === "Enter") { if (state.selected !== undefined) { - open(results[state.selected]); + open(state.results[state.selected]); } return false; } if (e.key === "Escape") { - state.query = ""; + clear(); } } + const autocomplete = (e) => { state.query = e.target.value; state.selected = 0; + + if (state.query) { + state.results = workspace.backend.index.search(state.query).map(id => { + let node = workspace.nodes.find(id); + if (!node) { + return undefined; + } + // if component value, get the parent + if (node.getValue()) { + node = node.getParent(); + // parent might not actually exist + if (!node.raw) return; + } + return node; + }).filter(n => n !== undefined); + } else { + state.results = []; + } + + if (state.query && state.results.length > 0) { + workspace.curtain = { + visible: false, + onclick: () => clear() + }; + } else { + workspace.curtain = null; + } + } + return (