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):

  • TdnElevatedButton
  • TdnTextFormField
  • TdnCheckBox
  • TdnSnackbar
  • TdnDropdownButton

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 support
  • TdnOutlinedButton - Secondary action button
  • TdnTextButton - Tertiary text-only button
  • TdnIconButton - Icon-only button
  • TdnRoundIconButton - Rounded icon button
  • TdnLoginButton - Specialized login button
  • TdnNavbarButton - Navigation bar button with selection state
  • TdnBtnFormField - Button styled as a form field for stacking

Form Inputs

  • TdnTextFormField - Text input with validation
  • TdnDropdownButton - Dropdown selector
  • TdnCheckBox - Switch-style checkbox field
  • TdnImageInput - Image upload/selection
  • TdnPhoneFormField - Phone number input
  • TdnLoginFormField - Specialized login field

Chips

  • TdnChoiceChip - Single selection chip
  • TdnInputChip - Deletable input chip
  • TdnDropdown - Chip with dropdown

Miscellaneous

  • TdnCheckbox - Standard checkbox
  • TdnCheckboxListTile - Checkbox with list tile
  • TdnSwitch - Toggle switch
  • TdnSwitchListTile - Switch with list tile
  • TdnSnackbar - Animated notification messages

Utilities

  • TdnBlockquote - Styled blockquote component
  • TdnSystemStatus - System status indicator
  • 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 bottom
  • bottomFieldMode: true - Square top, rounded bottom
  • withoutBorders: 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 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, displaySmall
  • headlineLarge, headlineMedium, headlineSmall
  • titleLarge, titleMedium, titleSmall
  • bodyLarge, bodyMedium, bodySmall
  • labelLarge, 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.easeOutCubic for 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:

  1. Find the new Tdn* equivalent
  2. Update imports
  3. Check for API changes
  4. Test thoroughly
  5. 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 rendering
  • google_fonts: ^6.3.2 - Typography
  • flutter_animate: ^4.5.2 - Advanced animations
  • collection: ^1.18.0 - Collection utilities

Contributing

When creating new components:

  1. Place in appropriate molecules/ subdirectory
  2. Use Tdn prefix
  3. Follow existing patterns
  4. Add documentation
  5. Support dark mode
  6. Include usage examples
  7. Export in main library file

Component Guidelines

  • Consistent naming convention (Tdn prefix)
  • 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/button_variant
enums/status_enum
foundations/border
foundations/colors
foundations/foundations
foundations/input_border
foundations/spacing
foundations/typography
localizations/base_localizations
models/blockquote_colors
models/button_colors
molecules/buttons/buttons
molecules/buttons/tdn_btn_form_field
molecules/buttons/tdn_elevated_button
molecules/buttons/tdn_icon_button
molecules/buttons/tdn_login_button
molecules/buttons/tdn_navbar_button
molecules/buttons/tdn_outlined_button
molecules/buttons/tdn_round_icon_button
molecules/buttons/tdn_text_button
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_dropdown_button
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/nav/tdn_navbar
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