Skip to content

Guides

Bricks

A brick is one node in a form spec — a field, a layout container, or a piece of output. Thirty ship in the box, and the registry that holds them is open: your own bricks are registered the same way and appear in the same palette.

Brick id Data type Notes
text, textarea, password string text supports masks and adornments
email, url, phone string paired with the matching validators
number number min / max / step
date, time, datetime string native pickers
select, radio string single choice
multi-select, select-boxes, tags array multiple choice
checkbox boolean inline label
signature string canvas, stored as a data URL
address object composite field
code string CodeMirror, loaded lazily
Brick id Type Notes
file input / object pluggable upload, per-brick uploadUrl, multiple mode
data-grid collection / array repeating rows with per-row validation
hidden input / string carries a value without rendering
Brick id Type Notes
group, row, column panel fieldset and flex containers
stepper panel wizard with per-step validation
tabs panel optional validate-before-leaving
nested-form panel references another form by specRef
content output static rich text
recap output live summary of the whole form

A searchable combobox implementing the full WAI-ARIA pattern — keyboard navigation, focus management, screen reader announcements. Options come from five sources:

optionsSource Where options come from
static a newline-separated string, or { label, value } objects
dataMap another field’s value in the same form
remote a URL, with {key} and {a.b} interpolation from context and data, plus optional server-side search
catalog a shared list resolved through optionSourceService
js a sandboxed snippet returning the list

labelKey and valueKey accept dotted paths, so name.common reads a nested property of each option object.

The row template is edited like any panel; at render time each row scopes its own data. minItems / maxItems validate the row count, rows reorder with accessible up/down buttons, and errors report as contacts[0].email.

Both gate navigation on validation. stepper validates the current step before advancing and can emit formSubmit from a final Submit button. tabs offers the same as an option, plus arrow-key navigation between tabs.

Optional prefix / suffix adornments, plus a mask config:

Mask token Accepts
9 a digit
a a letter
A a letter, upper-cased
* alphanumeric

Any other character is a literal and inserts itself — with the mask +229 99 99 99 99, the user only types digits: the prefix and the spaces appear on their own.

A live, read-only summary of everything filled so far. groupBySections turns labelled panels into titled sections, and collections render as tables — useful as the last step of a wizard.

createBrick returns a brick the registry accepts. The render function receives the brick’s props and returns a virtual node:

  1. Describe and render it.

    rating-brick.tsx
    import { createBrick, h, registerBrick } from '@streamline-pulse/formkrafter-wc'
    export const ratingBrick = createBrick({
    type: 'input',
    dataType: 'number',
    id: 'rating',
    name: 'Rating',
    category: 'Inputs',
    defaultConfigs: { label: 'Rating' },
    render: (props) =>
    h(
    'div',
    { class: { 'fk-field': true } },
    ...[1, 2, 3, 4, 5].map((star) =>
    h(
    'button',
    {
    type: 'button',
    'aria-label': `${star} stars`,
    onClick: () => props.onDataChange?.(star),
    },
    star <= Number(props.data ?? 0) ? '' : ''
    )
    )
    ),
    })
  2. Register it once, before the builder mounts.

    registerBrick(ratingBrick)
  3. It now appears in the palette under its category, and renders wherever a spec uses "id": "rating".

A project by Streamline Pulse