Skip to main content
PersonaChatLauncher is a floating action button (FAB) that toggles a PersonaChatView panel — for mounting a chat widget on any page as a support-style bubble, rather than dedicating a full-page route to chat.

Basic usage

Renders a 56px round button in the bottom-right corner. Clicking it opens a floating panel containing a full PersonaChatView. Clicking again (or the X button) closes it.

Panel dimensions

The panel is a fixed-size floating container. Control its size with panelWidth and panelHeight:
The panel has max-h-[calc(100vh-7rem)] and max-w-[calc(100vw-2rem)] constraints — it never overflows the viewport, even if you set very large dimensions.

Position

Both the FAB and the panel respect the position — right-6 / left-6 for the FAB, right-6 / left-6 for the panel.

Controlled vs. uncontrolled open state

Uncontrolled (default): The launcher manages its own open/closed state internally.
Controlled: You manage the state externally.
When open is provided, onOpenChange is called on every toggle, and the internal state is bypassed.

Custom FAB icon

Replace the default MessageCircle icon with your own:
The icon renders inside the FAB button (56px round, themed with --persona-primary).

Container-query responsive behavior

This is the most important technical detail about the launcher. Inside the floating panel:
  • PersonaSidebar needs to decide whether to dock inline or overlay as a full-screen panel.
  • PersonaFilesDrawer needs the same decision.
Normally these components use Tailwind’s md: / lg: responsive prefixes, which key off the browser viewport. But inside the launcher’s floating panel (24rem wide on a 1440px desktop), the viewport is still desktop-width even though the panel is narrow — so the sidebar/drawer would wrongly dock inline and compress the message area into a sliver. Since v0.7.3, PersonaChatView’s root is a named CSS container (@container/persona-chat), and both PersonaSidebar and PersonaFilesDrawer key their breakpoints off container queries:
This means:
  • On a narrow phone (375px viewport): the panel is also narrow → container is narrow → sidebar/drawer overlay correctly.
  • On a wide desktop (1440px viewport) with the launcher’s 24rem panel: the panel is still 384px → container is narrow → sidebar/drawer overlay correctly.
  • On a full-page PersonaChatView (1200px wide): the container is wide → sidebar/drawer dock inline correctly.
One rule covers all cases, no configuration needed.

Theme propagation

The FAB button is a sibling of PersonaChatView’s subtree, not a descendant. CSS custom properties set on PersonaChatView’s root don’t reach the FAB. The launcher handles this by computing buildThemeStyles(theme) once and applying it to a common ancestor (<div style={themeStyles} className="contents">) that wraps both the FAB and the panel. The className="contents" makes this wrapper invisible to layout — it contributes no box, just provides the CSS variable scope. PersonaChatView also sets the same styles on its own root (harmless duplication), but the launcher’s wrapper ensures primaryColor correctly colors the FAB button.

Props reference

Launcher-specific props

Passed-through PersonaChatViewProps

Everything else is passed straight through to the internal PersonaChatView:

Layout structure

Accessibility

  • FAB has aria-label="Open chat" / aria-label="Close chat" toggled by state.
  • Panel content is a full PersonaChatView with standard keyboard navigation (Enter to send, Shift+Enter for newline, Escape to stop streaming).

Integration examples

With Next.js App Router

With a help desk ticketing system