Skip to content

v0.9.0 — 8 new widgets, +15% surface (Wave 3 finishing pass)

Choose a tag to compare

@tannevaled tannevaled released this 06 Jul 09:53

Additive-only bump: 54 → 62 widgets. Every existing consumer keeps working unchanged.

Wave 3 (finishing pass) of the GTK / DaisyUI gap-closure campaign. Same recipe as v0.7.0 / v0.8.0: Base embedding, Draw(painter.Painter, *Theme), existing fillRect/strokeRect/DrawText helpers, theme.Extra["OnAccent"] fallback pattern.

Buttons

  • SplitButton — primary action button with an attached arrow slot; independent OnClick (main) and OnArrow (menu) callbacks, SplitButtonArrowW = 20 visual separator; Arrow = false collapses to a wide accent button.
  • IconButton — compact single-glyph button for toolbars. Distinct from Button (has text) and ToggleButton (has toggle state). Rendered subtly on theme.Surface with a Border stroke, not on Accent — the toolbar-icon convention.

Data display

  • Stat — DaisyUI-style KPI card: dim Title on top, big Value in the middle (double-stroked to fake bold weight — a testable visible signal), Change at the bottom with color derived from StatTrend (StatFlat/StatUp/StatDown, fixed RGB per trend).
  • Timeline — vertical event log: rail line in theme.Border, per-event colored marker (TimelineDefault/TimelineSuccess/TimelineWarning/TimelineError — mirrors Alert's fixed RGBs), Title next to the marker, optional dim Detail line below.

Interactive

  • DropZone — inline "drag files here" target with a dashed border (rendered as a series of short filled rects along each edge — the same abstraction level as the rest of the toolkit) + Hover state that recolors border in Accent on drag-over. OnDrop fires with []string{ev.Code} on synthetic EventChar with Hover = true (host convention).
  • Chip — removable tag: Text + optional close-x affordance. Closable = true reserves a right-side hit slot; EventMouseDown in that slot fires OnClose. Sibling to Badge (which is a counter/status pill with no close).

Composables

  • FormFieldLabel above a Child widget, with mutually-exclusive Help (dim caption in theme.Border) or Error (fixed red) below. Error takes precedence over Help when both are set. Events forward to Child when (X, Y) falls in its rect.
  • ProgressCircle — approximated circular progress: outer ring in theme.SurfaceAlt ("track"), inner square in theme.Surface ("hole"), fill band scaled by Fraction in theme.Accent, \"XX%\" centered in the hole in theme.OnSurface. Fraction clamps to [0, 1].

Development note

Built in parallel by 4 sub-agents in worktree isolation (/tmp/tk-w3-{a,b,c,d}). Each agent worked in its own fresh clone of v0.8.0; the 4 batches merged verbatim with no naming conflicts across the ~25 new package-level constants and enums, and 100.0% cov end-to-end. Third consecutive wave delivered by this pattern.

Verified

  • go vet ./... clean
  • go test -cover ./...100.0% of statements
  • Cross-compile smoke: js/wasm, linux/arm64, darwin/arm64 all clean
  • CI green

Compatibility

Additive only. No new theme fields, no new external deps beyond github.com/go-widgets/painter. No existing files touched.

To pin:

```go
require github.com/go-widgets/toolkit v0.9.0
```

Coverage now

DaisyUI 4 + libadwaita gap closure is materially complete. Remaining specialized widgets (Split view / DualPane variants, WindowControls, Aboutdialog, Snackbar-with-action) are either already covered by adjacent widgets or fall outside a pure-Go pixel-blitting library's scope.

License

BSD-3-Clause.