Componentcarousel
Carousel
A carousel with motion and swipe built using native scroll behavior.
Preview
A carousel with motion and swipe built using native scroll behavior.
Slide 1
@ui.Carousel(ui.CarouselProps{DOMProps: ui.DOMProps{Class: "w-full max-w-xs"}}) {
@ui.CarouselContent(ui.DOMProps{}) {
@ui.CarouselItem(ui.DOMProps{}) {
<div class="p-1">
@ui.Card(ui.DOMProps{}) {
@ui.CardContent(ui.DOMProps{Class: "flex aspect-square items-center justify-center p-6"}) {
<span class="text-4xl font-semibold">1</span>
}
}
</div>
}
}
@ui.CarouselPrevious(ui.DOMProps{})
@ui.CarouselNext(ui.DOMProps{})
}Installation
Add this component to your project using the CLI.
templcn add carouselUsage
1. Import the component in your Go or templ file:
import "your-module/ui"2. Use the component in your template:
@ui.Carousel(ui.CarouselProps{DOMProps: ui.DOMProps{Class: "w-full max-w-xs"}}) {
@ui.CarouselContent(ui.DOMProps{}) {
@ui.CarouselItem(ui.DOMProps{}) {
<div class="p-1">
@ui.Card(ui.DOMProps{}) {
@ui.CardContent(ui.DOMProps{Class: "flex aspect-square items-center justify-center p-6"}) {
<span class="text-4xl font-semibold">1</span>
}
}
</div>
}
}
@ui.CarouselPrevious(ui.DOMProps{})
@ui.CarouselNext(ui.DOMProps{})
}Composition
Use these parts together to build the component.
Carousel
├── CarouselContent
├── CarouselItem
├── Card
├── CardContent
├── CarouselPrevious
├── CarouselNextExamples
Named examples and common variations.
Default
A swipeable slide carousel.
Slide 1
@ui.Carousel(ui.CarouselProps{DOMProps: ui.DOMProps{Class: "w-full max-w-xs"}}) {
@ui.CarouselContent(ui.DOMProps{}) {
@ui.CarouselItem(ui.DOMProps{}) { <div class="grid h-28 place-items-center rounded-md border bg-muted/30">Slide 1</div> }
}
@ui.CarouselPrevious(ui.DOMProps{})
@ui.CarouselNext(ui.DOMProps{})
}API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| Orientation | string | "horizontal" | Slide direction. |
View source
package ui
import (
"context"
"io"
"github.com/a-h/templ"
)
type CarouselProps struct {
DOMProps
Orientation string
Loop bool
Align string
StartIndex int
}
type carouselRenderState struct {
orientation string
}
type carouselRenderStateKey struct{}
func Carousel(props CarouselProps) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {
attrs := attrsFromDOMProps(props.DOMProps, "carousel", "relative")
attrs["role"] = "region"
attrs["aria-roledescription"] = "carousel"
attrs["data-index"] = props.StartIndex
orientation := props.Orientation
if orientation == "" {
orientation = "horizontal"
}
attrs["data-orientation"] = orientation
if props.Loop {
attrs["data-loop"] = "true"
}
if props.Align != "" {
attrs["data-align"] = props.Align
}
if props.StartIndex > 0 {
attrs["data-start-index"] = props.StartIndex
}
ctx = context.WithValue(ctx, carouselRenderStateKey{}, carouselRenderState{orientation: orientation})
return renderElement(ctx, w, "div", attrs, templ.GetChildren(ctx))
})
}
func CarouselContent(props DOMProps) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {
orientation := carouselOrientationFromContext(ctx)
innerClass := "flex -ml-4"
if orientation == "vertical" {
innerClass = "flex -mt-4 flex-col"
}
attrs := attrsFromDOMProps(props, "carousel-content", "overflow-hidden")
attrs["aria-live"] = "polite"
inner := templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {
return renderElement(ctx, w, "div", templ.Attributes{"class": innerClass}, templ.GetChildren(ctx))
})
return renderElement(ctx, w, "div", attrs, inner)
})
}
func CarouselItem(props DOMProps) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {
className := "min-w-0 shrink-0 grow-0 basis-full pl-4"
if carouselOrientationFromContext(ctx) == "vertical" {
className = "min-w-0 shrink-0 grow-0 basis-full pt-4"
}
attrs := attrsFromDOMProps(props, "carousel-item", className)
attrs["role"] = "group"
attrs["aria-roledescription"] = "slide"
return renderElement(ctx, w, "div", attrs, templ.GetChildren(ctx))
})
}
func CarouselPrevious(props DOMProps) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {
className := cn(buttonClasses(ButtonVariantOutline, ButtonSizeIcon, ""), "absolute size-8 rounded-full top-1/2 -left-12 -translate-y-1/2")
if carouselOrientationFromContext(ctx) == "vertical" {
className = cn(buttonClasses(ButtonVariantOutline, ButtonSizeIcon, ""), "absolute size-8 rounded-full -top-12 left-1/2 -translate-x-1/2 rotate-90")
}
attrs := attrsFromDOMProps(props, "carousel-previous", className)
attrs["type"] = "button"
attrs["aria-label"] = "Previous slide"
children := templ.GetChildren(ctx)
if children == nil {
children = templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {
_, err := io.WriteString(w, `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m12 19-7-7 7-7"></path><path d="M19 12H5"></path></svg><span class="sr-only">Previous slide</span>`)
return err
})
}
return renderElement(ctx, w, "button", attrs, children)
})
}
func CarouselNext(props DOMProps) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {
className := cn(buttonClasses(ButtonVariantOutline, ButtonSizeIcon, ""), "absolute size-8 rounded-full top-1/2 -right-12 -translate-y-1/2")
if carouselOrientationFromContext(ctx) == "vertical" {
className = cn(buttonClasses(ButtonVariantOutline, ButtonSizeIcon, ""), "absolute size-8 rounded-full -bottom-12 left-1/2 -translate-x-1/2 rotate-90")
}
attrs := attrsFromDOMProps(props, "carousel-next", className)
attrs["type"] = "button"
attrs["aria-label"] = "Next slide"
children := templ.GetChildren(ctx)
if children == nil {
children = templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {
_, err := io.WriteString(w, `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14"></path><path d="m12 5 7 7-7 7"></path></svg><span class="sr-only">Next slide</span>`)
return err
})
}
return renderElement(ctx, w, "button", attrs, children)
})
}
func carouselOrientationFromContext(ctx context.Context) string {
state, ok := ctx.Value(carouselRenderStateKey{}).(carouselRenderState)
if !ok || state.orientation == "" {
return "horizontal"
}
return state.orientation
}