Composition / foldkit-composition/surface

SurfaceBlock

namespace · packages/composition/src/surface/index.ts:78

const SurfaceBlock = { define, reads, active, families }

Its type

type SurfaceBlock<
  Name extends string,
  Props extends Schema.Top,
  Regions extends Readonly<Record<string, Region>>,
  Model,
> = Block<Name, Props, Regions> & {
  readonly value: (data: unknown) => Option.Option<Model>
}

A Block that shows a Surface's feature.

In the guides

Members

SurfaceBlock.define

function · packages/composition/src/surface/index.ts:80

define<
  const Name extends string,
  Props extends Schema.Top,
  Root,
  Model,
  Message,
  Params,
  const Regions extends Readonly<Record<string, Region>> = {},
>(
  name: Name,
  config: {
    readonly Props: Props
    readonly regions?: Regions
    readonly provides: ReadonlyArray<Content>
    readonly surface: Surface<Root, Model, Message, Params>
    readonly params: (props: Props['Type']) => Params
  },
): SurfaceBlock<Name, Props, Regions, Model>

A Block showing surface, with the params params makes of its props.

SurfaceBlock.reads

function · packages/composition/src/surface/index.ts:124

reads<Root>(
  catalog: Catalog,
  document: Document,
): Option.Option<Projection<Root, Readonly<Record<string, unknown>>>>

Every Surface Block on the page as one Projection over the Model, keyed by node id; none when the page has none. A node whose props do not decode, or whose Block the Catalog lacks, reads nothing.

SurfaceBlock.active

function · packages/composition/src/surface/index.ts:153

active<Root>(
  name: string,
  owner: object,
  catalog: Catalog,
  documentOf: (model: Root) => Option.Option<Document>,
): PageReads<Root>

The page's Surface Blocks as an active Surface of the application owner (App.owner), for Data.wiring, Data.subscriptions or an SSR plan's surfaces: active while documentOf gives a page, and may send what each Surface lists. A Surface of another application is refused here.

SurfaceBlock.families

function · packages/composition/src/surface/index.ts:201

families<Root, ParentModel>(
  catalog: Catalog,
  config: {
    readonly from: ActiveSurface<Root, ParentModel>
    readonly document: (parent: ParentModel) => Document | undefined
  },
): Readonly<Record<string, SurfaceSource<Root>>>

Every Surface Block on the page as one Surface.each family per Block, keyed by Block name, each instance keyed by its node id. Where reads combines a page into one Projection for the Renderer, families keep each node's Surface, params, and requirements first-class, so Data.wiring, Data.subscriptions, Data.satisfy, and an SSR plan follow what the Document holds — including a draft preview overlay, which only changes what document returns.

from is the Surface whose Model carries the page (a route's Surface, say); document reads the Document out of it. A node whose props do not decode, or whose Block the Catalog lacks, resolves to no instance, as with reads. Blocks without a Surface have no family.