core
Package core provides the widget and element framework interfaces and lifecycle.
This package defines the foundational types for building reactive user interfaces: Widget, Element, State, and BuildContext. It follows a declarative UI model where widgets describe what the UI should look like, and the framework efficiently updates the actual UI to match.
Core Types
Widget is an immutable description of part of the UI. Widgets are lightweight configuration objects that can be created frequently without performance concerns.
Element is the instantiation of a Widget at a particular location in the tree. Elements manage the lifecycle and identity of widgets.
Stateful Widgets
For widgets that need mutable state, embed StateBase in your state struct:
type myState struct {
core.StateBase
count int
}
func (s *myState) InitState() {
// Initialize state here
}
func (s *myState) Build(ctx core.BuildContext) core.Widget {
return widgets.Text{Content: fmt.Sprintf("Count: %d", s.count)}
}
State Management
ManagedState provides automatic rebuild triggering:
s.count = core.NewManagedState(&s.StateBase, 0)
s.count.Set(s.count.Get() + 1) // Automatically triggers rebuild
Observable provides thread-safe reactive values:
counter := core.NewObservable(0)
core.UseObservable(&s.StateBase, counter) // Subscribe to changes
Hooks
UseController, UseListenable, and UseObservable help manage resources and subscriptions with automatic cleanup on disposal.
Package core provides the core widget and element framework.
Variables
DebugMode controls whether debug information is displayed in error widgets. When true, error widgets show detailed error messages and stack traces. When false, error widgets show minimal information.
var DebugMode = true
func GlobalOffsetOf
func GlobalOffsetOf(element Element) rendering.Offset
GlobalOffsetOf returns the accumulated offset for an element in the render tree.
func SetDebugMode
func SetDebugMode(debug bool)
SetDebugMode enables or disables debug mode for the framework.
func SetErrorWidgetBuilder
func SetErrorWidgetBuilder(builder ErrorWidgetBuilder)
SetErrorWidgetBuilder configures the global error widget builder. Pass nil to restore the default builder.
func UseController
func UseController[C Disposable](base *StateBase, create func() C) C
UseController creates a controller and registers it for automatic disposal. The controller will be disposed when the state is disposed.
Example:
func (s *myState) InitState() {
s.animation = core.UseController(&s.StateBase, func() *animation.AnimationController {
return animation.NewAnimationController(300 * time.Millisecond)
})
}
func UseListenable
func UseListenable(base *StateBase, listenable Listenable)
UseListenable subscribes to a listenable and triggers rebuilds. The subscription is automatically cleaned up when the state is disposed.
Example:
func (s *myState) InitState() {
s.controller = core.UseController(&s.StateBase, func() *MyController {
return NewMyController()
})
core.UseListenable(&s.StateBase, s.controller)
}
func UseObservable
func UseObservable[T any](base *StateBase, obs *Observable[T])
UseObservable subscribes to an observable and triggers rebuilds when it changes. Call this once in InitState(), not in Build(). The subscription is automatically cleaned up when the state is disposed.
Example:
func (s *myState) InitState() {
s.counter = core.NewObservable(0)
core.UseObservable(&s.StateBase, s.counter)
}
func (s *myState) Build(ctx core.BuildContext) core.Widget {
// Use .Value() in Build to read the current value
return widgets.TextOf(fmt.Sprintf("Count: %d", s.counter.Value()), ...)
}
type BuildContext
BuildContext provides access to the element tree during build.
type BuildContext interface {
Widget() Widget
FindAncestor(predicate func(Element) bool) Element
// DependOnInherited finds and depends on an ancestor InheritedWidget of the given type.
// The aspect parameter enables granular dependency tracking: when non-nil, only changes
// affecting that aspect will trigger rebuilds. Pass nil to depend on all changes.
DependOnInherited(inheritedType reflect.Type, aspect any) any
// DependOnInheritedWithAspects is like DependOnInherited but registers multiple aspects
// in a single tree walk. More efficient when depending on multiple aspects.
DependOnInheritedWithAspects(inheritedType reflect.Type, aspects ...any) any
}
type BuildOwner
BuildOwner tracks dirty elements that need rebuilding.
type BuildOwner struct {
// contains filtered or unexported fields
}
func NewBuildOwner
func NewBuildOwner() *BuildOwner
NewBuildOwner creates a new BuildOwner.
func (*BuildOwner) FlushBuild
func (b *BuildOwner) FlushBuild()
FlushBuild rebuilds all dirty elements in depth order.
func (*BuildOwner) NeedsWork
func (b *BuildOwner) NeedsWork() bool
NeedsWork returns true if there are dirty elements or pending layout/paint.
func (*BuildOwner) Pipeline
func (b *BuildOwner) Pipeline() *layout.PipelineOwner
Pipeline returns the PipelineOwner for render object scheduling.
func (*BuildOwner) ScheduleBuild
func (b *BuildOwner) ScheduleBuild(element Element)
ScheduleBuild marks an element as needing rebuild.
type ControllerBase
ControllerBase provides common functionality for controllers. Embed this struct in your controllers to get listener management for free.
Example:
type MyController struct {
core.ControllerBase
value int
}
func (c *MyController) SetValue(v int) {
c.value = v
c.NotifyListeners()
}
type ControllerBase struct {
// contains filtered or unexported fields
}
func (*ControllerBase) AddListener
func (c *ControllerBase) AddListener(fn func()) func()
AddListener adds a callback that fires when NotifyListeners() is called. Returns an unsubscribe function.
func (*ControllerBase) Dispose
func (c *ControllerBase) Dispose()
Dispose clears all listeners and marks the controller as disposed. Override this method if you need custom cleanup, but always call c.ControllerBase.Dispose() in your override.
func (*ControllerBase) IsDisposed
func (c *ControllerBase) IsDisposed() bool
IsDisposed returns true if this controller has been disposed.
func (*ControllerBase) ListenerCount
func (c *ControllerBase) ListenerCount() int
ListenerCount returns the number of registered listeners.
func (*ControllerBase) NotifyListeners
func (c *ControllerBase) NotifyListeners()
NotifyListeners calls all registered listeners. Safe to call after disposal (becomes a no-op).
type Disposable
Disposable is an interface for types that need cleanup.
type Disposable interface {
Dispose()
}
type Element
Element is the instantiation of a Widget at a particular location in the tree.
type Element interface {
Widget() Widget
Mount(parent Element, slot any)
Update(newWidget Widget)
Unmount()
MarkNeedsBuild()
RebuildIfNeeded()
VisitChildren(visitor func(Element) bool)
Depth() int
Slot() any
UpdateSlot(newSlot any)
}
func MountRoot
func MountRoot(root Widget, owner *BuildOwner) Element
MountRoot inflates and mounts the root widget with the provided build owner.
type ErrorBoundaryCapture
ErrorBoundaryCapture is implemented by error boundary elements to capture build errors from descendant widgets.
type ErrorBoundaryCapture interface {
// CaptureError captures a build error from a descendant widget.
// Returns true if the error was captured and handled.
CaptureError(err *errors.BuildError) bool
}
type ErrorWidgetBuilder
ErrorWidgetBuilder creates a fallback widget when a widget build fails. The builder receives the build error and should return a widget to display in place of the failed widget.
type ErrorWidgetBuilder func(err *errors.BuildError) Widget
func GetErrorWidgetBuilder
func GetErrorWidgetBuilder() ErrorWidgetBuilder
GetErrorWidgetBuilder returns the current error widget builder.
type IndexedSlot
IndexedSlot represents a child's position in a multi-child parent.
type IndexedSlot struct {
Index int
PreviousSibling Element
}
type InheritedElement
InheritedElement hosts an InheritedWidget and tracks dependents.
type InheritedElement struct {
// contains filtered or unexported fields
}
func NewInheritedElement
func NewInheritedElement(widget InheritedWidget, owner *BuildOwner) *InheritedElement
NewInheritedElement creates an InheritedElement for the given widget.
func (*InheritedElement) AddDependent
func (e *InheritedElement) AddDependent(dependent Element, aspect any)
AddDependent registers an element as depending on this inherited widget. If aspect is non-nil, it's added to the dependent's aspect set for granular tracking. If aspect is nil, a sentinel is added indicating the widget depends on all changes.
Note: Aspect sets only grow during an element's lifetime. If a widget changes which aspects it depends on across rebuilds, old aspects remain registered. This may cause extra rebuilds but is safe (over-notification, not under-notification).
func (*InheritedElement) DependOnInherited
func (e *InheritedElement) DependOnInherited(inheritedType reflect.Type, aspect any) any
func (*InheritedElement) DependOnInheritedWithAspects
func (e *InheritedElement) DependOnInheritedWithAspects(inheritedType reflect.Type, aspects ...any) any
func (*InheritedElement) FindAncestor
func (e *InheritedElement) FindAncestor(predicate func(Element) bool) Element
func (*InheritedElement) Mount
func (e *InheritedElement) Mount(parent Element, slot any)
func (*InheritedElement) MountWithSelf
func (e *InheritedElement) MountWithSelf(parent Element, slot any, self Element)
MountWithSelf allows a wrapper element to specify itself as the parent for children.
func (*InheritedElement) RebuildIfNeeded
func (e *InheritedElement) RebuildIfNeeded()
func (*InheritedElement) RebuildIfNeededWithSelf
func (e *InheritedElement) RebuildIfNeededWithSelf(self Element)
RebuildIfNeededWithSelf allows a wrapper element to specify itself as the parent.
func (*InheritedElement) RemoveDependent
func (e *InheritedElement) RemoveDependent(dependent Element)
RemoveDependent unregisters an element as depending on this inherited widget.
func (*InheritedElement) RenderObject
func (e *InheritedElement) RenderObject() layout.RenderObject
RenderObject returns the render object from the child element.
func (*InheritedElement) Unmount
func (e *InheritedElement) Unmount()
func (*InheritedElement) Update
func (e *InheritedElement) Update(newWidget Widget)
func (*InheritedElement) VisitChildren
func (e *InheritedElement) VisitChildren(visitor func(Element) bool)
type InheritedWidget
InheritedWidget provides data to descendants without explicit passing. Widgets can depend on an InheritedWidget via BuildContext.DependOnInherited.
type InheritedWidget interface {
Widget
// Child returns the child widget.
Child() Widget
// UpdateShouldNotify returns true if dependents should rebuild
// when this widget is updated.
UpdateShouldNotify(oldWidget InheritedWidget) bool
// UpdateShouldNotifyDependent returns true if a specific dependent should rebuild
// based on the aspects it registered. This enables granular rebuild optimization
// where dependents only rebuild when their specific aspects change.
UpdateShouldNotifyDependent(oldWidget InheritedWidget, aspects map[any]struct{}) bool
}
type Listenable
Listenable is an interface for types that can be listened to. AddListener should return an unsubscribe function.
type Listenable interface {
AddListener(listener func()) func()
}
type ManagedState
ManagedState holds a value and triggers rebuilds when it changes. Unlike Observable, it is tied to a specific StateBase.
ManagedState is NOT thread-safe. It must only be accessed from the UI thread. To update from a background goroutine, use drift.Dispatch:
go func() {
result := doExpensiveWork()
drift.Dispatch(func() {
s.data.Set(result) // Safe - runs on UI thread
})
}()
Example:
type myState struct {
core.StateBase
count *core.ManagedState[int]
}
func (s *myState) InitState() {
s.count = core.NewManagedState(&s.StateBase, 0)
}
func (s *myState) Build(ctx core.BuildContext) core.Widget {
return widgets.GestureDetector{
OnTap: func() { s.count.Set(s.count.Get() + 1) },
Child: widgets.TextOf(fmt.Sprintf("Count: %d", s.count.Get()), ...),
}
}
type ManagedState[T any] struct {
// contains filtered or unexported fields
}
Example:
This example shows how to use ManagedState for automatic rebuilds. ManagedState wraps a value and triggers rebuilds when it changes.
package main
import (
"fmt"
"github.com/go-drift/drift/pkg/core"
)
func main() {
// In a stateful widget's InitState:
//
// func (s *myState) InitState() {
// s.count = core.NewManagedState(&s.StateBase, 0)
// }
//
// In Build:
//
// func (s *myState) Build(ctx core.BuildContext) core.Widget {
// return widgets.GestureDetector{
// OnTap: func() {
// // Set automatically triggers a rebuild
// s.count.Set(s.count.Get() + 1)
// },
// ChildWidget: widgets.Text{
// Content: fmt.Sprintf("Count: %d", s.count.Get()),
// },
// }
// }
// Direct usage for demonstration:
base := &core.StateBase{}
count := core.NewManagedState(base, 0)
// Get the current value
fmt.Printf("Initial: %d\n", count.Get())
// Update using transform function
count.Update(func(v int) int { return v + 10 })
fmt.Printf("After update: %d\n", count.Value())
}
Output
Initial: 0
After update: 10
func NewManagedState
func NewManagedState[T any](base *StateBase, initial T) *ManagedState[T]
NewManagedState creates a new managed state value. Changes to this value will automatically trigger a rebuild.
func (*ManagedState[T]) Get
func (m *ManagedState[T]) Get() T
Get returns the current value.
func (*ManagedState[T]) Set
func (m *ManagedState[T]) Set(value T)
Set updates the value and triggers a rebuild.
func (*ManagedState[T]) Update
func (m *ManagedState[T]) Update(transform func(T) T)
Update applies a transformation to the current value and triggers a rebuild.
func (*ManagedState[T]) Value
func (m *ManagedState[T]) Value() T
Value returns the current value. Alias for Get().
type Notifier
Notifier triggers callbacks when Notify() is called. Unlike Observable, it doesn't hold a value. It is safe for concurrent use.
Notifier implements the Listenable interface, so it can be used with UseListenable.
Example:
refresh := core.NewNotifier()
unsub := refresh.AddListener(func() {
fmt.Println("Refresh triggered!")
})
refresh.Notify() // prints: Refresh triggered!
unsub() // stop listening
type Notifier struct {
// contains filtered or unexported fields
}
Example:
This example shows the Notifier type for event broadcasting. Unlike Observable, Notifier doesn't hold a value.
package main
import (
"fmt"
"github.com/go-drift/drift/pkg/core"
)
func main() {
refresh := core.NewNotifier()
// Add a listener
unsub := refresh.AddListener(func() {
fmt.Println("Refresh triggered!")
})
// Trigger the notification
refresh.Notify()
// Clean up
unsub()
}
Output
Refresh triggered!
func NewNotifier
func NewNotifier() *Notifier
NewNotifier creates a new notifier.
func (*Notifier) AddListener
func (n *Notifier) AddListener(fn func()) func()
AddListener adds a callback that fires when Notify() is called. Returns an unsubscribe function.
func (*Notifier) ListenerCount
func (n *Notifier) ListenerCount() int
ListenerCount returns the number of registered listeners.
func (*Notifier) Notify
func (n *Notifier) Notify()
Notify triggers all registered listeners.
type Observable
Observable holds a value and notifies listeners when it changes. It is safe for concurrent use.
Example:
count := core.NewObservable(0)
unsub := count.AddListener(func(value int) {
fmt.Println("Count changed to:", value)
})
count.Set(5) // prints: Count changed to: 5
unsub() // stop listening
type Observable[T any] struct {
// contains filtered or unexported fields
}
Example:
This example shows how to create an Observable for reactive state. Observable is thread-safe and can be shared across goroutines.
package main
import (
"fmt"
"github.com/go-drift/drift/pkg/core"
)
func main() {
// Create an observable with an initial value
counter := core.NewObservable(0)
// Add a listener that fires when the value changes
unsub := counter.AddListener(func(value int) {
fmt.Printf("Counter changed to: %d\n", value)
})
// Update the value - this triggers all listeners
counter.Set(5)
// Read the current value
current := counter.Value()
fmt.Printf("Current value: %d\n", current)
// Clean up when done
unsub()
}
Output
Counter changed to: 5
Current value: 5
func NewObservable
func NewObservable[T any](initial T) *Observable[T]
NewObservable creates a new observable with the given initial value.
func NewObservableWithEquality
func NewObservableWithEquality[T any](initial T, equalityFunc func(a, b T) bool) *Observable[T]
NewObservableWithEquality creates a new observable with a custom equality function. The equality function is used to determine if the value has changed.
Example:
This example shows how to use Observable with a custom equality function. This is useful when you want to avoid unnecessary updates.
package main
import (
"fmt"
"github.com/go-drift/drift/pkg/core"
)
func main() {
type User struct {
ID int
Name string
}
// Only notify listeners when the user ID changes
user := core.NewObservableWithEquality(User{ID: 1, Name: "Alice"}, func(a, b User) bool {
return a.ID == b.ID
})
user.AddListener(func(u User) {
fmt.Printf("User changed: %s\n", u.Name)
})
// This won't trigger listeners because ID is the same
user.Set(User{ID: 1, Name: "Alice Updated"})
// This will trigger listeners because ID changed
user.Set(User{ID: 2, Name: "Bob"})
}
Output
User changed: Bob
func (*Observable[T]) AddListener
func (o *Observable[T]) AddListener(fn func(T)) func()
AddListener adds a callback that fires whenever the value changes. Returns an unsubscribe function.
func (*Observable[T]) ListenerCount
func (o *Observable[T]) ListenerCount() int
ListenerCount returns the number of registered listeners.
func (*Observable[T]) Set
func (o *Observable[T]) Set(value T)
Set updates the value and notifies all listeners if the value changed. If a custom equality function was provided, it is used to determine if the value changed.
func (*Observable[T]) Update
func (o *Observable[T]) Update(transform func(T) T)
Update applies a transformation to the current value. This is useful for complex updates that depend on the current value.
func (*Observable[T]) Value
func (o *Observable[T]) Value() T
Value returns the current value.
type RenderObjectElement
RenderObjectElement hosts a RenderObject and optional children.
type RenderObjectElement struct {
// contains filtered or unexported fields
}
func NewRenderObjectElement
func NewRenderObjectElement(widget RenderObjectWidget, owner *BuildOwner) *RenderObjectElement
func (*RenderObjectElement) DependOnInherited
func (e *RenderObjectElement) DependOnInherited(inheritedType reflect.Type, aspect any) any
func (*RenderObjectElement) DependOnInheritedWithAspects
func (e *RenderObjectElement) DependOnInheritedWithAspects(inheritedType reflect.Type, aspects ...any) any
func (*RenderObjectElement) FindAncestor
func (e *RenderObjectElement) FindAncestor(predicate func(Element) bool) Element
func (*RenderObjectElement) Mount
func (e *RenderObjectElement) Mount(parent Element, slot any)
func (*RenderObjectElement) RebuildIfNeeded
func (e *RenderObjectElement) RebuildIfNeeded()
func (*RenderObjectElement) RenderObject
func (e *RenderObjectElement) RenderObject() layout.RenderObject
RenderObject exposes the backing render object for the element.
func (*RenderObjectElement) Unmount
func (e *RenderObjectElement) Unmount()
func (*RenderObjectElement) Update
func (e *RenderObjectElement) Update(newWidget Widget)
func (*RenderObjectElement) UpdateSlot
func (e *RenderObjectElement) UpdateSlot(newSlot any)
UpdateSlot updates the slot and notifies the render parent of the move.
func (*RenderObjectElement) VisitChildren
func (e *RenderObjectElement) VisitChildren(visitor func(Element) bool)
type RenderObjectWidget
RenderObjectWidget creates a render object directly.
type RenderObjectWidget interface {
Widget
CreateRenderObject(ctx BuildContext) layout.RenderObject
UpdateRenderObject(ctx BuildContext, renderObject layout.RenderObject)
}
type ScrollOffsetProvider
ScrollOffsetProvider reports a paint-time scroll offset for descendants.
type ScrollOffsetProvider interface {
ScrollOffset() rendering.Offset
}
type State
State holds mutable state for a StatefulWidget.
type State interface {
InitState()
Build(ctx BuildContext) Widget
SetState(fn func())
Dispose()
DidChangeDependencies()
DidUpdateWidget(oldWidget StatefulWidget)
}
type StateBase
StateBase provides common functionality for stateful widget states. Embed this struct in your state to eliminate boilerplate.
Example:
type myState struct {
core.StateBase
count int
}
func (s *myState) InitState() {
// No need to implement SetElement, SetState, Dispose, etc.
}
type StateBase struct {
// contains filtered or unexported fields
}
Example:
This example shows the StateBase type for stateful widgets. Embed StateBase in your state struct to get automatic lifecycle management.
package main
import (
"github.com/go-drift/drift/pkg/core"
)
func main() {
// In a real stateful widget, you would define:
//
// type counterState struct {
// core.StateBase
// count int
// }
//
// func (s *counterState) InitState() {
// s.count = 0
// }
//
// func (s *counterState) Build(ctx core.BuildContext) core.Widget {
// return widgets.GestureDetector{
// OnTap: func() {
// s.SetState(func() {
// s.count++
// })
// },
// ChildWidget: widgets.Text{
// Content: fmt.Sprintf("Count: %d", s.count),
// },
// }
// }
// StateBase provides SetState, OnDispose, and IsDisposed methods
state := &core.StateBase{}
_ = state
}
func (*StateBase) Build
func (s *StateBase) Build(ctx BuildContext) Widget
Build is a no-op default implementation that returns nil. Override this method to build your widget tree.
func (*StateBase) DidChangeDependencies
func (s *StateBase) DidChangeDependencies()
DidChangeDependencies is a no-op default implementation. Override this method to respond to inherited widget changes.
func (*StateBase) DidUpdateWidget
func (s *StateBase) DidUpdateWidget(oldWidget StatefulWidget)
DidUpdateWidget is a no-op default implementation. Override this method to respond to widget configuration changes.
func (*StateBase) Dispose
func (s *StateBase) Dispose()
Dispose cleans up resources. Override this method if you need custom cleanup, but always call s.RunDisposers() or s.StateBase.Dispose() in your override.
func (*StateBase) Element
func (s *StateBase) Element() *StatefulElement
Element returns the element associated with this state. Returns nil if the state has been disposed or not yet mounted.
func (*StateBase) InitState
func (s *StateBase) InitState()
InitState is a no-op default implementation. Override this method to initialize your state.
func (*StateBase) IsDisposed
func (s *StateBase) IsDisposed() bool
IsDisposed returns true if this state has been disposed.
func (*StateBase) OnDispose
func (s *StateBase) OnDispose(cleanup func()) func()
OnDispose registers a cleanup function to be called when the state is disposed. Returns an unregister function that can be called to remove the disposer. The cleanup function will only be called once.
func (*StateBase) RunDisposers
func (s *StateBase) RunDisposers()
RunDisposers executes all registered disposers in reverse order. This is called automatically by Dispose().
func (*StateBase) SetElement
func (s *StateBase) SetElement(element *StatefulElement)
SetElement stores the element reference for triggering rebuilds. This method is called automatically by the framework.
func (*StateBase) SetState
func (s *StateBase) SetState(fn func())
SetState executes the given function and schedules a rebuild. Safe to call even after disposal (becomes a no-op).
SetState is NOT thread-safe. It must only be called from the UI thread. To update state from a background goroutine, use drift.Dispatch.
type StatefulBuilder
StatefulBuilder provides a declarative way to create stateful widgets with full lifecycle support.
Example:
core.StatefulBuilder[int]{
Init: func() int { return 0 },
Build: func(count int, ctx core.BuildContext, setState func(func(int) int)) core.Widget {
return widgets.GestureDetector{
OnTap: func() { setState(func(c int) int { return c + 1 }) },
Child: widgets.TextOf(fmt.Sprintf("Count: %d", count), ...),
}
},
Dispose: func(count int) {
// cleanup resources
},
}.Widget()
type StatefulBuilder[S any] struct {
// Init creates the initial state value. Required.
Init func() S
// Build creates the widget tree. Required.
// The setState function updates the state and triggers a rebuild.
Build func(state S, ctx BuildContext, setState func(func(S) S)) Widget
// Dispose is called when the widget is removed from the tree. Optional.
Dispose func(state S)
// DidChangeDependencies is called when inherited widgets change. Optional.
DidChangeDependencies func(state S, ctx BuildContext)
// DidUpdateWidget is called when the widget configuration changes. Optional.
DidUpdateWidget func(state S, oldWidget StatefulWidget)
// WidgetKey is an optional key for the widget.
WidgetKey any
}
func (StatefulBuilder[S]) Widget
func (b StatefulBuilder[S]) Widget() Widget
Widget returns a Widget that can be used in the widget tree.
type StatefulElement
StatefulElement hosts a StatefulWidget and its State.
type StatefulElement struct {
// contains filtered or unexported fields
}
func NewStatefulElement
func NewStatefulElement(widget StatefulWidget, owner *BuildOwner) *StatefulElement
func (*StatefulElement) DependOnInherited
func (e *StatefulElement) DependOnInherited(inheritedType reflect.Type, aspect any) any
func (*StatefulElement) DependOnInheritedWithAspects
func (e *StatefulElement) DependOnInheritedWithAspects(inheritedType reflect.Type, aspects ...any) any
func (*StatefulElement) FindAncestor
func (e *StatefulElement) FindAncestor(predicate func(Element) bool) Element
func (*StatefulElement) Mount
func (e *StatefulElement) Mount(parent Element, slot any)
func (*StatefulElement) RebuildIfNeeded
func (e *StatefulElement) RebuildIfNeeded()
func (*StatefulElement) RenderObject
func (e *StatefulElement) RenderObject() layout.RenderObject
RenderObject returns the render object from the first render-object child.
func (*StatefulElement) Unmount
func (e *StatefulElement) Unmount()
func (*StatefulElement) Update
func (e *StatefulElement) Update(newWidget Widget)
func (*StatefulElement) VisitChildren
func (e *StatefulElement) VisitChildren(visitor func(Element) bool)
type StatefulWidget
StatefulWidget has mutable state that can change over time.
type StatefulWidget interface {
Widget
CreateState() State
}
type StatelessElement
StatelessElement hosts a StatelessWidget.
type StatelessElement struct {
// contains filtered or unexported fields
}
func NewStatelessElement
func NewStatelessElement(widget StatelessWidget, owner *BuildOwner) *StatelessElement
func (*StatelessElement) DependOnInherited
func (e *StatelessElement) DependOnInherited(inheritedType reflect.Type, aspect any) any
func (*StatelessElement) DependOnInheritedWithAspects
func (e *StatelessElement) DependOnInheritedWithAspects(inheritedType reflect.Type, aspects ...any) any
func (*StatelessElement) FindAncestor
func (e *StatelessElement) FindAncestor(predicate func(Element) bool) Element
func (*StatelessElement) Mount
func (e *StatelessElement) Mount(parent Element, slot any)
func (*StatelessElement) RebuildIfNeeded
func (e *StatelessElement) RebuildIfNeeded()
func (*StatelessElement) RenderObject
func (e *StatelessElement) RenderObject() layout.RenderObject
RenderObject returns the render object from the first render-object child.
func (*StatelessElement) Unmount
func (e *StatelessElement) Unmount()
func (*StatelessElement) Update
func (e *StatelessElement) Update(newWidget Widget)
func (*StatelessElement) VisitChildren
func (e *StatelessElement) VisitChildren(visitor func(Element) bool)
type StatelessWidget
StatelessWidget builds UI without mutable state.
type StatelessWidget interface {
Widget
Build(ctx BuildContext) Widget
}
type Widget
Widget is an immutable description of part of the UI.
type Widget interface {
CreateElement() Element
Key() any
}
func DefaultErrorWidgetBuilder
func DefaultErrorWidgetBuilder(err *errors.BuildError) Widget
DefaultErrorWidgetBuilder returns a placeholder widget when build fails. The actual error widget implementation is in pkg/widgets to avoid circular dependencies. This default returns nil, which signals the framework to use the widgets.ErrorWidget if available.
func Stateful
func Stateful[S any](init func() S, build func(state S, setState func(func(S) S)) Widget) Widget
Stateful creates a stateful widget using generics. For more control over lifecycle callbacks, use StatefulBuilder instead.
Generated by gomarkdoc