bkey_uikit 0.0.1 copy "bkey_uikit: ^0.0.1" to clipboard
bkey_uikit: ^0.0.1 copied to clipboard

BMoni design system for Flutter — typography, colour tokens, themes and a curated set of reusable UI primitives shared across Bkey products.

bkey_uikit #

Pub Version Flutter Dart License

A shared Flutter UI component library for Bkey products, built on top of the BMoni design system.

bkey_uikit provides design tokens, typography, theming, and reusable UI primitives that are used across Bkey Flutter apps. It has no dependency on any specific app's business logic, state management, routing, or localisation framework.


📋 What's Inside #

Layer Contents
Design Tokens BMoniColors — full colour palette + semantic light/dark tokens
BMoniTextStyles — complete type scale (display, heading, body, label)
BMoniTheme — Flutter ThemeData factory + TextTheme wiring
Enums Button, text-field, display, and status enums shared by all components
Components Buttons, text fields, text widgets, avatars, toasts, bottom sheets, empty states, loaders, layout primitives, and wallet cards
Fonts Rethink Sans (400–800, regular + italic) bundled in assets/fonts/
Wallet Assets Default wallet background art (USD/NGN/EUR/GBP/CAD/MXN/consolidated) plus 6 colour variants per currency, and shared SVG icons (logo_alt, info, eye_alt, eye_closed) bundled in assets/images/wallets/ and assets/svgs/

🚀 Installation #

Add bkey_uikit as a dependency in your pubspec.yaml:

dependencies:
  bkey_uikit: ^0.0.1

(Note: Adjust the installation instructions based on whether the package is published publicly or via a private git repository/path).


🛠️ Setup #

Wrap your app with BMoniTheme.darkTheme() (or the appropriate theme) to apply the full design system:

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

void main() {
  runApp(
    MaterialApp(
      theme: BMoniTheme.darkTheme(),
      home: const MyHomePage(),
    ),
  );
}

Import everything from a single barrel file:

import 'package:bkey_uikit/bkey_uikit.dart';

🎨 Design Tokens #

Colours #

Container(color: BMoniColors.brand500)
Container(color: context.colors.bg.greySubtle) // theme-aware extension

Typography #

Text('Hello', style: BMoniTextStyles.h4Semibold)
Text('Body', style: BMoniTextStyles.p2Regular)

🧩 Components Reference #

Every component below is exported from the single package:bkey_uikit/bkey_uikit.dart barrel.

Buttons & Actions #

BMoniButton

Primary action button with four visual variants and five sizes. Supports leading/trailing icons, loading state, and per-instance colour overrides. Triggers a light haptic on press.

BMoniButton(
  onPressed: () {},
  text: 'Confirm',
  variant: BMoniButtonVariant.primary,   // primary | secondary | outline | ghost
  size: BMoniButtonSize.large,            // extraSmall | small | medium | large | custom
  icon: Icons.check,
  iconPosition: BMoniButtonIconPosition.leading,
  isLoading: false,
  isDisabled: false,
)

// Convenience factories
BMoniButton.primary(onPressed: () {}, text: 'Save')
BMoniButton.secondary(onPressed: () {}, text: 'Edit')
BMoniButton.outline(onPressed: () {}, text: 'Cancel')
BMoniButton.ghost(onPressed: () {}, text: 'Skip')

UtilityButton

Square icon-only button used for compact toolbar actions.

UtilityButton(
  onTap: () {},
  size: 36,
  backgroundColor: BMoniColors.brand600,
  icon: const Icon(Icons.add, color: Colors.white, size: 24),
)

SwipeableActionRow

Row that reveals an action button when swiped left. A shared ValueNotifier<String?> ensures only one row is open at a time within a list.

final openItemId = ValueNotifier<String?>(null);

SwipeableActionRow(
  itemId: 'item-1',
  openItemId: openItemId,
  actionWidth: 72,
  actionColor: Colors.red,
  actionIcon: const Icon(Icons.delete, color: Colors.white),
  onActionPressed: () {/* delete */},
  onTap: () {/* open detail */},
  child: ListTile(title: Text('Swipe me left')),
)

Text & Typography #

Helper widgets that wrap Text with the BMoni type scale.

DisplayText('Welcome', level: 2, weight: DisplayWeight.bold)
HeadingText('Page title', level: 3, weight: HeadingWeight.semibold)
BodyText('Lorem ipsum', size: BodySize.medium, weight: BodyWeight.regular)
LabelText('Caption', size: LabelSize.small, weight: LabelWeight.medium)

// Domain-specific helpers
AmountText(1234.56, currency: r'$', decimalPlaces: 2)
StatusText('Pending', status: StatusType.warning)

ReadMoreText

Collapsible text widget with length- or line-based trimming, custom toggle labels, RegExp-based annotations, and rich-text support.

ReadMoreText(
  longString,
  trimMode: TrimMode.line,
  trimLines: 3,
  trimCollapsedText: 'read more',
  trimExpandedText: 'show less',
  onExpandChanged: (isExpanded) {},
)

Inputs & Forms #

BMoniTextFormField

Form field with two variants (filled and outlined), three sizes, label/helper/error slots, and prefix/suffix widgets.

BMoniTextFormField.filled(
  label: 'Email',
  hintText: 'you@example.com',
  keyboardType: TextInputType.emailAddress,
  size: BMoniTextFieldSize.medium,
  prefixIcon: const Icon(Icons.mail_outline),
  validator: (value) => value!.isEmpty ? 'Required' : null,
)

