@sonata-innovations/fiber-types 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +51 -0
- package/CHANGELOG.md +75 -0
- package/README.md +98 -0
- package/dist/flow-data.d.ts +3 -1
- package/dist/flow-data.d.ts.map +1 -1
- package/dist/flow.d.ts +1 -1
- package/dist/flow.d.ts.map +1 -1
- package/docs/fiber-concepts.md +461 -0
- package/docs/schema/flow-data-schema.json +256 -0
- package/docs/schema/flow-data-schema.md +371 -0
- package/docs/schema/flow-quick-reference.md +196 -0
- package/docs/schema/flow-schema.json +829 -0
- package/docs/schema/flow-schema.md +846 -0
- package/package.json +18 -10
|
@@ -0,0 +1,846 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Flow JSON Schema Reference
|
|
3
|
+
applies-to:
|
|
4
|
+
- "@sonata-innovations/fiber-types@^2.2"
|
|
5
|
+
read-when: "Exhaustive per-property reference for Flow JSON: every component type, property, condition, validation rule, calculation, and config field. For a compact overview use flow-quick-reference.md."
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
<!-- Generated from the Fiber repo's docs/ tree by project/scripts/sync-package-docs.mjs. Do not edit here. -->
|
|
9
|
+
# Fiber JSON Schema
|
|
10
|
+
|
|
11
|
+
> Canonical source: [`flow-schema.json`](flow-schema.json)
|
|
12
|
+
>
|
|
13
|
+
> **TypeScript shape**: as of `@sonata-innovations/fiber-types` v2, `Component` is a discriminated union keyed on `type` — `component.properties` narrows to the matching `Component*Properties` shape after a `type` check. The Flow JSON described here is unchanged.
|
|
14
|
+
|
|
15
|
+
The Flow JSON is the interchange format between FBT (the builder UI) and FBRE (the render engine). FBT authors it; FBRE consumes it and renders the form.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Flow (root)
|
|
20
|
+
|
|
21
|
+
| Field | Type | Required | Description |
|
|
22
|
+
| ---------- | --------------------------------------- | -------- | ------------------------------ |
|
|
23
|
+
| `uuid` | `string` | Yes | Unique identifier for the flow |
|
|
24
|
+
| `metadata` | [FlowMetadata](#flowmetadata) | Yes | Descriptive metadata |
|
|
25
|
+
| `config` | [FlowConfiguration](#flowconfiguration) | No | Runtime configuration |
|
|
26
|
+
| `screens` | [FlowScreen](#flowscreen)[] | Yes | Ordered list of screens |
|
|
27
|
+
| `calculations` | [FlowCalculation](#flowcalculation)[] | No | Top-level calculations |
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## FlowMetadata
|
|
32
|
+
|
|
33
|
+
Descriptive metadata for the flow. Accepts additional string properties beyond the ones listed.
|
|
34
|
+
|
|
35
|
+
| Field | Type | Required | Description |
|
|
36
|
+
| ------------- | -------- | -------- | ----------------------- |
|
|
37
|
+
| `name` | `string` | No | Name of the flow |
|
|
38
|
+
| `description` | `string` | No | Description of the flow |
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## FlowConfiguration
|
|
43
|
+
|
|
44
|
+
Runtime configuration for the flow, organized into semantic groups.
|
|
45
|
+
|
|
46
|
+
| Field | Type | Required | Description |
|
|
47
|
+
| ------------ | ------------------ | -------- | ------------------------------------ |
|
|
48
|
+
| `mode` | `FlowModeType` | No | Form presentation mode. See [Conversational Mode](#conversational-mode) |
|
|
49
|
+
| `theme` | `ThemeConfig` | No | Visual theme settings |
|
|
50
|
+
| `navigation` | `NavigationConfig` | No | Screen navigation settings |
|
|
51
|
+
| `controls` | `ControlsConfig` | No | Navigation controls settings |
|
|
52
|
+
| `summary` | `boolean` | No | Show a summary screen before completion |
|
|
53
|
+
| `confirmation` | `ConfirmationConfig` | No | Terminal thank-you screen shown after submission |
|
|
54
|
+
|
|
55
|
+
### ThemeConfig
|
|
56
|
+
|
|
57
|
+
The theme has two layers: `colorScheme` + `style` pick built-in presets (the seed palette and the shape), and the palette knobs override individual `--fbre-*` tokens on top. Any subset of knobs may be set; unset knobs fall through to the preset. Consumers needing finer control can still override the raw `--fbre-*` CSS custom properties directly.
|
|
58
|
+
|
|
59
|
+
| Field | Type | Required | Description |
|
|
60
|
+
| ------------ | --------------- | -------- | --------------------------------------------------------------------------- |
|
|
61
|
+
| `color` | `string` | No | Accent / primary color (`--fbre-theme-color`) |
|
|
62
|
+
| `colorScheme`| `"light" \| "dark"` | No | Built-in palette preset that seeds the token layer. Default `"light"`. Replaces the former `darkMode` boolean |
|
|
63
|
+
| `style` | `FlowStyleType` | No | Visual style for form elements. See [Style Types](#style-types) |
|
|
64
|
+
| `background` | `string` | No | Page/form ground (`--fbre-bg`) |
|
|
65
|
+
| `surface` | `string` | No | Raised surface: input fills, cards, popups (`--fbre-surface`) |
|
|
66
|
+
| `text` | `string` | No | Primary text color (`--fbre-text`); derives secondary/placeholder/label |
|
|
67
|
+
| `border` | `string` | No | Border/rule color (`--fbre-border`); derives hover/light/subtle |
|
|
68
|
+
| `radius` | `string` | No | Corner radius, any CSS length (`--fbre-radius`), e.g. `"3px"` |
|
|
69
|
+
| `fontFamily` | `string` | No | Font family stack (`--fbre-font`) |
|
|
70
|
+
| `error` | `string` | No | Error state color (`--fbre-error`) |
|
|
71
|
+
| `success` | `string` | No | Success state color (`--fbre-success`) |
|
|
72
|
+
| `warning` | `string` | No | Warning state color (`--fbre-warning`) |
|
|
73
|
+
|
|
74
|
+
#### Style Types
|
|
75
|
+
|
|
76
|
+
**Standard mode styles** (6):
|
|
77
|
+
|
|
78
|
+
| Value | Description |
|
|
79
|
+
| --- | --- |
|
|
80
|
+
| `"clean"` | Bottom-border inputs with uppercase labels (default) |
|
|
81
|
+
| `"outlined"` | Full-border inputs with normal-case labels |
|
|
82
|
+
| `"refined-clean"` | Animated underline focus with left-accent groups |
|
|
83
|
+
| `"airy-clean"` | Spacious layout with tinted focus and pill buttons |
|
|
84
|
+
| `"soft-outlined"` | Full-border 8px radius with shadow-ring focus |
|
|
85
|
+
| `"defined-outlined"` | Filled-background inputs with top-accent groups |
|
|
86
|
+
|
|
87
|
+
**Conversational mode styles** (4):
|
|
88
|
+
|
|
89
|
+
| Value | Description |
|
|
90
|
+
| --- | --- |
|
|
91
|
+
| `"centered-minimal"` | Thin underline inputs, 1px bordered option cards (6px radius), uppercase 12px labels, theme-tinted hover/selected |
|
|
92
|
+
| `"stacked-cards"` | Filled background cards with left accent bar, keyboard shortcut badges (A, B, C, D) on options |
|
|
93
|
+
| `"soft-float"` | Pill-shaped options (24px radius) with shadow lift on hover, rounded inputs and buttons |
|
|
94
|
+
| `"bold-statement"` | 2px borders, 700-weight 24px headers, inverted selection (dark fill + white text), filled input backgrounds |
|
|
95
|
+
|
|
96
|
+
Each style has a default stepper visual (see `stepperStyle`). When switching form mode in FBT, the style auto-switches to the first style of the target mode.
|
|
97
|
+
|
|
98
|
+
### NavigationConfig
|
|
99
|
+
|
|
100
|
+
| Field | Type | Required | Description |
|
|
101
|
+
| ------------------------ | ---------------------- | -------- | --------------------------------------------------------------------------- |
|
|
102
|
+
| `transition` | `ScreenTransitionType` | No | Screen transition animation type. See [Screen Transitions](#screen-transitions) |
|
|
103
|
+
| `allowInvalidTransition` | `boolean` | No | Allow navigating forward even when the screen has validation errors |
|
|
104
|
+
|
|
105
|
+
### ControlsConfig
|
|
106
|
+
|
|
107
|
+
| Field | Type | Required | Description |
|
|
108
|
+
| ------------ | -------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
109
|
+
| `show` | `boolean` | No | Show built-in next/back navigation buttons. Default `true` |
|
|
110
|
+
| `layout` | `"default"` \| `"centered"` \| `"inline-full"` \| `"stacked"` | No | Layout for the navigation controls. `"default"` = side-by-side grid (back-left / stepper-center / next-right); single-button rows collapse to full-width. `"centered"` = stepper row above, buttons centered as a group. `"inline-full"` = stepper row above, buttons side-by-side at 50% each (full-width when solo). `"stacked"` = stepper, Back, Next, all stacked full-width |
|
|
111
|
+
| `showStepper`| `boolean` | No | Show the step indicator dots in the controls bar. Default `true` |
|
|
112
|
+
| `stepperStyle`| `"default"` \| `"dots"` \| `"pill"` \| `"glow"` \| `"bar"` \| `"text"` | No | Style of the step indicator. `"default"` = use the form style's default stepper. `"dots"` = standard circles, scale on active. `"pill"` = active dot stretches to pill shape. `"glow"` = active dot gets a glow ring. `"bar"` = track + counter. `"text"` = "Step X of Y" above screen content. Default `"default"` |
|
|
113
|
+
|
|
114
|
+
### ConfirmationConfig
|
|
115
|
+
|
|
116
|
+
A terminal "thank you" screen shown after the flow is submitted (once `onFlowComplete` resolves). It is presentation-only — not a data-collection `Screen` — so it lives on the config. The screen renders only when `show` is not `false` **and** `title` or `body` has content. When shown, it replaces the final screen and the navigation controls/stepper are hidden.
|
|
117
|
+
|
|
118
|
+
`title` and `body` support the same `${...}` reference markup as display components — references resolve against collected field values, calculations, and external `context` values (by name). A parent application can also override the configured message at runtime by returning (or resolving with) a `{ title?, body? }` object from `onFlowComplete` — useful for post-submit data such as a server-generated reference number.
|
|
119
|
+
|
|
120
|
+
| Field | Type | Required | Description |
|
|
121
|
+
| ------- | --------- | -------- | ------------------------------------------------------------------ |
|
|
122
|
+
| `show` | `boolean` | No | Explicit off-switch. Content presence is the positive gate |
|
|
123
|
+
| `title` | `string` | No | Heading text. Supports `${...}` references and formatting |
|
|
124
|
+
| `body` | `string` | No | Body text. Supports `${...}` references and formatting |
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Conversational Mode
|
|
129
|
+
|
|
130
|
+
Set `config.mode` to `"conversational"` to transform FBRE into a one-question-per-screen experience optimized for completion rates.
|
|
131
|
+
|
|
132
|
+
**`FlowModeType`**: `"standard"` | `"conversational"` (default: `"standard"`)
|
|
133
|
+
|
|
134
|
+
### Behaviors
|
|
135
|
+
|
|
136
|
+
| Behavior | Description |
|
|
137
|
+
| --- | --- |
|
|
138
|
+
| **Vertical centering** | Content is vertically and horizontally centered within the viewport |
|
|
139
|
+
| **Auto-advance** | Single-select components (`radio`, `yesNo`, `cardSelect`, `dropDown`) advance to the next screen ~500ms after selection. Multi-select (`checkbox`, `dropDownMulti`) does NOT auto-advance |
|
|
140
|
+
| **Enter-to-advance** | Pressing Enter on `inputText` / `inputNumber` advances to the next screen. `inputTextArea` is excluded (Enter inserts newlines) |
|
|
141
|
+
| **Animated entry** | Components fade + scale in with staggered delays on screen transitions. Respects `prefers-reduced-motion` |
|
|
142
|
+
| **Larger tap targets** | Yes/No buttons, option items, card-select cards, and input fields are enlarged for easier tapping |
|
|
143
|
+
|
|
144
|
+
### Conversational styles
|
|
145
|
+
|
|
146
|
+
Conversational mode has 4 dedicated styles (separate from the 6 standard styles):
|
|
147
|
+
|
|
148
|
+
| Style | Personality |
|
|
149
|
+
| --- | --- |
|
|
150
|
+
| `centered-minimal` | Thin underline inputs, bordered option cards, uppercase labels, theme-tinted hover/selected |
|
|
151
|
+
| `stacked-cards` | Filled background cards with left accent bar, keyboard shortcut badges (A, B, C, D) on options |
|
|
152
|
+
| `soft-float` | Pill-shaped options with shadow lift on hover, rounded inputs and buttons |
|
|
153
|
+
| `bold-statement` | Heavy borders, bold typography, inverted selection (dark fill + white text) |
|
|
154
|
+
|
|
155
|
+
When switching to conversational mode in FBT, the style auto-switches to `"centered-minimal"` and the transition to `"scaleFade"`.
|
|
156
|
+
|
|
157
|
+
### Guards
|
|
158
|
+
|
|
159
|
+
- Auto-advance does **not** fire on the last screen
|
|
160
|
+
- Auto-advance does **not** fire if the screen fails validation
|
|
161
|
+
- Auto-advance respects condition-hidden screens (skips them)
|
|
162
|
+
- Auto-advance does **not** fire during an active transition
|
|
163
|
+
- Enter-to-advance validates the screen before advancing
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## FlowScreen
|
|
168
|
+
|
|
169
|
+
A single screen (page) in the flow.
|
|
170
|
+
|
|
171
|
+
| Field | Type | Required | Description |
|
|
172
|
+
| ----------------- | ------------------------------------------- | -------- | ---------------------------------------------------------------------------- |
|
|
173
|
+
| `uuid` | `string` | Yes | Unique identifier for the screen |
|
|
174
|
+
| `label` | `string` | No | Display label shown in navigation |
|
|
175
|
+
| `components` | [Component](#component)[] | Yes | Components on this screen |
|
|
176
|
+
| `conditions` | [FlowConditionConfig](#flowconditionconfig) | No | Condition for showing/hiding the screen |
|
|
177
|
+
| `nextButtonLabel` | `string` | No | Custom label for the Next/Done navigation button. Overrides the default text |
|
|
178
|
+
| `backButtonLabel` | `string` | No | Custom label for the Back navigation button. Overrides the default text |
|
|
179
|
+
| `valid` | `boolean` | No | _Runtime only._ Do not set in authored JSON |
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Component
|
|
184
|
+
|
|
185
|
+
A single form component. Components are recursive — `group` components contain child components.
|
|
186
|
+
|
|
187
|
+
| Field | Type | Required | Description |
|
|
188
|
+
| ----------------- | ------------------------------------------- | -------- | -------------------------------------------------------------- |
|
|
189
|
+
| `uuid` | `string` | Yes | Unique identifier for the component |
|
|
190
|
+
| `type` | `string` (enum — see [Component Types](#component-types)) | Yes | Component type key. In TypeScript, narrowing on this discriminator types `properties`. |
|
|
191
|
+
| `properties` | [ComponentProperties](#componentproperties) | Yes | Type-specific properties. TS-side: each `type` maps to a matching `Component*Properties` variant. |
|
|
192
|
+
| `conditions` | [FlowConditionConfig](#flowconditionconfig) | No | Condition for showing/hiding the component |
|
|
193
|
+
| `components` | [Component](#component)[] | No | Child component templates (used by `group` and `repeater`) |
|
|
194
|
+
| `value` | _any_ | No | _Runtime only._ Current value |
|
|
195
|
+
| `addedComponents` | [Component](#component)[][] | No | _Runtime only._ Group/repeater iterations. Do not set in authored JSON |
|
|
196
|
+
| `valid` | `boolean` | No | _Runtime only._ Do not set in authored JSON |
|
|
197
|
+
| `display` | `object` | No | _Runtime only._ Display overrides. Do not set in authored JSON |
|
|
198
|
+
|
|
199
|
+
### Component Types
|
|
200
|
+
|
|
201
|
+
| Type | Category | Description |
|
|
202
|
+
| --------------- | ----------- | ------------------------------------------------------------------------- |
|
|
203
|
+
| `header` | Display | Section heading |
|
|
204
|
+
| `text` | Display | Static text block |
|
|
205
|
+
| `divider` | Display | Visual separator with optional label |
|
|
206
|
+
| `callout` | Display | Styled alert/info box with variant coloring and optional icon |
|
|
207
|
+
| `table` | Display | Static comparison/data table with optional column highlighting |
|
|
208
|
+
| `inputText` | Input | Single-line text input |
|
|
209
|
+
| `inputTextArea` | Input | Multi-line text input |
|
|
210
|
+
| `inputNumber` | Input | Numeric input (supports optional decimal restriction and start adornment) |
|
|
211
|
+
| `dropDown` | Selection | Single-select dropdown |
|
|
212
|
+
| `dropDownMulti` | Selection | Multi-select dropdown |
|
|
213
|
+
| `checkbox` | Selection | Checkbox group |
|
|
214
|
+
| `radio` | Selection | Radio button group |
|
|
215
|
+
| `toggleSwitch` | Selection | Boolean toggle |
|
|
216
|
+
| `yesNo` | Selection | Two large tappable buttons for binary yes/no selection |
|
|
217
|
+
| `confirm` | Selection | Single checkbox for consent / opt-in (value is `true` when ticked, cleared when unticked) |
|
|
218
|
+
| `date` | Date & Time | Calendar popup date picker |
|
|
219
|
+
| `time` | Date & Time | Hour/minute/AM-PM time selector |
|
|
220
|
+
| `dateTime` | Date & Time | Combined calendar + time picker |
|
|
221
|
+
| `dateRange` | Date & Time | Two calendar pickers for start/end dates |
|
|
222
|
+
| `timeRange` | Date & Time | Two time selectors for start/end times |
|
|
223
|
+
| `dateTimeRange` | Date & Time | Two datetime pickers for start/end |
|
|
224
|
+
| `fileUpload` | Interactive | File upload |
|
|
225
|
+
| `rating` | Interactive | Star rating |
|
|
226
|
+
| `slider` | Interactive | Range slider |
|
|
227
|
+
| `colorPicker` | Interactive | Saturation/hue picker with hex input and optional swatches |
|
|
228
|
+
| `cardSelect` | Selection | Card-based single-select with optional price, features, and badge |
|
|
229
|
+
| `group` | Container | Groups child components visually (fieldset + condition grouping) |
|
|
230
|
+
| `repeater` | Container | Repeatable container — users can add/remove iterations of child components |
|
|
231
|
+
| `computed` | Computed | Displays a formula-evaluated result. Inside a repeater, evaluates per-iteration |
|
|
232
|
+
| `signature` | Interactive | Captures a hand-drawn or typed signature. Stores base64 PNG (draw) or text (type) |
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## ComponentProperties
|
|
237
|
+
|
|
238
|
+
Properties vary by component type. All fields are optional; which ones are relevant depends on the component `type`.
|
|
239
|
+
|
|
240
|
+
### Common Properties
|
|
241
|
+
|
|
242
|
+
| Field | Type | Applicable Types | Description |
|
|
243
|
+
| ------------- | ---------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
|
244
|
+
| `label` | `string` | All | Display label |
|
|
245
|
+
| `required` | `boolean` | All input/selection types | Field must have a value to pass validation |
|
|
246
|
+
| `placeholder` | `string` | Text inputs | Placeholder text when empty (dropdowns render a fixed built-in placeholder) |
|
|
247
|
+
| `helperText` | `string` | All input/selection types | Instructional text below the field |
|
|
248
|
+
| `tooltip` | `string` | All | Tooltip on hover/focus of info icon |
|
|
249
|
+
| `detail` | `string` | All | Rich text displayed above the component. Supports markup (`[b]`, `[i]`, `[l]`, `[s size="sm|lg|xl"]`). When set, hides the label unless `showLabel` is true |
|
|
250
|
+
| `width` | `ComponentWidth` | All | Component width for flow-based layout. See [Width](#width) |
|
|
251
|
+
|
|
252
|
+
### Display Component Properties
|
|
253
|
+
|
|
254
|
+
| Field | Type | Applicable Types | Description |
|
|
255
|
+
| ------------------ | ------------------------------------------------- | --------------------------- | ------------------------------------------------------------------ |
|
|
256
|
+
| `value` | `string` | `header`, `text`, `divider`, `callout` | Static content value (supports markup on text/callout) |
|
|
257
|
+
| `displayType` | `boolean` | `text` | When `true`, renders as display-only (no input) |
|
|
258
|
+
| `textAlign` | `"left"` \| `"center"` \| `"right"` | `divider` | Text alignment for the label |
|
|
259
|
+
| `title` | `string` | `callout` | Bold header text for the callout |
|
|
260
|
+
| `variant` | `"info"` \| `"success"` \| `"warning"` \| `"neutral"` | `callout` | Color scheme (default `"info"`) |
|
|
261
|
+
| `icon` | `string` | `callout` | Icon key: `info`, `check`, `warning`, `question`, `lightbulb`, `megaphone`, `bell`, `shield`, `lock`, `heart`, `flag`, `bookmark`, `zap`, `pencil`, `star`, or `none`. Falls back to variant default if omitted |
|
|
262
|
+
| `label` | `string` | `table` | Optional title displayed above the table |
|
|
263
|
+
| `columns` | `TableColumn[]` | `table` | Column definitions: `{ label: string }[]` |
|
|
264
|
+
| `rows` | `TableRow[]` | `table` | Row definitions: `{ label: string, values: string[] }[]` |
|
|
265
|
+
| `highlightColumn` | `integer` | `table` | 1-based column number to highlight (0 = none) |
|
|
266
|
+
|
|
267
|
+
### Computed Component Properties
|
|
268
|
+
|
|
269
|
+
| Field | Type | Description |
|
|
270
|
+
| ---------------- | -------------------------------------------- | -------------------------------------------------------------------------- |
|
|
271
|
+
| `label` | `string` | Display label for the computed value |
|
|
272
|
+
| `formula` | `string` | Formula expression. References fields via `{uuid}`, supports `+`, `-`, `*`, `/`, `SUM()`, `COUNT()`, `AVG()`, `MIN()`, `MAX()`, `IF()`, comparison operators, and `.selectedOption.metadata.key` |
|
|
273
|
+
| `format` | `"number"` \| `"currency"` \| `"percentage"` | Display format for the result (default `"number"`) |
|
|
274
|
+
| `decimalPlaces` | `integer` | Decimal places (0-10, default 2) |
|
|
275
|
+
| `currencySymbol` | `string` | Currency symbol when format is `"currency"` (default `"$"`) |
|
|
276
|
+
| `showLabel` | `boolean` | Whether to display the label (default `true`) |
|
|
277
|
+
| `detail` | `string` | Rich text description displayed above the computed value |
|
|
278
|
+
| `width` | `ComponentWidth` | Layout width |
|
|
279
|
+
|
|
280
|
+
Inside a repeater, formula references to sibling template UUIDs resolve to the current iteration's values. Aggregation functions (`SUM`, `COUNT`, `AVG`, `MIN`, `MAX`) still aggregate across all iterations. Outside a repeater, the computed component evaluates once using standard field resolution.
|
|
281
|
+
|
|
282
|
+
### Signature Properties
|
|
283
|
+
|
|
284
|
+
| Field | Type | Description |
|
|
285
|
+
| ----------- | -------------------------------------- | ------------------------------------------------------------------------------------ |
|
|
286
|
+
| `label` | `string` | Display label (default `"Signature"`) |
|
|
287
|
+
| `showLabel` | `boolean` | Whether to display the label |
|
|
288
|
+
| `detail` | `string` | Rich text description above the signature pad |
|
|
289
|
+
| `mode` | `"draw"` \| `"type"` \| `"both"` | Draw = canvas pad, Type = typed name in script font, Both = toggle between modes |
|
|
290
|
+
| `required` | `boolean` | Whether a signature is required |
|
|
291
|
+
| `width` | `ComponentWidth` | Layout width |
|
|
292
|
+
|
|
293
|
+
Draw mode stores the signature as a base64 PNG data URL. Type mode stores the typed name as a plain string.
|
|
294
|
+
|
|
295
|
+
### Text Input Properties
|
|
296
|
+
|
|
297
|
+
| Field | Type | Applicable Types | Description |
|
|
298
|
+
| -------------------- | ----------------------------------------------------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
|
|
299
|
+
| `regex` | `string` | `inputText`, `inputTextArea` | Regular expression for validation |
|
|
300
|
+
| `maxlength` | `integer` | `inputText`, `inputTextArea` | Maximum character length |
|
|
301
|
+
| `startAdornment` | `string` | `inputText`, `inputNumber` | Text/symbol at the start of the field (e.g. `$`, `+1`) |
|
|
302
|
+
| `decimalPlaces` | `integer` | `inputNumber` | When set, restricts input to a fixed number of decimal places (0-10). Uses controlled text input with keystroke filtering |
|
|
303
|
+
| `min` | `number` | `inputNumber` | Minimum allowed value. Sets HTML `min` attribute (constrains stepper arrows) and clamps value on blur |
|
|
304
|
+
| `max` | `number` | `inputNumber` | Maximum allowed value. Sets HTML `max` attribute (constrains stepper arrows) and clamps value on blur |
|
|
305
|
+
| `inputType` | `"text"` \| `"email"` \| `"tel"` \| `"url"` \| `"password"` | `inputText` | HTML input type hint. Controls mobile keyboard behavior and input masking. Default `"text"` |
|
|
306
|
+
| `readOnly` | `boolean` | `inputText`, `inputTextArea`, `inputNumber`, `dropDown`, `dropDownMulti`, `radio`, `checkbox`, `slider`, `date`, `time`, `dateTime` | When `true`, the field is non-editable with a muted background. Useful for locking pricing/values so users can see but not modify |
|
|
307
|
+
| `autocomplete` | `string` | `inputText`, `inputTextArea`, `inputNumber` | HTML `autocomplete` attribute value for browser autofill (e.g. `"email"`, `"tel"`, `"given-name"`) |
|
|
308
|
+
| `showPasswordToggle` | `boolean` | `inputText` | When `true` and `inputType` is `"password"`, shows an eye icon to toggle password visibility |
|
|
309
|
+
|
|
310
|
+
### Selection Component Properties
|
|
311
|
+
|
|
312
|
+
| Field | Type | Applicable Types | Description |
|
|
313
|
+
| -------------- | ----------------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
314
|
+
| `options` | [Option](#option)[] | `dropDown`, `dropDownMulti`, `checkbox`, `radio` | Available choices |
|
|
315
|
+
| `defaultValue` | `string` \| `"yes"` \| `"no"` | `yesNo`, `radio`, `cardSelect`, `dropDown` | Pre-selected option on first render. For `yesNo` use `"yes"` or `"no"`; for the others use the matching option `value`. Ignored when no option matches. Without a matching `defaultValue`, all of these start at `null` — there is no default-to-first-option behavior. |
|
|
316
|
+
|
|
317
|
+
### Slider Properties
|
|
318
|
+
|
|
319
|
+
| Field | Type | Description |
|
|
320
|
+
| ----------- | --------- | --------------- |
|
|
321
|
+
| `min` | `number` | Minimum value |
|
|
322
|
+
| `max` | `number` | Maximum value |
|
|
323
|
+
| `steps` | `number` | Step increment |
|
|
324
|
+
| `marks` | `boolean` | Show tick marks |
|
|
325
|
+
| `initValue` | `number` | Initial value |
|
|
326
|
+
|
|
327
|
+
### Rating Properties
|
|
328
|
+
|
|
329
|
+
| Field | Type | Description |
|
|
330
|
+
| ----------- | -------- | ----------------------------------------------------------------- |
|
|
331
|
+
| `max` | `number` | Maximum rating value |
|
|
332
|
+
| `precision` | `number` | Rating precision (e.g. `0.5` for half-stars, `1` for whole stars) |
|
|
333
|
+
| `icon` | `string` | Icon shape: `star`, `heart`, `thumbsUp`, `circle`, or `diamond` (default `"star"`) |
|
|
334
|
+
|
|
335
|
+
### File Upload Properties
|
|
336
|
+
|
|
337
|
+
| Field | Type | Description |
|
|
338
|
+
| --------- | --------- | ------------------------------------------------------- |
|
|
339
|
+
| `accept` | `string` | Comma-separated file extensions (e.g. `.pdf,.jpg,.png`) |
|
|
340
|
+
| `maxSize` | `integer` | Maximum file size in bytes |
|
|
341
|
+
|
|
342
|
+
### Group Properties
|
|
343
|
+
|
|
344
|
+
| Field | Type | Description |
|
|
345
|
+
| ------------- | --------- | ------------------------------------------------------------------------------------------------------------ |
|
|
346
|
+
| `showLabel` | `boolean` | Show the component label even when detail text is set. For groups, shows the group label as a visible header |
|
|
347
|
+
| `collapsible` | `boolean` | Allow the group to be collapsed/expanded |
|
|
348
|
+
| `showBorder` | `boolean` | Draw the container border/frame around the group |
|
|
349
|
+
|
|
350
|
+
### Repeater Properties
|
|
351
|
+
|
|
352
|
+
| Field | Type | Description |
|
|
353
|
+
| --------------- | --------- | --------------------------------------------------------------------------------------- |
|
|
354
|
+
| `showLabel` | `boolean` | Show the repeater label as a visible header |
|
|
355
|
+
| `collapsible` | `boolean` | Allow each iteration to be collapsed/expanded |
|
|
356
|
+
| `showBorder` | `boolean` | Draw the container border/frame around the repeater |
|
|
357
|
+
| `minIterations` | `integer` | Minimum number of rows (also initial count). Default `1`. Remove button hidden at minimum |
|
|
358
|
+
| `initialData` | `array` | Pre-populated data for rows. Each element maps template child UUIDs to initial values |
|
|
359
|
+
|
|
360
|
+
Repeaters are containers that support multiple iterations — users can add and remove rows of child components. Groups are purely visual containers (fieldset + condition grouping).
|
|
361
|
+
|
|
362
|
+
#### Nesting Rules
|
|
363
|
+
|
|
364
|
+
- Groups inside repeaters: allowed
|
|
365
|
+
- Repeaters inside groups: allowed
|
|
366
|
+
- Repeaters inside repeaters: **not** allowed
|
|
367
|
+
|
|
368
|
+
#### Migration
|
|
369
|
+
|
|
370
|
+
Legacy `group` components with `repeatable: true` must be migrated to `type: "repeater"` before loading.
|
|
371
|
+
|
|
372
|
+
### Date & Time Properties
|
|
373
|
+
|
|
374
|
+
| Field | Type | Applicable Types | Description |
|
|
375
|
+
| ------------------ | ------------ | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
376
|
+
| `placeholder` | `string` | `date`, `time`, `dateTime` | Placeholder text when empty |
|
|
377
|
+
| `placeholderStart` | `string` | `dateRange`, `timeRange`, `dateTimeRange` | Placeholder text for the start field |
|
|
378
|
+
| `placeholderEnd` | `string` | `dateRange`, `timeRange`, `dateTimeRange` | Placeholder text for the end field |
|
|
379
|
+
| `min` | `string` | All date/time types | Minimum allowed value. Accepts ISO date (`YYYY-MM-DD`), relative expression (`today`, `today+7`, `today-3`), or time (`HH:MM`) |
|
|
380
|
+
| `max` | `string` | All date/time types | Maximum allowed value. Same formats as `min` |
|
|
381
|
+
| `dateFormat` | `DateFormat` | `date`, `dateTime`, `dateRange`, `dateTimeRange` | Display format for dates. See [Date Format](#date-format). Default `"MM/DD/YYYY"` |
|
|
382
|
+
| `minTime` | `string` | `dateTime`, `dateTimeRange` | Minimum allowed time (`HH:MM`, 24h). Enforced independently from `min` date |
|
|
383
|
+
| `maxTime` | `string` | `dateTime`, `dateTimeRange` | Maximum allowed time (`HH:MM`, 24h). Enforced independently from `max` date |
|
|
384
|
+
| `step` | `number` | `time`, `dateTime`, `timeRange`, `dateTimeRange` | Minute interval for time selection. Default `15` |
|
|
385
|
+
|
|
386
|
+
#### Date Format
|
|
387
|
+
|
|
388
|
+
| Value | Example |
|
|
389
|
+
| -------------- | ---------------------- |
|
|
390
|
+
| `"MM/DD/YYYY"` | `02/17/2026` (default) |
|
|
391
|
+
| `"DD/MM/YYYY"` | `17/02/2026` |
|
|
392
|
+
| `"YYYY-MM-DD"` | `2026-02-17` |
|
|
393
|
+
|
|
394
|
+
#### Relative Date Constraints
|
|
395
|
+
|
|
396
|
+
The `min` and `max` properties on date-containing types accept relative expressions:
|
|
397
|
+
|
|
398
|
+
| Expression | Meaning |
|
|
399
|
+
| ----------- | ------------------------------------------------------- |
|
|
400
|
+
| `"today"` | Today's date |
|
|
401
|
+
| `"today+N"` | N days from today (e.g. `"today+14"` = two weeks ahead) |
|
|
402
|
+
| `"today-N"` | N days before today (e.g. `"today-7"` = one week ago) |
|
|
403
|
+
|
|
404
|
+
Fixed ISO dates (e.g. `"2026-01-01"`) continue to work as before. Relative expressions are resolved at render time in FBRE.
|
|
405
|
+
|
|
406
|
+
#### Value Formats
|
|
407
|
+
|
|
408
|
+
| Type | Value Format | Example |
|
|
409
|
+
| --------------- | -------------------- | ------------------------------------------------------------ |
|
|
410
|
+
| `date` | `"YYYY-MM-DD"` | `"2026-02-17"` |
|
|
411
|
+
| `time` | `"HH:MM"` (24h) | `"14:30"` |
|
|
412
|
+
| `dateTime` | `"YYYY-MM-DDTHH:MM"` | `"2026-02-17T14:30"` |
|
|
413
|
+
| `dateRange` | `{ start, end }` | `{ "start": "2026-02-17", "end": "2026-02-20" }` |
|
|
414
|
+
| `timeRange` | `{ start, end }` | `{ "start": "09:00", "end": "17:00" }` |
|
|
415
|
+
| `dateTimeRange` | `{ start, end }` | `{ "start": "2026-02-17T09:00", "end": "2026-02-20T17:00" }` |
|
|
416
|
+
|
|
417
|
+
### Yes/No Properties
|
|
418
|
+
|
|
419
|
+
| Field | Type | Description |
|
|
420
|
+
| ---------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
421
|
+
| `labelYes` | `string` | Custom label for the "Yes" button. Default `"Yes"` |
|
|
422
|
+
| `labelNo` | `string` | Custom label for the "No" button. Default `"No"` |
|
|
423
|
+
| `layout` | `string` | Button layout direction: `"horizontal"` (side-by-side) or `"vertical"` (stacked). Omit for responsive default (adapts to width) |
|
|
424
|
+
|
|
425
|
+
Value is `"yes"` or `"no"` (string).
|
|
426
|
+
|
|
427
|
+
### Color Picker Properties
|
|
428
|
+
|
|
429
|
+
| Field | Type | Description |
|
|
430
|
+
| -------------- | ---------- | ----------------------------------------------------------------- |
|
|
431
|
+
| `swatches` | `string[]` | Preset color swatches (hex format, e.g. `["#FF0000", "#00FF00"]`) |
|
|
432
|
+
| `defaultValue` | `string` | Default color value (hex format, e.g. `"#1976d2"`) |
|
|
433
|
+
|
|
434
|
+
Value is a hex color string (e.g. `"#FF5733"`).
|
|
435
|
+
|
|
436
|
+
### Card Select Properties
|
|
437
|
+
|
|
438
|
+
| Field | Type | Description |
|
|
439
|
+
| --------- | --------------------------------------- | ----------------------------------------------- |
|
|
440
|
+
| `options` | [CardSelectOption](#cardselectoption)[] | Array of card options to display |
|
|
441
|
+
| `columns` | `integer` | Number of columns in the card grid. Default `2` |
|
|
442
|
+
|
|
443
|
+
Value is the `value` string of the selected card option.
|
|
444
|
+
|
|
445
|
+
#### CardSelectOption
|
|
446
|
+
|
|
447
|
+
| Field | Type | Required | Description |
|
|
448
|
+
| ------------- | ---------- | -------- | ------------------------------------------------------------ |
|
|
449
|
+
| `label` | `string` | Yes | Display title for the card |
|
|
450
|
+
| `value` | `string` | Yes | Value stored when selected |
|
|
451
|
+
| `description` | `string` | No | Short description below the title |
|
|
452
|
+
| `title` | `string` | No | Heading text displayed prominently on the card |
|
|
453
|
+
| `features` | `string[]` | No | Feature strings displayed as a checklist |
|
|
454
|
+
| `badge` | `string` | No | Badge text shown as a pill above the card (e.g. `"Popular"`) |
|
|
455
|
+
| `metadata` | `object` | No | Arbitrary key-value pairs for calculations |
|
|
456
|
+
|
|
457
|
+
#### Card Select Example
|
|
458
|
+
|
|
459
|
+
```json
|
|
460
|
+
{
|
|
461
|
+
"type": "cardSelect",
|
|
462
|
+
"properties": {
|
|
463
|
+
"label": "Plan",
|
|
464
|
+
"showLabel": false,
|
|
465
|
+
"options": [
|
|
466
|
+
{
|
|
467
|
+
"label": "Pro",
|
|
468
|
+
"value": "pro",
|
|
469
|
+
"title": "$29/mo",
|
|
470
|
+
"features": ["20 flows", "1,000 submissions/mo"]
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
"label": "Business",
|
|
474
|
+
"value": "business",
|
|
475
|
+
"title": "$79/mo",
|
|
476
|
+
"badge": "Popular",
|
|
477
|
+
"features": ["100 flows", "5,000 submissions/mo"]
|
|
478
|
+
}
|
|
479
|
+
]
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
---
|
|
485
|
+
|
|
486
|
+
## Option
|
|
487
|
+
|
|
488
|
+
A selectable option used by `dropDown`, `dropDownMulti`, `checkbox`, and `radio` components.
|
|
489
|
+
|
|
490
|
+
| Field | Type | Required | Description |
|
|
491
|
+
| ---------- | --------------------------------------------- | -------- | --------------------------------------------------------------------------------------------- |
|
|
492
|
+
| `label` | `string` | Yes | Display text |
|
|
493
|
+
| `value` | `string` \| `number` | Yes | Value stored when selected |
|
|
494
|
+
| `metadata` | `Record<string, string \| number \| boolean>` | No | Structured key-value metadata (e.g. price, weight, unit). Consumed by the calculations engine |
|
|
495
|
+
|
|
496
|
+
### Option Metadata Example
|
|
497
|
+
|
|
498
|
+
```json
|
|
499
|
+
{
|
|
500
|
+
"type": "dropDown",
|
|
501
|
+
"properties": {
|
|
502
|
+
"label": "Material",
|
|
503
|
+
"options": [
|
|
504
|
+
{
|
|
505
|
+
"label": "Standard Steel",
|
|
506
|
+
"value": "steel",
|
|
507
|
+
"metadata": { "pricePerUnit": 12.50, "unit": "sqft" }
|
|
508
|
+
},
|
|
509
|
+
{
|
|
510
|
+
"label": "Premium Aluminum",
|
|
511
|
+
"value": "aluminum",
|
|
512
|
+
"metadata": { "pricePerUnit": 24.00, "unit": "sqft" }
|
|
513
|
+
}
|
|
514
|
+
]
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
---
|
|
520
|
+
|
|
521
|
+
## Width
|
|
522
|
+
|
|
523
|
+
Components use a flow-based layout system where each component declares its own width. Components flow left-to-right and wrap naturally, like words in a paragraph. This works at both the screen level and inside groups.
|
|
524
|
+
|
|
525
|
+
### ComponentWidth
|
|
526
|
+
|
|
527
|
+
| Value | CSS Width | Description |
|
|
528
|
+
| ------------------ | --------- | --------------------------------- |
|
|
529
|
+
| `"full"` | `100%` | Full width (default when omitted) |
|
|
530
|
+
| `"three-quarters"` | `75%` | Three quarters width |
|
|
531
|
+
| `"two-thirds"` | `66.67%` | Two thirds width |
|
|
532
|
+
| `"half"` | `50%` | Half width |
|
|
533
|
+
| `"third"` | `33.33%` | One third width |
|
|
534
|
+
| `"quarter"` | `25%` | Quarter width |
|
|
535
|
+
|
|
536
|
+
### Width Example
|
|
537
|
+
|
|
538
|
+
```json
|
|
539
|
+
{
|
|
540
|
+
"type": "group",
|
|
541
|
+
"properties": { "label": "Name" },
|
|
542
|
+
"components": [
|
|
543
|
+
{
|
|
544
|
+
"type": "inputText",
|
|
545
|
+
"properties": { "label": "First Name", "width": "half" }
|
|
546
|
+
},
|
|
547
|
+
{
|
|
548
|
+
"type": "inputText",
|
|
549
|
+
"properties": { "label": "Last Name", "width": "half" }
|
|
550
|
+
}
|
|
551
|
+
]
|
|
552
|
+
}
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
### Migration
|
|
556
|
+
|
|
557
|
+
Legacy group `layout` strings (e.g. `"2: 50,50"`) must be migrated to per-child `width` values before loading. The `layout` property is no longer supported.
|
|
558
|
+
|
|
559
|
+
---
|
|
560
|
+
|
|
561
|
+
## Validation
|
|
562
|
+
|
|
563
|
+
Components can have validation rules defined in `properties.validation`. This replaces the legacy `required` and `regex` flat properties. Legacy formats must be migrated before loading.
|
|
564
|
+
|
|
565
|
+
### FlowValidationConfig
|
|
566
|
+
|
|
567
|
+
| Field | Type | Required | Description |
|
|
568
|
+
| ------- | ----------------------------------- | -------- | -------------------------------- |
|
|
569
|
+
| `rules` | [ValidationRule](#validationrule)[] | Yes | Ordered list of validation rules |
|
|
570
|
+
|
|
571
|
+
### ValidationRule
|
|
572
|
+
|
|
573
|
+
| Field | Type | Required | Description |
|
|
574
|
+
| --------- | -------- | -------- | --------------------------------------------------------------- |
|
|
575
|
+
| `type` | `string` | Yes | Rule type (see [Validation Rule Types](#validation-rule-types)) |
|
|
576
|
+
| `params` | `object` | No | Type-specific parameters |
|
|
577
|
+
| `message` | `string` | No | Custom error message (default message used when omitted) |
|
|
578
|
+
|
|
579
|
+
### Validation Rule Types
|
|
580
|
+
|
|
581
|
+
| Type | Params | Default Message | Applicable Types |
|
|
582
|
+
| -------------- | --------------------- | ------------------------------------------ | ------------------------------------------- |
|
|
583
|
+
| `required` | — | "This field is required" | All input/selection types |
|
|
584
|
+
| `email` | — | "Please enter a valid email address" | `inputText` |
|
|
585
|
+
| `phone` | — | "Please enter a valid phone number" | `inputText` |
|
|
586
|
+
| `url` | — | "Please enter a valid URL" | `inputText` |
|
|
587
|
+
| `minLength` | `{ min: number }` | "Must be at least N characters" | `inputText`, `inputTextArea` |
|
|
588
|
+
| `maxLength` | `{ max: number }` | "Must be no more than N characters" | `inputText`, `inputTextArea` |
|
|
589
|
+
| `exactLength` | `{ length: number }` | "Must be exactly N characters" | `inputText`, `inputTextArea` |
|
|
590
|
+
| `minValue` | `{ min: number }` | "Must be at least N" | `inputNumber` |
|
|
591
|
+
| `maxValue` | `{ max: number }` | "Must be no more than N" | `inputNumber` |
|
|
592
|
+
| `pattern` | `{ regex: string }` | "Value does not match the required format" | `inputText`, `inputTextArea` |
|
|
593
|
+
| `minSelected` | `{ min: number }` | "Select at least N options" | `dropDownMulti`, `checkbox` |
|
|
594
|
+
| `maxSelected` | `{ max: number }` | "Select no more than N options" | `dropDownMulti`, `checkbox` |
|
|
595
|
+
| `fileType` | `{ types: string[] }` | "File type is not allowed" | `fileUpload` |
|
|
596
|
+
| `fileSize` | `{ max: number }` | "File must be smaller than N" | `fileUpload` |
|
|
597
|
+
| `contains` | `{ text: string }` | "Must contain \"text\"" | `inputText`, `inputTextArea` |
|
|
598
|
+
| `excludes` | `{ text: string }` | "Must not contain \"text\"" | `inputText`, `inputTextArea` |
|
|
599
|
+
| `matchesField` | `{ field: string }` | "Fields must match" | `inputText`, `inputTextArea`, `inputNumber` |
|
|
600
|
+
|
|
601
|
+
### Validation Example
|
|
602
|
+
|
|
603
|
+
```json
|
|
604
|
+
{
|
|
605
|
+
"validation": {
|
|
606
|
+
"rules": [
|
|
607
|
+
{ "type": "required" },
|
|
608
|
+
{ "type": "email" },
|
|
609
|
+
{
|
|
610
|
+
"type": "minLength",
|
|
611
|
+
"params": { "min": 5 },
|
|
612
|
+
"message": "Email must be at least 5 characters"
|
|
613
|
+
}
|
|
614
|
+
]
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
### Error Display
|
|
620
|
+
|
|
621
|
+
When validation fails, the first failing error message is shown below the field. If multiple rules fail, an "(and N more)" indicator is appended.
|
|
622
|
+
|
|
623
|
+
### Migration
|
|
624
|
+
|
|
625
|
+
Legacy `required` and `regex` properties must be migrated to `FlowValidationConfig` before loading.:
|
|
626
|
+
|
|
627
|
+
- `{ required: true }` → `{ validation: { rules: [{ type: "required" }] } }`
|
|
628
|
+
- `{ regex: "..." }` → `{ validation: { rules: [{ type: "pattern", params: { regex: "..." } }] } }`
|
|
629
|
+
|
|
630
|
+
---
|
|
631
|
+
|
|
632
|
+
## Screen Transitions
|
|
633
|
+
|
|
634
|
+
Animated transitions between screens can be enabled via `config.navigation.transition`. When absent or set to `"none"`, screen changes are instant (zero overhead).
|
|
635
|
+
|
|
636
|
+
### ScreenTransitionType
|
|
637
|
+
|
|
638
|
+
| Value | Effect | Direction-aware? |
|
|
639
|
+
| ------------- | ---------------------------------- | ---------------- |
|
|
640
|
+
| `"none"` | Instant swap (default) | — |
|
|
641
|
+
| `"slide"` | Full horizontal slide left/right | Yes |
|
|
642
|
+
| `"fade"` | Crossfade between screens | No |
|
|
643
|
+
| `"slideFade"` | 30px horizontal slide with opacity | Yes |
|
|
644
|
+
| `"rise"` | Vertical rise up / sink down | Yes |
|
|
645
|
+
| `"scaleFade"` | Scale 0.95→1 / 1→1.05 with opacity | No |
|
|
646
|
+
|
|
647
|
+
Direction-aware transitions reverse their animation when navigating backward.
|
|
648
|
+
|
|
649
|
+
### Example
|
|
650
|
+
|
|
651
|
+
```json
|
|
652
|
+
{
|
|
653
|
+
"config": {
|
|
654
|
+
"navigation": { "transition": "slideFade" }
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
### CSS Custom Properties
|
|
660
|
+
|
|
661
|
+
| Property | Default | Description |
|
|
662
|
+
| ---------------------------- | ------------------------------ | ---------------------- |
|
|
663
|
+
| `--fbre-transition-duration` | `250ms` | Animation duration |
|
|
664
|
+
| `--fbre-transition-easing` | `cubic-bezier(0.4, 0, 0.2, 1)` | Animation easing curve |
|
|
665
|
+
|
|
666
|
+
`@media (prefers-reduced-motion: reduce)` sets the duration to `0ms` automatically.
|
|
667
|
+
|
|
668
|
+
---
|
|
669
|
+
|
|
670
|
+
## Conditions
|
|
671
|
+
|
|
672
|
+
Conditions allow components and screens to be shown or hidden based on the runtime value of other components.
|
|
673
|
+
|
|
674
|
+
### FlowConditionConfig
|
|
675
|
+
|
|
676
|
+
| Field | Type | Required | Description |
|
|
677
|
+
| -------- | --------------------------------- | -------- | ----------------------------------------------------------------------- |
|
|
678
|
+
| `action` | `"show"` \| `"hide"` | Yes | `show` = visible when condition met; `hide` = hidden when condition met |
|
|
679
|
+
| `when` | [ConditionGroup](#conditiongroup) | Yes | The condition group to evaluate |
|
|
680
|
+
|
|
681
|
+
### ConditionGroup
|
|
682
|
+
|
|
683
|
+
| Field | Type | Required | Description |
|
|
684
|
+
| ------- | --------------------------------- | -------- | ----------------------------------------------------- |
|
|
685
|
+
| `logic` | `"and"` \| `"or"` | Yes | `and` = all rules must match; `or` = any rule matches |
|
|
686
|
+
| `rules` | [ConditionRule](#conditionrule)[] | Yes | One or more rules (minimum 1) |
|
|
687
|
+
|
|
688
|
+
### ConditionRule
|
|
689
|
+
|
|
690
|
+
| Field | Type | Required | Description |
|
|
691
|
+
| ------------ | ------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
|
692
|
+
| `source` | `string` | Yes | UUID of the source component, or a context key when `sourceType` is `"context"` |
|
|
693
|
+
| `sourceType` | `"component"` \| `"context"` | No | Where to resolve the source. `"component"` (default) looks up a component UUID. `"context"` looks up a key in FBRE's `context` prop |
|
|
694
|
+
| `operator` | `string` | Yes | Comparison operator (see [Operators](#operators)) |
|
|
695
|
+
| `value` | `string` \| `number` \| `boolean` \| `string[]` \| `number[]` | No | Comparison value. Omitted for unary operators |
|
|
696
|
+
|
|
697
|
+
#### External Context Conditions
|
|
698
|
+
|
|
699
|
+
When `sourceType` is `"context"`, the rule evaluates against a value from FBRE's `context` prop rather than a component UUID. This allows conditions based on external application state.
|
|
700
|
+
|
|
701
|
+
```jsx
|
|
702
|
+
<FBRE
|
|
703
|
+
flow={flow}
|
|
704
|
+
context={{ isInvite: true, userTier: "pro" }}
|
|
705
|
+
onFlowComplete={handleComplete}
|
|
706
|
+
/>
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
```json
|
|
710
|
+
{
|
|
711
|
+
"conditions": {
|
|
712
|
+
"action": "hide",
|
|
713
|
+
"when": {
|
|
714
|
+
"logic": "and",
|
|
715
|
+
"rules": [
|
|
716
|
+
{ "source": "isInvite", "sourceType": "context", "operator": "isTrue" }
|
|
717
|
+
]
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
### Operators
|
|
724
|
+
|
|
725
|
+
| Operator | Category | Expects Value | Description |
|
|
726
|
+
| -------------------- | -------- | ------------- | --------------------------------------------------------- |
|
|
727
|
+
| `equals` | Equality | Yes | Exact match |
|
|
728
|
+
| `notEquals` | Equality | Yes | Not an exact match |
|
|
729
|
+
| `contains` | String | Yes | Source contains the value substring |
|
|
730
|
+
| `notContains` | String | Yes | Source does not contain the value substring |
|
|
731
|
+
| `startsWith` | String | Yes | Source starts with the value |
|
|
732
|
+
| `endsWith` | String | Yes | Source ends with the value |
|
|
733
|
+
| `isEmpty` | Presence | No | Source has no value |
|
|
734
|
+
| `isNotEmpty` | Presence | No | Source has a value |
|
|
735
|
+
| `greaterThan` | Numeric | Yes | Source > value |
|
|
736
|
+
| `greaterThanOrEqual` | Numeric | Yes | Source >= value |
|
|
737
|
+
| `lessThan` | Numeric | Yes | Source < value |
|
|
738
|
+
| `lessThanOrEqual` | Numeric | Yes | Source <= value |
|
|
739
|
+
| `isOneOf` | Set | Yes (array) | Source value is in the provided array |
|
|
740
|
+
| `isNotOneOf` | Set | Yes (array) | Source value is not in the provided array |
|
|
741
|
+
| `includesAny` | Set | Yes (array) | Source (multi-value) includes any of the provided values |
|
|
742
|
+
| `includesAll` | Set | Yes (array) | Source (multi-value) includes all of the provided values |
|
|
743
|
+
| `includesNone` | Set | Yes (array) | Source (multi-value) includes none of the provided values |
|
|
744
|
+
| `isTrue` | Boolean | No | Source is truthy |
|
|
745
|
+
| `isFalse` | Boolean | No | Source is falsy |
|
|
746
|
+
|
|
747
|
+
---
|
|
748
|
+
|
|
749
|
+
## FlowCalculation
|
|
750
|
+
|
|
751
|
+
Top-level calculations are global formulas not tied to any screen. They compute values reactively from component inputs, option metadata, and other calculations.
|
|
752
|
+
|
|
753
|
+
| Field | Type | Required | Description |
|
|
754
|
+
| ---------------- | ------------------- | -------- | -------------------------------------------------------------- |
|
|
755
|
+
| `uuid` | `string` | Yes | Unique identifier for the calculation |
|
|
756
|
+
| `label` | `string` | Yes | Human-readable label |
|
|
757
|
+
| `formula` | `string` | Yes | Formula expression (see syntax below) |
|
|
758
|
+
| `format` | `CalculationFormat` | No | Display format: `"number"`, `"currency"`, or `"percentage"` |
|
|
759
|
+
| `decimalPlaces` | `integer` | No | Number of decimal places (0–10) |
|
|
760
|
+
| `currencySymbol` | `string` | No | Currency symbol when format is `"currency"` (defaults to `$`) |
|
|
761
|
+
|
|
762
|
+
### Formula Syntax
|
|
763
|
+
|
|
764
|
+
| Syntax | Description |
|
|
765
|
+
| --------------------------------------------- | --------------------------------------------------------------- |
|
|
766
|
+
| `{uuid}` | Component value reference |
|
|
767
|
+
| `{uuid}.selectedOption.metadata.key` | Selected option's metadata value |
|
|
768
|
+
| `SUM({uuid})` | Sum across repeater iterations |
|
|
769
|
+
| `COUNT({uuid})` | Count of repeater iterations |
|
|
770
|
+
| `AVG({uuid})` | Average across repeater iterations |
|
|
771
|
+
| `MIN({uuid})` | Minimum across repeater iterations |
|
|
772
|
+
| `MAX({uuid})` | Maximum across repeater iterations |
|
|
773
|
+
| `MIN(expr, expr, ...)` | Scalar minimum of N expressions (e.g. discount capping) |
|
|
774
|
+
| `MAX(expr, expr, ...)` | Scalar maximum of N expressions (e.g. minimum charge) |
|
|
775
|
+
| `IF(cond, then, else)` | Conditional — returns `then` when `cond != 0`, else `else` |
|
|
776
|
+
| `> < >= <= == !=` | Comparison operators (return `1` for true, `0` for false) |
|
|
777
|
+
| `+ - * /` | Arithmetic operators |
|
|
778
|
+
| `( )` | Grouping / precedence |
|
|
779
|
+
| Numeric literals | Constants (e.g. `0.08`, `100`) |
|
|
780
|
+
|
|
781
|
+
Formulas return `null` when any referenced field is empty or unresolvable. Calculations can reference other calculations by UUID; evaluation follows topological order.
|
|
782
|
+
|
|
783
|
+
### Example
|
|
784
|
+
|
|
785
|
+
```json
|
|
786
|
+
{
|
|
787
|
+
"calculations": [
|
|
788
|
+
{
|
|
789
|
+
"uuid": "calc-subtotal",
|
|
790
|
+
"label": "Subtotal",
|
|
791
|
+
"formula": "SUM({line-total-uuid})",
|
|
792
|
+
"format": "currency",
|
|
793
|
+
"decimalPlaces": 2,
|
|
794
|
+
"currencySymbol": "$"
|
|
795
|
+
},
|
|
796
|
+
{
|
|
797
|
+
"uuid": "calc-tax",
|
|
798
|
+
"label": "Tax Amount",
|
|
799
|
+
"formula": "{calc-subtotal} * 0.08",
|
|
800
|
+
"format": "currency",
|
|
801
|
+
"decimalPlaces": 2,
|
|
802
|
+
"currencySymbol": "$"
|
|
803
|
+
}
|
|
804
|
+
]
|
|
805
|
+
}
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
---
|
|
809
|
+
|
|
810
|
+
## Reference Markup
|
|
811
|
+
|
|
812
|
+
Text properties can include `${...}` references that resolve at render time. Resolution tries, in order: calculation results, component values, then keys from FBRE's `context` prop. References are replaced with the resolved value when the form is displayed.
|
|
813
|
+
|
|
814
|
+
### Syntax
|
|
815
|
+
|
|
816
|
+
| Pattern | Resolves To | Example |
|
|
817
|
+
| --- | --- | --- |
|
|
818
|
+
| `${calculation-uuid}` | Formatted calculation result | `${calc-456}` → `"$1,247.50"` |
|
|
819
|
+
| `${component-uuid}` | Component's current value | `${abc-123}` → `"John Smith"` |
|
|
820
|
+
| `${context-key}` | Value from the FBRE `context` prop | `${accountName}` → `"Acme Inc."` |
|
|
821
|
+
|
|
822
|
+
### Supported Surfaces
|
|
823
|
+
|
|
824
|
+
References are supported in the following component properties:
|
|
825
|
+
|
|
826
|
+
| Surface | Property | Resolution |
|
|
827
|
+
| --- | --- | --- |
|
|
828
|
+
| Display Text | `value` | HTML (within markup) |
|
|
829
|
+
| Header | `value` | Plain text |
|
|
830
|
+
| Callout | `title`, `value` | title: plain text, value: HTML |
|
|
831
|
+
| Field labels | `label` | Plain text |
|
|
832
|
+
| Field descriptions | `detail` | HTML (within markup) |
|
|
833
|
+
| Helper text | `helperText` | Plain text |
|
|
834
|
+
| Placeholders | `placeholder` | Plain text |
|
|
835
|
+
| Screen labels | `label` | Plain text |
|
|
836
|
+
|
|
837
|
+
### Example
|
|
838
|
+
|
|
839
|
+
```json
|
|
840
|
+
{
|
|
841
|
+
"type": "text",
|
|
842
|
+
"properties": {
|
|
843
|
+
"value": "Your total is ${calc-total} for ${service-type-uuid} service."
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
```
|