API reference

Template syntax

The markup of a component is HTML with C# expressions in braces. The compiler turns each form into the exact update it needs; nothing is interpreted at runtime.

Text and attributes

SyntaxMeaning
{expr}Text. C# interpolation rules apply: {time:F1}, {gold:N0}. Numbers, strings, booleans and enums are written without allocating
{(a ? b : c)}A conditional expression needs parentheses
{T("menu.play")}, {T("hud.gold", gold)}A text in the current locale; updates when the locale changes
attr={expr}An attribute, or a property such as value, checked, disabled
attr="text {expr}"An attribute with text around the expression
{@html expr}HTML parsed at runtime. Allocates: not for values that change every frame

Directives

SyntaxMeaning
class:name={cond}Adds the class while the condition is true
style:width="{percent}%", style:color={item.Color}A typed inline style: a direct setter, with no CSS parsing
style:translate={position}Moves the element without restyle, layout or paint
bind:value={x}, bind:checked={x}Two-way binding to a form control
bind:Value={x}Two-way binding to a [Bindable] prop of a child component
bind:this={el}A reference to the element, or to the child component
query:api="name", query:api="item-{item.Id}"The name game code finds the element or component by

Events

SyntaxMeaning
onclick={Handler}A method of the script
onclick={() => count++}An inline handler
onpointerdown={e => Press(e)}An inline handler that takes the event

The delegate is made once, when the element is built: not per click and not per frame. Any DOM event works as on plus its name: onpointermove, onkeydown, oninput, onwheel.

Blocks

SyntaxMeaning
{#if a}…{:else if b}…{:else}…{/if}Conditional content
{#each items as item, i (item.Id)}…{:else}…{/each}A keyed list: rows move instead of being rebuilt. {:else} shows when the list is empty
{#each items as item, i}…{/each}Without a key the index is the key, and rows get new items in place
{#virtual items as item, i (30)}…{/virtual}A long list with rows of one height (CSS pixels). Elements exist only for visible rows; the container needs a height and overflow: auto
{#key value}…{/key}Content rebuilt when the value changes
{@const x = expr}A local value inside a block

Inside {#each} and {#virtual}, item and i are the row's live values: a handler written as onclick={() => Select(item, i)} sees the current ones even after rows moved.

Components and slots

SyntaxMeaning
<Slider Label="Volume" bind:Value={volume} />A child component, after import Slider from "./Slider.dcue";. Self-closing is allowed
<Card Title={name} OnBuy={() => Buy(item)}>…</Card>Props from expressions; the content between the tags goes to the child's slot
<slot />, <slot name="footer" />Where the parent's content goes
<Card --card-bg="#222">A CSS variable passed into the child

Icons

SyntaxMeaning
<Icon id="mdi:home" />An Iconify icon as an inline <svg>. No import
<Icon icon="mdi:cog" id="settings" class="tool" />icon names the icon, so id is the element's own id
<Icon id={(on ? "mdi:eye" : "mdi:eye-off")} />A name from code; ? : needs parentheses
color, width, heightAn inline color and a fixed size. Without a size the icon is 1em high: set font-size

Styles

SyntaxMeaning
<style> .card { … } </style>Rules for this component's own elements only
:global(.dark) .card { … }The part in :global() matches outside the component
var(--card-bg)CSS variables pass through component boundaries

Not supported

Slot props (let:), dynamic tags and dynamic components. HTML entities such as &lt; are decoded by the compiler.