atlassian / pragmatic-drag-and-drop

Fast drag and drop for any experience on any tech stack
https://atlassian.design/components/pragmatic-drag-and-drop
Other
9.77k stars 223 forks source link

Using with Iframe #104

Closed SOG-web closed 3 months ago

SOG-web commented 3 months ago

please am trying to make an iframe my drop target, is it possible

import {
  SandpackLayout,
  SandpackCodeEditor,
  SandpackPreview,
  SandpackStack,
  useSandpack,
  SandpackConsole,
} from "@codesandbox/sandpack-react";
import { SandpackFileExplorer } from "sandpack-file-explorer";
import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
import { useEffect, useRef } from "react";
import CustomSandPackProvider from "./sandpack-provider";
import {
  dropTargetForElements,
  monitorForElements,
} from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
import invariant from "tiny-invariant";

export default function CustomSandPack() {
  const { sandpack, listen } = useSandpack();
  const { files, activeFile, clients } = sandpack;
  const previewRef = useRef(null);

  useEffect(() => {
    if (previewRef.current && clients[previewRef.current["clientId"]]) {
      const el = clients[previewRef.current["clientId"]].iframe;
      invariant(el);

      return dropTargetForElements({
        element: el,
        getData: () => ({ id: "root" }),
        onDragEnter: ({ source }) => {
          console.log("source", source);
        },
        onDragLeave: () => {
          console.log("leave");
        },
        onDrop: () => {
          console.log("drop");
        },
        canDrop: ({ source }) => {
          console.log("source", source);
          return true;
        },
      });
    }
  }, [previewRef, clients]);

  useEffect(() => {
    return monitorForElements({
      onDrop: (data) => {
        console.log("Dropped", data);
      },
      onDragStart: ({ source }) => {
        console.log("Drag Start", source, location);
      },
    });
  }, [clients]);

  useEffect(() => {
    console.log(files[activeFile].code);
  }, [sandpack, activeFile, files]);
  return (
    // <SandpackThemeProvider theme={nightOwl}>
    <SandpackStack>
      <SandpackLayout
        style={{
          display: "flex",
          minWidth: "100%",
          flexDirection: "row",
        }}
      >
        <div
          style={{
            display: "flex",
            minHeight: "300px",
            height: "100dvh",
            minWidth: "600px",
            backgroundColor: `var(--sp-colors-surface1)`,
          }}
        >
          <div
            style={{
              minWidth: 150,
              maxWidth: "300px",
              overflow: "hidden",
            }}
          >
            <SandpackFileExplorer />
          </div>
          <div style={{ flex: "min-content" }}>
            <SandpackCodeEditor
              extensions={[autocompletion()]}
              extensionsKeymap={[completionKeymap]}
              wrapContent
              style={{
                minHeight: "100%",
                maxHeight: "100%",
                overflow: "auto",
              }}
              showTabs
              closableTabs
              showInlineErrors
              showLineNumbers
              showRunButton
            />
          </div>
        </div>
        <div
          style={{
            overflow: "auto",
            height: "100dvh",
            backgroundColor: "white",
          }}
          className="bg-white flex flex-col flex-1"
        >
          <SandpackPreview
            ref={previewRef}
            style={{
              overflow: "auto",
              height: "80%",
              width: "100%",
              backgroundColor: "white",
            }}
            showNavigator
            showOpenNewtab
            showOpenInCodeSandbox={false}
            actionsChildren={
              <button onClick={() => window.alert("Bug reported!")}>
                Report bug
              </button>
            }
          />
          <SandpackConsole className="h-[20%] w-[100%] text-white" />
        </div>
      </SandpackLayout>
    </SandpackStack>
    // </SandpackThemeProvider>
  );
}

export function Sandpack() {
  return (
    <CustomSandPackProvider>
      <CustomSandPack />
    </CustomSandPackProvider>
  );
}
alexreardon commented 3 months ago

Hi there,

Yes usage with iframes is possible. See: https://github.com/atlassian/pragmatic-drag-and-drop/issues/24#issuecomment-2290171561

If you are still running into issues, please post a reproducible test case (eg with stackblitz which works well with iframes) and i'll take a further look.

I also plan to create a "working with iframes" guide