@sonata-innovations/fiber-types 2.3.0 → 3.0.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.
@@ -1,10 +1,12 @@
1
1
  ---
2
2
  title: Fiber Concepts
3
3
  applies-to:
4
- - "@sonata-innovations/fiber-types@^2.2"
5
- - "@sonata-innovations/fiber-fbre@^3.3"
6
- - "@sonata-innovations/fiber-fbt@^2.2"
7
- - "@sonata-innovations/fiber-fbtl@^2.2"
4
+ - "@sonata-innovations/fiber-types@^3.0"
5
+ - "@sonata-innovations/fiber-shared@^1.2"
6
+ - "@sonata-innovations/fiber-fbre@^4.0"
7
+ - "@sonata-innovations/fiber-fbt@^3.0"
8
+ - "@sonata-innovations/fiber-fbtl@^3.0"
9
+ - "@sonata-innovations/fiber-theme-editor@^2.0"
8
10
  read-when: "First contact with Fiber: the Flow/Screen/Component model, FlowData, builders vs render engine, conditions/validation/calculations concepts."
9
11
  ---
10
12
 
@@ -22,7 +24,7 @@ read-when: "First contact with Fiber: the Flow/Screen/Component model, FlowData,
22
24
  Fiber is a system for building and rendering data-collection forms. It splits authoring from rendering and offers two authoring surfaces targeted at different audiences:
23
25
 
24
26
  - **FBT (Fiber Tool)** — A visual drag-and-drop builder for power users / form designers. Full feature surface: screens, multi-rule conditions, validation, calculations, reference markup, the complete 30-type component palette. See the [FBT integration guide](@sonata-innovations/fiber-fbt/docs/integration/fbt.md).
25
- - **FBTL (Fiber Tool Lite)** — A stripped-down, end-user-friendly builder designed to be embedded in parent apps so non-technical end users (clinicians, teachers, etc.) can author their own forms. Five question types + Information Screens + single-rule conditions. Preserves advanced properties from loaded flows without editing them. See the [FBTL integration guide](@sonata-innovations/fiber-fbtl/docs/integration/fbtl.md).
27
+ - **FBTL (Fiber Tool Lite)** — A stripped-down, end-user-friendly builder designed to be embedded in parent apps so non-technical end users (clinicians, teachers, etc.) can author their own forms. Seven question types + Information Screens + single-rule conditions. Preserves advanced properties from loaded flows without editing them. See the [FBTL integration guide](@sonata-innovations/fiber-fbtl/docs/integration/fbtl.md).
26
28
  - **FBRE (Fiber Render Engine)** — A render engine that consumes Flow JSON, renders the interactive form for end users, and outputs collected data ("FlowData") back to the parent application. See the [FBRE integration guide](@sonata-innovations/fiber-fbre/docs/integration/fbre.md).
27
29
 
28
30
  A fourth library, the **Theme Editor**, is a plug-and-play widget that lets end users visually customize a flow's theme (color scheme, style, palette knobs) and emits the resulting `ThemeConfig`. See the [Theme Editor integration guide](@sonata-innovations/fiber-theme-editor/docs/integration/theme-editor.md).
@@ -87,15 +89,16 @@ The optional `config` object controls runtime behavior, organized into semantic
87
89
 
88
90
  | Group | Setting | Purpose |
89
91
  |-------|---------|---------|
90
- | _(flat)_ | `mode` | Presentation mode: `"standard"` (default) or `"conversational"` (one question at a time) |
91
92
  | `theme` | `color` | Primary accent color (CSS value) |
92
93
  | `theme` | `colorScheme` | Built-in palette preset: `"light"` (default) or `"dark"` (replaces the former `darkMode` boolean) |
93
94
  | `theme` | `style` | Visual style (`"clean"`, `"outlined"`, …) |
94
95
  | `theme` | `background` / `surface` / `text` / `border` | Palette knobs overriding the preset tokens |
95
- | `theme` | `radius` / `fontFamily` | Corner radius and font family knobs |
96
+ | `theme` | `radius` / `fontFamily` | Corner radius and font family knobs. `fontFamily` also accepts `{ family, src }`, which FBRE loads itself rather than assuming the host page already has the font |
96
97
  | `theme` | `error` / `success` / `warning` | Semantic state color knobs |
