defmodule AshHqWeb.Components.DocSidebar do @moduledoc """ Renders the sidebar data, and uses `Phoenix.LiveView.JS` to manage selection/collapsible state. """ use Surface.LiveComponent alias AshHqWeb.Components.Search alias Phoenix.LiveView.JS alias Surface.Components.LivePatch prop libraries, :any prop remove_version, :any prop selected_versions, :any prop class, :any prop sidebar_data, :any, default: [] def render(assigns) do ~F""" """ end # def render_icon(assigns, "Guide") do # ~F""" # # """ # end # def render_icon(assigns, "Api") do # ~F""" # # """ # end # def render_icon(assigns, "DataLayer") do # ~F""" # # """ # end # def render_icon(assigns, "Notifier") do # ~F""" # # """ # end # def render_icon(assigns, "Registry") do # ~F""" # # """ # end defp render_icon("Mix Tasks", _, _, item_classes, assigns) do Search.icon_for_type("Mix Task", item_classes, assigns) end defp render_icon("Code", _, _, item_classes, assigns) do Search.icon_for_type("Module", item_classes, assigns) end defp render_icon("DSLs & Extensions", type, _item_name, item_classes, assigns) do Search.icon_for_type(type, item_classes, assigns) end defp render_icon("Guides", "Tutorials", _item_name, item_classes, assigns) do Search.icon_for_type("Tutorial", item_classes, assigns) end defp render_icon("Guides", category, _item_name, item_classes, assigns) do type = case category do "Tutorials" -> "Tutorial" "How To" -> "How To" "Topics" -> "Topic" _ -> "Guide" end Search.icon_for_type(type, item_classes, assigns) end defp render_icon(_name, _category, _item_name, item_classes, assigns) do Search.icon_for_type("Unknown", item_classes, assigns) end defp id(category, library, name, id, item_id, global_id) do if category == "Tutorials" && library == "Ash" && name == "Get Started" do if String.starts_with?(global_id, "mobile") do "mobile-get-started-guide" else "get-started-guide" end else "#{global_id}-#{id}-#{slug(category)}-#{slug(library)}-#{item_id}" end end defp has_active?(list) when is_list(list), do: Enum.any?(list, &has_active?/1) defp has_active?({_, list}), do: has_active?(list) defp has_active?(%{active?: true}), do: true defp has_active?(_), do: false def mark_active(js \\ %JS{}, id) do js |> JS.remove_class( "bg-base-light-200 dark:bg-base-dark-700 active-sidebar-nav", to: ".active-sidebar-nav" ) |> JS.add_class( "bg-base-light-200 dark:bg-base-dark-700 active-sidebar-nav", to: "##{id}" ) |> JS.add_class( "bg-base-light-200 dark:bg-base-dark-700 active-sidebar-nav", to: "##{add_or_remove_mobile(id)}" ) end def collapse(js \\ %JS{}, id) do js |> JS.remove_class( "rotate-[-90deg]", to: "##{id}-chevron.rotate-\\[-90deg\\]" ) |> JS.remove_class( "rotate-[-90deg]", to: "##{add_or_remove_mobile(id)}-chevron.rotate-\\[-90deg\\]" ) |> JS.add_class( "rotate-[-90deg]", to: "##{id}-chevron:not(.rotate-\\[-90deg\\])" ) |> JS.add_class( "rotate-[-90deg]", to: "##{add_or_remove_mobile(id)}-chevron:not(.rotate-\\[-90deg\\])" ) |> JS.toggle(to: "##{id}-contents") |> JS.toggle(to: "##{add_or_remove_mobile(id)}-contents") end defp add_or_remove_mobile("mobile-" <> rest), do: rest defp add_or_remove_mobile(rest), do: "mobile-#{rest}" defp slug(string) do string |> String.downcase() |> String.replace(" ", "_") |> String.replace(~r/[^a-z0-9-_]/, "-") end end