Skip to content

Patterns · Overlays

SupportPanel

The rail’s Help & support panel: in-app support chat, help articles, contact options and the status page.

@rookcom/monarch-react/shellPattern

Chat, help articles, contacts and status

Usage examples

Help only

Purpose

Every Rook app offers help from the rail’s "Help & support" item: a side panel with chat to the support team, help articles and other ways to reach them. SupportPanel is that panel on Sheet. The chat runs through the product’s Support Chat API client; Monarch makes no network calls.

Use when

  • Once per app, opened from RookRail’s support entry (support.onOpen, open, panelId).
  • Help-only (no client) where chat is not offered yet.

Avoid when

  • Chat between colleagues: that is ChatDock (Rook Chat), bottom-right.
  • Contextual help on one field or page: use a Tooltip, Popover or inline help text.

Design principles

  • Nothing before it is asked for: the client connects on the first open, never at page load.
  • Injected, not built in: the product implements SupportChatClient over its Support Chat API with its own identity and single-flight session refresh.
  • Survives closing: the conversation, the draft and the live stream are kept while the panel is closed.
  • Never empty: connecting, a timeout, a failure, an ended session and an away team each have their own message, with Try again where it helps.
  • From the rail, beside it: a left sheet that can sit next to the rail (inset), never a bottom-right bubble, which belongs to Rook Chat.

API reference

import { SUPPORT_MESSAGE_MAX, SupportPanel, useSupportChat } from '@rookcom/monarch-react/shell';
ExportKindRenderingRoot class
SUPPORT_MESSAGE_MAXutilityclient–
SupportPanelcomponentclient.mn-layout-rail-collapsed
useSupportChathookclient–

Forwards its ref to the sheet. Built on Sheet and Tabs from @rookcom/monarch-react.

Also exported: useSupportChat (the chat state machine, for a custom surface on the same client) and SUPPORT_MESSAGE_MAX (5000).

SupportChatClient is { connect({ signal }), send(text, { clientMessageId }), subscribe?(listener), markRead?(messageId) }.

Generated from the TypeScript declarations of packages/react/src/patterns/overlays/support-panel.

Properties

open + onOpenChange (controlled, as the rail needs) or defaultOpen.

chat replaces the built-in chat with your own surface (for example a widget host element); client is then not used.

status.tone needs status.text: colour alone says nothing.

SupportPanel

The rail's "Help & support" panel: a side sheet with in-app support chat (through the product's Support Chat API client), help articles, contact options and the status page. It is a modal dialog (Sheet): focus moves in, Escape closes, focus returns. The conversation is kept while the panel is closed. Monarch makes no network calls; the client does.

PropTypeDescription
articlesReactNodeHelp articles (search, popular articles): the Help tab's first section.
chatReactNodeYour own chat surface instead of the built-in one (e.g. a widget host element).
classNamestring
clientSupportChatClientThe product's Support Chat API client. With it, the panel has a Chat tab.
connectTimeoutnumberGive up connecting after this long. Default 15000 ms; 0 waits forever.
contactsSupportContact[]Other ways to reach support.
defaultOpenboolean
defaultTab"help" | "chat"The tab shown first. Default `chat` when there is one.
formatTime((date: Date) => string)Formats message times. Default: the browser's short time.
helpHrefstring"Help Center" link in the footer.
idstringPanel id, for the rail's `support.panelId` (`aria-controls`).
insetstringDistance from the edge from 48rem up, so the panel opens beside the rail instead of over it, e.g. `var(--mn-layout-rail-collapsed)`. Default 0.
messagesPartial<SupportPanelMessages>Interface text, for translation.
onOpenChange((open: boolean) => void)
openbooleanOpen (controlled). Wire to the rail's `support.open`.
side"right" | "left"Edge the panel opens from. Default `left` (beside the rail).
statusSupportStatusThe status page.

Variants

