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.
The built-in catalog
Section titled “The built-in catalog”Inputs
Section titled “Inputs”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 |
geo-point |
object | GeoJSON Point: click the map or type latitude / longitude; Leaflet loaded lazily, OpenStreetMap tiles by default |
geo-area |
object | GeoJSON Polygon or LineString (shape): click to add vertices, drag to move, right-click to remove |
geo-address |
object | address search while typing (Nominatim by default, searchUrl with {q}), stored as a GeoJSON Feature with the normalised address and its point, adjustable on a map |
geo-layer |
object | a zone picked on a reference layer (layerUrl, GeoJSON FeatureCollection; codeProperty / nameProperty), stored as { code, name }, an array with multiple; a select lists the zones without the map |
national-id |
string | national identifier checked by idFormat: fr-nir (13 digits + key), bj-npi (10 digits), digits-<n> |
mrz |
object | machine-readable zone of a passport (2 × 44) or identity card (3 × 30): fields parsed, every ICAO 9303 check digit verified, the form refuses an inconsistent zone |
tax-id |
string | tax identifier checked by idFormat: bj-ifu (13 digits), fr-siren / fr-siret (Luhn key), digits-<n> |
iban |
string | IBAN checked with ISO 7064 mod 97-10, grouped by four on blur |
money |
object | { amount, currency }, the currency picked among currencies with currency as default |
appointment |
object | a slot { id, start, end } picked day by day, from slotsUrl (list with remaining) or generated from opening rules (days, from, to, duration, horizonDays, noticeHours, exclude) |
date-range |
object | { from, to }, the end never before the start |
document |
object | a scanned or uploaded document read by the host (services.documentReaderService, readUrl): the text read, the fields asked for (`key |
measure |
object | { value, unit, base }: a number with a unit of its family (length, area, mass, volume, duration), units restricting the choice, base holding the value in the family’s base unit (m, m², kg, l, h) so totals can mix units |
vehicle-plate |
string | registration plate checked by plateFormat (fr, bj, ci, sn, generic), upper-cased while typing and formatted on blur |
company-registry |
string | company registration number checked by registryFormat (ohada-rccm, fr-rcs, generic) |
Brick id |
Type | Notes |
|---|---|---|
file |
input / object | pluggable upload, per-brick uploadUrl, multiple mode |
data-grid |
collection / array | repeating rows with per-row validation |
key-value |
input / object | a flat object edited row by row (keyLabel, valueLabel); values take template variables from the form context like text fields |
hidden |
input / string | carries a value without rendering |
Layout
Section titled “Layout”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 |
Behaviors worth knowing
Section titled “Behaviors worth knowing”Select and multi-select
Section titled “Select and multi-select”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.
Data grid
Section titled “Data grid”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.
Stepper and tabs
Section titled “Stepper and tabs”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.
Text and phone
Section titled “Text and phone”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.
Registering your own brick
Section titled “Registering your own brick”createBrick returns a brick the registry accepts. The render function
receives the brick’s props and returns a virtual node:
-
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) ? '★' : '☆'))),}) -
Register it once, before the builder mounts.
registerBrick(ratingBrick) -
It now appears in the palette under its
category, and renders wherever a spec uses"id": "rating".
Next steps
Section titled “Next steps”A project by Streamline Pulse