Documentation
¶
Overview ¶
Button component: variant/size enums, default props, and class lookups.
CodeBlock component: a styled code display with an integrated copy button — the shared shape behind "copyable command" rows (mr-sync's commandLine) and detail-page ID rows (DiscordSync's copyIDRow), extracted per the 2026-10-10 four-project analysis (TODO_LIST #389).
CommandPalette component: a CSP-safe <dialog>-based command palette with client-side filtering over server-rendered groups, selection via links or wire actions.
DataState component: the honesty ladder for data-driven regions — disabled → unavailable → empty → content — extracted from dnsblockd's per-card ladders (9 accepted-duplication markers across 4 view files, 2026-10-10 analysis, TODO_LIST #393).
Package display provides UI components for data visualization and interactive elements including cards, tables, tabs, dropdowns, modals, tooltips, avatars, badges, and more.
Lightbox component: a native <dialog> image viewer with thumbnail triggers, prev/next navigation, rotate and zoom — extracted from DiscordSync's image thumbnails and nsfw-classifier's image viewer (2026-10-10 analysis, TODO_LIST #396). Zero framework JS: one CSP-safe singleton script; Escape, focus trap, and backdrop dismissal come from the native dialog.
Modal component: size enum, default props, and class lookup.
Prose component: a longform-content container for rendered markdown and article HTML. One wrapper class (.tc-prose, templates/custom.css) styles headings, lists, blockquotes, code, tables, and images via descendant selectors — the consumer renders raw content HTML inside and gets the library's typographic contract (theme-token colors, dark-mode overrides, logical/RTL-safe spacing) without per-element classes.
SegmentBar component: a stacked proportion bar with a legend — language shares, evidence breakdowns, storage composition. Extracted from mr-sync's language bars and nsfw-classifier's evidence proportions (2026-10-10 analysis, TODO_LIST #395).
StatusDot and LivePill components: the colored status indicator family — a dot (optionally pulsing) and a dot+text pill — extracted from the hand-rolled staleness/live pills in dnsblockd's dashboard and three other consumers (2026-10-10 analysis, TODO_LIST #392).
Index ¶
- Constants
- Variables
- func Accordion(props AccordionProps) templ.Component
- func AreaChart(props AreaChartProps) templ.Component
- func Avatar(props AvatarProps) templ.Component
- func AvatarShapeIsValid(v AvatarShape) bool
- func AvatarSizeIsValid(v AvatarSize) bool
- func AvatarStatusIsValid(v AvatarStatus) bool
- func Badge(props BadgeProps) templ.Component
- func BadgeSizeIsValid(v BadgeSize) bool
- func BadgeTypeIsValid(v BadgeType) bool
- func BarChart(props BarChartProps) templ.Component
- func BarOrientIsValid(v BarOrient) bool
- func BuildAreaPath(points []Point, height int) string
- func BuildPolylinePath(points []Point) string
- func BuildSmoothAreaPath(points []Point, height int) string
- func BuildSmoothPath(points []Point) string
- func Button(props ButtonProps) templ.Component
- func ButtonHTMLTypeIsValid(v ButtonHTMLType) bool
- func ButtonSizeIsValid(v ButtonSize) bool
- func ButtonTypeIsValid(v ButtonType) bool
- func Card(props CardProps) templ.Component
- func CardPaddingIsValid(v CardPadding) bool
- func Carousel(props CarouselProps) templ.Component
- func CodeBlock(props CodeBlockProps) templ.Component
- func CodeBlockVariantIsValid(v CodeBlockVariant) bool
- func CollapsibleSection(props CollapsibleSectionProps) templ.Component
- func CommandPalette(props CommandPaletteProps) templ.Component
- func CommandPaletteSizeIsValid(s CommandPaletteSize) bool
- func ComputeNiceTicks(minVal, maxVal float64, count int) []float64
- func ContextMenu(props ContextMenuProps) templ.Component
- func CopyButton(props CopyButtonProps) templ.Component
- func CountBadge(props CountBadgeProps) templ.Component
- func DataState(props DataStateProps) templ.Component
- func DataStateStateIsValid(s DataStateState) bool
- func DataTable(props DataTableProps) templ.Component
- func DateRange(props DateRangeProps) templ.Component
- func DefinitionGrid(props DefinitionGridProps) templ.Component
- func DefinitionList(props DefinitionListProps) templ.Component
- func Drawer(props DrawerProps) templ.Component
- func DrawerSideIsValid(s DrawerSide) bool
- func DrawerSizeIsValid(s DrawerSize) bool
- func Dropdown(props DropdownProps) templ.Component
- func DropdownItemKindIsValid(v DropdownItemKind) bool
- func DropdownPositionIsValid(v DropdownPosition) bool
- func EmptyState(props EmptyStateProps) templ.Component
- func ExternalLink(props ExternalLinkProps) templ.Component
- func Eyebrow(props EyebrowProps) templ.Component
- func FormatTickValue(v float64) string
- func Grid(props GridProps) templ.Component
- func GridColsIsValid(v GridCols) bool
- func GridGapIsValid(v GridGap) bool
- func HeadingTagTypeIsValid(t HeadingTagType) bool
- func Heatmap(props HeatmapProps) templ.Component
- func HoverCard(props HoverCardProps) templ.Component
- func HoverCardPositionIsValid(v HoverCardPosition) bool
- func Image(props ImageProps) templ.Component
- func KanbanBoard(props KanbanBoardProps) templ.Component
- func KanbanToneIsValid(v KanbanTone) bool
- func Lightbox(props LightboxProps) templ.Component
- func LineChart(props LineChartProps) templ.Component
- func LineChartStyleIsValid(v LineChartStyle) bool
- func ListNote(props ListNoteProps) templ.Component
- func LivePill(props LivePillProps) templ.Component
- func LoadingDialog(props LoadingDialogProps) templ.Component
- func Modal(props ModalProps) templ.Component
- func ModalSizeIsValid(s ModalSize) bool
- func OverlayKindIsValid(v OverlayKind) bool
- func PageHeader(props PageHeaderProps) templ.Component
- func PieChart(props PieChartProps) templ.Component
- func PieChartLabelModeIsValid(v PieChartLabelMode) bool
- func Popover(props PopoverProps) templ.Component
- func PopoverPositionIsValid(v PopoverPosition) bool
- func PositionIsValid(v Position) bool
- func Prose(props ProseProps) templ.Component
- func ProseSizeIsValid(v ProseSize) bool
- func RelativeTime(props RelativeTimeProps) templ.Component
- func SanitizeInnerRadius(r float64) float64
- func Scrollback(props ScrollbackProps) templ.Component
- func ScrollbackToneIsValid(tone ScrollbackTone) bool
- func SectionHeading(props SectionHeadingProps) templ.Component
- func SegmentBar(props SegmentBarProps) templ.Component
- func SimpleCard(props SimpleCardProps) templ.Component
- func SimpleEmptyState(message string) templ.Component
- func SortDirectionIsValid(v SortDirection) bool
- func Sparkline(props SparklineProps) templ.Component
- func StatCard(props StatCardProps) templ.Component
- func StatToneIsValid(v StatTone) bool
- func StatusBadge(status string) templ.Component
- func StatusBadgeWith(mapper StatusBadgeMapper, status string) templ.Component
- func StatusDot(props StatusDotProps) templ.Component
- func StatusToneIsValid(t StatusTone) bool
- func Table(props TableProps) templ.Component
- func TableCellPaddingIsValid(v TableCellPadding) bool
- func Tabs(props TabsProps) templ.Component
- func TabsVariantIsValid(v TabsVariant) bool
- func Tooltip(props TooltipProps) templ.Component
- func TooltipPositionIsValid(v TooltipPosition) bool
- func TrendDirectionIsValid(v TrendDirection) bool
- type AccordionItem
- type AccordionProps
- type AreaChartProps
- type AvatarProps
- type AvatarShape
- type AvatarSize
- type AvatarStatus
- type BadgeProps
- type BadgeSize
- type BadgeType
- type BarChartBar
- type BarChartProps
- type BarOrient
- type ButtonHTMLType
- type ButtonProps
- type ButtonSize
- type ButtonType
- type CardPadding
- type CardProps
- type CarouselProps
- type CarouselSlide
- type ChartLegendItem
- type ChartPadding
- type ChartRenderData
- type CodeBlockProps
- type CodeBlockVariant
- type CollapsibleSectionProps
- type CommandGroup
- type CommandItem
- type CommandPaletteProps
- type CommandPaletteSize
- type ContextMenuItem
- type ContextMenuProps
- type CopyButtonProps
- type CountBadgeProps
- type DataStateProps
- type DataStateState
- type DataTableColumn
- type DataTableProps
- type DateFormat
- type DateRangeProps
- type DefinitionGridProps
- type DefinitionItem
- type DefinitionListProps
- type DrawerProps
- type DrawerSide
- type DrawerSize
- type DropdownItem
- type DropdownItemKind
- type DropdownPosition
- type DropdownProps
- type EmptyStateProps
- type ExternalLinkProps
- type EyebrowProps
- type GridCols
- type GridGap
- type GridProps
- type HeadingLevel
- type HeadingTagType
- type HeatmapCell
- type HeatmapProps
- type HeatmapRow
- type HoverCardPosition
- type HoverCardProps
- type ImageProps
- type KanbanBoardProps
- type KanbanCard
- type KanbanColumn
- type KanbanMove
- type KanbanTone
- type LightboxImage
- type LightboxProps
- type LineChartProps
- type LineChartSeries
- type LineChartStyle
- type ListNoteProps
- type ListNoteVariant
- type LivePillProps
- type LoadingDialogProps
- type ModalProps
- type ModalSize
- type OverlayKind
- type PageHeaderProps
- type PieChartLabelMode
- type PieChartProps
- type PieChartSlice
- type Point
- type PopoverPosition
- type PopoverProps
- type Position
- type ProseProps
- type ProseSize
- type RelativeTimeProps
- type ScrollbackLine
- type ScrollbackProps
- type ScrollbackTone
- type SectionHeadingProps
- type SegmentBarProps
- type SegmentBarSegment
- type SimpleCardProps
- type SortDirection
- type SparklineProps
- type StatCardProps
- type StatTone
- type StatusBadgeMapper
- type StatusDotProps
- type StatusTone
- type Tab
- type TableCell
- type TableCellPadding
- type TableHeader
- type TableProps
- type TableRow
- type TabsProps
- type TabsVariant
- type TextAlign
- type TooltipPosition
- type TooltipProps
- type TrendDirection
Examples ¶
- Accordion
- AreaChart
- Avatar
- Badge
- BarChart
- Button
- Card
- Carousel
- CollapsibleSection
- ContextMenu
- CopyButton
- CountBadge
- DataTable
- DateRange
- DefinitionGrid
- DefinitionList
- Drawer
- Dropdown
- EmptyState
- ExternalLink
- Eyebrow
- Grid
- Heatmap
- HoverCard
- Image
- KanbanBoard
- KanbanBoard (CardAnatomy)
- KanbanBoard (ColumnAction)
- KanbanBoard (ColumnTone)
- KanbanBoard (OptimisticPending)
- KanbanBoard (ReadOnly)
- LineChart
- ListNote
- Modal
- PageHeader
- PieChart
- Popover
- RelativeTime
- Scrollback
- SectionHeading
- SimpleCard
- SimpleEmptyState
- Sparkline
- StatCard
- StatusBadge
- Table
- Table (FlushInCard)
- Tabs
- Tooltip
Constants ¶
const ( ChartColorBlue tone.ColorClass = "text-blue-600 dark:text-blue-400" ChartColorEmerald tone.ColorClass = "text-emerald-600 dark:text-emerald-400" ChartColorAmber tone.ColorClass = "text-amber-600 dark:text-amber-400" ChartColorRose tone.ColorClass = "text-rose-600 dark:text-rose-400" ChartColorViolet tone.ColorClass = "text-violet-600 dark:text-violet-400" ChartColorCyan tone.ColorClass = "text-cyan-600 dark:text-cyan-400" ChartColorOrange tone.ColorClass = "text-orange-600 dark:text-orange-400" ChartColorPink tone.ColorClass = "text-pink-600 dark:text-pink-400" )
Chart color constants: complete light+dark literals (tone.ColorClass) for chart series, slice, segment, spinner, and progress coloring via currentColor inheritance. Charts cycle them in declaration order; prefer them over hand-typed literals so a typo cannot silently render nothing (TODO #426).
const ( TooltipPositionTop = PositionTop TooltipPositionBottom = PositionBottom TooltipPositionStart = PositionStart TooltipPositionEnd = PositionEnd TooltipPositionLeft = PositionLeft TooltipPositionRight = PositionRight PopoverPositionTop = PositionTop PopoverPositionBottom = PositionBottom PopoverPositionStart = PositionStart PopoverPositionEnd = PositionEnd PopoverPositionLeft = PositionLeft PopoverPositionRight = PositionRight HoverCardPositionTop = PositionTop HoverCardPositionBottom = PositionBottom HoverCardPositionStart = PositionStart HoverCardPositionEnd = PositionEnd )
Legacy per-component constants, kept for source compatibility. The Left/Right spellings predate the logical axis; prefer Start/End in new code (identical placement in LTR, correct mirroring in RTL).
const CountBadgeDefaultMax = 99
CountBadgeDefaultMax is the standard overflow threshold (99).
const ProseSizeDefault = ProseSizeMD
ProseSizeDefault is the zero-value-compatible default size.
Variables ¶
var DateRangeDefaults = struct { Layout DateFormat PresentText string Separator string }{ Layout: DateFormatJanuary2006, PresentText: "Present", Separator: "–", }
DateRangeDefaults are used when props fields are zero.
Functions ¶
func Accordion ¶
func Accordion(props AccordionProps) templ.Component
Accordion renders a collapsible accordion using native <details>/<summary> elements for zero-JS toggle, native keyboard support, and built-in accessibility (implicit aria-expanded, role=group).
@display.Accordion(display.AccordionProps{
Items: []display.AccordionItem{
{ID: "faq1", Title: "What is this?", Open: true},
{ID: "faq2", Title: "How does it work?"},
},
})
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.Accordion(display.DefaultAccordionProps())
}
Output:
func AreaChart ¶ added in v1.7.0
func AreaChart(props AreaChartProps) templ.Component
AreaChart renders a pure-SVG area chart with axes, gridlines, multi-series filled areas, optional dots, and a legend. Zero JavaScript — all rendering is server-side. Each series renders both a stroked line and a semi-transparent fill from the line down to the baseline.
@display.AreaChart(display.AreaChartProps{
Series: []display.LineChartSeries{
{Name: "Active Users", Values: []float64{120, 180, 250, 300, 280, 340}},
},
XAxisLabels: []string{"Jan", "Feb", "Mar", "Apr", "May", "Jun"},
})
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.AreaChart(display.DefaultAreaChartProps())
}
Output:
func Avatar ¶
func Avatar(props AvatarProps) templ.Component
Avatar renders a user avatar with image, initials, or fallback
@display.Avatar(display.AvatarProps{Src: "/avatar.jpg", Alt: "Alice"})
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.Avatar(display.DefaultAvatarProps())
}
Output:
func AvatarShapeIsValid ¶ added in v0.7.0
func AvatarShapeIsValid(v AvatarShape) bool
AvatarShapeIsValid reports whether v is one of the defined AvatarShape constants.
func AvatarSizeIsValid ¶ added in v0.7.0
func AvatarSizeIsValid(v AvatarSize) bool
AvatarSizeIsValid reports whether v is one of the defined AvatarSize constants.
func AvatarStatusIsValid ¶ added in v0.8.0
func AvatarStatusIsValid(v AvatarStatus) bool
AvatarStatusIsValid reports whether v is one of the defined AvatarStatus constants.
func Badge ¶
func Badge(props BadgeProps) templ.Component
Badge renders a compact status label
@display.Badge(display.BadgeProps{Text: "Active", Type: display.BadgeSuccess, Dot: true})
Example ¶
package main
import (
"bytes"
"context"
"fmt"
"github.com/larsartmann/templ-components/display"
)
func main() {
props := display.DefaultBadgeProps()
props.Text = "Beta"
props.Type = display.BadgeInfo
var buf bytes.Buffer
_ = display.Badge(props).Render(context.Background(), &buf)
fmt.Println(buf.String())
// Output will contain the badge text and Tailwind classes
}
Output:
func BadgeSizeIsValid ¶ added in v0.7.0
BadgeSizeIsValid reports whether v is one of the defined BadgeSize constants.
func BadgeTypeIsValid ¶ added in v0.7.0
BadgeTypeIsValid reports whether v is one of the defined BadgeType constants.
func BarChart ¶ added in v1.5.0
func BarChart(props BarChartProps) templ.Component
BarChart renders a CSS-based bar chart — no JavaScript, no SVG. Horizontal orientation shows label bars; vertical shows columns. The chart is responsive and dark-mode aware.
@display.BarChart(display.BarChartProps{
Bars: []display.BarChartBar{
{Label: "general", Value: 1200},
{Label: "random", Value: 800},
{Label: "dev", Value: 450},
},
})
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.BarChart(display.DefaultBarChartProps())
}
Output:
func BarOrientIsValid ¶ added in v1.5.0
BarOrientIsValid reports whether v is one of the defined BarOrient constants.
func BuildAreaPath ¶ added in v1.7.0
BuildAreaPath builds a closed SVG path for a filled area: the polyline through the points, then down to the baseline and back to the start. The baseline is the bottom of the plot area (y = height).
func BuildPolylinePath ¶ added in v1.7.0
BuildPolylinePath builds an SVG path string connecting the given points with straight line segments: "M x,y L x,y ...". Returns "" for an empty slice.
func BuildSmoothAreaPath ¶ added in v1.25.1
BuildSmoothAreaPath builds a closed SVG path for a filled area under a smooth curve: the Catmull-Rom path through the points, closed along the baseline. The fill edge matches BuildSmoothPath exactly, so a smooth stroked line never detaches from its own fill. Fewer than 3 points falls back to the straight polyline area (matching BuildSmoothPath's own polyline fallback).
func BuildSmoothPath ¶ added in v1.7.0
BuildSmoothPath builds an SVG path string using cubic Bezier curves derived from a Catmull-Rom spline through the points. This produces visually smooth lines. Falls back to a straight polyline for fewer than 3 points.
func Button ¶
func Button(props ButtonProps) templ.Component
Button renders a button or link styled as a button. When Href is set, renders as an anchor tag; otherwise renders as a button element.
@display.Button(display.DefaultButtonProps())
@display.Button(display.ButtonProps{Text: "Save", Type: display.ButtonHTMLSubmit})
@display.Button(display.ButtonProps{Text: "Docs", Href: "/docs", Variant: display.ButtonSecondary})
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.Button(display.DefaultButtonProps())
}
Output:
func ButtonHTMLTypeIsValid ¶ added in v0.8.0
func ButtonHTMLTypeIsValid(v ButtonHTMLType) bool
ButtonHTMLTypeIsValid reports whether v is one of the defined ButtonHTMLType constants.
func ButtonSizeIsValid ¶ added in v0.8.0
func ButtonSizeIsValid(v ButtonSize) bool
ButtonSizeIsValid reports whether v is one of the defined ButtonSize constants.
func ButtonTypeIsValid ¶ added in v0.7.0
func ButtonTypeIsValid(v ButtonType) bool
ButtonTypeIsValid reports whether v is one of the defined ButtonType constants.
func Card ¶
Card renders a bordered card with optional header and footer
@display.Card(display.CardProps{Title: "Users", Subtitle: "Manage your users"}) {
<p>Card content goes here</p>
}
Example ¶
package main
import (
"bytes"
"context"
"fmt"
"github.com/larsartmann/templ-components/display"
)
func main() {
props := display.DefaultCardProps()
props.Title = "Hello World"
var buf bytes.Buffer
_ = display.Card(props).Render(context.Background(), &buf)
fmt.Println(buf.String())
}
Output:
func CardPaddingIsValid ¶ added in v0.7.0
func CardPaddingIsValid(v CardPadding) bool
CardPaddingIsValid reports whether v is one of the defined CardPadding constants.
func Carousel ¶ added in v0.17.0
func Carousel(props CarouselProps) templ.Component
Carousel renders a slide carousel with native CSS scroll-snap for touch-friendly swiping, momentum scrolling, and smooth programmatic navigation. Prev/next buttons use scrollBy; dots sync via scrollend.
@display.Carousel(display.CarouselProps{
Slides: []display.CararouselSlide{
{Content: templ.Raw("<div>Slide 1</div>")},
{Content: templ.Raw("<div>Slide 2</div>")},
},
ShowIndicators: true,
})
Example ¶
_ = Carousel(CarouselProps{
Slides: []CarouselSlide{
{Content: templ.Raw("<div>Slide 1</div>")},
},
ShowArrows: true,
})
func CodeBlock ¶ added in v1.22.0
func CodeBlock(props CodeBlockProps) templ.Component
CodeBlock renders a code display with an integrated copy button.
@display.CodeBlock(display.CodeBlockProps{Code: "go install ./...", Language: "bash"})
Variant display.CodeBlockCompactID renders the inline "copy this ID" row used on detail pages.
func CodeBlockVariantIsValid ¶ added in v1.22.0
func CodeBlockVariantIsValid(v CodeBlockVariant) bool
CodeBlockVariantIsValid reports whether v is one of the defined variants. Unknown values render the block variant (graceful fallback, never a panic).
func CollapsibleSection ¶ added in v1.6.0
func CollapsibleSection(props CollapsibleSectionProps) templ.Component
CollapsibleSection wraps content in a native <details>/<summary> pair so users can collapse detail-heavy regions. The section renders open by default. When StorageKey is set, the open/closed state can be persisted to localStorage: either by a consumer-side script reading the data-collapsible attribute, or — with PersistState and Nonce set — by the built-in nonce'd persistence script this component ships.
@display.CollapsibleSection(display.CollapsibleSectionProps{
Title: "Advanced Filters",
StorageKey: "advanced-filters",
PersistState: true,
Nonce: nonce,
}) {
<p>Collapsible content here.</p>
}
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.CollapsibleSection(display.DefaultCollapsibleSectionProps())
}
Output:
func CommandPalette ¶ added in v1.22.0
func CommandPalette(props CommandPaletteProps) templ.Component
CommandPalette renders a CSP-safe command palette: a <dialog> with a search input filtering server-rendered groups client-side. Items select via links (Href) or wire actions (Wire — htmx or Datastar through one spec). Open it with the built-in trigger button (TriggerLabel), the Cmd/Ctrl+K hotkey (Hotkey), or your own element carrying data-tc-palette-open.
@display.CommandPalette(display.CommandPaletteProps{
TriggerLabel: "Commands", Hotkey: true,
Groups: []display.CommandGroup{
{Label: "Pages", Items: []display.CommandItem{{Label: "Dashboard", Href: "/dashboard"}}},
},
})
The native <dialog> provides focus trapping, Escape-to-close, top-layer rendering, and ::backdrop; the tc-overlay/tc-modal classes select the shared animation profile in app.css.
func CommandPaletteSizeIsValid ¶ added in v1.22.0
func CommandPaletteSizeIsValid(s CommandPaletteSize) bool
CommandPaletteSizeIsValid reports whether s is one of the defined CommandPaletteSize constants.
func ComputeNiceTicks ¶ added in v1.7.0
ComputeNiceTicks produces human-readable axis tick values spanning [minVal, maxVal]. The tick count is approximate — the actual count may differ to produce round numbers (e.g., 0, 25, 50, 75, 100 instead of 0, 23, 46, 69, 92).
func ContextMenu ¶ added in v0.17.0
func ContextMenu(props ContextMenuProps) templ.Component
ContextMenu wraps children in a container that shows a custom context menu on right-click or via the keyboard (Shift+F10 / the Menu key). Uses the native Popover API (popover="auto") for light-dismiss, Escape-to-close, and top-layer rendering. CSP-safe singleton scripts handle the contextmenu → showPopover() cursor positioning, the Shift+F10/ContextMenu trigger-position opener, and shared menu keyboard navigation (ArrowUp/Down with RTL mapping, Home/End, focus-first-on-open). See ADR-0017.
@display.ContextMenu(display.ContextMenuProps{Items: []display.ContextMenuItem{
{Text: "Edit", Href: "/edit"},
{Text: "Delete", Href: "/delete"},
}}) {
<div class="p-4">Right-click me</div>
}
Example ¶
_ = ContextMenu(ContextMenuProps{
Items: []ContextMenuItem{
{Text: "Edit", Href: "/edit"},
},
})
func CopyButton ¶ added in v0.7.0
func CopyButton(props CopyButtonProps) templ.Component
Example ¶
package main
import (
"bytes"
"context"
"github.com/larsartmann/templ-components/display"
)
func main() {
props := display.DefaultCopyButtonProps()
props.Text = "pnpm add my-package"
props.Label = "Copy command"
var buf bytes.Buffer
_ = display.CopyButton(props).Render(context.Background(), &buf)
}
Output:
func CountBadge ¶ added in v0.7.0
func CountBadge(props CountBadgeProps) templ.Component
CountBadge renders its children with a count notification badge overlaid in the top-right corner. When Count is 0 the badge is hidden (no element). When Count exceeds Max, the badge displays "Max+" to prevent layout overflow.
@display.CountBadge(display.CountBadgeProps{Count: 5}) {
@icons.Icon(icons.Bell, "h-6 w-6")
}
Example ¶
package main
import (
"bytes"
"context"
"github.com/larsartmann/templ-components/display"
)
func main() {
props := display.CountBadgeProps{Count: 12, Max: 99}
var buf bytes.Buffer
_ = display.CountBadge(props).Render(context.Background(), &buf)
}
Output:
func DataState ¶ added in v1.22.0
func DataState(props DataStateProps) templ.Component
DataState renders the honesty ladder for one data region.
@display.DataState(display.DataStateProps{
State: display.DataStateUnavailable,
Title: "Unavailable — retrying",
Description: "The query failed; this region keeps retrying.",
})
Content rung (the zero value) renders children:
@display.DataState(display.DataStateProps{}) {
@display.Table(display.TableProps{Headers: []string{"Device"}, Rows: rows})
}
func DataStateStateIsValid ¶ added in v1.22.0
func DataStateStateIsValid(s DataStateState) bool
DataStateStateIsValid reports whether s is one of the defined states. Unknown values fall back to content (graceful — never a panic).
func DataTable ¶ added in v0.17.0
func DataTable(props DataTableProps) templ.Component
DataTable renders a data table with integrated sort management, optional pagination, and empty-state handling. It composes the Table component internally, generating correct sort-toggle URLs for each column header.
@display.DataTable(display.DataTableProps{
Columns: []display.DataTableColumn{
{Label: "Name", Sortable: true},
{Label: "Email", Sortable: true, SortKey: "email_address"},
{Label: "Role"},
},
Rows: []display.TableRow{
display.SimpleTableRow("Alice", "alice@example.com", "Admin"),
display.SimpleTableRow("Bob", "bob@example.com", "User"),
},
ActiveSortColumn: "Name",
ActiveSortDir: display.SortAsc,
SortBaseURL: "/users",
})
Example ¶
package main
import (
"bytes"
"context"
"fmt"
"github.com/larsartmann/templ-components/display"
)
func main() {
// DataTable wraps Table with integrated sort management, pagination,
// and empty-state handling. Set SortBaseURL + ActiveSortColumn/Dir to
// auto-generate sort-toggle links for each column header.
props := display.DataTableProps{
Columns: []display.DataTableColumn{
{Label: "Name", Sortable: true},
{Label: "Email", Sortable: true, SortKey: "email_address"},
{Label: "Role"},
},
Rows: []display.TableRow{
display.SimpleTableRow("Alice", "alice@example.com", "Admin"),
display.SimpleTableRow("Bob", "bob@example.com", "User"),
},
ActiveSortColumn: "Name",
ActiveSortDir: display.SortAsc,
SortBaseURL: "/users",
}
var buf bytes.Buffer
_ = display.DataTable(props).Render(context.Background(), &buf)
fmt.Println(buf.String())
}
Output:
func DateRange ¶ added in v1.8.2
func DateRange(props DateRangeProps) templ.Component
DateRange renders a date range with configurable formatting. When End is nil, the PresentText is shown. When Start is nil, only End is shown. When both are equal, only one date is shown (no range).
Layout semantics: DateRange renders an INLINE <time> element. Adjacent ranges flow on the same line with no injected separator — wrap them in a block/flex container or add margin classes via Class to stack or space them (e.g. two parallel roles on a resume). The adjacency output is pinned by TestGoldenDateRangeAdjacent.
@display.DateRange(display.DateRangeProps{
Start: &start,
End: nil, // shows "Present"
})
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.DateRange(display.DateRangeProps{PresentText: "Present"})
}
Output:
func DefinitionGrid ¶ added in v0.7.0
func DefinitionGrid(props DefinitionGridProps) templ.Component
DefinitionGrid renders term-detail pairs in a responsive grid. Each pair is wrapped in a SimpleCard so the grid shows a clean dashboard of key-value tiles. Composes through Grid internally for consistent responsive behavior.
@display.DefinitionGrid(display.DefinitionGridProps{
Cols: display.GridCols2,
Items: []display.DefinitionItem{
{Term: "CPU", Detail: "42%"},
{Term: "Memory", Detail: "8.2 GB"},
},
})
Example ¶
package main
import (
"bytes"
"context"
"github.com/larsartmann/templ-components/display"
)
func main() {
props := display.DefinitionGridProps{
Cols: display.GridCols2,
Items: []display.DefinitionItem{
{Term: "CPU", Detail: "42%"},
{Term: "Memory", Detail: "8.2 GB"},
},
}
var buf bytes.Buffer
_ = display.DefinitionGrid(props).Render(context.Background(), &buf)
}
Output:
func DefinitionList ¶ added in v0.6.0
func DefinitionList(props DefinitionListProps) templ.Component
DefinitionList renders a two-column <dl> with term labels on the left and detail values on the right. Ideal for metadata tables, settings summaries, and key-value display.
@display.DefinitionList(display.DefinitionListProps{
Items: []display.DefinitionItem{
{Term: "Email", Detail: "alice@example.com"},
{Term: "Status", DetailComponent: display.Badge(display.BadgeProps{Text: "Active", Type: display.BadgeSuccess})},
},
})
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.DefinitionList(display.DefaultDefinitionListProps())
}
Output:
func Drawer ¶ added in v0.3.0
func Drawer(props DrawerProps) templ.Component
Drawer renders an accessible side panel using the native <dialog> element.
@display.Drawer(display.DrawerProps{Title: "Settings", ID: "settings-drawer", Side: display.DrawerRight, Open: true, Nonce: nonce}) {
<p>Drawer content</p>
}
The native <dialog> element provides focus trapping, Escape-to-close, top-layer rendering, and ::backdrop. CSS handles slide animations based on the data-side attribute. The tc-drawer class selects the slide animation profile in app.css.
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.Drawer(display.DefaultDrawerProps())
}
Output:
func DrawerSideIsValid ¶ added in v0.7.0
func DrawerSideIsValid(s DrawerSide) bool
DrawerSideIsValid reports whether s is DrawerLeft or DrawerRight.
func DrawerSizeIsValid ¶ added in v0.7.0
func DrawerSizeIsValid(s DrawerSize) bool
DrawerSizeIsValid reports whether s is one of the defined DrawerSize constants.
func Dropdown ¶
func Dropdown(props DropdownProps) templ.Component
Dropdown renders a button-triggered action menu. Uses the native Popover API (popover="auto") for click-toggle via popovertarget, light-dismiss, Escape-to-close, and top-layer rendering. A shared singleton positioner (popoverPositionScriptComponent) anchors the menu to the trigger via getBoundingClientRect(); a thin keyboard-nav script handles ArrowUp/Down (with RTL mapping) and focuses the first menuitem on open. See ADR-0017.
@display.Dropdown(display.DropdownProps{
Label: "Actions",
Items: []display.DropdownItem{
{Text: "Edit", Href: "/edit"},
{Text: "Delete", Href: "/delete"},
},
})
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.Dropdown(display.DefaultDropdownProps())
}
Output:
func DropdownItemKindIsValid ¶ added in v0.8.0
func DropdownItemKindIsValid(v DropdownItemKind) bool
DropdownItemKindIsValid reports whether v is one of the defined DropdownItemKind constants.
func DropdownPositionIsValid ¶ added in v0.8.0
func DropdownPositionIsValid(v DropdownPosition) bool
DropdownPositionIsValid reports whether v is one of the defined DropdownPosition constants.
func EmptyState ¶
func EmptyState(props EmptyStateProps) templ.Component
EmptyState renders a centered empty state with icon, title, description, and optional action
@display.EmptyState(display.EmptyStateProps{
Title: "No repositories",
Description: "Connect your first repository to get started.",
Icon: "folder",
ActionText: "Connect Repository",
ActionHref: "/repos/connect",
})
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.EmptyState(display.DefaultEmptyStateProps())
}
Output:
func ExternalLink ¶ added in v1.5.0
func ExternalLink(props ExternalLinkProps) templ.Component
ExternalLink renders an off-site link with the safe-by-default target="_blank" rel="noopener noreferrer" pair — prevents tabnabbing and back-history manipulation.
The href is passed as a PLAIN STRING (not templ.SafeURL) so that templ's built-in URL sanitizer runs: it blocks javascript:, data:, vbscript: and other dangerous schemes by rewriting them to about:invalid. SafeURL would bypass that sanitization — it is a type-assertion, not a validator.
An external-arrow icon (↗) is appended by default for visual affordance.
@display.ExternalLink(display.ExternalLinkProps{Href: "https://discord.com", Text: "Open in Discord"})
@display.ExternalLink(display.ExternalLinkProps{Href: doc.URL, AriaLabel: "Documentation"}) {
@icons.Icon(icons.Book, "h-4 w-4")
}
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.ExternalLink(display.DefaultExternalLinkProps())
}
Output:
func Eyebrow ¶ added in v1.10.0
func Eyebrow(props EyebrowProps) templ.Component
Eyebrow renders a small monospace uppercase overline label. Rendered neutral gray by default; pass an accent color via BaseProps.Class (e.g. Class: "text-red-600 dark:text-red-400") to make it the tonal signal of a page family. Renders nothing when Text is empty.
@display.Eyebrow(display.EyebrowProps{Text: "Deploy #142 · production"})
Example ¶
package main
import (
"bytes"
"context"
"github.com/larsartmann/templ-components/display"
)
func main() {
var buf bytes.Buffer
_ = display.Eyebrow(display.EyebrowProps{
Text: "Deploy #142 · production",
}).Render(context.Background(), &buf)
}
Output:
func FormatTickValue ¶ added in v1.7.0
FormatTickValue formats a numeric value for axis tick labels. Whole numbers are shown without decimals; thousands and millions get K/M suffixes; small fractions use up to 1 decimal place.
func Grid ¶ added in v0.7.0
Grid renders a responsive grid container that stacks on mobile and expands at sm/lg breakpoints. Pass grid items as children.
@display.Grid(display.GridProps{Cols: display.GridCols3}) {
for _, u := range users {
@display.Card(display.CardProps{Title: u.Name}) { <p>{ u.Email }</p> }
}
}
For container-query-based responsiveness (grid adapts to its parent container, not the viewport):
@display.Grid(display.GridProps{Cols: display.GridCols3, ContainerAware: true}) {
// items
}
HYBRID RENDERING CAVEAT (strings.Builder path): Grid is a children-slot component. When a component is rendered OUTSIDE a templ file — e.g. a hybrid renderer calling component.Render(ctx, w) straight into a strings.Builder — the { children... } slot renders EMPTY: templ only captures children when the component is invoked from another templ template. Escape hatch: pass children programmatically via templ.WithChildren(ctx, child) before Render (pinned by TestGridHybridChildrenViaWithChildren). Details: docs/recipes/hybrid-strings-builder-rendering.md.
Example ¶
package main
import (
"bytes"
"context"
"fmt"
"github.com/larsartmann/templ-components/display"
)
func main() {
props := display.DefaultGridProps()
var buf bytes.Buffer
_ = display.Grid(props).Render(context.Background(), &buf)
fmt.Println(buf.String())
// Output will contain responsive grid classes
}
Output:
func GridColsIsValid ¶ added in v0.7.0
GridColsIsValid reports whether v is one of the defined GridCols constants.
func GridGapIsValid ¶ added in v0.9.0
GridGapIsValid reports whether v is one of the defined GridGap constants.
func HeadingTagTypeIsValid ¶ added in v1.19.3
func HeadingTagTypeIsValid(t HeadingTagType) bool
HeadingTagTypeIsValid reports whether t is one of h1–h6.
func Heatmap ¶ added in v1.6.0
func Heatmap(props HeatmapProps) templ.Component
Heatmap renders a CSS-based grid heatmap — no JavaScript, no SVG. Each cell's background opacity reflects its value relative to the maximum. The heatmap is responsive, dark-mode aware, and uses native table semantics for accessibility.
@display.Heatmap(display.HeatmapProps{
Rows: []display.HeatmapRow{
{Label: "Mon", Cells: []display.HeatmapCell{
{Value: 5}, {Value: 12}, {Value: 0}, {Value: 8},
}},
{Label: "Tue", Cells: []display.HeatmapCell{
{Value: 3}, {Value: 20}, {Value: 7}, {Value: 2},
}},
},
ColumnLabels: []string{"00:00", "06:00", "12:00", "18:00"},
HighlightPeak: true,
})
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.Heatmap(display.DefaultHeatmapProps())
}
Output:
func HoverCard ¶ added in v0.17.0
func HoverCard(props HoverCardProps) templ.Component
HoverCard wraps a trigger element in a hover-activated card with rich content.
Base path (every engine): the card appears on :hover and :focus-within via pure CSS opacity transitions, absolutely positioned in the flow.
Enhancement path (engines with the Popover + Interest Invokers APIs): the card is a `popover="hint"` panel and the trigger carries `interestfor` — the browser promotes it to the top layer on hover (escaping every overflow/z-index ancestor) and the shared popover-positioning script anchors it to the trigger with viewport clamping and edge flipping. The popover attribute is inert where unsupported, so the two paths never fight: a closed popover is display:none, which overrides the CSS hover visibility entirely.
@display.HoverCard(display.HoverCardProps{Position: display.HoverCardPositionTop}) {
<button>Hover me</button>
}
@display.HoverCard.HoverCardContent(display.HoverCardProps{Content: ...})
Example ¶
_ = HoverCard(HoverCardProps{
Position: HoverCardPositionTop,
Content: templ.Raw("<p>Info</p>"),
})
func HoverCardPositionIsValid ¶ added in v0.17.0
func HoverCardPositionIsValid(v HoverCardPosition) bool
HoverCardPositionIsValid reports whether v is one of the defined Position constants.
func Image ¶ added in v0.7.0
func Image(props ImageProps) templ.Component
Image renders an <img> with lazy loading, optional dimensions, and optional fallback source. The fallback swap is CSP-safe: a data-tc-img-fallback attribute on the img tag is consumed by a singleton error-capture listener.
For responsive images with multiple resolutions, use SrcSet and Sizes:
@display.Image(display.ImageProps{
Src: "/photo.jpg",
SrcSet: "/photo-480w.jpg 480w, /photo-800w.jpg 800w",
Sizes: "(max-width: 600px) 480px, 800px",
Alt: "Profile photo",
})
@display.Image(display.ImageProps{Src: "/photo.jpg", Alt: "Profile photo", Width: 128, Height: 128, FallbackSrc: "/placeholder.jpg"})
Example ¶
package main
import (
"bytes"
"context"
"github.com/larsartmann/templ-components/display"
)
func main() {
props := display.ImageProps{
Src: "/profile.jpg",
Alt: "Profile photo",
Width: 128,
Height: 128,
Lazy: true,
}
var buf bytes.Buffer
_ = display.Image(props).Render(context.Background(), &buf)
}
Output:
func KanbanBoard ¶ added in v1.16.0
func KanbanBoard(props KanbanBoardProps) templ.Component
KanbanBoard renders a kanban board: horizontally scrolling columns of cards. With Wire set, cards drag between columns (HTML5 drag-and-drop, CSP-safe singleton script) and carry per-card "move to previous/next column" buttons so the board is fully keyboard operable; both affordances submit the same hidden form.
@display.KanbanBoard(display.KanbanBoardProps{
Columns: []display.KanbanColumn{
{ID: "todo", Title: "To do", Cards: []display.KanbanCard{{ID: "c1", Title: "Write docs"}}},
{ID: "done", Title: "Done"},
},
Wire: &wire.Action{URL: "/api/kanban/move"},
})
Example ¶
package main
import (
"bytes"
"context"
"github.com/larsartmann/templ-components/display"
"github.com/larsartmann/templ-components/utils/wire"
)
func main() {
props := display.DefaultKanbanBoardProps()
props.Columns = []display.KanbanColumn{
{
ID: "todo",
Title: "To do",
Cards: []display.KanbanCard{
{ID: "c1", Title: "Write docs"},
{ID: "c2", Title: "Cut release", Href: "/issues/2"},
},
},
{ID: "doing", Title: "In progress"},
{ID: "done", Title: "Done"},
}
props.Wire = &wire.Action{URL: "/api/kanban/move"}
var buf bytes.Buffer
_ = display.KanbanBoard(props).Render(context.Background(), &buf)
}
Output:
Example (CardAnatomy) ¶
package main
import (
"bytes"
"context"
"fmt"
"html"
"io"
"regexp"
"strings"
"github.com/a-h/templ"
"github.com/larsartmann/templ-components/display"
"github.com/larsartmann/templ-components/utils/wire"
)
// RecipeTask is the consumer-side task model behind the card-anatomy recipe
// (docs/recipes/kanban-card-anatomy.md).
type RecipeTask struct {
Key string
Priority string
Tags []string
Assignees []RecipeAssignee
DescriptionMarkdown string
}
// RecipeAssignee is one card assignee in the card-anatomy recipe.
type RecipeAssignee struct {
Initials string
Name string
}
// cardAnatomyPreviewMaxRunes caps the card description preview length.
const cardAnatomyPreviewMaxRunes = 90
var (
cardAnatomyAttachmentPattern = regexp.MustCompile(`!\[([^\]]*)\]\([^)]*\)`)
cardAnatomySyntaxPattern = regexp.MustCompile(
`\[([^\]]*)\]\([^)]*\)|\*\*([^*]+)\*\*|\*([^*]+)\*|` + "`([^`]+)`")
)
// oneLinePreview flattens a markdown description into a single plain-text
// line for card display: attachments become [label] placeholders, link and
// emphasis syntax is stripped, whitespace collapses. Returns "" when nothing
// readable remains. Truncated previews end with an ellipsis.
func oneLinePreview(markdown string) string {
line := cardAnatomyAttachmentPattern.ReplaceAllString(markdown, "[$1]")
line = cardAnatomySyntaxPattern.ReplaceAllString(line, "$1$2$3$4")
line = strings.Join(strings.Fields(line), " ")
runes := []rune(line)
if len(runes) > cardAnatomyPreviewMaxRunes {
line = string(runes[:cardAnatomyPreviewMaxRunes]) + "…"
}
return line
}
// taskCardContent composes the recipe's card anatomy through the Content
// slot: identity badges, the 2+N tag overflow, an assignee stack, and a
// one-line description preview. The templ-side version of this composition
// (with real wrapper divs) is docs/recipes/kanban-card-anatomy.md.
func taskCardContent(task RecipeTask) templ.Component {
parts := []templ.Component{
display.Badge(display.BadgeProps{Text: task.Key, Size: display.BadgeSizeSM}),
display.StatusBadge(task.Priority),
}
for i, tag := range task.Tags {
switch i {
case 0, 1:
parts = append(parts, display.Badge(display.BadgeProps{
Text: tag,
Type: display.BadgeNeutral,
Size: display.BadgeSizeSM,
}))
case 2:
parts = append(parts, templ.Raw(fmt.Sprintf(
`<span class="text-xs font-medium text-gray-500 dark:text-gray-400">+%d</span>`,
len(task.Tags)-2,
)))
}
}
for _, assignee := range task.Assignees {
parts = append(parts, display.Avatar(display.AvatarProps{
Initials: assignee.Initials,
Alt: assignee.Name,
Size: display.AvatarSizeXS,
}))
}
if preview := oneLinePreview(task.DescriptionMarkdown); preview != "" {
parts = append(parts, templ.Raw(
`<p class="mt-1.5 truncate text-xs text-gray-500 dark:text-gray-400">`+
html.EscapeString(preview)+`</p>`))
}
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {
for _, part := range parts {
if err := part.Render(ctx, w); err != nil {
return fmt.Errorf("render kanban card content part: %w", err)
}
}
return nil
})
}
func main() {
// Rich card content per docs/recipes/kanban-card-anatomy.md.
task := RecipeTask{
Key: "PROJ-17",
Priority: "in progress",
Tags: []string{"backend", "api", "infra", "urgent"},
Assignees: []RecipeAssignee{{Initials: "LM", Name: "Lars M"}, {Initials: "AK", Name: "Anna K"}},
DescriptionMarkdown: "Fixes the **race** in the move pipeline. See [the design](/docs/design) and .",
}
props := display.KanbanBoardProps{
Columns: []display.KanbanColumn{{
ID: "todo",
Title: "To do",
Cards: []display.KanbanCard{
{ID: "c1", Title: "Fix move race", Content: taskCardContent(task)},
},
}},
Wire: &wire.Action{URL: "/api/kanban/move"},
}
var buf bytes.Buffer
_ = display.KanbanBoard(props).Render(context.Background(), &buf)
}
Output:
Example (ColumnAction) ¶
package main
import (
"bytes"
"context"
"github.com/larsartmann/templ-components/display"
"github.com/larsartmann/templ-components/utils/wire"
)
func main() {
// Per-column "add card" affordance via the Action slot. The consumer
// owns the element and its transport: this Button posts to the column's
// add-card endpoint in either dialect via its Wire field.
props := display.KanbanBoardProps{
Columns: []display.KanbanColumn{{
ID: "todo",
Title: "To do",
Action: display.Button(display.ButtonProps{
Text: "Add card",
Variant: display.ButtonSecondary,
Size: display.ButtonSizeSM,
Wire: &wire.Action{
URL: "/api/kanban/add-card",
Event: wire.EventClick,
},
}),
}},
}
var buf bytes.Buffer
_ = display.KanbanBoard(props).Render(context.Background(), &buf)
}
Output:
Example (ColumnTone) ¶
package main
import (
"bytes"
"context"
"github.com/larsartmann/templ-components/display"
)
func main() {
// Column status dot via the Tone field — instant column semantics
// (todo=blue, done=green) with zero JavaScript. The dot is aria-hidden
// (decorative); the zero value renders NO dot, so existing boards are
// unaffected. See KanbanTone for the palette.
props := display.KanbanBoardProps{
Columns: []display.KanbanColumn{
{ID: "todo", Title: "To do", Tone: display.KanbanToneBlue},
{ID: "blocked", Title: "Blocked", Tone: display.KanbanToneRed},
{ID: "done", Title: "Done", Tone: display.KanbanToneGreen},
},
}
var buf bytes.Buffer
_ = display.KanbanBoard(props).Render(context.Background(), &buf)
}
Output:
Example (OptimisticPending) ¶
package main
import (
"bytes"
"context"
"github.com/larsartmann/templ-components/display"
"github.com/larsartmann/templ-components/utils/wire"
)
func main() {
// Every wired board applies moves optimistically (ADR-0041): at submit
// time the card moves in the DOM and is marked pending (dim + spinner
// ring + aria-busy) until the server responds; a failed move reverts to
// its exact original position with a red flash and a screen-reader
// announcement. No extra props — wire the board and the register ships.
props := display.KanbanBoardProps{
Columns: []display.KanbanColumn{
{ID: "todo", Title: "To do", Cards: []display.KanbanCard{{ID: "c1", Title: "Write docs"}}},
{ID: "doing", Title: "In progress"},
},
Wire: &wire.Action{URL: "/api/kanban/move", Method: wire.MethodPost},
}
var buf bytes.Buffer
_ = display.KanbanBoard(props).Render(context.Background(), &buf)
}
Output:
Example (ReadOnly) ¶
package main
import (
"bytes"
"context"
"github.com/larsartmann/templ-components/display"
)
func main() {
// Without Wire the board renders as a static, read-only view.
var buf bytes.Buffer
_ = display.KanbanBoard(display.KanbanBoardProps{
Columns: []display.KanbanColumn{
{ID: "todo", Title: "To do", Cards: []display.KanbanCard{{ID: "c1", Title: "Write docs"}}},
},
}).Render(context.Background(), &buf)
}
Output:
func KanbanToneIsValid ¶ added in v1.18.0
func KanbanToneIsValid(v KanbanTone) bool
KanbanToneIsValid reports whether v is one of the defined KanbanTone constants. The zero value is intentionally invalid — a toneless column renders no dot.
func Lightbox ¶ added in v1.22.0
func Lightbox(props LightboxProps) templ.Component
Lightbox renders a native-dialog image viewer.
@display.Lightbox(display.LightboxProps{
Images: []display.LightboxImage{
{Src: "/img/1.jpg", Alt: "Front view", Caption: "Front"},
{Src: "/img/2.jpg", Alt: "Back view"},
},
})
Thumbnails mode renders one opener per image:
@display.Lightbox(display.LightboxProps{Thumbnails: true, Images: images})
func LineChart ¶ added in v1.7.0
func LineChart(props LineChartProps) templ.Component
LineChart renders a pure-SVG line chart with Y-axis ticks, optional gridlines, multi-series support, data-point dots, and a legend. Zero JavaScript — all rendering is server-side. Dark-mode aware via Tailwind dark: variants.
@display.LineChart(display.LineChartProps{
Series: []display.LineChartSeries{
{Name: "Revenue", Values: []float64{10, 25, 40, 35, 60, 55, 80}},
},
XAxisLabels: []string{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"},
})
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.LineChart(display.DefaultLineChartProps())
}
Output:
func LineChartStyleIsValid ¶ added in v1.7.0
func LineChartStyleIsValid(v LineChartStyle) bool
LineChartStyleIsValid reports whether v is one of the defined LineChartStyle constants.
func ListNote ¶ added in v0.6.0
func ListNote(props ListNoteProps) templ.Component
ListNote renders a "Showing N of M" hint when a list is truncated (ListNoteTruncated, the default: renders nothing when all rows fit), a count-only "Showing N items." hint (ListNoteCount: always renders — including zero — for list semantics), or a cursor-paginated position hint (ListNoteRange: "Showing X–Y of Z.", always renders).
@display.ListNote(display.ListNoteProps{Shown: 50, Total: 127})
@display.ListNote(display.ListNoteProps{Shown: 42, Variant: display.ListNoteCount})
@display.ListNote(display.ListNoteProps{RangeFrom: 193, RangeTo: 216, Total: 237, Variant: display.ListNoteRange})
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.ListNote(display.ListNoteProps{Shown: 10, Total: 100})
}
Output:
func LivePill ¶ added in v1.22.0
func LivePill(props LivePillProps) templ.Component
LivePill renders the dot+text status pill — "Live", "Reconnecting…", "Paused" — the dashboard connection indicator shape.
@display.LivePill(display.LivePillProps{Tone: display.StatusToneSuccess, Text: "Live", Pulse: true})
func LoadingDialog ¶ added in v1.26.0
func LoadingDialog(props LoadingDialogProps) templ.Component
LoadingDialog renders a BLOCKING loading state as a native <dialog> modal: focus is trapped, the page behind it is inert, and Escape or a backdrop click dismisses it. This is the modal twin of the static feedback.LoadingOverlay — use the static overlay when the page must stay reachable, and this dialog when the operation genuinely blocks the page.
@display.LoadingDialog(display.LoadingDialogProps{ID: "save-dialog", Message: "Saving...", Open: true})
func Modal ¶
func Modal(props ModalProps) templ.Component
Modal renders an accessible modal dialog using the native <dialog> element.
@display.Modal(display.ModalProps{Title: "Confirm", ID: "confirm-modal", Nonce: nonce}) {
<p>Are you sure?</p>
}
The native <dialog> element provides focus trapping, Escape-to-close, top-layer rendering, and ::backdrop. CSS handles open/close animations. The tc-modal class selects the scale animation profile in app.css.
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.Modal(display.DefaultModalProps())
}
Output:
func ModalSizeIsValid ¶ added in v0.7.0
ModalSizeIsValid reports whether s is one of the defined ModalSize constants.
func OverlayKindIsValid ¶ added in v0.8.0
func OverlayKindIsValid(v OverlayKind) bool
OverlayKindIsValid reports whether v is one of the defined OverlayKind constants.
func PageHeader ¶ added in v0.6.0
func PageHeader(props PageHeaderProps) templ.Component
PageHeader renders a page-level header with title, optional subtitle, optional breadcrumb above, and an optional action slot on the right. Title and subtitle accept plain strings or templ components (TitleComponent / SubtitleComponent) for rich content inside the heading.
@display.PageHeader(display.PageHeaderProps{
Title: "Users",
Subtitle: "Manage user accounts",
Action: display.Button(display.ButtonProps{Text: "New user", Href: "/users/new"}),
})
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.PageHeader(display.DefaultPageHeaderProps())
}
Output:
func PieChart ¶ added in v1.7.0
func PieChart(props PieChartProps) templ.Component
PieChart renders a pure-SVG pie or donut chart. Zero JavaScript — all rendering is server-side using SVG arc paths. Supports external labels, a legend, and a center label for donut charts. Dark-mode aware.
@display.PieChart(display.PieChartProps{
Slices: []display.PieChartSlice{
{Label: "Direct", Value: 45},
{Label: "Organic", Value: 30},
{Label: "Referral", Value: 25},
},
})
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.PieChart(display.DefaultPieChartProps())
}
Output:
func PieChartLabelModeIsValid ¶ added in v1.7.0
func PieChartLabelModeIsValid(v PieChartLabelMode) bool
PieChartLabelModeIsValid reports whether v is one of the defined PieChartLabelMode constants.
func Popover ¶ added in v0.15.0
func Popover(props PopoverProps) templ.Component
Popover renders a button-triggered floating panel with arbitrary content. Uses the native Popover API (popover="auto") for click-toggle via popovertarget, light-dismiss, Escape-to-close, and top-layer rendering.
Positioning: the Popover API promotes the panel to the top layer with position:fixed (UA stylesheet), detaching it from the trigger's DOM subtree. CSS classes therefore cannot anchor to the trigger. A thin singleton script (popoverPositionScriptComponent) reads the trigger's getBoundingClientRect() on open and sets style.left/top with viewport clamping. See ADR-0017.
@display.Popover(display.PopoverProps{TriggerText: "Details"}) {
<p class="text-sm">Popover content goes here.</p>
}
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.Popover(display.DefaultPopoverProps())
}
Output:
func PopoverPositionIsValid ¶ added in v0.15.0
func PopoverPositionIsValid(v PopoverPosition) bool
PopoverPositionIsValid reports whether v is one of the defined Position constants.
func PositionIsValid ¶ added in v1.24.0
PositionIsValid reports whether v is one of the defined Position constants.
func Prose ¶ added in v1.24.0
func Prose(props ProseProps) templ.Component
Prose renders a longform-content container (rendered markdown, articles, documentation bodies). The .tc-prose family in templates/custom.css styles the content's descendants — headings, lists, blockquotes, code, tables, images — so callers drop raw content HTML inside without per-element classes:
@display.Prose(display.ProseProps{Size: display.ProseSizeMD}) {
<h2>Release notes</h2>
<p>Plain markup is styled by the container.</p>
}
The wrapper carries BaseProps (ID, Class, Attrs, AriaLabel, Nonce); utilities still win over the descendant rules, so per-element Tailwind classes and the tc-fluid-* sizes compose on top.
func ProseSizeIsValid ¶ added in v1.24.0
ProseSizeIsValid reports whether v is one of the defined ProseSize constants.
func RelativeTime ¶ added in v0.7.0
func RelativeTime(props RelativeTimeProps) templ.Component
RelativeTime renders a <time> element with a human-readable relative timestamp (e.g. "2 hours ago", "just now", "3 days ago"). The datetime attribute carries the RFC 3339 timestamp for accessibility and SEO.
@display.RelativeTime(display.RelativeTimeProps{Time: createdAt})
@display.RelativeTime(display.RelativeTimeProps{Time: createdAt, AutoRefresh: false}) // static
Example ¶
package main
import (
"bytes"
"context"
"time"
"github.com/larsartmann/templ-components/display"
)
func main() {
props := display.RelativeTimeProps{
Time: time.Date(2025, 1, 15, 10, 30, 0, 0, time.UTC),
}
var buf bytes.Buffer
_ = display.RelativeTime(props).Render(context.Background(), &buf)
}
Output:
func SanitizeInnerRadius ¶ added in v1.8.0
SanitizeInnerRadius clamps the InnerRadius to the valid range [0, 1]. Values outside this range produce broken arc paths (inner radius larger than the pie, or negative hole size). Returns the clamped value.
func Scrollback ¶ added in v1.10.0
func Scrollback(props ScrollbackProps) templ.Component
Scrollback renders a server-rendered, terminal-style log block: monospace lines with a timestamp column and a tone-colored tag column. With Stagger enabled, lines fade in sequentially via CSS nth-child delays — zero JavaScript, and prefers-reduced-motion users see all lines immediately.
The block is decorative by default (aria-hidden). Pass AriaLabel when the lines carry real information screen readers should read.
@display.Scrollback(display.ScrollbackProps{
Stagger: true,
Lines: []display.ScrollbackLine{
{Timestamp: "12:47:03.184", Tag: "query", Text: "ads.example.com A", Tone: display.ScrollbackToneInfo},
{Timestamp: "12:47:03.185", Tag: "action", Text: "NXDOMAIN", Tone: display.ScrollbackToneDanger},
},
})
Example ¶
package main
import (
"bytes"
"context"
"github.com/larsartmann/templ-components/display"
)
func main() {
props := display.DefaultScrollbackProps()
props.Lines = []display.ScrollbackLine{
{
Timestamp: "12:47:03.184", Tag: "query",
Text: "ads.example.com A", Tone: display.ScrollbackToneInfo,
},
{
Timestamp: "12:47:03.184", Tag: "match",
Text: "blocklist: StevenBlack/hosts", Tone: display.ScrollbackToneDanger,
},
{
Timestamp: "12:47:03.185", Tag: "action",
Text: "NXDOMAIN", Tone: display.ScrollbackToneWarning,
},
}
var buf bytes.Buffer
_ = display.Scrollback(props).Render(context.Background(), &buf)
}
Output:
func ScrollbackToneIsValid ¶ added in v1.10.0
func ScrollbackToneIsValid(tone ScrollbackTone) bool
ScrollbackToneIsValid reports whether tone is a known scrollback tone.
func SectionHeading ¶ added in v1.8.2
func SectionHeading(props SectionHeadingProps) templ.Component
SectionHeading renders a section-level heading with configurable heading element (h1-h6), alignment, and optional subtitle. Headings include break-after-avoid for print pagination. Use this for section titles within page content (not the page title itself — use PageHeader for that).
@display.SectionHeading(display.SectionHeadingProps{
Title: "Experience",
Level: display.HeadingLevelH2,
Align: display.TextAlignCenter,
})
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.SectionHeading(display.SectionHeadingProps{Title: "Overview"})
}
Output:
func SegmentBar ¶ added in v1.22.0
func SegmentBar(props SegmentBarProps) templ.Component
SegmentBar renders a stacked proportion bar with an optional legend.
@display.SegmentBar(display.SegmentBarProps{
Segments: []display.SegmentBarSegment{
{Label: "Go", Value: 62.3},
{Label: "TypeScript", Value: 37.7},
},
})
Proportions use flex-grow (not percentage widths), so rounding never opens gaps between segments. The runtime flex-grow values are the component's documented inline-style exemption (same class as BarChart's bar widths — see utils.TestInlineStyleCompliance).
The role="img" wraps ONLY the bar graphic (img is a leaf role — visible descendants under it are invalid ARIA, achecker aria_descendant_valid); the legend renders as a real list sibling, readable as ordinary content.
func SimpleCard ¶
func SimpleCard(props SimpleCardProps) templ.Component
SimpleCard renders a card without header/footer for quick use. Internally composes through Card for consistent shell styling.
@display.SimpleCard(display.SimpleCardProps{}) {
<p>Content</p>
}
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.SimpleCard(display.DefaultSimpleCardProps())
}
Output:
func SimpleEmptyState ¶
SimpleEmptyState is a minimal empty state for inline use
@display.SimpleEmptyState("No items found")
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.SimpleEmptyState("No results found")
}
Output:
func SortDirectionIsValid ¶ added in v0.8.0
func SortDirectionIsValid(v SortDirection) bool
SortDirectionIsValid reports whether v is one of the defined SortDirection constants.
func Sparkline ¶ added in v1.5.0
func Sparkline(props SparklineProps) templ.Component
Sparkline renders a tiny inline SVG line chart showing a data trend. Pure SVG — no JavaScript. Uses currentColor for stroke so consumers control color via a Tailwind text color class on the parent or the Class prop.
@display.Sparkline(display.SparklineProps{Values: []float64{1, 3, 2, 5, 4, 6, 3}})
@display.Sparkline(display.SparklineProps{Values: rates, Filled: true, Class: "text-green-500 dark:text-green-400"})
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.Sparkline(display.DefaultSparklineProps())
}
Output:
func StatCard ¶
func StatCard(props StatCardProps) templ.Component
StatCard renders a dashboard stat card with value, label, optional change indicator, and an optional leading icon tile. When Href is set, the whole card is wrapped in an <a> so it acts as a clickable navigation link.
@display.StatCard(display.StatCardProps{Label: "Users", Value: "1,204", Icon: icons.Users})
@display.StatCard(display.StatCardProps{Label: "Active", Value: "42", Href: "/?activity=active"})
Example ¶
package main
import (
"bytes"
"context"
"fmt"
"github.com/larsartmann/templ-components/display"
)
func main() {
props := display.DefaultStatCardProps()
props.Value = "$12,345"
props.Label = "Total Revenue"
props.Trend = display.TrendUp
props.Change = "+12.5%"
var buf bytes.Buffer
_ = display.StatCard(props).Render(context.Background(), &buf)
fmt.Println(buf.String())
}
Output:
func StatToneIsValid ¶ added in v1.12.0
StatToneIsValid reports whether v is one of the defined StatTone constants. Map-driven off statTileLookup, so adding a tone constant keeps it in sync.
func StatusBadge ¶
StatusBadge is a convenience wrapper for common status values Maps status strings to badge types automatically
@display.StatusBadge("active")
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.StatusBadge("active")
}
Output:
func StatusBadgeWith ¶ added in v1.22.0
func StatusBadgeWith(mapper StatusBadgeMapper, status string) templ.Component
StatusBadgeWith renders a StatusBadge through a consumer-supplied mapper — inject your domain's status vocabulary (e.g. dnsblockd's allow/block states) without forking the component. A nil mapper falls back to the built-in mapping (identical to StatusBadge).
@display.StatusBadgeWith(func(s string) display.BadgeType {
if s == "blocked" { return display.BadgeError }
return display.MapStatusToBadgeType(s)
}, row.Status)
func StatusDot ¶ added in v1.22.0
func StatusDot(props StatusDotProps) templ.Component
StatusDot renders a colored status dot, optionally pulsing.
@display.StatusDot(display.StatusDotProps{Tone: display.StatusToneSuccess, Pulse: true, Label: "Live"})
Without a Label the dot is decorative (aria-hidden) — pair it with your own visible text.
func StatusToneIsValid ¶ added in v1.22.0
func StatusToneIsValid(t StatusTone) bool
StatusToneIsValid reports whether t is one of the defined tones. Unknown tones render neutral (graceful degradation).
func Table ¶
func Table(props TableProps) templ.Component
Table renders a responsive data table
@display.Table(display.TableProps{
Headers: []string{"Name", "Email", "Role"},
Rows: []display.TableRow{
display.SimpleTableRow("Alice", "alice@example.com", "Admin"),
display.SimpleTableRow("Bob", "bob@example.com", "User"),
},
})
For custom cell rendering, set Body to a component that renders <tr> elements directly — see the Body field on TableProps.
Example ¶
package main
import (
"bytes"
"context"
"fmt"
"github.com/larsartmann/templ-components/display"
)
func main() {
props := display.TableProps{
Headers: []string{"Name", "Email", "Role"},
Rows: []display.TableRow{
display.SimpleTableRow("Alice", "alice@example.com", "Admin"),
display.SimpleTableRow("Bob", "bob@example.com", "User"),
},
}
var buf bytes.Buffer
_ = display.Table(props).Render(context.Background(), &buf)
fmt.Println(buf.String())
}
Output:
Example (FlushInCard) ¶
package main
import (
"bytes"
"context"
"fmt"
"github.com/larsartmann/templ-components/display"
)
func main() {
// When nesting a Table inside a Card(CardPaddingNone), set Flush to true
// to suppress the table's own border and avoid a double-border defect.
// Use CellPadding: TableCellPaddingCompact for data-heavy dashboards.
props := display.TableProps{
Headers: []string{"Name", "Status"},
Rows: []display.TableRow{display.SimpleTableRow("Alice", "Active")},
Flush: true,
CellPadding: display.TableCellPaddingCompact,
}
var buf bytes.Buffer
_ = display.Table(props).Render(context.Background(), &buf)
fmt.Println(buf.String())
}
Output:
func TableCellPaddingIsValid ¶ added in v0.16.0
func TableCellPaddingIsValid(v TableCellPadding) bool
TableCellPaddingIsValid reports whether v is one of the defined TableCellPadding constants.
func Tabs ¶
Tabs renders a tabbed interface with accessible markup
@display.Tabs(display.TabsProps{
ActiveTabID: "users",
Tabs: []display.Tab{
{ID: "users", Label: "Users"},
{ID: "settings", Label: "Settings"},
},
})
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.Tabs(display.DefaultTabsProps())
}
Output:
func TabsVariantIsValid ¶ added in v0.8.0
func TabsVariantIsValid(v TabsVariant) bool
TabsVariantIsValid reports whether v is one of the defined TabsVariant constants.
func Tooltip ¶
func Tooltip(props TooltipProps) templ.Component
Tooltip wraps content in a hover/focus-activated tooltip. Pure CSS for show/hide (group-hover/group-focus-within); a singleton script propagates aria-describedby to the focusable trigger for screen-reader support.
@display.Tooltip(display.TooltipProps{Text: "More info"}) {
<button>Hover me</button>
}
Example ¶
package main
import (
"github.com/larsartmann/templ-components/display"
)
func main() {
_ = display.Tooltip(display.DefaultTooltipProps())
}
Output:
func TooltipPositionIsValid ¶ added in v0.7.0
func TooltipPositionIsValid(v TooltipPosition) bool
TooltipPositionIsValid reports whether v is one of the defined Position constants.
func TrendDirectionIsValid ¶ added in v0.7.0
func TrendDirectionIsValid(v TrendDirection) bool
TrendDirectionIsValid reports whether v is one of the defined TrendDirection constants.
Types ¶
type AccordionItem ¶
AccordionItem represents a single collapsible panel
type AccordionProps ¶
type AccordionProps struct {
utils.BaseProps
Items []AccordionItem
// Exclusive, when true, renders every <details> with the same name
// attribute — the platform's native exclusive disclosure group (Modern
// Web Guidance: search-hidden-content, "mutually exclusive
// disclosures"): opening one item closes the others, zero JS. The group
// name derives from ID (or a generated one), so two accordions on the
// same page never share a group. Engines without named details (older
// Firefox) degrade to independent items — every item stays operable.
Exclusive bool
}
AccordionProps configures an accordion component
func DefaultAccordionProps ¶
func DefaultAccordionProps() AccordionProps
DefaultAccordionProps returns sensible defaults
type AreaChartProps ¶ added in v1.7.0
type AreaChartProps struct {
utils.BaseProps
// Series is the data to plot.
Series []LineChartSeries
// XAxisLabels are category labels along the X-axis.
XAxisLabels []string
// Width is the SVG canvas width in pixels. Default: 600.
Width int
// Height is the SVG canvas height in pixels. Default: 300.
Height int
// Padding controls the inset around the plot area.
Padding ChartPadding
// Min overrides the auto-computed Y-axis minimum.
Min *float64
// Max overrides the auto-computed Y-axis maximum.
Max *float64
// MaxTicks is the tick budget for the Y axis: ComputeNiceTicks aims for
// at most this many ticks. 0 or negative keeps the default of 8. The
// final count is approximate — ticks snap to human-readable steps, so
// the actual count can land slightly above or below the budget.
MaxTicks int
// ShowGrid renders dashed horizontal gridlines at each Y tick. Default: true.
ShowGrid bool
// ShowDots renders a circle at each data point. Default: false (cleaner area look).
ShowDots bool
// ShowLegend renders a color-swatch legend above the chart when 2+ series.
ShowLegend bool
// Style controls whether lines are straight (Linear) or curved (Smooth).
Style LineChartStyle
// FillOpacity controls the transparency of the area fill (0.0–1.0).
// Default: 0.2.
FillOpacity float64
// ValueFormat formats Y-axis tick labels.
ValueFormat func(float64) string
// EmptyMessage is shown when Series is empty.
EmptyMessage string
}
AreaChartProps configures a pure-SVG area chart — a line chart with filled areas beneath each series. Like LineChart, it supports axes, gridlines, multi-series, dots, and a legend. Zero JavaScript.
Each series renders both a line (top edge) and a semi-transparent fill from the line down to the X-axis baseline. Uses currentColor for stroke and fill so Tailwind text-* classes control per-series coloring.
func DefaultAreaChartProps ¶ added in v1.7.0
func DefaultAreaChartProps() AreaChartProps
DefaultAreaChartProps returns sensible defaults for an area chart.
type AvatarProps ¶
type AvatarProps struct {
utils.BaseProps
Src string
Alt string
Initials string
Size AvatarSize
Shape AvatarShape
Status AvatarStatus
}
AvatarProps configures an avatar component
func DefaultAvatarProps ¶
func DefaultAvatarProps() AvatarProps
DefaultAvatarProps returns sensible defaults
type AvatarShape ¶
type AvatarShape string
AvatarShape defines the shape of an avatar
const ( AvatarShapeCircle AvatarShape = "circle" AvatarShapeSquare AvatarShape = "square" )
type AvatarSize ¶
type AvatarSize string
AvatarSize defines the size of an avatar
const ( AvatarSizeXS AvatarSize = "xs" AvatarSizeSM AvatarSize = "sm" AvatarSizeMD AvatarSize = "md" AvatarSizeLG AvatarSize = "lg" AvatarSizeXL AvatarSize = "xl" )
type AvatarStatus ¶
type AvatarStatus string
AvatarStatus represents the online status indicator for an avatar
const ( AvatarStatusNone AvatarStatus = "" AvatarStatusOnline AvatarStatus = "online" AvatarStatusOffline AvatarStatus = "offline" )
type BadgeProps ¶
type BadgeProps struct {
utils.BaseProps
Text string
Type BadgeType
Size BadgeSize
Pill bool
Dot bool
Href string
}
BadgeProps configures a status badge
func DefaultBadgeProps ¶
func DefaultBadgeProps() BadgeProps
DefaultBadgeProps returns sensible defaults
type BadgeType ¶
type BadgeType string
BadgeType defines the visual style of a badge
func MapStatusToBadgeType ¶ added in v1.22.0
MapStatusToBadgeType maps a status string to a badge type — the built-in mapping behind StatusBadge, exposed for consumer mappers that extend rather than replace it (dnsblockd carries four local mappers — the extraction demand behind StatusBadgeWith).
type BarChartBar ¶ added in v1.5.0
type BarChartBar struct {
// Label is the bar's category name (e.g. "general", "Alice").
Label string
// Value is the bar's magnitude.
Value float64
// Color overrides the default bar color — a complete light+dark bg-*
// literal (e.g. "bg-emerald-600 dark:bg-emerald-500"). Empty = use default.
Color tone.ColorClass
// Href makes the bar label a clickable link.
Href string
// Tooltip sets a per-bar title attribute (native browser tooltip).
// Useful for dense charts where per-bar labels are hidden.
Tooltip string
// ValueLabel overrides the auto-formatted value display. When set,
// this string is shown instead of ValueFormat(Value). Useful for
// composite labels like "123 (45%)" or "1.2 GB".
ValueLabel string
}
BarChartBar represents a single bar in a bar chart.
type BarChartProps ¶ added in v1.5.0
type BarChartProps struct {
utils.BaseProps
// Bars are the data points to render.
Bars []BarChartBar
// Orient is the bar orientation. Default: BarHorizontal.
Orient BarOrient
// Max overrides the auto-computed maximum (0 = auto from data).
Max float64
// BarColor is the default bg-* literal for bars without a per-bar Color
// override. Default: "bg-blue-600 dark:bg-blue-500".
BarColor tone.ColorClass
// LabelWidth is the label column width for horizontal charts (Tailwind
// width class, e.g. "w-32"). Default: "w-32".
LabelWidth string
// ShowValues renders the numeric value next to each bar.
ShowValues bool
// ValueFormat formats the value for display. Default: fmt.Sprintf("%.0f", v).
ValueFormat func(float64) string
// EmptyMessage is shown when Bars is empty. Default: "No data".
EmptyMessage string
// MinBarWidth sets the minimum width for vertical bars (Tailwind
// width class, e.g. "min-w-1" for dense time-series). Default: "min-w-12".
MinBarWidth string
// Gap controls the spacing between bars (Tailwind gap class,
// e.g. "gap-px" for dense charts). Default: "gap-2" (vertical),
// "" (horizontal, uses space-y-2).
Gap string
// Height sets the chart container height (CSS value, e.g. "8rem").
// Essential for vertical charts — percentage bar heights need a
// definite parent height. No effect on horizontal.
Height string
}
BarChartProps configures a CSS bar chart.
func DefaultBarChartProps ¶ added in v1.5.0
func DefaultBarChartProps() BarChartProps
DefaultBarChartProps returns sensible defaults for a bar chart.
type ButtonHTMLType ¶ added in v0.5.0
type ButtonHTMLType string
ButtonHTMLType is the HTML type attribute for a <button> element.
const ( ButtonHTMLButton ButtonHTMLType = "button" ButtonHTMLSubmit ButtonHTMLType = "submit" ButtonHTMLReset ButtonHTMLType = "reset" )
Button HTML type constants.
type ButtonProps ¶
type ButtonProps struct {
utils.BaseProps
Text string
Type ButtonHTMLType // button, submit, reset (default: button; ignored when Href is set)
Href string // if set, renders as <a> instead of <button>
Variant ButtonType // default: Primary
Size ButtonSize // default: MD
Disabled bool
Icon templ.Component
// Children, when set, replaces the default content (Icon + Text) inside
// the element. Use it to compose rich button content — a spinner plus a
// loading label, an icon-text stack, a badge — while keeping the
// library's classes, variants, and Wire/HTMX attributes. Consumer-owned:
// a11y of the inner markup is the consumer's responsibility (the element
// still carries AriaLabel when set).
Children templ.Component
External bool // adds target="_blank" and rel="noopener noreferrer" for links
// Wire is the optional transport-agnostic wiring (see the wire package).
// When set, the action's attributes are rendered on the element in the
// configured transport's dialect (htmx by default, Datastar opt-in) so
// the same props work under either runtime. Composes with Attrs.
Wire *wire.Action
}
ButtonProps configures a button or link styled as a button.
func DefaultButtonProps ¶
func DefaultButtonProps() ButtonProps
DefaultButtonProps returns sensible defaults.
type ButtonSize ¶
type ButtonSize string
ButtonSize defines the size of a button.
const ( ButtonSizeSM ButtonSize = "sm" ButtonSizeMD ButtonSize = "md" ButtonSizeLG ButtonSize = "lg" )
Button size constants.
type ButtonType ¶
type ButtonType string
ButtonType defines the visual style of a button.
const ( ButtonPrimary ButtonType = "primary" ButtonSecondary ButtonType = "secondary" ButtonDanger ButtonType = "danger" ButtonGhost ButtonType = "ghost" ButtonLink ButtonType = "link" // Outline variants: neutral shell (white/transparent, colored ring and // text) for secondary destructive/warning/informative actions such as // row-level Undo, Restore, or Report-spam buttons. They pair with the // filled Primary/Danger for the main action of a toolbar. ButtonOutlineDanger ButtonType = "outline-danger" ButtonOutlineWarning ButtonType = "outline-warning" ButtonOutlineSuccess ButtonType = "outline-success" ButtonOutlineInfo ButtonType = "outline-info" )
Button variant constants.
type CardPadding ¶
type CardPadding string
CardPadding defines the internal padding of a card
const ( CardPaddingNone CardPadding = "none" CardPaddingSM CardPadding = "sm" CardPaddingMD CardPadding = "md" CardPaddingLG CardPadding = "lg" )
type CardProps ¶
type CardProps struct {
utils.BaseProps
Title string
Subtitle string
HeaderAction templ.Component
// Header, when set, replaces the entire default header section (title,
// subtitle, header action). Use this for custom header layouts that the
// Title/Subtitle/HeaderAction fields can't express. When nil, the default
// header renders if Title or HeaderAction is set.
Header templ.Component
// Body, when set, overrides children for the card's main content area.
// Use this for struct-based composition; pass children for templ-block
// composition. If both are set, Body takes precedence.
Body templ.Component
Padding CardPadding
// TitleTag overrides the heading element for the card title.
// Defaults to h3 (HeadingTagH3) when empty. Set to HeadingTagH2 when the
// card is the first heading level after a page <h1> to maintain correct
// heading order for screen-reader navigation.
TitleTag HeadingTagType
// TitleClass, when set, overrides the default <h3> title classes. Consumer
// classes are merged LAST so they win via tailwind-merge.
TitleClass string
// HeaderClass, when set, overrides the default header wrapper classes.
// Consumer classes are merged LAST so they win via tailwind-merge.
HeaderClass string
// ContainerAware, when true, wraps the card in a @container div and swaps
// sm: breakpoint classes for @sm: so padding adapts to container width,
// not the viewport. Default false (viewport breakpoints). The @container
// wrapper applies container-type: inline-size containment, which
// suppresses the card's intrinsic width: inside shrink-to-fit parents
// (flex rows, inline-block, auto-sized grid columns) a container-aware
// card collapses to zero width unless the parent provides a definite
// width. That is why Card is opt-in. See ADR-0018.
ContainerAware bool
}
CardProps configures a card container.
Corners are SHARP by default. Restore rounding per card via Class ("rounded-lg") or apply the iOS-style continuous curve with Class: "rounded-lg tc-squircle" (progressive enhancement — browsers without CSS corner-shape render the plain rounded corners).
Set ContainerAware: true to make padding adapt to the card's parent container width (CSS @container) instead of the viewport. Useful when Card is placed inside a sidebar, grid cell, or other constrained layout. See ADR-0018.
func DefaultCardProps ¶
func DefaultCardProps() CardProps
DefaultCardProps returns sensible defaults
type CarouselProps ¶ added in v0.17.0
type CarouselProps struct {
utils.BaseProps
Slides []CarouselSlide
ShowIndicators bool
ShowArrows bool
}
CarouselProps configures a content carousel with prev/next navigation. Uses CSS scroll-snap for native touch/drag support and smooth scrolling.
func DefaultCarouselProps ¶ added in v0.17.0
func DefaultCarouselProps() CarouselProps
DefaultCarouselProps returns sensible defaults.
type CarouselSlide ¶ added in v0.17.0
CarouselSlide represents a single slide in a carousel.
type ChartLegendItem ¶ added in v1.8.0
ChartLegendItem holds a computed legend entry for a chart series.
type ChartPadding ¶ added in v1.7.0
ChartPadding defines the inset spacing around the plot area in an SVG chart. Left holds Y-axis labels, Bottom holds X-axis labels, Top/Right give breathing room.
func DefaultChartPadding ¶ added in v1.7.0
func DefaultChartPadding() ChartPadding
DefaultChartPadding returns sensible defaults for a 600×300 chart.
func (ChartPadding) Sanitize ¶ added in v1.8.0
func (p ChartPadding) Sanitize() ChartPadding
Sanitize clamps all padding fields to non-negative values. Negative padding produces negative plot dimensions (width - left - right < 0), which corrupt SVG path math. Called by LineChart and AreaChart before rendering.
type ChartRenderData ¶ added in v1.8.0
type ChartRenderData struct {
Width int
Height int
Padding ChartPadding
PlotW int
PlotH int
MinVal float64
MaxVal float64
RangeVal float64
Ticks []float64
HasData bool
LabelCount int
XAxisLabels []string
ShowGrid bool
ValueFormat func(float64) string
LegendItems []ChartLegendItem
EmptyMsg string
Class string
AriaLabel string
ID string
Attrs templ.Attributes
}
ChartRenderData bundles the pre-computed values shared between LineChart and AreaChart rendering. Both charts compute identical setup (bounds, ticks, padding, legend positions) — this struct eliminates the duplicated logic.
type CodeBlockProps ¶ added in v1.22.0
type CodeBlockProps struct {
utils.BaseProps
// Code is the text to display and copy. Rendered HTML-escaped by templ.
Code string
// Language optionally labels the block's language in the header
// ("bash", "go"). It is a label only — CodeBlock does not syntax-highlight.
Language string
// Label optionally overrides the header label. Defaults to Language
// when Language is set and Label is empty; both empty renders no header
// label (a copy-only header when copying is enabled).
Label string
// NoCopy hides the copy button. The zero value shows it — both extraction
// demand shapes (copyable command rows, ID rows) always carry copy.
NoCopy bool
// Variant selects block (zero value) or compact-id rendering.
Variant CodeBlockVariant
}
CodeBlockProps configures a code block.
func DefaultCodeBlockProps ¶ added in v1.22.0
func DefaultCodeBlockProps() CodeBlockProps
DefaultCodeBlockProps returns sensible defaults.
type CodeBlockVariant ¶ added in v1.22.0
type CodeBlockVariant string
CodeBlockVariant selects the rendering shape. Structural variants use an if-branch in the template (map lookups are for class data, not DOM shape).
const ( // CodeBlockBlock renders a figure with an optional header (language or // label) and a scrollable pre/code body. The zero value. CodeBlockBlock CodeBlockVariant = "block" // CodeBlockCompactID renders an inline monospace row with a copy button — // the detail-page "copy this ID" pattern. CodeBlockCompactID CodeBlockVariant = "compact-id" )
Code block variant constants.
type CollapsibleSectionProps ¶ added in v1.6.0
type CollapsibleSectionProps struct {
utils.BaseProps
// Title is the section heading text.
Title string
// TitleTag is the heading element (h1–h6). Default: HeadingTagH3.
TitleTag HeadingTagType
// Collapsed controls whether the section starts collapsed on initial
// render. Default: false (section is expanded).
Collapsed bool
// StorageKey, when non-empty, persists the open/closed state to
// localStorage under this key. A consumer-side script reads the
// data-collapsible attribute and toggles accordingly.
StorageKey string
// PersistState, when true, ships the persistence script with the
// component: a CSP-safe, nonce'd singleton that restores the saved
// open/closed state for every details[data-collapsible] on the page
// and writes back on toggle (capture phase — toggle does not bubble).
// Requires StorageKey AND BaseProps.Nonce; without a nonce the script
// is skipped so strict-CSP pages never receive un-nonced inline JS.
// Consumers who bring their own persistence script leave this false
// (the default) and keep reading data-collapsible themselves.
PersistState bool
// Icon overrides the default chevron. Default: icons.ChevronDown.
Icon icons.Name
}
CollapsibleSectionProps configures a collapsible section using native <details>/<summary> elements.
func DefaultCollapsibleSectionProps ¶ added in v1.6.0
func DefaultCollapsibleSectionProps() CollapsibleSectionProps
DefaultCollapsibleSectionProps returns sensible defaults.
type CommandGroup ¶ added in v1.22.0
type CommandGroup struct {
Label string
Items []CommandItem
}
CommandGroup is a labeled section of palette items. Groups whose items all fail the filter are hidden entirely while filtering.
type CommandItem ¶ added in v1.22.0
type CommandItem struct {
Label string
Hint string // secondary text rendered under or beside the label
Href string // link selection
Wire *wire.Action
}
CommandItem is one selectable row of the palette. Exactly one of Href (link navigation) or Wire (HTMX/Datastar action) should be set; with both, the link wins and Wire is ignored. Items with neither render as inert rows.
type CommandPaletteProps ¶ added in v1.22.0
type CommandPaletteProps struct {
utils.BaseProps
Placeholder string
Groups []CommandGroup
TriggerLabel string // renders an opener button when non-empty
Hotkey bool // register Cmd/Ctrl+K to open
EmptyMessage string
Size CommandPaletteSize
}
CommandPaletteProps configures a command palette.
func DefaultCommandPaletteProps ¶ added in v1.22.0
func DefaultCommandPaletteProps() CommandPaletteProps
DefaultCommandPaletteProps returns sensible defaults.
type CommandPaletteSize ¶ added in v1.22.0
type CommandPaletteSize string
CommandPaletteSize defines the width of the palette panel.
const ( CommandPaletteSizeSM CommandPaletteSize = "sm" CommandPaletteSizeMD CommandPaletteSize = "md" CommandPaletteSizeLG CommandPaletteSize = "lg" )
Command palette size constants.
type ContextMenuItem ¶ added in v0.17.0
ContextMenuItem represents a single item in a context menu.
type ContextMenuProps ¶ added in v0.17.0
type ContextMenuProps struct {
utils.BaseProps
Items []ContextMenuItem
}
ContextMenuProps configures a right-click context menu. The menu is positioned at the cursor on right-click within the container element. Items render as links or buttons.
func DefaultContextMenuProps ¶ added in v0.17.0
func DefaultContextMenuProps() ContextMenuProps
DefaultContextMenuProps returns sensible defaults.
type CopyButtonProps ¶ added in v0.7.0
type CopyButtonProps struct {
utils.BaseProps
// Text is the string to copy to the clipboard.
Text string
// Label is the button text in the idle state. Defaults to "Copy".
Label string
// CopiedLabel is the button text shown briefly after a successful copy.
// Defaults to "Copied!".
CopiedLabel string
// Icon optionally renders a leading clipboard icon.
Icon bool
// Href, when set, renders an <a> instead of a <button>. The link still
// copies text to the clipboard on click. Use for copy-as-link patterns.
Href string
// LabelClass, when set, replaces the label span's default color classes
// (text-gray-700 dark:text-gray-200). Use for themes that re-color the
// button's ancestors (re-colored tables, tinted cards) where the fixed
// palette fights the surroundings — e.g. "text-emerald-700
// dark:text-emerald-300" or a var(--…)-based pair of your own. The
// [data-tc-copy-text] attribute stays as the CSS escape hatch for full
// restyling.
LabelClass string
}
CopyButtonProps configures a button that copies text to the clipboard. When the user clicks the button, the text is copied via the Clipboard API, and the button label temporarily changes to CopiedLabel before reverting.
func DefaultCopyButtonProps ¶ added in v0.7.0
func DefaultCopyButtonProps() CopyButtonProps
DefaultCopyButtonProps returns sensible defaults.
type CountBadgeProps ¶ added in v0.7.0
type CountBadgeProps struct {
utils.BaseProps
// Count is the number to display in the badge.
Count int
// Max is the overflow threshold. When Count > Max, the badge shows
// "Max+" instead of the raw number (e.g. Max=99, Count=150 → "99+").
// Defaults to 99. Set to 0 to disable overflow.
Max int
}
CountBadgeProps configures an icon or element with a notification count badge overlaid in the top-right corner. Use it to show unread counts, pending items, or any numeric indicator on top of a bell icon, avatar, etc.
func DefaultCountBadgeProps ¶ added in v0.7.0
func DefaultCountBadgeProps() CountBadgeProps
DefaultCountBadgeProps returns sensible defaults.
type DataStateProps ¶ added in v1.22.0
type DataStateProps struct {
utils.BaseProps
// State selects the rung. DataStateContent (the zero value) renders
// Children; every other state renders the placeholder.
State DataStateState
// Title and Description carry the chosen state's copy — per-state truth,
// so they sit on the props, not in the component.
Title string
Description string
// TitleTag overrides the placeholder's heading element (defaults to h3,
// like EmptyState).
TitleTag HeadingTagType
// Icon overrides the state's default icon (empty: inbox, unavailable:
// exclamation-triangle, disabled: no-symbol).
Icon icons.Name
}
DataStateProps configures the data-state ladder for one region.
func DefaultDataStateProps ¶ added in v1.22.0
func DefaultDataStateProps() DataStateProps
DefaultDataStateProps returns sensible defaults.
type DataStateState ¶ added in v1.22.0
type DataStateState string
DataStateState is one rung of the data-state ladder.
const ( // DataStateContent renders the children — data loaded, everything fine. // The zero value. DataStateContent DataStateState = "content" // DataStateEmpty renders the empty placeholder — loaded, nothing there. DataStateEmpty DataStateState = "empty" // failed or is retrying. DataStateUnavailable DataStateState = "unavailable" // DataStateDisabled renders the feature-off placeholder — the data // source is switched off by configuration. DataStateDisabled DataStateState = "disabled" )
Data state constants.
type DataTableColumn ¶ added in v0.17.0
type DataTableColumn struct {
Label string
Sortable bool
// SortKey is the query-param value representing this column when sorting
// (e.g. "created_at"). When empty, defaults to the lowercase Label.
SortKey string
}
DataTableColumn defines a column in a DataTable with sort configuration.
type DataTableProps ¶ added in v0.17.0
type DataTableProps struct {
utils.BaseProps
Columns []DataTableColumn
Rows []TableRow
// ActiveSortColumn is the Label of the currently sorted column.
ActiveSortColumn string
// ActiveSortDir is the current sort direction of the active column.
ActiveSortDir SortDirection
// SortBaseURL is the base URL for sort links (e.g. "/users").
// Query params for sort/dir are appended automatically.
SortBaseURL string
// SortParam is the query-parameter name for the sort column (default: "sort").
SortParam string
// DirParam is the query-parameter name for the sort direction (default: "dir").
DirParam string
// Pagination, when set, renders below the table. Pass a
// navigation.Pagination component or any custom pager.
Pagination templ.Component
// EmptyState, when set and Rows is empty, replaces the table entirely.
EmptyState templ.Component
// Striped, Hover, Bordered — table appearance options (passed to Table).
Striped bool
Hover bool
Bordered bool
// Flush suppresses the table wrapper border — use when nesting inside
// a Card(CardPaddingNone) to avoid double borders.
Flush bool
// CellPadding controls vertical density (passed to Table).
CellPadding TableCellPadding
// Caption is an accessibility-only table caption (visually hidden).
Caption string
}
DataTableProps configures a data table with integrated sort management, optional pagination, and empty-state rendering. It composes Table internally, computing TypedHeaders with correct sort URLs from the current sort state.
Consumers provide column definitions and the current sort state (read from URL query params on the server). DataTable generates the correct sort-toggle links for each header automatically.
func DefaultDataTableProps ¶ added in v0.17.0
func DefaultDataTableProps() DataTableProps
DefaultDataTableProps returns sensible defaults.
type DateFormat ¶ added in v1.8.2
type DateFormat string
DateFormat defines the Go time layout used by DateRange. When empty, DateRangeDefaults.Layout is used.
const ( // DateFormatJanuary2006 renders as "January 2006". DateFormatJanuary2006 DateFormat = "January 2006" // DateFormatJan2006 renders as "Jan 2006". DateFormatJan2006 DateFormat = "Jan 2006" // DateFormat2006_01 renders as "2006-01". DateFormat2006_01 DateFormat = "2006-01" // DateFormatJan2_2006 renders as "Jan 2, 2006". DateFormatJan2_2006 DateFormat = "Jan 2, 2006" )
type DateRangeProps ¶ added in v1.8.2
type DateRangeProps struct {
utils.BaseProps
Start *time.Time
End *time.Time
// Layout overrides the date format. Defaults to "January 2006".
Layout DateFormat
// PresentText overrides the text shown when End is nil. Defaults to "Present".
PresentText string
// Separator overrides the range separator. Defaults to "–" (en dash).
Separator string
}
DateRangeProps configures a date range display.
type DefinitionGridProps ¶ added in v0.7.0
type DefinitionGridProps struct {
utils.BaseProps
// Items are the term-detail pairs to render.
Items []DefinitionItem
// Cols controls the responsive column count. Defaults to GridCols3 when
// empty or unknown.
Cols GridCols
// ContainerAware, when true, wraps the grid in a @container div and uses
// container-query variants (@sm:, @lg:) instead of viewport breakpoints.
// Default false (viewport breakpoints).
ContainerAware bool
}
DefinitionGridProps configures a responsive grid of definition items. Unlike DefinitionList (which renders a single two-column table), DefinitionGrid lays out each term-detail pair as a card in a responsive grid — ideal for dashboards and settings pages where many key-value pairs need to be scanned side by side.
Set ContainerAware: true to make the column count respond to the parent container's width (CSS @container) instead of the viewport. Useful when DefinitionGrid is placed inside a sidebar, card body, or other constrained layout. See ADR-0018.
func DefaultDefinitionGridProps ¶ added in v0.7.0
func DefaultDefinitionGridProps() DefinitionGridProps
DefaultDefinitionGridProps returns sensible defaults.
type DefinitionItem ¶ added in v0.6.0
type DefinitionItem struct {
Term string
Detail string
// DetailComponent overrides Detail when set — use for badges, links, or
// any rich content instead of plain text.
DetailComponent templ.Component
}
DefinitionItem is one term-detail pair in a DefinitionList.
type DefinitionListProps ¶ added in v0.6.0
type DefinitionListProps struct {
utils.BaseProps
Items []DefinitionItem
}
DefinitionListProps configures a two-column term/detail list.
func DefaultDefinitionListProps ¶ added in v0.6.0
func DefaultDefinitionListProps() DefinitionListProps
DefaultDefinitionListProps returns sensible defaults
type DrawerProps ¶ added in v0.3.0
type DrawerProps struct {
utils.BaseProps
Title string
Open bool
Side DrawerSide
Size DrawerSize
}
DrawerProps configures a drawer (side panel) component.
func DefaultDrawerProps ¶ added in v0.3.0
func DefaultDrawerProps() DrawerProps
DefaultDrawerProps returns sensible defaults.
type DrawerSide ¶ added in v0.3.0
type DrawerSide string
DrawerSide defines which side the drawer slides in from.
const ( DrawerLeft DrawerSide = "left" DrawerRight DrawerSide = "right" )
type DrawerSize ¶ added in v0.3.0
type DrawerSize string
DrawerSize defines the width of the drawer panel.
const ( DrawerSizeSM DrawerSize = "sm" DrawerSizeMD DrawerSize = "md" DrawerSizeLG DrawerSize = "lg" DrawerSizeXL DrawerSize = "xl" DrawerSize2XL DrawerSize = "2xl" // largest available width (max-w-2xl) )
Drawer size constants. DrawerSize2XL is the largest size (max-w-2xl).
type DropdownItem ¶
type DropdownItem struct {
Text string
Href string
Icon icons.Name
Kind DropdownItemKind
External bool
Disabled bool
Attrs templ.Attributes
}
DropdownItem represents a single action in a dropdown menu
func (DropdownItem) IsLink ¶
func (item DropdownItem) IsLink() bool
IsLink returns true if the item should render as a link. When Kind is unset, falls back to Href-based discrimination for backward compat.
type DropdownItemKind ¶
type DropdownItemKind string
DropdownItemKind determines how a dropdown item is rendered
const ( // DropdownItemLink renders the item as an anchor (<a>) element DropdownItemLink DropdownItemKind = "link" // DropdownItemButton renders the item as a <button> element DropdownItemButton DropdownItemKind = "button" )
type DropdownPosition ¶
type DropdownPosition string
DropdownPosition defines the inline ALIGNMENT of the always-below-trigger dropdown menu relative to the trigger's box (the menu itself always opens downward). Start aligns the menu's inline-start edge with the trigger's; End aligns the inline-end edges.
const ( DropdownPositionStart DropdownPosition = "start" DropdownPositionEnd DropdownPosition = "end" )
const ( DropdownPositionLeft DropdownPosition = "left" DropdownPositionRight DropdownPosition = "right" )
Legacy physical spellings from before the logical axis existed: Left behaves as Start and Right as End in every text direction. Removal is planned for v2 (ADR-0022).
type DropdownProps ¶
type DropdownProps struct {
utils.BaseProps
Label string
// Trigger, when set, replaces the default styled button CONTENT: the
// component renders inside a functionally-wired <button> (popovertarget,
// aria-haspopup, data-dropdown-trigger) with NO default visual classes,
// so the custom component owns the trigger's entire appearance (e.g. an
// avatar + email identity cluster). Leave nil for the default label +
// chevron button.
Trigger templ.Component
Items []DropdownItem
Position DropdownPosition
}
DropdownProps configures a dropdown action menu
func DefaultDropdownProps ¶
func DefaultDropdownProps() DropdownProps
DefaultDropdownProps returns sensible defaults
type EmptyStateProps ¶
type EmptyStateProps struct {
utils.BaseProps
Title string
// TitleTag overrides the heading element for the title.
// Defaults to h3 (HeadingTagH3) when empty. Set to HeadingTagH2 when the
// empty state is the first heading level after a page <h1>.
TitleTag HeadingTagType
Description string
Icon icons.Name
ActionText string
ActionHref string
ActionAttrs templ.Attributes
}
EmptyStateProps configures an empty state illustration
func DefaultEmptyStateProps ¶
func DefaultEmptyStateProps() EmptyStateProps
DefaultEmptyStateProps returns sensible defaults
type ExternalLinkProps ¶ added in v1.5.0
type ExternalLinkProps struct {
utils.BaseProps
// Href is the target URL. Passed as a plain string (NOT templ.SafeURL)
// so that templ's built-in URL sanitizer runs — it blocks javascript:,
// data:, vbscript: and other dangerous schemes by rewriting them.
Href string
// Text is the visible link text. When empty, children are rendered instead.
Text string
// ShowIcon controls whether the external-arrow icon (↗) is rendered.
// Default: true.
ShowIcon bool
}
ExternalLinkProps configures a safe external link.
func DefaultExternalLinkProps ¶ added in v1.5.0
func DefaultExternalLinkProps() ExternalLinkProps
DefaultExternalLinkProps returns sensible defaults for an external link.
type EyebrowProps ¶ added in v1.10.0
EyebrowProps configures a small uppercase overline label rendered above a title. Eyebrows read as status, not decoration: use them to anchor the eye before a headline (e.g. "DNS block · 12:47:03" above a page title).
func DefaultEyebrowProps ¶ added in v1.10.0
func DefaultEyebrowProps() EyebrowProps
DefaultEyebrowProps returns sensible defaults
type GridCols ¶ added in v0.7.0
type GridCols string
GridCols is a typed enum for the responsive column count of a Grid. Unknown values fall back to GridCols3 (graceful degradation — never panic).
const ( GridCols1 GridCols = "1" GridCols2 GridCols = "2" GridCols3 GridCols = "3" GridCols4 GridCols = "4" GridCols5 GridCols = "5" GridCols6 GridCols = "6" // GridColsAutoFit uses CSS auto-fit + minmax() instead of fixed breakpoints. // The grid responds to container width, not viewport. Requires MinColWidth. GridColsAutoFit GridCols = "auto-fit" // GridColsDefault is the canonical default (3 columns at the lg breakpoint). GridColsDefault GridCols = GridCols3 )
type GridGap ¶ added in v0.9.0
type GridGap string
GridGap is a typed enum for the gap spacing between grid items. Unknown values fall back to GridGapMD (graceful degradation — never panic).
type GridProps ¶ added in v0.7.0
type GridProps struct {
utils.BaseProps
// Cols controls the responsive column count. Defaults to GridCols3 when
// empty or unknown.
Cols GridCols
// Gap controls the spacing between grid items. Defaults to GridGapMD (gap-4).
Gap GridGap
// ContainerAware, when true, renders the grid inside an @container
// wrapper so column counts respond to the container's width instead of
// the browser viewport. Opt-in: the struct-literal zero value is
// viewport-based; DefaultGridProps() sets it true. Set it explicitly
// (true or false) whenever a bare GridProps{...} literal is used.
ContainerAware bool
// MinColWidth sets the minimum column width for auto-fit grids. Used only
// when Cols is GridColsAutoFit. Generates a CSS auto-fit/minmax template
// that responds to container width. Example: "190px" produces
// grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)).
// Ignored for fixed column counts. When Cols is GridColsAutoFit,
// ContainerAware is ignored (auto-fit already responds to container
// width via CSS minmax).
MinColWidth string
}
GridProps configures a responsive grid layout. Use Grid to lay out cards, stat cards, or any repeating content with consistent responsive breakpoints without repeating the long `grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3` utility string on every page.
Children require a templ render context: Grid receives its cells through the templ children slot, so rendering the component directly into a plain writer (`Component.Render(ctx, &buf)` from Go, outside a templ tree) emits the grid shell with EMPTY cells — valid HTML, silently missing content. Pass the items through a templ template (even a trivial one that ranges over a slice) so the children context exists. The same limitation applies to every children-carrying component in this library (Card's slots, Modal/Drawer content, Accordion items with nested markup, …).
func DefaultGridProps ¶ added in v0.7.0
func DefaultGridProps() GridProps
DefaultGridProps returns sensible defaults (GridCols3).
type HeadingLevel ¶ added in v1.8.2
type HeadingLevel string
HeadingLevel defines the HTML heading element used by SectionHeading.
const ( HeadingLevelH1 HeadingLevel = "h1" HeadingLevelH2 HeadingLevel = "h2" HeadingLevelH3 HeadingLevel = "h3" HeadingLevelH4 HeadingLevel = "h4" HeadingLevelH5 HeadingLevel = "h5" HeadingLevelH6 HeadingLevel = "h6" )
type HeadingTagType ¶ added in v1.19.3
type HeadingTagType string
HeadingTagType selects the heading element (h1–h6) a component renders for its title. The zero value and any unknown value fall back to h3 at render time. As a defined string type, untyped literals ("h2") still assign, so existing consumer call sites keep compiling.
const ( HeadingTagH1 HeadingTagType = "h1" HeadingTagH2 HeadingTagType = "h2" HeadingTagH3 HeadingTagType = "h3" HeadingTagH4 HeadingTagType = "h4" HeadingTagH5 HeadingTagType = "h5" HeadingTagH6 HeadingTagType = "h6" // HeadingTagDefault is the heading level used when TitleTag is empty or // unknown — h3 keeps the common card/section/empty-state outline sane // under a page-level h1. HeadingTagDefault = HeadingTagH3 )
type HeatmapCell ¶ added in v1.6.0
type HeatmapCell struct {
// Value is the cell's magnitude.
Value float64
// Label is the tooltip text for the cell.
Label string
// Href makes the cell a clickable link.
Href string
}
HeatmapCell represents a single cell in a heatmap grid.
type HeatmapProps ¶ added in v1.6.0
type HeatmapProps struct {
utils.BaseProps
// Rows are the data rows. Each row's Cells slice should have the same
// length as ColumnLabels.
Rows []HeatmapRow
// ColumnLabels are the labels for each column (e.g. hour labels).
ColumnLabels []string
// Max overrides the auto-computed maximum value (0 = auto from data).
Max float64
// ColorVar is the CSS custom property used for cell background color.
// Default: "--ds-brand".
ColorVar string
// CellSize is the Tailwind height class for each cell.
// Default: "h-5".
CellSize string
// ShowValues renders the numeric value inside each cell.
ShowValues bool
// ValueFormat formats the value for display. Default: fmt.Sprintf("%.0f", v).
ValueFormat func(float64) string
// EmptyMessage is shown when Rows is empty. Default: "No data".
EmptyMessage string
// HighlightPeak adds a ring to the cell with the highest value.
HighlightPeak bool
}
HeatmapProps configures a CSS-based heatmap grid.
func DefaultHeatmapProps ¶ added in v1.6.0
func DefaultHeatmapProps() HeatmapProps
DefaultHeatmapProps returns sensible defaults for a heatmap.
type HeatmapRow ¶ added in v1.6.0
type HeatmapRow struct {
// Label is the row heading (e.g. "Mon", "general").
Label string
// Cells are the per-column values for this row.
Cells []HeatmapCell
}
HeatmapRow represents a single row in a heatmap grid.
type HoverCardPosition ¶ added in v0.17.0
type HoverCardPosition = Position
HoverCardPosition is an alias of Position: where a HoverCard appears relative to its trigger.
type HoverCardProps ¶ added in v0.17.0
type HoverCardProps struct {
utils.BaseProps
Content templ.Component
Position HoverCardPosition
}
HoverCardProps configures a hover-activated card with rich content. The card appears on hover and focus, using pure CSS (no JavaScript). Accessible: the card content is linked to the trigger via aria-details (rich supplementary content — a hover card is not a tooltip, so no role="tooltip"). This is the reference implementation for the CSS-only overlay pattern — see ADR-0017 for the broader Popover API migration strategy.
func DefaultHoverCardProps ¶ added in v0.17.0
func DefaultHoverCardProps() HoverCardProps
DefaultHoverCardProps returns sensible defaults.
type ImageProps ¶ added in v0.7.0
type ImageProps struct {
utils.BaseProps
// Src is the primary image URL.
Src string
// Alt text for accessibility. Required for non-decorative images.
Alt string
// SrcSet defines multiple image sources for responsive delivery.
// Example: "photo-1x.jpg 1x, photo-2x.jpg 2x" or
// "photo-480w.jpg 480w, photo-800w.jpg 800w".
SrcSet string
// Sizes defines the intended display width at different breakpoints.
// Example: "(max-width: 600px) 480px, 800px".
// Pair with a width-descriptor srcset for responsive images.
Sizes string
// Width in CSS pixels. When set, the img tag includes a width attribute
// and helps prevent layout shift (CLS).
Width int
// Height in CSS pixels. When set, the img tag includes a height attribute.
Height int
// FallbackSrc, when non-empty, is used if Src fails to load. Handled via
// a CSP-safe event-delegation script — no inline onerror handler.
FallbackSrc string
// Lazy controls the loading attribute AND the fetch priority. When true
// (default) the img gets loading="lazy" and NO fetchpriority attribute;
// set it to false for the above-the-fold LCP image, which then gets
// loading="eager" plus fetchpriority="high".
//
// fetchpriority="low" is deliberately never emitted: pairing it with
// loading="lazy" is a documented anti-pattern (Modern Web Guidance
// "optimize-image-priority" makes it MANDATORY not to) — lazy images
// already load at normal priority when they enter the viewport, and an
// explicit low priority delays them further.
Lazy bool
// Rounded, when true, adds rounded-full for circular images (avatars, icons).
// Defaults to false (rounded-md).
Rounded bool
// Placeholder, when non-empty, is a tiny image URL (a 10-30px thumbhash
// or thumbnail) rendered blurred BEHIND the main image — the zero-JS
// blur-up pattern. The placeholder fills the box while Src loads and is
// covered the moment the full image paints (no JavaScript, no animation
// timing to race). Consumer generates the tiny image; the library adds
// only CSS.
Placeholder string
}
ImageProps configures an <img> element with lazy loading, aspect-ratio dimensions, and optional fallback source. The fallback is handled via a CSP-safe singleton script (no inline onerror handler) that swaps the src when the original fails to load.
func DefaultImageProps ¶ added in v0.7.0
func DefaultImageProps() ImageProps
DefaultImageProps returns sensible defaults.
type KanbanBoardProps ¶ added in v1.16.0
type KanbanBoardProps struct {
utils.BaseProps
// Columns renders left to right (right to left under dir="rtl").
Columns []KanbanColumn
// Wire is the move exchange. nil or empty URL renders a read-only board.
// Method defaults to POST, Event to submit, ContentType to form
// encoding; under htmx, Target defaults to the board root with
// hx-swap="outerHTML".
//
// Sorted views: the submitted index is advisory — the server owns the
// real ordering. On a server-sorted view (by priority, created-at, …)
// reject same-column moves in the handler; the sort re-asserts on
// re-render and would otherwise make the drop look broken. See
// docs/recipes/kanban-card-anatomy.md ("Moves on a sorted view").
Wire *wire.Action
// EmptyColumnText shows inside a column with no cards. Default "No cards".
EmptyColumnText string
// CSRFToken, when set, renders a hidden CSRF input (name from
// CSRFTokenName) inside the move form so submissions pass token checks.
CSRFToken string
// CSRFTokenName is the hidden input's name. Default "csrf_token".
CSRFTokenName string
}
KanbanBoardProps configures a Kanban board: horizontal swimlanes of draggable cards, movable via HTML5 drag-and-drop or per-card keyboard buttons, under either transport.
The move exchange: when Wire is set (non-empty URL), the component renders a hidden form carrying the Wire attributes plus three hidden inputs — card, column, index. Every move (drop or keyboard button) fills those inputs and submits the form, so the request travels as a plain form POST under htmx (hx-post) and Datastar (@post with form encoding) alike. The documented response is the freshly rendered board element itself: under htmx the component auto-targets its own id with hx-swap="outerHTML"; under Datastar wrap the endpoint in wire.Handler with PatchTarget{Selector: "#<board id>", Mode: wire.PatchModeOuter}. Decode submissions with ParseKanbanMove.
A board without Wire (or with an empty Wire.URL) is a read-only view: no drag handles, no move buttons, no script.
Moves apply optimistically: the card moves in the DOM the moment the move is submitted (before the request resolves) and wears a pending register (tc-kanban-pending spinner + aria-busy) until the server's re-render replaces it. A failed move (4xx/5xx, network error) is reverted to its original position, flashed with tc-kanban-move-failed, and announced through a role="alert" region. See ADR-0041 for the decision.
func DefaultKanbanBoardProps ¶ added in v1.16.0
func DefaultKanbanBoardProps() KanbanBoardProps
DefaultKanbanBoardProps returns sensible defaults.
type KanbanCard ¶ added in v1.16.0
type KanbanCard struct {
// ID is the stable card identity submitted as the move's card field.
// It must survive re-renders (never auto-generate it per request).
ID string
// Title is the card's heading text.
Title string
// Href, when set, links the card title to a detail page.
Href string
// Content renders arbitrary card body below the title (labels, avatars,
// metadata). Compose with Badge, Avatar, RelativeTime, … — the proven
// anatomy (identity badges, 2+N tag overflow, assignee stack, one-line
// description preview) is docs/recipes/kanban-card-anatomy.md; the
// compiling composition is ExampleKanbanBoard_cardAnatomy.
Content templ.Component
// Class overrides the card's Tailwind classes.
Class string
}
KanbanCard is one work item in a KanbanBoard column. ID is the consumer-supplied stable identity used by the move exchange — a card without an ID renders fine but is not draggable (the server could not route the move).
type KanbanColumn ¶ added in v1.16.0
type KanbanColumn struct {
// ID is the stable column identity submitted as the move's column field.
ID string
// Title is the column heading.
Title string
// Cards renders in order, top to bottom.
Cards []KanbanCard
// Action is an optional affordance rendered in the column header after
// the count badge — the standard "add card" spot. The consumer owns the
// whole element: compose display.Button (its Wire field for transport
// wiring), a plain link, or any templ markup — and owns its
// accessibility too: whatever renders there must be keyboard-reachable
// (a real button or link, not a hover-only div). nil omits it; boards
// without it render byte-identical to before.
Action templ.Component
// Tone is an optional status color rendered as a small dot before the
// column title (todo=blue, done=green, …). The zero value (and any
// unknown value) renders no dot — see KanbanTone.
Tone KanbanTone
// Class overrides the column's Tailwind classes.
Class string
}
KanbanColumn is one swimlane of a KanbanBoard. Like cards, columns need a stable ID to be droppable targets of the move exchange.
type KanbanMove ¶ added in v1.16.0
type KanbanMove struct {
Card string `form:"card"`
Column string `form:"column"`
Index int `form:"index"`
}
KanbanMove is one decoded card move: the card (its consumer-supplied ID), the target column ID, and the 0-based insertion position within that column's cards (0 = top). KanbanMove is one card move as submitted by a wired KanbanBoard. The form tags carry the exact field names the board's hidden move form sends (kanbanFieldCard/Column/Index); wire.DecodeForm fills them on the server.
func ParseKanbanMove ¶ added in v1.16.0
func ParseKanbanMove(r *http.Request) (KanbanMove, error)
ParseKanbanMove decodes a KanbanBoard move submission (form body or query parameters) into a KanbanMove via wire.DecodeForm. A missing index defaults to 0 (insert at top); a negative or non-numeric index is an error. Empty card or column fields are an error — a wired board always sends both.
The returned Index is advisory: the server owns the real ordering. When the board view is server-sorted, reject same-column moves (Card's current column == Column) — the sort re-asserts on re-render, so accepting them makes the drop look broken. Cross-column moves stay meaningful on sorted views. See docs/recipes/kanban-card-anatomy.md, "Moves on a sorted view".
type KanbanTone ¶ added in v1.18.0
type KanbanTone string
KanbanTone selects the semantic color of a KanbanColumn's status dot, mirroring StatTone's palette. Unlike StatTone, the zero value is toneless: an empty or unknown Tone renders no dot at all (columns are not required to carry status semantics).
const ( KanbanToneGray KanbanTone = "gray" KanbanToneBlue KanbanTone = "blue" KanbanToneGreen KanbanTone = "green" KanbanToneYellow KanbanTone = "yellow" KanbanToneRed KanbanTone = "red" KanbanTonePurple KanbanTone = "purple" )
Column dot tones. Match the palette of Badge/BadgeType and StatTone: gray, blue, green, yellow, red, purple.
func (KanbanTone) Hue ¶ added in v1.24.0
func (t KanbanTone) Hue() tone.Hue
Hue maps KanbanTone onto the categorical hue axis. Kanban lanes are categorical, not semantic — there is deliberately no Tone() here.
type LightboxImage ¶ added in v1.22.0
type LightboxImage struct {
// Src is the full-size image URL.
Src string
// Alt is the image's alternative text (required for a11y).
Alt string
// Caption optionally renders under the image.
Caption string
// ThumbSrc optionally overrides the thumbnail source (TriggerLabel
// button mode uses Src when empty).
ThumbSrc string
}
LightboxImage is one viewable image.
type LightboxProps ¶ added in v1.22.0
type LightboxProps struct {
utils.BaseProps
// Images renders in order; the viewer navigates them with wrap-around.
Images []LightboxImage
// TriggerLabel renders one opener button with this text (Thumbnails
// overrides it). Empty + no Thumbnails renders the dialog only —
// open it yourself via tcOpenLightbox("<id>-dialog", index).
TriggerLabel string
// Thumbnails renders one opener button per image (using ThumbSrc/Src
// as its thumbnail) instead of a single TriggerLabel button.
Thumbnails bool
}
LightboxProps configures the lightbox.
func DefaultLightboxProps ¶ added in v1.22.0
func DefaultLightboxProps() LightboxProps
DefaultLightboxProps returns sensible defaults.
type LineChartProps ¶ added in v1.7.0
type LineChartProps struct {
utils.BaseProps
// Series is the data to plot. Each series becomes one line.
Series []LineChartSeries
// XAxisLabels are category labels along the X-axis (e.g. month names).
// If empty, no X-axis labels are rendered.
XAxisLabels []string
// Width is the SVG canvas width in pixels. Default: 600.
Width int
// Height is the SVG canvas height in pixels. Default: 300.
Height int
// Padding controls the inset around the plot area. Default: DefaultChartPadding().
Padding ChartPadding
// Min overrides the auto-computed Y-axis minimum (nil = auto from data).
Min *float64
// Max overrides the auto-computed Y-axis maximum (nil = auto from data).
Max *float64
// MaxTicks is the tick budget for the Y axis: ComputeNiceTicks aims for
// at most this many ticks. 0 or negative keeps the default of 8. The
// final count is approximate — ticks snap to human-readable steps, so
// the actual count can land slightly above or below the budget.
MaxTicks int
// ShowGrid renders dashed horizontal gridlines at each Y tick. Default: true.
ShowGrid bool
// ShowDots renders a circle at each data point. Default: true.
ShowDots bool
// ShowLegend renders a color-swatch legend above the chart when there
// are 2+ series. Default: true.
ShowLegend bool
// Style controls whether lines are straight (Linear) or curved (Smooth).
// Default: LineChartStyleLinear.
Style LineChartStyle
// ValueFormat formats Y-axis tick labels. Default: FormatTickValue.
ValueFormat func(float64) string
// EmptyMessage is shown when Series is empty. Default: "No data".
EmptyMessage string
}
LineChartProps configures a pure-SVG line chart with axes, gridlines, multi-series support, and a legend. Zero JavaScript — all rendering is server-side SVG. Dark-mode aware via Tailwind dark: variants on SVG elements.
func DefaultLineChartProps ¶ added in v1.7.0
func DefaultLineChartProps() LineChartProps
DefaultLineChartProps returns sensible defaults for a line chart.
type LineChartSeries ¶ added in v1.7.0
type LineChartSeries struct {
// Name is the series label shown in the legend.
Name string
// Values are the Y-axis data points.
Values []float64
// Color overrides the palette color — a complete light+dark literal
// (prefer the ChartColor* constants; e.g. ChartColorEmerald). Empty =
// palette by index.
Color tone.ColorClass
// StrokeWidth is the line thickness. Default: 2.
StrokeWidth float64
// Dashed renders the line with a dashed pattern.
Dashed bool
}
LineChartSeries is a single data series in a line chart.
type LineChartStyle ¶ added in v1.7.0
type LineChartStyle string
LineChartStyle controls how series lines are drawn.
const ( // LineChartStyleLinear connects data points with straight line segments. LineChartStyleLinear LineChartStyle = "linear" // LineChartStyleSmooth connects data points with a Catmull-Rom spline curve. LineChartStyleSmooth LineChartStyle = "smooth" )
type ListNoteProps ¶ added in v0.6.0
type ListNoteProps struct {
utils.BaseProps
// Shown is the number of items currently rendered.
Shown int
// Total is the unfiltered/cap-exceeding match count. Read by the
// truncated variant ("N of M") and by ListNoteRange (the Z in
// "X–Y of Z"); ignored by ListNoteCount.
Total int
// RangeFrom is the 1-based index of the first item on the current page
// (ListNoteRange only). Non-positive values degrade to the count message.
RangeFrom int
// RangeTo is the 1-based index of the last item on the current page
// (ListNoteRange only). Non-positive values degrade to the count message.
RangeTo int
// Variant selects count semantics. Defaults to ListNoteTruncated.
Variant ListNoteVariant
}
ListNoteProps configures a "Showing N of M" truncation notice.
type ListNoteVariant ¶ added in v1.19.1
type ListNoteVariant string
ListNoteVariant selects which count semantics ListNote renders.
const ( // ListNoteTruncated renders "Showing N of M. Narrow your search to see // more." — and only when Total > Shown (a truncated result set). This is // the default; the zero value behaves identically. ListNoteTruncated ListNoteVariant = "truncated" // ListNoteCount renders "Showing N items." (pluralized) — count-only, // unconditionally, with no total and no advice. For list semantics where // "N items in range" is the whole message (e.g. an event log between two // timestamps): the consumer already knows why the list is shaped this // way, so count-only is the honest hint — including "Showing 0 items." // for an empty-but-loaded window. ListNoteCount ListNoteVariant = "count" // ListNoteRange renders "Showing X–Y of Z." — cursor-paginated position // semantics: X–Y is the 1-based span of items on the current page (from // RangeFrom/RangeTo), Z is the match count (Total). Unlike the truncated // variant it always renders — a cursor journal has no "everything fits" // signal, and "Showing 193–216 of 237." on the last page is the honest // you-have-seen-it-all hint. An empty or unpositioned range (non-positive // RangeFrom/RangeTo) degrades to the count message. ListNoteRange ListNoteVariant = "range" )
type LivePillProps ¶ added in v1.22.0
type LivePillProps struct {
utils.BaseProps
// Tone selects the dot's semantic color.
Tone StatusTone
// Text is the visible label ("Live", "Reconnecting…").
Text string
// Pulse renders the radiating ring on the pill's dot.
Pulse bool
}
LivePillProps configures the dot+text status pill.
func DefaultLivePillProps ¶ added in v1.22.0
func DefaultLivePillProps() LivePillProps
DefaultLivePillProps returns sensible defaults.
type LoadingDialogProps ¶ added in v1.26.0
type LoadingDialogProps struct {
utils.BaseProps
// Title names the dialog for assistive technology (aria-label fallback
// after AriaLabel and Message). It is not rendered as a visible header —
// a blocking loading state has nothing to close, so the dialog ships no
// header bar and no close button.
Title string
// Message is the visible loading text (also the aria-label fallback).
Message string
// ShowProgress swaps the "Please wait..." hint for a determinate bar.
ShowProgress bool
// Progress is clamped to [0, 100] before rendering.
Progress int
// Open auto-shows the dialog on load (native showModal via the shared
// overlay script). Toggle at runtime with tcOpenModal(id)/tcCloseModal(id)
// or the dialog element's native showModal()/close().
Open bool
}
LoadingDialogProps configures a modal loading dialog.
func DefaultLoadingDialogProps ¶ added in v1.26.0
func DefaultLoadingDialogProps() LoadingDialogProps
DefaultLoadingDialogProps returns sensible defaults.
type ModalProps ¶
ModalProps configures a modal dialog.
func DefaultModalProps ¶
func DefaultModalProps() ModalProps
DefaultModalProps returns sensible defaults.
type OverlayKind ¶ added in v0.7.0
type OverlayKind string
OverlayKind identifies whether an overlay is a Modal or a Drawer.
const ( // OverlayModal is the kind for Modal overlays. OverlayModal OverlayKind = "modal" // OverlayDrawer is the kind for Drawer overlays. OverlayDrawer OverlayKind = "drawer" )
type PageHeaderProps ¶ added in v0.6.0
type PageHeaderProps struct {
utils.BaseProps
Title string
// TitleComponent, when set, renders inside the <h1> instead of the Title
// string — for code elements, badges, or copy buttons inside the header
// title. Takes precedence over Title.
TitleComponent templ.Component
// Subtitle renders below the title in muted text.
Subtitle string
// SubtitleComponent, when set, renders inside the subtitle <p> instead
// of the Subtitle string. Takes precedence over Subtitle.
SubtitleComponent templ.Component
// Breadcrumb renders above the title (optional). Pass a navigation.Breadcrumbs
// component or any custom breadcrumb markup.
Breadcrumb templ.Component
// Action renders on the right side of the title row (optional). Use for
// primary buttons, back links, or status badges.
Action templ.Component
}
PageHeaderProps configures a page-level header with title, optional subtitle, and optional breadcrumb/action slots.
func DefaultPageHeaderProps ¶ added in v0.6.0
func DefaultPageHeaderProps() PageHeaderProps
DefaultPageHeaderProps returns sensible defaults
type PieChartLabelMode ¶ added in v1.7.0
type PieChartLabelMode string
PieChartLabelMode controls where slice labels are rendered.
const ( // PieChartLabelExternal renders labels outside the pie with leader lines. PieChartLabelExternal PieChartLabelMode = "external" // PieChartLabelNone suppresses labels (use the legend instead). PieChartLabelNone PieChartLabelMode = "none" )
type PieChartProps ¶ added in v1.7.0
type PieChartProps struct {
utils.BaseProps
// Slices is the data to plot.
Slices []PieChartSlice
// Width is the SVG canvas width in pixels. Default: 400.
Width int
// Height is the SVG canvas height in pixels. Default: 300.
Height int
// Donut renders a donut (ring) chart with an inner hole. Default: false (full pie).
Donut bool
// InnerRadius controls the donut hole size as a fraction of the radius
// (0.0–1.0). Default: 0.6.
InnerRadius float64
// ShowLabels renders slice labels outside the pie. Default: true.
ShowLabels bool
// LabelMode controls label positioning. Default: PieChartLabelExternal.
LabelMode PieChartLabelMode
// ShowLegend renders a color-swatch legend below the chart. Default: true.
ShowLegend bool
// CenterLabel is text rendered in the center of a donut chart (e.g. "128GB").
CenterLabel string
// EmptyMessage is shown when Slices is empty. Default: "No data".
EmptyMessage string
}
PieChartProps configures a pure-SVG pie or donut chart. Zero JavaScript — all rendering is server-side SVG using arc paths. Dark-mode aware via Tailwind dark: variants on SVG elements.
func DefaultDonutChartProps ¶ added in v1.7.0
func DefaultDonutChartProps() PieChartProps
DefaultDonutChartProps returns sensible defaults for a donut chart.
func DefaultPieChartProps ¶ added in v1.7.0
func DefaultPieChartProps() PieChartProps
DefaultPieChartProps returns sensible defaults for a pie chart.
type PieChartSlice ¶ added in v1.7.0
type PieChartSlice struct {
// Label is the slice's category name.
Label string
// Value is the slice's magnitude. Must be non-negative.
Value float64
// Color overrides the palette color with a Tailwind text-* class
// (e.g. "text-emerald-600 dark:text-emerald-400"). Empty = palette by index.
Color tone.ColorClass
}
PieChartSlice represents a single slice in a pie or donut chart.
type Point ¶ added in v1.7.0
type Point struct {
X, Y float64
}
Point is a coordinate pair in SVG user space.
func ScalePoints ¶ added in v1.7.0
ScalePoints maps data values to SVG point coordinates within a plot area of the given width and height. The X coordinate is distributed evenly across the value count; the Y coordinate is scaled from minVal..maxVal and inverted (SVG Y increases downward). If maxVal <= minVal the range is padded by 1 to avoid division by zero. The returned points are relative to the plot area origin (0,0); the caller offsets them by the chart padding.
type PopoverPosition ¶ added in v0.15.0
type PopoverPosition = Position
PopoverPosition is an alias of Position: where a Popover panel appears relative to its trigger.
type PopoverProps ¶ added in v0.15.0
type PopoverProps struct {
utils.BaseProps
TriggerText string
Position PopoverPosition
}
PopoverProps configures a popover component.
A popover is a floating panel triggered by a button click. It displays arbitrary content (unlike Dropdown which renders menu items) and dismisses on Escape, click-outside, or when the trigger is toggled again.
func DefaultPopoverProps ¶ added in v0.15.0
func DefaultPopoverProps() PopoverProps
DefaultPopoverProps returns sensible defaults.
type Position ¶ added in v1.24.0
type Position string
Position defines where a floating element appears relative to its trigger, expressed in logical (writing-direction aware) sides: start and end map to the inline start/end of the surrounding text direction (left/right in LTR, mirrored in RTL). It is the shared placement axis for Tooltip, Popover, and HoverCard.
Legacy physical spellings from before the logical axis existed. They keep their original physical behavior (never mirrored in RTL) and stay valid so existing consumers keep compiling; prefer PositionStart/PositionEnd, which are pixel-identical to them in LTR and mirror correctly in RTL. Removal is planned for v2 (ADR-0022).
type ProseProps ¶ added in v1.24.0
type ProseProps struct {
utils.BaseProps
// Children is the longform content (typically rendered markdown HTML).
// When nil, Prose renders its templ trailing block instead — both call
// styles work (the doc example uses the trailing block; programmatic Go
// consumers set this field). Before the fallback shipped (2026-10-30),
// trailing-block callers got an EMPTY container — the demo's own Prose
// section shipped empty for weeks.
Children templ.Component
// Size sets the font scale. Zero value falls back to ProseSizeMD.
Size ProseSize
}
ProseProps configures a longform-content container.
func DefaultProseProps ¶ added in v1.24.0
func DefaultProseProps() ProseProps
DefaultProseProps returns sensible defaults.
type ProseSize ¶ added in v1.24.0
type ProseSize string
ProseSize controls the container's font scale. Utilities beat the .tc-prose descendant rules, so the size classes override the base font.
type RelativeTimeProps ¶ added in v0.7.0
type RelativeTimeProps struct {
utils.BaseProps
// Time is the timestamp to display relative to now.
Time time.Time
// Now, when non-zero, pins the reference instant the relative string is
// computed against (defaults to time.Now at render time). Tests use it to
// pin boundary behavior ("59s vs 60s") deterministically; production
// callers leave it zero.
Now time.Time
// Title, when non-empty, overrides the default title (absolute time shown
// on hover). Set to "" to use the formatted absolute timestamp.
Title string
// EmptyText, when non-empty and Time is the zero value, renders this text
// instead of a relative string: zero timestamps mean "never" (never
// rotated, never used), and date noise like "Jan 1, 0001" is the opposite
// of the information the reader needs. The empty render stays inside the
// <time> shell but omits the meaningless zero datetime, the default
// zero-date title, and data-tc-relative (the auto-refresh script would
// re-format the placeholder into date noise). Unset, or a non-zero Time,
// keeps the exact prior behavior.
EmptyText string
// AutoRefresh defaults to true — the component injects a singleton script
// that uses the native Intl.RelativeTimeFormat API to live-update the text
// every 30 seconds. Also listens to htmx:afterSettle so newly-swapped
// <time> elements are formatted immediately. This is progressive enhancement:
// the server-rendered text is correct without JS; the script just keeps it
// fresh. Set to false for static contexts (PDF, email, SEO-only).
AutoRefresh bool
}
RelativeTimeProps configures a human-readable relative timestamp. The server renders the initial relative string ("2 hours ago"); the machine-readable datetime attribute is always present for screen readers and search engines.
func DefaultRelativeTimeProps ¶ added in v0.7.0
func DefaultRelativeTimeProps() RelativeTimeProps
DefaultRelativeTimeProps returns sensible defaults. Time defaults to now, AutoRefresh defaults to true (live-updating via Intl.RelativeTimeFormat).
type ScrollbackLine ¶ added in v1.10.0
type ScrollbackLine struct {
Timestamp string
Tag string
Text string
Tone ScrollbackTone
}
ScrollbackLine is one entry in a Scrollback. Timestamp is preformatted by the caller (e.g. "12:47:03.184"); Tag is a short column label (e.g. "query", "match"); Text is the line body.
type ScrollbackProps ¶ added in v1.10.0
type ScrollbackProps struct {
utils.BaseProps
// Lines renders top-down in the given order. Empty slice renders nothing.
Lines []ScrollbackLine
// Stagger animates lines in sequentially (pure CSS, reduced-motion safe).
// DefaultScrollbackProps enables it; the zero value renders instantly.
Stagger bool
}
ScrollbackProps configures a terminal-style log block.
func DefaultScrollbackProps ¶ added in v1.10.0
func DefaultScrollbackProps() ScrollbackProps
DefaultScrollbackProps returns sensible defaults.
type ScrollbackTone ¶ added in v1.10.0
type ScrollbackTone string
ScrollbackTone colors a scrollback line's tag column.
const ( ScrollbackToneNeutral ScrollbackTone = "neutral" ScrollbackToneInfo ScrollbackTone = "info" ScrollbackToneSuccess ScrollbackTone = "success" ScrollbackToneWarning ScrollbackTone = "warning" ScrollbackToneDanger ScrollbackTone = "danger" )
func (ScrollbackTone) Tone ¶ added in v1.24.0
func (t ScrollbackTone) Tone() tone.Tone
Tone maps ScrollbackTone onto the canonical semantic axis.
type SectionHeadingProps ¶ added in v1.8.2
type SectionHeadingProps struct {
utils.BaseProps
Title string
Level HeadingLevel
Align TextAlign
SubTitle string
}
SectionHeadingProps configures a section-level heading with typed heading level and alignment.
type SegmentBarProps ¶ added in v1.22.0
type SegmentBarProps struct {
utils.BaseProps
// Segments stack in the given order. A bar with no positive-value
// segments renders nothing (an empty proportion bar is no bar).
Segments []SegmentBarSegment
// NoLegend hides the dot+label+percent legend. The zero value shows it.
NoLegend bool
}
SegmentBarProps configures a stacked proportion bar.
func DefaultSegmentBarProps ¶ added in v1.22.0
func DefaultSegmentBarProps() SegmentBarProps
DefaultSegmentBarProps returns sensible defaults.
type SegmentBarSegment ¶ added in v1.22.0
type SegmentBarSegment struct {
// Label names the segment in the legend and the accessible summary.
Label string
// Value is the segment's magnitude (relative to the sum of all values).
// Negative values clamp to zero.
Value float64
// Color optionally overrides the deterministic palette — a complete
// light+dark literal pair such as "bg-emerald-600 dark:bg-emerald-400".
Color tone.ColorClass
}
SegmentBarSegment is one proportion of the bar.
type SimpleCardProps ¶
type SimpleCardProps struct {
utils.BaseProps
Padding CardPadding
// Body, when set, overrides children — same pattern as CardProps.Body.
Body templ.Component
}
SimpleCardProps configures a simple card without header/footer
func DefaultSimpleCardProps ¶
func DefaultSimpleCardProps() SimpleCardProps
DefaultSimpleCardProps returns sensible defaults
type SortDirection ¶ added in v0.8.0
type SortDirection string
SortDirection defines the sort order for a table column.
const ( SortNone SortDirection = "" SortAsc SortDirection = "asc" SortDesc SortDirection = "desc" )
type SparklineProps ¶ added in v1.5.0
type SparklineProps struct {
utils.BaseProps
// Values are the data points to plot. Fewer than 2 points renders nothing.
Values []float64
// Width is the SVG canvas width in pixels. Default: 120.
Width int
// Height is the SVG canvas height in pixels. Default: sparklineDefaultHeight.
Height int
// StrokeWidth controls the line thickness. Default: 1.5.
StrokeWidth float64
// Filled renders a filled area beneath the line (default: false).
Filled bool
// Min overrides the auto-computed minimum value (nil = auto from data).
Min *float64
// Max overrides the auto-computed maximum value (nil = auto from data).
Max *float64
}
SparklineProps configures a tiny inline SVG line chart for trend visualization.
func DefaultSparklineProps ¶ added in v1.5.0
func DefaultSparklineProps() SparklineProps
DefaultSparklineProps returns sensible defaults for a sparkline.
type StatCardProps ¶
type StatCardProps struct {
utils.BaseProps
Value string
Label string
Change string
Trend TrendDirection
// Tone selects the semantic color of the Icon tile. Empty/unknown
// values fall back to the blue default.
Tone StatTone
// Icon optionally renders a leading icon tile (e.g. icons.Users).
Icon icons.Name
// Href, when non-empty, wraps the whole card in an <a> so the card acts
// as a clickable navigation/filter link. Use this for dashboard stat cards
// that drill down into a filtered view.
Href string
// HxGet, when set, adds hx-get to the card for HTMX-driven updates.
// Mutually independent of Href — Href navigates, HxGet fetches partial HTML.
HxGet string
// HxTarget specifies the hx-target attribute (CSS selector for the swap target).
HxTarget string
// HxSwap specifies the hx-swap attribute (e.g. htmx.SwapInnerHTML, htmx.SwapOuterHTML).
HxSwap htmx.SwapStyle
// ValueID, when non-empty, sets the id attribute on the value <dd> node.
// Use on live-updating dashboards whose scripts address the value
// directly instead of querying the card's internal structure — so a
// markup refactor inside the card cannot break the script's selector.
ValueID string
}
StatCardProps configures a dashboard stat card
func DefaultStatCardProps ¶
func DefaultStatCardProps() StatCardProps
DefaultStatCardProps returns sensible defaults
type StatTone ¶ added in v1.12.0
type StatTone string
StatTone selects the semantic color of the StatCard icon tile. The zero value is the neutral default (blue) so existing call sites are unaffected.
type StatusBadgeMapper ¶ added in v1.22.0
StatusBadgeMapper maps a consumer status string to a badge type. Return the zero value ("" — rendered neutral) for unknown statuses; mappers that want the built-in mapping for unhandled values can call MapStatusToBadgeType.
type StatusDotProps ¶ added in v1.22.0
type StatusDotProps struct {
utils.BaseProps
// Tone selects the semantic color (neutral gray by default).
Tone StatusTone
// Pulse renders the radiating ring — live indicators. The zero value
// is a static dot; the animation carries a motion-reduce fallback.
Pulse bool
// Label, when set, renders screen-reader text naming the state — a
// colored dot that is the ONLY status indicator must be announced.
// Without a Label the dot renders aria-hidden (decorative next to
// visible text you provide).
Label string
}
StatusDotProps configures a standalone status dot.
func DefaultStatusDotProps ¶ added in v1.22.0
func DefaultStatusDotProps() StatusDotProps
DefaultStatusDotProps returns sensible defaults.
type StatusTone ¶ added in v1.22.0
type StatusTone string
StatusTone is the semantic color of a status indicator.
const ( // StatusToneNeutral is gray — connecting, paused, inert. The zero value. StatusToneNeutral StatusTone = "neutral" // StatusToneSuccess is green — live, online, healthy. StatusToneSuccess StatusTone = "success" // StatusToneWarning is amber — stale, reconnecting, waiting. StatusToneWarning StatusTone = "warning" // StatusToneDanger is red — offline, failed. StatusToneDanger StatusTone = "danger" // StatusToneInfo is blue — informational state. StatusToneInfo StatusTone = "info" )
Status tone constants.
func (StatusTone) DotHue ¶ added in v1.24.0
func (t StatusTone) DotHue() tone.Hue
DotHue is the hue StatusDot actually renders for t. Warning deliberately diverges from the tone table (amber here, yellow in the tone table's majority dialect) — the documented warning split brain, unified by the #428 decision.
func (StatusTone) Tone ¶ added in v1.24.0
func (t StatusTone) Tone() tone.Tone
Tone maps StatusTone onto the canonical semantic axis.
type TableCell ¶
TableCell represents a single cell in a table row. When Content is set, it takes priority over Text for rendering.
type TableCellPadding ¶ added in v0.16.0
type TableCellPadding string
TableCellPadding controls the vertical density of header and body cells.
const ( // TableCellPaddingComfortable is the default cell padding (px-4 py-3) — // suitable for general-purpose tables and content pages. TableCellPaddingComfortable TableCellPadding = "comfortable" // TableCellPaddingCompact reduces vertical padding (px-4 py-2) for // data-heavy dashboards and admin panels where rows should feel tighter. TableCellPaddingCompact TableCellPadding = "compact" )
type TableHeader ¶ added in v0.8.0
type TableHeader struct {
Label string
Sortable bool
SortDirection SortDirection
Href string // When set with Sortable=true, renders as <a> for server-side sorting
}
TableHeader defines a typed column header with optional sort capabilities. When TypedHeaders is set on TableProps, it takes precedence over Headers.
type TableProps ¶
type TableProps struct {
utils.BaseProps
Caption string
Headers []string
TypedHeaders []TableHeader // When set, takes precedence over Headers for sortable column rendering
Rows []TableRow
Striped bool
Hover bool
Bordered bool
// Flush, when true, suppresses the wrapper div's border and rounded corners.
// Use this when the table is nested inside a Card(CardPaddingNone) to avoid
// a double border — the card provides the outer border, and the table sits
// flush against it. The overflow-x-auto scroll wrapper is always retained.
Flush bool
// StickyHeader, when true, pins the header row to the top of the table's
// scroll container (sticky top-0 + z). Effective when the table scrolls
// vertically — inside a height-constrained wrapper or a scrollable
// ancestor (the built-in overflow-x-auto wrapper counts as a scroll
// container). Harmless no-op on short tables.
StickyHeader bool
// CellPadding controls the vertical density of header and body cells.
// Defaults to TableCellPaddingComfortable (px-4 py-3). Set to
// TableCellPaddingCompact (px-4 py-2) for data-heavy dashboards and admin
// panels where rows should feel tighter.
CellPadding TableCellPadding
// LazyRows, when true, applies content-visibility: auto to body rows.
// The browser skips rendering off-screen rows, giving 2-5x faster initial
// render for tables with 100+ rows. Uses contain-intrinsic-size so the
// scrollbar stays accurate. Recommended for large data tables.
LazyRows bool
// Body, when set, overrides Rows for the <tbody> content. The component
// should render <tr> elements directly — ideal for templ loops where each
// row needs custom cell rendering:
//
// @display.Table(display.TableProps{
// Headers: headers,
// Body: messageRows(messages),
// })
// templ messageRows(messages []Message) {
// for _, m := range messages {
// <tr><td>{ m.Text }</td><td>{ m.Author }</td></tr>
// }
// }
Body templ.Component
// BodyID, when non-empty, sets the id attribute on the <tbody> element.
// Use on live-updating dashboards whose scripts swap rows without
// querying the table's internal structure — so a markup refactor inside
// the table cannot break the script's selector.
BodyID string
}
TableProps configures a data table
func DefaultTableProps ¶
func DefaultTableProps() TableProps
DefaultTableProps returns sensible defaults
type TableRow ¶
type TableRow struct {
Cells []TableCell
// Href, when non-empty, makes the entire row clickable. The row gets
// data-tc-row-href, role="link", tabindex="0", and cursor-pointer.
Href string
// Class, when set, is merged onto the row's <tr> (consumer classes last,
// tailwind-merge resolves conflicts). Use it for per-row styling — e.g.
// a hover treatment on a Body-less table without flipping Table.Hover
// for every row, or a status tint on specific rows — without the
// dummy-Href hack of borrowing the clickable-row styling.
Class string
}
TableRow represents a single row in a table. When Href is set, the row becomes clickable (navigates on click/Enter). A CSP-safe singleton script handles click delegation and keyboard navigation. Clicks on interactive elements inside the row (links, buttons) are not hijacked.
func SimpleTableRow ¶
SimpleTableRow creates a row from string values for convenience
type TabsProps ¶
type TabsProps struct {
utils.BaseProps
Tabs []Tab
ActiveTabID string
Variant TabsVariant
ClientSide bool
// Wire, when set, switches the tabs from client-side toggling to
// SERVER-side switching: each tab link carries the wired action with the
// URL's `{tab}` placeholder substituted by that tab's ID (the same
// URL-template convention as the Calendar MonthNav `{year}`/`{month}`),
// and the endpoint re-renders the WHOLE Tabs component with the new
// ActiveTabID. Under htmx the action self-replaces the container with
// `outerHTML settle:0s` (the Calendar re-bind-window rationale: without
// settle, rapid tab clicks land in htmx's ~20ms processing window and
// silently no-op); under Datastar targeting is response-driven
// (wire.Handler) or id-matched — give the fragment root the Tabs' id.
// An empty Wire.Target defaults to the component's own `#ID` when ID is
// set. Wire is nil-safe inert: an empty URL wires nothing. ClientSide is
// ignored when Wire is set (one switching model at a time); the anchors'
// hash hrefs remain as the no-JS fallback, so the clone sets
// PreventDefault (the Datastar runtime auto-prevents only form+submit).
Wire *wire.Action
}
TabsProps configures a tab component
func DefaultTabsProps ¶
func DefaultTabsProps() TabsProps
DefaultTabsProps returns sensible defaults
type TabsVariant ¶
type TabsVariant string
TabsVariant defines the visual style of tabs
const ( TabsDefault TabsVariant = "default" TabsPills TabsVariant = "pills" )
type TextAlign ¶ added in v1.8.2
type TextAlign string
TextAlign defines the horizontal alignment of a SectionHeading.
type TooltipPosition ¶
type TooltipPosition = Position
TooltipPosition is an alias of Position: where a Tooltip appears relative to its trigger.
type TooltipProps ¶
type TooltipProps struct {
utils.BaseProps
Text string
Position TooltipPosition
}
TooltipProps configures a tooltip component.
The tooltip shows on :hover and :focus-within via pure CSS. A tiny singleton script (tooltipAriaScriptComponent) propagates aria-describedby from the non-focusable wrapper <div> to the first focusable child so screen readers announce the tooltip text on focus.
func DefaultTooltipProps ¶
func DefaultTooltipProps() TooltipProps
DefaultTooltipProps returns sensible defaults
type TrendDirection ¶
type TrendDirection string
TrendDirection represents the direction of a stat change
const ( TrendUp TrendDirection = "up" TrendDown TrendDirection = "down" TrendWarn TrendDirection = "warn" TrendNone TrendDirection = "none" )
func (TrendDirection) Tone ¶ added in v1.24.0
func (t TrendDirection) Tone() tone.Tone
Tone maps TrendDirection onto the canonical semantic axis.
Source Files
¶
- accordion_templ.go
- area_chart.go
- area_chart_templ.go
- avatar_templ.go
- badge_templ.go
- bar_chart.go
- bar_chart_templ.go
- button_go.go
- button_templ.go
- card_templ.go
- carousel_go.go
- carousel_templ.go
- chart_geometry.go
- chart_shared_templ.go
- code_block.go
- code_block_templ.go
- collapsible_section.go
- collapsible_section_templ.go
- command_palette.go
- command_palette_templ.go
- context_menu_templ.go
- copy_button_templ.go
- count_badge_templ.go
- data_state.go
- data_state_templ.go
- date_range_templ.go
- definition_grid_templ.go
- definition_list_templ.go
- doc.go
- drawer_go.go
- drawer_templ.go
- dropdown_templ.go
- empty_state_templ.go
- enums_go.go
- external_link.go
- external_link_templ.go
- eyebrow_templ.go
- grid_templ.go
- heading_tag.go
- heatmap.go
- heatmap_templ.go
- hover_card_templ.go
- image_templ.go
- kanban.go
- kanban_templ.go
- lightbox.go
- lightbox_templ.go
- line_chart.go
- line_chart_templ.go
- list_note_templ.go
- loading_dialog_templ.go
- modal_go.go
- modal_templ.go
- page_header_templ.go
- pie_chart.go
- pie_chart_templ.go
- popover_templ.go
- position.go
- prose.go
- prose_templ.go
- relative_time_templ.go
- scrollback_templ.go
- section_heading_templ.go
- segment_bar.go
- segment_bar_templ.go
- shared.go
- shared_templ.go
- sparkline.go
- sparkline_templ.go
- status_dot.go
- status_dot_templ.go
- table_data_templ.go
- table_templ.go
- tabs_templ.go
- tone_adapters.go
- tooltip_templ.go