From 65d77b63c6c3a9129c2155dbfe1643f949492578 Mon Sep 17 00:00:00 2001 From: Jorgelig Date: Tue, 17 Jan 2023 10:01:12 -0600 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20(editor)=20Add=20Ctrl=20+=20z=20sho?= =?UTF-8?q?rtcut=20to=20undo=20changes=20in=20editor=20(#255)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #217 --- .../TypebotHeader/TypebotHeader.tsx | 23 +++++++++++++++++-- apps/builder/src/hooks/useUndoShortcut.ts | 18 +++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 apps/builder/src/hooks/useUndoShortcut.ts diff --git a/apps/builder/src/features/editor/components/TypebotHeader/TypebotHeader.tsx b/apps/builder/src/features/editor/components/TypebotHeader/TypebotHeader.tsx index 20b9b0f68ac..f2749e6e14c 100644 --- a/apps/builder/src/features/editor/components/TypebotHeader/TypebotHeader.tsx +++ b/apps/builder/src/features/editor/components/TypebotHeader/TypebotHeader.tsx @@ -17,7 +17,7 @@ import { import { RightPanel, useEditor } from '../../providers/EditorProvider' import { useTypebot } from '../../providers/TypebotProvider' import { useRouter } from 'next/router' -import React from 'react' +import React, { useState } from 'react' import { isNotDefined } from 'utils' import { EditableTypebotName } from './EditableTypebotName' import { getBubbleActions } from 'typebot-js' @@ -27,6 +27,8 @@ import { headerHeight } from '../../constants' import { EditableEmojiOrImageIcon } from '@/components/EditableEmojiOrImageIcon' import { PublishButton } from '@/features/publish' import { CollaborationMenuButton } from '@/features/collaboration' +import { useUndoShortcut } from '@/hooks/useUndoShortcut' +import { useDebouncedCallback } from 'use-debounce' export const TypebotHeader = () => { const router = useRouter() @@ -41,6 +43,11 @@ export const TypebotHeader = () => { isSavingLoading, } = useTypebot() const { setRightPanel, rightPanel, setStartPreviewAtGroup } = useEditor() + const [isUndoShortcutTooltipOpen, setUndoShortcutTooltipOpen] = + useState(false) + const hideUndoShortcutTooltipLater = useDebouncedCallback(() => { + setUndoShortcutTooltipOpen(false) + }, 1000) const handleNameSubmit = (name: string) => updateTypebot({ name }) @@ -52,6 +59,14 @@ export const TypebotHeader = () => { setRightPanel(RightPanel.PREVIEW) } + useUndoShortcut(() => { + if (!canUndo) return + hideUndoShortcutTooltipLater.flush() + setUndoShortcutTooltipOpen(true) + hideUndoShortcutTooltipLater() + undo() + }) + const handleHelpClick = () => { isCloudProdInstance ? getBubbleActions().open() @@ -162,7 +177,11 @@ export const TypebotHeader = () => { - + } diff --git a/apps/builder/src/hooks/useUndoShortcut.ts b/apps/builder/src/hooks/useUndoShortcut.ts new file mode 100644 index 00000000000..5ef3c21a9bd --- /dev/null +++ b/apps/builder/src/hooks/useUndoShortcut.ts @@ -0,0 +1,18 @@ +import { useEventListener } from '@chakra-ui/react' + +export const useUndoShortcut = (undo: () => void) => { + const isUndoShortcut = (event: KeyboardEvent) => + (event.metaKey || event.ctrlKey) && event.key === 'z' + + useEventListener('keydown', (event: KeyboardEvent) => { + const target = event.target as HTMLElement | null + const isTyping = + target?.role === 'textbox' || + target instanceof HTMLTextAreaElement || + target instanceof HTMLInputElement + if (isTyping) return + if (isUndoShortcut(event)) { + undo() + } + }) +}