# `Doggo.Components`
[🔗](https://github.com/woylie/doggo/blob/0.14.6/lib/doggo/components.ex#L1)

This module defines macros that generate customized components.

## Usage

Add `use Doggo.Components` to your module and ensure you also add
`use Phoenix.Component`. Then use the macros in this module to generate the
components you need.

> #### `use Doggo.Components` {: .info}
>
> When you `use Doggo.Components`, the module will import `Doggo.Components`
> and define a `__dog_components__/1` function that returns a map containing
> the options of the Doggo components you used.

To generate all components with their default options:

    defmodule MyAppWeb.CoreComponents do
      use Doggo.Components
      use Phoenix.Component

      build_accordion()
      build_action_bar()
      build_alert()
      build_alert_dialog()
      build_app_bar()
      build_avatar()
      build_badge()
      build_bottom_navigation()
      build_box()
      build_breadcrumb()
      build_button()
      build_button_link()
      build_callout()
      build_card()
      build_carousel()
      build_cluster()
      build_combobox()
      build_date()
      build_datetime()
      build_disclosure_button()
      build_drawer()
      build_fallback()
      build_field()
      build_field_group()
      build_frame()
      build_icon()
      build_icon_sprite()
      build_image()
      build_menu()
      build_menu_bar()
      build_menu_button()
      build_menu_group()
      build_menu_item()
      build_menu_item_checkbox()
      build_menu_item_radio_group()
      build_modal()
      build_navbar()
      build_navbar_items()
      build_page_header()
      build_property_list()
      build_radio_group()
      build_skeleton()
      build_split_pane()
      build_stack()
      build_steps()
      build_switch()
      build_tab_navigation()
      build_table()
      build_tabs()
      build_tag()
      build_time()
      build_toggle_button()
      build_toolbar()
      build_tooltip()
      build_tree()
      build_tree_item()
      build_vertical_nav()
      build_vertical_nav_nested()
      build_vertical_nav_section()
    end

## Common Options

All component macros support the following options:

- `name` - The name of the function of the generated component. Defaults to
  the macro name.
- `base_class` - The base class used on the root element of the component. If
  not set, a default base class is used.
- `modifiers` - A keyword list of modifier attributes. For each item, an
  attribute is added. The options will be passed to
  `Phoenix.Component.attr/3`. Most components define a set of default
  modifiers that can be overridden. Any attribute type is allowed, but since
  the value will be used as data attribute value, it needs to be possible to
  convert the value to a string. The `:type` option defaults to `:string`.

Some components have additional options that are mostly used to allow the
customization of certain class names or to set the Gettext module.

# `build_button`
*since 0.6.0* *macro* 

Renders a button.

Use this component when you need to perform an action such as submitting a
form, confirming an action, deleting an item, toggling a setting, etc.

If you need to navigate to a different page or a specific section on the
current page and want to style the link like a button, use `button_link/1`
instead.

See also `button_link/1`, `toggle_button/1`, and `disclosure_button/1`.

> #### Maturity: Stable {: .info}

## Configuration

Generate the component with default options:

    build_button()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[
  name: :button,
  base_class: "button",
  modifiers: [
    variant: [
      values: ["primary", "secondary", "info", "success", "warning", "danger"],
      default: "primary"
    ],
    size: [values: ["small", "normal", "medium", "large"], default: "normal"],
    fill: [values: ["solid", "outline", "text"], default: "solid"],
    shape: [values: [nil, "circle", "pill"], default: nil]
  ]
]
```

## Usage

```heex
<.button>Confirm</.button>

<.button type="submit">
  Submit
</.button>
```

To indicate a loading state, for example when submitting a form, use the
`aria-busy` attribute:

```heex
<.button aria-label="Saving..." aria-busy>
  click me
</.button>
```

## Example CSS

For example CSS, you can have a look at the [demo styles](https://github.com/woylie/doggo/blob/main/demo/assets/css/components/_button.scss).

# `build_button_link`
*since 0.6.0* *macro* 

Renders a link (`<a>`) that has the style of a button.

Use this component when you need to style a link to a different page or a
specific section within the same page as a button.

To perform an action on the same page, including toggles and
revealing/hiding elements, you should always use a real button instead. See
`button/1`, `toggle_button/1`, and `disclosure_button/1`.

> #### Maturity: Stable {: .info}

## Configuration

Generate the component with default options:

    build_button_link()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[
  name: :button_link,
  base_class: "button",
  modifiers: [
    variant: [
      values: ["primary", "secondary", "info", "success", "warning", "danger"],
      default: "primary"
    ],
    size: [values: ["small", "normal", "medium", "large"], default: "normal"],
    fill: [values: ["solid", "outline", "text"], default: "solid"],
    shape: [values: [nil, "circle", "pill"], default: nil]
  ]
]
```

## Usage

```heex
<.button_link patch={~p"/confirm"}>
  Confirm
</.button_link>

<.button_link navigate={~p"/registration"}>
  Registration
</.button_link>
```

## Example CSS

For example CSS, you can have a look at the [demo styles](https://github.com/woylie/doggo/blob/main/demo/assets/css/components/_button.scss).

# `build_disclosure_button`
*since 0.6.0* *macro* 

Renders a button that toggles the visibility of another element.

Use this component to reveal or hide additional content, such as in
collapsible sections or dropdown menus.

For a button that toggles other states, use `toggle_button/1` instead. See
also `button/1` and `button_link/1`.

> #### Maturity: Refining {: .info}

## Configuration

Generate the component with default options:

    build_disclosure_button()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[
  name: :disclosure_button,
  base_class: "button",
  modifiers: [
    variant: [
      values: ["primary", "secondary", "info", "success", "warning", "danger"],
      default: "primary"
    ]
  ]
]
```

## Usage

Set the `controls` attribute to the DOM ID of the element that you want to
toggle with the button.

The initial state is hidden. Do not forget to add the `hidden` attribute to
the toggled element. Otherwise, visibility of the element will not align with
the `aria-expanded` attribute of the button.

```heex
<.disclosure_button controls="data-table">
  Data Table
</.disclosure_button>

<table id="data-table" hidden></table>
```

### CSS

To select disclosure buttons without class names and to apply styles
depending on the state (e.g. to render a caret), you can use the
`aria-controls` and `aria-expanded` attributes.

```css
button[aria-controls][aria-expanded] {
  /* Base styles for disclosure buttons */
}

button[aria-controls][aria-expanded="true"] {
  /* Styles when content is visible */
}
```

## Example CSS

For example CSS, you can have a look at the [demo styles](https://github.com/woylie/doggo/blob/main/demo/assets/css/components/_button.scss).

# `build_switch`
*since 0.6.0* *macro* 

Renders a switch as a button.

If you want to render a switch as part of a form, use the `input/1` component
with the type `"switch"` instead.

Note that this component only renders a button with a label, a state, and
`<span>` with the class `switch-control`. You will need to style the switch
control span with CSS in order to give it the appearance of a switch.

> #### Maturity: Experimental {: .info}

## Configuration

Generate the component with default options:

    build_switch()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :switch, base_class: "switch", modifiers: []]
```

## Usage

```heex
<.switch
  label="Subscribe"
  checked={true}
  phx-click="toggle-subscription"
/>
```

# `build_toggle_button`
*since 0.6.0* *macro* 

Renders a button that toggles a state.

Use this component to switch a feature or setting on or off, for example to
toggle dark mode or mute/unmute sound.

See also `button/1`, `button_link/1`, and `disclosure_button/1`.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_toggle_button()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[
  name: :toggle_button,
  base_class: "button",
  modifiers: [
    variant: [
      values: ["primary", "secondary", "info", "success", "warning", "danger"],
      default: "primary"
    ],
    size: [values: ["small", "normal", "medium", "large"], default: "normal"],
    fill: [values: ["solid", "outline", "text"], default: "solid"],
    shape: [values: [nil, "circle", "pill"], default: nil]
  ]
]
```

## Usage

With a `Phoenix.LiveView.JS` command:

```heex
<.toggle_button on_click={JS.push("toggle-mute")} pressed={@muted}>
  Mute
</.toggle_button>
```

## Accessibility

The button state is conveyed via the `aria-pressed` attribute and the button
styling. The button text should not change depending on the state. You may
however include an icon that changes depending on the state.

## CSS

A toggle button can be identified with an attribute selector for the
`aria-pressed` attribute.

```css
// any toggle button regardless of state
button[aria-pressed] {}

// unpressed toggle buttons
button[aria-pressed="false"] {}

// pressed toggle buttons
button[aria-pressed="true"] {}
```

# `build_accordion`
*since 0.6.0* *macro* 

Renders a set of headings that control the visibility of their content
sections.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_accordion()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :accordion, base_class: "accordion", modifiers: []]
```

## Usage

```heex
<.accordion id="dog-breeds">
  <:section title="Golden Retriever">
    <p>
      Friendly, intelligent, great with families. Origin: Scotland. Needs
      regular exercise.
    </p>
  </:section>
  <:section title="Siberian Husky">
    <p>
      Energetic, outgoing, distinctive appearance. Origin: Northeast Asia.
      Loves cold climates.
    </p>
  </:section>
  <:section title="Dachshund">
    <p>
      Playful, stubborn, small size. Origin: Germany. Enjoys sniffing games.
    </p>
  </:section>
</.accordion>
```

# `build_card`
*since 0.6.0* *macro* 

Renders a card in an `article` tag, typically used repetitively in a grid or
flex box layout.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_card()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :card, base_class: "card", modifiers: []]
```

## Usage

```heex
<.card>
  <:image>
    <img src="image.png" alt="Picture of a dog dressed in a poncho." />
  </:image>
  <:header><h2>Dog Fashion Show</h2></:header>
  <:main>
    The next dog fashion show is coming up quickly. Here's what you need
    to look out for.
  </:main>
  <:footer>
    <span>2023-11-15 12:24</span>
    <span>Events</span>
  </:footer>
</.card>
```

# `build_date`
*since 0.6.0* *macro* 

Formats a `Date`, `DateTime`, or `NaiveDateTime` as a date and renders it
in a `<time>` element.

> #### Maturity: Refining {: .info}
>
> The API of this component can be considered fairly stable, but there
> are still uncertainties about accessibility aspects, such as the
> handling of the `<time>` element and its `datetime` attribute by screen
> readers and the limited accessibility of the title attribute.
>

## Configuration

Generate the component with default options:

    build_date()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :date, base_class: nil, modifiers: []]
```

## Usage

By default, the given value is formatted for display with `to_string/1`. This:

```heex
<.date value={~D[2023-02-05]} />
```

Will be rendered as:

```html
<time datetime="2023-02-05">
  2023-02-05
</time>
```

You can also pass a custom formatter function. For example, if you are using
[ex_cldr_dates_times](https://hex.pm/packages/ex_cldr_dates_times) in your
application, you could do this:

```heex
<.date
  value={~D[2023-02-05]}
  formatter={&MyApp.Cldr.Date.to_string!/1}
/>
```

Which, depending on your locale, may be rendered as:

```html
<time datetime="2023-02-05">
  Feb 2, 2023
</time>
```

If you pass a `title_formatter`, a `title` attribute is added to the
element. This can be useful if you want to render the value in a shortened
or relative format, but still give the user access to the complete value.
Note that the title attribute is only be accessible to users who use
a pointer device. Some screen readers may however announce the `datetime`
attribute that is always added.

```heex
<.date
  value={@date}
  formatter={&relative_date/1}
  title_formatter={&MyApp.Cldr.Date.to_string!/1}
/>
```

Finally, the component can shift a `DateTime` to a different time zone
before converting it to a date:

```heex
<.date
  value={~U[2023-02-05 23:22:05Z]}
  timezone="Asia/Tokyo"
/>
```

Which would be rendered as:

```html
<time datetime="2023-02-06">
  2023-02-06
</time>
```

# `build_datetime`
*since 0.6.0* *macro* 

Formats a `DateTime` or `NaiveDateTime` as a date time and renders it
in a `<time>` element.

> #### Maturity: Refining {: .info}
>
> The API of this component can be considered fairly stable, but there
> are still uncertainties about accessibility aspects, such as the
> handling of the `<time>` element and its `datetime` attribute by screen
> readers and the limited accessibility of the title attribute.
>

## Configuration

Generate the component with default options:

    build_datetime()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :datetime, base_class: nil, modifiers: []]
```

## Usage

By default, the given value is formatted for display with `to_string/1`. This:

```heex
<.datetime value={~U[2023-02-05 12:22:06.003Z]} />
```

Will be rendered as:

```html
<time datetime="2023-02-05T12:22:06.003Z">
  2023-02-05 12:22:06.003Z
</time>
```

You can also pass a custom formatter function. For example, if you are using
[ex_cldr_dates_times](https://hex.pm/packages/ex_cldr_dates_times) in your
application, you could do this:

```heex
<.datetime
  value={~U[2023-02-05 14:22:06.003Z]}
  formatter={&MyApp.Cldr.DateTime.to_string!/1}
/>
```

Which, depending on your locale, may be rendered as:

```html
<time datetime="2023-02-05T14:22:06.003Z">
  Feb 2, 2023, 14:22:06 PM
</time>
```

The component can also truncate the value before passing it to the
formatter.

```heex
<.datetime
  value={~U[2023-02-05 12:22:06.003Z]}
  precision={:minute}
/>
```

If you pass a `title_formatter`, a `title` attribute is added to the
element. This can be useful if you want to render the value in a shortened
or relative format, but still give the user access to the complete value.
Note that the title attribute is only be accessible to users who use
a pointer device. Some screen readers may however announce the `datetime`
attribute that is always added.

```heex
<.datetime
  value={@datetime}
  formatter={&relative_date/1}
  title_formatter={&MyApp.Cldr.DateTime.to_string!/1}
/>
```

Finally, the component can shift a `DateTime` to a different time zone:

```heex
<.datetime
  value={~U[2023-02-05 23:22:05Z]}
  timezone="Asia/Tokyo"
/>
```

Which would be rendered as:

```html
<time datetime="2023-02-06T08:22:05+09:00">
  2023-02-06 08:22:05+09:00 JST Asia/Tokyo
</time>
```

# `build_fallback`
*since 0.6.0* *macro* 

The fallback component renders a given value unless it is empty, in which case
it renders a fallback value instead.

The values `nil`, `""`, `[]` and `%{}` are treated as empty values.

This component optionally applies a formatter function to non-empty values.

The primary purpose of this component is to enhance accessibility. In
situations where a value in a table column or property list is set to be
invisible or not displayed, it's crucial to provide an alternative text for
screen readers.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_fallback()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :fallback, base_class: "fallback", modifiers: []]
```

## Usage

Render the value of `@some_value` if it's available, or display the
default placeholder otherwise:

```heex
<.fallback value={@some_value} />
```

Apply a formatter function to `@some_value` if it is not `nil`:

```heex
<.fallback value={@some_value} formatter={&format_date/1} />
```

Set a custom placeholder and text for screen readers:

```heex
<.fallback
  value={@some_value}
  placeholder="n/a"
  accessibility_text="not available"
/>
```

# `build_property_list`
*since 0.6.0* *macro* 

Renders a list of properties as key/value pairs.

This component is useful for displaying data in a structured format, such as
a list of attributes for an entity. Each property is rendered as a `<dt>`
element for the label and a `<dd>` element for the value.

> #### Maturity: Stable {: .info}

## Configuration

Generate the component with default options:

    build_property_list()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :property_list, base_class: "property-list", modifiers: []]
