From 6f18803da08f2fa4bd9e20316709a4eb7e24a183 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <72865058+daavidrgz@users.noreply.github.com> Date: Tue, 8 Oct 2024 20:56:04 +0200 Subject: [PATCH] Add Mac shortcut support (#41) Closes #40 --- crates/web/frontend/package-lock.json | 32 +++++++++---------- crates/web/frontend/package.json | 6 ++-- .../components/apply-button/apply-button.tsx | 3 +- .../src/components/editor/editor-utils.ts | 8 +++-- .../frontend/src/components/editor/editor.tsx | 4 +-- .../shortcut-popup/shortcut-popup.tsx | 3 +- .../components/shortcut-popup/shortcuts.ts | 16 +++++----- crates/web/frontend/src/lib/utils.ts | 2 ++ 8 files changed, 40 insertions(+), 34 deletions(-) diff --git a/crates/web/frontend/package-lock.json b/crates/web/frontend/package-lock.json index a87e1bc8..f7673017 100644 --- a/crates/web/frontend/package-lock.json +++ b/crates/web/frontend/package-lock.json @@ -30,8 +30,8 @@ "@radix-ui/react-toast": "^1.2.2", "@radix-ui/react-tooltip": "^1.1.3", "@types/js-beautify": "^1.14.3", - "@uiw/codemirror-themes": "^4.23.4", - "@uiw/react-codemirror": "^4.23.4", + "@uiw/codemirror-themes": "^4.23.5", + "@uiw/react-codemirror": "^4.23.5", "@wasm-tool/wasm-pack-plugin": "^1.7.0", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", @@ -46,7 +46,7 @@ "react-dom": "^18.3.1", "react-resizable-panels": "^2.1.4", "sonner": "^1.5.0", - "tailwind-merge": "^2.5.2", + "tailwind-merge": "^2.5.3", "tailwindcss-animate": "^1.0.7", "vaul": "^1.0.0", "vscode-languageserver-protocol": "^3.17.5", @@ -1984,9 +1984,9 @@ } }, "node_modules/@uiw/codemirror-extensions-basic-setup": { - "version": "4.23.4", - "resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.23.4.tgz", - "integrity": "sha512-/p6uXHDfjm3pjWNsanMs7ZMms1XJpq6DZxXUFMyUYKnLkq3t9ukGWh7lYLaAmnsgT/wojJb/RkLByeCoFy7jYw==", + "version": "4.23.5", + "resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.23.5.tgz", + "integrity": "sha512-eTMfT8TejVN/D5vvuz9Lab+MIoRYdtqa2ftZZmU3JpcDIXf9KaExPo+G2Rl9HqySzaasgGXOOG164MAnj3MSIw==", "license": "MIT", "dependencies": { "@codemirror/autocomplete": "^6.0.0", @@ -2011,9 +2011,9 @@ } }, "node_modules/@uiw/codemirror-themes": { - "version": "4.23.4", - "resolved": "https://registry.npmjs.org/@uiw/codemirror-themes/-/codemirror-themes-4.23.4.tgz", - "integrity": "sha512-rnuNUOTVq+B9ym2V7tqjGWhAr+4dyVRGYan2pIRFPRNpYTcr7XsbcGRy6DBkHK5uVK8tAiqC1Gn7vPSdC1nZXg==", + "version": "4.23.5", + "resolved": "https://registry.npmjs.org/@uiw/codemirror-themes/-/codemirror-themes-4.23.5.tgz", + "integrity": "sha512-yWUTpaVroxIxjKASQAmKaYy+ZYtF+YB6d8sVmSRK2TVD13M+EWvVT2jBGFLqR1UVg7G0W/McAy8xdeTg+a3slg==", "license": "MIT", "dependencies": { "@codemirror/language": "^6.0.0", @@ -2030,16 +2030,16 @@ } }, "node_modules/@uiw/react-codemirror": { - "version": "4.23.4", - "resolved": "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.23.4.tgz", - "integrity": "sha512-HE2MlzxCNCl0THsaoBs4rSZymhdOtN+wTZUqLfgHYjYF2hvVzhn0sVNFkmr4urLP6khshWpVg87vvTz9V8qnyg==", + "version": "4.23.5", + "resolved": "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.23.5.tgz", + "integrity": "sha512-2zzGpx61L4mq9zDG/hfsO4wAH209TBE8VVsoj/qrccRe6KfcneCwKgRxtQjxBCCnO0Q5S+IP+uwCx5bXRzgQFQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.6", "@codemirror/commands": "^6.1.0", "@codemirror/state": "^6.1.1", "@codemirror/theme-one-dark": "^6.0.0", - "@uiw/codemirror-extensions-basic-setup": "4.23.4", + "@uiw/codemirror-extensions-basic-setup": "4.23.5", "codemirror": "^6.0.0" }, "funding": { @@ -4746,9 +4746,9 @@ } }, "node_modules/tailwind-merge": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.2.tgz", - "integrity": "sha512-kjEBm+pvD+6eAwzJL2Bi+02/9LFLal1Gs61+QB7HvTfQQ0aXwC5LGT8PEt1gS0CWKktKe6ysPTAy3cBC5MeiIg==", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.3.tgz", + "integrity": "sha512-d9ZolCAIzom1nf/5p4LdD5zvjmgSxY0BGgdSvmXIoMYAiPdAW/dSpP7joCDYFY7r/HkEa2qmPtkgsu0xjQeQtw==", "license": "MIT", "funding": { "type": "github", diff --git a/crates/web/frontend/package.json b/crates/web/frontend/package.json index 7decb490..aa23b9f5 100644 --- a/crates/web/frontend/package.json +++ b/crates/web/frontend/package.json @@ -33,8 +33,8 @@ "@radix-ui/react-toast": "^1.2.2", "@radix-ui/react-tooltip": "^1.1.3", "@types/js-beautify": "^1.14.3", - "@uiw/codemirror-themes": "^4.23.4", - "@uiw/react-codemirror": "^4.23.4", + "@uiw/codemirror-themes": "^4.23.5", + "@uiw/react-codemirror": "^4.23.5", "@wasm-tool/wasm-pack-plugin": "^1.7.0", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", @@ -49,7 +49,7 @@ "react-dom": "^18.3.1", "react-resizable-panels": "^2.1.4", "sonner": "^1.5.0", - "tailwind-merge": "^2.5.2", + "tailwind-merge": "^2.5.3", "tailwindcss-animate": "^1.0.7", "vaul": "^1.0.0", "vscode-languageserver-protocol": "^3.17.5", diff --git a/crates/web/frontend/src/components/apply-button/apply-button.tsx b/crates/web/frontend/src/components/apply-button/apply-button.tsx index 3cad1743..03db217a 100644 --- a/crates/web/frontend/src/components/apply-button/apply-button.tsx +++ b/crates/web/frontend/src/components/apply-button/apply-button.tsx @@ -1,4 +1,5 @@ import ActionButton from "@/components/action-button/action-button"; +import { isMac } from "@/lib/utils"; import { CirclePlay, Play } from "lucide-react"; import { useCallback, useEffect } from "react"; @@ -10,7 +11,7 @@ interface Props { const ApplyButton = ({ autoApply, onClick }: Props) => { const handleKeyDown = useCallback( (e: KeyboardEvent) => { - if (e.ctrlKey && e.key === "Enter") { + if ((isMac ? e.metaKey : e.ctrlKey) && e.key === "Enter") { e.preventDefault(); onClick(); } diff --git a/crates/web/frontend/src/components/editor/editor-utils.ts b/crates/web/frontend/src/components/editor/editor-utils.ts index e77f5f7e..7f9e48d3 100644 --- a/crates/web/frontend/src/components/editor/editor-utils.ts +++ b/crates/web/frontend/src/components/editor/editor-utils.ts @@ -1,3 +1,4 @@ +import { isMac } from "@/lib/utils"; import type { Data } from "@/model/data"; import FileType from "@/model/file-type"; import { @@ -96,6 +97,7 @@ const gqLanguageParser = LRLanguage.define({ const jsonLanguage = json(); const gqLanguage = new LanguageSupport(gqLanguageParser); const yamlLanguage = yaml(); +const modKey = isMac ? "Cmd" : "Ctrl"; const getCodemirrorLanguageByFileType = (fileType: FileType): LanguageSupport => { switch (fileType) { @@ -129,7 +131,7 @@ export const getCodemirrorExtensionsByFileType = ( return [ language, urlPlugin, - Prec.highest(keymap.of([{ key: "Ctrl-Enter", run: () => true }])), + Prec.highest(keymap.of([{ key: `${modKey}-Enter`, run: () => true }])), getDragAndDropExtension([FileType.JSON, FileType.YAML]), ]; case FileType.GQ: @@ -144,8 +146,8 @@ export const getCodemirrorExtensionsByFileType = ( Prec.highest( keymap.of([ { key: "Tab", run: acceptCompletion }, - { key: "Ctrl-.", run: startCompletion }, - { key: "Ctrl-Enter", run: () => true }, + { key: `${modKey}-.`, run: startCompletion }, + { key: `${modKey}-Enter`, run: () => true }, ]), ), getDragAndDropExtension([FileType.GQ]), diff --git a/crates/web/frontend/src/components/editor/editor.tsx b/crates/web/frontend/src/components/editor/editor.tsx index 8bcccf11..0653dfcd 100644 --- a/crates/web/frontend/src/components/editor/editor.tsx +++ b/crates/web/frontend/src/components/editor/editor.tsx @@ -1,6 +1,6 @@ import useLazyState from "@/hooks/useLazyState"; import { gqTheme } from "@/lib/theme"; -import { cn } from "@/lib/utils"; +import { cn, isMac } from "@/lib/utils"; import { Data } from "@/model/data"; import FileType from "@/model/file-type"; import { type LoadingState, loading, notLoading } from "@/model/loading-state"; @@ -111,7 +111,7 @@ const Editor = ({ const handleKeyDown = useCallback( (event: KeyboardEvent) => { if (!focused) return; - if (event.ctrlKey && (event.key === "s" || event.key === "S")) { + if ((isMac ? event.metaKey : event.ctrlKey) && (event.key === "s" || event.key === "S")) { event.preventDefault(); handleFormatCode(content, type); } diff --git a/crates/web/frontend/src/components/shortcut-popup/shortcut-popup.tsx b/crates/web/frontend/src/components/shortcut-popup/shortcut-popup.tsx index 681ce624..49351f03 100644 --- a/crates/web/frontend/src/components/shortcut-popup/shortcut-popup.tsx +++ b/crates/web/frontend/src/components/shortcut-popup/shortcut-popup.tsx @@ -1,3 +1,4 @@ +import { isMac } from "@/lib/utils"; import { Keyboard, X } from "lucide-react"; import { useState } from "react"; import ActionButton from "../action-button/action-button"; @@ -34,7 +35,7 @@ const ShortcutPopup = () => { Check all available keyboard shortcuts to improve your efficiency - {shortcutSections.map((shortcutSection) => ( + {shortcutSections(isMac).map((shortcutSection) => (