H3 components build OpenMW layout tables. They do not create elements, choose layers, retain your state, or own the lifetime of a rendered surface.
Layout, mount, and update
A layout is a Lua table that describes one widget and its children. An element is the live OpenMW object created from that table. H3 components return layouts; ui.create gives you the element.
local ui = require 'openmw.ui'
local text = require 'scripts.s3.components.text'
local status = text {
text = 'Ready',
}
local element = ui.create {
type = ui.TYPE.Container,
layer = 'Windows',
content = ui.content {
status,
},
}
status.props.text = 'Updated'
element:update()
status is a layout. element is the live mounted OpenMW object. Mutating the layout table does not redraw the engine until the owning element is updated. Use a Container for a content-fitting root; use a Widget when you need explicit size or relativeSize. Rebuild the root for structural changes; use element:update() for property changes.
Callbacks and context
H3 component callbacks are ordinary Lua functions. Low-level OpenMW event callbacks in an events table must be wrapped with async:callback. Interactive components update their own layout state before calling your callback, but they do not know which root owns the rendered tree.
Keep these components in menu or player scripts. A global or local script can coordinate state, but it cannot directly use the UI package.
The UI Components API lists the builders. The UI Recipes show larger compositions.