mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
fix: command palette tweaks and fixes (#7876)
This commit is contained in:
parent
4987cc53d0
commit
f597bd3e01
10 changed files with 116 additions and 44 deletions
|
@ -1,6 +1,6 @@
|
|||
// place here categories that you want to track. We want to track just a
|
||||
// small subset of categories at a given time.
|
||||
const ALLOWED_CATEGORIES_TO_TRACK = ["ai"] as string[];
|
||||
const ALLOWED_CATEGORIES_TO_TRACK = ["ai", "command_palette"] as string[];
|
||||
|
||||
export const trackEvent = (
|
||||
category: string,
|
||||
|
|
|
@ -49,6 +49,8 @@ import { jotaiStore } from "../../jotai";
|
|||
import { activeConfirmDialogAtom } from "../ActiveConfirmDialog";
|
||||
import { CommandPaletteItem } from "./types";
|
||||
import * as defaultItems from "./defaultCommandPaletteItems";
|
||||
import { trackEvent } from "../../analytics";
|
||||
import { useStable } from "../../hooks/useStable";
|
||||
|
||||
import "./CommandPalette.scss";
|
||||
|
||||
|
@ -130,12 +132,20 @@ export const CommandPalette = Object.assign(
|
|||
if (isCommandPaletteToggleShortcut(event)) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
setAppState((appState) => ({
|
||||
openDialog:
|
||||
setAppState((appState) => {
|
||||
const nextState =
|
||||
appState.openDialog?.name === "commandPalette"
|
||||
? null
|
||||
: { name: "commandPalette" },
|
||||
}));
|
||||
: ({ name: "commandPalette" } as const);
|
||||
|
||||
if (nextState) {
|
||||
trackEvent("command_palette", "open", "shortcut");
|
||||
}
|
||||
|
||||
return {
|
||||
openDialog: nextState,
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
window.addEventListener(EVENT.KEYDOWN, commandPaletteShortcut, {
|
||||
|
@ -174,10 +184,20 @@ function CommandPaletteInner({
|
|||
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const stableDeps = useStable({
|
||||
uiAppState,
|
||||
customCommandPaletteItems,
|
||||
appProps,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!uiAppState || !app.scene || !actionManager) {
|
||||
return;
|
||||
}
|
||||
// these props change often and we don't want them to re-run the effect
|
||||
// which would renew `allCommands`, cascading down and resetting state.
|
||||
//
|
||||
// This means that the commands won't update on appState/appProps changes
|
||||
// while the command palette is open
|
||||
const { uiAppState, customCommandPaletteItems, appProps } = stableDeps;
|
||||
|
||||
const getActionLabel = (action: Action) => {
|
||||
let label = "";
|
||||
if (action.label) {
|
||||
|
@ -533,15 +553,13 @@ function CommandPaletteInner({
|
|||
);
|
||||
}
|
||||
}, [
|
||||
stableDeps,
|
||||
app,
|
||||
appProps,
|
||||
uiAppState,
|
||||
actionManager,
|
||||
setAllCommands,
|
||||
lastUsed?.label,
|
||||
setLastUsed,
|
||||
setAppState,
|
||||
customCommandPaletteItems,
|
||||
]);
|
||||
|
||||
const [commandSearch, setCommandSearch] = useState("");
|
||||
|
|
|
@ -4,7 +4,7 @@ import { KEYS } from "../keys";
|
|||
import { Dialog } from "./Dialog";
|
||||
import { getShortcutKey } from "../utils";
|
||||
import "./HelpDialog.scss";
|
||||
import { ExternalLinkIcon } from "./icons";
|
||||
import { ExternalLinkIcon, GithubIcon, youtubeIcon } from "./icons";
|
||||
import { probablySupportsClipboardBlob } from "../clipboard";
|
||||
import { isDarwin, isFirefox, isWindows } from "../constants";
|
||||
import { getShortcutFromShortcutName } from "../actions/shortcuts";
|
||||
|
@ -17,8 +17,8 @@ const Header = () => (
|
|||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{t("helpDialog.documentation")}
|
||||
<div className="HelpDialog__link-icon">{ExternalLinkIcon}</div>
|
||||
{t("helpDialog.documentation")}
|
||||
</a>
|
||||
<a
|
||||
className="HelpDialog__btn"
|
||||
|
@ -26,8 +26,8 @@ const Header = () => (
|
|||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{t("helpDialog.blog")}
|
||||
<div className="HelpDialog__link-icon">{ExternalLinkIcon}</div>
|
||||
{t("helpDialog.blog")}
|
||||
</a>
|
||||
<a
|
||||
className="HelpDialog__btn"
|
||||
|
@ -35,8 +35,17 @@ const Header = () => (
|
|||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="HelpDialog__link-icon">{GithubIcon}</div>
|
||||
{t("helpDialog.github")}
|
||||
<div className="HelpDialog__link-icon">{ExternalLinkIcon}</div>
|
||||
</a>
|
||||
<a
|
||||
className="HelpDialog__btn"
|
||||
href="https://youtube.com/@excalidraw"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="HelpDialog__link-icon">{youtubeIcon}</div>
|
||||
YouTube
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -2095,3 +2095,24 @@ export const DeviceDesktopIcon = createIcon(
|
|||
</g>,
|
||||
{ ...tablerIconProps, strokeWidth: 1.5 },
|
||||
);
|
||||
|
||||
// arrow-bar-to-left
|
||||
export const arrowBarToLeftIcon = createIcon(
|
||||
<g>
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M10 12l10 0" />
|
||||
<path d="M10 12l4 4" />
|
||||
<path d="M10 12l4 -4" />
|
||||
<path d="M4 4l0 16" />
|
||||
</g>,
|
||||
tablerIconProps,
|
||||
);
|
||||
|
||||
export const youtubeIcon = createIcon(
|
||||
<g>
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M2 8a4 4 0 0 1 4 -4h12a4 4 0 0 1 4 4v8a4 4 0 0 1 -4 4h-12a4 4 0 0 1 -4 -4v-8z" />
|
||||
<path d="M10 9l5 3l-5 3z" />
|
||||
</g>,
|
||||
tablerIconProps,
|
||||
);
|
||||
|
|
|
@ -39,6 +39,7 @@ import Trans from "../Trans";
|
|||
import DropdownMenuItemContentRadio from "../dropdownMenu/DropdownMenuItemContentRadio";
|
||||
import { THEME } from "../../constants";
|
||||
import type { Theme } from "../../element/types";
|
||||
import { trackEvent } from "../../analytics";
|
||||
|
||||
import "./DefaultItems.scss";
|
||||
|
||||
|
@ -122,7 +123,7 @@ export const SaveAsImage = () => {
|
|||
};
|
||||
SaveAsImage.displayName = "SaveAsImage";
|
||||
|
||||
export const CommandPalette = () => {
|
||||
export const CommandPalette = (opts?: { className?: string }) => {
|
||||
const setAppState = useExcalidrawSetAppState();
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@ -130,9 +131,13 @@ export const CommandPalette = () => {
|
|||
<DropdownMenuItem
|
||||
icon={boltIcon}
|
||||
data-testid="command-palette-button"
|
||||
onSelect={() => setAppState({ openDialog: { name: "commandPalette" } })}
|
||||
onSelect={() => {
|
||||
trackEvent("command_palette", "open", "menu");
|
||||
setAppState({ openDialog: { name: "commandPalette" } });
|
||||
}}
|
||||
shortcut={getShortcutFromShortcutName("commandPalette")}
|
||||
aria-label={t("commandPalette.title")}
|
||||
className={opts?.className}
|
||||
>
|
||||
{t("commandPalette.title")}
|
||||
</DropdownMenuItem>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue