datatable

package
v0.1.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 30, 2026 License: MIT Imports: 8 Imported by: 1

Documentation

Overview

Package datatable provides a sortable data table widget with fixed header, virtualized rows, and column-level configuration.

Construction uses functional options for immutable configuration:

dt := datatable.New(
    datatable.Columns([]datatable.Column{
        {Key: "name", Title: "Name", Width: 200, Sortable: true},
        {Key: "size", Title: "Size", Width: 100, Sortable: true, Align: widget.TextAlignRight},
        {Key: "date", Title: "Modified", Width: 150, Sortable: true},
    }),
    datatable.RowCount(1000),
    datatable.CellValue(func(row int, col string) string {
        return data[row][col]
    }),
)

Fixed Header

The header row is always visible at the top, showing column titles and sort indicators (ascending/descending arrows). Clicking a sortable column header cycles through: none -> ascending -> descending -> none.

Virtualization

Only rows visible in the viewport are rendered. The table composes an internal scrollview.Widget for vertical scrolling. This allows efficient display of thousands of rows without performance degradation.

Selection

Optional row selection is supported via OnRowSelect and SelectedRow or SelectedRowSignal:

Signal Binding

Table properties can be bound to reactive signals from the state package.

Visual Style

Rendering of table-specific elements (header, row backgrounds, sort indicators, selection highlights) is delegated to a Painter implementation. Each design system supplies its own painter.

If no painter is set, DefaultPainter is used.

Accessibility

DataTable implements a11y.Accessible with a11y.RoleTable. Keyboard navigation with Up/Down moves selection, Home/End jump to first/last row.

Focus

DataTable implements widget.Focusable and participates in tab navigation.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CellPaintState

type CellPaintState struct {
	// Bounds is the cell's bounding rectangle.
	Bounds geometry.Rect

	// Value is the cell's text content.
	Value string

	// Align is the column text alignment.
	Align widget.TextAlign

	// RowIndex is the zero-based row index.
	RowIndex int

	// ColIndex is the zero-based column index.
	ColIndex int

	// Selected is true if the parent row is selected.
	Selected bool

	// Disabled is true if the table is disabled.
	Disabled bool

	// ColorScheme provides theme-derived colors.
	ColorScheme TableColorScheme
}

CellPaintState provides context for a single data cell.

type Column

type Column struct {
	// Key is the unique identifier for this column, used in CellValue and OnSort callbacks.
	Key string

	// Title is the display text shown in the header row.
	Title string

	// Width is the fixed column width in logical pixels. 0 means auto (flex).
	Width float32

	// MinWidth is the minimum column width for auto-sized columns.
	// Ignored when Width > 0. Default: 50.
	MinWidth float32

	// Sortable enables click-to-sort on this column's header.
	Sortable bool

	// Align controls horizontal text alignment for cells in this column.
	// Default: TextAlignLeft.
	Align widget.TextAlign
}

Column describes a single column in the data table.

Each column has a unique Key used to identify it in callbacks (CellValue, OnSort). Width and MinWidth control sizing; if Width is 0 the column receives equal share of remaining space after fixed-width columns are allocated.

type DefaultPainter

type DefaultPainter struct{}

DefaultPainter provides a minimal fallback painter with no design system styling.

func (DefaultPainter) PaintCell

func (p DefaultPainter) PaintCell(canvas widget.Canvas, cps CellPaintState)

PaintCell draws a single data cell with text.

func (DefaultPainter) PaintEmptyState

func (p DefaultPainter) PaintEmptyState(canvas widget.Canvas, bounds geometry.Rect)

PaintEmptyState draws a centered "No data" message.

func (DefaultPainter) PaintHeader

func (p DefaultPainter) PaintHeader(canvas widget.Canvas, bounds geometry.Rect, hps HeaderPaintState)

PaintHeader draws the header background.

func (DefaultPainter) PaintHeaderCell

func (p DefaultPainter) PaintHeaderCell(canvas widget.Canvas, bounds geometry.Rect, hcs HeaderCellPaintState)

PaintHeaderCell draws a column header with title and sort indicator.

func (DefaultPainter) PaintRow

func (p DefaultPainter) PaintRow(canvas widget.Canvas, rps RowPaintState)

PaintRow draws the row background with zebra striping and selection/hover highlights.

type HeaderCellPaintState

type HeaderCellPaintState struct {
	// Title is the column display text.
	Title string

	// Align is the column text alignment.
	Align widget.TextAlign

	// Sortable is true if this column supports sorting.
	Sortable bool

	// SortDir is the current sort direction for this column.
	SortDir SortDirection

	// Hovered is true if the mouse is over this header cell.
	Hovered bool

	// Disabled is true if the table is disabled.
	Disabled bool

	// ColorScheme provides theme-derived colors.
	ColorScheme TableColorScheme
}

HeaderCellPaintState provides context for a single header cell.

type HeaderPaintState

type HeaderPaintState struct {
	// Disabled is true if the table is disabled.
	Disabled bool

	// ColorScheme provides theme-derived colors.
	ColorScheme TableColorScheme
}

HeaderPaintState provides context for header background painting.

type Option

type Option func(*config)

Option configures a data table during construction.

func A11yLabel

func A11yLabel(label string) Option

A11yLabel sets the accessibility label for the table.

func CellValue

func CellValue(fn func(row int, col string) string) Option

CellValue sets the callback that provides cell text for a given row and column key.

func Columns

func Columns(cols []Column) Option

Columns sets the column definitions.

func Disabled

func Disabled(d bool) Option

Disabled sets the table's disabled state.

func DisabledFn

func DisabledFn(fn func() bool) Option

DisabledFn sets a dynamic function for the disabled state.

func DisabledReadonlySignal

func DisabledReadonlySignal(sig state.ReadonlySignal[bool]) Option

DisabledReadonlySignal binds the disabled state to a read-only signal.

func DisabledSignal

func DisabledSignal(sig state.Signal[bool]) Option

DisabledSignal binds the disabled state to a reactive signal.

func OnRowSelect

func OnRowSelect(fn func(row int)) Option

OnRowSelect sets the callback invoked when a row is selected.

func OnScroll

func OnScroll(fn func(offset float32)) Option

OnScroll sets the callback invoked when the scroll position changes.

func OnSort

func OnSort(fn func(col string, ascending bool)) Option

OnSort sets the callback invoked when a column sort changes. The ascending parameter indicates the new sort direction (true=asc, false=desc). The callback is NOT invoked when sort is cleared (direction returns to None).

func PainterOpt

func PainterOpt(p Painter) Option

PainterOpt sets the painter used to render table visuals.

func RowCount

func RowCount(n int) Option

RowCount sets the total number of data rows.

func RowCountFn

func RowCountFn(fn func() int) Option

RowCountFn sets a dynamic function that returns the row count.

func RowCountReadonlySignal

func RowCountReadonlySignal(sig state.ReadonlySignal[int]) Option

RowCountReadonlySignal binds the row count to a read-only signal.

func RowCountSignal

func RowCountSignal(sig state.Signal[int]) Option

RowCountSignal binds the row count to a reactive signal.

func RowHeight

func RowHeight(h float32) Option

RowHeight sets the height of each data row in logical pixels. Default: 32.

func ScrollYSignal

func ScrollYSignal(sig state.Signal[float32]) Option

ScrollYSignal binds the vertical scroll offset to a reactive signal (TWO-WAY).

func SelectedRow

func SelectedRow(row int) Option

SelectedRow sets the initially selected row index. Use -1 for no selection.

func SelectedRowReadonlySignal

func SelectedRowReadonlySignal(sig state.ReadonlySignal[int]) Option

SelectedRowReadonlySignal binds the selected row to a read-only signal.

func SelectedRowSignal

func SelectedRowSignal(sig state.Signal[int]) Option

SelectedRowSignal binds the selected row to a reactive signal. TWO-WAY binding: reads from signal, writes back on user selection.

func SelectionModeOpt

func SelectionModeOpt(mode SelectionMode) Option

SelectionModeOpt sets the row selection mode. Default: SelectionNone.

type Painter

type Painter interface {
	// PaintHeader draws the table header background.
	PaintHeader(canvas widget.Canvas, bounds geometry.Rect, state HeaderPaintState)

	// PaintHeaderCell draws a single header cell (column title + sort indicator).
	PaintHeaderCell(canvas widget.Canvas, bounds geometry.Rect, state HeaderCellPaintState)

	// PaintRow draws the background for a data row.
	PaintRow(canvas widget.Canvas, state RowPaintState)

	// PaintCell draws a single data cell.
	PaintCell(canvas widget.Canvas, state CellPaintState)

	// PaintEmptyState draws the empty state when RowCount is 0.
	PaintEmptyState(canvas widget.Canvas, bounds geometry.Rect)
}

Painter draws table-specific visual elements. Each design system (Material 3, Fluent, Cupertino) provides its own Painter implementation to render the table in its visual style.

If no Painter is set, the data table uses DefaultPainter.

type RowPaintState

type RowPaintState struct {
	// Bounds is the row's bounding rectangle.
	Bounds geometry.Rect

	// RowIndex is the zero-based row index in the data source.
	RowIndex int

	// Selected is true if this row is selected.
	Selected bool

	// Focused is true if this row has focus within the table.
	Focused bool

	// Hovered is true if the mouse is over this row.
	Hovered bool

	// Disabled is true if the table is disabled.
	Disabled bool

	// ColorScheme provides theme-derived colors.
	ColorScheme TableColorScheme
}

RowPaintState provides context for row background painting.

type SelectionMode

type SelectionMode uint8

SelectionMode defines how rows can be selected in the table.

const (
	// SelectionNone disables row selection. This is the default.
	SelectionNone SelectionMode = iota

	// SelectionSingle allows at most one row to be selected at a time.
	SelectionSingle

	// SelectionMulti allows multiple rows to be selected (Ctrl+click).
	SelectionMulti
)

SelectionMode constants.

func (SelectionMode) String

func (m SelectionMode) String() string

String returns a human-readable name for the selection mode.

type SortDirection

type SortDirection uint8

SortDirection represents the sort state of a column.

const (
	// SortNone means the column is not sorted.
	SortNone SortDirection = iota

	// SortAscending sorts the column in ascending order.
	SortAscending

	// SortDescending sorts the column in descending order.
	SortDescending
)

SortDirection constants.

func (SortDirection) Indicator

func (d SortDirection) Indicator() string

Indicator returns the unicode arrow character for the sort direction. Returns an empty string for SortNone.

func (SortDirection) String

func (d SortDirection) String() string

String returns a human-readable name for the sort direction.

type TableColorScheme

type TableColorScheme struct {
	HeaderBackground widget.Color // header row background
	HeaderText       widget.Color // header text color
	RowBackground    widget.Color // normal row background
	RowAlternate     widget.Color // alternate row background (zebra)
	SelectionColor   widget.Color // selected row background
	HoverColor       widget.Color // hovered row background
	FocusColor       widget.Color // focused row border
	CellText         widget.Color // cell text color
	Divider          widget.Color // column/row divider color
	EmptyText        widget.Color // empty state text color
}

TableColorScheme provides theme-derived colors for table painting. Zero value means the painter should use its built-in defaults.

type Widget

type Widget struct {
	widget.WidgetBase
	// contains filtered or unexported fields
}

Widget implements a sortable data table with fixed header, virtualized rows, and pluggable painting.

A data table is created with New using functional options:

dt := datatable.New(
    datatable.Columns(cols),
    datatable.RowCount(1000),
    datatable.CellValue(valueFn),
)

func New

func New(opts ...Option) *Widget

New creates a new data table Widget with the given options.

The returned widget is visible, enabled, and focusable by default.

func (*Widget) AccessibilityActions

func (w *Widget) AccessibilityActions() []a11y.Action

AccessibilityActions returns the list of supported actions.

func (*Widget) AccessibilityHint

func (w *Widget) AccessibilityHint() string

AccessibilityHint returns the accessibility hint.

func (*Widget) AccessibilityLabel

func (w *Widget) AccessibilityLabel() string

AccessibilityLabel returns the accessibility label.

func (*Widget) AccessibilityRole

func (w *Widget) AccessibilityRole() a11y.Role

AccessibilityRole returns the ARIA role for this widget.

func (*Widget) AccessibilityState

func (w *Widget) AccessibilityState() a11y.State

AccessibilityState returns the current accessibility state.

func (*Widget) AccessibilityValue

func (w *Widget) AccessibilityValue() string

AccessibilityValue returns the current table state as a string.

func (*Widget) Children

func (w *Widget) Children() []widget.Widget

Children returns the internal scroll view as the single child.

func (*Widget) Draw

func (w *Widget) Draw(ctx widget.Context, canvas widget.Canvas)

Draw renders the data table.

func (*Widget) Event

func (w *Widget) Event(ctx widget.Context, e event.Event) bool

Event handles an input event and returns true if consumed.

func (*Widget) GetRowCount

func (w *Widget) GetRowCount() int

GetRowCount returns the current row count.

func (*Widget) InvalidateData

func (w *Widget) InvalidateData()

InvalidateData signals that the underlying data has changed.

func (*Widget) IsFocusable

func (w *Widget) IsFocusable() bool

IsFocusable reports whether the table can currently receive focus.

func (*Widget) IsRowSelected

func (w *Widget) IsRowSelected(row int) bool

IsRowSelected reports whether the given row is selected.

func (*Widget) Layout

func (w *Widget) Layout(ctx widget.Context, constraints geometry.Constraints) geometry.Size

Layout calculates the table's size within the given constraints.

func (*Widget) Mount

func (w *Widget) Mount(ctx widget.Context)

Mount creates signal bindings for push-based invalidation.

func (*Widget) ScrollToRow

func (w *Widget) ScrollToRow(row int)

ScrollToRow scrolls to make the given row visible.

func (*Widget) SetSort

func (w *Widget) SetSort(colKey string, dir SortDirection)

SetSort programmatically sets the sort column and direction. Pass an empty key or SortNone to clear sorting.

func (*Widget) SortColumn

func (w *Widget) SortColumn() (string, SortDirection)

SortColumn returns the currently sorted column key and direction. Returns empty string and SortNone if no column is sorted.

func (*Widget) Unmount

func (w *Widget) Unmount()

Unmount is called when the table is removed from the widget tree.

func (*Widget) VisibleRowRange

func (w *Widget) VisibleRowRange() (start, end int)

VisibleRowRange returns the indices of currently visible rows [start, end).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL