bc_ui 0.4.2 copy "bc_ui: ^0.4.2" to clipboard
bc_ui: ^0.4.2 copied to clipboard

A Flutter design system porting heroui-native 1:1 — 60+ token-driven components, light and dark, on a Material 3 base.

bc_ui — HeroUI Native, ported to Flutter

A Flutter design system that ports heroui-native 1:1
Same tokens, same variants, same motion — on a Material 3 base, so the rest of the Material ecosystem keeps working.

API reference · Components · Theming · Example app


Why #

  • One token system, 64 semantic color slots. Every color is precomputed from heroui-native's oklch sources — including each color-mix derived hover/soft shade — into a light and a dark palette. No component hard-codes a color.
  • iOS-grade surfaces. Continuous ("squircle") corners via RoundedSuperellipseBorder, layered surface/overlay shadows, and frosted headers built on real BackdropFilter blur.
  • The motion is ported, not approximated. Press scale 0.985 with width compensation, switch thumb spring (mass 2 / stiffness 1600 / damping 120), tab indicator that tracks your finger, 1500ms shimmer — see BCMotion.
  • Material stays available. BCTheme.light() returns a ThemeData, so Scaffold, Navigator, showDialog and every Material widget still work.
  • Inter is bundled. No font setup, no missing-glyph surprises.
  • 60+ components, all light/dark aware, all documented in the API reference.
Light Dark
Light theme Dark theme

The screen above is assembled entirely from bc_ui — header, card, buttons, tabs, list group, chips, bottom nav. Its source is example/lib/showcase/screens/demo_app_screen.dart.

Install #

flutter pub add bc_ui

or add it by hand:

dependencies:
  bc_ui: ^0.4.0

Requires Dart SDK ^3.12.1. The only runtime dependency is phone_numbers_parser, which BCPhoneField uses for parsing and validation — pure Dart, no platform channels.

Setup #

import 'package:bc_ui/bc_ui.dart';

MaterialApp(
  theme: BCTheme.light(),
  darkTheme: BCTheme.dark(),
  themeMode: ThemeMode.system,
  // Only needed if you use BCToast:
  builder: (context, child) => BCToastProvider(child: child!),
  home: const HomeScreen(),
);

That's the whole setup — every component reads its colors from the BCThemeExtension those two factories install.

Quick start #

// Buttons: 7 variants x 3 sizes
BCButton(
  variant: BCButtonVariant.secondary,
  onPressed: () {},
  startContent: const Icon(Icons.add, size: 18),
  child: const Text('Add item'),
);

// A frosted app header — pair with extendBodyBehindAppBar so there is
// something to blur. The hairline appears only once content scrolls under.
Scaffold(
  extendBodyBehindAppBar: true,
  appBar: BCAppHeader(
    title: const Text('Inbox'),
    subtitle: const Text('12 unread'),
    actions: [
      BCHeaderIconButton(icon: const Icon(Icons.search), onPressed: () {}),
    ],
  ),
  body: ListView(children: const []),
);

// Swipeable tabs: the bar and the panels share one controller, so a drag
// switches tabs and carries the indicator with it.
final tabs = BCTabsController<String>(values: const ['music', 'podcasts']);

Column(
  children: [
    BCTabs(items: items, controller: tabs, fullWidth: true),
    Expanded(
      child: BCTabView(
        controller: tabs,
        children: const [MusicPanel(), PodcastsPanel()],
      ),
    ),
  ],
);

// Compound form field with built-in validation states
BCTextField(
  isRequired: true,
  children: [
    const BCTextFieldLabel('Email'),
    const BCTextFieldInput(hintText: 'you@example.com'),
    const BCTextFieldDescription("We'll never share your email."),
  ],
);

// Toast
BCToast.show(context, const BCToastData(
  title: 'Changes saved',
  variant: BCToastVariant.success,
));

Components #

Full props, defaults and enums for every entry: API reference.