```

## Usage

Each property is specified using the `:prop` slot with a `label` attribute
and an inner block.

```heex
<.property_list>
  <:prop label={gettext("Name")}>George</:prop>
  <:prop label={gettext("Age")}>42</:prop>
</.property_list>
```

## Example CSS

For example CSS, you can have a look at the [demo styles](https://github.com/woylie/doggo/blob/main/demo/assets/css/components/_property-list.scss).

# `build_table`
*since 0.6.0* *macro* 

Renders a simple table.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_table()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :table, base_class: "table-container", modifiers: []]
```

## Usage

```heex
<.table id="pets" rows={@pets}>
  <:col :let={p} label="name"><%= p.name %></:col>
  <:col :let={p} label="age"><%= p.age %></:col>
</.table>
```

# `build_tabs`
*since 0.6.0* *macro* 

Renders tab panels.

This component is meant for tabs that toggle content panels within the page.
If you want to link to a different view or live action, use
`tab_navigation/1` instead.

> #### Maturity: Developing {: .info}
>
> The necessary JavaScript for making this component fully functional and
> accessible will be added in a future version.
>
> **Missing features**
>
> - Roving tabindex
> - Move focus with arrow keys
>

## Configuration

Generate the component with default options:

    build_tabs()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :tabs, base_class: "tabs", modifiers: []]
```

## Usage

```heex
<.tabs id="dog-breed-profiles" label="Dog Breed Profiles">
  <:panel label="Golden Retriever">
    <p>
      Friendly, intelligent, great with families. Origin: Scotland. Needs
      regular exercise.
    </p>
  </:panel>
  <:panel label="Siberian Husky">
    <p>
      Energetic, outgoing, distinctive appearance. Origin: Northeast Asia.
      Loves cold climates.
    </p>
  </:panel>
  <:panel label="Dachshund">
    <p>
      Playful, stubborn, small size. Origin: Germany. Enjoys sniffing games.
    </p>
  </:panel>
</.tabs>
```

# `build_tag`
*since 0.6.0* *macro* 

Renders a tag, typically used for displaying labels, categories, or keywords.

> #### Maturity: Refining {: .info}

## Configuration

Generate the component with default options:

    build_tag()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[
  name: :tag,
  base_class: "tag",
  modifiers: [
    size: [values: ["small", "normal", "medium", "large"], default: "normal"],
    variant: [
      values: [nil, "primary", "secondary", "info", "success", "warning",
       "danger"],
      default: nil
    ],
    shape: [values: [nil, "pill"], default: nil]
  ]
]
```

## Usage

```heex
<.tag>Well-Trained</.tag>
```

With icon:

```heex
<.tag>
  Puppy
  <.icon><Heroicons.edit /></.icon>
</.tag>
```

With delete button:

