Box Styles and Composition
This page documents how the default BoxUxPixi composes layers and how styles are resolved.
Every root BoxTree has a style value set in options from @wonderlandlabs-pixi-ux/style-tree that defines how the
background and border of the box is visualized: colors, stroke color and width, and alpha. Individual children are
given styleNames, and styleVerbs that can be changed do interaction (hover, click, etc.) to give visual cues.
In the style tree you can style specific paths such as topPanel.button or generic wildcards such as topPanel.*.button.
You can also create tree-wide targets like icon that are true for icons throughout the tree regardless of location.
The principles here are similar to the specificity pattern in CSS: you can create a generic color like
button.bgColor and an override like button.bgColor + hover with "verbs" that reflect specific interaction situations
or state changes like disabled or primary.
Style Resolution
Each node contributes:
styleNamemodeVerb[]- root
globalVerb[]
The UX resolves each style property using this order:
- Hierarchical property path (
button.icon.bgColor) - Hierarchical object (
button.icon->bgColor) - Atomic property path (
icon.bgColor) - Atomic object (
icon->bgColor)
State list used in lookups:
globalVerb + modeVerb
Default Style Properties
The default UX reads:
bgColorbgAlphabgStrokeColorbgStrokeAlphabgStrokeSize
UX pairing
the BoxTree state is renderer-agnostic; it is not designed to be specific to a particular rendering system (HTML, PIXI, three.js, SVG...) but to have universal positioning and sizing for any number of systems.
Each box has a specific .ux class that renders all the content for the box; by default it is the PIXI based renderer. That renderer produces a background graphic for coloring a rectangle behind all the content, a child collection for injecting all the children of the associated BoxTree, and an overlay container for the graphic that asserts a border outline over all the other parts of the layer.
Custom Layers
A custom system can add other layers around these ones, for instance, for a shadow or a tinted cover; these can be injected into the content map of the renderer by
- creating a custom key(string) to insert content into the content map
- defining an order for that key
- manually creating content and injecting it into the content map
You may want to create a superclass of the renderer.
Built-in layer keys (for the PIXI renderer):
BOX_RENDER_CONTENT_ORDER.BACKGROUND = 0BOX_RENDER_CONTENT_ORDER.CHILDREN = 50BOX_RENDER_CONTENT_ORDER.CONTENT = 75BOX_RENDER_CONTENT_ORDER.OVERLAY = 100BOX_UX_ORDERmaps layer names to z-indexessetUxOrder(name, zIndex)adds/updates a named layer order and throws on duplicate z-indexgetUxOrder(name)resolves named layer order
Each render cycle:
- Built-ins are created if absent
- Child UX instances are resolved
- Children container is cleared and repopulated from current child UX containers
- Optional
box.contentis rendered into theCONTENTlayer (textand image URL content) - Background/stroke graphics are redrawn
- Content map items are sorted by
zIndexand non-empty items are attached to the root container
Render queueing is handled by BoxTree state watchers, not by BoxUxPixi.
Built-in Content Items
BACKGROUND: fill graphic (bgColor)CHILDREN: child UX container hostCONTENT: optional node content host (box.content)OVERLAY: container that holds stroke graphic (bgStrokeColor,bgStrokeSize)
Adding Your Own Layers
import { Graphics } from 'pixi.js';
import { BoxUxPixi } from '@wonderlandlabs-pixi-ux/box';
box.styles = styles;
const ux = new BoxUxPixi(box);
const customLayer = new Graphics();
customLayer.zIndex = 76; // 75 is reserved for CONTENT
customLayer.visible = true;
ux.content.set('CUSTOM', customLayer);
ux.box.render();
Use any string key and set zIndex on the display object to place custom layers.