Category Components
Navigation BCAppHeader · BCSliverAppHeader · BCHeaderIconButton · BCBottomNav · BCNavRail · BCNavDrawer · BCToolbar · BCTabs · BCTabView
Actions BCButton · BCSocialAuthButton · BCBrandLogo · BCLinkButton · BCCloseButton · BCFab · BCSpeedDial · BCToggleButton · BCToggleButtonGroup · BCPressable
Containers BCSurface · BCCard · BCListGroup · BCAccordion · BCFlipCard · BCScrollShadow
Data display BCText · BCAvatar · BCChip · BCRibbon · BCTagGroup · BCSeparator · BCSkeleton · BCSpinner · BCProgress · BCLoadingOverlay · BCRating · BCEmptyState
Forms BCInput · BCTextField · BCTextArea · BCPasswordInput · BCSearchField · BCInputOTP · BCDateField · BCTimeField · BCDateTimePicker · BCPhoneField · BCSelect · BCControlField
Selection BCCheckbox · BCRadioGroup · BCSwitch · BCSlider · BCRangeSlider
Overlays BCDialog · BCPopover · BCMenu · BCToast

The three pickers — BCDateField, BCTimeField, BCDateTimePicker — share a presentation prop (dialog, popover, bottomSheet), so swapping one for another never changes how it opens.

Naming is predictable across the library: variant picks the look, size picks the metrics, state is controlled (value + onValueChange), and disabled/invalid are always isDisabled / isInvalid.

Theming #

Custom accent #

BCTheme.light(
  overrides: BCThemeOverrides(accent: const Color(0xFF0F766E)),
);

Accent-derived tokens (hover, soft, soft-foreground, focus) are recomputed for you, so a single color change stays consistent everywhere.

Reading tokens in your own widgets #

final bc = context.bcTheme;

DecoratedBox(
  decoration: ShapeDecoration(
    color: bc.accentSoft,
    shape: BCShapes.continuous(BCRadius.xxl),
    shadows: bc.surfaceShadow.shadows,
  ),
);

Design tokens #

BCColorsLight/BCColorsDark (raw palettes) · BCRadius (2→32, field 14) · BCSpacing (4px unit) · BCTypography (tailwind text scale) · BCShadows (layered surface/overlay shadows) · BCMotion (springs and timings) · BCShapes (continuous corners) · BCSizes · BCDuration · BCBreakpoints.

See Theme and tokens for the full list.

Example app #

example/ mirrors heroui-native's demo: a full demo screen plus one page per component, each with vertically paged usage variants and a pagination rail.

cd example && flutter run

Using bc_ui with an AI agent #

The repo ships an agent skill that teaches Claude Code, Cursor, Copilot and friends to reach for the right component, pass real props, and read colors from the theme instead of hard-coding them.

npx skills add binary-castle/bc-ui-flutter

Or copy skills/bc-ui/ into your project's .claude/skills/ by hand — the skill ships inside the published package too, so it is already in your pub cache.

Its per-component references are generated by the same script that writes doc/api.md, so they cannot drift from the source.

Documentation #

  • API reference — every component, prop, default and enum. The prop tables are generated from the source, so they track the code.
  • dart doc generates the full dartdoc site from the inline documentation.
  • Regenerate both the reference and the agent skill with python3 tool/gen_api_doc.py; --check fails if either is stale, and --check-coverage lists public symbols nothing documents. Run both before publishing.

Tests #

flutter test

License #

Apache-2.0 — see LICENSE.

bc_ui is a port of heroui-native (Apache-2.0, © NextUI Inc.), reimplemented in Dart against Flutter's widget layer. NOTICE records the attribution, how the port differs, and the bundled Inter font (OFL) and CC0 brand marks.

3
likes
160
points
548
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A Flutter design system porting heroui-native 1:1 — 60+ token-driven components, light and dark, on a Material 3 base.

Repository (GitHub)
View/report issues

License

Apache-2.0 (license)

Dependencies

flutter, phone_numbers_parser

More

Packages that depend on bc_ui