swiss_army_component 0.4.0
swiss_army_component: ^0.4.0 copied to clipboard
Swiss Army Component: a reusable Flutter component library with widgets, utilities, and theme support. Includes a CLI to help install and use the package in existing apps.
Swiss Army Component #
A reusable Flutter component library with widgets, theme helpers, validators, and a small CLI. This README answers the most common “how do I use X?” questions with examples for every component we ship.
Install #
Add to pubspec.yaml:
dependencies:
swiss_army_component: ^0.2.0
Or from the CLI (run inside your Flutter app directory):
sac install
flutter pub get
What’s Inside (and Examples) #
Import once:
import 'package:swiss_army_component/swiss_army_component.dart';
Buttons #
Column(
children: [
const AppElevatedButton(
title: 'Primary',
onPressed: doSomething,
),
const NormalElevatedButton(
title: 'Filled',
onPressed: doSomething,
),
const AppSecondaryElevatedButton(
label: 'Secondary',
onPressed: doSomething,
),
const AppOutlinedButton(
label: 'Outline',
onPressed: doSomething,
),
const ConfigElevatedButton(
label: 'Sized 40%',
width: 160,
onPressed: doSomething,
),
const ConfigOutlinedButton(
label: 'Outlined 40%',
width: 160,
onPressed: doSomething,
),
],
);
Key props: bgColor/textColor, radius, width/height, brdColor, buttonHeight.
Social Login #
Column(
children: [
SocialLoginButton(
provider: SocialProvider.google,
onPressed: () => handleGoogleSignIn(),
),
SocialLoginButton(
provider: SocialProvider.apple,
onPressed: () => handleAppleSignIn(),
),
SocialLoginButton(
provider: SocialProvider.facebook,
onPressed: () => handleFacebookSignIn(),
),
],
);
App Bars #
// Basic with gradient
Scaffold(
appBar: const CustomAppBar(
title: 'Dashboard',
gradientColors: [Color(0xFF10BB76), Color(0xFF086D50)],
),
);
// Solid background + custom back
CustomAppBar(
title: 'Settings',
backgroundColor: Colors.indigo,
onBack: () => Navigator.pop(context),
);
// Transparent overlay
const TransparentAppBar(
title: 'Profile',
foregroundColor: Colors.white,
);
// Search bar
SearchAppBar(
hintText: 'Search products...',
onChanged: (q) => filter(q),
gradientColors: [Colors.teal, Colors.green],
);
// Tabbed
TabbedAppBar(
title: 'Orders',
tabs: const [Tab(text: 'Active'), Tab(text: 'History')],
controller: tabController,
);
// Sliver (collapsing)
CustomScrollView(
slivers: [
CustomSliverAppBar(
title: 'Profile',
expandedHeight: 200,
gradientColors: [Colors.purple, Colors.deepPurple],
),
SliverList(...),
],
);
Key props: gradientColors, backgroundColor, transparent, actions, bottom, leading, onBack, titleWidget, height, elevation, shape.
Search #
// size controls bottom margin if ismargin=true
const CustomSearchBar(16);
Text Widgets #
const BrandNameText(title: 'Swiss Army');
const ProductTitleText(title: 'Travel Backpack', smallSize: true);
SmallAppText('Caption');
MedAppText('Body');
BigAppText('Headline');
ImportantAppText('Required Field');
PriceText(price: '1299.95', currency: Currency.naira, isProfit: true);
const SlashedPriceText(price: '1599', currency: '₺');
Note: AppText defaults to Google Fonts (Poppins), but you can use custom asset fonts by providing the fontFamily property or a textStyle with a font family.
Spacing Helpers #
Column(
children: [
vSpace(12),
hSpace(8),
Padding(padding: simPad(12, 16), child: const Text('Padded')),
],
);
Text Fields #
// Labeled input with validation
AppTextFormField(
label: 'Email',
hint: 'you@example.com',
keyboardType: TextInputType.emailAddress,
validator: FormValidator.isValidEmail,
textInputAction: TextInputAction.done,
);
// Minimal input
const NormalAppTextFormField(
hint: 'Username',
textInputAction: TextInputAction.next,
);
// Phone input
AppPhoneTextField(
label: 'Phone',
onChanged: (number) => debugPrint(number.completeNumber),
);
// Multiline
const AppMultiLineTextFormField(
label: 'Notes',
maxLines: 5,
textInputAction: TextInputAction.newline,
);
// Rounded pill input
const AppRoundedTextFormField(
hint: 'Search',
prefixIcon: IconButton(icon: Icon(Icons.search), onPressed: null),
);
// Bio/long text
const BioField(label: 'About you');
OTP Input #
OTPTextField(
controller: otpController,
onCompleted: (code) => debugPrint('OTP: $code'),
);
6-digit input using pinput, with a disabled soft keyboard by default.
Validators #
Form(
child: AppTextFormField(
label: 'Password',
obscureText: true,
validator: FormValidator.isValidPassword,
textInputAction: TextInputAction.done,
),
);
Available checks: isValidEmail, isValidFullName, isValidName, isValidUsername, isValidPhone, isValidPassword.
Logging #
appLog('User logged in', {'id': userId});
Theme (Light/Dark + Overrides) #
// Default palettes
MaterialApp(
theme: SACTheme.light(),
darkTheme: SACTheme.dark(),
);
// Per-mode overrides
final config = SACThemeConfig(
// Shared base colors (fallback)
primary: Colors.blue,
secondary: Colors.amber,
// --- Light Mode Overrides ---
primaryLight: Colors.teal,
backgroundLight: const Color(0xFFFDFCF9), // Light background
scaffoldBackgroundLight: Colors.white, // specific scaffold color
appBarBackgroundLight: Colors.white, // specific app bar color
inputFillColorLight: Colors.grey[100], // specific input color
// --- Dark Mode Overrides ---
primaryDark: Colors.deepPurple,
backgroundDark: const Color(0xFF0E1116), // Dark background
scaffoldBackgroundDark: Colors.black, // specific scaffold color
appBarBackgroundDark: Colors.grey[900], // specific app bar color
inputFillColorDark: Colors.grey[800], // specific input color
// --- Component Geometry (Shared) ---
appBarElevation: 0,
inputBorderRadius: 12.0,
fontFamily: 'Roboto',
);
MaterialApp(
theme: SACTheme.light(config),
darkTheme: SACTheme.dark(config),
);
Advanced Theme Customization #
SACThemeConfig supports over 50 properties for granular control over every component:
- Structure:
scaffoldBackground...,appBarBackground...,drawerWidth,visualDensity - Navigation:
bottomNav...,navigationBar...,navigationRail... - Buttons:
fab...,elevatedButtonStyle,outlinedButtonStyle, etc. - Inputs:
inputFillColor...,inputBorderRadius,switchActiveColor,checkboxFillColor - Surfaces:
cardColor...,dialogBackground...,bottomSheet...,snackBar... - Typography:
fontFamily,displayLarge,bodyMedium, etc.
Mode-specific fields (...Light / ...Dark) allow you to create completely distinct visual identities for light and dark modes while sharing structural traits like border radius.
CLI Commands #
To use the sac command-line tool globally, first activate it:
dart pub global activate swiss_army_component
Make sure ~/.pub-cache/bin is in your PATH. Then you can use:
sac install— Adds the package dependency to your project's pubspec.yamlsac doctor— Quick environment checksac examples— Prints code snippets for reference
Exports Map #
Public API (from swiss_army_component.dart):
- Widgets: AppElevatedButton, NormalElevatedButton, AppSecondaryElevatedButton, AppOutlinedButton, ConfigElevatedButton, ConfigOutlinedButton, CustomAppBar, CustomSearchBar, OTPTextField, text widgets (SmallAppText, MedAppText, BigAppText, PriceText, SlashedPriceText, BrandNameText, ProductTitleText, ImportantAppText), spacing helpers (vSpace, hSpace, simPad), text fields (AppTextFormField, NormalAppTextFormField, AppPhoneTextField, AppMultiLineTextFormField, AppRoundedTextFormField, BioField).
- Theme: SACTheme, SACThemeConfig, SACThemeBase, AppChipTheme, AppColors.
- Utilities: FormValidator, appLog.
Project Structure #
lib/
├── widgets/ # Reusable UI components
├── utils/ # Theme + validators + logging
│ ├── theme/ # Theme builders and config
│ ├── validators/ # Form validators
│ └── logging/ # Logging utility
└── swiss_army_component.dart # Public exports
Publishing to pub.dev #
- Bump version in
pubspec.yaml. - Update
CHANGELOG.md. - Run
flutter pub publish.
Support #
For issues, feature requests, or questions:
- Open an issue on GitHub Issues
- Check existing issues before filing new ones