From 522086620911d92e747fbfe40a24736aecf9b3ab Mon Sep 17 00:00:00 2001 From: do4mother Date: Thu, 16 Oct 2025 12:25:53 +0700 Subject: [PATCH 1/7] feat: add disable hotkeys feature --- packages/core/components/Puck/index.tsx | 5 +++-- packages/core/lib/use-hotkey.ts | 8 +++++++- packages/core/store/default-app-state.ts | 1 + packages/core/types/AppState.tsx | 1 + 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/core/components/Puck/index.tsx b/packages/core/components/Puck/index.tsx index b036047525..5cf7d41006 100644 --- a/packages/core/components/Puck/index.tsx +++ b/packages/core/components/Puck/index.tsx @@ -431,6 +431,7 @@ function PuckLayout< const rightSideBarVisible = useAppStore( (s) => s.state.ui.rightSideBarVisible ); + const disableHotKeys = useAppStore((s) => s.state.ui.disableHotKeys); const { width: leftWidth, @@ -498,11 +499,11 @@ function PuckLayout< if (ready && iframe.enabled) { const frameDoc = getFrame(); - if (frameDoc) { + if (frameDoc && !disableHotKeys) { return monitorHotkeys(frameDoc); } } - }, [ready, iframe.enabled]); + }, [ready, iframe.enabled, disableHotKeys]); usePreviewModeHotkeys(); diff --git a/packages/core/lib/use-hotkey.ts b/packages/core/lib/use-hotkey.ts index 17bbbde522..613aedb457 100644 --- a/packages/core/lib/use-hotkey.ts +++ b/packages/core/lib/use-hotkey.ts @@ -1,6 +1,7 @@ import { useEffect } from "react"; import { create } from "zustand"; import { subscribeWithSelector } from "zustand/middleware"; +import { useAppStore } from '../store'; const keys = [ "ctrl", @@ -168,7 +169,12 @@ export const monitorHotkeys = (doc: Document) => { }; export const useMonitorHotkeys = () => { - useEffect(() => monitorHotkeys(document), []); + const disableHotKeys = useAppStore((s) => s.state.ui.disableHotKeys) + + useEffect(() => { + if (disableHotKeys) return; + return monitorHotkeys(document); + }, [disableHotKeys]); }; export const useHotkey = (combo: KeyMapStrict, cb: Function) => { diff --git a/packages/core/store/default-app-state.ts b/packages/core/store/default-app-state.ts index 3a4e00e8c2..c23f2f7865 100644 --- a/packages/core/store/default-app-state.ts +++ b/packages/core/store/default-app-state.ts @@ -4,6 +4,7 @@ import { PrivateAppState } from "../types/Internal"; export const defaultAppState: PrivateAppState = { data: { content: [], root: {}, zones: {} }, ui: { + disableHotKeys: false, leftSideBarVisible: true, rightSideBarVisible: true, arrayState: {}, diff --git a/packages/core/types/AppState.tsx b/packages/core/types/AppState.tsx index a0e2ec506b..a78bbf1f55 100644 --- a/packages/core/types/AppState.tsx +++ b/packages/core/types/AppState.tsx @@ -10,6 +10,7 @@ export type ItemWithId = { export type ArrayState = { items: ItemWithId[]; openId: string }; export type UiState = { + disableHotKeys?: boolean; leftSideBarVisible: boolean; rightSideBarVisible: boolean; leftSideBarWidth?: number | null; From 07cadab825afb853277ce1adf452104c7aa11539 Mon Sep 17 00:00:00 2001 From: do4mother Date: Fri, 17 Oct 2025 08:53:09 +0700 Subject: [PATCH 2/7] feat: integrate hotkey state into app state --- packages/core/components/Puck/index.tsx | 11 +++++++---- packages/core/lib/use-hotkey.ts | 8 +++++--- packages/core/store/default-app-state.ts | 2 +- packages/core/types/AppState.tsx | 6 +++++- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/packages/core/components/Puck/index.tsx b/packages/core/components/Puck/index.tsx index 5cf7d41006..cfa4cbae15 100644 --- a/packages/core/components/Puck/index.tsx +++ b/packages/core/components/Puck/index.tsx @@ -27,7 +27,7 @@ import type { Metadata, AsFieldProps, DefaultComponentProps, - ComponentData, + HotkeyState, } from "../../types"; import { SidebarSection } from "../SidebarSection"; @@ -124,6 +124,7 @@ type PuckProps< }; initialHistory?: InitialHistory; metadata?: Metadata; + hotkeys?: HotkeyState }; const propsContext = createContext>({}); @@ -159,6 +160,7 @@ function PuckProvider< metadata, onAction, fieldTransforms, + hotkeys, } = usePropsContext(); const iframe: IframeConfig = useMemo( @@ -242,6 +244,7 @@ function PuckProvider< const newAppState = { ...defaultAppState, + hotkeys, data: { ...initialData, root: { ...initialData?.root, props: root.props }, @@ -431,7 +434,7 @@ function PuckLayout< const rightSideBarVisible = useAppStore( (s) => s.state.ui.rightSideBarVisible ); - const disableHotKeys = useAppStore((s) => s.state.ui.disableHotKeys); + const enabledHotkeys = useAppStore((s) => s.state.hotkeys.enabled); const { width: leftWidth, @@ -499,11 +502,11 @@ function PuckLayout< if (ready && iframe.enabled) { const frameDoc = getFrame(); - if (frameDoc && !disableHotKeys) { + if (frameDoc && enabledHotkeys) { return monitorHotkeys(frameDoc); } } - }, [ready, iframe.enabled, disableHotKeys]); + }, [ready, iframe.enabled, enabledHotkeys]); usePreviewModeHotkeys(); diff --git a/packages/core/lib/use-hotkey.ts b/packages/core/lib/use-hotkey.ts index 613aedb457..52ab348c56 100644 --- a/packages/core/lib/use-hotkey.ts +++ b/packages/core/lib/use-hotkey.ts @@ -98,6 +98,8 @@ const useHotkeyStore = create<{ ); export const monitorHotkeys = (doc: Document) => { + console.log("monitorHotkeys"); + const onKeyDown = (e: KeyboardEvent) => { const key = keyCodeMap[e.code]; @@ -169,12 +171,12 @@ export const monitorHotkeys = (doc: Document) => { }; export const useMonitorHotkeys = () => { - const disableHotKeys = useAppStore((s) => s.state.ui.disableHotKeys) + const enabledHotkeys = useAppStore((s) => s.state.hotkeys.enabled) useEffect(() => { - if (disableHotKeys) return; + if (!enabledHotkeys) return; return monitorHotkeys(document); - }, [disableHotKeys]); + }, [enabledHotkeys]); }; export const useHotkey = (combo: KeyMapStrict, cb: Function) => { diff --git a/packages/core/store/default-app-state.ts b/packages/core/store/default-app-state.ts index c23f2f7865..1de451bc5e 100644 --- a/packages/core/store/default-app-state.ts +++ b/packages/core/store/default-app-state.ts @@ -2,9 +2,9 @@ import { defaultViewports } from "../components/ViewportControls/default-viewpor import { PrivateAppState } from "../types/Internal"; export const defaultAppState: PrivateAppState = { + hotkeys: { enabled: true }, data: { content: [], root: {}, zones: {} }, ui: { - disableHotKeys: false, leftSideBarVisible: true, rightSideBarVisible: true, arrayState: {}, diff --git a/packages/core/types/AppState.tsx b/packages/core/types/AppState.tsx index a78bbf1f55..2d50691ff0 100644 --- a/packages/core/types/AppState.tsx +++ b/packages/core/types/AppState.tsx @@ -9,8 +9,11 @@ export type ItemWithId = { export type ArrayState = { items: ItemWithId[]; openId: string }; +export type HotkeyState = { + enabled: boolean; +} + export type UiState = { - disableHotKeys?: boolean; leftSideBarVisible: boolean; rightSideBarVisible: boolean; leftSideBarWidth?: number | null; @@ -40,6 +43,7 @@ export type UiState = { }; export type AppState = { + hotkeys: HotkeyState; data: UserData; ui: UiState; }; From a18c0302c20d94f5c95d05b0fa4dea80c55443fb Mon Sep 17 00:00:00 2001 From: do4mother Date: Fri, 17 Oct 2025 09:00:57 +0700 Subject: [PATCH 3/7] fix: remove debug log from monitorHotkeys function --- packages/core/lib/use-hotkey.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/core/lib/use-hotkey.ts b/packages/core/lib/use-hotkey.ts index 52ab348c56..389e0cd3e7 100644 --- a/packages/core/lib/use-hotkey.ts +++ b/packages/core/lib/use-hotkey.ts @@ -98,8 +98,6 @@ const useHotkeyStore = create<{ ); export const monitorHotkeys = (doc: Document) => { - console.log("monitorHotkeys"); - const onKeyDown = (e: KeyboardEvent) => { const key = keyCodeMap[e.code]; From d83ca0b70fc52d8d44ae4196e5ecdfde6ac117a0 Mon Sep 17 00:00:00 2001 From: do4mother Date: Thu, 13 Nov 2025 09:51:07 +0700 Subject: [PATCH 4/7] refactor: hotkey state to AppStore --- packages/core/components/Puck/index.tsx | 7 ++++--- packages/core/lib/use-hotkey.ts | 4 ++-- packages/core/store/default-app-state.ts | 1 - packages/core/store/index.ts | 3 +++ packages/core/types/AppState.tsx | 1 - 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/core/components/Puck/index.tsx b/packages/core/components/Puck/index.tsx index cfa4cbae15..2d8a1d41c9 100644 --- a/packages/core/components/Puck/index.tsx +++ b/packages/core/components/Puck/index.tsx @@ -160,7 +160,7 @@ function PuckProvider< metadata, onAction, fieldTransforms, - hotkeys, + hotkeys = { enabled: true }, } = usePropsContext(); const iframe: IframeConfig = useMemo( @@ -244,7 +244,6 @@ function PuckProvider< const newAppState = { ...defaultAppState, - hotkeys, data: { ...initialData, root: { ...initialData?.root, props: root.props }, @@ -333,6 +332,7 @@ function PuckProvider< onAction, metadata, fieldTransforms: loadedFieldTransforms, + hotkeys: hotkeys, }; }, [ @@ -345,6 +345,7 @@ function PuckProvider< onAction, metadata, loadedFieldTransforms, + hotkeys ] ); @@ -434,7 +435,7 @@ function PuckLayout< const rightSideBarVisible = useAppStore( (s) => s.state.ui.rightSideBarVisible ); - const enabledHotkeys = useAppStore((s) => s.state.hotkeys.enabled); + const enabledHotkeys = useAppStore((s) => s.hotkeys.enabled); const { width: leftWidth, diff --git a/packages/core/lib/use-hotkey.ts b/packages/core/lib/use-hotkey.ts index 389e0cd3e7..1035cb67db 100644 --- a/packages/core/lib/use-hotkey.ts +++ b/packages/core/lib/use-hotkey.ts @@ -1,7 +1,7 @@ import { useEffect } from "react"; import { create } from "zustand"; import { subscribeWithSelector } from "zustand/middleware"; -import { useAppStore } from '../store'; +import { useAppStore } from "../store"; const keys = [ "ctrl", @@ -169,7 +169,7 @@ export const monitorHotkeys = (doc: Document) => { }; export const useMonitorHotkeys = () => { - const enabledHotkeys = useAppStore((s) => s.state.hotkeys.enabled) + const enabledHotkeys = useAppStore((s) => s.hotkeys.enabled); useEffect(() => { if (!enabledHotkeys) return; diff --git a/packages/core/store/default-app-state.ts b/packages/core/store/default-app-state.ts index 1de451bc5e..3a4e00e8c2 100644 --- a/packages/core/store/default-app-state.ts +++ b/packages/core/store/default-app-state.ts @@ -2,7 +2,6 @@ import { defaultViewports } from "../components/ViewportControls/default-viewpor import { PrivateAppState } from "../types/Internal"; export const defaultAppState: PrivateAppState = { - hotkeys: { enabled: true }, data: { content: [], root: {}, zones: {} }, ui: { leftSideBarVisible: true, diff --git a/packages/core/store/index.ts b/packages/core/store/index.ts index e0844fc051..c90ac64362 100644 --- a/packages/core/store/index.ts +++ b/packages/core/store/index.ts @@ -14,6 +14,7 @@ import { ComponentData, RootDataWithProps, ResolveDataTrigger, + HotkeyState, } from "../types"; import { createReducer, PuckAction } from "../reducer"; import { getItem } from "../lib/data/get-item"; @@ -87,6 +88,7 @@ export type AppStore< nodes: NodesSlice; permissions: PermissionsSlice; fieldTransforms: FieldTransforms; + hotkeys: HotkeyState; }; export type AppStoreApi = StoreApi; @@ -113,6 +115,7 @@ export const createAppStore = (initialAppStore?: Partial) => iframe: {}, metadata: {}, fieldTransforms: {}, + hotkeys: { enabled: true }, ...initialAppStore, fields: createFieldsSlice(set, get), history: createHistorySlice(set, get), diff --git a/packages/core/types/AppState.tsx b/packages/core/types/AppState.tsx index 2d50691ff0..bebbf0523b 100644 --- a/packages/core/types/AppState.tsx +++ b/packages/core/types/AppState.tsx @@ -43,7 +43,6 @@ export type UiState = { }; export type AppState = { - hotkeys: HotkeyState; data: UserData; ui: UiState; }; From e025ac8c219477191ded03c6c1c729b8611aacd4 Mon Sep 17 00:00:00 2001 From: do4mother Date: Thu, 20 Nov 2025 08:42:15 +0700 Subject: [PATCH 5/7] fix: change hotkeys type to Partial --- packages/core/components/Puck/index.tsx | 2 +- packages/core/store/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/components/Puck/index.tsx b/packages/core/components/Puck/index.tsx index 2d8a1d41c9..e8b2f2ba80 100644 --- a/packages/core/components/Puck/index.tsx +++ b/packages/core/components/Puck/index.tsx @@ -124,7 +124,7 @@ type PuckProps< }; initialHistory?: InitialHistory; metadata?: Metadata; - hotkeys?: HotkeyState + hotkeys?: Partial }; const propsContext = createContext>({}); diff --git a/packages/core/store/index.ts b/packages/core/store/index.ts index c90ac64362..42f6e8fbe8 100644 --- a/packages/core/store/index.ts +++ b/packages/core/store/index.ts @@ -88,7 +88,7 @@ export type AppStore< nodes: NodesSlice; permissions: PermissionsSlice; fieldTransforms: FieldTransforms; - hotkeys: HotkeyState; + hotkeys: Partial; }; export type AppStoreApi = StoreApi; From ef7b741e291b6eaf98dfd9a0fad58a20a5862a6e Mon Sep 17 00:00:00 2001 From: do4mother Date: Thu, 20 Nov 2025 08:45:42 +0700 Subject: [PATCH 6/7] fix: simplify hotkeys prop handling --- packages/core/components/Puck/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/components/Puck/index.tsx b/packages/core/components/Puck/index.tsx index e8b2f2ba80..deab8f17ef 100644 --- a/packages/core/components/Puck/index.tsx +++ b/packages/core/components/Puck/index.tsx @@ -332,7 +332,7 @@ function PuckProvider< onAction, metadata, fieldTransforms: loadedFieldTransforms, - hotkeys: hotkeys, + hotkeys, }; }, [ From 93206925f8cc6f594dd9dd8c7f1def865dd821b3 Mon Sep 17 00:00:00 2001 From: do4mother Date: Thu, 20 Nov 2025 08:46:37 +0700 Subject: [PATCH 7/7] fix: prevent re-render generateAppStore from hotkeys object --- packages/core/components/Puck/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/components/Puck/index.tsx b/packages/core/components/Puck/index.tsx index deab8f17ef..4008a6d159 100644 --- a/packages/core/components/Puck/index.tsx +++ b/packages/core/components/Puck/index.tsx @@ -345,7 +345,7 @@ function PuckProvider< onAction, metadata, loadedFieldTransforms, - hotkeys + hotkeys.enabled ] );