```heex
<.tag>
  High Energy
  <.button
    phx-click="remove-tag"
    phx-value-tag="high-energy"
    aria-label="Remove tag"
  >
    <.icon><Heroicons.x /></.icon>
  </.button>
</.tag>
```

## Example CSS

For example CSS, you can have a look at the [demo styles](https://github.com/woylie/doggo/blob/main/demo/assets/css/components/_tag.scss).

# `build_time`
*since 0.6.0* *macro* 

Formats a `Time`, `DateTime`, or `NaiveDateTime` as a time and renders it
in a `<time>` element.

> #### Maturity: Refining {: .info}
>
> The API of this component can be considered fairly stable, but there
> are still uncertainties about accessibility aspects, such as the
> handling of the `<time>` element and its `datetime` attribute by screen
> readers and the limited accessibility of the title attribute.
>

## Configuration

Generate the component with default options:

    build_time()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :time, base_class: nil, modifiers: []]
```

## Usage

By default, the given value is formatted for display with `to_string/1`. This:

```heex
<.time value={~T[12:22:06.003Z]} />
```

Will be rendered as:

```html
<time datetime="12:22:06.003">
  12:22:06.003
</time>
```

You can also pass a custom formatter function. For example, if you are using
[ex_cldr_dates_times](https://hex.pm/packages/ex_cldr_dates_times) in your
application, you could do this:

```heex
<.time
  value={~T[12:22:06.003]}
  formatter={&MyApp.Cldr.Time.to_string!/1}
/>
```

Which, depending on your locale, may be rendered as:

```html
<time datetime="14:22:06.003">
  14:22:06 PM
</time>
```

The component can also truncate the value before passing it to the
formatter.

```heex
<.time
  value={~U[2023-02-05 12:22:06.003Z]}
  precision={:minute}
/>
```

If you pass a `title_formatter`, a `title` attribute is added to the
element. This can be useful if you want to render the value in a shortened
or relative format, but still give the user access to the complete value.
Note that the title attribute is only be accessible to users who use
a pointer device. Some screen readers may however announce the `datetime`
attribute that is always added.

```heex
<.time
  value={@time}
  formatter={&relative_time/1}
  title_formatter={&MyApp.Cldr.Time.to_string!/1}
/>
```

Finally, the component can shift a `DateTime` to a different time zone:

```heex
<.time
  value={~U[2023-02-05 23:22:05Z]}
  timezone="Asia/Tokyo"
/>
```

Which would be rendered as:

```html
<time datetime="08:22:05">
  08:22:05
</time>
```

# `build_tree`
*since 0.6.0* *macro* 

Renders a hierarchical list as a tree.

A good use case for this component is a folder structure. For navigation and
other menus, a regular nested list should be preferred.

> #### Maturity: Experimental {: .info}
>
> The necessary JavaScript for making this component fully functional and
> accessible will be added in a future version.
>
> **Missing features**
>
> - Expand and collapse nodes
> - Select nodes
> - Navigate tree with arrow keys
>

## Configuration

Generate the component with default options:

    build_tree()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :tree, base_class: "tree", modifiers: []]
```

## Usage

```heex
<.tree label="Dogs">
  <tree_item>
    Breeds
    <:items>
      <.tree_item>Golden Retriever</.tree_item>
      <.tree_item>Labrador Retriever</.tree_item>
    </:items>
  </.tree_item>
  <.tree_item>
    Characteristics
    <:items>
      <.tree_item>Playful</.tree_item>
      <.tree_item>Loyal</.tree_item>
    </:items>
  </.tree_item>
</.tree>
```

## CSS

You can target the wrapper with an attribute selector for the role:

```css
[role="tree"] {}
```

# `build_tree_item`
*since 0.6.0* *macro* 

Renders a tree item within a `tree/1`.

This component can be used as a direct child of `tree/1` or within the `items`
slot of this component.

> #### Maturity: Experimental {: .info}
>
> The necessary JavaScript for making this component fully functional and
> accessible will be added in a future version.
>
> **Missing featumres**
>
> - Expand and collapse nodes
> - Select nodes
> - Navigate tree with arrow keys
>

## Configuration

Generate the component with default options:

    build_tree_item()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :tree_item, base_class: "tree-item", modifiers: []]
```

## Usage

```heex
<.tree label="Dogs">
  <.tree_item>
    Breeds
    <:items>
      <.tree_item>Golden Retriever</.tree_item>
      <.tree_item>Labrador Retriever</.tree_item>
    </:items>
  </.tree_item>
  <.tree_item>
    Characteristics
    <:items>
      <.tree_item>Playful</.tree_item>
      <.tree_item>Loyal</.tree_item>
    </:items>
  </.tree_item>
</.tree>
```

Icons can be added before the label:

```heex
<.tree_item>
  <Heroicon.folder /> Breeds
  <:items>
    <.tree_item><Heroicon.document /> Golden Retriever</.tree_item>
    <.tree_item><Heroicon.document /> Labrador Retriever</.tree_item>
  </:items>
</.tree_item>
```

# `build_alert`
*since 0.6.0* *macro* 

The alert component serves as a notification mechanism to provide feedback to
the user.

For supplementary information that doesn't require the user's immediate
attention, use `callout/1` instead.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_alert()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[
  name: :alert,
  base_class: "alert",
  modifiers: [
    level: [values: ["info", "success", "warning", "danger"], default: "info"]
  ]
]
```

## Usage

Minimal example:

```heex
<.alert id="some-alert"></.alert>
```

With title, icon and level:

```heex
<.alert id="some-alert" level={:info} title="Info">
  message
  <:icon><Heroicon.light_bulb /></:icon>
</.alert>
```

# `build_alert_dialog`
*since 0.6.0* *macro* 

Renders an alert dialog that requires the immediate attention and response of
the user.

This component is meant for situations where critical information must be
conveyed, and an explicit response is required from the user. It is typically
used for confirmation dialogs, warning messages, error notifications, and
other scenarios where an immediate decision is necessary.

For non-critical dialogs, such as those containing forms or additional
information, use `Doggo.Components.build_modal/1` instead.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_alert_dialog()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :alert_dialog, base_class: "alert-dialog", modifiers: []]
```

## Usage

```heex
<.alert_dialog id="end-session-modal">
  <:title>End Training Session Early?</:title>
  <p>
    Are you sure you want to end the current training session with Bella?
    She's making great progress today!
  </p>
  <:footer>
    <.button phx-click="end-session">
      Yes, end session
    </.button>
    <.button phx-click={JS.exec("data-cancel", to: "#end-session-modal")}>
      No, continue training
    </.button>
  </:footer>
</.alert_dialog>
```

To open the dialog, use the `show_modal/1` function.

```heex
<.button
  phx-click={.show_modal("end-session-modal")}
  aria-haspopup="dialog"
>
  show
</.button>
```

## CSS

To hide the modal when the `open` attribute is not set, use the following CSS
styles:

```css
dialog.alert-dialog:not([open]),
dialog.alert-dialog[open="false"] {
  display: none;
}
```

## Semantics

While the `showModal()` JavaScript function is typically recommended for
managing modal dialog semantics, this component utilizes the `open` attribute
to control visibility. This approach is chosen to eliminate the need for
library consumers to add additional JavaScript code. To ensure proper
modal semantics, the `aria-modal` attribute is added to the dialog element.

# `build_badge`
*since 0.6.0* *macro* 

Generates a badge component, typically used for drawing attention to elements
like notification counts.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_badge()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[
  name: :badge,
  base_class: "badge",
  modifiers: [
    size: [values: ["small", "normal", "medium", "large"], default: "normal"],
    variant: [
      values: [nil, "primary", "secondary", "info", "success", "warning",
       "danger"],
      default: nil
    ]
  ]
]
```

## Usage

```heex
<.badge>8</.badge>
```

# `build_skeleton`
*since 0.6.0* *macro* 

Renders a skeleton loader, a placeholder for content that is in the process
of loading.

It mimics the layout of the actual content, providing a better user
experience during loading phases.

> #### Maturity: Developing {: .info}
>
> This component may not address all accessibility aspects.
>

## Configuration

Generate the component with default options:

    build_skeleton()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[
  name: :skeleton,
  base_class: "skeleton",
  modifiers: [
    type: [
      values: ["text-line", "text-block", "image", "circle", "rectangle",
       "square"],
      required: true
    ]
  ]
]
```

## Usage

Render one of the primitive types in isolation:

```heex
<.skeleton type="text_line" />
```

Combine primitives for complex layouts:

```heex
<div class="card-skeleton" aria-busy="true">
  <.skeleton type="image" />
  <.skeleton type="text-line" />
  <.skeleton type="text-line" />
  <.skeleton type="text-line" />
  <.skeleton type="rectangle" />
</div>
```

To modify the primitives for your use cases, you can either configure
additional modifiers or use CSS properties:

```heex
<Doggo.skeleton type="text-line" variant="header" />
```

```heex
<Doggo.skeleton type="image" style="--aspect-ratio: 75%;" />
```

## Aria-busy attribute

When using skeleton loaders, apply `aria-busy="true"` to the container
element that contains the skeleton layout. For standalone use, add the
attribute directly to the individual skeleton loader.

## Async result component

The easiest way to load data asynchronously and render a skeleton loader is
to use LiveView's
[async operations](`m:Phoenix.LiveView#module-async-operations`)
and `Phoenix.Component.async_result/1`.