PropValuesDescription
content'chat + help (tabs)''chat only''help only'Tabs appear when there is both a chat and help content.
side'left''right'Left (default) for the rail; inset keeps it clear of the rail from 48rem up.

States

StateExposed asBehaviour
Connecting–A status while connect runs (15 seconds at most by default).
Ready–The conversation log, availability line and composer.
Sending / Not sentdata-pendingA message shows "Sending…" until stored; a failure says "Not sent." with Try again (same client id).
Typing–"Sam is typing…" in a status line.
Away–Availability offline: the team will reply here later.
Error / ended–Timeout, failure, ended session or unavailable: an alert, with Try again except for unavailable.

Interaction behaviour

  • Opening connects once; Try again connects again (the previous attempt is aborted).
  • Enter sends, Shift+Enter adds a line; the composer keeps focus after sending.
  • Live events add replies (deduplicated by id), typing, availability and the end of a session.
  • While the chat is visible, the newest support message is reported with markRead.
  • The Help tab holds the articles slot and the contacts; the footer keeps the status page and Help Center one click away.

Keyboard support

KeysAction
EscapeClose the panel; focus returns to what opened it (the rail item).
Tab / Shift+TabMove within the panel (focus is trapped while open).
← / →Switch between Chat and Help.
EnterSend the message.
Shift+EnterNew line in the message.

Accessibility

Role
dialog (modal Sheet) labelled by its title and described by its description
Accessible name
"Help & support" (messages.title).
  • Focus moves into the panel on open and back to the opener on close, also when the opener is the rail item (not a SheetTrigger); without it, the visible [data-rook-support-trigger].
  • The conversation is a focusable role="log" (polite), so new replies are announced and the history can be scrolled by keyboard.
  • Errors are alerts; connecting and typing are status messages.
  • External links say they open in a new tab; the status dot is decorative and the state is in the link text.
  • Security: Monarch makes no requests. Messages are rendered as text, never as HTML, and are capped at 5000 characters. The client owns identity, tokens and refresh; never pass a secret key to the browser.

Responsive behaviour

  • A 28rem side sheet from 48rem up; below that the full screen width, with safe-area insets.
  • Messages wrap long words; the composer grows to 10rem, then scrolls.

Theme support

  • Sheet surface tokens; your messages use the accent solid colours, support’s the muted surface.
  • The sheet’s slide-in and the contact hover are removed under reduced motion.

Do and don't

Do

  • Open it from the rail and pass open and panelId back to the rail for aria-expanded and aria-controls.
  • Implement connect with the abort signal, and send idempotently by clientMessageId.
  • Keep the panel mounted for the whole session so the conversation survives navigation.

Don't

  • Do not put a support bubble bottom-right.
  • Do not connect before the first open.
  • Do not show raw API errors in the chat; reject and let the panel explain.
  • RookRail: Its Help & support entry opens the panel.
  • Sheet: The side panel it is built on.
  • ChatDock: Chat between colleagues.

Dependencies

KindDepends on
npm packagesreact
Monarch componentsButton, Sheet, Spinner, Tabs, Input

Testing coverage

  • Connects on first open only; labelled, described dialog; conversation log; availability; markRead.
  • Enter sends, Shift+Enter is a new line; optimistic then stored.
  • A failed send is marked and retried with the same client id.
  • Live replies (deduplicated), typing, away and an ended session.
  • Timeout aborts and offers Try again; load failure.
  • Conversation and draft kept across close and reopen; focus returns to the opener.
  • Chat and Help tabs (arrow keys), articles, contacts, status with text, Help Center.
  • Own chat surface; help only; defaultOpen, id, inset and translation; SSR when closed.
CheckCovered
Axe in jsdomYes
Server renderingYes
Browser suitesVisual baselines: /__gallery/support-panel (and the open panel in visual.spec.ts); Cross-browser axe: /components/support-panel

Tests: packages/react/src/patterns/overlays/support-panel