Mavna

Layouts

An inline card, a full page, or a drawer. One config field chooses the layout, and the drawer opens from its own button, a prop, or a ref.

variant chooses how the widget sits in your page. The flow inside is the same in all three.

Compact

variant: "compact" is the default: one card that holds the form, the routes and the transfer. It takes the width of its container, so it fits in a sidebar or a checkout panel. The widget on Embed the widget is this layout.

Wide

variant: "wide" is the full-page layout the Mavna app uses: a header with the network toggle, the wallet button and the menu, and the form with the routes beside it. Use it when the widget is the page.

Drawer

variant: "drawer" puts the compact card in a popup that rises from the bottom over a dimmed page. By default it comes with its own button, labelled Bring funds to Stellar. It closes on its close button, the dimmed backdrop, or the Escape key. Escape first closes a menu open inside the widget, or goes back from a screen such as the chain picker, and closes the drawer only when there is neither. While your user's wallet is showing a prompt, the drawer stays open.

To open it from your own button instead, pass the open prop: the widget then shows no button of its own, and onClose is called once the closing animation has finished.

const [open, setOpen] = useState(false);

<MavnaWidget config={config} open={open} onClose={() => setOpen(false)} />;

Or take a ref and call its methods:

const ref = useRef<MavnaWidgetRef>(null);

<MavnaWidget ref={ref} config={config} />;

// ref.current?.openDrawer(), closeDrawer(), toggleDrawer(), isOpen()

The component's types

The declarations below are copied from packages/widget/src/MavnaWidget.tsx when this site is built.

/**
 * The Mavna widget: one self-contained component that quotes, routes and (by
 * default) manages wallets itself, configured by a single object.
 *
 * It builds its own engine from the config and renders the whole flow inside a
 * scoped `.mv-root`. The `wide` variant is the full-page layout the Mavna app
 * uses; the `drawer` variant rises from the bottom to a full-page popup, opened by
 * its own trigger, by the `open` prop, or by the imperative handle on the ref.
 *
 * The engine is memoised on the config values that actually change it, so a stable
 * config keeps one engine (and one wallet session) for the widget's life.
 */
export interface MavnaWidgetProps {
  readonly config: MavnaWidgetConfig;
  /** Drawer only: drive the open state from the host instead of the trigger. */
  readonly open?: boolean;
  /** Drawer only: called once the close animation has finished. */
  readonly onClose?: () => void;
}

export interface MavnaWidgetRef {
  openDrawer(): void;
  closeDrawer(): void;
  toggleDrawer(): void;
  isOpen(): boolean;
}

On this page