Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions workspaces/js/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
export type {
Action,
ActiveBlock,
ComponentActiveBlock,
TourComponentActiveBlock,
SurveyActiveBlock,
BlockState,
FlowsProperties,
StateMemory,
Expand Down
3 changes: 3 additions & 0 deletions workspaces/react/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
export type {
Action,
ActiveBlock,
ComponentActiveBlock,
TourComponentActiveBlock,
SurveyActiveBlock,
BlockState,
FlowsProperties,
StateMemory,
Expand Down
2 changes: 1 addition & 1 deletion workspaces/react/src/lib/active-block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export const blockToActiveBlock = ({

const activeBlock: ActiveBlock = {
id: block.id,
type: block.type as ActiveBlock["type"],
type: block.type,
component: block.componentType,
props,
};
Expand Down
94 changes: 82 additions & 12 deletions workspaces/shared/src/types/active-block.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,97 @@
import { type FlowsProperties } from "./components";
import type {
FlowsProperties,
ComponentProps,
SurveyComponentProps,
TourComponentProps,
} from "./components";

export interface ActiveBlock {
type ActiveBlockBase<T extends string, P extends { __flows: FlowsProperties }> = {
/**
* Unique identifier of the block, useful for stable key during rendering. Keep in mind each workflow version will have a different id for each block.
* Unique identifier of the block. Useful as a stable `key` during rendering.
*
* Note: each workflow version assigns different ids to each block, so this value changes on workflow publish.
*/
id: string;
/**
* Unique identifier of the tour block this tour-component belongs to. Keep in mind each workflow version will have a different id for each block.
* Discriminant that identifies the block variant. Use this to narrow the type and access type-safe `props`.
*
* - `"component"` — a standalone workflow block
* - `"tour-component"` — a single step within a tour
* - `"survey"` — a survey block
*/
tourBlockId?: string;
type: T;
/**
* Type of the block, either "component" or "tour-component" or "survey".
* The key of the registered UI component used to render this block.
* Must match a key registered in `FlowsProvider` (React) or `init` (JS).
*/
type: "component" | "tour-component" | "survey";
component: string;
/**
* The UI Component used to render this block.
* Props to pass to the component. The exact shape depends on the block `type`:
*
* - `"component"` → `ComponentProps`
* - `"tour-component"` → `TourComponentProps` — includes `continue`, `previous?`, and `cancel`
* - `"survey"` → `SurveyComponentProps` — includes `survey`, `complete`, and `cancel`
*/
component: string;
props: P;
};

/**
* An `ActiveBlock` representing a standalone workflow component block.
*
* Narrow to this type by checking `block.type === "component"`.
*/
export type ComponentActiveBlock = ActiveBlockBase<
"component",
ComponentProps<Record<string, unknown>>
>;

/**
* An `ActiveBlock` representing a single step within a tour.
*
* Narrow to this type by checking `block.type === "tour-component"`.
*/
export type TourComponentActiveBlock = ActiveBlockBase<
"tour-component",
TourComponentProps<Record<string, unknown>>
> & {
/**
* Props to be passed to the component including both data and exit node methods.
* Unique identifier of the parent tour block this step belongs to. Useful as a stable `key` during rendering.
*
* Prefer this over `id` when rendering tour steps — reusing the same key across steps lets the browser
* reuse the DOM element rather than unmounting and remounting it between individual steps.
*
* Note: each workflow version assigns different ids to each block, so this value changes on workflow publish.
*/
props: { __flows: FlowsProperties } & Record<string, unknown>;
}
tourBlockId?: string;
};

/**
* An `ActiveBlock` representing a survey block.
*
* Narrow to this type by checking `block.type === "survey"`.
*/
export type SurveyActiveBlock = ActiveBlockBase<
"survey",
SurveyComponentProps<Record<string, unknown>>
>;

/**
* A block that is currently active and ready to render.
*
* Use `block.type` to narrow to a specific variant and access type-safe `props`:
*
* ```ts
* if (block.type === "tour-component") {
* // props is TourComponentProps — includes continue, previous?, cancel
* block.props.continue();
* }
* ```
*
* @see {@link ComponentActiveBlock} for `"component"` blocks
* @see {@link TourComponentActiveBlock} for `"tour-component"` blocks
* @see {@link SurveyActiveBlock} for `"survey"` blocks
*/
export type ActiveBlock = ComponentActiveBlock | TourComponentActiveBlock | SurveyActiveBlock;
Comment thread
VojtechVidra marked this conversation as resolved.

export const createActiveBlockProxy = (
block: ActiveBlock,
Expand Down
Loading