UNPKG

@tldraw/editor

Version:

tldraw infinite canvas SDK (editor).

247 lines (231 loc) • 7.22 kB
import { Fragment, jsx, jsxs } from "react/jsx-runtime"; import { useValue } from "@tldraw/state-react"; import { memo, useRef } from "react"; import { useCanvasEvents } from "../hooks/useCanvasEvents.mjs"; import { useEditor } from "../hooks/useEditor.mjs"; import { usePassThroughWheelEvents } from "../hooks/usePassThroughWheelEvents.mjs"; import { preventDefault } from "../utils/dom.mjs"; import { runtime } from "../utils/runtime.mjs"; import { watermarkDesktopSvg, watermarkMobileSvg } from "../watermarks.mjs"; import { LicenseManager } from "./LicenseManager.mjs"; import { useLicenseContext } from "./LicenseProvider.mjs"; import { useLicenseManagerState } from "./useLicenseManagerState.mjs"; const WATERMARK_DESKTOP_LOCAL_SRC = `data:image/svg+xml;utf8,${encodeURIComponent(watermarkDesktopSvg)}`; const WATERMARK_MOBILE_LOCAL_SRC = `data:image/svg+xml;utf8,${encodeURIComponent(watermarkMobileSvg)}`; const Watermark = memo(function Watermark2() { const licenseManager = useLicenseContext(); const editor = useEditor(); const isMobile = useValue("is mobile", () => editor.getViewportScreenBounds().width < 700, [ editor ]); const licenseManagerState = useLicenseManagerState(licenseManager); if (!["licensed-with-watermark", "unlicensed"].includes(licenseManagerState)) return null; return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx(LicenseStyles, {}), /* @__PURE__ */ jsx( WatermarkInner, { src: isMobile ? WATERMARK_MOBILE_LOCAL_SRC : WATERMARK_DESKTOP_LOCAL_SRC, isUnlicensed: licenseManagerState === "unlicensed" } ) ] }); }); const UnlicensedWatermark = memo(function UnlicensedWatermark2({ isDebugMode, isMobile }) { const editor = useEditor(); const events = useCanvasEvents(); const ref = useRef(null); usePassThroughWheelEvents(ref); const url = "https://tldraw.dev/pricing?utm_source=sdk&utm_medium=organic&utm_campaign=watermark"; return /* @__PURE__ */ jsx( "div", { ref, className: LicenseManager.className, "data-debug": isDebugMode, "data-mobile": isMobile, "data-unlicensed": true, "data-testid": "tl-watermark-unlicensed", draggable: false, ...events, children: /* @__PURE__ */ jsx( "button", { draggable: false, role: "button", onPointerDown: (e) => { editor.markEventAsHandled(e); preventDefault(e); }, title: "The tldraw SDK requires a license key to work in production. You can get a free 100-day trial license at tldraw.dev/pricing.", onClick: () => { runtime.openWindow(url, "_blank", true); }, children: "Get a license for production" } ) } ); }); const WatermarkInner = memo(function WatermarkInner2({ src, isUnlicensed }) { const editor = useEditor(); const isDebugMode = useValue("debug mode", () => editor.getInstanceState().isDebugMode, [editor]); const isMobile = useValue("is mobile", () => editor.getViewportScreenBounds().width < 700, [ editor ]); const events = useCanvasEvents(); const ref = useRef(null); usePassThroughWheelEvents(ref); const maskCss = `url('${src}') center 100% / 100% no-repeat`; const url = "https://tldraw.dev/?utm_source=sdk&utm_medium=organic&utm_campaign=watermark"; if (isUnlicensed) { return /* @__PURE__ */ jsx(UnlicensedWatermark, { isDebugMode, isMobile }); } return /* @__PURE__ */ jsx( "div", { ref, className: LicenseManager.className, "data-debug": isDebugMode, "data-mobile": isMobile, "data-testid": "tl-watermark-licensed", draggable: false, ...events, children: /* @__PURE__ */ jsx( "button", { draggable: false, role: "button", onPointerDown: (e) => { editor.markEventAsHandled(e); preventDefault(e); }, title: "Build infinite canvas applications with the tldraw SDK. Learn more at https://tldraw.dev.", onClick: () => { runtime.openWindow(url, "_blank"); }, style: { mask: maskCss, WebkitMask: maskCss } } ) } ); }); const LicenseStyles = memo(function LicenseStyles2() { const editor = useEditor(); const className = LicenseManager.className; const CSS = ` /* ------------------- SEE LICENSE ------------------- The tldraw watermark is part of tldraw's license. It is shown for unlicensed or "licensed-with-watermark" users. By using this library, you agree to preserve the watermark's behavior, keeping it visible, unobscured, and available to user-interaction. To remove the watermark, please purchase a license at tldraw.dev. */ .${className} { position: absolute; bottom: max(var(--tl-space-2), env(safe-area-inset-bottom)); right: max(var(--tl-space-2), env(safe-area-inset-right)); width: 96px; height: 32px; display: flex; align-items: center; justify-content: center; z-index: var(--tl-layer-watermark) !important; background-color: color-mix(in srgb, var(--tl-color-background) 62%, transparent); opacity: 1; border-radius: 5px; pointer-events: all; padding: 2px; box-sizing: content-box; } .${className} > button { position: absolute; width: 96px; height: 32px; pointer-events: all; cursor: inherit; color: var(--tl-color-text); opacity: .38; border: 0; padding: 0; background-color: currentColor; } .${className}[data-debug='true'] { bottom: max(46px, env(safe-area-inset-bottom)); } .${className}[data-mobile='true'] { border-radius: 4px 0px 0px 4px; right: max(-2px, calc(env(safe-area-inset-right) - 2px)); width: 8px; height: 48px; } .${className}[data-mobile='true'] > button { width: 8px; height: 32px; } .tl-container[dir='rtl'] .${className} { right: auto; left: max(var(--tl-space-2), env(safe-area-inset-left)); } .tl-container[dir='rtl'] .${className}[data-mobile='true'] { border-radius: 0px 4px 4px 0px; left: max(-2px, calc(env(safe-area-inset-left) - 2px)); } .${className}[data-unlicensed='true'] > button { font-size: 100px; position: absolute; pointer-events: all; cursor: pointer; color: var(--tl-color-text); opacity: 0.8; border: 0; padding: 0; background-color: transparent; font-size: 11px; font-weight: 600; text-align: center; } .${className}[data-mobile='true'][data-unlicensed='true'] > button { display: none; } @media (hover: hover) { .${className} > button { pointer-events: none; } .${className}:hover { background-color: var(--tl-color-background); transition: background-color 0.2s ease-in-out; transition-delay: 0.32s; } .${className}:hover > button { animation: ${className}_delayed_link 0.2s forwards ease-in-out; animation-delay: 0.32s; } .${className} > button:focus-visible { opacity: 1; } } @keyframes ${className}_delayed_link { 0% { cursor: inherit; opacity: .38; pointer-events: none; } 100% { cursor: pointer; opacity: 1; pointer-events: all; } }`; return /* @__PURE__ */ jsx("style", { nonce: editor.options.nonce, children: CSS }); }); export { Watermark }; //# sourceMappingURL=Watermark.mjs.map