defmodule <%= @module %>.Components.Shell do @moduledoc """ Dashboard layout shell with responsive sidebar and topbar. Ejected from PhiaUI — owns this copy of the source. Customise freely. CSS Grid on desktop (sidebar 240 px + 1fr content); sidebar becomes a JS-toggled drawer on mobile via `Phoenix.LiveView.JS` — no Alpine.js required. ## Sub-components - `shell/1` — full-height outer wrapper - `topbar/1` — sticky top navigation bar - `sidebar/1` — collapsible sidebar (drawer on mobile, static on desktop) - `mobile_sidebar_toggle/1` — hamburger button that calls `JS.toggle/1` ## Example <.shell> <.topbar> <.mobile_sidebar_toggle /> My App
<.sidebar>
<%= @inner_content %>
""" use Phoenix.Component alias Phoenix.LiveView.JS import <%= @module %>.ClassMerger, only: [cn: 1] attr :class, :string, default: nil, doc: "Additional CSS classes for the outer wrapper" attr :rest, :global, doc: "HTML attributes forwarded to the wrapper div" slot :inner_block, required: true @doc "Full-height application shell wrapper." def shell(assigns) do ~H"""
<%= render_slot(@inner_block) %>
""" end attr :class, :string, default: nil, doc: "Additional CSS classes" attr :rest, :global slot :inner_block, required: true @doc "Horizontal top navigation bar (h-14, border-b)." def topbar(assigns) do ~H"""
<%= render_slot(@inner_block) %>
""" end attr :id, :string, default: "sidebar-drawer", doc: "Element id used by JS.toggle" attr :class, :string, default: nil, doc: "Additional CSS classes" attr :rest, :global, doc: "HTML attributes forwarded to the aside element" slot :inner_block, required: true @doc """ Responsive sidebar. Hidden by default on mobile; shown as a fixed overlay drawer when toggled via `mobile_sidebar_toggle/1`. Always visible on `md:` breakpoint and above. """ def sidebar(assigns) do ~H""" """ end attr :target, :string, default: "#sidebar-drawer", doc: "CSS selector for the sidebar element to toggle" attr :class, :string, default: nil, doc: "Additional CSS classes" attr :rest, :global @doc """ Hamburger button that toggles the mobile sidebar via `Phoenix.LiveView.JS`. Hidden on `md:` and above — only shown on mobile. """ def mobile_sidebar_toggle(assigns) do ~H""" """ end end