FinUI

FinUI is a reusable Flutter UI foundation extracted from GXNU Class Tool.

It contains:

  • Theme: FuiTheme, FuiAccent, FuiDynamicThemeBuilder, palette extension, typography and Material defaults.
  • Tokens: spacing, radius, icon sizes, animation durations and shared insets.
  • Controls: buttons, icon buttons, text fields, combo boxes, tags, tiles, sections, surfaces, progress bars, empty states and toast.
  • Navigation: FuiNavigationShell for bottom tabs, rail, optional expanded desktop rail, and split panes.
  • Adaptive navigation: FuiNavigationShell and FuiNavigation.openDetail keep apps on one API while FinUI chooses bottom tabs, rail, push, bottom sheet, dialog or split layouts from screen width. In split mode the detail pane owns a local Navigator stack, so nested detail pages can push, animate, and pop inside the right pane.
  • Adaptive split: FuiAdaptiveSplitScaffold opens master-detail pages side-by-side on wide screens, can add a third supplementary pane when enough width is available, and presents details through FuiNavigation.openDetail on compact screens.

Default breakpoints:

  • Bottom tabs: width below 720.
  • Navigation rail: width from 720.
  • Three-pane shell: width at least 900, height at least 600, and aspect ratio at least 1.2.
  • Expanded rail: enable with autoExtendRail: true; default expansion width is 1100. Force it with extendedRail: true.

Use it from an app:

dependencies:
  fin_ui: ^0.1.0
import 'package:fin_ui/fin_ui.dart';

MaterialApp(
  theme: FuiTheme.light(),
  darkTheme: FuiTheme.dark(),
  scrollBehavior: FuiTheme.scrollBehavior,
);
FuiNavigationShell(
  selectedIndex: selectedIndex,
  onSelected: onSelected,
  autoExtendRail: true,
  splitPlan: const FuiSplitNavigationPlan(
    placeholderData: FuiSecondaryPlaceholderData(
      icon: FUIIcons.apps,
      title: '选择功能',
      subtitle: '打开功能后会在这里显示详情',
    ),
  ),
  items: const [
    FuiNavigationItem(
      destination: FuiNavigationDestination(
        icon: FUIIcons.home,
        selectedIcon: FUIIcons.homeFilled,
        label: 'Home',
      ),
      page: HomePage(),
    ),
  ],
);
FuiAdaptiveSplitScaffold<ItemId>(
  masterTitle: 'Items',
  items: items,
  selectedValue: selectedId,
  onSelected: onSelected,
  plan: const FuiSplitNavigationPlan(
    placeholderData: FuiSecondaryPlaceholderData(
      title: '选择项目',
      subtitle: '项目详情会在右侧显示',
    ),
  ),
  detailBuilder: (context, id) => DetailPane(id: id),
  supplementaryBuilder: (context, id) => InspectorPane(id: id),
);

When a detail page uses FuiPageHead, FinUI automatically shows a close button for the first right-pane detail and a back button for deeper pages in the local detail stack. Call FuiNavigation.openDetail(context, builder: ...) from either the master pane or another detail page; FinUI decides whether to push a full page or push inside the split detail pane.