Accessing internal state of CP from command handlers.
Opened this issue · 1 comments
I am looking at implementing a formatting function for a text area to be triggered from
command pal. To do this, being able to see what control was focused when command-pal
was invoked would be valuable.
Obviously I can't find that when command-pal is active as focus is in the search input.
In pull #33 I set focusedElement to store that data when command-pal is activated by
hotkey or button click.
It would be nice to access that from c.focusedElement (c=CommandPal(...)) or something.
Any ideas on how to do this cleanly?
I did manage to add a new displayPalette() method on #28. But the implementation feels hacky.
I have a new way to do this that should replace #28 (issue #25) as well as expose internal state.
In main.js:
appInternalInfo: object = { focusedElement: null; displayPalette: null, ...};
class CommandPal {
...
start () {
this.app = new App({ ...,
props: { ...
exposeInternals: appInternalInfo,
} });
displayPalette(state) { appInternalInfo.displayPalette(state) }
/* use setter/getter on (virtual) focusedElement property of CommandPal */
get focusedElement() {
return appInternalInfo.focusedElement && appInternalInfo.focusedElement()
}
set focusedElement(newElement) {
return appInternalInfo.focusedElement(newElement)
}
in App.svelte:
...
export let exposeInternals: any; // should be object, but without creating an
// interface here and needing to keep it in sync
// with appInternalInfo in main.js any will do;
let focusedElement: HTMLElement | null = null; // also requires casting all
// <HTMLElement>document.activeElement
exposeInternals.focusedElement = (newValue) => (
newValue ? focusedElement=newValue : focusedElement )
exposeInternals.displayPalette = async active_state => {
if (! showModal) {focusedElement = <HTMLElement>document.activeElement}
if (active_state === undefined) {
showModal = !showModal;
} else if ([true, false].includes(active_state)) {
showModal = active_state;
} else {
throw("Non-boolean: " + active_state +
" - passed to displayPalette")
}
}
onMount(() => { ... }
This removed the need for an entire file and functions used to pass the displayPalette method.
For read only props, you could use:
$: exposeInternals.read_me = showModal
Plus you can expose both hotkey.js and Fuse that are bundled into command-pal to the
web page so they don't have to load those libraries and can piggyback off the bundled ones.
// in shortcuts.js use
export hk = hotkey;
// in App.svelte
import hk from "./shortcuts";
exposeInternals.Fuse = Fuse
exposeInternals.hotkey = hk
Thoughts?