A single recursive template renders this tree, however deep it goes. Click a name to select it. Drag any row onto another to move it there - drop it directly on a folder to file it inside. Use the icons to expand a folder, add a file, or delete a node.
<fx-repeat id="tree" ref="folder|file" recursive="true">
renders the whole arbitrary-depth tree. Each level recurses into its own
matching children via a plain <fx-repeat-ref> placeholder -
no hand-written, depth-capped chain of nested repeats. Left without a
ref of its own, it defaults to the nearest ancestor
<fx-repeat>'s ref, so every recursion level
matches children the same way its parent did.drop-scope="parent" anywhere: every recursion
level is synthesized with no id of its own, so Fore's default
drop scoping (nearest ancestor with a literal id) resolves to
the single outer id="tree" for every node - the whole tree is
one drop scope, so any row can be dragged onto any other, near or far.<fx-repeat> is the only way to
drop inside a folder that has no children to drop onto - it needs a
real, non-zero box (display: block plus a min-height)
or there is nothing left to hit-test. A file's copy of that same element is
suppressed with display: none, keyed on a
data-kind="{name()}" marker, since a file can never be a
container.@ui-selected marker set with
fx-setattribute and read back with
//*[@ui-selected='true'] - not index(), which can't
address a synthesized, id-less nested repeat. That lets a marker set at any
depth be read from entirely outside the tree, e.g. by a property panel.@collapsed) is purely a CSS/DOM
concern, never XForms relevant - the subtree stays fully in the
model while its <ul> is hidden, so it still counts and is
still selectable. Which of the two twisty triggers is visible is likewise
decided by CSS keyed on data-collapsed, not by each trigger's own
ref/relevant: a predicate like
self::folder[@collapsed='true'] only resolves once at initial
binding and won't reliably go stale as the attribute keeps flipping, where CSS
re-evaluates on every change.