Skip to Content
API ReferencerendererOverview

@parity/product-sdk-renderer

Build and validate renderer trees.

The host draws a Pocket card face, and a rendered chat body, from a RendererNode: a closed vocabulary of layout and design tokens resolved by the host’s own theme. A product names structure, never markup, colours or URLs.

Two halves. The builders construct that vocabulary with the compiler checking the names and shapes. validateFace checks a finished tree against the protocol, so a face is wrong at build time rather than blank on a phone.

Nothing here is specific to Pocket, and nothing here talks to a host.

npm install @parity/product-sdk-renderer

Exports

Classes

NameSummary
FaceValidationErrorThrown by assertFaceValid. Carries the whole verdict, warnings included.

Functions

NameSummary
archive()Image bytes from a path inside the product’s executable archive.
assertFaceValid()validateFace, but throws on any error.
background()A background fill. Omitting the shape leaves it to the host.
blendingMode()How the node composites against what is behind it.
border()A border. Omitting the shape leaves it to the host.
box()Children stacked on top of one another. With no children and a background, a filled rectangle.
bulletin()Image bytes from a Bulletin chain blob, addressed by CID.
button()A pressable button. Give it a clickAction or it reports nothing.
circle()A circle.
column()Children stacked vertically.
effect()Applies an effect to its children. The only node with no modifiers of its own.
fillHeight()Fill the available height.
fillWidth()Fill the available width.
height()A fixed height.
image()An image the host fetches. Build the source with bulletin() or archive().
margin()Outer spacing. Reads as padding does.
marginEach()Outer spacing with every edge named.
minHeight()A minimum height.
minWidth()A minimum width.
nil()Nothing. Draws no space.
opacity()Opacity, where 0 is transparent and 255 opaque.
padding()Inner spacing. padding(16) is 16 on every edge; padding(20, 24) is 20
paddingEach()Inner spacing with every edge named.
rounded()Rounded corners of the given radius.
row()Children laid out horizontally.
spacer()Empty space of a fixed size.
square()Square corners.
str()A raw string node. text is what you usually want.
text()A line of text, wrapped in the String child the protocol requires.
textField()An editable field. Give it a valueChangeAction or it reports nothing.
validateFace()Check a face against the renderer protocol.
width()A fixed width.

Interfaces

NameSummary
BoxOptionsOptions every node with modifiers accepts.
ButtonOptionsOptions every node with modifiers accepts.
ColumnOptionsOptions every node with modifiers accepts.
DimensionsEdge dimensions. bottom defaults to top and start to end when absent.
FaceIssueOne thing wrong with a face, and where.
FaceVerdict—
HostLimitsOne host’s own bounds.
ImageOptionsOptions every node with modifiers accepts.
NodeOptionsOptions every node with modifiers accepts.
RowOptionsOptions every node with modifiers accepts.
SpacerOptions—
TextFieldOptionsOptions every node with modifiers accepts.
TextOptionsOptions every node with modifiers accepts.
ValidateFaceOptions—

Type Aliases

