ToonUI
Write ToonUI

Catalog

How to configure the official ToonUI component catalog exposed by @toon-ui/core.

The official catalog comes from @toon-ui/core and defines what the language supports today.

The catalog is configurable, but it is not free-form.

You do this:

const components = ['text', 'card', 'button'] as const;

You do not do this:

const components = ['delete_product', 'invoiceSummary'] as const;

Those are business concepts, not ToonUI components. Business intent belongs in reply="...", submitted form values, tools, routes, server actions, and application code.

How catalog configuration works

One component key controls three things:

  1. what the server teaches the model in the prompt
  2. what the validator accepts from model output
  3. what React components your client must register to render that output
// shared/catalog.ts
export const toonComponents = [
  'text',
  'card',
  'form',
  'field',
  'button',
  'table',
] as const;
// server/toon.ts
import { createToonProtocol } from '@toon-ui/core';
import { toonComponents } from './shared/catalog';

export const toon = createToonProtocol({
  components: toonComponents,
});
// client/toon-runtime.tsx
'use client';

import { createToonReactRuntime } from '@toon-ui/react';
import { toonComponents } from './shared/catalog';

export const toon = createToonReactRuntime({
  components: {
    text: TextComponent,
    card: CardComponent,
    form: FormComponent,
    field: FieldComponent,
    button: ButtonComponent,
    table: TableComponent,
  },
});

The array and the React registry must describe the same active surface. If the model emits a component outside that surface, ToonUI rejects it instead of silently rendering unsupported UI.

Official component matrix

Use this matrix when deciding what to enable.

KeyGroupPurposeRequired children/dependenciesRoot?
textContentVisible copy.Yes
headingContentSemantic heading hierarchy.Yes
separatorContentVisual divider.Yes
badgeContentShort semantic status label.Yes
cardStructureGeneral content container.Can contain other enabled nodes.Yes
listStructureRepeated structured results.Requires item.Yes
itemStructureSingle list entry.Usually used inside list; can contain other enabled nodes.Structural
tableStructureExact tabular data.Uses columns: and row: lines.Yes
emptyStructure/FeedbackZero-result state.Can contain other enabled nodes.Yes
tabsStructureParallel grouped views.Requires tab.Yes
tabStructureSingle tabs panel.Only valid inside tabs.No
accordionStructureProgressive disclosure.Requires section.Yes
sectionStructureSingle accordion section.Only valid inside accordion.No
formCaptureStructured data capture.Requires field and button.Yes
fieldCaptureForm input primitive.Only useful inside form.Structural
buttonCaptureReply or submit interaction.Yes
confirmCaptureConfirmation flow container.Can contain other enabled nodes, usually text and button.Yes
alertFeedbackImportant callout.Can contain other enabled nodes.Yes
progressFeedbackDeterministic progress indicator.Yes
loadingFeedbackTransient loading state.Yes
toastFeedbackEphemeral result feedback.Yes
dialogOverlayModal interaction container.Can contain other enabled nodes.Yes
sheetOverlayEdge-attached contextual panel.Can contain other enabled nodes.Yes
popoverOverlayInline contextual overlay.Can contain other enabled nodes.Yes
tooltipOverlayShort contextual hint.Yes
breadcrumbNavigationHierarchical path navigation.Requires crumb.Yes
crumbNavigationSingle breadcrumb step.Only valid inside breadcrumb.No
paginationNavigationPage navigation state.Yes
menuNavigationList of actions.Requires action.Yes
commandNavigationCommand-palette style actions.Requires action.Yes
actionNavigationSingle menu/command action.Only valid inside menu or command.No
chartAnalyticsTrend or comparison visualization.Requires series and point.Yes
seriesAnalyticsChart data series.Only valid inside chart; requires point.No
pointAnalyticsSingle chart data point.Only valid inside series.No

Dependency rules

Some keys are not useful by themselves because the parser and validator expect a parent/child shape.

If you enableYou must also enable
formfield, button
listitem
tabstab
accordionsection
menuaction
commandaction
chartseries, point
breadcrumbcrumb

ToonUI throws early when this configuration is invalid. That is intentional. A broken catalog should fail during setup, not after the model has already produced unusable UI.

Configure by capability

These are examples, not exported presets. ToonUI does not ship a ready-made design system or a default UI catalog.

Text-only responses

const components = ['text', 'heading', 'separator'] as const;

Use this when the model should only structure copy.

Cards and simple actions

const components = ['text', 'heading', 'badge', 'card', 'button'] as const;

Use this for entity summaries, status, and simple reply actions.

Forms

const components = ['text', 'form', 'field', 'button'] as const;

If you enable form, you MUST enable field and button.

Search results and empty states

const components = ['text', 'list', 'item', 'badge', 'button', 'empty'] as const;

Use this for repeated entities and zero-result flows.

Exact data

const components = ['text', 'table'] as const;

Use this when columns and exact values matter.

const components = ['breadcrumb', 'crumb', 'pagination', 'menu', 'command', 'action'] as const;

Use this only when your app has matching navigation/action behavior.

Charts

const components = ['chart', 'series', 'point'] as const;

Use this when your React app has a real chart adapter. If not, do not enable it.

Overlays

const components = ['text', 'dialog', 'sheet', 'popover', 'tooltip', 'button'] as const;

Use overlays only when your UI shell can render them correctly.

Variants and type families

FamilyValues
Button variantsprimary, secondary, danger, ghost, outline
Badge variantssuccess, warning, danger, neutral, info
Alert variantsinfo, success, warning, danger
Confirm variantsneutral, info, warning, danger, success
Field typestext, email, number, password, date, time, textarea, select, checkbox, radio, switch, combobox, otp, slider, multiselect
Chart typesbar, line, area, pie
Sheet sidesleft, right, top, bottom
Separator orientationshorizontal, vertical

Official description support

description="..." is officially supported on:

  • card
  • form
  • alert
  • confirm
  • dialog
  • item
  • empty
  • chart

Do not add description everywhere just because your design system has subtitles. The language only accepts it where the parser supports it.

Official trigger support

trigger="..." is officially supported on nodes that may need a launcher label:

  • confirm
  • dialog
  • sheet
  • popover
  • tooltip
  • command

The trigger is only a label. Your React host still controls open/close behavior.

Server and client must agree

Bad configuration:

// server teaches table
createToonProtocol({ components: ['text', 'table'] });

// client cannot render table
createToonReactRuntime({
  components: {
    text: TextComponent,
  },
});

Correct configuration:

const components = ['text', 'table'] as const;

createToonProtocol({ components });

createToonReactRuntime({
  components: {
    text: TextComponent,
    table: TableComponent,
  },
});

Important modeling rule

The catalog defines the language, not your product semantics.

For example:

  • form means “collect structured input”
  • button means “trigger interaction”
  • reply="open:customer-42" is your app-level intent encoding

The catalog should stay generic. Your app decides what those actions mean.

  1. Complete Syntax Reference
  2. AI Authoring Rules
  3. @toon-ui/react
  4. Errors and Validation

On this page