UI content elements
The leaf elements that display something: UIText, UIImage, UIVideo. Each has one mutable
content property (.text, .src, .player) that lives on the element — content is never a
style. For editable text see UIInput in interactive.md.
At a glance
import photo from './photo.jpg'
const caption = UIText("Loading…").style({ color: "white", fontSize: 16 })
const screen = UIScreen([
UIImage(photo).style({ width: "100%", height: 220, borderRadius: 16, objectFit: "cover" }),
caption,
]).style({ bgColor: "black", p: 16, pt: "safe-top", gap: 12 })
screen.open()
caption.text = "Sunset over the harbor" // re-renders immediatelyUIText
UIText(text: string): UIText
text.text = "Updated" // get/set the displayed stringText-specific styles (on top of the common element styles):
textAlign: "start" | "center" | "end" | "left" | "right" // default left
fontFamily: string // system: "serif", "sans-serif", "monospaced"; custom via registerFont
fontSize: UIValue // default 14
lineHeight: UIValue | "normal"
fontWeight: number | "normal" | "bold" // 400, 700, …
fontStyle: "normal" | "italic"
color: Color
textDecoration: "underline" | "line-through" | "none"
letterSpacing: UIValuelineHeight: 1.5 means 1.5 px — a bare number is px everywhere. A multiplier is
"1.5em" (resolved against this element's own fontSize; there is no inheritance).
the default screen background is black — always set color explicitly.
UIText's .style() takes no border/background-image props — bgColor, padding, and margins
work, but a decorated text chip is a UIRow/UIColumn around a UIText. Custom fonts must be
registered before the screen opens — see fonts.md.
UIImage
UIImage(src: ImageSource): UIImage
// ImageSource:
// string — remote URL, or an asset() / imported project file
// FetchResponse — a downloaded body used directly as pixels
// File — from openFilePicker()
// SvgSource — wrapped raw SVG XML
// Canvas — a 2D Canvas, baked to a texture on assign
img.src // get the (resolved) source / set a new one — updates the displayed imageImage-specific styles:
objectFit: "cover" | "contain" | "fill" // how the source maps into the box
tintColor: Color // SVG sources only
borderRadius: number // px (number only on UIImage)tintColor applies only to SVG sources, and it replaces all fill and
stroke colors in the SVG — it's for monochrome icons, not multicolored artwork.
a bare relative path string (UIImage("./photo.png")) does not resolve to a bundled
asset — plain strings work only for https://… URLs. Import the file or use asset('./photo.png').
Cropping an atlas: setSourceRect
img.setSourceRect(x: number, y: number, w: number, h: number): this // texture pixelsRenders only a sub-rectangle of the source — the spritesheet primitive. The rect's w/h become
the element's intrinsic size (one frame, not the whole atlas), and the cropped frame always fills
the box, overriding objectFit. Chainable and safe to call before the element is on screen (the
initial crop is applied at mount). Sprite-style animation is swapping the rect per frame:
const icon = UIImage(atlasUrl).style({ width: 64, height: 64 }).setSourceRect(0, 0, 128, 128)
let frame = 0
setInterval(() => { icon.setSourceRect((++frame % 8) * 128, 0, 128, 128) }, 100)Pitfall: bgImage is not image content
const img = UIImage("") // ✗ empty source as a placeholder
img.style.bgImage = url // ✗ bgImage is container decoration, not content
const img = UIImage(url) // ✓ the source goes in the constructor…
img.src = newUrl // ✓ …and swaps via .srcUIVideo
UIVideo(player: VideoPlayer): UIVideo
video.player // read-only — the VideoPlayer passed at constructionThe element is just the on-screen surface; playback lives entirely on the
VideoPlayer — create it first, control it directly:
const player = new VideoPlayer(asset('./intro.mp4'))
const video = UIVideo(player).style({ width: "100%", height: 220, borderRadius: 12, objectFit: "cover" })
player.play()Video-specific style:
objectFit: "cover" | "contain" | "fill"UIVideo also accepts the drawable styles (border*, bgColor, …) for framing. The player is
a native resource — dispose() it when the video is gone for good, and stop playback in the
screen's onClose (see Conventions — Lifecycle).
See also
- UI element model — content props vs styles, capturing refs
- Styling — common styles, units,
emresolution - Fonts —
registerFontfor customfontFamily - Media players —
VideoPlayercontrol surface - Interactive elements —
UIInput/UITextAreafor editable text