Assuming you defined a card skeleton component as described above:

```heex
<.async_result :let={puppy} assign={@puppy}>
  <:loading><.card_skeleton /></:loading>
  <:failed :let={_reason}>There was an error loading the puppy.</:failed>
  <!-- Card for loaded content -->
</.async_result>
```

## Example CSS

For example CSS, you can have a look at the [demo styles](https://github.com/woylie/doggo/blob/main/demo/assets/css/components/_skeleton.scss).

# `build_field`
*since 0.6.0* *macro* 

Renders a form field including input, label, errors, and description.

A `Phoenix.HTML.FormField` may be passed as argument,
which is used to retrieve the input name, ID, and values.
Otherwise all attributes may be passed explicitly.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_field()

In addition to the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`, the build macro
also supports the following options.

- `:gettext_module` - If set, errors as well as the `required_text` and
  `optional_text` are automatically translated using this module. This only
  works if the `:field` attribute is set. Without it,
  errors passed to the component are rendered unchanged.
- `:required_text` - Defines a text that is rendered next to the label
  in required fields. Defaults to `"(required)"`. This value is translated
  if `gettext_module` is set. If you use a symbol like an asterisk, it is
  good practice to add a sentence explaining that fields marked with an
  that symbol are required.
- `:optional_text` - Defines a text that is rendered next to the label
  in optional fields. Defaults to `nil`. This value is translated
  if `gettext_module` is set.

### Default options

```elixir
[
  name: :field,
  base_class: "field",
  modifiers: [],
  gettext_module: nil,
  required_text: "(required)",
  optional_text: nil
]
```

## Usage

### Types

In addition to all HTML input types, the following type values are also
supported:

- `"select"`
- `"checkbox-group"`
- `"radio-group"`
- `"switch"`

### Class and Global Attribute

Note that the `class` attribute is applied to the outer container, while
the `rest` global attribute is applied to the `<input>` element.

### Gettext

To translate field errors as well as the `required_text` and `optional_text`
using Gettext, set the `gettext_module` option when building the component:

    build_field(gettext_module: MyApp.Gettext)

### Label positioning

The component does not provide an attribute to modify label positioning
directly. Instead, label positioning should be handled with CSS. If your
application requires different label positions, such as horizontal and
vertical layouts, it is recommended to add a modifier class to the form.

For example, the default style could position labels above inputs. To place
labels to the left of the inputs in a horizontal form layout, you can add an
`is-horizontal` class to the form:

```heex
<.form class="is-horizontal">
  <!-- inputs -->
</.form>
```

Then, in your CSS, apply the necessary styles to the `.field` class within
forms having the `is-horizontal` class:

```css
form.is-horizontal .field {
  // styles to position label left of the input
}
```

The component has a `hide_label` attribute to visually hide labels while still
making them accessible to screen readers. If all labels within a form need to
be visually hidden, it may be more convenient to define a
`.has-visually-hidden-labels` modifier class for the `<form>`.

```heex
<.form class="has-visually-hidden-labels">
  <!-- inputs -->
</.form>
```

Ensure to take checkbox and radio labels into consideration when writing the
CSS styles.

### Examples

```heex
<.field field={@form[:name]} />
```

```heex
<.field field={@form[:email]} type="email" />
```

#### Radio group and checkbox group

The `radio-group` and `checkbox-group` types allow you to easily render groups
of radio buttons or checkboxes with a single component invocation. The
`options` attribute is required for these types and has the same format as
the options for the `select` type, except that options may not be nested.

```heex
<.field
  field={@form[:email]}
  type="checkbox-group"
  label="Cuisine"
  options={[
    {"Mexican", "mexican"},
    {"Japanese", "japanese"},
    {"Libanese", "libanese"}
  ]}
/>
```

Note that the `checkbox-group` type renders an additional hidden input with
an empty value before the checkboxes. This ensures that a value exists in case
all checkboxes are unchecked. Consequently, the resulting list value includes
an extra empty string. While `Ecto.Changeset.cast/3` filters out empty strings
in array fields by default, you may need to handle the additional empty string
manual in other contexts.

# `build_field_group`
*since 0.6.0* *macro* 

Use the field group component to visually group multiple inputs in a form.

This component is intended for styling purposes and does not provide semantic
grouping. For semantic grouping of related form elements, use the `<fieldset>`
and `<legend>` HTML elements instead.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_field_group()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :field_group, base_class: "field-group", modifiers: []]
```

## Usage

Visual grouping of inputs:

```heex
<.field_group>
  <.field field={@form[:given_name]} label="Given name" />
  <.field field={@form[:family_name]} label="Family name"/>
</.field_group>
```

Semantic grouping (for reference):

```heex
<fieldset>
  <legend>Personal Information</legend>
  <.field field={@form[:given_name]} label="Given name" />
  <.field field={@form[:family_name]} label="Family name"/>
</fieldset>
```

# `build_app_bar`
*since 0.6.0* *macro* 

The app bar is typically located at the top of the interface and provides
access to key features and navigation options.

> #### Maturity: Experimental {: .info}

## Configuration

Generate the component with default options:

    build_app_bar()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :app_bar, base_class: "app-bar", modifiers: []]
```

## Usage

```heex
<.app_bar title="Page title">
  <:navigation label="Open menu" on_click={JS.push("toggle-menu")}>
    <.icon><Lucideicons.menu aria-hidden /></.icon>
  </:navigation>
  <:action label="Search" on_click={JS.push("search")}>
    <.icon><Lucideicons.search aria-hidden /></.icon>
  </:action>
  <:action label="Like" on_click={JS.push("like")}>
    <.icon><Lucideicons.heart aria-hidden /></.icon>
  </:action>
</.app_bar>
```

# `build_box`
*since 0.6.0* *macro* 

Renders a box for a section on the page.

> #### Maturity: Refining {: .info}

## Configuration

Generate the component with default options:

    build_box()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :box, base_class: "box", modifiers: []]
```

## Usage

Minimal example with only a box body:

```heex
<.box>
  <p>This is a box.</p>
</.box>
```

With title, banner, action, and footer:

```heex
<.box>
  <:title>Profile</:title>
  <:banner>
    <img src="banner-image.png" alt="" />
  </:banner>
  <:action>
    <button_link patch={~p"/profiles/#{@profile}/edit"}>Edit</button_link>
  </:action>

  <p>This is a profile.</p>

  <:footer>
    <p>Last edited: <%= @profile.updated_at %></p>
  </:footer>
</.box>
```

## Example CSS

For example CSS, you can have a look at the [demo styles](https://github.com/woylie/doggo/blob/main/demo/assets/css/components/_box.scss).

# `build_cluster`
*since 0.6.0* *macro* 

The cluster component is used to visually group child elements while
applying a consistent gap between them.

Common use cases are groups of buttons, groups of tags, or similar items.

> #### Maturity: Stable {: .info}

## Configuration

Generate the component with default options:

    build_cluster()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :cluster, base_class: "cluster", modifiers: []]
```

## Usage

```heex
<.cluster>
  <div>some item</div>
  <div>some other item</div>
</.cluster>
```

## Example CSS

For example CSS, you can have a look at the [demo styles](https://github.com/woylie/doggo/blob/main/demo/assets/css/layouts/_cluster.scss).

# `build_drawer`
*since 0.6.0* *macro* 

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.

> #### Maturity: Experimental {: .info}

## Configuration

Generate the component with default options:

    build_drawer()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :drawer, base_class: "drawer", modifiers: []]
```

## Usage

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

# `build_page_header`
*since 0.6.0* *macro* 

Renders a header that is specific to the content of the current page.

Unlike a site-wide header, which offers consistent navigation and elements
like logos throughout the website or application, this component is meant
to describe the unique content of each page. For instance, on an article page,
it would display the article's title.

It is typically used as a direct child of the `<main>` element.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_page_header()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :page_header, base_class: "page-header", modifiers: []]
```

## Usage

```heex
<main>
  <.page_header title="Puppy Profiles" subtitle="Share Your Pup's Story">
    <:action>
      <.button_link patch={~p"/puppies/new"}>Add New Profile</.button_link>
    </:action>
  </.page_header>

  <section>
    <!-- Content -->
  </section>
</main>
```

With back link:

```heex
<main>
  <.page_header title="Puppy Profile">
    <:navigation navigate={~p"/puppies"}>
      Back to puppy list
    </:navigation>
    <:action>
      <.button_link patch={~p"/puppies/new"}>Add New Profile</.button_link>
    </:action>
  </.page_header>

  <section>
    <!-- Content -->
  </section>
</main>
```

# `build_split_pane`
*since 0.6.0* *macro* 

Renders a horizontal or vertical resizable split pane.

> #### Maturity: Experimental {: .info}
>
> The necessary JavaScript for making this component fully functional and
> accessible will be added in a future version.
>
> **Missing features**
>
> - Resize panes with the mouse
> - Resize panes with the keyboard
>

## Configuration

Generate the component with default options:

    build_split_pane()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :split_pane, base_class: "split-pane", modifiers: []]
```

