diff --git a/packages/core/components/DropZone/index.tsx b/packages/core/components/DropZone/index.tsx index 67473160b7..319bebc117 100644 --- a/packages/core/components/DropZone/index.tsx +++ b/packages/core/components/DropZone/index.tsx @@ -125,7 +125,11 @@ function DropZoneEdit({ zone, allow, disallow, style }: DropZoneProps) { */ if (userIsDragging) { if (draggingNewComponent) { - isEnabled = hoveringOverArea; + if (appContext.safariFallbackMode) { + isEnabled = true; + } else { + isEnabled = hoveringOverArea; + } } else { isEnabled = draggingOverArea && hoveringOverZone; } diff --git a/packages/core/components/Puck/context.tsx b/packages/core/components/Puck/context.tsx index ace11fc26d..5a4cdeaf17 100644 --- a/packages/core/components/Puck/context.tsx +++ b/packages/core/components/Puck/context.tsx @@ -14,6 +14,7 @@ import { PuckHistory } from "../../lib/use-puck-history"; import { defaultViewports } from "../ViewportControls/default-viewports"; import { Viewports } from "../../types/Viewports"; import { IframeConfig } from "../../types/IframeConfig"; +import { UAParser } from "ua-parser-js"; export const defaultAppState: AppState = { data: { content: [], root: { props: { title: "" } } }, @@ -58,6 +59,7 @@ type AppContext = { status: Status; setStatus: (status: Status) => void; iframe: IframeConfig; + safariFallbackMode?: boolean; }; const defaultContext: AppContext = { @@ -79,6 +81,7 @@ const defaultContext: AppContext = { status: "LOADING", setStatus: () => null, iframe: {}, + safariFallbackMode: false, }; export const appContext = createContext(defaultContext); @@ -103,9 +106,39 @@ export const AppProvider = ({ setStatus("MOUNTED"); }, []); + const [safariFallbackMode, setSafariFallbackMode] = useState(false); + + useEffect(() => { + const ua = new UAParser(navigator.userAgent); + + const { browser } = ua.getResult(); + + if ( + browser.name === "Safari" && + (browser.version?.indexOf("17.2.") || + browser.version?.indexOf("17.3.") || + browser.version?.indexOf("17.4.")) + ) { + if (process.env.NODE_ENV !== "production" && value.iframe.enabled) { + console.warn( + `Detected Safari ${browser.version}, which contains a bug that prevents Puck DropZones from detecting a mouseover event within an iframe. This affects Safari versions 17.2, 17.3 and 17.4.\n\nRunning in compatibility mode, which may have some DropZone side-effects. Alternatively, consider disabling iframes: https://puckeditor.com/docs/integrating-puck/viewports#opting-out-of-iframes.\n\nSee https://github.com/measuredco/puck/issues/411 for more information. This message will not show in production.` + ); + } + + setSafariFallbackMode(true); + } + }, []); + return ( {children} diff --git a/packages/core/package.json b/packages/core/package.json index a5385b218f..d185b383cc 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -46,6 +46,7 @@ "@types/jest": "^29.5.4", "@types/react": "^18.2.0", "@types/react-dom": "^18.2.0", + "@types/ua-parser-js": "^0.7.39", "css-box-model": "^1.2.1", "eslint": "^7.32.0", "eslint-config-custom": "*", @@ -60,10 +61,11 @@ }, "dependencies": { "@measured/auto-frame-component": "0.1.1", - "@measured/dnd": "16.6.0-canary.f472135", + "@measured/dnd": "16.6.0-canary.eda7e8b", "deep-diff": "^1.0.2", "react-hotkeys-hook": "^4.4.1", "react-spinners": "^0.13.8", + "ua-parser-js": "^1.0.37", "use-debounce": "^9.0.4", "uuid": "^9.0.1" }, diff --git a/yarn.lock b/yarn.lock index e1aba076e3..cc566cd819 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1453,10 +1453,10 @@ object-hash "^3.0.0" react-frame-component "5.2.6" -"@measured/dnd@16.6.0-canary.f472135": - version "16.6.0-canary.f472135" - resolved "https://registry.yarnpkg.com/@measured/dnd/-/dnd-16.6.0-canary.f472135.tgz#c416112271d9c0f3c21ee57aff44b927ce0347e8" - integrity sha512-EvFj+RCpZvdZHSiReo565g6c6zMp7PxmMYMwtA1MCSnBqn4Ll4ozgddnQWYVcyfbv99zOAmMx7CNeo/XC1oiwA== +"@measured/dnd@16.6.0-canary.fb068c0": + version "16.6.0-canary.fb068c0" + resolved "https://registry.yarnpkg.com/@measured/dnd/-/dnd-16.6.0-canary.fb068c0.tgz#5aaa3d107c717432e55500063bdd5ae169c56ec3" + integrity sha512-r9F0kJi48VKbZRnSiJL/Xx6Y1S1K5VQeLzC1ZN4Nu03p5Gt4kos5/04YE7BODq/keq/b70QYi4/owboEIe30/A== dependencies: "@babel/runtime" "^7.23.2" css-box-model "^1.2.1" @@ -2625,6 +2625,11 @@ resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.3.tgz#3d06b6769518450871fbc40770b7586334bdfd90" integrity sha512-THo502dA5PzG/sfQH+42Lw3fvmYkceefOspdCwpHRul8ik2Jv1K8I5OZz1AT3/rs46kwgMCe9bSBmDLYkkOMGg== +"@types/ua-parser-js@^0.7.39": + version "0.7.39" + resolved "https://registry.yarnpkg.com/@types/ua-parser-js/-/ua-parser-js-0.7.39.tgz#832c58e460c9435e4e34bb866e85e9146e12cdbb" + integrity sha512-P/oDfpofrdtF5xw433SPALpdSchtJmY7nsJItf8h3KXqOslkbySh8zq4dSWXH2oTjRvJ5PczVEoCZPow6GicLg== + "@types/unist@*", "@types/unist@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.0.tgz#988ae8af1e5239e89f9fbb1ade4c935f4eeedf9a" @@ -12929,6 +12934,11 @@ typescript@^5.1.6: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.2.tgz#00d1c7c1c46928c5845c1ee8d0cc2791031d4c43" integrity sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ== +ua-parser-js@^1.0.37: + version "1.0.37" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.37.tgz#b5dc7b163a5c1f0c510b08446aed4da92c46373f" + integrity sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ== + ufo@^1.3.0: version "1.3.2" resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.3.2.tgz#c7d719d0628a1c80c006d2240e0d169f6e3c0496"