glaze/oat/accordion

Oat documentation: https://oat.ink/components/accordion/

The accordion helpers render semantic HTML accordion markup using <details> and <summary> elements.

Anatomy

An accordion is a container of collapsible sections rendered as <details><summary>...</summary>...</details>. Most apps compose it from item entries, with optional group wrappers when you want browser-native single-open behavior per group.

Group behaviour

Items inside a group get a shared name attribute on their underlying <details> elements. Browsers use this to treat them as a mutually-exclusive set, so opening one closes others with the same name.

Items not placed in a group are rendered without a name attribute and can be opened independently.

Recipes

A basic accordion inside a section

import glaze/oat/accordion
import lustre/element/html

fn faq() {
  accordion.accordion(
    html.section,
    [],
    [
      accordion.item(
        label: html.text("What is Oat?"),
        content: [html.p([], [html.text("A UI toolkit for Lustre.")])],
      ),
      accordion.item(
        label: html.text("Does it use semantic HTML?"),
        content: [html.p([], [html.text("Yes, with details/summary.")])],
      ),
    ],
  )
}

Multiple groups in one container

import glaze/oat/accordion
import lustre/element/html

fn settings_panels() {
  accordion.accordion(
    html.div,
    [],
    [
      accordion.group("account", [
        accordion.item(label: html.text("Profile"), content: [html.text("...")]),
        accordion.item(label: html.text("Security"), content: [html.text("...")]),
      ]),
      accordion.group("notifications", [
        accordion.item(label: html.text("Email"), content: [html.text("...")]),
        accordion.item(label: html.text("Push"), content: [html.text("...")]),
      ]),
    ],
  )
}

References

Types

Represents an accordion entry in the tree passed to accordion.

Values are either:

  • item: one rendered <details> block.
  • group: a named collection of nested items.

This type is opaque to keep rendering rules internal and predictable.

pub opaque type Item(msg)

Values

pub fn accordion(
  element: fn(
    List(attribute.Attribute(msg)),
    List(element.Element(msg)),
  ) -> element.Element(msg),
  attrs: List(attribute.Attribute(msg)),
  children: List(Item(msg)),
) -> element.Element(msg)

Render an accordion container from a list of items.

You provide:

  • element: the container constructor (for example html.div, html.section)
  • attrs: attributes for that container
  • children: items and/or groups to render

Each item renders to:

  • <details>
    • <summary>{label}</summary>
    • {content...}

Grouped items include a shared name attribute on <details> to enable browser-native single-open behavior within that group.

pub fn group(name: String, items: List(Item(msg))) -> Item(msg)

Create a named group of accordion items.

All items in a group are rendered with <details name="{name}">, allowing the browser to manage them as a mutually-exclusive set.

Use distinct names for separate groups.

pub fn item(
  label label: element.Element(msg),
  content content: List(element.Element(msg)),
) -> Item(msg)

Create a single accordion item.

The label is rendered inside <summary>, and content is rendered as the body of the corresponding <details>.

Keep the label concise and descriptive for accessibility and scanning.

Search Document