## Usage

Horizontal separator with label:

```heex
<.split_pane
  id="sidebar-splitter"
  label="Sidebar"
  orientation="horizontal"
>
  <:primary>One</:primary>
  <:secondary>Two</:secondary>
</.split_pane>
```

Horizontal separator with visible label:

```heex
<.split_pane id="sidebar-splitter"
  labelledby="sidebar-label"
  orientation="horizontal"
>
  <:primary>
    <h2 id="sidebar-label">Sidebar</h2>
    <p>One</p>
  </:primary>
  <:secondary>Two</:secondary>
</.split_pane>
```

Nested window splitters:

```heex
<.split_pane
  id="sidebar-splitter"
  label="Sidebar"
  orientation="horizontal"
>
  <:primary>One</:primary>
  <:secondary>
    <.split_pane
      id="filter-splitter"
      label="Filters"
      orientation="vertical"
    >
      <:primary>Two</:primary>
      <:secondary>Three</:secondary>
    </.split_pane>
  </:secondary>
</.split_pane>
```

# `build_stack`
*since 0.6.0* *macro* 

Applies a vertical margin between the child elements.

> #### Maturity: Stable {: .info}

## Configuration

Generate the component with default options:

    build_stack()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :stack, base_class: "stack", modifiers: []]
```

## Usage

```heex
<.stack>
  <div>some block</div>
  <div>some other block</div>
</.stack>
```

By default, the margin is only applied to the direct children of the
component. To apply a vertical margin on children at any nesting level, set
the `recursive` attribute.

```heex
<.stack recursive>
  <div>
    <div>some nested block</div>
    <div>another nested block</div>
  </div>
  <div>some other block</div>
</.stack>
```

## Example CSS

For example CSS, you can have a look at the [demo styles](https://github.com/woylie/doggo/blob/main/demo/assets/css/layouts/_stack.scss).

# `build_avatar`
*since 0.6.0* *macro* 

Renders profile picture, typically to represent a user.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_avatar()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[
  name: :avatar,
  base_class: "avatar",
  modifiers: [
    size: [values: ["small", "normal", "medium", "large"], default: "normal"],
    shape: [values: [nil, "circle"], default: nil]
  ]
]
```

## Usage

Minimal example with only the `src` attribute:

```heex
<.avatar src="avatar.png" />
```

Render avatar as a circle:

```heex
<.avatar src="avatar.png" circle />
```

Use a placeholder image in case the avatar is not set:

```heex
<.avatar src={@user.avatar_url} placeholder_src="fallback.png" />
```

Render an text as the placeholder value:

```heex
<.avatar src={@user.avatar_url} placeholder_content="A" />
```

# `build_carousel`
*since 0.6.0* *macro* 

Renders a carousel for presenting a sequence of items, such as images or text.

> #### Maturity: Experimental {: .info}
>
> The necessary JavaScript for making this component fully functional and
> accessible will be added in a future version.
>
> **Missing features**
>
> - Handle pagination tabs
> - Auto rotation
> - Disable auto rotation when controls are used
> - Disable previous/next button on first/last item.
> - Focus management and keyboard support for pagination
>

## Configuration

Generate the component with default options:

    build_carousel()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :carousel, base_class: "carousel", modifiers: []]
```

## Usage

```heex
<.carousel label="Our Dogs">
  <:previous label="Previous Slide">
    <Heroicons.chevron_left />
  </:previous>
  <:next label="Next Slide">
    <Heroicons.chevron_right />
  </:next>
  <:item label="1 of 3">
    <.image
      src="https://github.com/woylie/doggo/blob/main/assets/dog_poncho.jpg?raw=true"
      alt="A dog wearing a colorful poncho walks down a fashion show runway."
      ratio={{16, 9}}
    />
  </:item>
  <:item label="2 of 3">
    <.image
      src="https://github.com/woylie/doggo/blob/main/assets/dog_poncho.jpg?raw=true"
      alt="A dog dressed in a sumptuous, baroque-style costume, complete with jewels and intricate embroidery, parades on an ornate runway at a luxurious fashion show, embodying opulence and grandeur."
      ratio={{16, 9}}
    />
  </:item>
  <:item label="3 of 3">
    <.image
      src="https://github.com/woylie/doggo/blob/main/assets/dog_poncho.jpg?raw=true"
      alt="A dog adorned in a lavish, flamboyant outfit, including a large feathered hat and elaborate jewelry, struts confidently down a luxurious fashion show runway, surrounded by bright lights and an enthusiastic audience."
      ratio={{16, 9}}
    />
  </:item>
</.carousel>
```

This component defines colocated Phoenix LiveView hook with the name
`Doggo.Components.Carousel.` (note the trailing `.`).

```js
import { hooks as doggoHooks } from "phoenix-colocated/doggo";

const Hooks = {
  'Doggo.Components.Carousel.': doggoHooks['Doggo.Components.Carousel.']
};

const liveSocket = new LiveSocket("/live", Socket, {
  // ...
  hooks: Hooks,
});
```

## Example CSS

For example CSS, you can have a look at the [demo styles](https://github.com/woylie/doggo/blob/main/demo/assets/css/components/_carousel.scss).

# `build_frame`
*since 0.6.0* *macro* 

Renders a frame with an aspect ratio for images or videos.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_frame()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[
  name: :frame,
  base_class: "frame",
  modifiers: [
    ratio: [
      values: ["1:1", "3:2", "2:3", "4:3", "3:4", "5:4", "4:5", "16:9", "9:16"],
      required: true
    ],
    shape: [values: [nil, "circle"], default: nil]
  ]
]
```

## Usage

Rendering an image with the aspect ratio 4:3.

```heex
<.frame ratio="4:3">
  <img src="image.png" alt="An example image illustrating the usage." />
</.frame>
```

Rendering an image as a circle.

```heex
<.frame circle>
  <img src="image.png" alt="An example image illustrating the usage." />
</.frame>
```

# `build_icon`
*since 0.6.0* *macro* 

Renders an icon with optional text.

The component does not make assumptions about the icon library. Instead, it
allows you to reference functions from libraries or custom functions that
render SVG icons.

> #### Maturity: Refining {: .info}

## Configuration

Generate the component with default options:

    build_icon()

In addition to the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`, the build macro
also supports the following options.

- `:icon_module` (required) - The module that defines the function
  component(s) for rendering the icon SVG elements.
- `:icon_fun` - The name of a function component defined in the icon module
  that has a `name` attribute (string) renders the corresponding icon
  SVG element. If not set, the component will use the function component
  with the same name as the icon name and not set any attributes.
- `:names` - Either a list of available icon names or a 0-arity function
  that returns the list. This is only used in the generated storybook.

### Default options

```elixir
[
  name: :icon,
  base_class: "icon",
  modifiers: [],
  icon_module: nil,
  icon_fun: nil,
  names: []
]
```

## Usage

## Configuration

For icon libraries that define a separate function component for each
individual icon such as `heroicons`, you need to set the `icon_module`
option.

```elixir
defmodule MyAppWeb.CoreComponents do
  use Doggo.Components
  use Phoenix.Component

  build_icon(icon_module: Heroicons)
end
```

The `name` attribute passed to the generated icon component needs to
reference a function component in the configured module.

```heex
<.icon name="bug_ant" />
```

In this example, the icon component will use `Heroicons.bug_ant/1` to render
the SVG icon in its inner markup.

Names are internally normalized by replacing dashes with underscores.
Therefore, both `name="bug_ant"` and `name="bug-ant"` will work.

For icon libraries that expose a single function component, you can
additionally set the `icon_fun` option.

```elixir
build_icon(icon_module: MyIcons, icon_fun: :render)
```

In that case, the generated icon component will pass the `name` attribute
on to the referenced function component.

```heex
<.icon name="circle-question" />
```

In this example, the generated markup will be similar to:

```heex
<span class="icon">
  <MyIcons.render name="circle-question" />
</span>
```

## Text display

Render an icon with visually hidden text:

```heex
<.icon name="bug_ant" text="report bug" />
```

To display the text visibly:

```heex
<.icon name="bug_ant" text="report bug" text_position="after" />
```

Or:

```heex
<.icon name="bug_ant" text="report bug" text_position="before" />
```

The `text_position` attribute values are chosen to work with both
left-to-right and right-to-left languages. Refer to the CSS example for
applying the position correctly.

> #### aria-hidden {: .info}
>
> Not all icon libraries set the `aria-hidden` attribute by default. Always
> make sure that it is set on the `<svg>` element that the library renders.

## Example CSS

For example CSS, you can have a look at the [demo styles](https://github.com/woylie/doggo/blob/main/demo/assets/css/components/_icon.scss).

# `build_icon_sprite`
*since 0.6.0* *macro* 

Renders an icon using an SVG sprite.

> #### Maturity: Refining {: .info}

## Configuration

Generate the component with default options:

    build_icon_sprite()

In addition to the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`, the build macro
also supports the following options.

- `:sprite_url` - URL of the icon sprite.

### Default options

```elixir
[
  name: :icon_sprite,
  base_class: "icon",
  modifiers: [],
  sprite_url: "/assets/icons/sprite.svg"
]
```

## Usage

Render an icon with visually hidden text:

```heex
<.icon name="arrow-left" text="Go back" />
```

To display the text visibly:

```heex
<.icon name="arrow-left" text="Go back" text_position={:right} />
```

## Example CSS

For example CSS, you can have a look at the [demo styles](https://github.com/woylie/doggo/blob/main/demo/assets/css/components/_icon.scss).

# `build_image`
*since 0.6.0* *macro* 

Renders an image with an optional caption.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_image()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[
  name: :image,
  base_class: "image",
  modifiers: [
    ratio: [
      values: [nil, "1:1", "3:2", "2:3", "4:3", "3:4", "5:4", "4:5", "16:9",
       "9:16"],
      default: nil
    ]
  ]
]
```

## Usage

```heex
<.image
  src="https://github.com/woylie/doggo/blob/main/assets/dog_poncho.jpg?raw=true"
  alt="A dog wearing a colorful poncho walks down a fashion show runway."
  ratio={{16, 9}}
>
  <:caption>
    Spotlight on canine couture: A dog fashion show where four-legged models
    dazzle the runway with the latest in pet apparel.
  </:caption>
</.image>
```

# `build_menu`
*since 0.6.0* *macro* 

Renders a menu that offers a list of actions or functions.

This component is meant for organizing actions within an application, rather
than for navigating between different pages or sections of a website.

See also `menu_bar/1`, `menu_group/1`, `menu_button/1`, `menu_item/1`, and
`menu_item_checkbox/1`.

> #### Maturity: Experimental {: .info}
>
> The necessary JavaScript for making this component fully functional and
> accessible will be added in a future version.
>
> **Missing features**
>
> - Focus management
> - keyboard support
>

## Configuration

Generate the component with default options:

    build_menu()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :menu, base_class: "menu", modifiers: []]
```

## Usage

If the menu is always visible or can only be toggled by a keyboard shortcut,
set the `label` attribute.

```heex
<.menu label="Actions">
  <:item>Copy</:item>
  <:item>Paste</:item>
  <:item role="separator"></:item>
  <:item>Sort lines</:item>
</.menu>
```

If the menu is toggled by a `menu_button/1`, ensure that the `controls`
attribute of the button matches the DOM ID of the menu and that the
`labelledby` attribute of the menu matches the DOM ID of the button.

<.menu_button controls="actions-menu" id="actions-button">
  Actions
</.menu_button>
<.menu labelledby="actions-button" hidden></.menu>

# `build_menu_bar`
*since 0.6.0* *macro* 

Renders a menu bar, similar to those found in desktop applications.

This component is meant for organizing actions within an application, rather
than for navigating between different pages or sections of a website.

See also `menu/1`, `menu_group/1`, `menu_button/1`, `menu_item/1`, and
`menu_item_checkbox/1`.

> #### Maturity: Experimental {: .info}
>
> The necessary JavaScript for making this component fully functional and
> accessible will be added in a future version.
>
> **Missing features**
>
> - Focus management
> - keyboard support
>

## Configuration

Generate the component with default options:

    build_menu_bar()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :menu_bar, base_class: "menu-bar", modifiers: []]
```

## Usage

```heex
<.menu_bar label="Main">
  <:item>
    <.menu_button controls="actions-menu" id="actions-button">
      Actions
    </.menu_button>

    <.menu id="actions-menu" labelledby="actions-button" hidden>
      <:item>
        <.menu_item on_click={JS.push("view-dog-profiles")}>
          View Dog Profiles
        </.menu_item>
      </:item>
      <:item>
        <.menu_item on_click={JS.push("add-dog-profile")}>
          Add Dog Profile
        </.menu_item>
      </:item>
      <:item>
        <.menu_item on_click={JS.push("dog-care-tips")}>
          Dog Care Tips
        </.menu_item>
      </:item>
    </.menu>
  </:item>
  <:item role="separator"></:item>
  <:item>
    <.menu_item on_click={JS.dispatch("myapp:help")}>
      Help
    </.menu_item>
  </:item>
</.menu_bar>
```

# `build_menu_button`
*since 0.6.0* *macro* 

Renders a button that toggles an actions menu.

This component can be used on its own or as part of a `menu_bar/1` or `menu/1`.
See also `menu_item/1`, `menu_item_checkbox/1`, and `menu_group/1`.

For a button that toggles the visibility of an element that is not a menu, use
`disclosure_button/1`. For a button that toggles other states, use
`toggle_button/1`. See also `button/1` and `button_link/1`.

> #### Maturity: Experimental {: .info}

## Configuration

Generate the component with default options:

    build_menu_button()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :menu_button, base_class: "menu-button", modifiers: []]
```

## Usage

Set the `controls` attribute to the DOM ID of the element that you want to
toggle with the button.

The initial state is hidden. Do not forget to add the `hidden` attribute to
the toggled menu. Otherwise, visibility of the element will not align with
the `aria-expanded` attribute of the button.

```heex
<div>
  <.menu_button controls="actions-menu" id="actions-button">
    Actions
  </.menu_button>

  <.menu id="actions-menu" labelledby="actions-button" hidden>
    <:item>
      <.menu_item on_click={JS.push("view-dog-profiles")}>
        View Dog Profiles
      </.menu_item>
    </:item>
    <:item>
      <.menu_item on_click={JS.push("add-dog-profile")}>
        Add Dog Profile
      </.menu_item>
    </:item>
    <:item>
      <.menu_item on_click={JS.push("dog-care-tips")}>
        Dog Care Tips
      </.menu_item>
    </:item>
  </.menu>
</div>
```

If this menu button is a child of a `menu_bar/1` or a `menu/1`, set the
`menuitem` attribute.

```heex
<.menu id="actions-menu">
  <:item>
    <.menu_button controls="actions-menu" id="actions-button" menuitem>
      Dog Actions
    </.menu_button>
    <.menu id="dog-actions-menu" labelledby="actions-button" hidden>
      <:item><!-- ... --></:item>
    </.menu>
  </:item>
  <:item><!-- ... --></:item>
</.menu>
```

# `build_menu_group`
*since 0.6.0* *macro* 

This component can be used to group items within a `menu/1` or `menu_bar/1`.

See also `menu_button/1`, `menu_item/1`, and `menu_item_checkbox/1`.

> #### Maturity: Experimental {: .info}
>
> The necessary JavaScript for making this component fully functional and
> accessible will be added in a future version.
>
> **Missing features**
>
> - Focus management
> - Keyboard support
>

## Configuration

Generate the component with default options:

    build_menu_group()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :menu_group, base_class: "menu-group", modifiers: []]
```

## Usage

```heex
<.menu id="actions-menu" labelledby="actions-button" hidden>
  <:item>
    <.menu_group label="Dog actions">
      <:item>
        <.menu_item on_click={JS.push("view-dog-profiles")}>
          View Dog Profiles
        </.menu_item>
      </:item>
      <:item>
        <.menu_item on_click={JS.push("add-dog-profile")}>
          Add Dog Profile
        </.menu_item>
      </:item>
      <:item>
        <.menu_item on_click={JS.push("dog-care-tips")}>
          Dog Care Tips
        </.menu_item>
      </:item>
    </.menu_group>
  </:item>
  <:item role="separator" />
  <:item>
    <.menu_item on_click={JS.push("help")}>Help</.menu_item>
  </:item>
</.menu>
```

# `build_menu_item`
*since 0.6.0* *macro* 

Renders a button that acts as a menu item within a `menu/1` or `menu_bar/1`.

A menu item is meant to be used to trigger an action. For a button that
toggles the visibility of a menu, use `menu_button/1`.

> #### Maturity: Experimental {: .info}

## Configuration

Generate the component with default options:

    build_menu_item()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :menu_item, base_class: "menu-item", modifiers: []]
```

## Usage

```heex
<.menu label="Actions">
  <:item>
    <.menu_item on_click={JS.dispatch("myapp:copy")}>
      Copy
    </.menu_item>
  </:item>
  <:item>
    <.menu_item on_click={JS.dispatch("myapp:paste")}>
      Paste
    </.menu_item>
  </:item>
</.menu>
```

# `build_menu_item_checkbox`
*since 0.6.0* *macro* 

Renders a menu item checkbox as part of a `menu/1` or `menu_bar/1`.

See also `menu_item/1`.

> #### Maturity: Experimental {: .info}
>
> The necessary JavaScript for making this component fully functional and
> accessible will be added in a future version.
>
> **Missing features**
>
> - State management
> - Keyboard support
>

## Configuration

Generate the component with default options:

    build_menu_item_checkbox()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :menu_item_checkbox, base_class: "menu-item-checkbox", modifiers: []]
```

## Usage

```heex
<.menu label="Actions">
  <:item>
    <.menu_item_checkbox on_click={JS.dispatch("myapp:toggle-word-wrap")}>
      Word wrap
    </.menu_item_checkbox>
  </:item>
</.menu>
```

# `build_menu_item_radio_group`
*since 0.6.0* *macro* 

Renders a group of menu item radios as part of a `menu/1` or `menu_bar/1`.

See also `menu_button/1`, `menu_item/1`, and `menu_item_checkbox/1`.

> #### Maturity: Experimental {: .info}
>
> The necessary JavaScript for making this component fully functional and
> accessible will be added in a future version.
>
> **Missing features**
>
> - Focus management
> - State management
> - Keyboard support
>

## Configuration

Generate the component with default options:

    build_menu_item_radio_group()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[
  name: :menu_item_radio_group,
  base_class: "menu-item-radio-group",
  modifiers: []
]
```

