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"""
"""
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"""