fin_ui 0.1.1 copy "fin_ui: ^0.1.1" to clipboard
fin_ui: ^0.1.1 copied to clipboard

A reusable Flutter UI foundation with adaptive navigation, theme tokens, split panes, and polished app controls.

example/lib/main.dart

import 'package:fin_ui/fin_ui.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const FinUiExampleApp());
}

class FinUiExampleApp extends StatelessWidget {
  const FinUiExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FinUI Example',
      theme: FuiTheme.light(),
      darkTheme: FuiTheme.dark(),
      scrollBehavior: FuiTheme.scrollBehavior,
      home: const ExampleShell(),
    );
  }
}

class ExampleShell extends StatefulWidget {
  const ExampleShell({super.key});

  @override
  State<ExampleShell> createState() => _ExampleShellState();
}

class _ExampleShellState extends State<ExampleShell> {
  int selectedIndex = 0;

  @override
  Widget build(BuildContext context) {
    return FuiNavigationShell(
      selectedIndex: selectedIndex,
      onSelected: (index) => setState(() => selectedIndex = index),
      autoExtendRail: true,
      splitPlan: const FuiSplitNavigationPlan(
        placeholderData: FuiSecondaryPlaceholderData(
          icon: FUIIcons.apps,
          title: 'Select content',
          subtitle: 'Open a detail page to show it here on wide screens.',
        ),
      ),
      items: const [
        FuiNavigationItem(
          destination: FuiNavigationDestination(
            icon: FUIIcons.home,
            selectedIcon: FUIIcons.homeFilled,
            label: 'Home',
          ),
          page: HomePage(),
        ),
        FuiNavigationItem(
          destination: FuiNavigationDestination(
            icon: FUIIcons.calendar,
            selectedIcon: FUIIcons.calendarFilled,
            label: 'Schedule',
          ),
          page: SchedulePage(),
        ),
        FuiNavigationItem(
          destination: FuiNavigationDestination(
            icon: FUIIcons.settings,
            selectedIcon: FUIIcons.settingsFilled,
            label: 'Settings',
          ),
          page: SettingsPage(),
        ),
      ],
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return FUIPage(
      children: [
        const _PageTitle(
          title: 'FinUI',
          subtitle: 'Theme, controls, and adaptive navigation.',
        ),
        const SizedBox(height: FUITokens.gap16),
        FUISection(
          title: 'Actions',
          children: [
            FUITile(
              icon: FUIIcons.apps,
              title: 'Open detail',
              subtitle: 'Uses FuiNavigation.openDetail and FuiPageRoute.',
              onTap: () => FuiNavigation.openDetail(
                context,
                builder: (context) => const DetailPage(),
              ),
            ),
            FUITile(
              icon: FUIIcons.info,
              title: 'Show toast',
              subtitle: 'Context-based overlay toast.',
              onTap: () => FUIToast.success(context, message: 'Saved'),
            ),
          ],
        ),
        const SizedBox(height: FUITokens.gap16),
        const FUISurface(
          padding: FUIInsets.card,
          child: Wrap(
            spacing: FUITokens.gap8,
            runSpacing: FUITokens.gap8,
            children: [
              FUITag(label: 'Primary', variant: FUITagVariant.primary),
              FUITag(label: 'Success', variant: FUITagVariant.success),
              FUITag(label: 'Warning', variant: FUITagVariant.warning),
              FUITag(label: 'Danger', variant: FUITagVariant.danger),
            ],
          ),
        ),
      ],
    );
  }
}

class SchedulePage extends StatelessWidget {
  const SchedulePage({super.key});

  @override
  Widget build(BuildContext context) {
    return const FUIPage(
      children: [
        _PageTitle(
          title: 'Schedule',
          subtitle: 'Example page kept alive by IndexedStack.',
        ),
        SizedBox(height: FUITokens.gap16),
        FUISection(
          title: 'Today',
          children: [
            FUITile(
              icon: FUIIcons.today,
              title: 'Morning session',
              subtitle: '08:30 - 10:00',
              showChevron: false,
            ),
            FUITile(
              icon: FUIIcons.schedule,
              title: 'Afternoon session',
              subtitle: '14:00 - 15:30',
              showChevron: false,
            ),
          ],
        ),
      ],
    );
  }
}

class SettingsPage extends StatefulWidget {
  const SettingsPage({super.key});

  @override
  State<SettingsPage> createState() => _SettingsPageState();
}

class _SettingsPageState extends State<SettingsPage> {
  String mode = 'auto';

  @override
  Widget build(BuildContext context) {
    return FUIPage(
      children: [
        const _PageTitle(title: 'Settings', subtitle: 'Example controls.'),
        const SizedBox(height: FUITokens.gap16),
        FUISegmentedControl<String>(
          value: mode,
          items: const [
            FUISegmentedItem(
              value: 'light',
              label: 'Light',
              icon: FUIIcons.lightMode,
            ),
            FUISegmentedItem(
              value: 'dark',
              label: 'Dark',
              icon: FUIIcons.darkMode,
            ),
            FUISegmentedItem(
              value: 'auto',
              label: 'Auto',
              icon: FUIIcons.autoBrightness,
            ),
          ],
          onChanged: (value) => setState(() => mode = value),
        ),
        const SizedBox(height: FUITokens.gap16),
        const FUITextField(
          label: 'Search',
          hintText: 'Type something',
          prefixIcon: FUIIcons.search,
        ),
      ],
    );
  }
}

class DetailPage extends StatelessWidget {
  const DetailPage({super.key});

  @override
  Widget build(BuildContext context) {
    return FUIPage(
      children: [
        const FuiPageHead(
          title: 'Detail page',
          subtitle: 'Uses the FinUI navigation transition policy.',
        ),
        const SizedBox(height: FUITokens.gap16),
        FUISection(
          title: 'Nested navigation',
          children: [
            FUITile(
              icon: FUIIcons.add,
              title: 'Open nested detail',
              subtitle: 'Pushes another detail through the same API.',
              onTap: () => FuiNavigation.openDetail(
                context,
                builder: (context) => const NestedDetailPage(),
              ),
            ),
          ],
        ),
      ],
    );
  }
}

class NestedDetailPage extends StatelessWidget {
  const NestedDetailPage({super.key});

  @override
  Widget build(BuildContext context) {
    return const FUIPage(
      children: [
        FuiPageHead(title: 'Nested detail', subtitle: 'Back closes this page.'),
        SizedBox(height: FUITokens.gap16),
        FUIEmptyState(
          icon: FUIIcons.check,
          title: 'Done',
          message: 'The nested detail route is working.',
        ),
      ],
    );
  }
}

class _PageTitle extends StatelessWidget {
  const _PageTitle({required this.title, required this.subtitle});

  final String title;
  final String subtitle;

  @override
  Widget build(BuildContext context) {
    final colors = context.colors;
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          title,
          style: Theme.of(context).textTheme.headlineSmall?.copyWith(
            color: colors.textPrimary,
            fontWeight: FontWeight.w800,
          ),
        ),
        const SizedBox(height: FUITokens.gap4),
        Text(
          subtitle,
          style: Theme.of(context).textTheme.bodyMedium?.copyWith(
            color: colors.textSecondary,
            fontWeight: FontWeight.w500,
          ),
        ),
      ],
    );
  }
}
1
likes
150
points
168
downloads

Documentation

Documentation
API reference

Publisher

unverified uploader

Weekly Downloads

A reusable Flutter UI foundation with adaptive navigation, theme tokens, split panes, and polished app controls.

Repository (GitHub)
View/report issues
Contributing

Topics

#flutter #ui #design-system #adaptive #navigation

License

MIT (license)

Dependencies

dynamic_color, easy_refresh, fluentui_system_icons, flutter, get

More

Packages that depend on fin_ui