97
98
  | `navigation` | `transition` | Screen transition animation type |
98
99
  | `navigation` | `allowInvalidTransition` | Allow navigating past screens with validation errors |
100
+ | `navigation` | `autoAdvance` | Advance ~500ms after a single-select choice (default off) |
101
+ | `navigation` | `advanceOnEnter` | Advance on Enter in a single-line input (default on) |
99
102
  | `controls` | `show` | Show/hide built-in next/back buttons |
100
103
  | `controls` | `layout` | Controls layout (`"default"`, `"centered"`, `"inline-full"`, or `"stacked"`) |
101
104
  | `controls` | `showStepper` | Show/hide the step indicator |
@@ -291,11 +294,11 @@ The formula engine lives in `@sonata-innovations/fiber-shared`, so calculations
291
294
  ### Authoring Phase (FBT or FBTL)
292
295
 
293
296
  1. A form author opens **FBT** (power users) or **FBTL** (non-technical end users) in a parent application
294
- 2. They assemble the flow — FBT via multi-screen drag-and-drop with the full component palette; FBTL via a flat, one-question-per-screen list limited to five question types plus Information Screens
297
+ 2. They assemble the flow — FBT via multi-screen drag-and-drop with the full component palette; FBTL via a flat, one-question-per-screen list limited to seven question types plus Information Screens
295
298
  3. The builder produces a Flow JSON object via the `onFlowChange` callback (FBT also exposes `exportFlow()` on the store)
296
299
  4. The parent application saves the Flow JSON (to a database, file, API, etc.)
297
300
 
298
- FBTL emits a flow with one component per screen (conversational mode) and promotes component-level conditions to screen-level conditions on emit. Loading a multi-screen flow into FBTL flattens it into the one-per-screen shape on the next save, while preserving all advanced properties (calculations, reference markup, multi-rule conditions, etc.) that FBTL itself cannot edit. The resulting JSON remains fully interoperable with FBT.
301
+ FBTL uses a **page-break model**: each stage card carries a break-after flag, so a freshly authored flow is one question per screen until the author merges cards onto a shared screen. Screen structure round-trips a loaded multi-screen flow's boundaries become break flags rather than being flattened away — and the host can switch the builder to a single-screen model entirely (`options.screenModel`). A component-level condition is promoted to a screen-level condition only when its screen ends up holding exactly one component; otherwise it stays on the component as an in-place show/hide. Advanced properties FBTL cannot edit (calculations, reference markup, multi-rule conditions, and so on) are preserved untouched, and the resulting JSON remains fully interoperable with FBT.
299
302
 
300
303
  ### Rendering Phase (FBRE)
301
304
 
@@ -386,6 +389,8 @@ The markup → HTML converter lives in `@sonata-innovations/fiber-shared`, share
386
389
 
