Skip to content

Quick Start

This page gets your first Miuix page running in five minutes: wire up the theme → build the scaffold → use components.

Minimal example

Wrap your app root in MiuixSystemTheme (follows the system light/dark mode automatically); components then read colors and text styles via MiuixTheme.of(context):

dart
import 'package:flutter/material.dart';
import 'package:flutter_miuix/miuix.dart';

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

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

  @override
  Widget build(BuildContext context) {
    // MiuixSystemTheme follows the system brightness and applies Miuix colors
    return MiuixSystemTheme(
      child: Builder(
        builder: (context) {
          final theme = MiuixTheme.of(context);
          return MaterialApp(
            debugShowCheckedModeBanner: false,
            theme: ThemeData(
              useMaterial3: true,
              colorScheme: ColorScheme.fromSeed(
                seedColor: theme.colors.primary,
                brightness: theme.brightness,
              ),
              brightness: theme.brightness,
            ),
            home: const HomePage(),
          );
        },
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return MiuixScaffold(
      topBar: const MiuixTopAppBar(title: 'flutter_miuix'),
      content: (padding) => Center(
        child: MiuixButton(
          onPressed: () {},
          child: const MiuixText('Hello Miuix'),
        ),
      ),
    );
  }
}

Why keep MaterialApp?

Miuix widgets only depend on MiuixTheme and do not require Material. In practice you still want MaterialApp for routing, Overlay, text direction, and other infrastructure. The example bridges the Miuix primary color into Material's ColorScheme.fromSeed so both worlds look consistent.

Understanding MiuixScaffold

MiuixScaffold is the page skeleton. It hosts the top bar, bottom bar, floating action button, snackbars, and popups:

dart
MiuixScaffold(
  topBar: const MiuixTopAppBar(title: 'Title'),  // usually MiuixTopAppBar
  bottomBar: ...,                                // usually MiuixNavigationBar
  floatingActionButton: ...,                     // floating action button
  snackbarHost: ...,                             // MiuixSnackbarHost
  content: (padding) => ListView(
    padding: padding,                            // ⚠️ apply the padding to your content root
    children: [...],
  ),
)

content is a builder whose padding argument accounts for the top bar, bottom bar, and system safe areas — always apply it to the content root (e.g. ListView.padding or a Padding), or your content will be covered by the top bar. This design lets content scroll underneath a frosted-glass app bar.

Common components at a glance

dart
// Switch
MiuixSwitch(
  value: isOn,
  onChanged: (v) => setState(() => isOn = v),
)

// Checkbox (tri-state: true / false / null)
MiuixCheckbox(
  value: checked,
  onChanged: (v) => setState(() => checked = v ?? false),
)

// Text field (floating label + focus border animation)
MiuixTextField(
  label: 'Username',
  onChanged: (v) {},
)

// Frosted-glass app bar — liquid glass in one line
MiuixTopAppBar(title: 'Title', blurred: true)

Showing a snackbar

Create a MiuixSnackbarHostState, mount a MiuixSnackbarHost on the scaffold, and enqueue messages from anywhere:

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final _snackbarHost = MiuixSnackbarHostState();

  @override
  Widget build(BuildContext context) {
    return MiuixScaffold(
      topBar: const MiuixTopAppBar(title: 'Snackbar demo'),
      snackbarHost: MiuixSnackbarHost(state: _snackbarHost),
      content: (padding) => Center(
        child: MiuixButton(
          onPressed: () {
            _snackbarHost.showSnackbar('Saved', actionLabel: 'Undo');
          },
          child: const MiuixText('Show snackbar'),
        ),
      ),
    );
  }
}

Documentation conventions

A few conventions used throughout the component reference:

  • "required" in a default-value column means the parameter is required (no default; must be provided).
  • Defaults written as MiuixXxxDefaults.yyy come from that component's Defaults constants; exact values are listed in each component's Defaults table.
  • Every component's sizes, corner radii, and paddings are customizable via constructor parameters, with defaults matching the original miuix.
  • Colors go through MiuixColors semantic roles and text through MiuixTextStyles presets, switching automatically with light/dark themes.
  • All examples compile and run as-is and show only the most common parameters; see each component's table for the full list.

Full example project

The repository's example/ directory contains demo pages in 14 categories: buttons, inputs, menus, display, list items, pickers, feedback, overlays, navigation, side navigation, utilities, theme, blur, and foundation.

Next steps

  • Theming — custom colors, forced light/dark, Monet dynamic color
  • Input components — start browsing the API with TextField and Switch

Released under the Apache-2.0 License.