openpencil/crates/op-web-sdk/bindings/ops.ts

866 lines
53 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { JsonValue } from "./serde_json/JsonValue";
/**
* A single Action is a 1-key object: `{ "<action_name>": <body> }`.
*
* Examples (all are valid JSON `Action`s):
* - `{ "set": { "$state.count": "$state.count + 1" } }`
* - `{ "fetch": { "url": "/api/x", "into": "$state.u" } }`
* - `{ "push": "/detail/42" }`
*
* The body shape per action is NOT validated here — see `jian-core::action`.
*/
export type Action = { [key in string]?: JsonValue };
export type AlignItems = "start" | "center" | "end" | "stretch";
export type AppConfig = { name: string, version: string, id: string, entry: string | null, capabilities: Array<Capability> | null, theme: string | null, orientation: Orientation | null, backgroundColor: string | null, icon: string | null,
/**
* C19 splash-frame config.
*/
splash: SplashConfig | null,
/**
* C18 ASP web handshake postMessage origin allowlist.
* Only consulted by the web host; strict match; no wildcards.
*/
aspAllowedOrigins: Array<string> | null,
/**
* Auto-update backend descriptor — same idea as `app.icon`:
* the schema declares the source of truth (which release feed
* to consult), the host crate translates it into a concrete
* `Updater` impl. `None` (the default) means the host's own
* fallback wins (typically `NullUpdater`). Only consulted by
* hosts that compile with their respective updater feature
* (`jian-host-desktop/updater`).
*
* TS-side, the type widens to a generic discriminated record so
* third-party hosts can declare their own kinds without forking
* `ops.ts`; the Rust side is the typed `UpdaterConfig` struct
* below.
*/
updater: { kind: string; [key: string]: unknown } | null, };
export type AppLifecycleHooks = { onLaunch: Array<Action> | null, onResume: Array<Action> | null, onBackground: Array<Action> | null, onTerminate: Array<Action> | null, };
export type BlendMode = "normal" | "darken" | "multiply" | "screen" | "overlay" | "lighten" | "difference" | "hue" | "saturation" | "color" | "luminosity" | "soft_light" | "color_dodge" | "color_burn" | "hard_light" | "exclusion";
export type BlurBody = { radius: number, visible: boolean | null, };
/**
* Boolean that may also be an expression.
*/
export type BoolOrExpression = boolean | string;
/**
* Inclusive viewport-width range for a responsive screen variant.
*/
export type BreakpointRange = { minWidth: number | null, maxWidth: number | null, };
export type Capability = "storage" | "network" | "camera" | "microphone" | "location" | "notifications" | "clipboard" | "biometric" | "file_system" | "haptic";
/**
* Checkbox with an optional adjacent `label`. `checked` two-way binds
* via `bindings.bind:value`.
*/
export type CheckboxNode = { width: SizingBehavior | null, height: SizingBehavior | null, checked: BoolOrExpression | null, label: string | null, fill: Array<PenFill> | null, stroke: PenStroke | null, effects: Array<PenEffect> | null, cornerRadius: CornerRadius | null, states: WidgetStates | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, minWidth: number | null, maxWidth: number | null, minHeight: number | null, maxHeight: number | null, };
/**
* Figma-style per-axis anchoring for absolutely positioned nodes.
*/
export type Constraints = { h: HConstraint, v: VConstraint, };
export type ConversionEntry = { kind: ConversionKind,
/**
* Caller-stable key, e.g. "src/Button.tsx#Button" or "route:/settings".
*/
key: string, sourcePath: string | null,
/**
* Content fingerprint of the source unit; used for incremental conversion.
*/
sourceHash: string | null,
/**
* Master frame id (component) or screen frame id. None for token entries.
*/
nodeId: string | null,
/**
* Source-node id to document-node id mapping for idempotent reruns.
*/
nodeIds: { [key in string]?: string } | null, };
export type ConversionKind = "token" | "component" | "screen";
/**
* Ledger of code-to-design conversion units.
*/
export type ConversionSpec = { entries: Array<ConversionEntry>, };
export type CornerRadius = number | [number, number, number, number];
/**
* One named colour from the design-md colour palette.
*/
export type DesignMdColor = {
/**
* Human label, e.g. "Primary".
*/
name: string,
/**
* `#RRGGBB` hex value.
*/
hex: string,
/**
* How the colour is used, e.g. "buttons and links".
*/
role: string, };
/**
* A structured design-system brief attached to a [`PenDocument`].
*
* [`PenDocument`]: crate::document::PenDocument
*/
export type DesignMdSpec = {
/**
* Original markdown source — kept verbatim for round-trip fidelity.
*/
raw: string, projectName: string | null, visualTheme: string | null, colorPalette: Array<DesignMdColor> | null, typography: DesignMdTypography | null, componentStyles: string | null, layoutPrinciples: string | null, generationNotes: string | null, };
/**
* Typography guidance from the design-md typography section.
*/
export type DesignMdTypography = { fontFamily: string | null, headings: string | null, body: string | null,
/**
* Free-form scale description — usually the whole section text.
*/
scale: string | null, };
export type EllipseNode = { width: SizingBehavior | null, height: SizingBehavior | null, cornerRadius: number | null, innerRadius: number | null, startAngle: number | null, sweepAngle: number | null, fill: Array<PenFill> | null, stroke: PenStroke | null, effects: Array<PenEffect> | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, minWidth: number | null, maxWidth: number | null, minHeight: number | null, maxHeight: number | null, };
/**
* All supported event hook keys. Note: input events (`onChange`, `onSubmit`, `onFocus`,
* `onBlur`) apply only to input-kind nodes. `on_key` is keyboard, `on_reach_end`
* is list-scroll-end, etc.
*/
export type EventHandlers = { onTap: Array<Action> | null, onDoubleTap: Array<Action> | null, onLongPress: Array<Action> | null, onPanStart: Array<Action> | null, onPanUpdate: Array<Action> | null, onPanEnd: Array<Action> | null, onScaleStart: Array<Action> | null, onScaleUpdate: Array<Action> | null, onScaleEnd: Array<Action> | null, onRotateStart: Array<Action> | null, onRotateUpdate: Array<Action> | null, onRotateEnd: Array<Action> | null, onHoverEnter: Array<Action> | null, onHoverLeave: Array<Action> | null, onChange: Array<Action> | null, onSubmit: Array<Action> | null, onFocus: Array<Action> | null, onBlur: Array<Action> | null, onKey: Array<Action> | null, onScroll: Array<Action> | null, onReachEnd: Array<Action> | null, };
/**
* A Tier 1 expression source — represented as a raw string.
*
* Parsing and validation are the responsibility of `jian-core::expression::parser`
* (Plan 2). The schema crate only guarantees the string is present; content-level
* correctness is deferred.
*/
export type Expression = string;
export type FontStyleKind = "normal" | "italic";
export type FontWeight = number | string;
/**
* Forward declaration of PenNode union — defined in `node/mod.rs`.
* We accept `Vec<super::PenNode>` as children.
*/
export type FrameNode = { children: Array<PenNode> | null, imageSearchQuery: string | null, reusable: boolean | null, slot: Array<string> | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null,
/**
* Screen marker: this top-level frame is one screen of the app,
* mounted at the given route path ("/" = entry). Consumed only by
* the screen-projection pass; ignored elsewhere. Additive 1.x.
*/
screen: string | null,
/**
* Breakpoint range for screen variants. Invalid ranges are stripped
* during responsive screen projection.
*/
breakpoint: BreakpointRange | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, width: SizingBehavior | null, height: SizingBehavior | null, layout: LayoutMode | null, gap: NumberOrExpression | null, padding: Padding | null, justifyContent: JustifyContent | null, alignItems: AlignItems | null, clipContent: boolean | null, cornerRadius: CornerRadius | null, fill: Array<PenFill> | null, stroke: PenStroke | null, effects: Array<PenEffect> | null, minWidth: number | null, maxWidth: number | null, minHeight: number | null, maxHeight: number | null, };
export type GestureOverrides = {
/**
* When true, this node and its subtree bypass the Arena and receive raw pointer events.
*/
rawPointer: boolean | null, disabled: Expression | null, scrollBehavior: ScrollBehavior | null,
/**
* Override drag threshold in logical pixels (default 8).
*/
dragThreshold: number | null,
/**
* Override long-press duration in ms (default 500).
*/
longPressDuration: number | null,
/**
* Author-explicit Tab-traversal opt-in.
*
* `Some(true)` — node enters the focus chain regardless of its
* semantic role.
* `Some(false)` — node is excluded even if its `semantics.role`
* would otherwise auto-include it (e.g. a decorative `Input`).
* `None` — falls back to the role heuristic (`Button` / `Link`
* / `Input` are auto-included; everything else is opt-in).
*/
focusable: boolean | null, };
export type GradientStop = { offset: number, color: string, };
export type GroupNode = { children: Array<PenNode> | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, width: SizingBehavior | null, height: SizingBehavior | null, layout: LayoutMode | null, gap: NumberOrExpression | null, padding: Padding | null, justifyContent: JustifyContent | null, alignItems: AlignItems | null, clipContent: boolean | null, cornerRadius: CornerRadius | null, fill: Array<PenFill> | null, stroke: PenStroke | null, effects: Array<PenEffect> | null, minWidth: number | null, maxWidth: number | null, minHeight: number | null, maxHeight: number | null, };
/**
* Horizontal anchoring for an absolutely positioned node.
*/
export type HConstraint = "left" | "right" | "center" | "left_right" | "scale";
export type IconFontNode = { iconFontName: string, iconFontFamily: string | null, width: SizingBehavior | null, height: SizingBehavior | null, fill: Array<PenFill> | null, stroke: PenStroke | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, minWidth: number | null, maxWidth: number | null, minHeight: number | null, maxHeight: number | null, };
export type ImageFillBody = { url: string, mode: ImageFillMode | null, originalSize: ImageOriginalSize | null, transform: ImageTransform | null,
/**
* Figma TILE paint scale. A value of `1.0` draws each source bitmap pixel
* as one document pixel; omitted values retain that default. Other image
* placement modes ignore this field.
*/
tileScale?: number | null, explain: string | null, opacity: number | null,
/**
* Per-fill compositing mode. Optional for wire compatibility with
* documents authored before image fills supported blending.
*/
blendMode: BlendMode | null, exposure: number | null, contrast: number | null, saturation: number | null, temperature: number | null, tint: number | null, highlights: number | null, shadows: number | null, };
export type ImageFillMode = "fill" | "fit" | "crop" | "tile" | "stretch";
export type ImageFitMode = "fill" | "fit" | "crop" | "tile";
export type ImageNode = { src: string, objectFit: ImageFitMode | null, width: SizingBehavior | null, height: SizingBehavior | null, cornerRadius: CornerRadius | null, effects: Array<PenEffect> | null, exposure: number | null, contrast: number | null, saturation: number | null, temperature: number | null, tint: number | null, highlights: number | null, shadows: number | null, imagePrompt: string | null, imageSearchQuery: string | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, minWidth: number | null, maxWidth: number | null, minHeight: number | null, maxHeight: number | null, };
export type ImageOriginalSize = { width: number, height: number, };
export type ImageTransform = { m00: number, m01: number, m02: number, m10: number, m11: number, m12: number, };
export type JustifyContent = "start" | "center" | "end" | "space_between" | "space_around";
export type LayoutMode = "none" | "vertical" | "horizontal";
export type LineNode = { x2: number | null, y2: number | null, stroke: PenStroke | null, effects: Array<PenEffect> | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, };
export type LinearGradientBody = { angle: number | null, stops: Array<GradientStop>, explain: string | null, opacity: number | null, blendMode: BlendMode | null, };
export type LiveRegion = "off" | "polite" | "assertive";
/**
* An ABI version string for the Tier 3 WASM module. The only recognised
* value today is `jian.wasm.v1`; Jian rejects unknown ABI at load time.
*/
export type LogicAbi = string;
export type LogicModuleRef = { id: string, source: string, integrity: string | null, abi: LogicAbi, capabilities: Array<Capability> | null, };
/**
* Pixel operation used when this node masks the sibling layers in front of
* it. This lives on the shared base because Figma permits masks on frames,
* rectangles, text, instances, and vector nodes alike.
*/
export type MaskType = "alpha" | "vector" | "luminance";
/**
* Uniform-grid mesh gradient (v1). A `rows`×`cols` lattice of
* `MeshVertexStop`s is Gouraud-interpolated across the node's
* round-rect. Mirrors the sibling gradient bodies for the shared
* `explain`/`opacity`/`blend_mode` tail.
*/
export type MeshGradientBody = { rows: number, cols: number, stops: Array<MeshVertexStop>, explain: string | null, opacity: number | null, blendMode: BlendMode | null, };
/**
* A single vertex of a `MeshGradient` grid. `row`/`col` are 0-based
* indices into a `rows`×`cols` lattice; `color` is the Gouraud-shaded
* colour anchored at that vertex.
*/
export type MeshVertexStop = { row: number, col: number, color: string, };
/**
* Declarative per-node navigation: clicking the node pushes/replaces/pops a route.
* Equivalent to `events.on_tap = [{"push": "..."}]` but more editor-discoverable.
*/
export type NavigationRoute = { "push": string } | { "replace": string } | { "pop": null };
export type NodeLifecycleHooks = { onMount: Array<Action> | null, onUnmount: Array<Action> | null, };
/**
* Numeric input with optional +/- steppers. Precise complement to
* `slider`; `value` two-way binds via `bindings.bind:value`. When
* omitted, `min`/`max`/`step` default to none/none/1 at runtime.
*/
export type NumberInputNode = { width: SizingBehavior | null, height: SizingBehavior | null,
/**
* Placeholder shown when `value` is empty.
*/
placeholder: string | null, value: NumberOrExpression | null, returnKeyHint: string | null,
/**
* Lucide glyph drawn at the left content edge. See `TextInputNode`.
*/
leadingIcon: string | null,
/**
* Lucide glyph drawn at the right content edge. See `TextInputNode`.
*/
trailingIcon: string | null, min: number | null, max: number | null, step: number | null, fill: Array<PenFill> | null, stroke: PenStroke | null, effects: Array<PenEffect> | null, cornerRadius: CornerRadius | null, states: WidgetStates | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, minWidth: number | null, maxWidth: number | null, minHeight: number | null, maxHeight: number | null, };
/**
* Opacity can be a number or a `$variable` reference string.
*/
export type NumberOrExpression = number | string;
export type Orientation = "portrait" | "landscape" | "auto";
export type Padding = number | [number, number] | [number, number, number, number] | string;
export type PageLifecycleHooks = { onEnter: Array<Action> | null, onLeave: Array<Action> | null, onForeground: Array<Action> | null, onBackground: Array<Action> | null, };
export type PathFillRule = "nonzero" | "evenodd";
export type PathNode = { iconId: string | null, d: string | null, anchors: Array<PenPathAnchor> | null, closed: boolean | null, fillRule?: PathFillRule | null,
/**
* Whether this path acts as a sibling mask for the layers above it.
*
* This is intentionally optional so existing `.op` documents retain
* their byte shape. It is the legacy opaque-path marker; newer alpha,
* vector, and luminance semantics use the shared `mask_type` field.
*/
mask?: boolean | null, width: SizingBehavior | null, height: SizingBehavior | null, fill: Array<PenFill> | null, stroke: PenStroke | null, effects: Array<PenEffect> | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, minWidth: number | null, maxWidth: number | null, minHeight: number | null, maxHeight: number | null, };
export type PenDocument = {
/**
* Document format version stored in files since v0.x. Always present.
*/
version: string, name: string | null,
/**
* Wire shape: axis-name → ordered theme names. Frozen from v0.x.
*/
themes: { [key in string]?: Array<string> } | null, variables: { [key in string]?: VariableDefinition } | null, pages: Array<PenPage> | null,
/**
* Default-on-deserialize so a multi-page document that carries only
* `pages` (no top-level `children`) still loads — the TS web app's
* whole-document sync (`document.post.ts`) accepts `{version, pages}`
* without a `children` array. Always serialized (even empty `[]`).
*/
children: Array<PenNode>,
/**
* "1.0" when any v1 extension is present; undefined ⇒ legacy v0.x.
*/
formatVersion: string | null,
/**
* Responsive opt-in. Absent or false preserves legacy behavior.
*/
responsive: boolean | null,
/**
* App id (reverse-DNS). Required when `app` is set; otherwise optional.
*/
id: string | null, app: AppConfig | null, routes: RoutesConfig | null, state: { [key in string]?: StateEntry } | null, lifecycle: AppLifecycleHooks | null, logicModules: Array<LogicModuleRef> | null,
/**
* Per-document design-system brief (the "design.md"). Optional —
* absent on documents that never authored one.
*/
designMd: DesignMdSpec | null,
/**
* Code-to-design conversion ledger.
*/
conversion: ConversionSpec | null, };
export type PenEffect = { "type": "blur" } & BlurBody | { "type": "background_blur" } & BlurBody | { "type": "shadow" } & ShadowBody;
export type PenFill = { "type": "solid" } & SolidFillBody | { "type": "linear_gradient" } & LinearGradientBody | { "type": "radial_gradient" } & RadialGradientBody | { "type": "mesh_gradient" } & MeshGradientBody | { "type": "shader" } & ShaderFillBody | { "type": "image" } & ImageFillBody;
/**
* Union of all concrete node types.
* Tag is the JSON `"type"` field.
*/
export type PenNode = { "type": "frame" } & FrameNode | { "type": "group" } & GroupNode | { "type": "rectangle" } & RectangleNode | { "type": "ellipse" } & EllipseNode | { "type": "line" } & LineNode | { "type": "polygon" } & PolygonNode | { "type": "path" } & PathNode | { "type": "text" } & TextNode | { "type": "text_input" } & TextInputNode | { "type": "image" } & ImageNode | { "type": "icon_font" } & IconFontNode | { "type": "text_area" } & TextAreaNode | { "type": "select" } & SelectNode | { "type": "switch" } & SwitchNode | { "type": "checkbox" } & CheckboxNode | { "type": "slider" } & SliderNode | { "type": "radio_group" } & RadioGroupNode | { "type": "number_input" } & NumberInputNode | { "type": "progress" } & ProgressNode | { "type": "tabs" } & TabsNode | { "type": "ref" } & RefNode;
export type PenPage = { id: string, name: string, children: Array<PenNode>,
/**
* Optional infinite-canvas background for this page. When absent,
* editors use their normal canvas surface and grid treatment.
*/
backgroundColor?: string | null, state: { [key in string]?: StateEntry } | null, lifecycle: PageLifecycleHooks | null, };
export type PenPathAnchor = { x: number, y: number, handleIn: PenPathHandle | null, handleOut: PenPathHandle | null, pointType: PenPathPointType | null, };
export type PenPathHandle = { x: number, y: number, };
export type PenPathPointType = "corner" | "mirrored" | "independent";
export type PenStroke = { thickness: StrokeThickness, align: StrokeAlign | null, join: StrokeJoin | null, cap: StrokeCap | null, dashPattern: Array<number> | null, dashOffset: number | null, fill: Array<PenFill> | null, };
export type PolygonNode = { polygonCount: number, width: SizingBehavior | null, height: SizingBehavior | null, cornerRadius: number | null, fill: Array<PenFill> | null, stroke: PenStroke | null, effects: Array<PenEffect> | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, minWidth: number | null, maxWidth: number | null, minHeight: number | null, maxHeight: number | null, };
export type PrimitiveType = "int" | "float" | "number" | "string" | "bool" | "array" | "object" | "date";
/**
* Progress indicator. Display-only (not focusable/keyboard-driven):
* `value` is read from the state graph via `bindings.value`. `max`
* defaults to 100; `indeterminate` shows an animated unknown-progress
* state and ignores `value`.
*/
export type ProgressNode = { width: SizingBehavior | null, height: SizingBehavior | null, value: NumberOrExpression | null, max: number | null, indeterminate: boolean | null, fill: Array<PenFill> | null, stroke: PenStroke | null, effects: Array<PenEffect> | null, cornerRadius: CornerRadius | null, states: WidgetStates | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, minWidth: number | null, maxWidth: number | null, minHeight: number | null, maxHeight: number | null, };
export type RadialGradientBody = { cx: number | null, cy: number | null, radius: number | null, stops: Array<GradientStop>, explain: string | null, opacity: number | null, blendMode: BlendMode | null, };
/**
* Single-choice radio group. Renders one radio per `option`; the
* selected option `value` two-way binds via `bindings.bind:value`.
*/
export type RadioGroupNode = { width: SizingBehavior | null, height: SizingBehavior | null,
/**
* Currently selected option `value`.
*/
value: string | null, options: Array<SelectOption> | null, fill: Array<PenFill> | null, stroke: PenStroke | null, effects: Array<PenEffect> | null, cornerRadius: CornerRadius | null, states: WidgetStates | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, minWidth: number | null, maxWidth: number | null, minHeight: number | null, maxHeight: number | null, };
export type RectangleNode = { children: Array<PenNode> | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, width: SizingBehavior | null, height: SizingBehavior | null, layout: LayoutMode | null, gap: NumberOrExpression | null, padding: Padding | null, justifyContent: JustifyContent | null, alignItems: AlignItems | null, clipContent: boolean | null, cornerRadius: CornerRadius | null, fill: Array<PenFill> | null, stroke: PenStroke | null, effects: Array<PenEffect> | null, minWidth: number | null, maxWidth: number | null, minHeight: number | null, maxHeight: number | null, };
export type RefNode = { ref: string, descendants: { [key in string]?: JsonValue } | null, children: Array<PenNode> | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, };
export type RouteSpec = { pageId: string, preload: boolean | null, guards: Array<Action> | null,
/**
* Path-parameter type declarations (v1.0 additive — 2026-04-24).
* Keys correspond to `:param` placeholders in the route path
* (e.g. path `/detail/:id` → key `id`). The AI Action Surface
* uses these types when synthesising the JsonSchema for the
* derived `open_*(p)` action; runtime does strict type-checking
* on incoming values rather than silent coercion.
*/
params: { [key in string]?: StateType } | null, };
export type RoutesConfig = { entry: string, routes: { [key in string]?: RouteSpec }, transitions: { [key in string]?: Transition } | null, };
export type ScrollBehavior = "auto" | "contain" | "none";
/**
* Dropdown select. The runtime pops an option list; the selected
* option `value` two-way binds via `bindings.bind:value`.
*/
export type SelectNode = { width: SizingBehavior | null, height: SizingBehavior | null,
/**
* Shown when no option is selected.
*/
placeholder: string | null,
/**
* Currently selected option `value`.
*/
value: string | null, options: Array<SelectOption> | null, fill: Array<PenFill> | null, stroke: PenStroke | null, effects: Array<PenEffect> | null, cornerRadius: CornerRadius | null, states: WidgetStates | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, minWidth: number | null, maxWidth: number | null, minHeight: number | null, maxHeight: number | null, };
/**
* A single dropdown option: the persisted `value` and its display `label`.
*/
export type SelectOption = { value: string, label: string, };
export type SemanticAction = { name: string, label: string, handler: Array<Action>, };
export type SemanticRole = "button" | "link" | "image" | "text" | "heading" | "input" | "list" | "list_item" | "header" | "nav" | "main" | "dialog" | "alert";
export type SemanticsMeta = { role: SemanticRole | null, label: string | null, hint: string | null, liveRegion: LiveRegion | null, disabled: Expression | null, actions: Array<SemanticAction> | null,
/**
* Author-stable override for the auto-derived AI action name.
* When set, the resulting action name is `<scope>.<aiName>`
* without the auto `_<hash4>` suffix and survives slug recomputes
* across builds. See `2026-04-24-ai-action-surface.md` §3.3-3.4.
*/
aiName: string | null,
/**
* Tool description shown to external AI agents. Overrides the
* auto-generated default; lets authors steer what a model "sees"
* without changing visible UI text.
*/
aiDescription: string | null,
/**
* `true` permanently hides the node's derived action from the AI
* surface (StaticHidden). Defaults to `false`. ConfirmGated /
* StateGated availability are decided dynamically and do **not**
* require this flag — see ai-action-surface.md §4.
*/
aiHidden: boolean | null,
/**
* Historical `aiName` values still accepted by `execute_action`
* for transparent migration after a rename. Aliases are honoured
* at execute time (with `audit reason_code: "alias_used"`) but
* not surfaced by `list_available_actions`. See §9.
*/
aiAliases: Array<string> | null, };
/**
* Native SkSL shader fill (v1). The `sksl` source is stored RAW and is
* treated as untrusted: the renderer entrypoint is the SkSL signature
* `half4 main(float2 fragCoord)`. On compile failure the backend
* degrades to a visible solid fill (the first `color` uniform, else
* mid-gray) and never panics. Mirrors the sibling gradient bodies for
* the shared `opacity`/`blend_mode` tail.
*
* Pencil-flavoured WebGL-GLSL import is an explicit follow-up, NOT v1;
* v1 expects SkSL (Skia's GLSL dialect) verbatim.
*/
export type ShaderFillBody = {
/**
* RAW SkSL source. Entrypoint: `half4 main(float2 fragCoord)`.
*/
sksl: string,
/**
* Optional named-uniform map (`float` / `vec*` / `color`). A
* shader may declare none; absent or empty both mean "no uniforms".
*/
uniforms: { [key in string]?: ShaderUniformValue } | null, explain: string | null, opacity: number | null, blendMode: BlendMode | null, };
/**
* One named uniform value bound into an SkSL shader fill via
* `RuntimeShaderBuilder` at paint time. `untagged` so the wire form is
* the bare JSON scalar/array the author wrote — a number is a `float`,
* a number array is a `vec2`/`vec3`/`vec4`, and a hex string is a
* `color` mapped to a `vec4` (premultiplied RGBA). The named-uniforms
* map on `ShaderFillBody` is optional; a shader may take none.
*/
export type ShaderUniformValue = number | Array<number> | string;
export type ShadowBody = { inner: boolean | null, visible: boolean | null, offsetX: number, offsetY: number, blur: number, spread: number, color: string, };
export type SidedThickness = { top: number | null, right: number | null, bottom: number | null, left: number | null, };
/**
* Sizing value: a number, a fixed keyword, or an arbitrary string (typically `$variable` ref).
*/
export type SizingBehavior = number | SizingKeyword | string;
export type SizingKeyword = "fit_content" | "fill_container";
/**
* Range slider. `value` two-way binds via `bindings.bind:value`;
* `min`/`max`/`step` default to 0/100/1 at runtime when omitted.
*/
export type SliderNode = { width: SizingBehavior | null, height: SizingBehavior | null, min: number | null, max: number | null, step: number | null, value: NumberOrExpression | null, fill: Array<PenFill> | null, stroke: PenStroke | null, effects: Array<PenEffect> | null, cornerRadius: CornerRadius | null, states: WidgetStates | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, minWidth: number | null, maxWidth: number | null, minHeight: number | null, maxHeight: number | null, };
export type SolidFillBody = { color: string, explain: string | null, opacity: number | null, blendMode: BlendMode | null, };
export type SplashConfig = { background: string | null, image: string | null, text: string | null, minDurationMs: number | null, };
export type StateEntry = { type: StateType, default: JsonValue | null, description: string | null, persist: boolean | null, };
/**
* Recursive state type description.
*/
export type StateType = PrimitiveType | { oneOf: Array<StateType>, } | { array: StateType, } | { object: { [key in string]?: StateType }, };
export type StrokeAlign = "inside" | "center" | "outside";
export type StrokeCap = "none" | "round" | "square";
export type StrokeJoin = "miter" | "bevel" | "round";
export type StrokeThickness = number | [number, number, number, number] | SidedThickness;
export type StyleOverride = { fill: Array<PenFill> | null, stroke: PenStroke | null, effects: Array<PenEffect> | null, opacity: number | null, };
export type StyledTextSegment = { text: string, fontFamily: string | null, fontSize: number | null, fontWeight: number | null, fontStyle: FontStyleKind | null, fill: string | null, underline: boolean | null, strikethrough: boolean | null, href: string | null, };
/**
* On/off toggle. `checked` two-way binds via `bindings.bind:value`.
*/
export type SwitchNode = { width: SizingBehavior | null, height: SizingBehavior | null, checked: BoolOrExpression | null, fill: Array<PenFill> | null, stroke: PenStroke | null, effects: Array<PenEffect> | null, cornerRadius: CornerRadius | null, states: WidgetStates | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, minWidth: number | null, maxWidth: number | null, minHeight: number | null, maxHeight: number | null, };
/**
* Tabbed panel switcher. Unlike the leaf widgets this is a CONTAINER:
* `children[i]` is the panel for `tabs[i]`. The active tab `value`
* two-way binds via `bindings.bind:value`; only the active panel is
* painted at runtime.
*/
export type TabsNode = { width: SizingBehavior | null, height: SizingBehavior | null,
/**
* Tab bar entries; `value` keys the active tab, `label` is shown.
*/
tabs: Array<SelectOption> | null,
/**
* Currently active tab `value`.
*/
value: string | null,
/**
* Panel subtrees, one per tab (parallel to `tabs` by index).
*/
children: Array<PenNode> | null, fill: Array<PenFill> | null, stroke: PenStroke | null, effects: Array<PenEffect> | null, cornerRadius: CornerRadius | null, states: WidgetStates | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, minWidth: number | null, maxWidth: number | null, minHeight: number | null, maxHeight: number | null, };
export type TextAlign = "left" | "center" | "right" | "justify";
export type TextAlignVertical = "top" | "middle" | "bottom";
/**
* Multi-line writable text input. Like `text_input` but wraps and
* scrolls vertically; two-way binds via `bindings.bind:value`.
*/
export type TextAreaNode = { width: SizingBehavior | null, height: SizingBehavior | null,
/**
* Placeholder shown when `value` is empty.
*/
placeholder: string | null,
/**
* Initial value. Two-way binding lives on `bindings.bind:value`.
*/
value: string | null, returnKeyHint: string | null,
/**
* Lucide glyph drawn at the left content edge. See `TextInputNode`.
*/
leadingIcon: string | null,
/**
* Lucide glyph drawn at the right content edge. See `TextInputNode`.
*/
trailingIcon: string | null,
/**
* Visible-line window before the content scrolls (chat-style).
*/
maxVisibleLines: number | null, fill: Array<PenFill> | null, stroke: PenStroke | null, effects: Array<PenEffect> | null, cornerRadius: CornerRadius | null, states: WidgetStates | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, minWidth: number | null, maxWidth: number | null, minHeight: number | null, maxHeight: number | null, };
export type TextContent = string | Array<StyledTextSegment>;
export type TextGrowth = "auto" | "fixed-width" | "fixed-width-height";
/**
* Single-line text input. Forms / counters need a writable input
* surface that two-way binds via `bindings.bind:value`. The walker
* renders a styled rectangle + caret placeholder; full IME and
* selection-painter wiring lands in the desktop host (Plan 8) once
* the gesture arena gains `Focus` recognizers.
*/
export type TextInputNode = { width: SizingBehavior | null, height: SizingBehavior | null,
/**
* Placeholder shown when `value` is empty. Static text — author
* `bindings.placeholder` if it needs to react to state.
*/
placeholder: string | null,
/**
* Initial value. Two-way binding lives on `bindings.bind:value`,
* which derive lifts into a `set_*` action and the runtime keeps
* in sync with the state graph.
*/
value: string | null,
/**
* Request secure platform text entry (password-style keyboard traits).
*/
secure: boolean | null,
/**
* Platform return-key hint (`default`, `done`, `go`, `next`, `search`,
* or `send`). Unknown values degrade to `default` at the host boundary.
*/
returnKeyHint: string | null,
/**
* Lucide glyph drawn at the left content edge (e.g. `mail`, `lock`).
* The painter insets the text/caret past it so the whole box stays
* one interactive node. `None` = no leading icon.
*/
leadingIcon: string | null,
/**
* Lucide glyph drawn at the right content edge (e.g. `eye` for a
* password reveal). Decorative in Phase 1 (no toggle behaviour).
*/
trailingIcon: string | null, fill: Array<PenFill> | null, stroke: PenStroke | null, effects: Array<PenEffect> | null, cornerRadius: CornerRadius | null, states: WidgetStates | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, minWidth: number | null, maxWidth: number | null, minHeight: number | null, maxHeight: number | null, };
export type TextNode = { width: SizingBehavior | null, height: SizingBehavior | null, content: TextContent, fontFamily: string | null, fontSize: number | null, fontWeight: FontWeight | null, fontStyle: FontStyleKind | null, letterSpacing: number | null, lineHeight: number | null, textAlign: TextAlign | null, textAlignVertical: TextAlignVertical | null, textGrowth: TextGrowth | null, underline: boolean | null, strikethrough: boolean | null, fill: Array<PenFill> | null, effects: Array<PenEffect> | null, state: { [key in string]?: StateEntry } | null, bindings: { [key in string]?: Expression } | null, events: EventHandlers | null, lifecycle: NodeLifecycleHooks | null, semantics: SemanticsMeta | null, gestures: GestureOverrides | null, route: NavigationRoute | null, id: string, name: string | null, role: string | null, explain: string | null, x: number | null, y: number | null, rotation: number | null, constraints: Constraints | null, opacity: NumberOrExpression | null, enabled: BoolOrExpression | null, visible: boolean | null, locked: boolean | null, flipX: boolean | null, flipY: boolean | null,
/**
* Sibling-mask semantics. Absence means this node is painted normally.
*/
maskType?: MaskType | null,
/**
* Composite this node's complete rendered subtree with the backdrop.
* Absence is the source-over default; pass-through groups also stay absent.
*/
blendMode?: BlendMode | null, theme: { [key in string]?: string } | null, minWidth: number | null, maxWidth: number | null, minHeight: number | null, maxHeight: number | null, };
export type ThemedValue = { value: VariableScalar, theme: { [key in string]?: string } | null, };
export type Transition = "push" | "fade" | "modal" | "none";
/**
* Vertical anchoring for an absolutely positioned node.
*/
export type VConstraint = "top" | "bottom" | "center" | "top_bottom" | "scale";
export type VariableDefinition = { type: VariableKind, value: VariableValue, };
export type VariableKind = "color" | "number" | "boolean" | "string";
export type VariableScalar = boolean | number | string;
export type VariableValue = VariableScalar | Array<ThemedValue>;
/**
* Authored overrides for the four auto-derived interaction states.
*/
export type WidgetStates = { hover: StyleOverride | null, pressed: StyleOverride | null, focused: StyleOverride | null, disabled: StyleOverride | null, };