From c52f88e34c0fc4e379607e0841e30f3eaaade2ac Mon Sep 17 00:00:00 2001 From: TKman <102001532+greekr4@users.noreply.github.com> Date: Fri, 20 Mar 2026 23:36:07 +0900 Subject: [PATCH] feat: add spacebar hold to temporarily activate Hand (pan) tool Hold Spacebar to temporarily switch to the Hand tool for panning, release to return to the previously active tool. This matches the standard Figma UX pattern. - Uses separate keydown/keyup event listeners for reliable handling - Guards against text editing mode and key repeat - References state.activeTool for correct tool state Fixes #147 --- packages/core/src/fonts.ts | 2 +- packages/core/src/kiwi/kiwi-serialize.ts | 12 +----------- src/composables/use-keyboard.ts | 22 ++++++++++++++++++++++ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/packages/core/src/fonts.ts b/packages/core/src/fonts.ts index 34ac729a7..5c8eaba1a 100644 --- a/packages/core/src/fonts.ts +++ b/packages/core/src/fonts.ts @@ -301,7 +301,7 @@ export function collectFontKeys(graph: SceneGraph, nodeIds: string[]): Array<[st return [...fontKeys].map((k) => k.split('\0') as [string, string]) } -let cjkFallbackFamilies: string[] = [] +const cjkFallbackFamilies: string[] = [] let cjkFallbackPromise: Promise | null = null function getCJKCandidates(): string[] { diff --git a/packages/core/src/kiwi/kiwi-serialize.ts b/packages/core/src/kiwi/kiwi-serialize.ts index f3dafdfa6..5d452aec6 100644 --- a/packages/core/src/kiwi/kiwi-serialize.ts +++ b/packages/core/src/kiwi/kiwi-serialize.ts @@ -2,23 +2,13 @@ export const FIG_KIWI_VERSION = 106 import { deflateSync, inflateSync } from 'fflate' -<<<<<<< HEAD:packages/core/src/kiwi/kiwi-serialize.ts import { getLoadedFontData, normalizeFontFamily, weightToStyle } from '../fonts' import { encodeVectorNetworkBlob } from '../vector' import { stringToGuid, VARIABLE_BINDING_FIELDS } from './kiwi-convert' import type { SceneGraph, SceneNode, CharacterStyleOverride } from '../scene-graph' -import type { Color, GUID } from '../types' +import type { Color, GUID, Matrix } from '../types' import type { NodeChange, Paint, VariableConsumptionEntry } from './codec' -======= -import { weightToStyle, getLoadedFontData, normalizeFontFamily } from './fonts' -import { encodeVectorNetworkBlob } from './vector' -import { stringToGuid, VARIABLE_BINDING_FIELDS } from './kiwi/kiwi-convert' - -import type { NodeChange, Paint, VariableConsumptionEntry } from './kiwi/codec' -import type { SceneGraph, SceneNode, CharacterStyleOverride } from './scene-graph' -import type { Color, GUID, Matrix } from './types' ->>>>>>> 4df3671 (fix: kiwi serialization bugs causing broken auto-layout in Figma import):packages/core/src/kiwi-serialize.ts const fontDigestCache = new Map() diff --git a/src/composables/use-keyboard.ts b/src/composables/use-keyboard.ts index 81a256c5a..247018abd 100644 --- a/src/composables/use-keyboard.ts +++ b/src/composables/use-keyboard.ts @@ -94,6 +94,28 @@ export function useKeyboard() { if (html) store.pasteFromHTML(html, cursorPos) }) + // Spacebar hold → temporary Hand tool (Figma-style canvas pan) + let toolBeforeSpace: (typeof store.state.activeTool) | null = null + + useEventListener(window, 'keydown', (e: KeyboardEvent) => { + if (isEditing(e)) return + if (e.code === 'Space' && !e.metaKey && !e.ctrlKey && !e.altKey && !e.repeat) { + if (store.state.activeTool !== 'HAND') { + toolBeforeSpace = store.state.activeTool + store.setTool('HAND') + } + e.preventDefault() + } + }) + + useEventListener(window, 'keyup', (e: KeyboardEvent) => { + if (e.code === 'Space' && toolBeforeSpace) { + store.setTool(toolBeforeSpace) + toolBeforeSpace = null + e.preventDefault() + } + }) + const keys = useMagicKeys({ passive: false, onEventFired(e) {