Tiendana UI Kit
A comprehensive Flutter UI component library that provides a robust design system with reusable widgets, design tokens, and utilities for building consistent Flutter applications.
Features
- 🎨 Complete Design System: Design tokens, foundations, and component library
- 🌓 Dark Mode Support: Full theming support for light and dark modes
- 📱 Responsive: Components adapt to different screen sizes
- ♿ Accessible: Built with accessibility in mind
- 🎯 Type-Safe: Strongly typed APIs with enums and models
- 🔧 Customizable: Extensive customization options while maintaining consistency
Project Structure
lib/
├── constants/ # Icon constants, SVG paths, image paths
│ ├── app_icons.dart
│ ├── image_constants.dart
│ ├── svg_constants.dart
│ └── tiendana_icon_app.dart
│
├── enums/ # Component variant enums
│ ├── blockquote_enum.dart
│ ├── button_variant.dart
│ └── status_enum.dart
│
├── foundations/ # Semantic design decisions
│ ├── border.dart
│ ├── colors.dart
│ ├── input_border.dart
│ ├── spacing.dart
│ └── typography.dart
│
├── tokens/ # Raw atomic design values
│ ├── border.dart
│ ├── colors.dart
│ ├── shadows.dart
│ ├── size.dart
│ ├── spacing.dart
│ └── typography.dart
│
├── models/ # Data models for components
│ ├── blockquote_colors.dart
│ └── button_colors.dart
│
├── molecules/ # Reusable UI components
│ ├── buttons/ # Button components
│ ├── chips/ # Chip components
│ ├── input/ # Form input components
│ ├── miscellaneous/ # Checkbox, Switch, Snackbar
│ ├── nav/ # Navigation components
│ └── utilities/ # Helper components
│
├── ui/ # Theme and app configuration
│ ├── theme.dart
│ └── app_styles.dart
│
├── utils/ # Utilities and extensions
│ ├── extensions.dart
│ └── utils.dart
│
├── providers/ # Data providers (countries, etc.)
└── localizations/ # i18n support
Component Naming Convention
All components use the Tdn prefix (Tiendana):
TdnElevatedButtonTdnTextFormFieldTdnCheckBoxTdnSnackbarTdnDropdownButton
Note: Old components with App* prefix are deprecated and should not be used in new code.
Getting Started
Installation
Add to your pubspec.yaml:
dependencies:
tiendana_uikit:
git:
url: https://github.com/Tiendana/tiendana_uikit.git
ref: main
Prerequisites
- Flutter SDK: >=3.7.2
- Dart SDK: >=3.7.2
Quick Start
1. Import the Package
You can import the entire library or specific components:
// Import everything
import 'package:tiendana_uikit/tiendana_uikit.dart';
// Or import specific modules
import 'package:tiendana_uikit/molecules/buttons/buttons.dart';
import 'package:tiendana_uikit/molecules/input/input.dart';
import 'package:tiendana_uikit/foundations/foundations.dart';
2. Setup Theme
import 'package:tiendana_uikit/ui/theme.dart';
MaterialApp(
theme: ThemeProvider.light(),
darkTheme: ThemeProvider.dark(),
themeMode: ThemeMode.system,
home: MyApp(),
);
3. Use Components
import 'package:tiendana_uikit/molecules/buttons/tdn_elevated_button.dart';
import 'package:tiendana_uikit/molecules/input/tdn_text_form_field.dart';
import 'package:tiendana_uikit/molecules/input/tdn_check_box.dart';
// Button
TdnElevatedButton(
onPressed: () {},
child: Text('Submit'),
)
// Text Field
TdnTextFormField(
hintText: 'Enter your name',
onChanged: (value) {},
)
// Checkbox with Switch Style
TdnCheckBox(
title: Text('Enable notifications'),
value: isEnabled,
onChanged: (value) => setState(() => isEnabled = value),
)
Component Categories
Buttons
TdnElevatedButton- Primary action button with gradient supportTdnOutlinedButton- Secondary action buttonTdnTextButton- Tertiary text-only buttonTdnIconButton- Icon-only buttonTdnRoundIconButton- Rounded icon buttonTdnLoginButton- Specialized login buttonTdnNavbarButton- Navigation bar button with selection stateTdnBtnFormField- Button styled as a form field for stacking
Form Inputs
TdnTextFormField- Text input with validationTdnDropdownButton- Dropdown selectorTdnCheckBox- Switch-style checkbox fieldTdnImageInput- Image upload/selectionTdnPhoneFormField- Phone number inputTdnLoginFormField- Specialized login field
Chips
TdnChoiceChip- Single selection chipTdnInputChip- Deletable input chipTdnDropdown- Chip with dropdown
Miscellaneous
TdnCheckbox- Standard checkboxTdnCheckboxListTile- Checkbox with list tileTdnSwitch- Toggle switchTdnSwitchListTile- Switch with list tileTdnSnackbar- Animated notification messages
Utilities
TdnBlockquote- Styled blockquote componentTdnSystemStatus- System status indicator
Navigation
TdnNavbar- Navigation bar component
Usage Examples
Buttons
// Elevated button with gradient
TdnElevatedButton(
onPressed: () {},
child: Text('Submit'),
variant: ButtonVariant.primary,
)
// Outlined button
TdnOutlinedButton(
onPressed: () {},
child: Text('Cancel'),
variant: ButtonVariant.secondary,
)
// Round icon button
TdnRoundIconButton(
icon: Icons.add,
onPressed: () {},
)
Form Fields
// Text input
TdnTextFormField(
hintText: 'Enter your email',
prefixIcon: Icon(Icons.email),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value?.isEmpty ?? true) return 'Required';
return null;
},
)
// Dropdown
TdnDropdownButton(
label: 'Select country',
items: items,
onChanged: (value) {},
)
// Checkbox field
TdnCheckBox(
title: Text('Accept terms'),
value: accepted,
onChanged: (value) => setState(() => accepted = value),
)
Form Field Stacking
Create seamless multi-field forms:
Column(
children: [
// First field - rounded top, flat bottom
TdnTextFormField(
hintText: 'Name',
topFieldMode: true,
),
// Middle fields - flat top and bottom
TdnTextFormField(
hintText: 'Email',
withoutBorders: true,
),
TdnDropdownButton(
label: 'Country',
items: items,
withoutBorders: true,
),
// Last field - flat top, rounded bottom
TdnCheckBox(
title: Text('Agree to terms'),
value: agreed,
bottomFieldMode: true,
onChanged: (value) {},
),
],
)
Border Modes:
topFieldMode: true- Rounded top, square bottombottomFieldMode: true- Square top, rounded bottomwithoutBorders: true- Square all sides (for middle fields)
Snackbars
// Success snackbar with animation
ScaffoldMessenger.of(context).showSnackBar(
TdnSnackbar.success(
context: context,
message: 'Operation successful',
action: SnackBarAction(
label: 'UNDO',
onPressed: () {},
),
),
);
// Other variants
TdnSnackbar.error(context: context, message: 'Error occurred');
TdnSnackbar.info(context: context, message: 'Information');
TdnSnackbar.warning(context: context, message: 'Warning');
Features:
- Animated icon expansion
- Status-based colors
- Centered positioning
- Action button support
Chips
// Choice chip
TdnChoiceChip(
label: Text('Option 1'),
selected: true,
onSelected: (selected) {},
)
// Input chip
TdnInputChip(
label: Text('Tag'),
onDeleted: () {},
)
Navigation
// Navigation bar
TdnNavbar(
items: ['Home', 'Search', 'Profile', 'Settings'],
selectedIndex: _currentIndex,
onItemSelected: (index) {
setState(() => _currentIndex = index);
},
)
Utilities
// System status with animation
TdnSystemStatus(
text: 'Server Online',
status: StatusEnum.success,
enableAnimation: true,
)
// Error status
TdnSystemStatus(
text: 'Connection Failed',
status: StatusEnum.error,
)
// Blockquote variants
TdnBlockquote(
title: 'Important',
text: 'Read this carefully.',
variant: BlockquoteEnum.info,
)
TdnBlockquote(
title: 'Warning',
text: 'This cannot be undone.',
variant: BlockquoteEnum.warning,
)
TdnBlockquote(
title: 'Error',
text: 'Something went wrong.',
variant: BlockquoteEnum.alert,
)
Design System Architecture
Tokens (Raw Values)
Atomic design values that represent the smallest design decisions:
ColorsTokens.colorPrimary // #48DD0A
SpacingTokens.spacingMd // 16.0
TypographyTokens.fontSizeLg // 18.0
ShadowTokens.shadowMedium
BorderTokens.radiusMd
Foundations (Semantic Decisions)
Higher-level semantic meanings built on tokens:
ColorsFoundation.primaryLight
ColorsFoundation.inputBorderColor
TypographyFoundations.fontButton
SpacingFoundation.paddingLarge
BorderFoundation.inputBorderRadius
Best Practice: Use Foundations in your components for better semantic meaning and easier theming.
Color System
Light & Dark Mode
All colors have light and dark variants:
ColorsFoundation.primaryLight
ColorsFoundation.primaryDark
Status Colors
ColorsTokens.colorSuccess // Green
ColorsTokens.colorError // Red
ColorsTokens.colorInfo // Blue
ColorsTokens.colorWarning // Orange
Theme Colors
Theme.of(context).colorScheme.primary
Theme.of(context).colorScheme.secondary
Theme.of(context).colorScheme.surface
Typography
Use TypographyFoundations for consistent text styles:
Text(
'Hello World',
style: TypographyFoundations.fontButton,
)
// Or via context extensions
Text(
'Headline',
style: context.headlineLarge,
)
Available styles:
displayLarge,displayMedium,displaySmallheadlineLarge,headlineMedium,headlineSmalltitleLarge,titleMedium,titleSmallbodyLarge,bodyMedium,bodySmalllabelLarge,labelMedium,labelSmall
Spacing
Consistent spacing tokens:
SpacingTokens.spacing4 // 4.0
SpacingTokens.spacing8 // 8.0
SpacingTokens.spacing12 // 12.0
SpacingTokens.spacing16 // 16.0
SpacingTokens.spacing24 // 24.0
SpacingTokens.spacing32 // 32.0
// Or use foundations
SpacingFoundation.paddingSmall
SpacingFoundation.paddingMedium
SpacingFoundation.paddingLarge
Icons
Custom Icon Fonts
// Tiendana custom icons
Icon(TiendanaIconApp.power_up)
Icon(TiendanaIconApp.domicilio)
// App icons
Icon(AppIcons.turnos)
Images & Assets
// Access package images
Image(image: ImageConstants.assetImage('logo_largo.png'))
// Or use helper
ImageConstants.asset('logo_largo.png', width: 100)
Utilities
Extensions
// Context extensions
context.textTheme
context.colors
context.theme
// Typography extensions
context.headlineLarge
context.bodyMedium
// Breakpoint checks
constraints.isMobile
constraints.isTablet
constraints.isDesktop
// Duration extensions
"2:30".toDuration()
Duration(minutes: 5).toHumanizedString()
Dark Mode Check
bool isDark = TiendanaUtils.checkIfDarkTheme(context);
Animation Guidelines
Standard animation patterns used in the library:
class _MyWidgetState extends State<MyWidget>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 400),
vsync: this,
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
- Duration: 300-500ms for most transitions
- Curve:
Curves.easeOutCubicfor natural motion - Always dispose controllers
Best Practices
1. Use const Constructors
const TdnElevatedButton(
onPressed: null,
child: Text('Button'),
)
2. Prefer Named Parameters
TdnTextFormField(
hintText: 'Name',
errorText: 'Required',
enabled: true,
)
3. Use Foundations Over Tokens
// Good
color: ColorsFoundation.primaryLight
// Avoid
color: ColorsTokens.colorPrimary
4. Maintain Single Responsibility
Each component should have one clear purpose.
5. Document Public APIs
/// Brief description
///
/// Detailed explanation with examples
///
/// Usage:
/// ```dart
/// MyWidget(param: value)
/// ```
class MyWidget extends StatelessWidget {
/// Parameter description
final String param;
const MyWidget({super.key, required this.param});
}
Migration from Legacy Components
If you're using old App* prefixed components:
- Find the new
Tdn*equivalent - Update imports
- Check for API changes
- Test thoroughly
- Update documentation
Example:
// Old
AppButton(...)
// New
TdnElevatedButton(...)
Enums and Variants
Button Variants
enum ButtonVariant {
primary, // Primary actions (green/natura theme)
secondary, // Secondary actions (forest theme)
tertiary, // Tertiary actions
red, // Destructive/delete actions
lavender, // Alternative styling
}
Status Types
enum StatusEnum {
none, // Neutral/inactive state
success, // Success state (green)
warning, // Warning state (orange)
error, // Error state (red)
progress, // In-progress state (blue)
}
Blockquote Variants
enum BlockquoteEnum {
none, // Neutral styling
info, // Informational messages (blue)
warning, // Warning messages (yellow)
alert, // Error/alert messages (red)
}
Dependencies
Core dependencies:
flutter_svg: ^2.0.17- SVG renderinggoogle_fonts: ^6.3.2- Typographyflutter_animate: ^4.5.2- Advanced animationscollection: ^1.18.0- Collection utilities
Contributing
When creating new components:
- Place in appropriate
molecules/subdirectory - Use
Tdnprefix - Follow existing patterns
- Add documentation
- Support dark mode
- Include usage examples
- Export in main library file
Component Guidelines
- Consistent naming convention (
Tdnprefix) - Support dark mode when applicable
- Include comprehensive documentation with examples
- Use design tokens and foundations
- Provide proper accessibility support
Testing
Components should be testable in isolation:
testWidgets('TdnButton shows text', (tester) async {
await tester.pumpWidget(
MaterialApp(
home: TdnElevatedButton(
onPressed: () {},
child: Text('Test'),
),
),
);
expect(find.text('Test'), findsOneWidget);
});
License
TODO: Add license information
Additional Resources
Maintained by: Tiendana Team
Version: 0.0.1
Status: Active Development
For issues, feature requests, or questions, please visit our GitHub Issues page.
Libraries
- constants/app_icons
- Flutter icons AppIcons Copyright (C) 2021 by original authors @ fluttericon.com, fontello.com This font was generated by FlutterIcon.com, which is derived from Fontello.
- constants/image_constants
- constants/svg_constants
- constants/tiendana_icon_app
- Flutter icons MyFlutterApp Copyright (C) 2021 by original authors @ fluttericon.com, fontello.com This font was generated by FlutterIcon.com, which is derived from Fontello.
- enums/blockquote_enum
- enums/status_enum
- foundations/border
- foundations/colors
- foundations/foundations
- foundations/input_border
- foundations/spacing
- foundations/typography
- localizations/base_localizations
- models/blockquote_colors
- molecules/buttons/tdn_btn_form_field
- molecules/chips/chips
- molecules/chips/tdn_choice_chip
- molecules/chips/tdn_dropdown
- molecules/chips/tdn_input_chip
- molecules/input/input
- molecules/input/tdn_check_box
- molecules/input/tdn_document_form_field
- molecules/input/tdn_image_input
- molecules/input/tdn_login_form_field
- molecules/input/tdn_login_phone_input_text
- molecules/input/tdn_multi_select_dropdown
- molecules/input/tdn_phone_form_field
- molecules/input/tdn_single_select_dropdown
- molecules/input/tdn_text_form_field
- molecules/miscellaneous/miscellaneous
- molecules/miscellaneous/tdn_checkbox
- molecules/miscellaneous/tdn_checkbox_list_tile
- molecules/miscellaneous/tdn_snackbar
- molecules/miscellaneous/tdn_switch
- molecules/miscellaneous/tdn_switch_list_tile
- molecules/utilities/tdn_blockquote
- molecules/utilities/tdn_system_status
- providers/countries
- tiendana_uikit
- Tiendana UI Kit - A comprehensive Flutter UI component library
- tokens/border
- tokens/colors
- tokens/shadows
- tokens/size
- tokens/spacing
- tokens/tokens
- tokens/typography
- ui/app_styles
- ui/painters/tour_painter
- ui/src/models/tour_state
- ui/theme
- utils/extensions
- utils/utils