Accordion
Vertically stacked interactive sections to organize content.
TailwindCSS
Is it accessible?
Yes. It adheres to the WAI-ARIA design pattern.
Is it styled?
Yes. It comes with default styles that matches the other components aesthetic.
Is it animated?
Yes. It's animated by default, but you can disable it if you prefer.
package showcase
import "github.com/axzilla/templui/components"
templ AccordionDefault() {
<div class="w-full max-w-sm">
@components.Accordion(components.AccordionProps{
Class: "w-full",
}) {
@components.AccordionItem() {
@components.AccordionTrigger() {
Is it accessible?
}
@components.AccordionContent() {
Yes. It adheres to the WAI-ARIA design pattern.
}
}
@components.AccordionItem() {
@components.AccordionTrigger() {
Is it styled?
}
@components.AccordionContent() {
Yes. It comes with default styles that matches the other components aesthetic.
}
}
@components.AccordionItem() {
@components.AccordionTrigger() {
Is it animated?
}
@components.AccordionContent() {
Yes. It's animated by default, but you can disable it if you prefer.
}
}
}
</div>
}
package components
import (
"github.com/axzilla/templui/icons"
"github.com/axzilla/templui/utils"
)
type AccordionProps struct {
ID string
Class string
Attributes templ.Attributes
}
type AccordionItemProps struct {
ID string
Class string
Attributes templ.Attributes
}
type AccordionTriggerProps struct {
ID string
Class string
Attributes templ.Attributes
}
type AccordionContentProps struct {
ID string
Class string
Attributes templ.Attributes
}
templ Accordion(props ...AccordionProps) {
{{ var p AccordionProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"divide-y rounded-md divide-border border",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</div>
}
templ AccordionItem(props ...AccordionItemProps) {
{{ var p AccordionItemProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<details
if p.ID != "" {
id={ p.ID }
}
name="accordion"
class={
utils.TwMerge(
"group",
"open:[&>summary_svg]:rotate-180",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</details>
}
templ AccordionTrigger(props ...AccordionTriggerProps) {
{{ var p AccordionTriggerProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<summary
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex w-full items-center justify-between py-4 px-5",
"text-left font-medium cursor-pointer",
"transition-all hover:underline",
"list-none [&::-webkit-details-marker]:hidden",
p.Class,
),
}
{ p.Attributes... }
>
<div class="flex-1">
{ children... }
</div>
@icons.ChevronDown(icons.IconProps{Size: 16, Class: "transition-transform"})
</summary>
}
templ AccordionContent(props ...AccordionContentProps) {
{{ var p AccordionContentProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"px-5 pb-4 pt-0",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</div>
}
Usage
@components.Accordion(components.AccordionProps{...})