Documentation
¶
Overview ¶
Package registry provides a widget registration system for dynamic widget creation.
The registry allows third-party developers to register custom widgets that can be instantiated by name at runtime. This enables dynamic widget creation from configuration files, declarative UI builders, or visual editors.
Quick Start ¶
Register a widget factory during package initialization:
package mywidgets
import "github.com/gogpu/ui/registry"
func init() {
registry.RegisterWidget("my-button", NewMyButton, registry.WidgetInfo{
Name: "my-button",
Description: "Custom button widget",
Category: registry.CategoryInput,
Version: "1.0.0",
})
}
func NewMyButton(config map[string]any) (registry.Widget, error) {
label, _ := config["label"].(string)
return &MyButton{label: label}, nil
}
Create widgets dynamically in your application:
package main
import (
"github.com/gogpu/ui/registry"
_ "github.com/example/mywidgets" // Auto-registers via init()
)
func main() {
// Create widget by name
widget, err := registry.CreateWidget("my-button", map[string]any{
"label": "Click Me",
})
if err != nil {
log.Fatal(err)
}
// List all registered widgets
for _, name := range registry.ListWidgets() {
info, _ := registry.GetWidgetInfo(name)
fmt.Printf("%s (%s): %s\n", info.Name, info.Category, info.Description)
}
}
Thread Safety ¶
The registry is safe for concurrent access. Multiple goroutines can register, create, and query widgets simultaneously without external synchronization.
Categories ¶
Widgets are organized into categories for discoverability:
- CategoryInput: Interactive widgets (buttons, text fields, checkboxes)
- CategoryDisplay: Read-only widgets (labels, images, progress bars)
- CategoryContainer: Widgets that contain other widgets (panels, scroll views)
- CategoryCustom: User-defined widgets that don't fit other categories
Best Practices ¶
Widget factories should:
- Validate all required configuration parameters
- Provide sensible defaults for optional parameters
- Return descriptive errors for invalid configuration
- Initialize widgets to a valid state
Example with validation:
func NewValidatedWidget(config map[string]any) (registry.Widget, error) {
// Validate required parameters
label, ok := config["label"].(string)
if !ok || label == "" {
return nil, fmt.Errorf("label is required and must be a non-empty string")
}
// Optional parameter with default
width, _ := config["width"].(float64)
if width <= 0 {
width = 100 // Default width
}
return &MyWidget{label: label, width: width}, nil
}
Index ¶
- Variables
- func ClearGlobalRegistry()
- func HasWidget(name string) bool
- func ListWidgets() []string
- func ListWidgetsByCategory(category Category) []string
- func MustRegisterWidget(name string, factory WidgetFactory, info ...WidgetInfo)
- func RegisterWidget(name string, factory WidgetFactory, info ...WidgetInfo) error
- func UnregisterWidget(name string) error
- func WidgetCount() int
- type Canvas
- type Category
- type Constraints
- type Context
- type Event
- type Size
- type Widget
- type WidgetFactory
- type WidgetInfo
- type WidgetRegistry
- func (r *WidgetRegistry) AllInfo() []WidgetInfo
- func (r *WidgetRegistry) Clear()
- func (r *WidgetRegistry) Count() int
- func (r *WidgetRegistry) Create(name string, config map[string]any) (Widget, error)
- func (r *WidgetRegistry) Has(name string) bool
- func (r *WidgetRegistry) Info(name string) (WidgetInfo, bool)
- func (r *WidgetRegistry) List() []string
- func (r *WidgetRegistry) ListByCategory(category Category) []string
- func (r *WidgetRegistry) MustRegister(name string, factory WidgetFactory, info ...WidgetInfo)
- func (r *WidgetRegistry) Register(name string, factory WidgetFactory, info ...WidgetInfo) error
- func (r *WidgetRegistry) Unregister(name string) error
Constants ¶
This section is empty.
Variables ¶
var ( // ErrWidgetNotFound is returned when a widget is not registered. ErrWidgetNotFound = errors.New("widget not found") // ErrWidgetExists is returned when attempting to register a duplicate widget. ErrWidgetExists = errors.New("widget already registered") // ErrNilFactory is returned when a nil factory is provided. ErrNilFactory = errors.New("factory cannot be nil") // ErrEmptyName is returned when an empty name is provided. ErrEmptyName = errors.New("widget name cannot be empty") )
Common errors returned by registry operations.
Functions ¶
func ClearGlobalRegistry ¶
func ClearGlobalRegistry()
ClearGlobalRegistry removes all widgets from the global registry.
WARNING: This is primarily intended for testing. Use with caution in production code as it will break any code relying on registered widgets.
func ListWidgets ¶
func ListWidgets() []string
ListWidgets returns all registered widget names from the global registry.
The returned list is sorted alphabetically.
func ListWidgetsByCategory ¶
ListWidgetsByCategory returns widgets in a specific category from the global registry.
The returned list is sorted alphabetically.
func MustRegisterWidget ¶
func MustRegisterWidget(name string, factory WidgetFactory, info ...WidgetInfo)
MustRegisterWidget is like RegisterWidget but panics on failure.
Use this in init() functions where registration failure indicates a programming error that should be caught during development.
func RegisterWidget ¶
func RegisterWidget(name string, factory WidgetFactory, info ...WidgetInfo) error
RegisterWidget adds a widget factory to the global registry.
This is the primary function for registering widgets. Call this from your package's init() function to enable automatic registration on import.
Example:
func init() {
registry.RegisterWidget("my-widget", NewMyWidget, registry.WidgetInfo{
Name: "my-widget",
Description: "A custom widget",
Category: registry.CategoryCustom,
Version: "1.0.0",
})
}
func UnregisterWidget ¶
UnregisterWidget removes a widget from the global registry.
Returns an error if the widget is not registered.
func WidgetCount ¶
func WidgetCount() int
WidgetCount returns the number of registered widgets in the global registry.
Types ¶
type Category ¶
type Category string
Category represents the category of a widget for organization and filtering.
const ( // CategoryInput represents interactive widgets like buttons, text fields, checkboxes. CategoryInput Category = "input" // CategoryDisplay represents read-only widgets like labels, images, progress bars. CategoryDisplay Category = "display" // CategoryContainer represents widgets that contain other widgets like panels, scroll views. CategoryContainer Category = "container" // CategoryCustom represents user-defined widgets that don't fit other categories. CategoryCustom Category = "custom" )
Widget categories for organization and discoverability.
type Constraints ¶
type Constraints = geometry.Constraints
Constraints is an alias for the geometry.Constraints type.
type Widget ¶
Widget is an alias for the widget.Widget interface.
This allows third-party packages to use registry.Widget without importing the widget package directly, simplifying the import graph.
func CreateWidget ¶
CreateWidget creates a widget by name from the global registry.
This is the primary function for creating widgets dynamically. The config parameter is passed to the widget's factory function.
Example:
widget, err := registry.CreateWidget("button", map[string]any{
"label": "Click Me",
"onClick": func() { fmt.Println("Clicked!") },
})
type WidgetFactory ¶
WidgetFactory creates a widget from configuration.
The config parameter is a map of configuration options specific to the widget type. Factories should validate required parameters and provide sensible defaults.
Returns an error if the configuration is invalid or the widget cannot be created.
type WidgetInfo ¶
type WidgetInfo struct {
// Name is the unique identifier used for registration.
Name string
// Description provides a human-readable description of the widget.
Description string
// Category organizes widgets for filtering and discovery.
Category Category
// Version is the semantic version of the widget (e.g., "1.0.0").
Version string
}
WidgetInfo describes a registered widget.
This metadata is used for widget discovery, documentation, and tooling.
func AllWidgetInfo ¶
func AllWidgetInfo() []WidgetInfo
AllWidgetInfo returns information about all registered widgets.
The returned slice is sorted by widget name.
func GetWidgetInfo ¶
func GetWidgetInfo(name string) (WidgetInfo, bool)
GetWidgetInfo returns information about a registered widget.
Returns false as the second value if the widget is not registered.
func (WidgetInfo) Validate ¶
func (i WidgetInfo) Validate() error
Validate checks if the WidgetInfo has all required fields.
type WidgetRegistry ¶
type WidgetRegistry struct {
// contains filtered or unexported fields
}
WidgetRegistry manages widget registration and creation.
The registry maintains a thread-safe collection of widget factories and metadata, allowing dynamic widget creation by name.
Use the package-level functions (RegisterWidget, CreateWidget, etc.) for the global registry, or create a custom registry for testing or isolated use cases.
func GlobalRegistry ¶
func GlobalRegistry() *WidgetRegistry
GlobalRegistry returns the global widget registry instance.
This is useful for advanced use cases where direct access to the registry is needed, such as iterating over all widgets or implementing custom registration logic.
func NewWidgetRegistry ¶
func NewWidgetRegistry() *WidgetRegistry
NewWidgetRegistry creates a new empty WidgetRegistry.
Use this to create an isolated registry for testing or when you need multiple independent registries.
func (*WidgetRegistry) AllInfo ¶
func (r *WidgetRegistry) AllInfo() []WidgetInfo
AllInfo returns a copy of all registered widget information.
The returned slice is sorted by widget name.
func (*WidgetRegistry) Clear ¶
func (r *WidgetRegistry) Clear()
Clear removes all registered widgets.
This is primarily useful for testing to reset the registry state.
func (*WidgetRegistry) Count ¶
func (r *WidgetRegistry) Count() int
Count returns the number of registered widgets.
func (*WidgetRegistry) Create ¶
Create creates a widget by name using its registered factory.
The config parameter is passed to the widget's factory function. Pass nil for widgets that don't require configuration.
Returns ErrWidgetNotFound if no widget is registered with the given name.
func (*WidgetRegistry) Has ¶
func (r *WidgetRegistry) Has(name string) bool
Has returns true if a widget with the given name is registered.
func (*WidgetRegistry) Info ¶
func (r *WidgetRegistry) Info(name string) (WidgetInfo, bool)
Info returns the WidgetInfo for a registered widget.
Returns false as the second value if the widget is not registered.
func (*WidgetRegistry) List ¶
func (r *WidgetRegistry) List() []string
List returns the names of all registered widgets in sorted order.
func (*WidgetRegistry) ListByCategory ¶
func (r *WidgetRegistry) ListByCategory(category Category) []string
ListByCategory returns the names of widgets in the specified category.
The returned list is sorted alphabetically.
func (*WidgetRegistry) MustRegister ¶
func (r *WidgetRegistry) MustRegister(name string, factory WidgetFactory, info ...WidgetInfo)
MustRegister is like Register but panics if registration fails.
This is intended for use in init() functions where registration failure indicates a programming error.
func (*WidgetRegistry) Register ¶
func (r *WidgetRegistry) Register(name string, factory WidgetFactory, info ...WidgetInfo) error
Register adds a widget factory to the registry.
The name must be unique within the registry. If info is provided, it stores metadata about the widget for discovery purposes.
Returns ErrEmptyName if name is empty, ErrNilFactory if factory is nil, or ErrWidgetExists if a widget with the same name is already registered.
func (*WidgetRegistry) Unregister ¶
func (r *WidgetRegistry) Unregister(name string) error
Unregister removes a widget from the registry.
Returns ErrWidgetNotFound if the widget is not registered.