NameSummary
ArrangementMain-axis distribution of children.
ArrangementMain-axis distribution of children.
BlendingModeHow a node composites with what is behind it. The values are those common
BlendingModeHow a node composites with what is behind it. The values are those common
ButtonVariantButton emphasis.
ButtonVariantButton emphasis.
ColorTokenSemantic color tokens, resolved by the host’s theme.
ColorTokenSemantic color tokens, resolved by the host’s theme.
ContentAlignmentPlacement of content within a Box.
ContentAlignmentPlacement of content within a Box.
DimensionsThe protocol’s own vocabulary types, re-exported so one import covers a face.
EffectA visual effect. Each variant names one effect and carries its parameters.
EffectA visual effect. Each variant names one effect and carries its parameters.
FaceIssueCodeWhat is wrong with a face.
HorizontalAlignmentCross-axis alignment of Column children.
HorizontalAlignmentCross-axis alignment of Column children.
ImageFitHow an image meets the box its modifiers size.
ImageFitHow an image meets the box its modifiers size.
ImageSourceWhere image bytes come from. The host fetches them; the tree carries no URL.
ImageSourceWhere image bytes come from. The host fetches them; the tree carries no URL.
ModifierLayout and styling applied to one node.
ModifierLayout and styling applied to one node.
RendererNodeA node in a product-rendered tree. Container variants recurse through
RendererNodeA node in a product-rendered tree. Container variants recurse through
ShapeOutline of a background or border.
ShapeOutline of a background or border.
SizeA size in logical pixels, SCALE-encoded as Compact<u64>.
SizeA size in logical pixels, SCALE-encoded as Compact<u64>.
TypographyStyleTypography presets, resolved by the host’s design system.
TypographyStyleTypography presets, resolved by the host’s design system.
VerticalAlignmentCross-axis alignment of Row children.
VerticalAlignmentCross-axis alignment of Row children.

Variables

NameSummary
androidLimitsThe Polkadot Android app.
KNOWN_HOST_LIMITSEvery host whose bounds we know.

Classes

class FaceValidationError

Thrown by assertFaceValid. Carries the whole verdict, warnings included.

Extends: Error

Constructors

constructor
new FaceValidationError(verdict: FaceVerdict): FaceValidationError

Properties

verdict
propertyreadonlyFaceVerdict

Functions

archive()

Image bytes from a path inside the product’s executable archive.

archive(path: string): ImageSource

assertFaceValid()

validateFace, but throws on any error.

For a build step that should stop. Warnings do not throw: a build that failed on advice would teach people to switch it off.

assertFaceValid(face: unknown, options: ValidateFaceOptions = {}): void

background()

A background fill. Omitting the shape leaves it to the host.

background(color: ColorToken, shape?: Shape): Modifier

blendingMode()

How the node composites against what is behind it.

blendingMode(mode: BlendingMode): Modifier

border()

A border. Omitting the shape leaves it to the host.

border(width: Size, color: ColorToken, shape?: Shape): Modifier

box()

Children stacked on top of one another. With no children and a background, a filled rectangle.

box(children: RendererNode[], options: BoxOptions = {}): RendererNode

bulletin()

Image bytes from a Bulletin chain blob, addressed by CID.

bulletin(cid: string): ImageSource

button()

A pressable button. Give it a clickAction or it reports nothing.

button(label: string, options: ButtonOptions = {}): RendererNode

circle()

A circle.

circle(): Shape

column()

Children stacked vertically.

column(children: RendererNode[], options: ColumnOptions = {}): RendererNode

effect()

Applies an effect to its children. The only node with no modifiers of its own.

effect(applied: "Rainbow", children: RendererNode[]): RendererNode

fillHeight()

Fill the available height.

fillHeight(value: boolean = true): Modifier

fillWidth()

Fill the available width.

fillWidth(value: boolean = true): Modifier

height()

A fixed height.

height(value: Size): Modifier

image()

An image the host fetches. Build the source with bulletin() or archive().

image(source: ImageSource, options: ImageOptions = {}): RendererNode

margin()

Outer spacing. Reads as padding does.

margin(vertical: Size, horizontal: Size = vertical): Modifier

marginEach()

Outer spacing with every edge named.

marginEach(edges: Dimensions): Modifier

minHeight()

A minimum height.

minHeight(value: Size): Modifier

minWidth()

A minimum width.

minWidth(value: Size): Modifier

nil()

Nothing. Draws no space.

nil(): RendererNode

opacity()

Opacity, where 0 is transparent and 255 opaque.

opacity(value: number): Modifier

padding()

Inner spacing. padding(16) is 16 on every edge; padding(20, 24) is 20 vertical and 24 horizontal.

The protocol’s Dimensions requires top and end and defaults bottom to top and start to end, which is exactly a vertical/horizontal shorthand. Naming it that way is what makes the missing-end error unreachable. Reach for paddingEach when the four edges genuinely differ.

padding(vertical: Size, horizontal: Size = vertical): Modifier

paddingEach()

Inner spacing with every edge named.

paddingEach(edges: Dimensions): Modifier

rounded()

Rounded corners of the given radius.

rounded(radius: Size): Shape

row()

Children laid out horizontally.

row(children: RendererNode[], options: RowOptions = {}): RendererNode

spacer()

Empty space of a fixed size.

spacer(options: SpacerOptions): RendererNode

square()

Square corners.

square(): Shape

str()

A raw string node. text is what you usually want.

str(content: string): RendererNode

text()

A line of text, wrapped in the String child the protocol requires.

text(content: string, options: TextOptions = {}): RendererNode

textField()

An editable field. Give it a valueChangeAction or it reports nothing.

textField(options: TextFieldOptions): RendererNode

validateFace()

Check a face against the renderer protocol.

Errors are what the protocol forbids: no host can draw them. Warnings are shapes the protocol allows and a product almost certainly did not mean, such as a misspelled prop name, which every host silently ignores.

Pass options.host when you are about to ship to one host and want its own bounds enforced rather than merely reported.

A host’s cap on face size is measured against what you pass. A string is measured as it stands, and a tree is measured as compact JSON. If you write a preview file with indentation, pass the text you are about to write rather than the tree, or the check will measure something smaller than the file.

validateFace(face: unknown, options: ValidateFaceOptions = {}): FaceVerdict

width()

A fixed width.

width(value: Size): Modifier

Interfaces

interface BoxOptions

Options every node with modifiers accepts.

Extends: NodeOptions

Properties

contentAlignment
propertyoptionalContentAlignment

interface ButtonOptions

Options every node with modifiers accepts.

Extends: NodeOptions

Properties

clickAction
propertyoptionalstring

The id the host reports when the button is pressed. A button without one is inert.

enabled
propertyoptionalboolean
loading
propertyoptionalboolean
variant
propertyoptionalButtonVariant

interface ColumnOptions

Options every node with modifiers accepts.

Extends: NodeOptions

Properties

horizontalAlignment
propertyoptionalHorizontalAlignment
verticalArrangement
propertyoptionalArrangement

interface Dimensions

Edge dimensions. bottom defaults to top and start to end when absent.

Properties

bottom
propertyoptionalSize

Bottom edge; defaults to top.

end
propertySize

End edge.

start
propertyoptionalSize

Start edge; defaults to end.

top
propertySize

Top edge.

interface FaceIssue

One thing wrong with a face, and where.

Properties

code
propertyFaceIssueCode
message
propertystring
path
propertystring

Where in the tree, as .value.children[2].value.props.style. Empty for the face itself.

interface FaceVerdict

Properties

errors
propertyFaceIssue[]

What the protocol forbids. No host can draw a face with any of these.

ok
propertyboolean

True when there are no errors. Warnings never make a face invalid.

warnings
propertyFaceIssue[]

What the protocol allows and no product means.

interface HostLimits

One host’s own bounds.

Properties

maxBytes
propertynumber

Largest face, measured as JSON text in bytes.

maxDepth
propertynumber

Deepest tree the host will decode, counting the root as level 1.

maxSizeValue
propertynumber

Largest value a Size may carry.

name
propertystring

Named in every message about these bounds, so advice says who is asking.

interface ImageOptions

Options every node with modifiers accepts.

Extends: NodeOptions

Properties

fit
propertyoptionalImageFit

interface NodeOptions

Options every node with modifiers accepts.

Properties

modifiers
propertyoptionalModifier[]

interface RowOptions

Options every node with modifiers accepts.

Extends: NodeOptions

Properties

horizontalArrangement
propertyoptionalArrangement
verticalAlignment
propertyoptionalVerticalAlignment

interface SpacerOptions

Properties

height
propertyoptionalSize
width
propertyoptionalSize

interface TextFieldOptions

Options every node with modifiers accepts.

Extends: NodeOptions

Properties

enabled
propertyoptionalboolean
label
propertyoptionalstring
placeholder
propertyoptionalstring
text
propertystring
valueChangeAction
propertyoptionalstring

The id the host reports on every change, carrying the new value.

interface TextOptions

Options every node with modifiers accepts.

Extends: NodeOptions

Properties

color
propertyoptionalColorToken
style
propertyoptionalTypographyStyle

interface ValidateFaceOptions

Properties

host
propertyoptionalHostLimits

Check against one host’s own bounds and report a breach as an error. Left out, every known host’s bounds are checked and a breach is a warning naming that host.

Type Aliases

type Arrangement

Main-axis distribution of children.

type Arrangement = Codec<Arrangement>

type Arrangement

Main-axis distribution of children.

type Arrangement = "Start" | "End" | "Center" | "SpaceBetween" | "SpaceAround" | "SpaceEvenly"

type BlendingMode

How a node composites with what is behind it. The values are those common to CSS mix-blend-mode, SwiftUI BlendMode and Compose BlendMode.

type BlendingMode = Codec<BlendingMode>

type BlendingMode

How a node composites with what is behind it. The values are those common to CSS mix-blend-mode, SwiftUI BlendMode and Compose BlendMode.

type BlendingMode = "Normal" | "Multiply" | "Screen" | "Overlay" | "Darken" | "Lighten" | "ColorDodge" | "ColorBurn" | "HardLight" | "SoftLight" | "Difference" | "Exclusion" | "Hue" | "Saturation" | "Color" | "Luminosity"

type ButtonVariant

Button emphasis.

type ButtonVariant = Codec<ButtonVariant>

type ButtonVariant

Button emphasis.

type ButtonVariant = "Primary" | "Secondary" | "Text"

type ColorToken

Semantic color tokens, resolved by the host’s theme.

type ColorToken = Codec<ColorToken>

type ColorToken

Semantic color tokens, resolved by the host’s theme.

type ColorToken = "FgPrimary" | "FgSecondary" | "FgTertiary" | "BgSurfaceMain" | "BgSurfaceContainer" | "BgSurfaceNested" | "FgSuccess" | "FgError" | "FgWarning"

type ContentAlignment

Placement of content within a Box.

type ContentAlignment = Codec<ContentAlignment>

type ContentAlignment

Placement of content within a Box.

type ContentAlignment = "TopStart" | "TopCenter" | "TopEnd" | "CenterStart" | "Center" | "CenterEnd" | "BottomStart" | "BottomCenter" | "BottomEnd"

type Dimensions

The protocol’s own vocabulary types, re-exported so one import covers a face.

type Dimensions = Codec<Dimensions>

type Effect

A visual effect. Each variant names one effect and carries its parameters.

type Effect = Codec<"Rainbow">

type Effect

A visual effect. Each variant names one effect and carries its parameters.

type Effect = "Rainbow"

type FaceIssueCode

What is wrong with a face.

type FaceIssueCode = "invalid-json" | "not-an-object" | "missing-tag" | "unknown-node" | "unknown-modifier" | "unknown-shape" | "unknown-image-source" | "unknown-enum" | "missing-field" | "wrong-type" | "size-not-integer" | "size-negative" | "size-too-large" | "opacity-out-of-range" | "tree-too-deep" | "unknown-field" | "button-without-action" | "text-field-without-action" | "text-without-content" | "host-limit-depth" | "host-limit-size" | "host-limit-bytes"

type HorizontalAlignment

Cross-axis alignment of Column children.

type HorizontalAlignment = Codec<HorizontalAlignment>

type HorizontalAlignment

Cross-axis alignment of Column children.

type HorizontalAlignment = "Start" | "Center" | "End"

type ImageFit

How an image meets the box its modifiers size.

type ImageFit = Codec<ImageFit>

type ImageFit

How an image meets the box its modifiers size.

type ImageFit = "None" | "Fill" | "Cover" | "Contain" | "ScaleDown"

