defmodule AshHqWeb.Components.TreeView do
@moduledoc """
A tree view with collapsable nodes.
The component must be supplied with a list of `%Item{}` structs defining
the behaviour of each node in the tree.
"""
use Surface.Component
alias AshHqWeb.Components.TreeView.Item
alias Phoenix.LiveView.JS
@doc "DOM id for the outer div"
prop id, :string, required: true
@doc "Any additional CSS classes to add to the outer div"
prop class, :css_class
@doc "`TreeView.Item` nodes to display"
slot default
def render(assigns) do
~F"""
"""
end
defmodule Item do
@moduledoc """
Data for an item in the TreeView.
"""
use Surface.Component
alias __MODULE__
prop path, :string, from_context: {Item, :path}
@doc "Logical name for the tree view item. Combined with the parent path to build the DOM id."
prop name, :string, default: nil
@doc "Text to display for the item."
prop text, :string, default: ""
@doc "Optional icon to display beside text"
prop icon, :any
@doc "Event handler to run when item clicked, eg JS.patch(~p'/some/path')"
prop to, :string
@doc "When true, allows the item's children to be hidden with a chevron icon."
prop collapsable, :boolean, default: false
@doc "The initial collapsed state of the children items."
prop collapsed, :boolean, default: false
@doc "The initial selection state of the item."
prop selected, :boolean, default: false
@doc "When true, displays an indentation guide to align deeply nested items."
prop indent_guide, :boolean, default: false
@doc "Any additional classes to add to the `
` element for the item."
prop class, :css_class, default: nil
@doc "Children `TreeView.Item` nodes."
slot default
def render(assigns) do
~F"""
"""
end
defp handle_click(js \\ %Phoenix.LiveView.JS{}, id, collapsable) do
if collapsable,
do: toggle_class(js, "collapsed", to: "##{id}"),
else: js
end
defp toggle_class(js, class, to: selector) do
js
|> JS.add_class(class, to: "#{selector}:not(.#{class})")
|> JS.remove_class(class, to: "#{selector}.#{class}")
end
end
end