Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

fix: palette chaining with compatibility #1215

Merged
merged 1 commit into from
Mar 21, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 47 additions & 11 deletions src/components/palette/index.js
Original file line number Diff line number Diff line change
@@ -47,7 +47,13 @@ This shows that using keyboardHideStart event is faster than not using it.
* @param {function} onremove Callback to call when palette is removed
* @returns {void}
*/
// Track active palette for chaining
let activePalette = null;

export default function palette(getList, onsSelectCb, placeholder, onremove) {
// Store previous palette if exists
const previousPalette = activePalette;
const isChained = !!previousPalette;
/**@type {HTMLInputElement} */
const $input = (
<input
@@ -65,8 +71,11 @@ export default function palette(getList, onsSelectCb, placeholder, onremove) {
// Create a palette with input and hints
inputhints($input, generateHints, onSelect);

// Removes the darkened color from status bar and navigation bar
restoreTheme(true);
// Only set the darkened theme when this is not a chained palette
if (!isChained) {
// Removes the darkened color from status bar and navigation bar
restoreTheme(true);
}

// Remove palette when input is blurred
$input.addEventListener("blur", remove);
@@ -77,24 +86,41 @@ export default function palette(getList, onsSelectCb, placeholder, onremove) {
// Add to DOM
app.append($palette, $mask);

// If we're in a chained palette, ensure we don't lose focus
if (isChained) {
// Don't let any blur events from previous palette affect this one
setTimeout(() => {
$input.focus();
}, 0);
}

// Focus input to show options
$input.focus();

// Trigger input event to show hints immediately
$input.dispatchEvent(new Event("input"));

// Add to action stack to remove on back button
actionStack.push({
id: "palette",
action: remove,
});
// Store this palette as the active one for chaining
activePalette = { remove };

/**
* On select callback for inputhints
* @param {string} value
*/
function onSelect(value) {
remove();
setTimeout(() => {
onsSelectCb(value);
}, 0);
const currentPalette = { remove };
activePalette = currentPalette;

onsSelectCb(value);

if (activePalette === currentPalette) {
remove();
}
}

/**
@@ -113,7 +139,7 @@ export default function palette(getList, onsSelectCb, placeholder, onremove) {
*/
async function generateHints(setHints, hintModification) {
const list = getList(hintModification);
let data = list instanceof Promise ? await list : list;
const data = list instanceof Promise ? await list : list;
setHints(data);
}

@@ -125,18 +151,28 @@ export default function palette(getList, onsSelectCb, placeholder, onremove) {
keyboardHandler.off("keyboardHideStart", remove);
$input.removeEventListener("blur", remove);

restoreTheme();
$palette.remove();
$mask.remove();

// Restore previous palette if chained
if (isChained && previousPalette) {
activePalette = previousPalette;
} else {
activePalette = null;
restoreTheme();
}

if (typeof onremove === "function") {
onremove();
return;
}

const { activeFile, editor } = editorManager;
if (activeFile.wasFocused) {
editor.focus();
// If not chained or last in chain, focus the editor
if (!isChained) {
const { activeFile, editor } = editorManager;
if (activeFile.wasFocused) {
editor.focus();
}
}

remove = () => {
2 changes: 0 additions & 2 deletions src/palettes/changeTheme/index.js
Original file line number Diff line number Diff line change
@@ -8,8 +8,6 @@ export default function changeTheme(type = "editor") {
() => generateHints(type),
(value) => onselect(value),
strings[type === "editor" ? "editor theme" : "app theme"],
undefined,
(value) => onselect(value),
);
}