import type { Meta, StoryObj } from "@storybook/react-vite"; import { Box } from "@mantine/core"; import type { ReactNode } from "react"; import type { AppBridge } from "@modelcontextprotocol/ext-apps/app-bridge"; import type { Tool } from "@modelcontextprotocol/client"; import { fn } from "storybook/test"; import { AppRenderer, type BridgeFactory } from "./AppRenderer"; const PLACEHOLDER_SANDBOX = "data:text/html,Mock%20Sandbox"; const cohortTool: Tool = { name: "get-cohort-data", title: "Cohort Data", description: "Returns cohort retention heatmap data.", inputSchema: { type: "object" }, }; function createMockBridge(): AppBridge { return { sendToolInput: async () => {}, sendToolResult: async () => {}, sendToolCancelled: async () => {}, sendHostContextChange: async () => {}, addEventListener: () => {}, removeEventListener: () => {}, teardownResource: async () => ({}), close: async () => {}, } as unknown as AppBridge; } const okFactory: BridgeFactory = () => createMockBridge(); const pendingFactory: BridgeFactory = () => new Promise(() => { // Never resolves — represents the period before the bridge is ready. }); const failingFactory: BridgeFactory = () => Promise.reject(new Error("Bridge connect failed: handshake timed out")); function FrameContainer({ children, size, }: { children: ReactNode; size: "default" | "maximized"; }) { const dims = size === "maximized" ? { w: "100%", h: 600 } : { w: 480, h: 320 }; return ( {children} ); } const meta: Meta = { title: "Elements/AppRenderer", component: AppRenderer, args: { sandboxPath: PLACEHOLDER_SANDBOX, tool: cohortTool, onError: fn(), }, parameters: { layout: "centered", }, }; export default meta; type Story = StoryObj; export const Loading: Story = { args: { bridgeFactory: pendingFactory, }, render: (args) => ( ), }; export const Loaded: Story = { args: { bridgeFactory: okFactory, }, render: (args) => ( ), }; export const BridgeError: Story = { args: { bridgeFactory: failingFactory, }, render: (args) => ( ), }; export const Maximized: Story = { args: { bridgeFactory: okFactory, }, render: (args) => ( ), };