Skill v1.0.0
currentTrusted Publisher100/100version: "1.0.0" name: xb-ui description: >- Build spatial UI in an XR Blocks app with the core xb.SpatialPanel system — a grid of rows and columns holding text, text buttons, icon buttons, and images, with a unified onTriggered select handler. Use for HUDs, menus, dialogs, and control panels when you want a lightweight, no-extra-dependency UI. For rich flexbox layouts with gradients, strokes, and shadows, use xb-uiblocks instead. Covers addGrid/addRow/addCol/addText/addTextButton/addIconButton, panel positioning, and the enableUI() setup.
xb-ui: core spatial UI (SpatialPanel)
A SpatialPanel hosts a grid; rows and columns nest to lay out views. Lightweight and dependency-free. (For gradients/shadows/flexbox fidelity, use `xb-uiblocks`.) This is for rapid prototyping, if authoring advanced spatial UI, use xb-uiblocks skill.
Setup
const options = new xb.Options();options.enableUI(); // spatial UI + reticlesxb.init(options);
Build a panel
class Menu extends xb.Script {init() {const panel = new xb.SpatialPanel({backgroundColor: '#1a1a1abb',width: 2.5,height: 1.5,});panel.position.set(0, xb.user.height, -xb.user.panelDistance);this.add(panel);const grid = panel.addGrid();// Rows take a `weight` = fraction of the parent's height.grid.addRow({weight: 0.6}).addText({text: 'Welcome to XR',fontColor: '#ffffff',fontSize: 0.08,});const controls = grid.addRow({weight: 0.4});// Columns take a `weight` = fraction of the row's width.const yes = controls.addCol({weight: 0.5}).addIconButton({text: 'check_circle', // Material icon name (fonts.google.com/icons)fontSize: 0.5,});const send = controls.addCol({weight: 0.5}).addTextButton({text: 'Send',fontColor: '#ffffff',backgroundColor: '#4285f4',fontSize: 0.24,});// onTriggered unifies click / pinch / touch on a button.yes.onTriggered = () => console.log('yes');send.onTriggered = () => console.log('send');panel.updateLayouts(); // call after building if you set positions manually}}
Cheatsheet
- Panel:
new xb.SpatialPanel({backgroundColor, width, height, useDefaultPosition});
set panel.position and (for a manually placed root) panel.isRoot = true.
- Containers:
panel.addGrid()→grid.addRow({weight})→row.addCol({weight}). - Views:
.addText({text, fontColor, fontSize}),
.addTextButton({text, fontColor, backgroundColor, fontSize}), .addIconButton({text: '<material_icon>', fontSize}). Update text via view.text = '…'.
- Scrolling text:
new xb.ScrollingTroikaTextView({text, fontSize})then.addText(str). - Interactions: assign
button.onTriggered = () => {…}; colors are hex strings.
See templates/1_ui, templates/6_ai, and samples/sound for complete panels.