Current section
Files
Jump to
Current section
Files
lib/doggo/components/drawer.ex
defmodule Doggo.Components.Drawer do
@moduledoc false
@behaviour Doggo.Component
use Phoenix.Component
@impl true
def doc do
"""
Renders a drawer with a `brand`, `top`, and `bottom` slot.
All slots are optional, and you can render any content in them. If you want
to use the drawer as a sidebar, you can use the `vertical_nav/1` and
`vertical_nav_section/1` components.
"""
end
@impl true
def usage do
"""
Minimal example:
```heex
<.drawer>
<:main>Content</:main>
</.drawer>
```
With all slots:
```heex
<.drawer>
<:header>Doggo</:header>
<:main>Content at the top</:main>
<:footer>Content at the bottom</:footer>
</.drawer>
```
With navigation and sections:
```heex
<.drawer>
<:header>
<.link navigate={~p"/"}>App</.link>
</:header>
<:main>
<.vertical_nav label="Main">
<:item>
<.link navigate={~p"/dashboard"}>Dashboard</.link>
</:item>
<:item>
<.vertical_nav_nested>
<:title>Content</:title>
<:item current_page>
<.link navigate={~p"/posts"}>Posts</.link>
</:item>
<:item>
<.link navigate={~p"/comments"}>Comments</.link>
</:item>
</.vertical_nav_nested>
</:item>
</.vertical_nav>
<.vertical_nav_section>
<:title>Search</:title>
<:item><input type="search" placeholder="Search" /></:item>
</.vertical_nav_section>
</:main>
<:footer>
<.vertical_nav label="User menu">
<:item>
<.link navigate={~p"/settings"}>Settings</.link>
</:item>
<:item>
<.link navigate={~p"/logout"}>Logout</.link>
</:item>
</.vertical_nav>
</:footer>
</.drawer>
```
"""
end
@impl true
def config do
[
type: :layout,
since: "0.6.0",
maturity: :experimental,
modifiers: []
]
end
@impl true
def nested_classes(base_class) do
[
"#{base_class}-footer",
"#{base_class}-header",
"#{base_class}-main"
]
end
@impl true
def attrs_and_slots do
quote do
attr :rest, :global, doc: "Any additional HTML attributes."
slot :header, doc: "Optional slot for the brand name or logo."
slot :main,
doc: """
Slot for content that is rendered after the brand, at the start of the
side bar.
"""
slot :footer,
doc: """
Slot for content that is rendered at the end of the drawer, potentially
pinned to the bottom, if there is enough room.
"""
end
end
@impl true
def init_block(_opts, _extra) do
[]
end
@impl true
def render(assigns) do
~H"""
<aside class={@class} {@data_attrs} {@rest}>
<div :if={@header != []} class={"#{@base_class}-header"}>
{render_slot(@header)}
</div>
<div :if={@main != []} class={"#{@base_class}-main"}>
{render_slot(@main)}
</div>
<div :if={@footer != []} class={"#{@base_class}-footer"}>
{render_slot(@footer)}
</div>
</aside>
"""
end
end