defmodule TarakanWeb.Layouts do @moduledoc """ This module holds layouts and related functionality used by your application. """ use TarakanWeb, :html # Embed all files in layouts/* within this module. # The default root.html.heex file contains the HTML # skeleton of your application, namely HTML headers # and other static content. embed_templates "layouts/*" @doc """ The Tarakan mark: a blade asterisk, six blades off one centre at (33,33), every outer tip a point. The spine is the heavy axis (full width y=18..48); the four diagonals carry their widest section a third of the way out and converge at the centre, which the spine keeps solid. """ attr :class, :any, default: "h-6 w-6" def logo_mark(assigns) do ~H""" """ end @doc """ Shared page shell: gutters, max width, and vertical padding under the nav. All app pages should use this so spacing stays consistent. Pass `class` only for extras (e.g. `space-y-5`), not for competing padding. """ attr :id, :string, default: nil attr :width, :atom, default: :wide, values: [:wide, :focused, :compact, :form] attr :class, :any, default: nil attr :rest, :global slot :inner_block, required: true def page(assigns) do ~H"""
{render_slot(@inner_block)}
""" end @doc """ Renders your app layout. This function is typically invoked from every template, and it often contains your application menu, sidebar, or similar. ## Examples

Content

""" attr :flash, :map, required: true, doc: "the map of flash messages" attr :current_scope, :map, default: nil, doc: "the current [scope](https://phoenix.hexdocs.pm/scopes.html)" attr :current_path, :string, default: nil, doc: "request path, supplied by TarakanWeb.CurrentPath; drives the nav highlight" slot :inner_block, required: true def app(assigns) do ~H"""
{render_slot(@inner_block)}
<.flash_group flash={@flash} />
""" end attr :path, :string, required: true attr :current, :string, default: nil attr :label, :string, required: true # Server-rendered highlight. This used to be a JavaScript hook that toggled # classes after paint, which meant every page rendered with nothing active for # a frame, and dead routes like /pricing never highlighted at all because they # have no LiveSocket to run the hook. defp nav_link(assigns) do assigns = assign(assigns, :active, TarakanWeb.CurrentPath.active?(assigns.current, assigns.path)) ~H""" <.link navigate={@path} aria-current={@active && "page"} class={[ "inline-flex shrink-0 items-center border-r-2 border-rule px-5 font-mono", "text-[11px] uppercase tracking-[0.12em] transition hover:bg-panel hover:text-ink", @active && "bg-panel text-ink shadow-[inset_0_-2px_0_0_var(--color-signal)]", !@active && "text-ink-faint" ]} > {@label} """ end attr :path, :string, required: true attr :current, :string, default: nil attr :label, :string, required: true defp mobile_nav_link(assigns) do assigns = assign(assigns, :active, TarakanWeb.CurrentPath.active?(assigns.current, assigns.path)) ~H""" <.link navigate={@path} aria-current={@active && "page"} class={[ "block px-4 py-3.5 font-mono text-[11px] uppercase tracking-[0.12em]", "transition hover:bg-panel", @active && "bg-panel text-ink shadow-[inset_2px_0_0_0_var(--color-signal)]", !@active && "text-ink" ]} > {@label} """ end @doc """ Shows the flash group with standard titles and content. ## Examples <.flash_group flash={@flash} /> """ attr :flash, :map, required: true, doc: "the map of flash messages" attr :id, :string, default: "flash-group", doc: "the optional id of flash container" def flash_group(assigns) do ~H"""
<.flash kind={:info} flash={@flash} /> <.flash kind={:error} flash={@flash} /> <.flash id="client-error" kind={:error} auto_dismiss={false} title={gettext("We can't find the internet")} phx-disconnected={ show(".phx-client-error #client-error") |> JS.remove_attribute("hidden", to: ".phx-client-error #client-error") } phx-connected={hide("#client-error") |> JS.set_attribute({"hidden", ""})} hidden > {gettext("Attempting to reconnect")} <.icon name="hero-arrow-path" class="ml-1 size-3 motion-safe:animate-spin" /> <.flash id="server-error" kind={:error} auto_dismiss={false} title={gettext("Something went wrong!")} phx-disconnected={ show(".phx-server-error #server-error") |> JS.remove_attribute("hidden", to: ".phx-server-error #server-error") } phx-connected={hide("#server-error") |> JS.set_attribute({"hidden", ""})} hidden > {gettext("Attempting to reconnect")} <.icon name="hero-arrow-path" class="ml-1 size-3 motion-safe:animate-spin" />
""" end end