Widgets that provide the basic structure for applications.
Material Design app structure with AppBar, Body, FAB, Drawer, and more.
&material.Scaffold{
AppBar: material.NewAppBar(&widgets.Text{Data: "My App"}),
Body: &widgets.Center{
Child: &widgets.Text{Data: "Hello, World!"},
},
FloatingActionButton: material.NewFloatingActionButton(
widgets.NewIcon(widgets.IconAdd),
onAdd,
),
Drawer: buildDrawer(),
BottomNavigationBar: buildBottomNav(),
}AppBar- Top app barBody- Main contentFloatingActionButton- FAB widgetFloatingActionButtonLocation- FAB positionDrawer- Side navigation drawerBottomNavigationBar- Bottom navigationBottomSheet- Bottom sheet widgetBackgroundColor- Background colorResizeToAvoidBottomInset- Resize when keyboard appears
FABLocationEndFloat- Bottom right (default)FABLocationCenterFloat- Bottom centerFABLocationStartFloat- Bottom leftFABLocationEndDocked- Docked to bottom bar, rightFABLocationCenterDocked- Docked to bottom bar, center
&material.Scaffold{
AppBar: material.NewAppBar(&widgets.Text{
Data: "Dashboard",
}),
Body: &widgets.ListView{
Children: buildDashboardItems(),
},
FloatingActionButton: material.NewFloatingActionButton(
widgets.NewIcon(widgets.IconAdd),
func() {
showCreateDialog()
},
),
FloatingActionButtonLocation: material.FABLocationEndFloat,
Drawer: buildNavigationDrawer(),
BottomNavigationBar: buildBottomNavigationBar(),
BackgroundColor: goflow.NewColor(250, 250, 250, 255),
}iOS-style page structure.
&cupertino.CupertinoPageScaffold{
NavigationBar: cupertino.NewNavigationBar(&widgets.Text{
Data: "My App",
}),
Child: &widgets.Center{
Child: &widgets.Text{Data: "Hello, iOS!"},
},
}NavigationBar- Top navigation barChild- Main contentBackgroundColor- Background colorResizeToAvoidBottomInset- Resize when keyboard appears
&cupertino.CupertinoPageScaffold{
NavigationBar: cupertino.NewNavigationBar(&widgets.Text{
Data: "Settings",
}),
Child: &widgets.ListView{
Children: buildSettingsItems(),
},
BackgroundColor: cupertino.DefaultLightTheme().BackgroundColor,
}iOS-style tabbed interface.
&cupertino.CupertinoTabScaffold{
TabBar: buildTabBar(),
TabBuilder: func(ctx goflow.BuildContext, index int) goflow.Widget {
switch index {
case 0:
return buildHomeTab()
case 1:
return buildSearchTab()
case 2:
return buildProfileTab()
default:
return &widgets.Container{}
}
},
CurrentIndex: 0,
}TabBar- Tab bar widgetTabBuilder- Function to build tab contentCurrentIndex- Currently active tabBackgroundColor- Background color
currentTab := signals.New(0)
&cupertino.CupertinoTabScaffold{
TabBar: buildTabBar(currentTab),
TabBuilder: func(ctx goflow.BuildContext, index int) goflow.Widget {
tabs := []goflow.Widget{
buildHomeTab(),
buildSearchTab(),
buildProfileTab(),
}
if index < len(tabs) {
return tabs[index]
}
return &widgets.Container{}
},
CurrentIndex: currentTab.Get(),
}Material Design top app bar.
appBar := material.NewAppBar(&widgets.Text{Data: "Title"})
appBar.Leading = widgets.NewIconButton(widgets.IconMenu, onMenuPressed)
appBar.Actions = []goflow.Widget{
widgets.NewIconButton(widgets.IconSearch, onSearch),
widgets.NewIconButton(widgets.IconSettings, onSettings),
}Title- Title widget (usually Text)Leading- Leading widget (usually menu or back button)Actions- Action widgets (usually icon buttons)BackgroundColor- Background colorForegroundColor- Text/icon colorElevation- Shadow elevationHeight- AppBar height (default 56.0)
isSearching := signals.New(false)
appBar := material.NewAppBar(
func() goflow.Widget {
if isSearching.Get() {
return buildSearchField()
}
return &widgets.Text{Data: "My App"}
}(),
)
appBar.Actions = []goflow.Widget{
widgets.NewIconButton(widgets.IconSearch, func() {
isSearching.Set(!isSearching.Get())
}),
}iOS-style navigation bar.
navBar := cupertino.NewNavigationBar(&widgets.Text{Data: "Title"})
navBar.Leading = widgets.NewIconButton(widgets.IconArrowBack, onBack)
navBar.Trailing = widgets.NewIconButton(widgets.IconEdit, onEdit)Middle- Middle widget (title)Leading- Leading widget (back button)Trailing- Trailing widget (action button)BackgroundColor- Background colorBorderColor- Border colorPadding- Internal paddingHeight- Bar height (default 44.0)
Side navigation drawer.
drawer := material.NewDrawer(&widgets.Column{
Children: []goflow.Widget{
material.NewDrawerHeader(&widgets.Column{
Children: []goflow.Widget{
&widgets.Text{Data: "John Doe"},
&widgets.Text{Data: "john@example.com"},
},
}),
material.NewListTile(&widgets.Text{Data: "Home"}),
material.NewListTile(&widgets.Text{Data: "Settings"}),
material.NewListTile(&widgets.Text{Data: "Logout"}),
},
})Child- Drawer contentBackgroundColor- Background colorElevation- Shadow elevationWidth- Drawer width (default 304.0)
func buildDrawer() goflow.Widget {
return material.NewDrawer(&widgets.Column{
Children: []goflow.Widget{
// Header
material.NewDrawerHeader(&widgets.Container{
Padding: goflow.NewEdgeInsets(16, 16, 16, 16),
Child: &widgets.Column{
Children: []goflow.Widget{
&widgets.Icon{
Icon: widgets.IconPerson,
Size: 48.0,
},
&widgets.Text{Data: "John Doe"},
&widgets.Text{Data: "john@example.com"},
},
MainAxisAlign: widgets.MainAxisCenter,
},
}),
// Navigation items
material.NewListTile(&widgets.Row{
Children: []goflow.Widget{
widgets.NewIcon(widgets.IconHome),
&widgets.Text{Data: "Home"},
},
}),
material.NewListTile(&widgets.Row{
Children: []goflow.Widget{
widgets.NewIcon(widgets.IconSettings),
&widgets.Text{Data: "Settings"},
},
}),
// Divider
&widgets.Container{
Height: floatPtr(1.0),
Color: goflow.NewColor(224, 224, 224, 255),
},
material.NewListTile(&widgets.Row{
Children: []goflow.Widget{
widgets.NewIcon(widgets.IconLogout),
&widgets.Text{Data: "Logout"},
},
}),
},
})
}Material Design bottom navigation.
currentIndex := signals.New(0)
bottomNav := material.NewBottomNavigationBar([]material.BottomNavigationBarItem{
{Icon: widgets.IconHome, Label: "Home"},
{Icon: widgets.IconSearch, Label: "Search"},
{Icon: widgets.IconPerson, Label: "Profile"},
})
bottomNav.CurrentIndex = currentIndex.Get()
bottomNav.OnTap = func(index int) {
currentIndex.Set(index)
}Items- Navigation itemsCurrentIndex- Currently selected indexOnTap- Callback when item tappedBackgroundColor- Background colorSelectedItemColor- Selected item colorUnselectedItemColor- Unselected item colorShowSelectedLabels- Show labels for selected itemsShowUnselectedLabels- Show labels for unselected itemsType- Navigation bar typeElevation- Shadow elevation
material.BottomNavigationBarItem{
Icon: widgets.IconHome,
ActiveIcon: &widgets.IconHomeFilled, // Optional
Label: "Home",
BackgroundColor: nil, // Optional
Tooltip: "Go to home", // Optional
}func buildBottomNavigationBar(currentIndex *signals.Signal[int]) goflow.Widget {
items := []material.BottomNavigationBarItem{
{Icon: widgets.IconHome, Label: "Home"},
{Icon: widgets.IconSearch, Label: "Search"},
{Icon: widgets.IconFavorite, Label: "Favorites"},
{Icon: widgets.IconPerson, Label: "Profile"},
}
bottomNav := material.NewBottomNavigationBar(items)
bottomNav.CurrentIndex = currentIndex.Get()
bottomNav.OnTap = func(index int) {
currentIndex.Set(index)
}
bottomNav.SelectedItemColor = goflow.NewColor(33, 150, 243, 255)
return bottomNav
}// Material (Android, Web, Desktop)
&material.Scaffold{
AppBar: appBar,
Body: body,
}
// Cupertino (iOS, macOS)
&cupertino.CupertinoPageScaffold{
NavigationBar: navBar,
Child: body,
}
// Adaptive (Recommended)
func buildPage() goflow.Widget {
if goflow.GetPlatform().IsApple() {
return &cupertino.CupertinoPageScaffold{...}
}
return &material.Scaffold{...}
}// ✅ Good - 3-5 items
items := []material.BottomNavigationBarItem{
{Icon: widgets.IconHome, Label: "Home"},
{Icon: widgets.IconSearch, Label: "Search"},
{Icon: widgets.IconPerson, Label: "Profile"},
}
// ❌ Too many - use drawer instead
items := []material.BottomNavigationBarItem{
// 7 items - overwhelming
}appBar := material.NewAppBar(&widgets.Text{Data: "Details"})
appBar.Leading = widgets.NewIconButton(
widgets.IconArrowBack,
func() {
navigator.Pop()
},
)// ✅ Good - one primary action
fab := material.NewFloatingActionButton(
widgets.NewIcon(widgets.IconAdd),
createNew,
)
// ❌ Avoid - multiple FABs confuse usersfunc buildDrawer() goflow.Widget {
return material.NewDrawer(&widgets.Column{
Children: []goflow.Widget{
// 1. Header
buildDrawerHeader(),
// 2. Primary navigation
buildNavigationItems(),
// 3. Divider
buildDivider(),
// 4. Secondary actions
buildSecondaryActions(),
},
})
}