Widgets for displaying text, icons, and images.
Display styled text content.
&widgets.Text{
Data: "Hello, World!",
}Data- Text content to displayStyle- Text style (font, size, color, weight, etc.)
&widgets.Text{
Data: "Simple text",
}style := goflow.NewTextStyle()
style.FontSize = 24.0
style.Color = goflow.NewColor(33, 150, 243, 255) // Blue
style.FontWeight = goflow.FontWeightBold
&widgets.Text{
Data: "Styled text",
Style: style,
}// Create text style
style := goflow.NewTextStyle()
// Font properties
style.FontSize = 16.0 // Font size in pixels
style.FontWeight = goflow.FontWeightNormal // or FontWeightBold
style.FontStyle = goflow.FontStyleNormal // or FontStyleItalic
// Color
style.Color = goflow.NewColor(0, 0, 0, 255)
// Alignment
style.TextAlign = goflow.TextAlignCenter // Left, Center, Right, Justify
// Decoration
style.Decoration = goflow.TextDecorationUnderline // Underline, Overline, LineThroughfunc buildHeading(text string) goflow.Widget {
style := goflow.NewTextStyle()
style.FontSize = 32.0
style.FontWeight = goflow.FontWeightBold
style.Color = goflow.NewColor(0, 0, 0, 255)
return &widgets.Text{
Data: text,
Style: style,
}
}
func buildSubheading(text string) goflow.Widget {
style := goflow.NewTextStyle()
style.FontSize = 20.0
style.FontWeight = goflow.FontWeightBold
style.Color = goflow.NewColor(100, 100, 100, 255)
return &widgets.Text{
Data: text,
Style: style,
}
}
func buildBody(text string) goflow.Widget {
style := goflow.NewTextStyle()
style.FontSize = 16.0
style.Color = goflow.NewColor(0, 0, 0, 255)
return &widgets.Text{
Data: text,
Style: style,
}
}errorStyle := goflow.NewTextStyle()
errorStyle.Color = goflow.NewColor(244, 67, 54, 255) // Red
&widgets.Text{
Data: "Error message",
Style: errorStyle,
}
successStyle := goflow.NewTextStyle()
successStyle.Color = goflow.NewColor(76, 175, 80, 255) // Green
&widgets.Text{
Data: "Success!",
Style: successStyle,
}counter := signals.New(0)
&widgets.Text{
Data: fmt.Sprintf("Count: %d", counter.Get()),
}
// Update text reactively
button := material.NewButton(
&widgets.Text{Data: "Increment"},
func() {
counter.Set(counter.Get() + 1)
},
)Display icons from the Material Icons set.
&widgets.Icon{
Icon: widgets.IconHome,
Size: 24.0,
Color: goflow.NewColor(33, 150, 243, 255),
}Icon- Icon data (from predefined icons)Size- Icon size in pixels (default 24.0)Color- Icon colorSemanticLabel- Accessibility label
widgets.IconHome
widgets.IconMenu
widgets.IconSearch
widgets.IconSettings
widgets.IconFavorite
widgets.IconAdd
widgets.IconRemove
widgets.IconClose
widgets.IconCheck
widgets.IconArrowBack
widgets.IconArrowForward
widgets.IconEdit
widgets.IconDelete
widgets.IconShare
widgets.IconPerson
widgets.IconEmail
widgets.IconPhone
widgets.IconInfo
widgets.IconWarning
widgets.IconErroricon := widgets.NewIcon(widgets.IconHome)icon := widgets.NewIcon(widgets.IconFavorite)
icon.Size = 32.0
icon.Color = goflow.NewColor(244, 67, 54, 255) // Red&widgets.Row{
Children: []goflow.Widget{
widgets.NewIcon(widgets.IconPerson),
&widgets.Text{Data: "Profile"},
},
MainAxisAlignment: widgets.MainAxisCenter,
}func buildStatusIcon(status string) goflow.Widget {
var icon widgets.IconData
var color *goflow.Color
switch status {
case "success":
icon = widgets.IconCheck
color = goflow.NewColor(76, 175, 80, 255) // Green
case "warning":
icon = widgets.IconWarning
color = goflow.NewColor(255, 152, 0, 255) // Orange
case "error":
icon = widgets.IconError
color = goflow.NewColor(244, 67, 54, 255) // Red
default:
icon = widgets.IconInfo
color = goflow.NewColor(33, 150, 243, 255) // Blue
}
iconWidget := widgets.NewIcon(icon)
iconWidget.Size = 48.0
iconWidget.Color = color
return iconWidget
}appBar := material.NewAppBar(&widgets.Text{Data: "My App"})
appBar.Leading = widgets.NewIconButton(widgets.IconMenu, onMenuPressed)
appBar.Actions = []goflow.Widget{
widgets.NewIconButton(widgets.IconSearch, onSearch),
widgets.NewIconButton(widgets.IconSettings, onSettings),
}Button that displays an icon.
See buttons.md#iconbutton for complete documentation.
button := widgets.NewIconButton(
widgets.IconFavorite,
func() {
toggleFavorite()
},
)
button.Color = goflow.NewColor(244, 67, 54, 255)
button.IconSize = 28.0Display images from various sources.
&widgets.Image{
Source: &widgets.AssetImage{Path: "assets/logo.png"},
Width: floatPtr(200.0),
Height: floatPtr(150.0),
Fit: widgets.ImageFitCover,
}Source- Image source (Asset, Network, or File)Fit- How to inscribe the imageWidth- Image width (optional)Height- Image height (optional)SemanticLabel- Accessibility label
AssetImage - Load from bundled assets:
&widgets.AssetImage{
Path: "assets/images/logo.png",
}NetworkImage - Load from URL:
&widgets.NetworkImage{
URL: "https://example.com/image.jpg",
}FileImage - Load from file system:
&widgets.FileImage{
Path: "/path/to/image.png",
}ImageFitFill- Fill the box, distorting aspect ratioImageFitContain- Contain within box, preserving aspect ratioImageFitCover- Cover the box, preserving aspect ratio (crop if needed)ImageFitFitWidth- Fit width, height may overflowImageFitFitHeight- Fit height, width may overflowImageFitNone- No scalingImageFitScaleDown- Scale down if needed, never scale up
image := widgets.NewImage(&widgets.AssetImage{
Path: "assets/profile.jpg",
})
image.Width = floatPtr(100.0)
image.Height = floatPtr(100.0)
image.Fit = widgets.ImageFitCoverimage := widgets.NewImage(&widgets.NetworkImage{
URL: "https://example.com/avatar.jpg",
})
image.Fit = widgets.ImageFitContainfunc buildAvatar(imageURL string, size float64) goflow.Widget {
image := widgets.NewImage(&widgets.NetworkImage{
URL: imageURL,
})
image.Width = &size
image.Height = &size
image.Fit = widgets.ImageFitCover
return &widgets.Container{
Width: &size,
Height: &size,
Decoration: &goflow.BoxDecoration{
BorderRadius: size / 2, // Circular
},
Child: image,
}
}isLoading := signals.New(true)
func buildImageWithLoading(url string) goflow.Widget {
if isLoading.Get() {
return &widgets.Center{
Child: &widgets.Container{
Width: floatPtr(50.0),
Height: floatPtr(50.0),
Child: &widgets.Text{Data: "Loading..."},
},
}
}
return widgets.NewImage(&widgets.NetworkImage{
URL: url,
})
}func buildGallery(imageURLs []string) goflow.Widget {
images := make([]goflow.Widget, len(imageURLs))
for i, url := range imageURLs {
image := widgets.NewImage(&widgets.NetworkImage{
URL: url,
})
image.Fit = widgets.ImageFitCover
images[i] = &widgets.Container{
Width: floatPtr(150.0),
Height: floatPtr(150.0),
Margin: goflow.NewEdgeInsets(8, 8, 8, 8),
Child: image,
}
}
return &widgets.GridView{
Children: images,
CrossAxisCount: 3,
ChildAspectRatio: 1.0,
MainAxisSpacing: 8.0,
CrossAxisSpacing: 8.0,
}
}// ✅ Good - semantic style names
func buildTitle(text string) goflow.Widget {
style := goflow.NewTextStyle()
style.FontSize = 24.0
style.FontWeight = goflow.FontWeightBold
return &widgets.Text{Data: text, Style: style}
}
// ❌ Avoid - hardcoded styles everywhere
&widgets.Text{
Data: "Title",
Style: &goflow.TextStyle{
FontSize: 24.0,
FontWeight: goflow.FontWeightBold,
},
}// ✅ Good - accessible
icon := widgets.NewIcon(widgets.IconHome)
icon.SemanticLabel = "Home"
image := widgets.NewImage(source)
image.SemanticLabel = "User profile picture"// Profile pictures - cover
image.Fit = widgets.ImageFitCover
// Logos - contain
image.Fit = widgets.ImageFitContain
// Banners - fit width
image.Fit = widgets.ImageFitFitWidth// Standard sizes
const (
IconSizeSmall = 18.0
IconSizeMedium = 24.0 // Default
IconSizeLarge = 32.0
IconSizeHuge = 48.0
)var (
ColorPrimary = goflow.NewColor(33, 150, 243, 255)
ColorAccent = goflow.NewColor(255, 64, 129, 255)
ColorError = goflow.NewColor(244, 67, 54, 255)
ColorSuccess = goflow.NewColor(76, 175, 80, 255)
)
&widgets.Text{
Data: "Success!",
Style: &goflow.TextStyle{
Color: ColorSuccess,
},
}// ✅ Good - specify dimensions
image := widgets.NewImage(source)
image.Width = floatPtr(200.0)
image.Height = floatPtr(150.0)
// ❌ Avoid - unbounded images can cause layout issues
image := widgets.NewImage(source)func buildImageWithFallback(url string) goflow.Widget {
if url == "" {
return widgets.NewIcon(widgets.IconPerson)
}
return widgets.NewImage(&widgets.NetworkImage{
URL: url,
})
}// ✅ Good - clear icon for action
widgets.NewIconButton(widgets.IconDelete, onDelete)
// ✅ Also good - icon with label
&widgets.Row{
Children: []goflow.Widget{
widgets.NewIcon(widgets.IconDelete),
&widgets.Text{Data: "Delete"},
},
}// Float pointer helper
func floatPtr(f float64) *float64 {
return &f
}
// Build text with style
func styledText(text string, fontSize float64, color *goflow.Color) goflow.Widget {
style := goflow.NewTextStyle()
style.FontSize = fontSize
style.Color = color
return &widgets.Text{
Data: text,
Style: style,
}
}
// Build circular avatar
func circularImage(source widgets.ImageSource, size float64) goflow.Widget {
image := widgets.NewImage(source)
image.Width = &size
image.Height = &size
image.Fit = widgets.ImageFitCover
return &widgets.Container{
Width: &size,
Height: &size,
Decoration: &goflow.BoxDecoration{
BorderRadius: size / 2,
},
Child: image,
}
}