PhiaUi.Components.TreeEnhanced (phia_ui v0.1.17)

Copy Markdown View Source

Enhanced tree view components for PhiaUI.

10 components extending the base tree/1 and tree_item/1 with icons, tri-state checkboxes, file-system display, search filtering, lazy loading, and virtual rendering for large datasets.

Component Overview

ComponentTierKey Feature
icon_tree:widgetTree root with icon support
icon_tree_item:widgetLeaf/branch + Lucide icon + badge
checkbox_tree:interactiveTri-state checkbox tree root
checkbox_tree_item:interactiveCheckbox item with indeterminate state
searchable_tree:widgetTree with search input above
file_tree:widgetFile-system display tree root
file_tree_item:widgetFile/folder item with extension icon
lazy_tree:interactiveTree root with lazy-load hook
lazy_tree_item:interactiveItem with loading/loaded states
virtual_tree:widgetHook-owned virtual rendering tree

Hooks required

  • PhiaCheckboxTree — checkbox_tree, checkbox_tree_item (sets .indeterminate)
  • PhiaLazyTree — lazy_tree, lazy_tree_item (fires expand events)
  • PhiaVirtualTree — virtual_tree (owns DOM rendering)

Summary

Functions

Checkbox tree root. Requires PhiaCheckboxTree hook to set the .indeterminate JS property on items with data-indeterminate="true".

Checkbox tree item with tri-state support.

File-system display tree root.

File or folder tree item with extension-based icon.

Tree root with icon-item support.

Tree item with optional icon, badge, href, and expandable branch support.

Tree root with lazy-load support via the PhiaLazyTree hook.

Lazy tree item. Fires an expand event to load children on first open.

Tree with a search input above. Filtering logic lives in the LiveView.

Virtual-rendered tree for large datasets (1000+ nodes).

Functions

checkbox_tree(assigns)

Checkbox tree root. Requires PhiaCheckboxTree hook to set the .indeterminate JS property on items with data-indeterminate="true".

Example

<.checkbox_tree id="permission-tree">
  <.checkbox_tree_item
    id="perm-read"
    label="Read"
    checked={:read in @permissions}
    on_check="toggle_permission"
    value="read"
  />
</.checkbox_tree>

Attributes

  • id (:string) (required) - Unique ID (required for phx-hook).
  • class (:string) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required)

checkbox_tree_item(assigns)

Checkbox tree item with tri-state support.

The .indeterminate JS property is set by the PhiaCheckboxTree hook on mounted() and updated() when data-indeterminate="true".

Example

<.checkbox_tree_item
  id="item-files"
  label="Files"
  checked={:files in @checked}
  indeterminate={has_partial_check?(@checked, @file_ids)}
  on_check="toggle_perm"
  value="files"
>
  <.checkbox_tree_item id="item-read" label="Read" checked={:read in @checked} />
</.checkbox_tree_item>

Attributes

  • id (:string) (required) - Unique ID for the checkbox element.
  • label (:string) (required)
  • checked (:boolean) - Defaults to false.
  • indeterminate (:boolean) - Server-computed partial-check state. Defaults to false.
  • on_check (:string) - phx-click event name. Defaults to "check_tree_item".
  • value (:string) - phx-value-value sent on check. Defaults to nil.
  • depth (:integer) - Indentation depth (multiplied by ml-4). Defaults to 0.
  • class (:string) - Defaults to nil.

Slots

  • inner_block

file_tree(assigns)

File-system display tree root.

Example

<.file_tree id="project-files">
  <.file_tree_item label="src" type={:folder} expanded={true}>
    <.file_tree_item label="app.ex" type={:file} />
  </.file_tree_item>
</.file_tree>

Attributes

  • id (:string) (required)
  • class (:string) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required)

file_tree_item(assigns)

File or folder tree item with extension-based icon.

Folders show a folder icon and use <details>/<summary>. Files show a file-type icon based on their extension.

Example

<.file_tree_item label="mix.exs" type={:file} on_click="open" value="mix.exs" />

<.file_tree_item label="lib" type={:folder} expanded={true}>
  <.file_tree_item label="app.ex" type={:file} />
</.file_tree_item>

Attributes

  • label (:string) (required) - File or folder name.
  • type (:atom) - Item type. Defaults to :file. Must be one of :file, or :folder.
  • expanded (:boolean) - Defaults to false.
  • selected (:boolean) - Defaults to false.
  • size (:string) - Optional file size string (e.g. '4.2 KB'). Defaults to nil.
  • modified (:string) - Optional last-modified string. Defaults to nil.
  • on_click (:string) - Defaults to nil.
  • value (:string) - Defaults to nil.
  • class (:string) - Defaults to nil.

Slots

  • inner_block

icon_tree(assigns)

Tree root with icon-item support.

Example

