{"id":42458316,"url":"https://github.com/gogpu/ui","last_synced_at":"2026-05-16T13:04:17.927Z","repository":{"id":330466992,"uuid":"1110749464","full_name":"gogpu/ui","owner":"gogpu","description":"Pure Go GUI toolkit built on GoGPU — widgets, layouts, styling","archived":false,"fork":false,"pushed_at":"2025-12-25T19:50:44.000Z","size":36,"stargazers_count":16,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-12-27T04:07:44.732Z","etag":null,"topics":["go","golang","gui","ui","webgpu","widgets","zero-cgo"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gogpu.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-05T16:58:07.000Z","updated_at":"2025-12-26T02:21:49.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/gogpu/ui","commit_stats":null,"previous_names":["gogpu/ui"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/gogpu/ui","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gogpu%2Fui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gogpu%2Fui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gogpu%2Fui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gogpu%2Fui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gogpu","download_url":"https://codeload.github.com/gogpu/ui/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gogpu%2Fui/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28843215,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-28T07:39:25.367Z","status":"ssl_error","status_checked_at":"2026-01-28T07:39:24.487Z","response_time":57,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","gui","ui","webgpu","widgets","zero-cgo"],"created_at":"2026-01-28T09:10:12.271Z","updated_at":"2026-05-10T14:59:38.285Z","avatar_url":"https://github.com/gogpu.png","language":"Shell","funding_links":[],"categories":["GUI"],"sub_categories":["Search and Analytic Databases"],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/gogpu/.github/main/assets/logo.png\" alt=\"GoGPU Logo\" width=\"120\" /\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003egogpu/ui\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eEnterprise-Grade GUI Toolkit for Go\u003c/strong\u003e\u003cbr\u003e\n  Modern widgets, reactive state, GPU-accelerated rendering — zero CGO\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/gogpu/ui/actions\"\u003e\u003cimg src=\"https://github.com/gogpu/ui/actions/workflows/ci.yml/badge.svg\" alt=\"CI\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://app.codecov.io/gh/gogpu/ui\"\u003e\u003cimg src=\"https://codecov.io/gh/gogpu/ui/branch/main/graph/badge.svg\" alt=\"Coverage\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://goreportcard.com/report/github.com/gogpu/ui\"\u003e\u003cimg src=\"https://goreportcard.com/badge/github.com/gogpu/ui\" alt=\"Go Report Card\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://pkg.go.dev/github.com/gogpu/ui\"\u003e\u003cimg src=\"https://pkg.go.dev/badge/github.com/gogpu/ui.svg\" alt=\"Go Reference\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/gogpu/ui/releases/latest\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/gogpu/ui?style=flat\u0026label=version\" alt=\"Version\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://go.dev/\"\u003e\u003cimg src=\"https://img.shields.io/badge/Go-1.25+-00ADD8?logo=go\" alt=\"Go Version\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://opensource.org/licenses/MIT\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT-yellow.svg\" alt=\"License\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/gogpu/ui/stargazers\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/gogpu/ui?style=flat\u0026labelColor=555\u0026color=yellow\" alt=\"Stars\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/orgs/gogpu/discussions\"\u003e\u003cimg src=\"https://img.shields.io/badge/Discussions-join-blue\" alt=\"Discussions\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n\u003e **Join the Discussion:** Help shape the future of Go GUI! Share your ideas, report issues, and discuss features at our [GitHub Discussions](https://github.com/orgs/gogpu/discussions/18).\n\n---\n\n## Overview\n\n**gogpu/ui** is an enterprise-grade GUI toolkit for Go, designed for building:\n\n- **IDEs** (GoLand, VS Code class)\n- **Design Tools** (Photoshop, Figma class)\n- **CAD Applications**\n- **Professional Dashboards**\n- **Chrome/Electron Replacement Apps**\n\n### Key Differentiators\n\n| Feature | gogpu/ui | Fyne | Gio |\n|---------|----------|------|-----|\n| **CGO-free** | Yes | No | Yes |\n| **WebGPU rendering** | Yes | OpenGL | Direct GPU |\n| **Reactive state** | Signals | Binding | Events |\n| **Layout engine** | Flexbox + Grid | Custom | Flex |\n| **Accessibility** | Day 1 (ARIA roles) | Limited | Limited |\n| **Plugin system** | Yes | No | No |\n\n---\n\n## Screenshot\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/user-attachments/assets/f67636bc-7426-4865-9269-11e2a81124ad\" alt=\"gogpu/ui Widget Demo\" width=\"600\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\u003cem\u003eexamples/hello — Checkboxes, Radio Buttons, ListView (1000 items), Material Design 3\u003c/em\u003e\u003c/p\u003e\n\n---\n\n## Quick Start\n\n\u003e **Important:** The gogpu ecosystem is **pure Go with zero CGO**. You must set `CGO_ENABLED=0` (the Go default) — do **not** enable CGO.\n\nThe fastest way to get started is to clone and run one of the included examples:\n\n```bash\ngit clone https://github.com/gogpu/ui.git\ncd ui/examples/hello\ngo run .\n```\n\nHere is a minimal example using `desktop.Run` (recommended):\n\n```go\npackage main\n\nimport (\n    \"log\"\n\n    _ \"github.com/gogpu/gg/gpu\"\n    \"github.com/gogpu/gogpu\"\n    \"github.com/gogpu/ui/app\"\n    \"github.com/gogpu/ui/desktop\"\n    \"github.com/gogpu/ui/primitives\"\n    \"github.com/gogpu/ui/widget\"\n)\n\nfunc main() {\n    gogpuApp := gogpu.NewApp(gogpu.DefaultConfig().\n        WithTitle(\"My App\").\n        WithSize(800, 600).\n        WithContinuousRender(false)) // Event-driven: 0% CPU when idle\n\n    uiApp := app.New(\n        app.WithWindowProvider(gogpuApp),\n        app.WithPlatformProvider(gogpuApp),\n        app.WithEventSource(gogpuApp.EventSource()),\n    )\n\n    uiApp.SetRoot(\n        primitives.Box(\n            primitives.Text(\"Hello gogpu/ui!\").\n                FontSize(24).Bold().\n                Color(widget.RGBA8(33, 33, 33, 255)),\n            primitives.Text(\"Enterprise-grade GUI for Go\").\n                FontSize(16).\n                Color(widget.RGBA8(100, 100, 100, 255)),\n        ).Padding(24).Gap(12).Background(widget.RGBA8(255, 255, 255, 255)),\n    )\n\n    if err := desktop.Run(gogpuApp, uiApp); err != nil {\n        log.Fatal(err)\n    }\n}\n```\n\n---\n\n## Packages\n\n### Core (Phase 0)\n\n| Package | Description | Coverage |\n|---------|-------------|----------|\n| `geometry` | Point, Size, Rect, Constraints, Insets | 98.8% |\n| `event` | MouseEvent, KeyEvent, WheelEvent, FocusEvent, Modifiers | 100% |\n| `widget` | Widget, WidgetBase, Context, Canvas, Lifecycle (mount/unmount), SchedulerRef | 100% |\n| `internal/render` | Canvas, SceneCanvas, IconCache (2-level LRU), DPI-aware SVG | 96.5% |\n| `internal/layout` | Flex, Stack, Grid layout engines | 89.9% |\n\n### MVP (Phase 1)\n\n| Package | Description | Coverage |\n|---------|-------------|----------|\n| `a11y` | Accessibility: 35+ ARIA roles, Accessible interface, Tree, Announcer | 99.1% |\n| `state` | Reactive signals, Binding, Scheduler with push-based invalidation | 100% |\n| `primitives` | Box, Text, Image widgets with fluent builder API | 94.4% |\n| `app` | Window integration via gpucontext interfaces (dependency inversion) | 98.6% |\n\n### Extensibility (Phase 1.5)\n\n| Package | Description | Coverage |\n|---------|-------------|----------|\n| `layout` | Public layout API with custom algorithms | 89.5% |\n| `registry` | Widget factory registration for third-party widgets | 100% |\n| `theme` | Theme system with Extensions and Registry | 100% |\n| `plugin` | Plugin bundling with dependency resolution | 99.4% |\n\n### Interactive Widgets (Phase 2 — Complete)\n\n| Package | Description | Coverage |\n|---------|-------------|----------|\n| `cdk` | Component Development Kit — Content[C] polymorphic pattern | 100% |\n| `core/button` | Generic button with pluggable Painter, 4 variants, 3 sizes, signal bindings | 96%+ |\n| `core/checkbox` | Toggleable checkbox with checked/unchecked/indeterminate states, signal bindings | 96%+ |\n| `core/radio` | Mutually exclusive radio group with vertical/horizontal layout, signal bindings | 96%+ |\n| `core/textfield` | Text input with cursor, selection, clipboard, validation, signal bindings | 96%+ |\n| `core/slider` | Slider: continuous/discrete, horizontal/vertical, drag+keyboard, signal bindings | 94.6% |\n| `core/dialog` | Modal dialog: backdrop overlay, action buttons, focus trapping, Alert/Confirm | 96.9% |\n| `core/dropdown` | Dropdown/select with overlay menu, keyboard navigation, signal bindings | 96%+ |\n| `overlay` | Overlay/popup stack, container, position helper | 95%+ |\n| `primitives` | Box, Text, Image, RepaintBoundary (pixel caching + tile-parallel scene.Scene) | 94.4% |\n| `theme/material3` | Material Design 3 — theme (HCT color science) + 21 component painters | 97%+ |\n| `focus` | Keyboard focus management with Tab/Shift+Tab navigation | 95.2% |\n| `internal/focus` | Internal focus manager implementation | 15.2% |\n\n### Phase 3 (Complete)\n\n| Package | Description | Coverage |\n|---------|-------------|----------|\n| `animation` | Animation engine: tween, spring, M3 presets, orchestration (Stagger/Chain/Repeat/Reverse) | 92.3% |\n| `transition` | Widget enter/exit animations: Fade, Slide, Scale effects, Show/Hide wrapper | 98.7% |\n| `core/scrollview` | Scrollable container: vertical/horizontal/both, wheel+keyboard+drag, PushClip/PushTransform, signal bindings | 96.5% |\n| `core/tabview` | Tabbed navigation: lazy content switching, closeable tabs, keyboard nav, Top/Bottom position, signal bindings | 92.1% |\n| `core/listview` | Virtualized list: fixed-height items, recycling, single/multi selection, keyboard nav, M3 painter | 96%+ |\n| `core/gridview` | Virtualized 2D grid: fixed cell size, auto-fit columns, cell recycling, selection, keyboard nav | 92.1% |\n| `core/linechart` | Real-time line chart: multiple series, rolling window, grid, Y-axis labels, thread-safe PushValue | 98.8% |\n| `core/progressbar` | Linear progress bar: 0-100%, rounded corners, label, signal binding, PushClipRoundRect | 99.3% |\n| `core/collapsible` | Expandable section: animated expand/collapse, keyboard focus, arrow indicator, Tween animation | 98.2% |\n| `primitives` | Box (HBox/VBox direction), Text, Image, ThemeScope, RepaintBoundary | 94%+ |\n\n### Phase 4 (In Progress)\n\n| Package | Description | Coverage |\n|---------|-------------|----------|\n| `core/progress` | Circular progress: determinate arc + indeterminate spinner, polyline approximation | 97.4% |\n| `core/popover` | Popover (click) + Tooltip (hover): 12 placements, auto-flip, overlay integration | 97.1% |\n| `core/splitview` | Resizable split panels: draggable divider, min constraints, collapse, handle dots | 96.8% |\n| `core/treeview` | Hierarchical tree: expand/collapse, virtualized rendering, connector lines, keyboard nav | 96%+ |\n| `core/datatable` | Sortable column table: fixed header, virtualized rows, zebra striping, sort indicators | 96%+ |\n| `core/toolbar` | Horizontal action bar: icon buttons, separators, spacers, custom widget items | 96%+ |\n| `core/menu` | MenuBar + ContextMenu: submenus, separators, disabled items, shortcut display | 96%+ |\n| `core/docking` | IDE-style dockable panels: border layout, tabbed groups, Dock/Undock API | 95.3% |\n| `theme/material3` | 21 component painters (all widgets covered) | 97%+ |\n| `theme/devtools` | **JetBrains DevTools**: 22 painters, Int UI gray scale, dark/light, IDE-style | 96%+ |\n| `theme/fluent` | Microsoft Fluent Design: 9 painters, accent colors, inner focus ring, light/dark | 96%+ |\n| `theme/cupertino` | Apple HIG: 9 painters, iOS toggle switch, segmented control, pill buttons | 96%+ |\n| `theme/font` | Font Registry: CSS weight matching (W3C spec), Weight 100-900, Style, Family/Face | 97.7% |\n| `icon` | SVG icons (JetBrains expui), 2-level cache, DPI-aware rasterization, gg/svg renderer | 97%+ |\n| `i18n` | Internationalization: Locale, Bundle, Translator, CLDR plural rules, RTL, LocaleSignal | 97.9% |\n| `dnd` | Drag and drop: DragSource/DropTarget interfaces, Manager, 5px threshold, Escape cancel | 99.3% |\n| `offscreen` | Headless widget rendering: CPU-only `*image.RGBA` output, no GPU/window/app required | 100% |\n| `uitest` | Testing utilities: MockCanvas, MockContext, event factories, widget helpers, assertions | 93.1% |\n| `internal/dirty` | Dirty region tracking: Collector, Tracker, merge algorithm, partial repaints | 100% |\n\n| `compositor` | Layer Tree: OffsetLayer, PictureLayer, ClipRectLayer, OpacityLayer | 95%+ |\n\n**Total: ~170,000+ lines of code | 56+ packages | ~6,800+ tests | 97%+ average coverage**\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                    User Application                         │\n├─────────────────────────────────────────────────────────────┤\n│  theme/material3/  │  theme/devtools/ │  theme/fluent/      │\n│  21 Painters       │  22 Painters     │  9 Painters         │\n│  theme/cupertino/  │                  │                     │\n│  9 Painters        │                  │                     │\n├─────────────────────────────────────────────────────────────┤\n│  22 Interactive Widgets (core/)                             │\n│  button, checkbox, radio, textfield, dropdown, slider,      │\n│  dialog, scrollview, tabview, listview, gridview, linechart,│\n│  progressbar, progress, collapsible, popover, splitview,    │\n│  treeview, datatable, toolbar, menu, docking                │\n├──────────────┬──────────────────────────────────────────────┤\n│  cdk/        │  Content[C] polymorphic pattern              │\n├──────────────┴──────────────────────────────────────────────┤\n│  primitives/       │  animation/     │  transition/         │\n│  Box (HBox/VBox),  │  Tween, Spring  │  Fade, Slide, Scale  │\n│  Text, Image,      │  M3 Presets,    │  Enter/Exit          │\n│  RepaintBoundary   │  Orchestration  │                      │\n├─────────────────────────────────────────────────────────────┤\n│  icon/  │  i18n/  │  dnd/   │  uitest/ │  theme/font/       │\n├─────────────────────────────────────────────────────────────┤\n│  app/ + FocusManager │  focus/ │  overlay/ │  render/       │\n├─────────────────────────────────────────────────────────────┤\n│  desktop/            (Layer Tree Compositor, ADR-007)       │\n│  compositor/         (OffsetLayer, PictureLayer, Compositor)│\n│  offscreen/          (headless widget → *image.RGBA)        │\n├─────────────────────────────────────────────────────────────┤\n│  layout/           │  state/         │  a11y/               │\n│  Flex, Stack, Grid │  Signals, Bind  │  ARIA Roles, Tree    │\n├─────────────────────────────────────────────────────────────┤\n│  registry/         │  plugin/        │  theme/              │\n├─────────────────────────────────────────────────────────────┤\n│  widget/           │  event/         │  geometry/           │\n│  Widget, Context   │  Mouse, Key     │  Point, Rect         │\n│  Canvas, Lifecycle │  Wheel, Focus   │  Constraints         │\n├─────────────────────────────────────────────────────────────┤\n│  internal/render   │  internal/layout│  internal/focus      │\n│  Canvas, Scene,    │  Flex, Grid     │  Manager, Ring       │\n│  IconCache (LRU)   │  internal/dirty │  Tracker, Collector  │\n├─────────────────────────────────────────────────────────────┤\n│  gogpu/gg          │  gpucontext     │  coregx/signals      │\n│  2D Graphics       │  Shared Ifaces  │  State Management    │\n└─────────────────────────────────────────────────────────────┘\n```\n\n### Dependency Principle\n\n```\nui → gpucontext (interfaces)       ← dependency inversion\nui → gg (2D rendering)\nui → coregx/signals (reactive)\n\ngogpu → gpucontext (implements)    ← concrete implementation\ngg → wgpu → naga                   ← internal to gg\n```\n\n**ui never imports gogpu, wgpu, or naga directly.**\n\n---\n\n## Examples\n\n| Example | Description |\n|---------|-------------|\n| [`examples/hello`](examples/hello) | Widget demo: checkbox, radio, ListView (1000 items), M3 theme, event-driven GPU rendering |\n| [`examples/signals`](examples/signals) | Reactive signals: TextSignal, ContentSignal, CheckedSignal, SelectedSignal, DisabledSignal |\n| [`examples/taskmanager`](examples/taskmanager) | Full task manager: charts, tables, animations, real-time data |\n| [`examples/gallery`](examples/gallery) | Widget gallery: all 22 widgets, 4 design systems (M3/DevTools/Fluent/Cupertino), theme switching |\n| [`examples/ide`](examples/ide) | GoLand-inspired IDE layout: DevTools theme, toolbar, tree, tabs, terminal, SVG icons |\n| [`examples/modular-compositor`](examples/modular-compositor) | Multi-module offscreen rendering: clock + notification compositor ([#75](https://github.com/gogpu/ui/issues/75)) |\n\nRun any example:\n\n```bash\ncd examples/gallery\ngo run .\n```\n\n---\n\n## API Examples\n\n### Primitives\n\n```go\n// Box — universal container\nprimitives.Box(children...).\n    Padding(16).\n    PaddingXY(24, 8).\n    Background(theme.Surface).\n    Rounded(8).\n    BorderStyle(1, theme.Outline).\n    ShadowLevel(2).\n    Gap(8)\n\n// Text — static\nprimitives.Text(\"Hello World\").\n    FontSize(24).\n    Bold().\n    Color(theme.OnSurface).\n    Align(primitives.TextAlignCenter).\n    MaxLines(2).\n    Ellipsis()\n\n// Text — reactive (auto-updates when signal changes)\nprimitives.TextFn(func() string {\n    return fmt.Sprintf(\"Count: %d\", count.Get())\n}).FontSize(18)\n\n// Text — signal binding (auto-updates when signal changes)\ntitle := state.NewSignal(\"Hello World\")\nprimitives.NewText(\"\").ContentSignal(title).FontSize(24)\n\n// Image\nprimitives.Image(mySource).\n    Size(48, 48).\n    Cover().\n    Rounded(24).\n    Alt(\"User avatar\")\n```\n\n### Slider\n\n```go\n// Basic slider\ns := slider.New(\n    slider.Min(0),\n    slider.Max(100),\n    slider.Value(50),\n    slider.OnChange(func(v float32) { fmt.Println(\"Value:\", v) }),\n)\n\n// Discrete slider with step snapping and marks\ns := slider.New(\n    slider.Min(0), slider.Max(100), slider.Step(10),\n    slider.Marks([]slider.Mark{{Value: 0}, {Value: 50}, {Value: 100}}),\n    slider.PainterOpt(material3.SliderPainter{Theme: m3}),\n)\n\n// Two-way signal binding\nvolume := state.NewSignal[float32](75)\ns := slider.New(\n    slider.Min(0), slider.Max(100),\n    slider.ValueSignal(volume),  // reads AND writes back on drag\n)\n```\n\n### Dialog\n\n```go\n// Simple alert dialog\nd := dialog.Alert(\"Error\", \"File not found.\", func() { log.Println(\"dismissed\") })\nd.Show(ctx)\n\n// Confirmation dialog\nd := dialog.Confirm(\"Delete?\", \"This cannot be undone.\",\n    func() { log.Println(\"canceled\") },\n    func() { deleteItem() },\n)\nd.Show(ctx)\n\n// Custom dialog with M3 painter\nd := dialog.New(\n    dialog.Title(\"Settings\"),\n    dialog.Content(settingsWidget),\n    dialog.Actions(\n        dialog.Action{Label: \"Cancel\", Variant: dialog.VariantTextOnly},\n        dialog.Action{Label: \"Save\", Variant: dialog.VariantFilled, Default: true,\n            OnClick: func() { saveSettings() }},\n    ),\n    dialog.PainterOpt(material3.DialogPainter{Theme: m3}),\n)\nd.Show(ctx)\n```\n\n### Animation\n\n```go\n// Tween animation with M3 easing\nctrl := animation.NewController()\nopacity := state.NewSignal[float32](0)\nanimation.To(opacity, 1.0).\n    Duration(animation.DurationMedium2).\n    Ease(animation.M3Standard).\n    Start(ctrl)\n\n// Spring physics (critically damped)\nposition := state.NewSignal[float32](0)\nanimation.SpringTo(position, 200).\n    Stiffness(animation.StiffnessMedium).\n    DampingRatio(animation.DampingNoBouncy).\n    Start(ctrl)\n\n// Color tween (Flutter pattern: float32 engine + Tween[T])\nprogress := state.NewSignal[float32](0)\nanimation.To(progress, 1.0).Duration(300*time.Millisecond).Start(ctrl)\ncolorTween := animation.NewColorTween(startColor, endColor)\n// in Draw: canvas.DrawRect(bounds, colorTween.At(progress.Get()))\n\n// Parallel composition\nanimation.Parallel(\n    animation.To(opacity, 1.0).Duration(200*time.Millisecond),\n    animation.To(translateY, 0).Duration(300*time.Millisecond),\n).Start(ctrl)\n```\n\n### ScrollView\n\n```go\n// Basic vertical scrollview\nsv := scrollview.New(longContentWidget,\n    scrollview.DirectionOpt(scrollview.Vertical),\n    scrollview.ScrollbarOpt(scrollview.ScrollbarAuto),\n    scrollview.OnScroll(func(x, y float32) { fmt.Printf(\"scroll: %.0f\\n\", y) }),\n)\n\n// 2D scrollview with signal binding\nscrollY := state.NewSignal[float32](0)\nsv := scrollview.New(largeCanvas,\n    scrollview.DirectionOpt(scrollview.Both),\n    scrollview.ScrollYSignal(scrollY), // two-way binding\n    scrollview.PainterOpt(material3.ScrollbarPainter{Theme: m3}),\n)\n```\n\n### TabView\n\n```go\n// Basic tab view\ntv := tabview.New([]tabview.Tab{\n    {Label: \"Profile\", Content: profileWidget},\n    {Label: \"Settings\", Content: settingsWidget},\n    {Label: \"About\", Content: aboutWidget},\n}, tabview.OnSelect(func(idx int) { fmt.Println(\"Tab:\", idx) }))\n\n// Closeable tabs with M3 painter and signal binding\nselected := state.NewSignal[int](0)\ntv := tabview.New(tabs,\n    tabview.Closeable(true),\n    tabview.SelectedSignalOpt(selected),\n    tabview.PainterOpt(material3.TabViewPainter{Theme: m3}),\n    tabview.OnClose(func(idx int) { removeDynamicTab(idx) }),\n)\n```\n\n### Reactive State\n\n```go\n// Create a signal\nname := state.NewSignal(\"World\")\n\n// Computed value (auto-updates)\ngreeting := state.NewComputed(func() string {\n    return \"Hello, \" + name.Get() + \"!\"\n})\n\n// Bind signal to widget invalidation\nbinding := state.Bind(name, ctx)\ndefer binding.Unbind()\n\n// Batch multiple changes (single re-render)\nscheduler.Batch(func() {\n    firstName.Set(\"Alice\")\n    lastName.Set(\"Smith\")\n    age.Set(30)\n})\n```\n\n### Widget Signal Bindings\n\n```go\n// Bind signals directly to widget properties\nlabel := state.NewSignal(\"Submit\")\ndisabled := state.NewSignal(false)\n\nbtn := button.New(\n    button.TextSignal(label),\n    button.DisabledSignal(disabled),\n    button.OnClick(func() {\n        label.Set(\"Processing...\")\n        disabled.Set(true)\n    }),\n)\n\n// Two-way binding: checkbox state synced with signal\nagreed := state.NewSignal(false)\ncb := checkbox.New(\n    checkbox.CheckedSignal(agreed),\n    checkbox.LabelOpt(\"I agree to terms\"),\n)\n```\n\n### Accessibility\n\n```go\n// Every widget implements a11y.Accessible\nfunc (b *MyButton) AccessibilityRole() a11y.Role   { return a11y.RoleButton }\nfunc (b *MyButton) AccessibilityLabel() string      { return b.text }\nfunc (b *MyButton) AccessibilityActions() []a11y.Action {\n    return []a11y.Action{a11y.ActionClick}\n}\n\n// Accessibility tree with stable node IDs\nroot := a11y.NewNode(a11y.RoleWindow, \"My Application\")\ntree := a11y.NewMemoryTree(root)\nbutton := a11y.NewNode(a11y.RoleButton, \"Save\")  // stable uint64 ID\ntree.Insert(root, button)\n```\n\n### Offscreen Rendering\n\n```go\n// Render widgets to image without GPU, window, or app\nr := offscreen.NewRenderer(400, 120)\nr.Render(primitives.Text(\"Hello, World!\").FontSize(24))\nimg := r.Image() // *image.RGBA — ready for png.Encode, testing, compositing\n\n// HiDPI with dark theme and white background\ndark := material3.NewDark(widget.Hex(0x00BFA5))\nr := offscreen.NewRenderer(800, 240,\n    offscreen.WithTheme(dark),\n    offscreen.WithScale(2.0),\n    offscreen.WithBackground(widget.ColorWhite),\n)\nr.Render(myWidgetTree)\n```\n\n### Window Integration\n\n```go\n// ui connects to windowing via interfaces (not concrete types)\nuiApp := app.New(\n    app.WithWindowProvider(gogpuApp),    // gpucontext.WindowProvider\n    app.WithPlatformProvider(gogpuApp),  // gpucontext.PlatformProvider\n    app.WithTheme(myTheme),\n)\n\nuiApp.SetRoot(rootWidget)\n\n// Headless mode for testing (no window needed)\ntestApp := app.New()  // works without any providers\ntestApp.SetRoot(rootWidget)\ntestApp.Window().Frame()  // processes layout + draw\n```\n\n---\n\n## Implementation Progress\n\n### Phase 0: Foundation ✅\n\n- [x] Geometry types (Point, Size, Rect, Constraints, Insets)\n- [x] Event system (Mouse, Keyboard, Wheel, Focus, Modifiers)\n- [x] Widget interface, WidgetBase, Context, Canvas\n- [x] Layout engines (Flexbox, Stack, Grid)\n- [x] Canvas implementation (gogpu/gg)\n\n### Phase 1: MVP ✅\n\n- [x] Accessibility foundation (35+ ARIA roles, Accessible interface, Tree)\n- [x] Reactive signals integration (coregx/signals, Binding, Scheduler)\n- [x] Basic primitives (Box, Text, Image with fluent API)\n- [x] Window integration (app package via gpucontext interfaces)\n\n### Phase 1.5: Extensibility ✅\n\n- [x] Widget Registry (third-party registration)\n- [x] Public Layout API (custom algorithms)\n- [x] Theme System + Extensions + Registry\n- [x] Plugin System (bundling, dependency resolution)\n\n### Phase 2: Beta ✅\n\n- [x] Button widget (4 variants, 3 sizes, keyboard activation)\n- [x] Checkbox widget (checked/unchecked/indeterminate, pluggable Painter)\n- [x] Radio group widget (vertical/horizontal, arrow key navigation)\n- [x] TextField widget (cursor, selection, clipboard, validation)\n- [x] Dropdown/Select widget (overlay menu, keyboard nav, scroll)\n- [x] Overlay infrastructure (stack, container, position)\n- [x] Material Design 3 theme (HCT color science, 21 painters)\n- [x] Keyboard navigation (focus management, Tab/Shift+Tab, shortcuts)\n- [x] ThemeScope (theme override for widget subtrees)\n- [x] Event-driven rendering (0% CPU when idle)\n- [x] Reactive signal bindings for all widgets (TextSignal, CheckedSignal, SelectedSignal, DisabledSignal, ContentSignal)\n\n### Phase 3: Release Candidate ✅\n\n- [x] Retained-mode rendering: dirty tracking, DrawTree, DrawStats (SP1)\n- [x] RepaintBoundary: per-widget pixel caching (SP2)\n- [x] scene.Scene integration: tile-parallel rendering via SceneCanvas (SP3)\n- [x] Slider widget (continuous/discrete, horizontal/vertical, M3 painter)\n- [x] Dialog/Modal widget (backdrop, actions, focus trapping, M3 painter)\n- [x] Animation engine (Tween, Spring, CubicBezier, M3 motion tokens)\n- [x] Animation presets (M3 motion tokens) + orchestration (Stagger, Chain, Repeat)\n- [x] Transitions: enter/exit animations (Fade, Slide, Scale)\n- [x] ScrollView widget (vertical/horizontal/both, wheel+keyboard+drag)\n- [x] TabView widget (lazy content, closeable tabs, keyboard nav)\n- [x] ListView widget (virtualized list, recycling, single/multi selection, M3 painter)\n- [x] GridView widget (virtualized 2D grid, auto-fit columns, cell recycling)\n- [x] LineChart widget (real-time, multiple series, rolling window)\n- [x] ProgressBar widget (linear, rounded corners, signal binding)\n- [x] Collapsible section widget (animated expand/collapse)\n- [x] Box HBox/VBox direction support\n- [x] Dirty region tracking (internal/dirty)\n- [x] Performance benchmarks (36 across 5 packages)\n\n### Phase 4: Production (v1.0) — In Progress\n\n- [x] Circular progress indicator (determinate arc + indeterminate spinner)\n- [x] SplitView (resizable split panels, draggable divider)\n- [x] Popover/Tooltip (12 placements, auto-flip, overlay)\n- [x] TreeView (hierarchical, expand/collapse, virtualized)\n- [x] DataTable (sortable columns, fixed header, virtualized rows)\n- [x] Toolbar (icon buttons, separators, spacers)\n- [x] Menu system (MenuBar + ContextMenu, submenus, shortcuts)\n- [x] IDE-style docking system (border layout, tabbed groups)\n- [x] Drag \u0026 drop foundation (DragSource, DropTarget, Manager)\n- [x] Fluent Design theme (9 painters, accent colors)\n- [x] Cupertino theme (9 painters, iOS-style)\n- [x] i18n (CLDR plural rules, RTL detection, LocaleSignal)\n- [x] Icon system (vector paths, 10 Material icons, De Casteljau)\n- [x] Font registry (CSS weight matching, W3C spec)\n- [x] Testing utilities (MockCanvas, MockContext, assertions)\n- [x] Dirty region tracking (merge algorithm, partial repaints)\n- [x] Performance benchmarks (36 across 5 packages)\n- [x] Hover tracking (W3C PointerEventSource, HoverTracker, cursor management)\n- [x] ScreenBounds coordinate system (overlay positioning, hit-testing)\n- [x] Event coordinate transforms (ScrollView content-space dispatch)\n- [x] Inter font full Unicode (Cyrillic, Greek, Vietnamese)\n- [x] MeasureText on Canvas (layout calculations without drawing)\n- [x] FocusManager integration in Window (Tab/Shift+Tab navigation)\n- [x] OnTextInput handler (platform character input API)\n- [x] Task Manager example (charts, tables, animations)\n- [x] Widget Gallery example (all widgets, 4 design systems, theme switching)\n- [x] Incremental rendering pipeline (ADR-004): frame skip, persistent pixmap, dirty regions\n- [x] Auto RepaintBoundary in ListView (per-item pixel caching)\n- [x] DrawStats observability (CachedWidgets, DirtyRegionCount)\n- [x] Tracker.Intersects() fast path in RepaintBoundary\n- [x] Centralized ImageCache with LRU eviction (64MB, thread-safe)\n- [x] Offscreen renderer (headless widget → *image.RGBA, no GPU/window)\n- [ ] Platform accessibility adapters (UIA, AT-SPI2, NSAccessibility)\n- [ ] Performance optimization pass\n\n---\n\n## Requirements\n\n| Dependency | Purpose | Status |\n|------------|---------|--------|\n| Go 1.25+ | Language runtime | Required |\n| CGO_ENABLED=0 | Pure Go (no C compiler needed) | Default |\n| [gogpu/gogpu](https://github.com/gogpu/gogpu) | Windowing, input, GPU surface | For examples |\n| [gogpu/gg](https://github.com/gogpu/gg) | 2D graphics rendering | Integrated |\n| [gogpu/gpucontext](https://github.com/gogpu/gpucontext) | Shared interfaces | Integrated |\n| [coregx/signals](https://github.com/coregx/signals) | Reactive state management | Integrated |\n\n\u003e **Note:** The entire ecosystem is pure Go. Do **not** set `CGO_ENABLED=1` — this will cause build errors from the `goffi` package which requires CGO to be disabled.\n\n---\n\n## Installation\n\n```bash\n# UI toolkit (library)\ngo get github.com/gogpu/ui@latest\n\n# For runnable applications you also need gogpu (windowing) and gg (rendering):\ngo get github.com/gogpu/gogpu@latest\ngo get github.com/gogpu/gg@latest\n```\n\n---\n\n## Related Projects\n\n| Project | Description |\n|---------|-------------|\n| [gogpu/gogpu](https://github.com/gogpu/gogpu) | Graphics framework — GPU abstraction, windowing, input |\n| [gogpu/gg](https://github.com/gogpu/gg) | 2D graphics — Canvas API, GPU text |\n| [gogpu/wgpu](https://github.com/gogpu/wgpu) | Pure Go WebGPU — Vulkan, Metal, GLES, Software |\n| [gogpu/naga](https://github.com/gogpu/naga) | Shader compiler — WGSL to SPIR-V, MSL, GLSL |\n\n**Total ecosystem: 800K+ lines of Pure Go** — no CGO, no Rust, no C.\n\n---\n\n## Contributing\n\nContributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\n**Ways to contribute:**\n- Test the packages, report bugs\n- API feedback and suggestions\n- Documentation improvements\n- Spread the word (Reddit, Hacker News, Dev.to)\n- Code contributions (see open issues)\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n---\n\n## Star History\n\n\u003ca href=\"https://star-history.com/#gogpu/ui\u0026Date\"\u003e\n \u003cpicture\u003e\n   \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://api.star-history.com/svg?repos=gogpu/ui\u0026type=Date\u0026theme=dark\" /\u003e\n   \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://api.star-history.com/svg?repos=gogpu/ui\u0026type=Date\" /\u003e\n   \u003cimg alt=\"Star History Chart\" src=\"https://api.star-history.com/svg?repos=gogpu/ui\u0026type=Date\" /\u003e\n \u003c/picture\u003e\n\u003c/a\u003e\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003egogpu/ui\u003c/strong\u003e — Enterprise-grade GUI for Go\u003cbr\u003e\n  \u003csub\u003ePart of the \u003ca href=\"https://github.com/gogpu\"\u003eGoGPU\u003c/a\u003e ecosystem\u003c/sub\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgogpu%2Fui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgogpu%2Fui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgogpu%2Fui/lists"}