IfcSpatialElement
spatial tree
Universal AEC interface component. Anchored to IfcSpatialElement in the IFC 4.3
hierarchy; classified as Uniclass SL. Consumed by app-workplace-bim
(Tauri 2.10 + xeokit) and app-console-bim (web-only read surface) under the
mode-prop pattern.
Preview
recipe.html
<!-- bim-spatial-tree — universal AEC interface component.
Default expansion: storey-level (per BB.4 Bonsai research).
Mode prop: workplace (selectable, draggable, editable) | console (selectable, read-only).
Purpose-built widget — NOT a repurposed scene-graph viewer.
-->
<aside class="bim-spatial-tree" data-mode="console" aria-label="Spatial hierarchy">
<header class="bim-spatial-tree__header">
<h3>Spatial</h3>
<input type="search" class="bim-spatial-tree__search"
placeholder="Search by space name…"
aria-label="Search spaces" />
</header>
<ul class="bim-spatial-tree__list" role="tree">
<li role="treeitem" aria-expanded="true" data-ifc-class="IfcSite">
<span class="bim-spatial-tree__icon" aria-hidden="true">⌧</span>
<span class="bim-spatial-tree__label">Site</span>
<ul role="group">
<li role="treeitem" aria-expanded="true" data-ifc-class="IfcBuilding">
<span class="bim-spatial-tree__icon" aria-hidden="true">▣</span>
<span class="bim-spatial-tree__label">Building A</span>
<ul role="group">
<li role="treeitem" aria-expanded="true" data-ifc-class="IfcBuildingStorey">
<span class="bim-spatial-tree__icon" aria-hidden="true">═</span>
<span class="bim-spatial-tree__label">Ground Floor</span>
<ul role="group" hidden><!-- spaces deliberately collapsed by default --></ul>
</li>
<li role="treeitem" aria-expanded="true" data-ifc-class="IfcBuildingStorey">
<span class="bim-spatial-tree__icon" aria-hidden="true">═</span>
<span class="bim-spatial-tree__label">Level 02</span>
<ul role="group" hidden></ul>
</li>
<li role="treeitem" aria-expanded="true" data-ifc-class="IfcBuildingStorey">
<span class="bim-spatial-tree__icon" aria-hidden="true">═</span>
<span class="bim-spatial-tree__label">Level 03</span>
<ul role="group" hidden></ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</aside>
recipe.css
.bim-spatial-tree {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
font-size: 0.9rem;
color: #1a1a1a;
border-right: 1px solid #e5e7eb;
background: #fafbfc;
width: 18rem;
height: 100%;
overflow-y: auto;
display: flex;
flex-direction: column;
}
.bim-spatial-tree__header {
padding: 0.75rem;
border-bottom: 1px solid #e5e7eb;
background: #fff;
position: sticky;
top: 0;
}
.bim-spatial-tree__header h3 {
margin: 0 0 0.5rem;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
color: #6b7280;
}
.bim-spatial-tree__search {
width: 100%;
padding: 0.4rem 0.6rem;
font: inherit;
border: 1px solid #d1d5db;
border-radius: 4px;
}
.bim-spatial-tree__list {
list-style: none;
margin: 0;
padding: 0.5rem 0;
}
.bim-spatial-tree__list ul {
list-style: none;
margin: 0;
padding-left: 1.25rem;
}
.bim-spatial-tree__list li[role="treeitem"] {
padding: 0.25rem 0.5rem;
cursor: pointer;
display: flex;
align-items: center;
gap: 0.5rem;
border-radius: 3px;
}
.bim-spatial-tree__list li[role="treeitem"]:hover {
background: #e5e7eb;
}
.bim-spatial-tree__list li[role="treeitem"][aria-selected="true"] {
background: #1e3a8a;
color: #fff;
}
.bim-spatial-tree__icon {
display: inline-block;
width: 1rem;
text-align: center;
font-size: 0.85rem;
color: #6b7280;
}
.bim-spatial-tree[data-mode="workplace"] .bim-spatial-tree__list li[role="treeitem"] {
/* draggable affordance for authoring mode */
cursor: grab;
}
aria.md
bim-spatial-tree — accessibility
Role and structure
- Container is
<aside aria-label="Spatial hierarchy">. - Tree is
<ul role="tree">. - Each spatial item is
<li role="treeitem" aria-expanded="…">. - Children are
<ul role="group">. - The
aria-expandedattribute reflects the collapse/expand state. Storey-level nodes default toaria-expanded="true"; their child<ul role="group">ishiddenby default to defer per BB.4 ("expanded-to-storey, no auto-expand to spaces").
Selection
- Selected node carries
aria-selected="true". - Multi-select is allowed in workplace mode (
Ctrl/Cmd-click,Shift-click); console mode is single-select.
Keyboard navigation
| Key | Action |
|---|---|
| Arrow Up / Down | Move focus between sibling tree items |
| Arrow Right | Expand the focused item if it has children; otherwise focus first child |
| Arrow Left | Collapse the focused item if expanded; otherwise focus parent |
| Enter / Space | Activate (select) the focused item |
| Home / End | Focus first / last visible tree item |
| / (slash) | Move focus to the search input |
Search
- Search input is
<input type="search" aria-label="Search spaces">. - Search filters the tree by space name (
IfcSpace.LongName,IfcSpace.Name), case-insensitive substring match. - Match results expand the matching path automatically; non-matching branches collapse.
Mode-prop behaviour
data-mode="workplace"— affordance for drag-to-reorder and multi-select; cursor:grab.data-mode="console"— read-only; cursor:pointer; no drag-to-reorder; single-select only.
Don't
- Don't auto-expand into the space level. Bonsai's storey-default expansion is the convention every AEC practitioner expects.
- Don't reuse a generic scene-graph viewer (the Outliner-as-Tree pattern). Build the dedicated SpatialTree widget.
IFC mapping
| Token | IFC anchor | Uniclass |
|---|---|---|
bim-spatial-tree | IfcSpatialElement | SL |
Component renders the IfcSpatialElement family. See the
token taxonomy research
for the full IFC × Uniclass cross-walk.
Code overlays applicable
This token's IFC anchor (IfcSpatialElement) accepts IfcConstraint
relationships from any jurisdictional code overlay registered in service-codes.
Composition order: municipal → provincial → federal → accessibility.
No overlays registered for IfcSpatialElement in this jurisdiction.
First Woodfine BC RS-1 encoding lands at v0.0.3 (per sub-agent B's 6–8 week roadmap).