## Usage

```heex
<.menu id="actions-menu" labelledby="actions-button" hidden>
  <:item>
    <.menu_item_radio_group label="Theme">
      <:item on_click={JS.dispatch("switch-theme-light")}>
        Light
      </:item>
      <:item on_click={JS.dispatch("switch-theme-dark")} checked>
        Dark
      </:item>
    </.menu_item_radio_group>
  </:item>
</.menu>
```

# `build_action_bar`
*since 0.6.0* *macro* 

The action bar offers users quick access to primary actions within the
application.

It is typically positioned to float above other content.

> #### Maturity: Experimental {: .info}
>
> The necessary JavaScript for making this component fully functional and
> accessible will be added in a future version.
>
> **Missing features**
>
> - Roving tabindex
> - Move focus with arrow keys
>

## Configuration

Generate the component with default options:

    build_action_bar()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :action_bar, base_class: "action-bar", modifiers: []]
```

## Usage

```heex
<.action_bar>
  <:item label="Edit" on_click={JS.push("edit")}>
    <.icon><Lucideicons.pencil aria-hidden /></.icon>
  </:item>
  <:item label="Move" on_click={JS.push("move")}>
    <.icon><Lucideicons.move aria-hidden /></.icon>
  </:item>
  <:item label="Archive" on_click={JS.push("archive")}>
    <.icon><Lucideicons.archive aria-hidden /></.icon>
  </:item>
</.action_bar>
```

# `build_callout`
*since 0.6.0* *macro* 

Use the callout to highlight supplementary information related to the main
content.

For information that needs immediate attention of the user, use `alert/1`
instead.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_callout()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[
  name: :callout,
  base_class: "callout",
  modifiers: [
    variant: [values: ["info", "success", "warning", "danger"], default: "info"]
  ]
]
```

## Usage

Standard callout:

```heex
<.callout id="callout-dog-care-tip" title="Dog Care Tip">
  <p>Regular exercise is essential for keeping your dog healthy and happy.</p>
</.callout>
```

Callout with an icon:

```heex
<.callout id="callout-fun-dog-fact" title="Fun Dog Fact">
  <:icon><Heroicons.information_circle /></:icon>
  <p>
    Did you know? Dogs have a sense of time and can get upset when their
    routine is changed.
  </p>
</.callout>
```

# `build_combobox`
*since 0.6.0* *macro* 

Renders a text input with a popup that allows users to select a value from
a list of suggestions.

> #### Maturity: Experimental {: .info}
>
> The necessary JavaScript for making this component fully functional and
> accessible will be added in a future version.
>
> **Missing features**
>
> - Showing/hiding suggestions
> - Filtering suggestions
> - Selecting a value
> - Focus management
> - Keyboard support
>

## Configuration

Generate the component with default options:

    build_combobox()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :combobox, base_class: "combobox", modifiers: []]
```

## Usage

With simple values:

```heex
<.combobox
  id="dog-breed-selector"
  name="breed"
  list_label="Dog breeds"
  options={[
    "Labrador Retriever",
    "German Shepherd",
    "Golden Retriever",
    "French Bulldog",
    "Bulldog"
  ]}
/>
```

With label/value pairs:

```heex
<.combobox
  id="dog-breed-selector"
  name="breed"
  list_label="Dog breeds"
  options={[
    {"Labrador Retriever", "labrador"},
    {"German Shepherd", "german_shepherd"},
    {"Golden Retriever", "golden_retriever"},
    {"French Bulldog", "french_bulldog"},
    {"Bulldog", "bulldog"}
  ]}
/>
```

With label/value/description tuples:

```heex
<.combobox
  id="dog-breed-selector"
  name="breed"
  list_label="Dog breeds"
  options={[
    {"Labrador Retriever", "labrador", "Friendly and outgoing"},
    {"German Shepherd", "german_shepherd", "Confident and smart"},
    {"Golden Retriever", "golden_retriever", "Intelligent and friendly"},
    {"French Bulldog", "french_bulldog", "Adaptable and playful"},
    {"Bulldog", "bulldog", "Docile and willful"}
  ]}
/>
```

# `build_modal`
*since 0.6.0* *macro* 

Renders a modal dialog for content such as forms and informational panels.

This component is appropriate for non-critical interactions. For dialogs
requiring immediate user response, such as confirmations or warnings, use
`.alert_dialog/1` instead.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_modal()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :modal, base_class: "modal", modifiers: []]
```

## Usage

There are two primary ways to manage the display of the modal: via URL state
or by setting and removing the `open` attribute.

### With URL

To toggle the modal visibility based on the URL:

1. Use the `:if` attribute to conditionally render the modal when a specific
   live action matches.
2. Set the `on_cancel` attribute to patch back to the original URL when the
   user chooses to close the modal.
3. Set the `open` attribute to declare the modal's initial visibility state.

#### Example

```heex
<.modal
  :if={@live_action == :show}
  id="pet-modal"
  on_cancel={JS.patch(~p"/pets")}
  open
>
  <:title>Show pet</:title>
  <p>My pet is called Johnny.</p>
  <:footer>
    <.link phx-click={JS.exec("data-cancel", to: "#pet-modal")}>
      Close
    </.link>
  </:footer>
</.modal>
```

To open the modal, patch or navigate to the URL associated with the live
action.

```heex
<.link patch={~p"/pets/#{@id}"}>show</.link>
```

### Without URL

To toggle the modal visibility dynamically with the `open` attribute:

1. Omit the `open` attribute in the template.
2. Use the `show_modal/1` and `hide_modal/1` functions to change the
   visibility.

#### Example

```heex
<.modal id="pet-modal">
  <:title>Show pet</:title>
  <p>My pet is called Johnny.</p>
  <:footer>
    <.link phx-click={JS.exec("data-cancel", to: "#pet-modal")}>
      Close
    </.link>
  </:footer>
</.modal>
```

To open modal, use the `show_modal/1` function.

```heex
<.button
  phx-click={Doggo.show_modal("pet-modal")}
  aria-haspopup="dialog"
>
  show
</.button>
```

## CSS

To hide the modal when the `open` attribute is not set, use the following CSS
styles:

```css
dialog.modal:not([open]),
dialog.modal[open="false"] {
  display: none;
}
```

## Semantics

While the `showModal()` JavaScript function is typically recommended for
managing modal dialog semantics, this component utilizes the `open` attribute
to control visibility. This approach is chosen to eliminate the need for
library consumers to add additional JavaScript code. To ensure proper
modal semantics, the `aria-modal` attribute is added to the dialog element.

# `build_radio_group`
*since 0.6.0* *macro* 

Renders a group of radio buttons, for example for a toolbar.

To render radio buttons within a regular form, use `input/1` with the
`"radio-group"` type instead.

> #### Maturity: Experimental {: .info}

## Configuration

Generate the component with default options:

    build_radio_group()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :radio_group, base_class: "radio-group", modifiers: []]
```

## Usage

```heex
<.radio_group
  id="favorite-dog"
  name="favorite-dog"
  label="Favorite Dog"
  options={[
    {"Labrador Retriever", "labrador"},
    {"German Shepherd", "german_shepherd"},
    {"Golden Retriever", "golden_retriever"},
    {"French Bulldog", "french_bulldog"},
    {"Beagle", "beagle"}
  ]}
/>
```

## CSS

To target the wrapper, you can use an attribute selector:

```css
[role="radio-group"] {}
```

# `build_toolbar`
*since 0.6.0* *macro* 

Renders a container for a set of controls.

> #### Maturity: Experimental {: .info}
>
> The necessary JavaScript for making this component fully functional and
> accessible will be added in a future version.
>
> **Missing features**
>
> - Roving tabindex
> - Move focus with arrow keys
>

## Configuration

Generate the component with default options:

    build_toolbar()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :toolbar, base_class: "toolbar", modifiers: []]
```

## Usage

Direct children of this component can be any types buttons or groups of
buttons.

```heex
<.toolbar label="Actions for the dog">
  <div role="group">
    <button phx-click="feed-dog">
      <.icon label="Feed dog"><Icons.feed /></.icon>
    </button>
    <button phx-click="walk-dog">
      <.icon label="Walk dog"><Icons.walk /></.icon>
    </button>
  </div>
  <div role="group">
    <button phx-click="teach-trick">
      <.icon label="Teach a Trick"><Icons.teach /></.icon>
    </button>
    <button phx-click="groom-dog">
      <.icon label="Groom dog"><Icons.groom /></.icon>
    </button>
  </div>
</.toolbar>
```

# `build_tooltip`
*since 0.6.0* *macro* 

Renders content with a tooltip.

There are different ways to render a tooltip. This component renders a `<div>`
with the `tooltip` role, which is hidden unless the element is hovered on or
focused. For example CSS for this kind of tooltip, refer to
[ARIA: tooltip role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tooltip_role).

