CalmUI
API Reference

.calmui Reference

Source structure, bindings, directives, scripts, and component boundaries.

A .calmui file is a UTF-8 component source. It is compiled into a versioned .cuipack; Unreal Shipping never parses component source.

Top-level sections

SectionCardinalityPurpose
<import component="Name" from="./Name.calmui" />Zero or moreImport a project component by relative path.
<template>Exactly oneDeclare the element and component tree.
<style scoped>Zero or oneCSS owned by this component type.
<style>Zero or oneGlobal CSS contributed by this component.
<script lang="ts">Zero or oneLocal, sandboxed view behaviour.
MenuButton.calmui
<template>
  <button :disabled="props.disabled" @click="activate">
    <slot>{{ props.label }}</slot>
  </button>
</template>

<style scoped>
button { color: var(--color-text); }
</style>

<script lang="ts">
import { defineComponent } from "@calmui/runtime";

export default defineComponent(({ emit }) => ({
  activate: () => emit("activate"),
}));
</script>

Bindings and events

  • :disabled="props.disabled" binds an attribute.
  • {{ props.label }} binds text.
  • @click="activate" calls a function returned by the script.
  • @click="$emit('activate')" emits directly without a script function.
  • @click="$action('MainMenu.Continue', { saveId: lastSaveId })" dispatches a declared Action Contract directly without a script forwarding function.
  • <slot /> and <slot name="header">fallback</slot> project caller content.

Template expressions are intentionally small: literals, props, returned script bindings, loop variables, dotted paths, a ternary conditional, .length on an array path, and $emit. They are not general JavaScript expressions. Logical && and || select and return one of their operands, so {{ title || "Untitled" }} remains text rather than becoming a boolean. cond ? a : b (.cuipack 1.13+) short-circuits like JavaScript's - the untaken branch never evaluates, so flag ? "ok" : props.mightBeMissing.length is safe even when props.mightBeMissing is absent while flag is true - and nests without parentheses on either side. items.length reads an array's element count; see docs/calmui-component-format.md for the full profile, including the .length-on-non-array diagnostic and the feature/format gate.

Structure and identity

DirectiveMeaning
ui:if="expression"Create or destroy the subtree.
ui:show="expression"Preserve the instance but suppress paint and hit testing.
ui:for="item in props.items"Repeat content.
ui:virtual="fixed"Window a keyed ui:for with fixed row height.
ui:key="item.id"Give repeated components stable domain identity.

Every component repeated with ui:for requires a stable ui:key; list indexes are not valid identity. This preserves focus and per-instance state across insert, remove, and reorder operations.

Script boundary

Component TypeScript is for local UI behaviour. It can use state, computed, watch, lifecycle hooks, timers, the read-only Store facade, and typed Actions. It cannot read files, use the network, call system APIs, or access Unreal objects directly. Gameplay state remains owned by the C++ Store.

See Components, TypeScript, and the repository contract docs/calmui-component-format.md for compiler-level detail.

On this page