name: xb-uiblocks
description: >-
Build rich spatial UI with the uiblocks addon — flexbox-laid-out 3D cards/panels
(UICard, UIPanel, UIText, UIImage, UIIcon) with gradients, strokes,
rounded corners, drop/inner shadows, and spatial behaviors (head-leash, billboard,
grab/manipulate, object-anchor). Use when you need web-like styling fidelity or
real flexbox layout beyond the lightweight core xb.SpatialPanel. Requires
options.uikit.enable(uikit) and the @pmndrs/uikit peer deps. The complete
reference (styling rules, behaviors, gotchas, troubleshooting) lives at
src/addons/uiblocks/SKILL.md.
xb-uiblocks — rich flexbox spatial UI
uiblocks wraps @pmndrs/uikit (yoga flexbox) for styled 3D cards. Use it over the core
xb-ui SpatialPanel when you need flexbox layout, gradients, strokes,
or shadows. Don't mix the two on one panel, and never import UIPanel/UICard from
xrblocks core — they exist only in this addon.
Full reference (UICard/UIPanel/UIText/UIImage/UIIcon props, behaviors, sizing gotchas, and a clicks/styling/sizing troubleshooting playbook):
../../src/addons/uiblocks/SKILL.md. Samples:src/addons/uiblocks/samples/.
Setup
Needs the @pmndrs/uikit + yoga/troika peer deps in your importmap (see the addon
README) and:
const options = new xb.Options();
options.enableUI();
options.uikit.enable(uikit); // REQUIRED — registers the uikit renderer
Quick start
import * as uikit from '@pmndrs/uikit';
import * as THREE from 'three';
import {UICore, UIPanel, UIText, raycastSortFunction} from 'uiblocks';
import * as xb from 'xrblocks';
class CustomScript extends xb.Script {
constructor() {
super();
this.uiCore = new UICore(this);
}
init() {
// REQUIRED for raycasting against uiblocks to work.
if (xb.core.input.raycaster) {
xb.core.input.raycaster.sortFunction = raycastSortFunction;
}
const card = this.uiCore.createCard({
name: 'HelloCard',
sizeX: 1.0,
sizeY: 0.6,
position: new THREE.Vector3(0, 1.5, -1),
width: 'auto',
alignItems: 'center', // shrink-wrap + center (see full ref §5.1)
});
const panel = new UIPanel({
width: '100%',
height: '100%',
fillColor: '#1a1a24',
cornerRadius: 20,
padding: 30,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
});
card.add(panel);
panel.add(
new UIText('Hello World', {
fontSize: 32,
fontWeight: 'bold',
color: 'white',
})
);
}
}
Top rules (see full reference for the rest)
- Borders that follow corners: use
strokeWidth/strokeColor, notborderWidth/borderColor. - Colors are hex strings (
'#ffffff') orTHREE.Color— neverrgba()/hsla(). - No built-in button class: compose a
UIPanel+ childUIText/UIIcon/UIImage. - One
UICardper spatial pivot; partition complex layouts with childUIPanels + flexbox.
Designing complex, elegant spatial UI
For multi-section, polished interfaces, follow the design guide in §6 of the full reference
(../../src/addons/uiblocks/SKILL.md). The essentials:
- Tokens first. Fix a
pixelSize(density), a smallfontSize/fontWeighttype scale, a spacing scale (gap/paddingmultiples of one unit), one–twocornerRadiusvalues, and a restrained hex palette — then reuse them everywhere. - Compose, don't multiply. Build the whole screen inside one
UICard; partition into sections with nestedUIPanels + flexbox (flexDirection,justifyContent,flexGrow). - Elevation, not Z gaps. Convey layering with
dropShadow*,innerShadow*, andstrokeWidth/strokeColor(sharedcornerRadius) — avoid large literalposition.zoffsets. - Comfort + legibility. Place at
xb.user.height/-xb.user.panelDistance; keep opaque enoughfillColor+ a shadow/stroke to read over AR passthrough; size text for distance. - Purposeful motion & affordances.
ToggleAnimationBehaviorfor enter/exit, hover/press states for feedback, gentlelerponHeadLeashBehavior/BillboardBehavior. - Grab & anchor.
ManipulationBehavior({draggable, faceCamera, manipulationMargin})with a header as the grab handle;ObjectAnchorBehavior(+ billboard) for contextual, object-attached UI.
See §6.7 of the full reference for a complete, styled settings-card example.