H3lp Yours3lfDocs
api

UI Components

H3 UI component contracts and copyable examples.

H3 components are passive layout builders for registered menu and player scripts. Each call returns an OpenMW layout; it does not create an element or own your state. Start with UI Layouts and Lifecycle, jump to a UI recipe for a complete surface, or use H3UI when you want recipes, player-configured appearance, tokens, and a style cascade above these primitives.

A content-only root uses ui.TYPE.Container so it sizes itself to its children. The default ui.TYPE.Widget is also valid, but needs explicit geometry.

Choose by job

NeedComponents
Basic layout shapewidget, container, row, column
Text, images, and spacingtext, image, spacer
Lists and repeated contentlist, listItem, grid
Framed contentbox, bookFrame, dialog, tooltip
Actions and indicatorsbutton, iconButton, meter, itemSlot
State and inputtoggle, slider, selector, numberInput, searchInput, textInput
Tabbed or expandable contenttabs, collapsible
Morrowind window chromeheadBlock, caption, pinButton, window

Shared layout options

Most builders accept these layout fields:

FieldTypeDescription
namestring?Name a child for lookup from its owning Content.
propstable?Set layout properties such as size, position, or visible.
externaltable?Set parent-facing properties such as grow or stretch.
eventstable?Supply low-level OpenMW callbacks. Wrap them with async:callback.
userDataany?Attach caller-owned data to a layout.
templateopenmw.ui.Template?Override the default template where supported.
contentopenmw.ui.Content?Provide child content; takes precedence over children.
childrenopenmw.ui.LayoutOrElement[]?Provide child layouts when content is absent.

The builders shallow-copy props and external. They do not copy child layouts, textures, or caller state deeply.

Mount a component

local ui = require 'openmw.ui'
local column = require 'scripts.s3.components.column'
local text = require 'scripts.s3.components.text'
local util = require 'openmw.util'

ui.create {
  type = ui.TYPE.Container,
  layer = 'Windows',
  props = {
    position = util.vector2(80, 80),
  },
  content = ui.content {
    column {
      children = {
        text {
          text = 'Hello from H3',
        },
      },
    },
  },
}

Keep element when a callback changes layout state, then call element:update(). Rebuild the root for structural changes. The component tests provide larger executable constructions.