A simpler alternative for styled text-only tooltips is to use a data attribute
and the [`attr` CSS function](https://developer.mozilla.org/en-US/docs/Web/CSS/attr).
Doggo does not provide a component for that kind of tooltip, since it is
controlled by attributes only. You can check
[Pico CSS](https://picocss.com/docs/tooltip) for an example implementation.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_tooltip()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :tooltip, base_class: "tooltip-container", modifiers: []]
```

## Usage

With an inline text:

```heex
<p>
  Did you know that the
  <.tooltip id="labrador-info">
    Labrador Retriever
    <:tooltip>
      <p><strong>Labrador Retriever</strong></p>
      <p>
        Labradors are known for their friendly nature and excellent
        swimming abilities.
      </p>
    </:tooltip>
  </.tooltip>
  is one of the most popular dog breeds in the world?
</p>
```

If the inner block contains a link, add the `:contains_link` attribute:

```heex
<p>
  Did you know that the
  <.tooltip id="labrador-info" contains_link>
    <.link navigate={~p"/labradors"}>Labrador Retriever</.link>
    <:tooltip>
      <p><strong>Labrador Retriever</strong></p>
      <p>
        Labradors are known for their friendly nature and excellent
        swimming abilities.
      </p>
    </:tooltip>
  </.tooltip>
  is one of the most popular dog breeds in the world?
</p>
```

# `build_bottom_navigation`
*since 0.6.0* *macro* 

Renders a navigation that sticks to the bottom of the screen.

> #### Maturity: Experimental {: .info}

## Configuration

Generate the component with default options:

    build_bottom_navigation()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :bottom_navigation, base_class: "bottom-navigation", modifiers: []]
```

## Usage

```heex
<.bottom_navigation current_value={@view}>
  <:item
    label="Profile"
    navigate={~p"/pets/#{@pet}"}
    value={Profile}
  >
    <Lucideicons.user aria-hidden="true" />
  </:item>
  <:item
    label="Appointments"
    navigate={~p"/pets/#{@pet}/appointments"}
    value={Appointments}
  >
    <Lucideicons.calendar_days aria-hidden="true" />
  </:item>
  <:item
    label="Messages"
    navigate={~p"/pets/#{@pet}/messages"}
    value={Messages}
  >
    <Lucideicons.mails aria-hidden="true" />
  </:item>
</.bottom_navigation>
```

# `build_breadcrumb`
*since 0.6.0* *macro* 

Renders a breadcrumb navigation.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_breadcrumb()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :breadcrumb, base_class: "breadcrumb", modifiers: []]
```

## Usage

```heex
<.breadcrumb>
  <:item patch="/categories">Categories</:item>
  <:item patch="/categories/1">Reviews</:item>
  <:item patch="/categories/1/articles/1">The Movie</:item>
</.breadcrumb>
```

# `build_navbar`
*since 0.6.0* *macro* 

Renders a navigation bar.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_navbar()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :navbar, base_class: "navbar", modifiers: []]
```

## Usage

```heex
<.navbar>
  <:brand><.link navigate={~p"/"}>Pet Clinic</.link></:brand>
  <.navbar_items>
    <:item><.link navigate={~p"/about"}>About</.link></:item>
    <:item><.link navigate={~p"/services"}>Services</.link></:item>
    <:item>
      <.link navigate={~p"/login"} class="button">Log in</.link>
    </:item>
  </.navbar_items>
</.navbar>
```

You can place multiple navigation item lists in the inner block. If the
`.navbar` is styled as a flex box, you can use the CSS `order` property to
control the display order of the brand and lists.

```heex
<.navbar>
  <:brand><.link navigate={~p"/"}>Pet Clinic</.link></:brand>
  <.navbar_items class="navbar-main-links">
    <:item><.link navigate={~p"/about"}>About</.link></:item>
    <:item><.link navigate={~p"/services"}>Services</.link></:item>
  </.navbar_items>
  <.navbar_items class="navbar-user-menu">
    <:item>
      <.button_link navigate={~p"/login"}>Log in</.button_link>
    </:item>
  </.navbar_items>
</.navbar>
```

If you have multiple `<nav>` elements on your page, it is recommended to set
the `aria-label` attribute.

```heex
<.navbar aria-label="main navigation">
  <!-- ... -->
</.navbar>
```

# `build_navbar_items`
*since 0.6.0* *macro* 

Renders a list of navigation items.

Meant to be used in the inner block of the `navbar` component.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_navbar_items()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :navbar_items, base_class: "navbar-items", modifiers: []]
```

## Usage

```heex
<.navbar_items>
  <:item><.link navigate={~p"/about"}>About</.link></:item>
  <:item><.link navigate={~p"/services"}>Services</.link></:item>
  <:item>
    <.link navigate={~p"/login"} class="button">Log in</.link>
  </:item>
</.navbar_items>
```

# `build_steps`
*since 0.6.0* *macro* 

Renders a navigation for form steps.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_steps()

In addition to the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`, the build macro
also supports the following options.

- `:current_class` - This class is added to the current step.
- `:completed_class` - This class is added to previous steps.
- `:upcoming_class` - This class is added to upcoming steps.
- `:visually_hidden_class` - This class is used to visually hide the
  accessibility text added to completed steps.

### Default options

```elixir
[name: :steps, base_class: "steps", modifiers: []]
```

## Usage

With patch navigation:

```heex
<.steps current_step={0}>
  <:step on_click={JS.patch(to: ~p"/form/step/personal-information")}>
    Profile
  </:step>
  <:step on_click={JS.patch(to: ~p"/form/step/delivery")}>
    Delivery
  </:step>
  <:step on_click={JS.patch(to: ~p"/form/step/confirmation")}>
    Confirmation
  </:step>
</.steps>
```

With push events:

```heex
<.steps current_step={0}>
  <:step on_click={JS.push("go-to-step", value: %{step: "profile"})}>
    Profile
  </:step>
  <:step on_click={JS.push("go-to-step", value: %{step: "delivery"})}>
    Delivery
  </:step>
  <:step on_click={JS.push("go-to-step", value: %{step: "confirmation"})}>
    Confirmation
  </:step>
</.steps>
```

# `build_tab_navigation`
*since 0.6.0* *macro* 

Renders navigation tabs.

This component is meant for tabs that link to a different view or live
action, each with a distinct URL. If you want to render tabs that switch
between in-page content panels, use `tabs/1` instead.

> #### Maturity: Refining {: .info}

## Configuration

Generate the component with default options:

    build_tab_navigation()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :tab_navigation, base_class: "tab-navigation", modifiers: []]
```

## Usage

```heex
<.tab_navigation current_value={@live_action}>
  <:item
    patch={~p"/pets/#{@pet}"}
    value={[:show, :edit]}
  >
    Profile
  </:item>
  <:item
    patch={~p"/pets/#{@pet}/appointments"}
    value={:appointments}
  >
    Appointments
  </:item>
  <:item
    patch={~p"/pets/#{@pet}/messages"}
    value={:messages}
  >
    Messages
  </:item>
</.tab_navigation>
```

### Current Item

Each item has a `value` attribute that can be either a single value or a
list of values. If you patch between live actions using this component, you
would set the value to the list of live actions for which this tab is
active.

The root element itself has a `current_value` attribute. To determine
whether a tab item is active, the current value is compared with the value
of the tab item. If the value is a list, the tab item is considered active
if the current value is contained in that list.

Tab items are marked active by setting `aria-current="page"`. You can select
the item in CSS with `.tab-navigation a[aria-current]`.

## Example CSS

For example CSS, you can have a look at the [demo styles](https://github.com/woylie/doggo/blob/main/demo/assets/css/components/_tab-navigation.scss).

# `build_vertical_nav`
*since 0.6.0* *macro* 

Renders a vertical navigation menu.

It is commonly placed within drawers or sidebars.

For hierarchical menu structures, use `vertical_nav_nested/1` within the
`:item` slot.

To include sections in your drawer or sidebar that are not part of the
navigation menu (like informational text or a site search), use the
`vertical_nav_section/1` component.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_vertical_nav()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :vertical_nav, base_class: "vertical-nav", modifiers: []]
```

## Usage

```heex
<.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>
```

# `build_vertical_nav_nested`
*since 0.6.0* *macro* 

Renders nested navigation items within the `:item` slot of the
`vertical_nav/1` component.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_vertical_nav_nested()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :vertical_nav_nested, base_class: "vertical-nav-nested", modifiers: []]
```

## Usage

```heex
<.vertical_nav label="Main">
  <: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>
```

# `build_vertical_nav_section`
*since 0.6.0* *macro* 

Renders a section within a sidebar or drawer that contains one or more
items which are not navigation links.

To render navigation links, use `vertical_nav/1` instead.

> #### Maturity: Developing {: .info}

## Configuration

Generate the component with default options:

    build_vertical_nav_section()

The build macro supports the [common options](`m:Doggo.Components#module-common-options`)
`name`, `base_class`, and `modifiers`.

### Default options

```elixir
[name: :vertical_nav_section, base_class: "vertical-nav-section", modifiers: []]
```

## Usage

```heex
<.vertical_nav_section>
  <:title>Search</:title>
  <:item><input type="search" placeholder="Search" /></:item>
</.vertical_nav_section>
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
