Skip to content

Host-integrated Mermaid download and fullscreen hooks #490

@simon5057

Description

@simon5057

Problem Statement

When Streamdown is embedded inside a desktop webview or an iframe sidebar panel, the Mermaid download and fullscreen actions are confined to the web context:

  • Download is sandboxed to the browser/webview and cannot invoke host-native save dialogs or write files to user-selected locations.
  • Fullscreen is limited to the iframe/panel container, not a true host-level expanded view.

This blocks good UX for desktop integrations where the host application needs to handle these actions natively.

Proposed Solution

Add optional callback hooks to the Mermaid controls configuration:

  • onMermaidDownload(payload) — called before the default download. Receives the generated Blob, suggested filename, mimeType, chart source, and config. If the callback returns { handled: true }, the default browser download is skipped.
  • onMermaidFullscreen(payload) — called before the default fullscreen. Receives chart source and config. If the callback returns { handled: true }, the default fullscreen behavior is skipped.

If no callbacks are provided, existing behavior is unchanged.

Alternatives Considered

  • Custom renderer plugin: Using the existing customRenderer API to replace the entire Mermaid block. This is too heavy-handed — it requires reimplementing the full Mermaid UI just to intercept two actions.

Use Case

import { Streamdown } from "streamdown";

<Streamdown
  mermaid={{
    config: { theme: "dark" },
    onDownload: async ({ blob, filename, mimeType, chart, config }) => {
      // Forward blob to desktop host via postMessage / bridge API
      window.parent.postMessage(
        { type: "save-file", blob, filename, mimeType },
        "*"
      );
      return { handled: true }; // skip default browser download
    },
    onFullscreen: ({ chart, config }) => {
      // Ask host to open chart in a dedicated large window
      window.parent.postMessage(
        { type: "open-fullscreen", chart, config },
        "*"
      );
      return { handled: true }; // skip default in-panel fullscreen
    },
  }}
>
  {markdown}
</Streamdown>;

Priority

Important

Contribution

  • I am willing to help implement this feature

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions