flutter_page_scaffold 0.4.1 copy "flutter_page_scaffold: ^0.4.1" to clipboard
flutter_page_scaffold: ^0.4.1 copied to clipboard

A reusable main content area template widget with page titles, section headers, and theme-aware styling.

flutter_page_scaffold #

A reusable Flutter widget package for consistent, theme-aware main content area layouts. Provides structured page templates with bold titles, section headers with accent bars, and grouped content cards.

example

Features #

  • MainAreaTemplate -- Page-level wrapper with large title, description, icon, and action buttons
  • MainAreaSection -- Grouped content card with accent-bar section headers
  • Unified title-tab bar -- Pill-style tabs merged into the title row for compact navigation
  • Card-free mode -- showCard: false for dashboard-style floating layouts
  • Fully theme-aware -- All colors derived from Theme.of(context), works with any ThemeData
  • Zero dependencies -- Only requires Flutter SDK

Installation #

Add to your pubspec.yaml:

dependencies:
  flutter_page_scaffold: ^0.4.0

Then run:

flutter pub get

Usage #

Basic page layout #

import 'package:flutter_page_scaffold/flutter_page_scaffold.dart';

MainAreaTemplate(
  title: 'Network Devices',
  description: 'Manage network switches across all domains.',
  icon: Icons.router,
  actions: [
    FilledButton.icon(
      onPressed: () {},
      icon: const Icon(Icons.add),
      label: const Text('Add'),
    ),
  ],
  child: Column(
    children: [
      MainAreaSection(
        label: 'TOOLBAR',
        child: Row(children: [/* toolbar content */]),
      ),
      const SizedBox(height: 12),
      MainAreaSection(
        label: 'DATA',
        expanded: true,
        child: MyDataTable(),
      ),
    ],
  ),
)

Tabbed page layout (unified bar) #

When tabs is provided, the title and tabs merge into a single unified bar with pill-style tab chips. The description text becomes a tooltip (hover the ? icon).

MainAreaTemplate(
  title: 'Network Manager',
  description: 'Manage network infrastructure.',  // shown as tooltip
  icon: Icons.router,
  actions: [
    FilledButton.icon(
      onPressed: () {},
      icon: const Icon(Icons.add),
      label: const Text('Add Device'),
    ),
  ],
  tabs: [
    PageTab(
      label: 'Devices',
      icon: Icons.table_chart_outlined,
      child: Column(children: [/* device list content */]),
    ),
    PageTab(
      label: 'Settings',
      icon: Icons.settings_outlined,
      child: Column(children: [/* settings content */]),
    ),
  ],
  onTabChanged: (index) => print('Switched to tab $index'),
)

Tab animation and state control #

MainAreaTemplate(
  title: 'Manager',
  maintainState: false,                              // dispose unselected tabs
  tabTransitionDuration: const Duration(milliseconds: 200), // fade animation
  tabs: [
    PageTab(label: 'Tab A', child: ContentA()),
    PageTab(label: 'Tab B', child: ContentB()),
  ],
)

Custom tab bar #

MainAreaTemplate(
  title: 'Custom',
  tabs: [
    PageTab(label: 'One', child: ContentOne()),
    PageTab(label: 'Two', child: ContentTwo()),
  ],
  tabBarBuilder: (tabs, selectedIndex, onTabSelected) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        for (int i = 0; i < tabs.length; i++)
          TextButton(
            onPressed: () => onTabSelected(i),
            child: Text(tabs[i].label),
          ),
      ],
    );
  },
)

Dashboard layout (no card) #

MainAreaTemplate(
  title: 'Dashboard',
  icon: Icons.home_rounded,
  showCard: false,    // content floats directly on page background
  child: Column(
    children: [
      Expanded(child: Row(children: [Card(...), Card(...), Card(...)])),
      Expanded(child: Row(children: [Card(...), Card(...)])),
    ],
  ),
)

When showCard is false, MainAreaSection widgets automatically switch from grey to white backgrounds with individual shadows via PageScaffoldScope.

Visibility control #

The unified bar responds to showTitle and showTabs independently:

// Tabs only (no title/icon)
MainAreaTemplate(
  title: 'Manager',        // still required but hidden
  showTitle: false,
  tabs: [
    PageTab(label: 'Tab A', child: ContentA()),
    PageTab(label: 'Tab B', child: ContentB()),
  ],
)

// Title only (tabs hidden, content still switches via initialTabIndex)
MainAreaTemplate(
  title: 'Manager',
  showTabs: false,
  tabs: [...],
)

// Both hidden (just the card content)
MainAreaTemplate(
  title: 'Manager',
  showTitle: false,
  showTabs: false,
  tabs: [...],
)

API Reference #

MainAreaTemplate #

Property Type Default Description
title String required Large bold page title
description String? null Tooltip in tabbed mode; visible subtitle in no-tabs mode
icon IconData? null Icon displayed before the title in a tinted container
actions List<Widget>? null Action buttons at the trailing edge of the title bar
child Widget? null Main content (required when tabs is null)
outerPadding EdgeInsetsGeometry? EdgeInsets.all(24) Padding around the template
cardPadding EdgeInsetsGeometry? EdgeInsets.all(20) Padding inside the content card
tabs List<PageTab>? null Tab definitions; enables unified title-tab bar
showTitle bool true Show/hide title, icon, and description in the bar
showTabs bool true Show/hide tab pills (only when tabs is provided)
showCard bool true Wrap content in a card container with rounded corners and shadow
initialTabIndex int 0 Starting tab index
onTabChanged ValueChanged<int>? null Callback when selected tab changes
maintainState bool true Keep all tab children mounted via IndexedStack
tabTransitionDuration Duration? null Fade animation duration when switching tabs
tabBarBuilder TabBarBuilder? null Custom tab bar widget builder (replaces pill tabs)

PageTab #

Property Type Default Description
label String required Tab label displayed in the pill chip
icon IconData? null Icon displayed before the label inside the pill
child Widget required Content widget shown when this tab is selected

MainAreaSection #

Property Type Default Description
label String? null Uppercase section header with accent bar
child Widget required Section content
padding EdgeInsetsGeometry? EdgeInsets.all(16) Padding around content
expanded bool false If true, fills remaining space in a Column

PageScaffoldScope #

An InheritedWidget provided by MainAreaTemplate that exposes configuration to descendant widgets. MainAreaSection reads this automatically to adjust its appearance when showCard changes.

final scope = PageScaffoldScope.maybeOf(context);
if (scope != null && !scope.showCard) {
  // card-free mode — sections use surface color with shadow
}

Theme Integration #

All colors are pulled from Theme.of(context).colorScheme:

Widget element Color token
Page background scaffoldBackgroundColor
Content card surface
Section background surfaceContainerHighest (or surface when showCard: false)
Accent bar primary
Title text onSurface
Description text onSurfaceVariant
Section header text onSurfaceVariant
Card shadow shadow (6% opacity)
Selected tab pill primary (8% alpha bg, solid text)
Unselected tab text onSurfaceVariant
Bar separator outlineVariant

Works out of the box with light, dark, or any custom ThemeData.

Example #

A playground app is included in example/. Run it with:

cd example
flutter run -d chrome

The playground demonstrates three page layouts (table, settings, dashboard) with toggles for title, tabs, keep-alive, animation, card mode, and a theme switcher for light, dark, and sunshine themes.

License #

MIT

1
likes
160
points
245
downloads

Publisher

unverified uploader

Weekly Downloads

A reusable main content area template widget with page titles, section headers, and theme-aware styling.

Repository (GitHub)
View/report issues

Topics

#widget #ui #layout #scaffold

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on flutter_page_scaffold