Neo Brutalist UI

pub package license: MIT Flutter platforms

Neo Brutalist UI banner

Neo-Brutalist Flutter widgets, layout helpers, and animation primitives.

Neo Brutalist UI provides composable UI components with hard borders, zero-blur shadows, high contrast color tokens, responsive layout helpers, and motion building blocks. It stays focused on presentation primitives: you provide the application state, routes, persistence, validation, and domain behavior.

Contents

Install

dependencies:
  neo_mobile_kit: ^0.2.1
import 'package:neo_mobile_kit/neo_mobile_kit.dart';

Quick start

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

void main() => runApp(const DemoApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: NeoTheme.buildTheme(Brightness.light),
      darkTheme: NeoTheme.buildTheme(Brightness.dark),
      home: const DemoPage(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    final palette = NeoPalette.of(context);

    return Scaffold(
      body: Stack(
        children: [
          Positioned.fill(
            child: NeoOrbBackground(specs: buildAuthOrbs(palette)),
          ),
          Center(
            child: NeoPanel(
              width: 360,
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  const NeoPill(label: 'NEO'),
                  const SizedBox(height: 16),
                  NeoButton(
                    label: 'Create interface',
                    icon: Icons.arrow_forward_rounded,
                    onPressed: () {},
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}

Design principles

  • Bold outlines: components use thick borders and explicit shape boundaries.
  • Zero-blur shadows: shadows behave like hard offsets instead of soft elevation.
  • Token-first styling: palettes and spacing values are centralized.
  • Composition over screens: widgets are small enough to be placed in your own Scaffold, Stack, CustomScrollView, dialogs, forms, and feature pages.
  • Controlled motion: animation widgets expose duration, curve, delay, ordering, and replay settings instead of hiding behavior behind a fixed flow.

Out of scope: app architecture, route management, data storage, networking, authentication, form validation rules, and complete product screens.

Theme system

NeoTheme

Builds a Material ThemeData with Neo-Brutalist color extensions and typography defaults.

Parameter Type Purpose
brightness Brightness Selects light or dark palette values.
preset NeoThemePreset Selects a named palette family.
MaterialApp(
  theme: NeoTheme.buildTheme(
    Brightness.light,
    preset: NeoThemePreset.limeArcade,
  ),
)

Use NeoTheme at the app boundary, then read NeoPalette.of(context) inside components that need token-aware colors.

NeoPalette

NeoPalette is a ThemeExtension that exposes page, surface, primary, outline, text, and shadow colors.

Member Type Purpose
of BuildContext -> NeoPalette Reads the active palette.
forBrightness Brightness -> NeoPalette Resolves a palette without a context.
copyWith NeoPalette Creates adjusted palette values.
lerp NeoPalette Supports animated theme transitions.
final palette = NeoPalette.of(context);

Container(
  color: palette.surfaceAlt,
  child: Text('Token-aware text', style: TextStyle(color: palette.textPrimary)),
)

Use it when composing custom widgets next to package components.

NeoThemePreset

Named palette families for quickly changing visual tone while preserving the same component structure.

Value Purpose
worldSkills Competitive blue palette.
candyPunch Pink accent palette.
limeArcade Electric green palette.
hotCircuit Orange and cyan palette.
NeoTheme.buildTheme(
  Brightness.dark,
  preset: NeoThemePreset.hotCircuit,
)

Use presets as a starting point; components still accept color overrides where appropriate.

NeoColors and NeoTokens

Static constants for base colors, border width, radii, and hard-shadow offsets.

API Type Purpose
NeoColors class Shared base color constants.
NeoTokens.borderWidth double Default heavy border width.
NeoTokens.radius* double Default corner radii.
NeoTokens.shadowOffset Offset Default hard-shadow offset.
Container(
  decoration: BoxDecoration(
    border: Border.all(width: NeoTokens.borderWidth),
    borderRadius: BorderRadius.circular(NeoTokens.radiusMedium),
  ),
)

Use tokens when creating custom companion components.

Layout

NeoPageShell

Scrollable page wrapper with safe area handling, optional background layer, maximum width, padding, and alignment.

Parameter Type Purpose
child Widget Foreground content.
background Widget? Optional full-page visual layer.
maxWidth double Maximum readable content width.
padding EdgeInsets Page padding.
alignment AlignmentGeometry Content placement.
NeoPageShell(
  background: NeoOrbBackground(specs: buildAuthOrbs(NeoPalette.of(context))),
  maxWidth: 720,
  child: const NeoPanel(child: Text('Content')),
)

Use it for bounded pages where you still own the content and navigation.

NeoSplitLayout

Responsive two-column layout that collapses to a vertical stack below a breakpoint.

Parameter Type Purpose
primary Widget Main column content.
secondary Widget Supporting column content.
collapseBreakpoint double Width below which content stacks.
primaryFlex int Main column flex.
secondaryFlex int Supporting column flex.
NeoSplitLayout(
  primary: NeoPanel(child: Text('Editor')),
  secondary: NeoPanel(child: Text('Inspector')),
)

Use it for forms, dashboards, settings panels, and catalog pages.

NeoSectionHeader

Section heading with optional eyebrow pill, subtitle, and action widget.

Parameter Type Purpose
title String Main heading.
subtitle String? Supporting copy.
eyebrow String? Optional pill label.
action Widget? Optional trailing or stacked action.
NeoSectionHeader(
  eyebrow: 'CATALOG',
  title: 'Inputs',
  subtitle: 'Controls for collecting user intent.',
  action: NeoButton(label: 'Add', onPressed: () {}),
)

Use it above component groups rather than inside every small widget.

NeoBreakpoints and NeoSpacing

Constants for responsive thresholds and spacing values.

API Type Purpose
NeoBreakpoints.compact double Compact width threshold.
NeoBreakpoints.medium double Medium width threshold.
NeoBreakpoints.pageMaxWidth double Default shell width.
NeoSpacing.* double Reusable gap scale.
const gap = SizedBox(height: NeoSpacing.md);

Use these constants to keep custom layouts aligned with package components.

Core widgets

NeoPanel

Base surface component with thick border, configurable color, radius, padding, width, and hard shadow.

Parameter Type Purpose
child Widget Panel content.
color Color? Surface override.
shadowColor Color? Hard-shadow color override.
padding EdgeInsetsGeometry Inner spacing.
radius double Corner radius.
offset Offset Shadow offset.
width double? Optional fixed width.
NeoPanel(
  padding: const EdgeInsets.all(20),
  child: Text('Card content'),
)

Use it as the primitive surface for custom cards and controls.

NeoButton

High-contrast action control with optional icon, disabled state, and primary or secondary variant.

Parameter Type Purpose
label String Button text.
icon IconData? Optional leading icon.
variant NeoButtonVariant Primary or secondary style.
onPressed VoidCallback? Tap callback; null disables the button.
NeoButton(
  label: 'Create record',
  icon: Icons.add_rounded,
  variant: NeoButtonVariant.primary,
  onPressed: createRecord,
)

Use it for commands. Wrap it with your own validation or loading state when needed.

NeoIconButton

Square icon action with border, hard shadow, size control, and color overrides.

Parameter Type Purpose
icon IconData Displayed icon.
onPressed VoidCallback? Tap callback.
size double Button width and height.
backgroundColor Color? Surface override.
shadowColor Color? Shadow override.
iconColor Color? Icon color override.
NeoIconButton(
  icon: Icons.settings_rounded,
  onPressed: openSettings,
)

Use it in app bars, panels, and compact tool rows.

NeoInputField

Labeled text input with an icon tile, bordered input shell, and token-aware colors.

Parameter Type Purpose
label String Field label.
hint String Input hint text.
icon IconData Leading icon.
controller TextEditingController? Optional text controller.
obscureText bool Obscures text for sensitive input.
keyboardType TextInputType? Keyboard hint.
onChanged ValueChanged<String>? Change callback.
NeoInputField(
  label: 'Email',
  hint: 'name@example.com',
  icon: Icons.email_rounded,
  controller: emailController,
)

Use your own validators and form state around it.

NeoPill

Compact label badge with optional colors and rotation.

Parameter Type Purpose
label String Display text.
backgroundColor Color? Fill override.
textColor Color? Text override.
rotation double Rotation in radians.
const NeoPill(
  label: 'ACTIVE',
  rotation: -0.04,
)

Use it for category labels, status labels, and section eyebrows.

NeoWindowPanel

Panel with a title bar, optional window dots, trailing widget, accent strip, and content body.

Parameter Type Purpose
title String Header label.
child Widget Body content.
accentColor Color? Header fill override.
color Color? Body fill override.
shadowColor Color? Shadow override.
padding EdgeInsetsGeometry Body padding.
showWindowDots bool Toggles decorative header dots.
trailing Widget? Header trailing action.
NeoWindowPanel(
  title: 'profile.json',
  trailing: const NeoPill(label: 'LIVE'),
  child: Text('Window content'),
)

Use it for framed editor-like sections and structured cards.

NeoBottomSheetCard

Bottom-sheet surface with handle, title, optional subtitle, content, and responsive actions.

Parameter Type Purpose
title String Sheet title.
subtitle String? Supporting text.
child Widget Main sheet content.
primaryActionLabel String? Primary action text.
secondaryActionLabel String? Secondary action text.
onPrimaryPressed VoidCallback? Primary action callback.
onSecondaryPressed VoidCallback? Secondary action callback.
showModalBottomSheet<void>(
  context: context,
  backgroundColor: Colors.transparent,
  builder: (_) => NeoBottomSheetCard(
    title: 'Filters',
    child: Text('Custom filter controls'),
    primaryActionLabel: 'Apply',
    onPrimaryPressed: () => Navigator.pop(context),
  ),
);

Use it as a shell for your own modal content.

NeoEmptyState

Empty-state panel with icon, title, message, and optional action.

Parameter Type Purpose
title String Main message.
message String Supporting text.
icon IconData Visual marker.
buttonLabel String? Optional action label.
onPressed VoidCallback? Optional action callback.
NeoEmptyState(
  icon: Icons.inbox_rounded,
  title: 'No records yet',
  message: 'Create a record to populate this list.',
  buttonLabel: 'Create',
  onPressed: createRecord,
)

Use it where your data layer returns an empty collection.

NeoSearchBox

Search input with clear button, hard-shadow shell, and configurable height, radius, and hint.

Parameter Type Purpose
controller TextEditingController Search text controller.
onChanged ValueChanged<String>? Change callback.
hintText String Placeholder text.
backgroundColor Color? Fill override.
radius double Corner radius.
contentHeight double Inner input height.
padding EdgeInsetsGeometry Inner padding.
NeoSearchBox(
  controller: searchController,
  hintText: 'Search widgets',
  onChanged: filterCatalog,
)

Use it with your own filtering logic.

NeoAccordion

Expandable panel for progressive disclosure.

Parameter Type Purpose
title String Header text.
child Widget Expanded content.
initiallyExpanded bool Initial expanded state.
subtitle String? Optional helper text.
leading Widget? Optional leading widget.
NeoAccordion(
  title: 'Advanced options',
  child: Text('Hidden controls'),
)

Use it for optional settings and dense forms.

NeoActionTile

Tappable action row with title, subtitle, icon, and optional trailing widget.

Parameter Type Purpose
title String Main label.
subtitle String? Supporting text.
leading Widget? Optional leading widget.
trailing Widget? End accessory.
onTap VoidCallback? Tap callback.
NeoActionTile(
  title: 'Upload file',
  subtitle: 'Attach a local document',
  leading: Icon(Icons.upload_rounded),
  onTap: pickFile,
)

Use it in menus, settings, and action lists.

NeoCompactListItem

Dense list row with optional leading widget and trailing accessory.

Parameter Type Purpose
title String Primary text.
subtitle String? Secondary text.
leading Widget? Leading visual.
trailing Widget? Trailing visual.
onTap VoidCallback? Tap callback.
NeoCompactListItem(
  title: 'Jane Doe',
  subtitle: 'Designer',
  trailing: const NeoPill(label: 'NEW'),
  onTap: openProfile,
)

Use it when vertical space is limited.

NeoListItem

Larger list item with icon treatment, title, subtitle, and optional metadata.

Parameter Type Purpose
title String Primary text.
subtitle String Secondary text.
icon IconData Leading icon.
trailing Widget? Trailing accessory.
onTap VoidCallback? Tap callback.
NeoListItem(
  icon: Icons.article_rounded,
  title: 'Release notes',
  subtitle: 'Read the latest changes',
  onTap: openReleaseNotes,
)

Use it for readable content lists.

NeoDetailRow

Label-value row for displaying metadata inside panels.

Parameter Type Purpose
label String Metadata label.
value String Metadata value.
leading Widget? Optional leading widget.
helper String? Optional helper text.
trailing Widget? Optional trailing widget.
emphasis bool Uses primary emphasis styling.
const NeoDetailRow(
  label: 'Status',
  value: 'Published',
  helper: 'Visible to users',
)

Use it inside detail cards and inspector panels.

NeoSummaryCard

Compact summary surface for title, subtitle, and optional child content.

Parameter Type Purpose
title String Summary title.
value String Prominent value text.
helper String? Supporting text.
badge String? Optional badge label.
icon IconData? Optional icon.
highlight bool Uses primary emphasis styling.
NeoSummaryCard(
  icon: Icons.analytics_rounded,
  title: 'Revenue',
  value: '\$12,400',
  helper: 'Updated today',
  badge: 'LIVE',
)

Use it for compact overview cards.

NeoStatCard

Metric card with label, value, optional helper text, and icon.

Parameter Type Purpose
label String Metric label.
value String Metric value.
helper String? Supporting text.
icon IconData? Optional icon.
const NeoStatCard(
  label: 'Tasks',
  value: '24',
  helper: '+6 this week',
)

Use it for dashboard metrics.

NeoAppBar

Responsive top control bar with search, menu action, settings action, and theme toggle slot.

Parameter Type Purpose
title String Semantic title value.
subtitle String Semantic subtitle value.
isDark bool Current theme state.
searchController TextEditingController Search controller.
onSearchChanged ValueChanged<String> Search callback.
onThemeToggle ValueChanged<bool> Theme callback.
onMenuPressed VoidCallback? Optional menu action.
onSettingsPressed VoidCallback? Optional settings action.
NeoAppBar(
  title: 'Catalog',
  subtitle: 'Components',
  isDark: isDark,
  searchController: searchController,
  onSearchChanged: setQuery,
  onThemeToggle: setDarkMode,
  onMenuPressed: openMenu,
)

Use it as a composable control row; you still decide page structure and routing.

NeoBottomNav and NeoBottomNavItem

Bottom navigation surface with animated selected indicator.

Parameter Type Purpose
items List<NeoBottomNavItem> Navigation labels and icons.
currentIndex int Selected item index.
onChanged ValueChanged<int> Selection callback.
NeoBottomNav(
  currentIndex: index,
  onChanged: setIndex,
  items: const [
    NeoBottomNavItem(label: 'Home', icon: Icons.home_rounded),
    NeoBottomNavItem(label: 'Profile', icon: Icons.person_rounded),
  ],
)

Use your own page switcher, router, or state controller around it.

showNeoSideMenu and NeoSideMenuItem

Dialog helper that presents a left-side menu using Neo-Brutalist surfaces.

Parameter Type Purpose
context BuildContext Dialog context.
items List<NeoSideMenuItem> Menu actions.
title String Menu title.
width double Menu width.
showNeoSideMenu(
  context: context,
  title: 'SECTIONS',
  items: [
    NeoSideMenuItem(
      label: 'Dashboard',
      icon: Icons.dashboard_rounded,
      onPressed: openDashboard,
    ),
  ],
);

Use it for command menus where the destination behavior remains yours.

showNeoOrbRevealTransition

Overlay transition that expands from a keyed origin and calls onCovered when the overlay covers the screen.

Parameter Type Purpose
context BuildContext Overlay context.
originKey GlobalKey Widget origin for expansion.
color Color Overlay fill color.
onCovered VoidCallback Called when coverage threshold is reached.
duration Duration Animation duration.
coveredAt double Progress threshold for callback.
final key = GlobalKey();

NeoIconButton(
  key: key,
  icon: Icons.dark_mode_rounded,
  onPressed: () {
    showNeoOrbRevealTransition(
      context: context,
      originKey: key,
      color: NeoPalette.of(context).page,
      onCovered: toggleTheme,
    );
  },
)

Use it as a visual transition primitive around your own state changes.

Animation primitives

NeoFadeSlide

Entrance animation that fades and translates a child from an offset.

Parameter Type Purpose
child Widget Animated child.
delay Duration Start delay.
duration Duration Animation duration.
offset Offset Initial translation.
curve Curve Animation curve.
NeoFadeSlide(
  offset: NeoMotionTokens.slideUpOffset,
  child: NeoPanel(child: Text('Animated in')),
)

Use it around any widget that should enter with subtle motion.

NeoPop

Scale-and-fade entrance animation with an elastic curve by default.

Parameter Type Purpose
child Widget Animated child.
delay Duration Start delay.
duration Duration Animation duration.
beginScale double Initial scale.
curve Curve Animation curve.
NeoPop(
  child: NeoIconButton(
    icon: Icons.star_rounded,
    onPressed: () {},
  ),
)

Use it for small emphatic entrances.

NeoPanelDrop

Panel-style entrance with translation, scale, and slight rotation.

Parameter Type Purpose
child Widget Animated child.
delay Duration Start delay.
duration Duration Animation duration.
offset Offset Initial translation.
beginScale double Initial scale.
beginTurns double Initial rotation turns.
curve Curve Animation curve.
NeoPanelDrop(
  child: NeoWindowPanel(
    title: 'drop.panel',
    child: Text('Dropped content'),
  ),
)

Use it for cards that should feel placed into the layout.

NeoPressMotion

Press feedback wrapper that moves and scales a child while pressed.

Parameter Type Purpose
child Widget Pressable child.
onTap VoidCallback? Tap callback.
enabled bool Enables press behavior.
duration Duration Feedback duration.
pressedOffset Offset Press translation.
pressedScale double Press scale.
NeoPressMotion(
  onTap: submit,
  child: NeoPanel(child: Text('Press me')),
)

Use it when composing custom controls.

NeoScrollReveal

Visibility-aware entrance wrapper for scrollable content.

Parameter Type Purpose
child Widget Revealed child.
preset NeoEntrancePreset Animation style.
delay Duration Start delay.
viewportPadding double Visibility threshold padding.
repeat bool Allows replay.
resetOnExit bool Resets when leaving viewport.
ListView(
  children: items.map((item) {
    return NeoScrollReveal(
      preset: NeoEntrancePreset.panelDrop,
      child: NeoListItem(title: item.title),
    );
  }).toList(),
)

Use it inside your own scroll views.

NeoEntranceGroup

Staggers multiple children using ordering strategies such as in-order, radial, corner, or directional reveal.

Parameter Type Purpose
children List<Widget> Animated children.
builder NeoEntranceGroupBuilder? Optional custom layout builder.
preset NeoEntrancePreset Child animation style.
sort NeoStaggerSort Delay ordering strategy.
origin NeoStaggerOrigin Origin for spatial sorts.
columns int Grid column count for spatial sorts.
replayOnScroll bool Uses scroll reveal per child.
NeoEntranceGroup(
  columns: 2,
  sort: NeoStaggerSort.radial,
  builder: (children) => Wrap(spacing: 12, runSpacing: 12, children: children),
  children: [
    NeoStatCard(label: 'Open', value: '18'),
    NeoStatCard(label: 'Done', value: '42'),
  ],
)

Use it to animate groups while keeping the layout builder explicit.

NeoMotionTokens

Shared durations, curves, offsets, scales, and press values for custom motion.

API Type Purpose
fast, normal, slow Duration Shared durations.
easeOut, pop, drop Curve Shared curves.
slide*Offset Offset Entrance offsets.
pressScale, pressOffset double, Offset Press feedback values.
AnimatedContainer(
  duration: NeoMotionTokens.normal,
  curve: NeoMotionTokens.easeOut,
)

Use these tokens to keep custom animations consistent.

Background primitives

NeoOrbBackground and NeoOrbSpec

Animated field of bordered circular shapes. Each orb is configured by position, size, color, shadow, travel distance, and phase.

Parameter Type Purpose
specs List<NeoOrbSpec> Orb definitions.
duration Duration Loop duration.
Scaffold(
  body: Stack(
    children: [
      Positioned.fill(
        child: NeoOrbBackground(
          specs: buildAuthOrbs(NeoPalette.of(context)),
        ),
      ),
      const Center(child: Text('Your content')),
    ],
  ),
)

Use it as a background layer inside your own stack.

NeoMoonBackground and NeoMoonSpec

Animated crescent-like shape field for dark or high-contrast compositions.

Parameter Type Purpose
specs List<NeoMoonSpec> Moon definitions.
duration Duration Loop duration.
Positioned.fill(
  child: NeoMoonBackground(
    specs: [
      NeoMoonSpec(
        leftFactor: .1,
        topFactor: .2,
        size: 120,
        color: NeoColors.moon,
        shadowColor: palette.shadowSoft,
        pageColor: palette.page,
        borderColor: palette.outline,
        xTravel: 12,
        yTravel: 16,
      ),
    ],
  ),
)

Use it for layered visual texture without taking over page structure.

NeoShellBackground

Convenience background that chooses orb or moon visuals based on theme brightness.

Parameter Type Purpose
variant NeoShellBackgroundVariant Selects the preset composition.
NeoShellBackground.index constructor Maps an index to a preset variant.
const NeoShellBackground(
  variant: NeoShellBackgroundVariant.home,
)

Use it when you want a quick visual layer while still composing the page.

NeoProfileMotionBanner

Animated decorative banner made of moving bordered shapes.

Parameter Type Purpose
key Key? Optional widget key.
SizedBox(
  height: 180,
  child: NeoProfileMotionBanner(),
)

Use it inside a panel or header region as an accent layer.

Data and feedback widgets

NeoDataTableLite

Small horizontal-scroll data table with token-aware header and highlighted rows.

Parameter Type Purpose
columns List<NeoDataTableColumn> Column labels and flex values.
rows List<NeoDataTableRow> Row cell values.
NeoDataTableLite(
  columns: const [
    NeoDataTableColumn(label: 'Name', flex: 2),
    NeoDataTableColumn(label: 'Status'),
  ],
  rows: const [
    NeoDataTableRow(cells: ['API', 'Stable'], highlight: true),
  ],
)

Use it for small datasets; use a full data grid for very large tables.

NeoFilterChips and NeoFilterChipItem

Multi-select chip group with optional icons and wrapping or horizontal layout.

Parameter Type Purpose
items List<NeoFilterChipItem<T>> Available filter options.
selectedValues Set<T> Current selected values.
onChanged ValueChanged<Set<T>> Selection callback.
allowWrap bool Wraps chips when true.
NeoFilterChips<String>(
  selectedValues: selectedTags,
  onChanged: setTags,
  items: const [
    NeoFilterChipItem(value: 'ui', label: 'UI'),
    NeoFilterChipItem(value: 'motion', label: 'Motion'),
  ],
)

Use it with your own filter state.

NeoInfoBanner

Status banner with tone variants for information, success, warning, and error.

Parameter Type Purpose
title String Banner title.
message String Banner message.
variant NeoInfoBannerVariant Visual tone.
trailing Widget? Optional trailing widget.
NeoInfoBanner(
  variant: NeoInfoBannerVariant.warning,
  title: 'Check values',
  message: 'Some fields need review before saving.',
  trailing: const NeoPill(label: 'REVIEW'),
)

Use it for contextual feedback above forms and lists.

NeoMetricStrip and NeoMetricItem

Responsive strip of compact metric tiles.

Parameter Type Purpose
items List<NeoMetricItem> Metric values.
NeoMetricStrip(
  items: const [
    NeoMetricItem(label: 'Open', value: '12'),
    NeoMetricItem(label: 'Closed', value: '31'),
  ],
)

Use it for summary sections where each metric is small.

NeoStatusCluster and NeoStatusItem

Group of tone-aware status chips.

Parameter Type Purpose
items List<NeoStatusItem> Status chips.
spacing double Horizontal spacing.
runSpacing double Wrap spacing.
NeoStatusCluster(
  items: const [
    NeoStatusItem(label: 'Synced', tone: NeoStatusTone.success),
    NeoStatusItem(label: 'Review', tone: NeoStatusTone.warning),
  ],
)

Use it for compact status summaries.

Progress and timeline widgets

NeoProgressBadge

Small progress indicator with label and filled track.

Parameter Type Purpose
label String Progress label.
progress double Progress value from 0 to 1.
value String Display value, such as a percentage.
const NeoProgressBadge(
  label: 'Completion',
  progress: 0.72,
  value: '72%',
)

Use it in cards or headers where full progress bars are too large.

NeoShapeLoader

Animated loading indicator composed from Neo-Brutalist shapes.

Parameter Type Purpose
size double Loader width basis.
label String? Optional label.
duration Duration Loop duration.
const NeoShapeLoader(
  label: 'Loading components',
)

Use it for loading states that should match the visual language.

NeoStepper and NeoStepItem

Vertical step list with active and completed states.

Parameter Type Purpose
steps List<NeoStepItem> Step data.
currentStep int Current step index.
NeoStepper(
  currentStep: 1,
  steps: const [
    NeoStepItem(label: 'Account'),
    NeoStepItem(label: 'Details'),
    NeoStepItem(label: 'Confirm'),
  ],
)

Use it to show process state; you control navigation and validation.

NeoTabs and NeoTabItem

Responsive tab chip group with selected-state styling.

Parameter Type Purpose
items List<NeoTabItem> Tab labels and icons.
currentIndex int Selected index.
onChanged ValueChanged<int> Selection callback.
NeoTabs(
  currentIndex: tabIndex,
  onChanged: setTab,
  items: const [
    NeoTabItem(label: 'Widgets', icon: Icons.widgets_rounded),
    NeoTabItem(label: 'Motion', icon: Icons.bolt_rounded),
  ],
)

Use it with your own tab state and content switching.

NeoTimeline and NeoTimelineEntry

Vertical timeline for dated or ordered events.

Parameter Type Purpose
entries List<NeoTimelineEntry> Timeline rows.
highlightedIndex int? Optional highlighted row.
NeoTimeline(
  highlightedIndex: 1,
  entries: const [
    NeoTimelineEntry(title: 'Created', subtitle: 'Record added'),
    NeoTimelineEntry(title: 'Reviewed', subtitle: 'Quality check passed'),
  ],
)

Use it for audit trails, history, and multi-step summaries.

Onboarding and presentation widgets

NeoOrbSubmitButton and NeoOrbSubmitSpinner

Submit control that shrinks into an orb, awaits async work, and expands an overlay before calling onSuccess.

Parameter Type Purpose
label String Button label.
onSubmit Future<T?> Function() Async submit action.
onSuccess ValueChanged<T> Called when submit returns a non-null result.
NeoOrbSubmitButton<User>(
  label: 'Save',
  onSubmit: saveUser,
  onSuccess: (user) => Navigator.pop(context, user),
)

Use it for high-emphasis submit moments. Your callback owns validation, errors, and navigation.

NeoThemeToggle

Theme toggle with an orb reveal transition before invoking onChanged.

Parameter Type Purpose
isDark bool Current brightness state.
onChanged ValueChanged<bool> Called with next dark-mode state.
width double Control width.
height double Control height.
backgroundColor Color? Fill override.
NeoThemeToggle(
  isDark: isDark,
  onChanged: setDarkMode,
)

Use it with your own theme controller.

NeoAppSettingsSheet

Settings sheet for choosing theme mode and palette preset.

Parameter Type Purpose
themeMode ThemeMode Current theme mode.
preset NeoThemePreset Current palette preset.
onThemeModeChanged ValueChanged<ThemeMode> Theme mode callback.
onPresetChanged ValueChanged<NeoThemePreset> Palette callback.
onReset VoidCallback Reset callback.
NeoAppSettingsSheet(
  themeMode: themeMode,
  preset: preset,
  onThemeModeChanged: setThemeMode,
  onPresetChanged: setPreset,
  onReset: resetAppearance,
)

Use it when your app already exposes theme state.

NeoOnboardingPage and NeoOnboardingStep

Configurable presentation widget for a short multi-step introduction with custom text, icon, labels, and finish callback.

Parameter Type Purpose
appName String Displayed product or section name.
steps List<NeoOnboardingStep> Step content.
onFinish VoidCallback Called when the user finishes or skips.
iconMotion NeoOnboardingIconMotion Controls icon animation intensity.
showSkip bool Toggles skip action.
showBack bool Toggles back action.
skipLabel, backLabel, nextLabel, finishLabel String Action labels.
NeoOnboardingPage(
  appName: 'Design System',
  steps: const [
    NeoOnboardingStep(
      title: 'Compose surfaces',
      description: 'Use panels, inputs, and actions inside your own layout.',
      icon: Icons.dashboard_customize_rounded,
    ),
  ],
  onFinish: () => Navigator.pop(context),
)

Use it as a presentation component. You decide when to show it and what happens after completion.

NeoOnboardingWizard

Embeddable step wizard that renders arbitrary step content and exposes controls for custom action rows.

Parameter Type Purpose
steps List<NeoOnboardingWizardStep> Wizard step definitions.
showProgress bool Toggles progress UI.
initialIndex int Initial step.
onComplete VoidCallback? Completion callback.
onStepChange ValueChanged<int>? Index-change callback.
onStepChanged NeoOnboardingStepChanged? Step-change callback.
actionsBuilder NeoOnboardingActionsBuilder? Custom actions builder.
NeoOnboardingWizard(
  steps: [
    NeoOnboardingWizardStep(
      id: 'profile',
      title: 'Profile',
      content: NeoInputField(
        label: 'Name',
        hint: 'Enter a name',
        icon: Icons.person_rounded,
      ),
    ),
  ],
  onComplete: submit,
)

Use it inside your own form, dialog, or page.

NeoSplashPage

Animated presentation page with configurable logo content and next-page builder.

Parameter Type Purpose
nextPageBuilder WidgetBuilder Builds the next widget when animation completes.
logo Widget? Optional custom logo widget.
logoText String Text used by the default logo.
replace bool Uses replacement navigation when true.
NeoSplashPage(
  logo: const FlutterLogo(size: 72),
  nextPageBuilder: (_) => const CatalogPage(),
)

Use it only when an animated presentation moment fits your product. For smaller motion needs, use the animation primitives directly.

Platform support

The package uses Flutter, Material widgets, dart:math, dart:async, dart:ui, and Flutter animation APIs. It does not use platform channels.

Platform Support
Android Supported
iOS Supported
Web Supported
Windows Supported
macOS Supported
Linux Supported

Example app

The package includes a runnable example at example/lib/main.dart.

cd packages/neo_mobile_kit
flutter pub get
flutter run -d chrome

The example should be treated as documentation for component composition. It does not define application architecture or data behavior.

Contributing

Contributions should keep APIs composable, documented, and independent from application-specific behavior.

Before opening a pull request:

flutter analyze
flutter test

Document any new public symbol with Dartdoc and add a small example when the API introduces new behavior.

License

MIT. See LICENSE.

Libraries

core/theme/neo_theme
core/theme/neo_tokens
neo_mobile_kit
shared/animations/neo_animations
shared/animations/neo_entrance_group
shared/animations/neo_entrance_types
shared/animations/neo_fade_slide
shared/animations/neo_motion_tokens
shared/animations/neo_panel_drop
shared/animations/neo_pop
shared/animations/neo_press_motion
shared/animations/neo_scroll_reveal
shared/backgrounds/neo_auth_background
shared/backgrounds/neo_moon_background
shared/backgrounds/neo_orb_background
shared/backgrounds/neo_profile_motion_banner
shared/backgrounds/neo_shell_background
shared/layout/neo_breakpoints
shared/layout/neo_page_shell
shared/layout/neo_section_header
shared/layout/neo_spacing
shared/layout/neo_split_layout
shared/navigation/neo_app_bar
shared/navigation/neo_bottom_nav
shared/navigation/neo_orb_reveal_transition
shared/navigation/neo_side_menu
shared/onboarding/neo_onboarding_page
shared/splash/neo_splash_config
shared/splash/neo_splash_controller
shared/splash/neo_splash_page
shared/splash/widgets/bubble_wave_layer
shared/splash/widgets/floating_shape_layer
shared/splash/widgets/liquid_surface_layer
shared/splash/widgets/logo_reveal_layer
shared/splash/widgets/splash_drop_fill
shared/splash/widgets/splash_scene
shared/widgets/neo_accordion
shared/widgets/neo_action_tile
shared/widgets/neo_app_settings_sheet
shared/widgets/neo_bottom_sheet_card
shared/widgets/neo_button
shared/widgets/neo_compact_list_item
shared/widgets/neo_data_table_lite
shared/widgets/neo_detail_row
shared/widgets/neo_empty_state
shared/widgets/neo_filter_chips
shared/widgets/neo_icon_button
shared/widgets/neo_info_banner
shared/widgets/neo_input_field
shared/widgets/neo_list_item
shared/widgets/neo_metric_strip
shared/widgets/neo_onboarding_wizard
shared/widgets/neo_orb_submit_button
shared/widgets/neo_panel
shared/widgets/neo_pill
shared/widgets/neo_progress_badge
shared/widgets/neo_shape_loader
shared/widgets/neo_stat_card
shared/widgets/neo_status_cluster
shared/widgets/neo_stepper
shared/widgets/neo_summary_card
shared/widgets/neo_tabs
shared/widgets/neo_theme_toggle
shared/widgets/neo_timeline
shared/widgets/neo_window_panel