BMoniTextFormField.outlined(
  label: 'Reference',
  hintText: 'INV-001',
)

BMoniTextAreaField

Multiline note input with a built-in grapheme-aware character counter.

BMoniTextAreaField(
  controller: _noteController,
  label: 'Add a note',
  hintText: 'Optional message',
  maxLength: 120,
  maxLines: 4,
)

FileUploadWidget

Dotted-border upload area. Switches between placeholder, loading, and uploaded states.

FileUploadWidget(
  fileBytes: bytes,
  fileName: 'invoice.pdf',
  isLoading: false,
  onTap: pickFile,
  onRemove: () => setState(() => bytes = null),
  errorMessage: validationError,
)

Avatars & Images #

ProfileAvatar & ChatAvatar

ProfileAvatar(imageUrl: user.avatarUrl, name: user.fullName, size: 48)

ChatAvatar(
  imageUrl: null,
  name: 'Alice Doe',
  userId: 'u_123',
  size: 40,
)

ProfileImageWidget

Tap-aware profile image that supports network URLs, asset paths, and local files. Caches network images.

ProfileImageWidget(
  imageUrl: profile.imageUrl,
  radius: 40,
  onTap: pickNewAvatar,
)

Layout & Containers #

ActivitySectionCard & SectionHeader

ActivitySectionCard(
  header: const SectionHeader(
    title: 'Recent activity',
    trailing: Text('View all'),
  ),
  child: const Padding(
    padding: EdgeInsets.all(16),
    child: Text('Section content'),
  ),
  footer: const Divider(),
)

InfoCard

Inline informational/warning/tip card.

InfoCard(
  message: 'Your KYC is being reviewed.',
  title: 'In review',
  icon: Icons.info_outline,
)

CustomAppBar

Scaffold(
  appBar: CustomAppBar(
    title: 'Settings',
    showBackButton: true,
    actions: [IconButton(onPressed: () {}, icon: const Icon(Icons.help))],
  ),
)

Sheets & Overlays #

BMoniBottomSheet.show & BMoniTitledBottomSheet

final result = await BMoniBottomSheet.show<String>(
  context: context,
  child: const BMoniTitledBottomSheet(
    title: 'Choose option',
    children: [/* ... */],
  ),
);

BMoniOptionsBottomSheet

BMoniOptionsBottomSheet(
  title: 'More actions',
  options: [
    BMoniBottomSheetOption(icon: 'assets/svgs/edit.svg', title: 'Edit', onTap: () {}),
    BMoniBottomSheetOption(icon: 'assets/svgs/delete.svg', title: 'Delete', onTap: () {}),
  ],
)

SelectorBottomSheet<T> & SearchableSelectorBottomSheet<T>

final picked = await BMoniBottomSheet.show<Currency>(
  context: context,
  child: SelectorBottomSheet<Currency>(
    items: currencies,
    selected: current,
    title: 'Choose currency',
    label: (c) => c.name,
    value: (c) => c.code,
    icon: (c) => c.flagAsset,
    showIcon: true,
  ),
);

Feedback & Status #

BMoniToast and BMoniToastOverlay

BMoniToastOverlay.showSuccess(
  context: context,
  message: 'Payment sent!',
  title: 'Success',
);

BMoniToastOverlay.showError(context: context, message: 'Network error');

EmptyState, FailureWidget, & InProgressWidget

EmptyState(
  svgAsset: 'assets/svgs/empty_box.svg',
  message: 'No transactions yet',
  subtitle: 'Send or receive funds to get started',
  buttonText: 'Add money',
  onButtonPressed: () {},
)

Loaders

const ProgressLoaderWidget() // Square branded loading container
const ChasingDots() // Three small white dots animating

Wallet Cards #

BMoniWalletCard

A 250px-tall card with a configurable background, a top-left logo slot, an optional bottom-right info button, a centred balance slot, and a built-in scale-down press animation.

BMoniWalletCard(
  background: const BMoniWalletCardBackground.type(BMoniWalletType.usd),
  onInfoTap: () => showWalletDetails(),
  reserveBottomSpaceForPageIndicator: hasMultiplePages,
  balanceChild: BMoniWalletCardBalance(
    wholePart: r'$1,234',
    decimalPart: '.56',
    isHidden: isBalanceHidden,
    onToggleHidden: toggleHideBalance,
  ),
)

🧪 Testing #

Run the tests using the standard Flutter test command:

flutter test

💡 Example #

A complete component gallery lives in the example/ directory. It boots straight into a navigable list of every widget grouped by category (buttons, inputs, sheets, wallet cards, feedback, …) and is themed with BMoniTheme.darkTheme().

cd example
flutter pub get
flutter run

📄 License #

Copyright 2026 Bkey, Inc.

Licensed under the Apache License, Version 2.0 — you may use, modify, and distribute the SDK (including in proprietary applications) provided you preserve the copyright and license notices and comply with the terms in the LICENSE file.

For commercial support or enterprise inquiries, contact developers@bkey.me.

2
likes
160
points
32
downloads

Documentation

Documentation
API reference

Publisher

verified publisherbkey.me

Weekly Downloads

BMoni design system for Flutter — typography, colour tokens, themes and a curated set of reusable UI primitives shared across Bkey products.

Repository (GitHub)
View/report issues

Topics

#ui #design-system #widget #components #bkey

License

Apache-2.0 (license)

Dependencies

cached_network_image, characters, dotted_border, flutter, flutter_svg

More

Packages that depend on bkey_uikit