type ImageSource

Where image bytes come from. The host fetches them; the tree carries no URL.

type ImageSource = Codec<ImageSource>

type ImageSource

Where image bytes come from. The host fetches them; the tree carries no URL.

type ImageSource = { tag: "Bulletin"; value: string } | { tag: "Archive"; value: string }

type Modifier

Layout and styling applied to one node.

type Modifier = Codec<Modifier>

type Modifier

Layout and styling applied to one node.

type Modifier = { tag: "Margin"; value: Dimensions } | { tag: "Padding"; value: Dimensions } | { tag: "Background"; value: Background } | { tag: "Border"; value: BorderStyle } | { tag: "Height"; value: Size } | { tag: "Width"; value: Size } | { tag: "MinWidth"; value: Size } | { tag: "MinHeight"; value: Size } | { tag: "FillWidth"; value: boolean } | { tag: "FillHeight"; value: boolean } | { tag: "Opacity"; value: number } | { tag: "BlendingMode"; value: BlendingMode }

type RendererNode

A node in a product-rendered tree. Container variants recurse through children.

type RendererNode = Codec<RendererNode>

type RendererNode

A node in a product-rendered tree. Container variants recurse through children.

type RendererNode = { tag: "Nil"; value?: undefined } | { tag: "String"; value: { text: string } } | { tag: "Box"; value: { children: RendererNode[]; modifiers: Modifier[]; props: BoxProps } } | { tag: "Column"; value: { children: RendererNode[]; modifiers: Modifier[]; props: ColumnProps } } | { tag: "Row"; value: { children: RendererNode[]; modifiers: Modifier[]; props: RowProps } } | { tag: "Spacer"; value: { modifiers: Modifier[] } } | { tag: "Text"; value: { children: RendererNode[]; modifiers: Modifier[]; props: TextProps } } | { tag: "Button"; value: { children: RendererNode[]; modifiers: Modifier[]; props: ButtonProps } } | { tag: "TextField"; value: { modifiers: Modifier[]; props: TextFieldProps } } | { tag: "Image"; value: { modifiers: Modifier[]; props: ImageProps } } | { tag: "Effect"; value: { children: RendererNode[]; props: EffectProps } }

type Shape

Outline of a background or border.

type Shape = Codec<Shape>

type Shape

Outline of a background or border.

type Shape = { tag: "Rounded"; value: Size } | { tag: "Circle"; value?: undefined } | { tag: "Square"; value?: undefined }

type Size

A size in logical pixels, SCALE-encoded as Compact<u64>.

type Size = Codec<Size>

type Size

A size in logical pixels, SCALE-encoded as Compact<u64>.

type Size = number | bigint

type TypographyStyle

Typography presets, resolved by the host’s design system.

type TypographyStyle = Codec<TypographyStyle>

type TypographyStyle

Typography presets, resolved by the host’s design system.

type TypographyStyle = "HeadlineLarge" | "TitleMediumRegular" | "BodyLargeRegular" | "BodyMediumRegular" | "BodySmallRegular"

type VerticalAlignment

Cross-axis alignment of Row children.

type VerticalAlignment = Codec<VerticalAlignment>

type VerticalAlignment

Cross-axis alignment of Row children.

type VerticalAlignment = "Top" | "Center" | "Bottom"

Variables

androidLimits

The Polkadot Android app.

maxDepth and maxSizeValue come from its RendererNodeJsonDecoder, where the size ceiling is Int.MAX_VALUE because the tree maps into Compose, which reads a size back as an Int. maxBytes is its MAX_FACE_BYTES, applied both to a streamed face and to a preview file in the worker archive.

let androidLimits: HostLimits = ...

KNOWN_HOST_LIMITS

Every host whose bounds we know.

A caller who names no host is checked against all of these, as advice. The iOS app has no renderer yet; it joins this list when it does.

let KNOWN_HOST_LIMITS: readonly HostLimits[] = ...