/* Copyright 2026 Marimo. All rights reserved. */ import { ExternalLinkIcon } from "lucide-react"; import type React from "react"; import { useState } from "react"; import { Button } from "@/components/ui/button"; import { DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Constants } from "@/core/constants"; import { getExportLayout } from "@/core/export/layout"; import { useRequestClient } from "@/core/network/requests"; import { VirtualFileTracker } from "@/core/static/virtual-file-tracker"; import { Spinner } from "../icons/spinner"; import { stageForPublish } from "./stage-for-publish"; type PublishState = | { kind: "idle" } | { kind: "publishing" } | { kind: "staged"; claimUrl: string } | { kind: "failed"; message: string }; export const ShareStaticNotebookModal: React.FC<{ onClose: () => void; }> = ({ onClose }) => { const [state, setState] = useState({ kind: "idle" }); const { exportAsHTML } = useRequestClient(); const handlePublish = async () => { setState({ kind: "publishing" }); try { const { contents: html, filename } = await exportAsHTML({ download: false, includeCode: true, files: VirtualFileTracker.INSTANCE.filenames(), layout: await getExportLayout(), // Published notebooks are served from a remote origin, so assets must // come from the CDN — never the local server (which is the dev-mode // default). The server substitutes {version}. assetUrl: "https://cdn.jsdelivr.net/npm/@marimo-team/frontend@{version}/dist", }); const claimUrl = await stageForPublish(filename, html); // Best effort: after the async work above, browsers may treat this as a // popup and block it. The dialog keeps the link either way. window.open(claimUrl, "_blank", "noopener,noreferrer"); setState({ kind: "staged", claimUrl }); } catch (error) { setState({ kind: "failed", message: error instanceof Error ? error.message : "Something went wrong", }); } }; if (state.kind === "staged") { return ( Finish publishing If the confirmation page didn't open in a new tab, open it below. ); } const isPublishing = state.kind === "publishing"; return ( Publish HTML to web Publish a static snapshot of this notebook to{" "} molab . Snapshots can be viewed by anyone on the internet. {state.kind === "failed" && (

Publish failed: {state.message}

)}
); };