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.

This package is the protocol as data, plus a checker. validateFace holds a finished tree against the vocabulary, so a face is wrong at build time rather than blank on a phone, and NODE_SCHEMA lets anything that builds trees hold its own coverage against the protocol.

To write a face, reach for @parity/product-sdk-react-renderer, which authors one in JSX. 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
assertFaceValid()validateFace, but throws on any error.
validateFace()Check a face against the renderer protocol.

Interfaces

NameSummary
DimensionsEdge dimensions. bottom defaults to top and start to end when absent.
FaceIssueOne thing wrong with a face, and where.
FaceVerdict—
Field—
HostLimitsOne host’s own bounds.
NodeSchema—
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.
FieldKindWhat a single field may hold.
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.
MODIFIER_SCHEMAThe modifiers, keyed by their tag, each mapped to what its value holds.
NODE_SCHEMAThe node types, keyed by their tag. Typing the key requires every one of them.

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

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

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

Interfaces

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 Field

Properties

required
propertyoptionalboolean
type
propertyFieldKind

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 NodeSchema

Properties

children
propertyoptionalboolean

value.children is part of this node.

fields
propertyoptionalRecord<string, Field>

Fields directly under value. Only String has any.

modifiers
propertyoptionalboolean

value.modifiers is part of this node.

props
propertyoptionalRecord<string, Field>

Fields under value.props.

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 FieldKind

What a single field may hold.

type FieldKind = { kind: "string" } | { kind: "boolean" } | { kind: "size" } | { kind: "opacity" } | { kind: "dimensions" } | { kind: "background" } | { kind: "border" } | { kind: "imageSource" } | { kind: "enum"; members: readonly string[] }

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[] = ...

MODIFIER_SCHEMA

The modifiers, keyed by their tag, each mapped to what its value holds.

let MODIFIER_SCHEMA: Record<ModifierTag, FieldKind> = ...

NODE_SCHEMA

The node types, keyed by their tag. Typing the key requires every one of them.

let NODE_SCHEMA: Record<NodeTag, NodeSchema> = ...
Last updated on