File-explorer mechanics for table rows — the piece that turns any
<.table_default> (or plain <table>) into a collapsible tree:
depth indentation, a disclosure chevron, and a leading type icon,
all inside the row's name cell.
This is deliberately a cell, not a whole table component. An earlier monolithic tree-table (phoenix_kit_catalogue, retired 2026-06-28) couldn't compose with sortable column headers, column configuration, or card view — so the reusable core piece is the one thing every tree view shares: the name cell. The consumer owns the walk (which rows appear, in what order, at what depth) and the expanded-set state; this component just renders one row's tree affordances.
Usage
Walk your nested data into a flat list of {node, depth} rows in
display order, skipping children of collapsed nodes, then:
<.table_default id="files" ...>
<.table_default_body>
<.table_default_row :for={{node, depth} <- @tree_rows}>
<.tree_name_cell
depth={depth}
expandable={node.children != []}
expanded={MapSet.member?(@expanded, node.uuid)}
toggle_event="toggle_node"
value={node.uuid}
icon={if node.folder?, do: "hero-folder", else: "hero-document-text"}
icon_class={node.folder? && "w-4 h-4 text-warning shrink-0"}
>
{node.name}
</.tree_name_cell>
<%!-- ordinary cells for the remaining columns --%>
</.table_default_row>
</.table_default_body>
</.table_default>The chevron pushes toggle_event with %{"uuid" => value}; the
consumer flips the uuid in its expanded MapSet and rebuilds the
walked rows. Non-expandable rows render a fixed-width spacer so
names at the same depth stay aligned.
Summary
Functions
Attributes
depth(:integer) - Tree depth; 0 is a root row. Defaults to0.expandable(:boolean) - Render the disclosure chevron (true) or an aligning spacer (false). Defaults tofalse.expanded(:boolean) - Defaults tofalse.toggle_event(:string) - Event pushed by the chevron with%{"uuid" => value}. Defaults tonil.toggle_target(:any) - Optional phx-target for the toggle (LiveComponent consumers). Defaults tonil.value(:string) - Sent as phx-value-uuid on toggle. Defaults tonil.toggle_label(:string) - aria-label for the chevron — pass a translated string. Defaults to"Toggle".icon(:string) - Optional heroicon rendered before the content. Defaults tonil.icon_class(:any) - Classes for the leading icon (nil → default). Defaults tonil.indent(:string) - Indentation per depth level (any CSS length). Defaults to"1.5rem".class(:any) - Extra classes for the<td>. Defaults tonil.- Global attributes are accepted.
Slots
inner_block(required)