From 805354d724fd1242d0133478ef9a86a0279fde37 Mon Sep 17 00:00:00 2001 From: Nuno Miguel Date: Thu, 20 Mar 2025 11:02:41 +0000 Subject: [PATCH 1/2] feat: improve sidebar --- lib/atomic/organizations.ex | 4 +- lib/atomic_web/components/accordion.ex | 86 ++++++++++++++++++++++ lib/atomic_web/components/organizations.ex | 74 +++++++++++++------ lib/atomic_web/components/sidebar.ex | 29 ++++++-- lib/atomic_web/config.ex | 9 +++ 5 files changed, 169 insertions(+), 33 deletions(-) create mode 100644 lib/atomic_web/components/accordion.ex diff --git a/lib/atomic/organizations.ex b/lib/atomic/organizations.ex index e2c58e8ae..511c906aa 100644 --- a/lib/atomic/organizations.ex +++ b/lib/atomic/organizations.ex @@ -19,7 +19,9 @@ defmodule Atomic.Organizations do [%Organization{}, ...] """ - def list_organizations(params \\ %{}) + def list_organizations do + Organization |> Repo.all() + end def list_organizations(opts) when is_list(opts) do Organization diff --git a/lib/atomic_web/components/accordion.ex b/lib/atomic_web/components/accordion.ex new file mode 100644 index 000000000..5d75d11d7 --- /dev/null +++ b/lib/atomic_web/components/accordion.ex @@ -0,0 +1,86 @@ +defmodule AtomicWeb.Components.Accordion do + @moduledoc """ + Provides accordion-related components and helper functions. + """ + use AtomicWeb, :component + + alias Phoenix.LiveView.JS + import AtomicWeb.Components.Icon + + @doc """ + Accordion components allows users to show and hide sections of related panel on a page. + + ## Examples + + ```heex + <.accordion> + <:trigger>Accordion + <:panel>Content + + ``` + """ + + attr :class, :any, doc: "Extend existing component styles" + attr :controlled, :boolean, default: false + attr :id, :string, required: true + attr :rest, :global + + slot :trigger, validate_attrs: false + slot :panel, validate_attrs: false + + @spec accordion(Socket.assigns()) :: Rendered.t() + def accordion(assigns) do + ~H""" +
+ <%= for {{trigger, panel}, idx} <- @trigger |> Enum.zip(@panel) |> Enum.with_index() do %> +

+ +

+
+
+
+ {render_slot(panel)} +
+
+
+ <% end %> +
+ """ + end + + defp trigger_id(id, idx), do: "#{id}_trigger#{idx}" + defp panel_id(id, idx), do: "#{id}_panel#{idx}" + + defp handle_click(%{controlled: controlled, id: id}, idx) do + op = + {"aria-expanded", "true", "false"} + |> JS.toggle_attribute(to: "##{trigger_id(id, idx)}") + |> JS.toggle_attribute({"data-expanded", ""}, to: "##{panel_id(id, idx)}") + + if controlled do + op + |> JS.set_attribute({"aria-expanded", "false"}, + to: "##{id} .accordion-trigger:not(##{trigger_id(id, idx)})" + ) + |> JS.remove_attribute("data-expanded", + to: "##{id} .accordion-panel:not(##{panel_id(id, idx)})" + ) + else + op + end + end +end diff --git a/lib/atomic_web/components/organizations.ex b/lib/atomic_web/components/organizations.ex index 9a575a8ce..bc39b7d93 100644 --- a/lib/atomic_web/components/organizations.ex +++ b/lib/atomic_web/components/organizations.ex @@ -2,7 +2,7 @@ defmodule AtomicWeb.Components.Organizations do @moduledoc false use AtomicWeb, :live_component - import AtomicWeb.Components.Avatar + import AtomicWeb.Components.{Avatar, Accordion} alias Atomic.Accounts alias Atomic.Organizations @@ -10,35 +10,61 @@ defmodule AtomicWeb.Components.Organizations do @impl true def render(assigns) do ~H""" - + + + """ end diff --git a/lib/atomic_web/components/sidebar.ex b/lib/atomic_web/components/sidebar.ex index 510b30c42..6faa56b89 100644 --- a/lib/atomic_web/components/sidebar.ex +++ b/lib/atomic_web/components/sidebar.ex @@ -44,11 +44,11 @@ defmodule AtomicWeb.Components.Sidebar do <.sidebar_dropdown current_user={@current_user} orientation={:down} /> - +