Skip to content

Common Properties

phroun edited this page Aug 22, 2026 · 3 revisions

Every non-virtual type accepts these, on top of whatever it defines itself. A trinket page lists only what is particular to that trinket; this is the rest.

new label caption="Ready" fg=green stretch=1 align=left
new button caption="Cancel" !enabled acc_name="Cancel and close"
Property Type Default Meaning
acc_name string Accessibility name announced by screen readers.
align fill | left | center | right | top | middle | bottom Layout alignment of this item in its cell.
bg color inherited Background color (named or "#rrggbb").
column_units units inherited Units one grid column spans (denomination override).
enabled flag true Whether the trinket accepts input.
fg color inherited Text/foreground color (named or "#rrggbb").
font ui-text | ui-term | Monday | Tuesday | Black Serif | Double-Struck | Bold Fraktur | Bold Italic | Fraktur | Bold Script | Black Sans | Black Italic | Italic inherited Font family for this trinket's text (graphical: a family or the ui-* tree; text backend: Monday, Tuesday, or a cipher style).
max_height units Maximum height, in units.
max_width units Maximum width, in units.
min_height units Minimum height, in units.
min_width units Minimum width, in units.
name string Debug/tooling label; not identity.
row_units units inherited Units one grid row spans (denomination override).
stretch int 0 Layout stretch factor relative to siblings.
visible flag true Whether the trinket is shown.

A live host answers for itself. conn.Describe() returns the running service's registry, with types, defaults and tips, which is the authority if this table and your build disagree.

Two exceptions

Virtual types do not take them. A virtual type is a piece of another object's structure rather than something placed on its own — an item, a column, a tab, a dockrow. They carry no trinket identity and skip the common set entirely.

A type's own property wins. Where a type defines a property under a name that is also common, its own definition is the one that applies.

Not every type supports every one

The common set is what may be asked; a type answers for what it can do. Ask a type with no text for a font and the property is rejected —

font: not supported by this type

— rather than being silently dropped. A property that appears to have had no effect therefore did not fail: if no error was reported, it was applied.

Writing values

A property is name=value. A flag is written as the bare name, negated with !:

new checkbox caption="Ready" enabled       # on
new checkbox caption="Ready" !enabled      # off
new checkbox caption="Ready" ?checked      # indeterminate, where a type takes it

? asserts indeterminate and is meaningful only where a type has three states — a tri-state checkbox. Everywhere else it is an error rather than a synonym for off. enabled=true / enabled=false also parse, but the bare form is the idiom.

Strings are quoted; words, numbers and colors are not.

Units

min_width, max_height, column_units and row_units are in units, the abstract layout coordinate. A unit is a sub-cell quantity — but how far sub-cell is not a constant. Each container defines it for its own subtree.

column_units and row_units are that definition: how many units make up one character cell here. A trinket resolves them by looking at itself, then walking up its ancestors and taking the first that sets them. 8×16 is only the answer when nothing in the chain does.

So the same number means different things in different places:

new textinput min_width=160
Where it sits Columns
under nothing that sets a denomination (8×16) 20
inside a container with column_units=16 10
inside a container with column_units=1 160

A unit count is therefore only meaningful relative to a denomination, and the denomination is a property of where the trinket sits, not of the value. Write sizes against the denomination of the container you are putting the trinket into.

What units do buy you is independence from the other two variables: at a given denomination, min_width=160 is the same number of columns at every font size, at every zoom, and on both surfaces. The conversion to cells or to pixels happens at paint time.

There is no half a unit. Units are integers everywhere in a layout.

Choosing a denomination

Setting column_units / row_units on a container re-denominates it and everything beneath it, until something deeper sets its own:

p=new panel column_units=1 row_units=1 children={
	new button caption="OK" min_width=6        # six columns, not six eighths
}

Finer units give sub-cell placement — the default 8×16 lets a layout position things at an eighth of a column, which is what makes the same layout land correctly on a pixel surface. Coarser units, down to 1×1, make a unit be a cell, which is simpler when a subtree is only ever going to sit on a character grid.

This is also how a subtree with its own idea of a cell fits in — an embedded terminal at its own font size, an MDI child that scales independently. Since it changes what a unit means inside that subtree, a size written outside it does not describe the same thing inside it.

Layout hints

stretch and align are read by the parent's layout manager, but they live on the child. In a build script that means they must appear on the child's own statement — which they naturally do, since properties apply in the order written:

p=new panel layout=vbox children={
	new label caption="Fixed height"
	new listview stretch=1              # takes the leftover room
	new button caption="OK" align=right
}

stretch is a weight relative to siblings, not a size. 0 (the default) means the trinket takes its preferred size and no more. Two children at stretch=1 split the leftover space evenly; 1 beside 2 splits it one third to two thirds.

align places the trinket within the space it was given, on the axis across the layout: fill (the default) takes the whole cross-axis, and left center right top middle bottom place it and leave the rest.

Colors

fg and bg take either a named color as a bare word, or a hex string:

new label caption="Warning" fg=bright_yellow
new panel bg="#1e1e2e"

The named set is the terminal sixteen plus default: black red green yellow blue magenta cyan white, each with a bright_ twin, and default for the surface's own.

Prefer the names. They resolve through the active palette, so they follow a theme change and mean something sensible on a terminal that has only sixteen colors. A hex value is exact and does neither.

inherited, the default, means the trinket takes its parent's color rather than a fixed one.

Fonts

font names the family for this trinket's text. What resolves depends on the surface:

Value Terminal Graphical
ui-text ui-term the terminal's own glyphs the UI face, proportional or monospaced
Monday Tuesday the built-in text faces the same, resolved as families
Black Serif Fraktur Double-Struck Bold Script rendered as the corresponding Unicode letterforms plain text
any other name ignored the real font family, if the system has it

The cipher styles — Black Serif, Fraktur, Double-Struck, Bold Fraktur, Bold Script, Black Sans, Black Italic, Bold Italic, Italic — work by substituting Unicode's alternate letterforms, which is how a terminal with one font shows several. On a graphical surface, where real faces are available, they stay plain rather than turning your text into mathematical alphanumerics.

Omit font to inherit. There is no way to spell "the default" explicitly — an empty family is an error.

Accessibility

acc_name is what a screen reader announces for the trinket. Set it where the visible text is not the whole story:

new button caption="×" acc_name="Close this window"
new textinput acc_name="Search query"       # the label is a separate trinket

A trinket's role and state — button, checkbox, read-only, disabled — come from its type and its properties and are reported without being asked for. acc_name is only the name.

name is not identity

name is a debug and tooling label. It is not how anything is addressed.

Identity is the handle you bind in the build script:

q=new textinput placeholder="Search"    # q is the handle

and ui.TextInput("q") — or ui.text_input("q"), or kt_ui_id(ui, "q") — is how a client reaches it afterwards. Two trinkets may share a name harmlessly; two handles may not.

See also

Properties and Values · Events · Object Model · TextInput

Clone this wiki locally