1
0
mirror of https://github.com/axzilla/templui.git synced 2025-02-24 04:04:09 +00:00
templui/pkg/components/accordion.templ

96 lines
3.0 KiB
Plaintext
Raw Normal View History

2024-10-07 09:49:40 +02:00
package components
import "github.com/axzilla/goilerplate/pkg/icons"
2024-10-07 09:49:40 +02:00
// AccordionItem represents a single item in the Accordion component.
type AccordionItem struct {
// ID is the unique identifier for the accordion item.
// It is used to manage the open/closed state of the item.
ID string
// Trigger is the content of the accordion item's header/trigger.
// This is typically text, but can be any templ.Component.
Trigger templ.Component
// Content is the expandable content of the accordion item.
// This can be any templ.Component.
Content templ.Component
}
// AccordionProps defines the properties for the Accordion component.
type AccordionProps struct {
// Items is a slice of AccordionItem structs representing each item in the accordion.
Items []AccordionItem
// Class specifies additional CSS classes to apply to the accordion container.
// Default: "" (empty string)
Class string
// Attributes allows passing additional HTML attributes to the accordion container element.
// Default: nil
Attributes templ.Attributes
}
// Accordion renders an accordion component based on the provided props.
// It uses Alpine.js for interactivity and state management.
//
// Usage:
//
// @components.Accordion(components.AccordionProps{
// Items: []components.AccordionItem{
// {
// ID: "item-1",
// Trigger: templ.Raw("Is it accessible?"),
// Content: templ.Raw("Yes. It adheres to the WAI-ARIA design pattern."),
// },
// {
// ID: "item-2",
// Trigger: templ.Raw("Is it styled?"),
// Content: templ.Raw("Yes. It comes with default styles that match the other components' aesthetic."),
// },
// },
// Class: "w-full sm:max-w-[70%]",
// Attributes: templ.Attributes{"data-testid": "my-accordion"},
// })
//
// Props:
// - Items: A slice of AccordionItem structs, each representing an item in the accordion.
// - Class: Additional CSS classes to apply to the accordion container. Default: "" (empty string)
// - Attributes: Additional HTML attributes to apply to the accordion container element. Default: nil
templ Accordion(props AccordionProps) {
<div
x-data="{
activeItem: null,
toggleItem(itemId) {
this.activeItem = this.activeItem === itemId ? null : itemId;
}
}"
class={ "divide-y divide-border rounded-md border", props.Class }
{ props.Attributes... }
>
for _, item := range props.Items {
<div class="group">
<h3>
<button
type="button"
@click={ "toggleItem('" + item.ID + "')" }
class="flex w-full items-center justify-between py-4 px-5 text-left font-medium transition-all hover:underline [&[aria-expanded=true]>svg]:rotate-180"
:aria-expanded={ "activeItem === '" + item.ID + "'" }
>
@item.Trigger
@icons.ChevronDown(icons.IconProps{Size: "16"})
2024-10-07 09:49:40 +02:00
</button>
</h3>
<div
x-show={ "activeItem === '" + item.ID + "'" }
x-collapse
x-cloak
class="px-5 pb-4 pt-0"
>
@item.Content
</div>
</div>
}
</div>
}