From 8dfde7b94eab163b07f3b14c2b2fe8149f04d1c9 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Sun, 3 Mar 2024 15:41:19 +0100 Subject: [PATCH 1/3] Fixed toolbar button click behaviour for Safari --- .../FormattingToolbarPlugin.ts | 5 +++ .../mantine-shared/Toolbar/ToolbarButton.tsx | 41 ++++++++++++++++--- .../Toolbar/ToolbarDropdownTarget.tsx | 21 +++++++++- 3 files changed, 60 insertions(+), 7 deletions(-) diff --git a/packages/core/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts b/packages/core/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts index 5a04c3a39d..8a9741a9ee 100644 --- a/packages/core/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +++ b/packages/core/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts @@ -39,6 +39,7 @@ export class FormattingToolbarView { "Attempting to update uninitialized formatting toolbar" ); } + console.log(this.state); emitUpdate(this.state); }; @@ -95,8 +96,12 @@ export class FormattingToolbarView { (editorWrapper === (event.relatedTarget as Node) || editorWrapper.contains(event.relatedTarget as Node)) ) { + console.log(event); + console.log(this.state); return; } + console.log(event); + console.log(this.state); if (this.state?.show) { this.state.show = false; diff --git a/packages/react/src/components/mantine-shared/Toolbar/ToolbarButton.tsx b/packages/react/src/components/mantine-shared/Toolbar/ToolbarButton.tsx index eb427dd0ff..d0864a246a 100644 --- a/packages/react/src/components/mantine-shared/Toolbar/ToolbarButton.tsx +++ b/packages/react/src/components/mantine-shared/Toolbar/ToolbarButton.tsx @@ -1,5 +1,5 @@ import { ActionIcon, Button, Tooltip } from "@mantine/core"; -import { ForwardedRef, MouseEvent, forwardRef } from "react"; +import { MouseEvent, forwardRef, useRef } from "react"; import type { IconType } from "react-icons"; import { TooltipContent } from "../Tooltip/TooltipContent"; @@ -17,8 +17,9 @@ export type ToolbarButtonProps = { /** * Helper for basic buttons that show in the formatting toolbar. */ -export const ToolbarButton = forwardRef( - (props: ToolbarButtonProps, ref: ForwardedRef) => { +export const ToolbarButton = forwardRef( + (props, ref) => { + const buttonRef = useRef(null); const ButtonIcon = props.icon; return ( @@ -33,6 +34,13 @@ export const ToolbarButton = forwardRef( {/*Creates an ActionIcon instead of a Button if only an icon is provided as content.*/} {props.children ? ( ) : ( { + if (buttonRef.current !== null) { + buttonRef.current.focus(); + } + }} onClick={props.onClick} data-selected={props.isSelected ? "true" : undefined} data-test={ @@ -55,7 +78,15 @@ export const ToolbarButton = forwardRef( } size={30} disabled={props.isDisabled || false} - ref={ref}> + // TODO: Ugly code for combining refs + ref={(node) => { + buttonRef.current = node; + if (typeof ref === "function") { + ref(node); + } else if (ref) { + ref.current = node; + } + }}> {ButtonIcon && } )} diff --git a/packages/react/src/components/mantine-shared/Toolbar/ToolbarDropdownTarget.tsx b/packages/react/src/components/mantine-shared/Toolbar/ToolbarDropdownTarget.tsx index 39cf54a779..5a0dbfad45 100644 --- a/packages/react/src/components/mantine-shared/Toolbar/ToolbarDropdownTarget.tsx +++ b/packages/react/src/components/mantine-shared/Toolbar/ToolbarDropdownTarget.tsx @@ -1,5 +1,5 @@ import { Button } from "@mantine/core"; -import { MouseEventHandler, forwardRef } from "react"; +import { MouseEventHandler, forwardRef, useRef } from "react"; import type { IconType } from "react-icons"; import { HiChevronDown } from "react-icons/hi"; @@ -14,16 +14,33 @@ export const ToolbarDropdownTarget = forwardRef< HTMLButtonElement, ToolbarDropdownTargetProps >((props: ToolbarDropdownTargetProps, ref) => { + const buttonRef = useRef(null); const TargetIcon = props.icon; + return ( ); From c9f9cb2958cb9944dad9da77c54e8f0d6ff88ab5 Mon Sep 17 00:00:00 2001 From: yousefed Date: Mon, 4 Mar 2024 14:04:06 +0100 Subject: [PATCH 2/3] fix --- .../FormattingToolbarPlugin.ts | 7 +--- .../mantine-shared/Toolbar/ToolbarButton.tsx | 35 ++++--------------- .../Toolbar/ToolbarDropdownTarget.tsx | 19 +++------- 3 files changed, 12 insertions(+), 49 deletions(-) diff --git a/packages/core/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts b/packages/core/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts index 8a9741a9ee..a60f1cb398 100644 --- a/packages/core/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +++ b/packages/core/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts @@ -3,8 +3,8 @@ import { EditorState, Plugin, PluginKey } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; import type { BlockNoteEditor } from "../../editor/BlockNoteEditor"; -import { BlockSchema, InlineContentSchema, StyleSchema } from "../../schema"; import { UiElementPosition } from "../../extensions-shared/UiElementPosition"; +import { BlockSchema, InlineContentSchema, StyleSchema } from "../../schema"; import { EventEmitter } from "../../util/EventEmitter"; export type FormattingToolbarState = UiElementPosition; @@ -39,7 +39,6 @@ export class FormattingToolbarView { "Attempting to update uninitialized formatting toolbar" ); } - console.log(this.state); emitUpdate(this.state); }; @@ -96,12 +95,8 @@ export class FormattingToolbarView { (editorWrapper === (event.relatedTarget as Node) || editorWrapper.contains(event.relatedTarget as Node)) ) { - console.log(event); - console.log(this.state); return; } - console.log(event); - console.log(this.state); if (this.state?.show) { this.state.show = false; diff --git a/packages/react/src/components/mantine-shared/Toolbar/ToolbarButton.tsx b/packages/react/src/components/mantine-shared/Toolbar/ToolbarButton.tsx index d0864a246a..17b11292be 100644 --- a/packages/react/src/components/mantine-shared/Toolbar/ToolbarButton.tsx +++ b/packages/react/src/components/mantine-shared/Toolbar/ToolbarButton.tsx @@ -1,5 +1,5 @@ import { ActionIcon, Button, Tooltip } from "@mantine/core"; -import { MouseEvent, forwardRef, useRef } from "react"; +import { MouseEvent, forwardRef } from "react"; import type { IconType } from "react-icons"; import { TooltipContent } from "../Tooltip/TooltipContent"; @@ -19,7 +19,6 @@ export type ToolbarButtonProps = { */ export const ToolbarButton = forwardRef( (props, ref) => { - const buttonRef = useRef(null); const ButtonIcon = props.icon; return ( @@ -36,10 +35,8 @@ export const ToolbarButton = forwardRef( @@ -65,10 +54,8 @@ export const ToolbarButton = forwardRef( { - if (buttonRef.current !== null) { - buttonRef.current.focus(); - } + onMouseDown={(e) => { + (e.currentTarget as HTMLButtonElement).focus(); }} onClick={props.onClick} data-selected={props.isSelected ? "true" : undefined} @@ -78,15 +65,7 @@ export const ToolbarButton = forwardRef( } size={30} disabled={props.isDisabled || false} - // TODO: Ugly code for combining refs - ref={(node) => { - buttonRef.current = node; - if (typeof ref === "function") { - ref(node); - } else if (ref) { - ref.current = node; - } - }}> + ref={ref}> {ButtonIcon && } )} diff --git a/packages/react/src/components/mantine-shared/Toolbar/ToolbarDropdownTarget.tsx b/packages/react/src/components/mantine-shared/Toolbar/ToolbarDropdownTarget.tsx index 5a0dbfad45..0e6ca3dd2f 100644 --- a/packages/react/src/components/mantine-shared/Toolbar/ToolbarDropdownTarget.tsx +++ b/packages/react/src/components/mantine-shared/Toolbar/ToolbarDropdownTarget.tsx @@ -1,5 +1,5 @@ import { Button } from "@mantine/core"; -import { MouseEventHandler, forwardRef, useRef } from "react"; +import { MouseEventHandler, forwardRef } from "react"; import type { IconType } from "react-icons"; import { HiChevronDown } from "react-icons/hi"; @@ -14,17 +14,14 @@ export const ToolbarDropdownTarget = forwardRef< HTMLButtonElement, ToolbarDropdownTargetProps >((props: ToolbarDropdownTargetProps, ref) => { - const buttonRef = useRef(null); const TargetIcon = props.icon; return ( ); From e0fedc2ec3db0842eaae474b48454e37c2ab946a Mon Sep 17 00:00:00 2001 From: yousefed Date: Mon, 4 Mar 2024 14:28:24 +0100 Subject: [PATCH 3/3] only apply fix to safari --- packages/core/src/util/browser.ts | 10 ++++++---- .../mantine-shared/Toolbar/ToolbarButton.tsx | 9 +++++++-- .../mantine-shared/Toolbar/ToolbarDropdownTarget.tsx | 5 ++++- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/packages/core/src/util/browser.ts b/packages/core/src/util/browser.ts index d32090c334..e5fcf8ac71 100644 --- a/packages/core/src/util/browser.ts +++ b/packages/core/src/util/browser.ts @@ -1,8 +1,8 @@ export const isAppleOS = () => - typeof navigator !== "undefined" && - (/Mac/.test(navigator.platform) || - (/AppleWebKit/.test(navigator.userAgent) && - /Mobile\/\w+/.test(navigator.userAgent))); + typeof navigator !== "undefined" && + (/Mac/.test(navigator.platform) || + (/AppleWebKit/.test(navigator.userAgent) && + /Mobile\/\w+/.test(navigator.userAgent))); export function formatKeyboardShortcut(shortcut: string) { if (isAppleOS()) { @@ -16,3 +16,5 @@ export function mergeCSSClasses(...classes: string[]) { return classes.filter((c) => c).join(" "); } +export const isSafari = () => + /^((?!chrome|android).)*safari/i.test(navigator.userAgent); diff --git a/packages/react/src/components/mantine-shared/Toolbar/ToolbarButton.tsx b/packages/react/src/components/mantine-shared/Toolbar/ToolbarButton.tsx index 17b11292be..81feed73fa 100644 --- a/packages/react/src/components/mantine-shared/Toolbar/ToolbarButton.tsx +++ b/packages/react/src/components/mantine-shared/Toolbar/ToolbarButton.tsx @@ -2,6 +2,7 @@ import { ActionIcon, Button, Tooltip } from "@mantine/core"; import { MouseEvent, forwardRef } from "react"; import type { IconType } from "react-icons"; +import { isSafari } from "@blocknote/core"; import { TooltipContent } from "../Tooltip/TooltipContent"; export type ToolbarButtonProps = { @@ -36,7 +37,9 @@ export const ToolbarButton = forwardRef( // Needed as Safari doesn't focus button elements on mouse down // unlike other browsers. onMouseDown={(e) => { - (e.currentTarget as HTMLButtonElement).focus(); + if (isSafari()) { + (e.currentTarget as HTMLButtonElement).focus(); + } }} onClick={props.onClick} data-selected={props.isSelected ? "true" : undefined} @@ -55,7 +58,9 @@ export const ToolbarButton = forwardRef( // Needed as Safari doesn't focus button elements on mouse down // unlike other browsers. onMouseDown={(e) => { - (e.currentTarget as HTMLButtonElement).focus(); + if (isSafari()) { + (e.currentTarget as HTMLButtonElement).focus(); + } }} onClick={props.onClick} data-selected={props.isSelected ? "true" : undefined} diff --git a/packages/react/src/components/mantine-shared/Toolbar/ToolbarDropdownTarget.tsx b/packages/react/src/components/mantine-shared/Toolbar/ToolbarDropdownTarget.tsx index 0e6ca3dd2f..cd8a25b9b8 100644 --- a/packages/react/src/components/mantine-shared/Toolbar/ToolbarDropdownTarget.tsx +++ b/packages/react/src/components/mantine-shared/Toolbar/ToolbarDropdownTarget.tsx @@ -1,3 +1,4 @@ +import { isSafari } from "@blocknote/core"; import { Button } from "@mantine/core"; import { MouseEventHandler, forwardRef } from "react"; import type { IconType } from "react-icons"; @@ -21,7 +22,9 @@ export const ToolbarDropdownTarget = forwardRef< // Needed as Safari doesn't focus button elements on mouse down // unlike other browsers. onMouseDown={(e) => { - (e.currentTarget as HTMLButtonElement).focus(); + if (isSafari()) { + (e.currentTarget as HTMLButtonElement).focus(); + } }} leftSection={TargetIcon && } rightSection={}