387
390
  `${...}` tokens interpolate live values into text. A token is resolved in order against: **calculations** (by UUID) → **component values** (by UUID) → **context** (by key, from FBRE's `context` prop). Unresolvable references render as empty. This powers dynamic text like "Your total is ${calc-uuid}" or "Welcome back, ${userName}".
388
391
 
392
+ Writing one means knowing a UUID, so builders offer a picker. `resolvableReferences(flow)` from `@sonata-innovations/fiber-shared` returns every reference a flow can resolve, in that same order — use it rather than re-walking the flow, so a picker cannot drift from what the renderer will actually resolve. See [Confirmation Screen → Building your own picker](@sonata-innovations/fiber-fbre/docs/features/confirmation-screen.md#building-your-own-picker).
393
+
389
394
  ---
390
395
 
391
396
  ## 11. Extension Points
@@ -406,7 +411,7 @@ A template is likewise data — a `TemplateData` object (`{ type, label, icon, f
406
411
 
407
412
  Presets and templates being plain data (rather than code) is what enables server-side storage: the hosted platform stores tenant-scoped custom presets and templates in the database and serves them to FBT at load time. Older factory-function definitions (functions returning fresh `Component`/`Flow` objects) are still accepted for back-compat, but data-based definitions are the current model.
408
413
 
409
- See [`custom-presets-and-templates.md`](@sonata-innovations/fiber-fbt/docs/features/custom-presets-and-templates.md) for the full authoring guide.
414
+ See [`custom-presets-and-templates.md`](features/custom-presets-and-templates.md) for the full authoring guide.
410
415
 
411
416
  ---
412
417
 
@@ -448,9 +453,17 @@ FBRE accepts a flow through one of three mutually exclusive prop shapes:
448
453
  2. **Remote flow** — `<FBRE flowId="..." apiEndpoint="..." />`. FBRE fetches a published flow from a Fiber server and renders it client-side. All evaluation (conditions, validation, calculations) still happens in the browser.
449
454
  3. **Server-driven** — `<FBRE flowId="..." sessionEndpoint="..." />`. FBRE starts a session and receives one screen at a time; the server evaluates conditions and validation between screens (using the same `fiber-shared` engines) and assembles the final FlowData. The full flow definition never reaches the client — useful for sensitive branching logic and server-side integrations between screens.
450
455
 
451
- ### Conversational Mode
456
+ ### Style Families
457
+
458
+ `theme.style` is one flat vocabulary of ten values, but four of them — `centered-minimal`, `stacked-cards`, `soft-float`, `bold-statement` — share a presentation treatment: a vertically centered narrow column, staggered component entry, enlarged tap targets and bolder type. That shared half is the **focused** family; the other six are the **form** family.
459
+
460
+ The family is derived from the style, never authored — it does not appear in Flow JSON. FBRE emits it as `data-style-family`, and `fiber-types` exports `styleFamily()` / `FOCUSED_STYLES` for builders grouping a style picker. Because it derives from `theme.style`, the presentation travels with the theme through every render path, server-driven included.
461
+
462
+ A focused style is a *look*. Pacing — how many questions land on a screen — is a property of the flow's structure (see FBTL's `screenModel`), and the two advance behaviors below are separate `navigation` flags. FBTL authors focused-styled flows by default.
463
+
464
+ ### Advance Behaviors
452
465
 
453
- Setting `config.mode: "conversational"` (or the FBRE `mode` prop) renders the flow one question at a time in a chat-like presentation instead of the standard screen-per-page layout. Same Flow JSON, same condition/validation/FlowData behavioronly the presentation changes. FBTL authors flows in this shape by default.
466
+ `navigation.autoAdvance` (default `false`) advances ~500ms after a single-select choice; `navigation.advanceOnEnter` (default `true`) advances when Enter is pressed in a single-line input. Both only ever fire on a screen with exactly one visible input, never on the last screen, and never on an invalid screen. Neither is tied to a stylea `clean` form with one question per screen advances on Enter just like a focused one.
454
467
 
455
468
  ### Confirmation Screen
456
469
 
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  title: FlowData Schema
3
3
  applies-to:
4
- - "@sonata-innovations/fiber-types@^2.2"
5
- - "@sonata-innovations/fiber-fbre@^3.3"
4
+ - "@sonata-innovations/fiber-types@^3.0"
5
+ - "@sonata-innovations/fiber-fbre@^4.0"
6
6
  read-when: "Consuming FlowData output from FBRE: structure, per-type value shapes, exclusion rules, containers, calculations."
7
7
  ---
8
8
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: Flow JSON Quick Reference
3
3
  applies-to:
4
- - "@sonata-innovations/fiber-types@^2.2"
4
+ - "@sonata-innovations/fiber-types@^3.0"
5
5
  read-when: "Constructing or interpreting Flow JSON: structure, component types and value types, options, conditions, validation, widths, inline markup. For exhaustive per-property detail, use flow-schema.md instead."
6
6
  ---
7
7
 
@@ -36,9 +36,8 @@ Flow
36
36
 
37
37
  | Field | Type | Default | Description |
38
38
  |-------|------|---------|-------------|
39
- | `mode` | `FlowModeType` | `"standard"` | `"standard"` or `"conversational"` conversational mode centers content, auto-advances on selection, and Enter-advances on text inputs |
40
- | `theme` | `ThemeConfig` | — | `{ color?, colorScheme?, style?, background?, surface?, text?, border?, radius?, fontFamily?, error?, success?, warning? }` visual theme settings (palette knobs + preset) |
41
- | `navigation` | `NavigationConfig` | — | `{ transition?, allowInvalidTransition? }` — screen navigation settings |
39
+ | `theme` | `ThemeConfig` | | `{ color?, colorScheme?, style?, background?, surface?, text?, border?, radius?, fontFamily?, error?, success?, warning? }` visual theme settings (palette knobs + preset). `fontFamily` is a CSS stack string **or** `{ family, src }` for a font FBRE loads itself |
40
+ | `navigation` | `NavigationConfig` | — | `{ transition?, allowInvalidTransition?, autoAdvance?, advanceOnEnter? }` screen navigation settings. `autoAdvance` (default `false`) advances ~500ms after a single-select choice; `advanceOnEnter` (default `true`) advances on Enter in a single-line input. Both only fire on a screen with exactly one visible input |
42
41
  | `controls` | `ControlsConfig` | — | `{ show?, layout?, showStepper?, stepperStyle? }` — navigation controls settings |
43
42
  | `confirmation` | `ConfirmationConfig` | — | `{ show?, title?, body? }` — terminal thank-you screen (see [Confirmation Screen](@sonata-innovations/fiber-fbre/docs/integration/fbre.md#confirmation-screen)) |
44
43
  | `summary` | `boolean` | `false` | Show summary screen before completion |
@@ -70,8 +70,11 @@
70
70
  "description": "Corner radius as a CSS length (--fbre-radius), e.g. '3px'."
71
71
  },
72
72
  "fontFamily": {
73
- "type": "string",
74
- "description": "Font family stack (--fbre-font)."
73
+ "description": "Font family (--fbre-font). A plain CSS stack string uses whatever font the host page already provides; an object additionally carries the sources FBRE registers itself via ensureFontLoaded, which is what makes a brand font work inside a shadow root.",
74
+ "oneOf": [
75
+ { "type": "string" },
76
+ { "$ref": "#/$defs/FontFamilyConfig" }
77
+ ]
75
78
  },
76
79
  "error": {
77
80
  "type": "string",
@@ -87,12 +90,79 @@
87
90
  },
88
91
  "style": {
89
92
  "type": "string",
90
- "description": "Visual style for form elements. Standard mode styles: 'clean' = bottom-border inputs with uppercase labels (default). 'outlined' = full-border inputs with normal-case labels. 'refined-clean' = animated underline focus with left-accent groups. 'airy-clean' = spacious layout with tinted focus and pill buttons. 'soft-outlined' = full-border 8px radius with shadow-ring focus. 'defined-outlined' = filled-background inputs with top-accent groups. Conversational mode styles: 'centered-minimal' = thin underline inputs, bordered option cards, uppercase labels. 'stacked-cards' = filled background cards with left accent, keyboard shortcut badges. 'soft-float' = pill-shaped options with shadow lift on hover. 'bold-statement' = heavy borders, bold typography, inverted selection. Each style has a default stepper visual (see stepperStyle).",
93
+ "description": "Visual style for form elements. One flat vocabulary of ten, in two families. Form family: 'clean' = bottom-border inputs with uppercase labels (default). 'outlined' = full-border inputs with normal-case labels. 'refined-clean' = animated underline focus with left-accent groups. 'airy-clean' = spacious layout with tinted focus and pill buttons. 'soft-outlined' = full-border 8px radius with shadow-ring focus. 'defined-outlined' = filled-background inputs with top-accent groups. Focused family (adds vertical centering, staggered component entry, enlarged tap targets and bolder type): 'centered-minimal' = thin underline inputs, bordered option cards, uppercase labels. 'stacked-cards' = filled background cards with left accent, keyboard shortcut badges. 'soft-float' = pill-shaped options with shadow lift on hover. 'bold-statement' = heavy borders, bold typography, inverted selection. Each style has a default stepper visual (see stepperStyle).",
91
94
  "enum": ["clean", "outlined", "refined-clean", "airy-clean", "soft-outlined", "defined-outlined", "centered-minimal", "stacked-cards", "soft-float", "bold-statement"]
92
95
  }
93
96
  }
94
97
  },
95
98
 
99
+ "FontSource": {
100
+ "type": "object",
101
+ "additionalProperties": false,
102
+ "required": ["url"],
103
+ "properties": {
104
+ "url": {
105
+ "type": "string",
106
+ "description": "Where the font file is served from."
107
+ },
108
+ "format": {
109
+ "type": "string",
110
+ "description": "CSS format() hint, e.g. 'woff2'."
111
+ }
112
+ }
113
+ },
114
+ "FontFaceConfig": {
115
+ "type": "object",
116
+ "description": "One @font-face — a single weight/style of the family.",
117
+ "additionalProperties": false,
118
+ "required": ["src"],
119
+ "properties": {
120
+ "src": {
121
+ "type": "array",
122
+ "items": { "$ref": "#/$defs/FontSource" },
123
+ "minItems": 1
124
+ },
125
+ "weight": {
126
+ "type": "string",
127
+ "description": "CSS font-weight: '400', '700', or a variable range like '100 900'."
128
+ },
129
+ "style": {
130
+ "type": "string",
131
+ "enum": ["normal", "italic", "oblique"]
132
+ },
133
+ "display": {
134
+ "type": "string",
135
+ "enum": ["auto", "block", "swap", "fallback", "optional"]
136
+ },
137
+ "unicodeRange": { "type": "string" }
138
+ }
139
+ },
140
+ "FontFamilyConfig": {
141
+ "type": "object",
142
+ "description": "A brand font the renderer can load, rather than a family name it can only hope the host page already has.",
143
+ "additionalProperties": false,
144
+ "required": ["family"],
145
+ "properties": {
146
+ "family": {
147
+ "type": "string",
148
+ "description": "CSS family name, used for both the @font-face and the token value."
149
+ },
150
+ "src": {
151
+ "type": "array",
152
+ "items": { "$ref": "#/$defs/FontSource" },
153
+ "description": "Shorthand for a single regular face. Merged with faces."
154
+ },
155
+ "faces": {
156
+ "type": "array",
157
+ "items": { "$ref": "#/$defs/FontFaceConfig" },
158
+ "description": "Additional faces — a second weight, an italic."
159
+ },
160
+ "stack": {
161
+ "type": "string",
162
+ "description": "Full CSS stack written to --fbre-font. Defaults to the family plus a system fallback."
163
+ }
164
+ }
165
+ },
96
166
  "NavigationConfig": {
97
167
  "type": "object",
98
168
  "description": "Screen navigation settings.",
@@ -105,6 +175,14 @@
105
175
  "allowInvalidTransition": {
106
176
  "type": "boolean",
107
177
  "description": "Allow navigating forward even when the screen has validation errors."
178
+ },
179
+ "autoAdvance": {
180
+ "type": "boolean",
181
+ "description": "Advance to the next screen ~500ms after a single-select choice (radio, yesNo, cardSelect, dropDown). Default false. Only fires on a screen with exactly one visible input."
182
+ },
183
+ "advanceOnEnter": {
184
+ "type": "boolean",
185
+ "description": "Advance to the next screen when Enter is pressed in a single-line input (inputText, inputNumber). Default true. Never fires in a textarea, inside an open popup, on the last screen, on an invalid screen, or on a screen with more than one visible input."
108
186
  }
109
187
  }
110
188
  },
@@ -136,7 +214,7 @@
136
214
 
137
215
  "ConfirmationConfig": {
138
216
  "type": "object",
139
- "description": "Terminal 'thank you' / confirmation screen shown after the flow is submitted. Presentation-only, so it lives on the config rather than as a Screen. Renders only when 'show' is not false and 'title' or 'body' has content (or the parent supplies an override via the onFlowComplete return value).",
217
+ "description": "Terminal 'thank you' / confirmation screen shown after the flow is submitted. Presentation-only, so it lives on the config rather than as a Screen. In local and remote modes it renders only when 'show' is not false and 'title' or 'body' has content (or the parent supplies an override via the onFlowComplete return value); server-driven mode falls back to a generic 'Thank you' when nothing is configured. An explicit 'show': false renders nothing in every mode.",
140
218
  "properties": {
141
219
  "show": {
142
220
  "type": "boolean",
@@ -157,11 +235,6 @@
157
235
  "type": "object",
158
236
  "description": "Runtime configuration for the flow.",
159
237
  "properties": {
160
- "mode": {
161
- "type": "string",
162
- "description": "Form presentation mode. 'standard' = multi-field screens (default). 'conversational' = one-question-per-screen, vertically centered, with auto-advance on selection, Enter-to-advance on text inputs, and animated component entry.",
163
- "enum": ["standard", "conversational"]
164
- },
165
238
  "theme": { "$ref": "#/$defs/ThemeConfig" },
166
239
  "navigation": { "$ref": "#/$defs/NavigationConfig" },
167
240
  "controls": { "$ref": "#/$defs/ControlsConfig" },
@@ -250,7 +323,7 @@
250
323
  ]
251
324
  },
252
325
  "properties": {
253
- "description": "Type-specific properties. JSON schema is the open ComponentProperties shape below; TypeScript narrows it per-type via the variant map in fiber-types/src/component-variants.ts.",
326
+ "description": "Type-specific properties. JSON schema is the open ComponentProperties shape below; TypeScript narrows it per-type via the variant map in types/src/component-variants.ts.",
254
327
  "$ref": "#/$defs/ComponentProperties"
255
328
  },
256
329
  "conditions": { "$ref": "#/$defs/FlowConditionConfig" },
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: Flow JSON Schema Reference
3
3
  applies-to:
4
- - "@sonata-innovations/fiber-types@^2.2"
4
+ - "@sonata-innovations/fiber-types@^3.0"
5
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
6
  ---
7
7
 
@@ -45,7 +45,6 @@ Runtime configuration for the flow, organized into semantic groups.
45
45
 
46
46
  | Field | Type | Required | Description |
47
47
  | ------------ | ------------------ | -------- | ------------------------------------ |
48
- | `mode` | `FlowModeType` | No | Form presentation mode. See [Conversational Mode](#conversational-mode) |
49
48
  | `theme` | `ThemeConfig` | No | Visual theme settings |
50
49
  | `navigation` | `NavigationConfig` | No | Screen navigation settings |
51
50
  | `controls` | `ControlsConfig` | No | Navigation controls settings |
@@ -66,14 +65,45 @@ The theme has two layers: `colorScheme` + `style` pick built-in presets (the see
66
65
  | `text` | `string` | No | Primary text color (`--fbre-text`); derives secondary/placeholder/label |
67
66
  | `border` | `string` | No | Border/rule color (`--fbre-border`); derives hover/light/subtle |
68
67
  | `radius` | `string` | No | Corner radius, any CSS length (`--fbre-radius`), e.g. `"3px"` |
69
- | `fontFamily` | `string` | No | Font family stack (`--fbre-font`) |
68
+ | `fontFamily` | `string \| FontFamilyConfig` | No | Font family (`--fbre-font`). See [FontFamilyConfig](#fontfamilyconfig) |
70
69
  | `error` | `string` | No | Error state color (`--fbre-error`) |
71
70
  | `success` | `string` | No | Success state color (`--fbre-success`) |
72
71
  | `warning` | `string` | No | Warning state color (`--fbre-warning`) |
73
72
 
73
+ #### FontFamilyConfig
74
+
75
+ A plain string is a CSS stack and nothing more: the form renders in that family only if the host page already loaded it, and falls back to `system-ui` otherwise — silently, and to something that looks approximately fine. Passing an object instead gives the renderer the sources, and FBRE registers the faces in the owning document itself.
76
+
77
+ That matters most where the host cannot patch around it. FBRE is designed to mount inside a shadow root, and `@font-face` rules declared inside a shadow root's stylesheet are never registered — faces resolve at document level only.
78
+
79
+ | Field | Type | Required | Description |
80
+ | -------- | ------------------ | -------- | ------------------------------------------------------------------ |
81
+ | `family` | `string` | Yes | CSS family name, used for both the `@font-face` and the token value |
82
+ | `src` | `FontSource[]` | No | Shorthand for a single regular face. Merged with `faces` |
83
+ | `faces` | `FontFaceConfig[]` | No | Additional faces — a second weight, an italic |
84
+ | `stack` | `string` | No | Full stack written to `--fbre-font`. Defaults to the family plus a system fallback |
85
+
86
+ `FontSource` is `{ url, format? }`; `FontFaceConfig` is `{ src, weight?, style?, display?, unicodeRange? }`.
87
+
88
+ ```json
89
+ {
90
+ "fontFamily": {
91
+ "family": "Brand Sans",
92
+ "src": [{ "url": "https://cdn.example.com/brand.woff2", "format": "woff2" }],
93
+ "faces": [
94
+ { "src": [{ "url": "https://cdn.example.com/brand-bold.woff2", "format": "woff2" }], "weight": "700" }
95
+ ]
96
+ }
97
+ }
98
+ ```
99
+
100
+ See [FBRE Theming Guide → Loading a brand font](@sonata-innovations/fiber-fbre/docs/features/fbre-theming.md#loading-a-brand-font).
101
+
74
102
  #### Style Types
75
103
 
76
- **Standard mode styles** (6):
104
+ Ten values, one flat vocabulary. Any style may be used on any flow.
105
+
106
+ **Form family** (6):
77
107
 
78
108
  | Value | Description |
79
109
  | --- | --- |
@@ -84,7 +114,7 @@ The theme has two layers: `colorScheme` + `style` pick built-in presets (the see
84
114
  | `"soft-outlined"` | Full-border 8px radius with shadow-ring focus |
85
115
  | `"defined-outlined"` | Filled-background inputs with top-accent groups |
86
116
 
87
- **Conversational mode styles** (4):
117
+ **Focused family** (4):
88
118
 
89
119
  | Value | Description |
90
120
  | --- | --- |
@@ -93,7 +123,9 @@ The theme has two layers: `colorScheme` + `style` pick built-in presets (the see
93
123
  | `"soft-float"` | Pill-shaped options (24px radius) with shadow lift on hover, rounded inputs and buttons |
94
124
  | `"bold-statement"` | 2px borders, 700-weight 24px headers, inverted selection (dark fill + white text), filled input backgrounds |
95
125
 
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.
126
+ The four focused styles additionally share a presentation treatment vertical centering, a narrow column, staggered component entry, enlarged tap targets and bolder type. That shared half is the **focused family**; see [Style Families](#style-families).
127
+
128
+ Each style has a default stepper visual (see `stepperStyle`).
97
129
 
98
130
  ### NavigationConfig
99
131
 
@@ -101,6 +133,8 @@ Each style has a default stepper visual (see `stepperStyle`). When switching for
101
133
  | ------------------------ | ---------------------- | -------- | --------------------------------------------------------------------------- |
102
134
  | `transition` | `ScreenTransitionType` | No | Screen transition animation type. See [Screen Transitions](#screen-transitions) |
103
135
  | `allowInvalidTransition` | `boolean` | No | Allow navigating forward even when the screen has validation errors |
136
+ | `autoAdvance` | `boolean` | No | Advance ~500ms after a single-select choice. Default `false`. See [Advance Behaviors](#advance-behaviors) |
137
+ | `advanceOnEnter` | `boolean` | No | Advance when Enter is pressed in a single-line input. Default `true`. See [Advance Behaviors](#advance-behaviors) |
104
138
 
105
139
  ### ControlsConfig
106
140
 
@@ -113,7 +147,7 @@ Each style has a default stepper visual (see `stepperStyle`). When switching for
113
147
 
114
148
  ### ConfirmationConfig
115
149
 
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.
150
+ 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. In local and remote modes the screen renders only when `show` is not `false` **and** `title` or `body` has content; server-driven mode falls back to a generic "Thank you" when nothing is configured, and renders nothing on an explicit `show: false` (see [Per-mode behavior](@sonata-innovations/fiber-fbre/docs/features/confirmation-screen.md#per-mode-behavior)). When shown, it replaces the final screen and the navigation controls/stepper are hidden.
117
151
 
118
152
  `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
153
 
@@ -125,42 +159,71 @@ A terminal "thank you" screen shown after the flow is submitted (once `onFlowCom
125
159
 
126
160
  ---
127
161
 
128
- ## Conversational Mode
162
+ ## Style Families
129
163
 
130
- Set `config.mode` to `"conversational"` to transform FBRE into a one-question-per-screen experience optimized for completion rates.
164
+ The ten `FlowStyleType` values are a flat vocabulary any style is valid on any
165
+ flow — but four of them share a presentation treatment. That shared half is a
166
+ **family**, derived from the style itself:
131
167
 
132
- **`FlowModeType`**: `"standard"` | `"conversational"` (default: `"standard"`)
168
+ | Family | Styles |
169
+ | --- | --- |
170
+ | `"form"` | `clean`, `outlined`, `refined-clean`, `airy-clean`, `soft-outlined`, `defined-outlined` |
171
+ | `"focused"` | `centered-minimal`, `stacked-cards`, `soft-float`, `bold-statement` |
133
172
 
134
- ### Behaviors
173
+ The focused family adds, on top of whichever of the four styles is selected:
135
174
 
136
- | Behavior | Description |
175
+ | Treatment | Description |
137
176
  | --- | --- |
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) |
177
+ | **Vertical centering** | Content is vertically and horizontally centered within a narrow column |
141
178
  | **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 |
179
+ | **Larger tap targets** | Yes/No buttons, option items, card-select cards and input fields are enlarged for easier tapping |
180
+ | **Bolder type** | Headers, labels, prompts and inputs step up in size |
143
181
 
144
- ### Conversational styles
182
+ The family is **never authored** — it does not appear in Flow JSON. FBRE derives
183
+ it and emits it as `data-style-family` alongside `data-style`. `fiber-types`
184
+ exports the derivation for builders that want to group a style picker by family:
145
185
 
146
- Conversational mode has 4 dedicated styles (separate from the 6 standard styles):
186
+ ```ts
187
+ import { FOCUSED_STYLES, styleFamily } from "@sonata-innovations/fiber-types";
147
188
 
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) |
189
+ styleFamily("bold-statement"); // "focused"
190
+ styleFamily("clean"); // "form"
191
+ styleFamily(undefined); // "form"
192
+ ```
193
+
194
+ Because the family derives from `theme.style`, presentation travels with the
195
+ theme through every render path — local, remote and server-driven alike.
154
196
 
155
- When switching to conversational mode in FBT, the style auto-switches to `"centered-minimal"` and the transition to `"scaleFade"`.
197
+ ---
198
+
199
+ ## Advance Behaviors
200
+
201
+ Auto-advance and Enter-to-advance are independent `navigation` flags. They are
202
+ **not** tied to a style or a family: a `clean` form with one question per screen
203
+ gets Enter-to-advance, and a `bold-statement` flow only auto-advances if it asks
204
+ to.
205
+
206
+ | Flag | Default | Behavior |
207
+ | --- | --- | --- |
208
+ | `navigation.autoAdvance` | `false` | Single-select components (`radio`, `yesNo`, `cardSelect`, `dropDown`) advance to the next screen ~500ms after selection. Multi-select (`checkbox`, `dropDownMulti`) never auto-advances |
209
+ | `navigation.advanceOnEnter` | `true` | Pressing Enter in an `inputText` / `inputNumber` advances to the next screen. `inputTextArea` is excluded (Enter inserts newlines) |
210
+
211
+ `autoAdvance` defaults off because a form that moves without a click is
212
+ surprising and shifts content ~500ms after a selection. `advanceOnEnter`
213
+ defaults on because Enter-to-advance is an ordinary form convention.
156
214
 
157
215
  ### Guards
158
216
 
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
217
+ Both behaviors share the same guards, and they are not configurable:
218
+
219
+ - Neither fires on a screen with **more than one visible input** — a shared
220
+ screen behaves like a normal form so later components aren't skipped
221
+ - Neither fires on the last screen (so Enter can never submit)
222
+ - Neither fires if the screen fails validation
223
+ - Both respect condition-hidden screens (they skip them)
224
+ - Auto-advance does not fire during an active transition
225
+ - Enter-to-advance does not fire inside an open popup (date picker, colour
226
+ picker, dropdown panel) — the overlay keeps its Enter
164
227
 
165
228
  ---
166
229
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sonata-innovations/fiber-types",
3
- "version": "2.3.0",
3
+ "version": "3.0.0",
4
4
  "description": "TypeScript type definitions for the Fiber form builder system",
5
5
  "keywords": [
6
6
  "fiber",