Block
Block configuration, properties, data binding, slots, events, imports, and helper functions in the Nativeblocks DSL.
A block is a UI component generated from an installed integration. You configure it with a key and optional visibility, set properties, bind data variables, nest children in slots, and attach event handlers. The surface differs per language: Kotlin uses named-argument factory functions, Swift instantiates classes and chains setters, TypeScript uses JSX.
Configuration
Everything is a named argument of the factory function. There is no method chaining.
nativeblocksColumn(
blockKey = "myKey",
blockVisibilityKey = boolVar,
width = NativeblocksColumn.WidthOptions.Match, // picker property -> typed option
paddingTop = "16", // plain property -> String
text = titleVar, // data -> bind a variable
content = { // slot -> nest children
childBlock1()
childBlock2()
},
onClick = { // event -> attach actions
action1()
},
)
| Parameter | Type | Description |
|---|---|---|
blockKey | string | Unique identifier within the frame. Required for blocks referenced in updateBlockProperties(). Auto-generated if omitted. |
blockVisibilityKey | BOOLEAN variable | Links show/hide state to a boolean variable. Auto-generated if omitted. |
Properties
Properties support up to three breakpoints: mobile, tablet, desktop. Only mobile is mandatory; tablet and desktop fall back to the mobile value unless you override them.
Each property takes a single value applied to all breakpoints. Picker properties take a generated option; plain properties take a String.
nativeblocksColumn(
blockKey = "root",
width = NativeblocksColumn.WidthOptions.Match, // picker option
paddingTop = "16", // plain String
)
Common dimension values: "match" fills the parent, "wrap" fits the content.
Typed properties
Properties constrained to a picker also expose a type-safe form. Prefer it to catch invalid values at compile time; use the string form when the value is dynamic.
// Typed option (validated at compile time)
nativeblocksColumn(blockKey = "root", width = NativeblocksColumn.WidthOptions.Match)
// Dynamic string (loose pickers only)
nativeblocksColumn(blockKey = "root", width = NativeblocksColumn.WidthOptions.Custom(dynamicValue))
Option naming: {ClassName}.{PropertyKey}Options.{Value}, e.g. NativeblocksColumn.WidthOptions.Match. Loose pickers add a .Custom("…") case for arbitrary strings.
Data
Data fields bind a frame variable to the block. Always pass a variable, never a raw string.
Data is a named argument whose name is the data key.
nativeblocksText(blockKey = "title", text = titleVar)
nativeblocksImage(blockKey = "logo", imageUrl = logoVar)
Slots
Slots are named child-block containers. Only layout and container blocks expose slots; leaf blocks like text and image have none.
Each slot is a named-argument lambda. Call child block factories directly inside, they auto-register to the slot.
nativeblocksCard(
blockKey = "card",
content = {
nativeblocksText(blockKey = "title", text = titleVar)
},
leadingIcon = {
nativeblocksImage(blockKey = "icon", imageUrl = iconVar)
},
)
Events
Events attach actions that fire when the block raises them. Event names are defined by the block (e.g. onClick, onLongClick). Multiple actions in the same event run top to bottom.
Events are named-argument lambdas. Call action factories directly inside.
nativeblocksButton(
blockKey = "btn",
onClick = {
navigateAction(actionName = "nav")
script { _, updateVariable, _ ->
updateVariable(loadingVar, "true")
}
},
onLongClick = {
feedbackAction(actionName = "haptic")
},
)
Auto-visibility
Every block without a user-supplied blockVisibilityKey gets one auto-generated as {key}_visibility, and a matching BOOLEAN variable with value "true" is injected into the frame. Only set blockVisibilityKey explicitly when you need to control a block's visibility from a script.
Imports
import com.example.app.generated.shared.*
import com.example.app.generated.integration.android.nativeblocks.column.nativeblocksColumn
import com.example.app.generated.integration.android.nativeblocks.text.nativeblocksText
// iOS equivalents
import com.example.app.generated.integration.ios.nativeblocks.vstack.nativeblocksVstack
Import the generated shared package first (it brings in the NB types and the frame factories), then each block factory directly.
Pattern: {basePackage}.generated.integration.{platform}.nativeblocks.{keyType}.{factoryName}. Import the class as well (…column.NativeblocksColumn) when you use its typed property options.
Naming conventions
Reference blocks by their unversioned alias (no version suffix). It always resolves to the latest installed version.
| API keyType | Class | Factory / component | Unversioned alias |
|---|---|---|---|
nativeblocks/column v2 | NativeblocksColumn2 | nativeblocksColumn2 | NativeblocksColumn / nativeblocksColumn |
nativeblocks/box v3 | NativeblocksBox3 | nativeblocksBox3 | NativeblocksBox / nativeblocksBox |
Only use a versioned name if you explicitly need a specific version.
Helper functions
When the same UI pattern repeats, extract it into a helper declared outside the frame function.
Helpers must extend BlocksScope so block factory calls self-register:
fun BlocksScope.productRow(key: String, nameVar: Variable, priceVar: Variable) {
nativeblocksRow(
blockKey = key,
width = NativeblocksRow.WidthOptions.Match,
content = {
nativeblocksText(blockKey = "${key}Name", text = nameVar)
nativeblocksText(blockKey = "${key}Price", text = priceVar)
},
)
}
fun frame(): NativeblocksFrame = androidFrame(name = "ProductList", route = "/products") {
val name1 by remember("")
val price1 by remember("")
rootBlock {
nativeblocksColumn(blockKey = "main", content = {
productRow("row1", name1, price1)
})
}
}