<.icon_tree id="nav-tree">
  <.icon_tree_item label="Components" icon="layers" expandable={true}>
    <.icon_tree_item label="Button" icon="square" />
  </.icon_tree_item>
</.icon_tree>

Attributes

  • id (:string) (required)
  • class (:string) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required)

icon_tree_item(assigns)

Tree item with optional icon, badge, href, and expandable branch support.

Uses <details>/<summary> for branches (zero-JS expand/collapse). Disabled items are non-interactive and visually dimmed.

Example

<.icon_tree_item label="Settings" icon="settings" on_click="nav" value="settings" />

<.icon_tree_item label="src" icon="folder" expandable={true} expanded={true}>
  <.icon_tree_item label="app.ex" icon="file-code" />
</.icon_tree_item>

Attributes

  • label (:string) (required)
  • icon (:string) - Lucide icon name shown before the label. Defaults to nil.
  • badge (:string) - Optional badge text. Defaults to nil.
  • badge_variant (:string) - Badge color variant string. Defaults to "secondary".
  • href (:string) - When set, renders label as <a> link. Defaults to nil.
  • expandable (:boolean) - Defaults to false.
  • expanded (:boolean) - Defaults to false.
  • selected (:boolean) - Defaults to false.
  • disabled (:boolean) - Defaults to false.
  • on_click (:string) - Defaults to nil.
  • value (:string) - Defaults to nil.
  • class (:string) - Defaults to nil.

Slots

  • inner_block

lazy_tree(assigns)

Tree root with lazy-load support via the PhiaLazyTree hook.

When a lazy_tree_item is expanded by the user, the hook fires push_event(@on_expand, %{"id" => item_id}) to the LiveView, which can load children and update the item's loaded assign.

Example

<.lazy_tree id="repo-tree" on_expand="load_children">
  <.lazy_tree_item id="src" label="src" expandable={true} loaded={@src_loaded}>
    <.lazy_tree_item :for={f <- @src_files} id={f.id} label={f.name} />
  </.lazy_tree_item>
</.lazy_tree>

Attributes

  • id (:string) (required) - Unique ID (required for phx-hook).
  • on_expand (:string) - push_event name when a node expands. Defaults to "tree_expand".
  • class (:string) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required)

lazy_tree_item(assigns)

Lazy tree item. Fires an expand event to load children on first open.

When loading is true, shows a spinner instead of children. When loaded is true, children are rendered normally.

Example

<.lazy_tree_item id="src-dir" label="src" expandable={true} loaded={@src_loaded} loading={@src_loading}>
  <.lazy_tree_item :for={f <- @src_files} id={f.id} label={f.name} />
</.lazy_tree_item>

Attributes

  • id (:string) (required) - Node ID sent to the hook on expand.
  • label (:string) (required)
  • expandable (:boolean) - Defaults to false.
  • expanded (:boolean) - Defaults to false.
  • loading (:boolean) - Shows a spinner while children load. Defaults to false.
  • loaded (:boolean) - When true, children are present and loading is done. Defaults to false.
  • class (:string) - Defaults to nil.

Slots

  • inner_block

searchable_tree(assigns)

Tree with a search input above. Filtering logic lives in the LiveView.

The search input fires on_search with phx-debounce="200". Your LiveView filters the tree data and re-renders only matching items.

Example

<.searchable_tree id="file-search" on_search="filter_files" search_value={@search}>
  <.icon_tree_item :for={file <- @filtered_files} label={file.name} icon="file" />
</.searchable_tree>

Attributes

  • id (:string) (required)
  • search_placeholder (:string) - Defaults to "Search...".
  • on_search (:string) - phx-change event for search input. Defaults to "search_tree".
  • search_value (:string) - Current search value for controlled input. Defaults to "".
  • class (:string) - Defaults to nil.

Slots

  • inner_block (required)

virtual_tree(assigns)

Virtual-rendered tree for large datasets (1000+ nodes).

The PhiaVirtualTree hook owns the DOM — only visible rows are rendered. Initial node data is passed as data-nodes JSON; subsequent updates are sent via push_event("update-nodes", %{nodes: [...]}).

Use phx-update="ignore" (set automatically) to prevent LiveView from reconciling the hook-managed DOM.

Example

<.virtual_tree
  id="large-tree"
  nodes={@flat_nodes}
  row_height={28}
  height={500}
/>

LiveView update

{:noreply, push_event(socket, "update-nodes", %{nodes: flat_nodes})}

Attributes

  • id (:string) (required) - Unique ID (required for phx-hook).
  • nodes (:list) (required) - Flat list of node maps with :id, :label, :depth, :expandable, :expanded.
  • row_height (:integer) - Height of each rendered row in pixels. Defaults to 32.
  • height (:integer) - Container height in pixels (viewport). Defaults to 400.
  • class (:string) - Defaults to nil.