Table of Contents

Ticket Widget Anatomy and Styling

Helpdocs Admin Updated by Helpdocs Admin

Every ticket widget is built from the same shared frame. This article describes that frame: the icon, the header, the description and the colours. It also lists the limits that apply to every widget.

In short: a widget is a bordered block with an icon on the left. The block has a title, an optional description, the main content and, at the bottom, action buttons. A provider can change the icon and the colours. The client handles the rest of the layout.

Layout at a glance

On a large screen the widget has two sides.

  • Left: the icon. It sits in a square with a background colour. By default the background is grey and the icon is white.
  • Right: the content block. From top to bottom it contains:
  1. Header: the title.
  2. Description: optional text.
  3. Content: the main body of the widget, which depends on the widget type.
  4. Actions: buttons the user can press. These are covered in a separate article.

Header and title

The header is always shown, even when the widget is collapsed. The title is required. A widget without a title is invalid.

  • The title is plain text.
  • It can be at most 256 characters. Anything longer is cut off by the client.
  • The title colour can be changed with titleColour (see "Colours").

Description

The description is optional Markdown text shown under the header. Use it to explain what the widget is for or what the user should do.

The description is always shown, including when the widget is collapsed. The only question is whether the user sees all of it or a preview.

Description length

What the user sees

Under 250 characters

Shown in full.

250 characters or more

A preview, with a control to expand and read the rest.

Rules:

  • It can be at most 10,000 characters. Anything longer is cut off by the client.
  • Markdown only. Raw HTML is not supported. HTML is sanitised for security, so it will not render as written.
**Order #4821** is waiting for approval.

- Placed by Jane Smith
- Needs sign-off before Friday

Tip: put the most important sentence first. If the text is long, only the start is visible until the user expands it.

Icon

The icon appears at the left of the widget.

  • Default: each widget type has its own default icon, white on a grey background. There are four, one each for Description, List, Progress and Form. There is also a separate error icon, used when something goes wrong.
  • Custom: a provider can supply its own SVG with the icon field.

Custom icon fields:

export interface CustomSvgContent {
readonly fill?: string | 'currentColor';
/**
* Four numbers separated by single spaces, e.g. "0 0 24 24".
* Commas are not supported.
*/
readonly viewBox: string;
/**
* Raw SVG markup (inner content of an <svg> element, e.g. <path> tags).
* Sanitized before rendering. Maximum 10,000 characters — if exceeded,
* the icon is ignored entirely (falls back to no icon) rather than
* truncated, since truncated SVG markup is likely to be invalid.
*/
readonly content: string;
}

Things to know:

  • Too long means no icon. If content is over 10,000 characters, the icon is ignored completely and the widget shows no icon. It is not truncated, because a cut-off SVG would probably be invalid.
  • Leave fill blank if unsure. currentColor follows the UI's colour, so the icon stays readable. A custom fill is allowed, but test it first, including against your chosen border colour.
{
"icon": {
"viewBox": "0 0 24 24",
"content": "<path d=\"M12 2L2 7l10 5 10-5-10-5z\"/>"
}
}

Colours

Two optional fields set colour. Both take one of these values: default, accent, good, warning, attention, light

Field

What it changes

borderColour

The outer border of the content block, and the background of the icon square on the left.

titleColour

The colour of the title text.

Notes:

  • The exact shade of each value is chosen by the client and can vary with the theme. You pick a meaning, not a colour code.
  • borderColour does not change the inner separators inside the content block. Those keep the default colour.
  • Setting borderColour also recolours the icon background. If you set a custom icon fill, check that it still contrasts with that background.
  • If you omit either field, the client uses its default style.

Type reference

export interface TicketWidgetContentBase<T> {
readonly type: TicketWidgetContentType;

readonly refreshMode?: TicketWidgetRefreshMode;
readonly refreshIntervalSec?: number;

readonly icon?: CustomSvgContent;

/**
* Maximum 256 characters. Hard-truncated (client-side) beyond this length.
*/
readonly title: string;
readonly titleColour?: ContentColor;

/**
* Markdown content, does not support HTML embed.
* Maximum 10,000 characters. Hard-truncated (client-side) beyond this length.
*/
readonly description?: string;

readonly borderColour?: ContentColor;

readonly value: T;

/**
* Action rendered on the far left, isolated from the secondary/primary
* action group (e.g. "back" in a multi-step form).
*
* Never gated by form validation: always enabled, even when the form is
* incomplete. When `form` is present, the current (possibly partial)
* answers are sent with the request so the provider can restore them
* (e.g. when the user steps back). This is NOT a submission; the provider
* must not validate, persist or act on the answers.
*/
readonly leadingAction?: TicketWidgetAction;

/**
* Secondary action rendered on the right, before the primary action.
* Typically a lower-emphasis action (e.g. "cancel", "skip").
*
* Never gated by form validation: always enabled, even when the form is
* incomplete. When `form` is present, the current (possibly partial)
* answers are sent with the request so the provider can remember them.
* This is NOT a submission; the provider must not validate, persist or
* act on the answers.
*/
readonly secondaryAction?: TicketWidgetAction;

/**
* Primary action rendered on the far right, the main call-to-action
* for this widget (e.g. "next", "submit").
*
* When `form` is present, disabled until the form is complete (all
* required fields answered). This is the only action that submits the
* form: the answers are sent as a submission, and the provider should
* validate and act on them.
*/
readonly primaryAction?: TicketWidgetAction;

/**
* Answers submitted by the user, keyed by field identifier, and sent back
* to the provider on the next request.
*
* Limits:
* - Maximum 20 entries. Entries beyond this are dropped.
* - Key: maximum 100 characters. Hard-truncated (client-side) beyond this length.
* - A null result is replaced with an empty result.
* - Invalid results are dropped, not converted.
* - Each choice identifier is hard-truncated (client-side) to 100 characters.
* - Maximum 10 choices per result. Choices beyond this are dropped.
*/
readonly form?: Record<string, TicketWidgetFieldResult>;

/**
* Arbitrary provider-defined data carried across requests. The client
* persists whatever the provider returns here and sends it back verbatim
* on the next request. Providers do not need to store session state
* themselves; the round trip through the client is the only state store.
*
* Limits (anything exceeding them is dropped, not truncated):
* - Maximum 20 entries.
* - Key: maximum 100 characters.
* - Value: maximum 1,000 characters.
* - Non-string values are dropped, not converted.
*/
readonly state?: Record<string, string>;
}

How did we do?

How the Widget Is Requested

Ticket Widget Actions: Leading, Secondary and Primary

Contact