button element
Does something when pressed: navigate, open a dialog, change client state, call an API, sign out, share, pay…
Renders
<button> (or <a> for action: "navigate"), class iwc-button iwc-button-<variant>Required
label (or content, bind, child elements). Actions navigate, open, toggle and scroll need target; state needs store and mutation; api needs api.Native apps
Compiled native apps and server-driven apps
Syntax
{ "type": "button" }An element lives in a screen's sections, another element's elements, a layout slot or a component root.
Properties
| Property | Type | Default | Description |
|---|---|---|---|
store | string | — | state store for action=state |
mutation | string | — | identifiers use letters, digits and '_' and do not start with a digit |
api | string | — | the api file to call (phoneSignIn: the auth.exchange api) |
success | object | — | api buttons: what happens after a 2xx answer
|
action | "navigate""open""close""toggle""submit""state""api""logout""scroll""share""install""notifications""sync""pay""tracking""native" | — | share: the system share sheet (web: Web Share, else copies the link) for target (default: this page) with value as the message; install: the browser's install prompt (pwa; hidden until the app can be installed); notifications: ask for notification permission and send the push subscription to pwa.push; sync: open the list of changes waiting to sync (offline); pay: call api for a payment, open the provider's payment sheet in a native app (hosted checkout on the web) and check it with confirm; tracking: value "start"/"stop" background location (platforms.*.background.location); native: call your own Kotlin/Swift extension named by target ("Scanner.scan") with value, and post its result to api |
label | string | — | |
variant | string | primary | text: heading, h1-h6, subheading, paragraph, caption, label, quote, code; button: primary, secondary, ghost |
target | string | — | route, element id, or URL |
newTab | boolean | — | |
value | any | — | value passed to a state mutation; strings starting with item. or props. are bound |
confirm | string | — | pay: the api that checks the payment on the server (it receives {id, provider, paymentId, signature, status}); the screen shows success only when it answers 2xx |
Plus the properties every element accepts: id, className, style, responsive, states, animation, visible, ariaLabel, attributes and more.
Events & actions
Actions: navigate · open · close · toggle · scroll · state · api · logout · share · install · notifications · sync · pay · tracking · native. API buttons send Idempotency-Key automatically and show a busy state while waiting.
Example
{
"type": "row",
"layout": { "gap": "12px", "wrap": true },
"elements": [
{ "type": "button", "label": "Shop now", "action": "navigate", "target": "/products" },
{
"type": "button",
"label": "Add to cart",
"variant": "secondary",
"action": "state",
"store": "cart",
"mutation": "add",
"value": { "id": "p-lamp", "name": "Desk Lamp", "price": 89, "quantity": 1 }
},
{
"type": "button",
"label": "Size guide",
"variant": "ghost",
"action": "open",
"target": "size-guide"
}
]
}variant is primary, secondary or ghost; any other word adds the class iwc-button-<word>. An api button fills :id-style path parameters from the current record, so a Delete button inside a list deletes its own row; success decides what happens next (message, navigate, reload, mutation).
Expected output
The HTML IWC rendered for the example above (inside the page's content wrapper). Class names such as i807b63fc are generated per element for its scoped CSS.
<div class="iwc-page ipage" id="iwc-content">
<div class="iwc-row i072c87e5">
<a class="iwc-button i31c3d13a iwc-button-primary" href="/products">Shop now</a>
<button class="iwc-button id3909b42 iwc-button-secondary" type="button" data-iwc-action="state" data-store="cart" data-mutation="add" data-value="{"id":"p-lamp","name":"Desk Lamp","price":89,"quantity":1}">
Add to cart
</button>
<button class="iwc-button i2ab48b08 iwc-button-ghost" type="button" data-iwc-action="open" data-target="size-guide">
Size guide
</button>
</div>
</div>Data, conditions & styling
- Conditional rendering:
"visible": {"auth": "signed-in"},{"roles": ["admin"]}or an expression such as"=product.stock > 0". Decided on the server: hidden elements are never sent. - Data binding:
bindtakes text from data (name,user.name,props.title,params.slug,state.cart.count);bindsbinds attributes. Containers become data-driven withdata+item. See data binding. - Styling:
classNamefor your stylesheets,stylefor CSS in JSON,statesfor hover/focus/active,animationfor entrance motion. See the style property reference. - Responsive behaviour:
responsiveapplies CSS at or below a breakpoint ({"mobile": {"padding": "12px"}}); grids also takeresponsiveColumns.