import type { FlowConditionConfig } from "./conditions.js"; import type { FlowCalculation } from "./calculation.js"; import type { ComponentPropertiesByType, ComponentType } from "./component-variants.js"; export type ScreenTransitionType = "none" | "slide" | "fade" | "slideFade" | "rise" | "scaleFade"; export type FlowStyleType = "clean" | "outlined" | "refined-clean" | "airy-clean" | "soft-outlined" | "defined-outlined" | "centered-minimal" | "stacked-cards" | "soft-float" | "bold-statement"; export type ControlsLayout = "default" | "centered" | "inline-full" | "stacked"; export type StepperStyle = "default" | "dots" | "pill" | "glow" | "bar" | "text"; export type FlowMetadata = Record & { name?: string; description?: string; }; /** Which built-in palette preset seeds the token layer. Replaces the former * `darkMode: boolean`. Light is the default. A future "auto" (follow the * viewer's `prefers-color-scheme`) is an additive option, not yet supported. */ export type ColorScheme = "light" | "dark"; /** One `url(...)` entry inside a face's `src`. `format` is the CSS * `format()` hint — "woff2", "woff", "truetype". */ export type FontSource = { url: string; format?: string; }; /** A single `@font-face`: one weight/style of a family. */ export type FontFaceConfig = { src: FontSource[]; /** CSS `font-weight` — "400", "700", or a variable range like "100 900". */ weight?: string; style?: "normal" | "italic" | "oblique"; display?: "auto" | "block" | "swap" | "fallback" | "optional"; unicodeRange?: string; }; /** * A brand font the renderer can actually load, rather than a family name it * can only hope the host page already has. * * Naming a family in a theme does nothing on its own: `fontFamily` maps to a * CSS family *string*, and if no `@font-face` for it is registered in the * owning document the form falls back to `system-ui` and looks approximately * fine, so nobody reports it. It matters most exactly where the host cannot * patch around it — a form mounted in a shadow root, since `@font-face` * rules inside a shadow stylesheet are not registered at all. * * Give the family sources here and the renderer registers the faces in the * owning document itself (`ensureFontLoaded` in `@sonata-innovations/fiber-fbre`), * so the family string and the loaded face cannot drift apart. */ export type FontFamilyConfig = { /** CSS family name. Used both for the `@font-face` and the token value. */ family: string; /** Shorthand for a single regular face. Merged with `faces`. */ src?: FontSource[]; /** Additional faces — a second weight, an italic. */ faces?: FontFaceConfig[]; /** * The full stack written to `--fbre-font`. Defaults to the family plus a * system fallback, so a face that fails to load still renders sensibly. */ stack?: string; }; /** * Visual theme settings. Two layers: * - `colorScheme` + `style` pick built-in presets (the seed palette + shape). * - The palette knobs (`color`, `background`, `surface`, `text`, `border`, * `radius`, `fontFamily`, and the semantic `error`/`success`/`warning`) * override individual `--fbre-*` tokens on top of the preset. Any subset may * be set; unset knobs fall through to the preset. Consumers needing finer * control can still override the raw `--fbre-*` CSS custom properties. */ export type ThemeConfig = { /** Accent / primary color (`--fbre-theme-color`). */ color?: string; /** Built-in palette preset that seeds the token layer. Default `"light"`. */ colorScheme?: ColorScheme; /** Built-in style variant (shape: borders, fills, spacing). */ style?: FlowStyleType; /** Page/form ground (`--fbre-bg`). */ background?: string; /** Raised surface: input fills, cards, popups (`--fbre-surface`). */ surface?: string; /** Primary text color (`--fbre-text`); derives secondary/placeholder/label. */ text?: string; /** Border/rule color (`--fbre-border`); derives hover/light/subtle. */ border?: string; /** Corner radius, any CSS length (`--fbre-radius`), e.g. `"3px"`. */ radius?: string; /** * Font family (`--fbre-font`). A plain CSS stack string uses whatever the * host page already provides; a `FontFamilyConfig` additionally carries the * sources the renderer needs to register the face itself. */ fontFamily?: string | FontFamilyConfig; /** Error state color (`--fbre-error`). */ error?: string; /** Success state color (`--fbre-success`). */ success?: string; /** Warning state color (`--fbre-warning`). */ warning?: string; }; export type NavigationConfig = { transition?: ScreenTransitionType; allowInvalidTransition?: boolean; /** * Advance to the next screen ~500ms after a single-select choice * (radio, yesNo, cardSelect, dropDown). Default `false` — a form that * moves without a click is surprising, and the content shift carries an * accessibility cost, so it is opt-in. The builders' focused presets turn * it on. * * Only ever fires on a screen with exactly one visible input; a shared * screen behaves like a normal form so later components aren't skipped. */ autoAdvance?: boolean; /** * Advance to the next screen when Enter is pressed in a single-line input * (`inputText`, `inputNumber`). Default `true` — Enter-to-advance is a form * convention, not a flourish. 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. */ advanceOnEnter?: boolean; }; export type ControlsConfig = { show?: boolean; layout?: ControlsLayout; showStepper?: boolean; stepperStyle?: StepperStyle; }; /** * Terminal "thank you" / confirmation screen shown after the flow is submitted. * Presentation-only — not a data-collection screen, so it lives here on the * config rather than in the `Flow → Screen → Component` hierarchy. * * `title` and `body` support reference markup (`${...}`) and text formatting, * resolved by FBRE against collected field values and external context. The * screen renders only when `show` is not `false` and at least one of * `title`/`body` has content (or the parent supplies an override via the * `onFlowComplete` return value). */ export type ConfirmationConfig = { /** Explicit off-switch. Content presence is the positive gate. */ show?: boolean; /** Heading text (supports `${...}` references + formatting). */ title?: string; /** Body text (supports `${...}` references + formatting). */ body?: string; }; export type FlowConfiguration = { theme?: ThemeConfig; navigation?: NavigationConfig; controls?: ControlsConfig; summary?: boolean; confirmation?: ConfirmationConfig; }; /** Fields every component variant carries regardless of `type`. */ type ComponentCommon = { uuid: string; conditions?: FlowConditionConfig; components?: Component[]; value?: any; addedComponents?: Component[][]; valid?: boolean; display?: Record; }; /** A component with a specific known `type`. Useful for helpers that want to * accept only the matching variant (e.g. `ComponentOfType<"inputText">`). */ export type ComponentOfType = ComponentCommon & { type: K; properties: ComponentPropertiesByType[K]; }; /** Component is a discriminated union keyed on `type`. Switching or guarding * on `component.type === "..."` narrows `component.properties` to the * matching `Component*Properties` shape from `properties.ts`. */ export type Component = { [K in ComponentType]: ComponentOfType; }[ComponentType]; /** Union of every registered properties shape. Replaces the prior * `Record` alias — consumers that previously typed a value as * `ComponentProperties` now get the union and must narrow (most often via * `component.type` on the enclosing `Component`). */ export type ComponentProperties = ComponentPropertiesByType[ComponentType]; export type FlowScreen = { uuid: string; label?: string; components: Component[]; conditions?: FlowConditionConfig; nextButtonLabel?: string; backButtonLabel?: string; valid?: boolean; }; export type Flow = { uuid: string; config?: FlowConfiguration; metadata: FlowMetadata; screens: FlowScreen[]; calculations?: FlowCalculation[]; }; export {}; //# sourceMappingURL=flow.d.ts.map