Standard Catalog Reference
The Standard Catalog (@freesail/standard-catalog) provides the baseline set of UI components and client-side functions for Freesail surfaces.
Catalog ID: https://freesail.dev/catalogs/standard-catalog.json
Using the Standard Catalog
Section titled “Using the Standard Catalog”import { ReactUI } from 'freesail';import { StandardCatalog } from '@freesail/standard-catalog';
<ReactUI.FreesailProvider theme={ReactUI.defaultLightTokens} catalogs={[StandardCatalog]}> <App /></ReactUI.FreesailProvider>The catalog namespace is exported as StandardCatalog.namespace — use this as the catalogId when calling create_surface.
Controlling Visibility
Section titled “Controlling Visibility”Use the show and hide functions to toggle component visibility dynamically. These write to the client-side __componentState path and take effect immediately without a round-trip to the agent.
{ "id": "open_modal_btn", "component": "Button", "label": "Open", "action": { "functionCall": { "call": "show", "args": { "componentId": "my_modal" } } }}The visible property on any component can also be bound to the data model for agent-controlled visibility.
Common Properties
Section titled “Common Properties”Every component inherits these properties from ComponentCommon:
| Property | Type | Required | Description |
|---|---|---|---|
id | ComponentId | ✅ | Unique identifier within the surface |
component | string | ✅ | Component type name (e.g. 'Text', 'Button') |
visible | DynamicBoolean | Controls rendering (default true). Use show/hide functions for dynamic control. | |
width | DynamicString | CSS width. Use '100%' for full parent width, px for small fixed elements. Prefer weight for proportional sizing. | |
height | DynamicString | CSS height. Prefer minHeight over fixed height so elements can grow. | |
weight | DynamicNumber | Flex-grow equivalent. Only valid as a direct child of Row or Column. | |
flexBasis | DynamicString | Defines the wrap breakpoint in a Row (e.g. '300px'). | |
minWidth | DynamicString | Hard minimum width floor after wrapping. | |
minHeight | DynamicString | Hard minimum height floor (e.g. '300px' for a chart card). | |
accessibility | object | { label, description } for screen readers. |
Components
Section titled “Components”Layout
Section titled “Layout”Column
Section titled “Column”Arranges children vertically.
| Property | Type | Required | Description |
|---|---|---|---|
children | ChildList | ✅ | Child component IDs or template |
gap | DynamicString | Spacing: none | sm | md | lg | xl or CSS length (default sm) | |
padding | DynamicString | Padding around content | |
justify | string | Main axis: start | center | end | spaceBetween | spaceAround | spaceEvenly | stretch | |
align | string | Cross-axis: start (default) | center | end | stretch. Set to stretch for list layouts. | |
theme | Theme | Design token overrides cascading to all children |
Arranges children horizontally. Wraps by default.
| Property | Type | Required | Description |
|---|---|---|---|
children | ChildList | ✅ | Child component IDs or template |
gap | DynamicString | Spacing: none | sm | md | lg | xl or CSS length (default sm) | |
padding | DynamicString | Padding around content | |
justify | string | Main axis: start | center | end | spaceBetween | spaceAround | spaceEvenly | stretch | |
align | string | Cross-axis: start | center | end | stretch. Use end when mixing labelled inputs with unlabelled Buttons. | |
wrap | string | wrap (default) | nowrap | wrap-reverse | |
theme | Theme | Design token overrides cascading to all children |
A styled container with border and optional shadow. Two variants: raised (default — elevated with shadow and rounded corners) and flat (no shadow, square corners, blends with main surface background).
| Property | Type | Required | Description |
|---|---|---|---|
child | ComponentId | ✅ | ID of the single child component. Wrap multiple elements in a Column/Row. |
variant | string | raised (default) | flat | |
borderWeight | number | Border thickness in pixels (default 1; set to 0 to remove) | |
padding | DynamicString | Internal padding (default '16px') | |
align | string | Cross-axis alignment of children: start | center | end | stretch (default) | |
justify | string | Main-axis distribution: start (default) | center | end | between | around | |
zoomable | boolean | When true, adds a zoom toggle that opens the card in a centred modal overlay | |
theme | Theme | Design token overrides for the card and all content inside |
FluidGrid
Section titled “FluidGrid”A responsive auto-fill grid. Each column is at least minItemWidth wide; the browser fills as many columns as fit. Use for card galleries, icon grids, and tile layouts.
| Property | Type | Required | Description |
|---|---|---|---|
children | ChildList | ✅ | Child component IDs or template |
minItemWidth | DynamicString | Minimum column width (default '200px') | |
gap | DynamicString | Gap between items |
TabularGrid
Section titled “TabularGrid”A fixed-column grid with optional header row and alternating row styling. Collapses to a single column on narrow containers (< 480px). Row content is composed using Row and Text components via the children template.
| Property | Type | Required | Description |
|---|---|---|---|
children | ChildList | ✅ | Template pointing to a Row component and a data path |
columns | number | Fixed column count (required when headers is absent) | |
headers | DynamicString[] | Column header labels. Length sets the column count. | |
columnWeights | number[] | Fractional width weights per column. Defaults to equal sizing. | |
rowPadding | DynamicString | Cell padding (default '10px 16px') | |
showGridLines | boolean | Row separators (default true) | |
gap | DynamicString | Gap between items | |
theme | Theme | Token overrides: bgMuted → header row, bgRaised → odd rows, bg → even rows, border → separators |
When placing
TextFieldorDropdowncomponents inside aTabularGrid, omit thelabelprop — the column headers already act as labels.
A scrollable list of children, vertical or horizontal.
| Property | Type | Required | Description |
|---|---|---|---|
children | ChildList | ✅ | Child component IDs or template |
direction | string | vertical (default) | horizontal | |
align | string | Cross-axis alignment |
TabGroup + Tab
Section titled “TabGroup + Tab”Tabbed container. TabGroup holds Tab children; one tab is visible at a time.
TabGroup:
| Property | Type | Required | Description |
|---|---|---|---|
children | ComponentId[] | ✅ | Array of Tab component IDs |
Tab:
| Property | Type | Required | Description |
|---|---|---|---|
title | DynamicString | ✅ | Tab label |
child | ComponentId | ✅ | Content component ID |
A modal overlay controlled by show/hide functions. Must be included in the parent layout’s children array to render (it renders as a fixed overlay regardless of its tree position). Visibility defaults to false. Includes a close button.
| Property | Type | Required | Description |
|---|---|---|---|
child | ComponentId | ✅ | Component shown inside the modal |
theme | Theme | Token overrides: bgRaised → modal panel background, textForeground → modal text |
Divider
Section titled “Divider”A horizontal or vertical separator line.
| Property | Type | Required | Description |
|---|---|---|---|
axis | string | horizontal (default) | vertical |
Spacer
Section titled “Spacer”An empty space for layout purposes.
| Property | Type | Required | Description |
|---|---|---|---|
width | DynamicString | Width (default '16px') | |
height | DynamicString | Height (default '16px') |
Display
Section titled “Display”Renders text content with Markdown support (bold, italic, links, inline code — no HTML, images, or headings inside Markdown). Heading variants (h1–h5) render as native heading elements.
| Property | Type | Required | Description |
|---|---|---|---|
text | DynamicString | ✅ | Text content |
variant | string | h1 | h2 | h3 | h4 | h5 | caption | body (default) | |
size | DynamicString | CSS font-size override (e.g. '12px', '1.2rem') | |
fontWeight | DynamicString | CSS font-weight override (e.g. 'bold', '500') | |
color | DynamicString | CSS color or semantic token name |
Displays a Material Symbols icon. The font is auto-injected on first render.
| Property | Type | Required | Description |
|---|---|---|---|
name | string | ✅ | Material Symbols name in camelCase (e.g. 'home', 'accountCircle'). Brand/social icons are not available. |
size | DynamicString | Semantic size (sm | md | lg | xl | 2xl | 3xl | 4xl) or CSS length (default lg) | |
color | DynamicString | CSS color or semantic token |
Displays an image from a URL (http/https only; invalid URLs show a placeholder).
| Property | Type | Required | Description |
|---|---|---|---|
url | DynamicString | ✅ | Image URL |
fit | string | CSS object-fit: contain (default) | cover | fill | none | scale-down | |
variant | string | icon | avatar | smallFeature | mediumFeature | largeFeature | header |
Plays a video. Set embed: true for YouTube and Vimeo URLs — the component detects the source and generates the correct embed URL automatically.
| Property | Type | Required | Description |
|---|---|---|---|
url | DynamicString | ✅ | Video URL |
embed | boolean | true for YouTube/Vimeo; false (default) for direct file URLs (.mp4, .webm) |
AudioPlayer
Section titled “AudioPlayer”Plays audio. Set embed: true for Spotify and SoundCloud URLs.
| Property | Type | Required | Description |
|---|---|---|---|
url | DynamicString | ✅ | Audio URL |
description | DynamicString | Title or summary shown above the player | |
embed | boolean | true for Spotify/SoundCloud; false (default) for direct file URLs (.mp3, .wav) |
Charts
Section titled “Charts”BarChart
Section titled “BarChart”Renders a bar chart. Supports vertical (default) and horizontal orientations.
| Property | Type | Required | Description |
|---|---|---|---|
data | array | DataBinding | ✅ | Array of { label, value, color? } objects |
title | DynamicString | Chart title | |
orientation | string | vertical (default) | horizontal | |
color | DynamicString | Default bar color (CSS) | |
showValues | DynamicBoolean | Show value labels on bars (default true) | |
chartHeight | DynamicNumber | Chart height in pixels (default 300) |
LineChart
Section titled “LineChart”Renders a line chart. Good for showing trends over time.
| Property | Type | Required | Description |
|---|---|---|---|
data | array | DataBinding | ✅ | Array of { label, value } objects (minimum 2 points) |
title | DynamicString | Chart title | |
color | DynamicString | Line color (default '#2563eb') | |
showDots | DynamicBoolean | Show data point circles (default true) | |
showArea | DynamicBoolean | Fill area under the line (default false) | |
chartHeight | DynamicNumber | Chart height in pixels (default 300) |
PieChart
Section titled “PieChart”Renders a pie or donut chart. Colors are auto-assigned if not provided per segment.
| Property | Type | Required | Description |
|---|---|---|---|
data | array | DataBinding | ✅ | Array of { label, value, color? } objects |
title | DynamicString | Chart title | |
donut | DynamicBoolean | Render as donut chart (default false) | |
size | DynamicNumber | Chart diameter in pixels (default 250) | |
align | string | Horizontal alignment: start (default) | center | end |
Sparkline
Section titled “Sparkline”A compact inline sparkline chart from an array of numbers. Use inside StatCard or alongside text.
| Property | Type | Required | Description |
|---|---|---|---|
values | number[] | DataBinding | ✅ | Numeric trend data (minimum 2 values) |
color | DynamicString | Line color (default '#2563eb') |
StatCard
Section titled “StatCard”A KPI summary card with a large value, label, and optional trend indicator. Use multiple StatCard components in a Row to build a dashboard header.
| Property | Type | Required | Description |
|---|---|---|---|
label | DynamicString | ✅ | Metric label (e.g. 'Total Revenue') |
value | DynamicString | ✅ | Formatted display value (e.g. '$12,340', '98%') |
trend | string | up | down | neutral | |
trendValue | DynamicString | Change text next to the arrow (e.g. '+12%') | |
trendColor | DynamicString | Color of the trend arrow | |
color | DynamicString | Accent color for the card’s left border | |
children | ChildList | Optional children below the stat value (e.g. a Sparkline) |
Button
Section titled “Button”A clickable button that triggers a server-side action or a local client-side function.
| Property | Type | Required | Description |
|---|---|---|---|
action | Action | ✅ | Server event or local function call |
label | DynamicString | Text label (used if child is not provided) | |
child | ComponentId | ID of a child component (e.g. an Icon) | |
variant | string | primary (default) | secondary | outline | borderless | danger | |
checks | CheckRule[] | Client-side validation — button is disabled if any check fails |
TextField
Section titled “TextField”A text input field.
| Property | Type | Required | Description |
|---|---|---|---|
placeholder | DynamicString | ✅ | Hint text shown inside the input when empty |
value | DynamicString | Data binding for the input value | |
label | DynamicString | Label shown above the input. Use in stacked Column forms; omit in inline Row forms. | |
variant | string | shortText (default) | longText | number | obscured | |
min | DynamicNumber | Minimum value (number variant only) | |
max | DynamicNumber | Maximum value (number variant only) | |
checks | CheckRule[] | Client-side validation rules |
CheckBox
Section titled “CheckBox”A checkbox toggle for boolean values.
| Property | Type | Required | Description |
|---|---|---|---|
label | DynamicString | ✅ | Label text |
value | DynamicBoolean | ✅ | Data binding for the checked state |
checks | CheckRule[] | Client-side validation rules |
ChoicePickerSingleSelect
Section titled “ChoicePickerSingleSelect”Selects exactly one option from a list.
| Property | Type | Required | Description |
|---|---|---|---|
options | array | DataBinding | ✅ | Array of { label, value } objects |
value | DynamicString | ✅ | Data binding for the selected value (string) |
label | DynamicString | Group label | |
variant | string | radio (default) | chips | |
checks | CheckRule[] | Client-side validation rules |
ChoicePickerMultiSelect
Section titled “ChoicePickerMultiSelect”Selects one or more options from a list.
| Property | Type | Required | Description |
|---|---|---|---|
options | array | DataBinding | ✅ | Array of { label, value } objects |
value | DynamicStringList | ✅ | Data binding for the selected values (string array) |
label | DynamicString | Group label | |
variant | string | checkbox (default) | chips | |
checks | CheckRule[] | Client-side validation rules |
Dropdown
Section titled “Dropdown”A select dropdown for choosing a single option.
| Property | Type | Required | Description |
|---|---|---|---|
options | array | DataBinding | ✅ | Array of { label, value } objects |
value | DynamicString | ✅ | Data binding for the selected value |
label | DynamicString | Label text | |
placeholder | DynamicString | Placeholder when no option is selected (default 'Select an option') | |
checks | CheckRule[] | Client-side validation rules |
DateInput
Section titled “DateInput”A date picker. Supports single date or date-range (from/to) selection. Emits ISO 8601 date strings with no time component. For time selection, use a TimeInput separately.
| Property | Type | Required | Description |
|---|---|---|---|
value | DynamicStringList | ✅ | Array of ISO 8601 date strings bound to the data model. Initialise to []. Single mode: ["YYYY-MM-DD"]. Range mode: ["YYYY-MM-DD", "YYYY-MM-DD"]. |
mode | string | single (default) | range | |
min | DynamicString | Earliest selectable date (ISO 8601) | |
max | DynamicString | Latest selectable date (ISO 8601) | |
label | DynamicString | Label text | |
checks | CheckRule[] | Client-side validation rules |
TimeInput
Section titled “TimeInput”A standalone time picker with hour/minute spinners. Use alongside a DateInput when you need separate date and time controls.
| Property | Type | Required | Description |
|---|---|---|---|
value | DynamicStringList | ✅ | Single-element array holding "HH:MM" in 24-hour format. Initialise to []. |
label | DynamicString | Label text | |
timeStep | number | DataBinding | Minute increment (default 1). Use 15 or 30 for slot-based selection. | |
timeFormat | string | DataBinding | 24h (default) | 12h | |
checks | CheckRule[] | Client-side validation rules |
Slider
Section titled “Slider”A slider for selecting a numeric value within a range. Supports multi-thumb for range selection.
| Property | Type | Required | Description |
|---|---|---|---|
value | DynamicNumber | number[] | ✅ | Single number for one thumb, or an array (e.g. [20, 80]) for multi-thumb range. |
min | number | ✅ | Minimum value |
max | number | ✅ | Maximum value |
step | number | Step increment (default 1) | |
label | DynamicString | Label text | |
checks | CheckRule[] | Client-side validation rules |
Component Theming
Section titled “Component Theming”Container components (Row, Column, Card, Modal, TabularGrid) accept a theme prop — a Theme object that overrides design tokens as CSS custom properties (--freesail-*) on the component’s root element, cascading to all descendants. This enables dynamic theme changes without recreating the surface.
Theme properties
Section titled “Theme properties”| Token | CSS variable | Description |
|---|---|---|
bg | --freesail-bg | Base surface background |
bgRaised | --freesail-bg-raised | Elevated surface background (Card raised variant) |
bgMuted | --freesail-bg-muted | Muted/subtle background |
textForeground | --freesail-text-foreground | Primary text colour |
textSecondary | --freesail-text-secondary | Secondary text colour |
primary | --freesail-primary | Brand accent (buttons, links) |
primaryHover | --freesail-primary-hover | Hover state for primary |
primaryForeground | --freesail-primary-foreground | Text on primary backgrounds |
border | --freesail-border | Borders and dividers |
All values are DynamicString — they accept CSS colour values, data bindings, or function calls.
Example: dark hero section
Section titled “Example: dark hero section”{ "id": "root", "component": "Row", "children": ["hero_content"], "theme": { "bg": "#1a2a4a", "textForeground": "#ffffff", "primary": "#60a5fa" }}Functions
Section titled “Functions”Validation
Section titled “Validation”| Function | Returns | Description |
|---|---|---|
required(value) | boolean | true if value is not null, undefined, empty string, or empty array |
email(value) | boolean | true if value is a valid email address |
regex(value, pattern) | boolean | true if value matches the regex pattern |
checkLength(value, { min?, max? }) | boolean | true if string/array length satisfies the constraints |
numeric(value, { min?, max? }) | boolean | true if numeric value satisfies the constraints |
Numeric
Section titled “Numeric”| Function | Returns | Description |
|---|---|---|
getLength(value) | number | Number of characters (string), elements (array), or 0 (null/undefined) |
Formatting
Section titled “Formatting”| Function | Returns | Description |
|---|---|---|
formatString(template, ...args) | string | Interpolates ${/path} and ${funcName()} expressions; also supports positional {0}, {1} placeholders |
formatNumber(value, fractionDigits?, useGrouping?) | string | Locale-aware number formatting |
formatCurrency(value, currency) | string | Formats a number as a currency string (e.g. '$1,234.56') |
formatDate(value, pattern) | string | Formats a date/time using a Unicode TR35 pattern |
pluralize(count, { zero?, one?, two?, few?, many?, other }) | string | Returns the CLDR-appropriate plural form |
now() | string | Current date and time as ISO 8601 |
| Function | Returns | Description |
|---|---|---|
and(...values) | boolean | true if all arguments are truthy |
or(...values) | boolean | true if any argument is truthy |
isEmpty(value) | boolean | true if null, undefined, empty string, empty array, or empty object |
Comparison
Section titled “Comparison”| Function | Returns | Description |
|---|---|---|
eq(a, b) | boolean | Strict equality |
neq(a, b) | boolean | Strict inequality |
gt(a, b) | boolean | a > b (numeric or date comparison) |
gte(a, b) | boolean | a >= b |
lt(a, b) | boolean | a < b |
lte(a, b) | boolean | a <= b |
UI Control
Section titled “UI Control”| Function | Returns | Description |
|---|---|---|
show(componentId) | void | Makes a component visible (writes to client-side __componentState) |
hide(componentId) | void | Makes a component invisible (writes to client-side __componentState) |
openUrl(url) | void | Opens a URL in a new browser tab (http/https only) |
formatDate Pattern Reference
Section titled “formatDate Pattern Reference”| Token | Example output |
|---|---|
yyyy | 2026 |
yy | 26 |
MMMM | January |
MMM | Jan |
MM | 01 |
M | 1 |
dd | 09 |
d | 9 |
EEEE | Tuesday |
E | Tue |
HH | 14 (24h) |
hh | 02 (12h) |
mm | 30 |
ss | 05 |
a | PM |
Semantic Color Tokens
Section titled “Semantic Color Tokens”Components that accept a color property support semantic token names in addition to CSS values:
| Token name | CSS variable | Usage |
|---|---|---|
textForeground | --freesail-text-foreground | Primary text colour |
textSecondary | --freesail-text-secondary | Secondary text colour |
primary | --freesail-primary | Brand accent |
primaryHover | --freesail-primary-hover | Hover state |
primaryForeground | --freesail-primary-foreground | Text on primary background |
error | --freesail-error | Error / danger |
success | --freesail-success | Success |
warning | --freesail-warning | Warning |
info | --freesail-info | Informational |
For background properties, these additional tokens are also available:
| Token name | CSS variable | Usage |
|---|---|---|
bg | --freesail-bg | Page/surface background |
bgRaised | --freesail-bg-raised | Card/panel background |
bgMuted | --freesail-bg-muted | Subtle background fills |
bgOverlay | --freesail-bg-overlay | Modal/dialog overlay backdrop |