Skip to main content

hybrid_calendar 1.0.0 copy "hybrid_calendar: ^1.0.0" to clipboard
hybrid_calendar: ^1.0.0 copied to clipboard

HybridCalendar widget allows creating customized Calendar with various properties like padding, colors, limit days, etc.

Banner

A highly customizable and feature-rich Flutter calendar widget with support for date selection, range selection, swipe navigation, and extensive styling options.

Features #

  • Single Date Selection - Select individual dates with ease
  • Date Range Selection - Select start and end dates for ranges
  • Swipe Navigation - Navigate between months with smooth swipe gestures
  • Customizable Styling - Full control over colors, text styles, and sizing
  • Date Restrictions - Set min/max selectable dates and navigable months
  • Disabled Dates - Disable specific dates or days of the week
  • Adjacent Month Days - Show or hide days from previous/next months
  • Localization Support - Automatic localization based on device locale
  • Flexible Configuration - Extensive configuration options for all use cases

Installation #

Add this to your pubspec.yaml:

dependencies:
  hybrid_calendar: ^1.0.0
  flutter_bloc: ^8.1.0
  easy_localization: ^3.0.0

Quick Start #

Basic Usage With MinSelectableDate #

Banner

 HybridCalendar(
  config: CalendarConfig(
    disabledDaysOfWeek: {DayOfWeek.sunday},
    minSelectableDate: DateTime(2026, 2, 13),
  ),
  onDateSelected: (_) {},
),

Date With Range Selection and Swipe, Without Header and Adjacent Month Days #

Banner
HybridCalendar(
  config: CalendarConfig(
    enableSwipe: true,
    firstDayOfWeek: DayOfWeek.friday,
    showAdjacentMonthDays: false,
    showHeader: false,
    mustActivateDateRanges: true,
  ),
  initialSelectedDate: DateTime(2026, 4),
  onDateSelected: (_) {},
)

Dum Calendar #

Banner
Container(
  decoration: BoxDecoration(
    border: Border.all(color: Colors.blue.shade200, width: 5),
    borderRadius: BorderRadius.circular(20),
  ),
  child: HybridCalendar(
    config: CalendarConfig(
      mustActivateDateRanges: true,
      disabledDaysOfWeek: {DayOfWeek.sunday},
      disabledDates: {DateTime.now().subtract(const Duration(days: 7))},
      style: CalendarStyle(
        borderColor: Colors.transparent,
        selectedDateColor: Colors.lightBlue.shade800,
        disabledDateColor: Colors.lightBlue.shade100,
        arrowDisabledColor: Colors.amber,
        isInRangeDateColor: Colors.lightBlue.shade300,
        arrowLeftColor: Colors.blueGrey,
        arrowRightColor: Colors.cyan,

        selectedDateTextStyle: const TextStyle(
          color: Colors.white,
          fontSize: 30,
          fontWeight: FontWeight.bold,
        ),
        disabledDateTextStyle: const TextStyle(
          color: Colors.grey,
          fontSize: 20,
          fontStyle: FontStyle.italic,
        ),
        defaultDateTextStyle: const TextStyle(
          color: Colors.black87,
          fontSize: 22,
          fontWeight: FontWeight.w500,
        ),
        headerTextStyle: TextStyle(
          color: Colors.blue.shade600,
          fontSize: 20,
          fontWeight: FontWeight.w700,
        ),
          weekDayTextStyle: TextStyle(
          color: Colors.lightBlue.shade400,
          fontSize: 20,
        ),

        dayCellSize: 40,
        padding: const EdgeInsets.all(10),
        margin: const EdgeInsets.all(0),
      ),
    ),
    onDateSelected: (day) {
      debugPrint("Día seleccionado: ${day.date}");
    },
  ),
)

Calendar Date Picker #

Banner
HybridCalendar(
  config: CalendarConfig(
    disabledDaysOfWeek: {DayOfWeek.sunday},
    minNavigableMonth: DateTime(2025, 11),
    maxNavigableMonth: DateTime(2026, 4),
    showYearPickerHeader: true
  ),
  onDateSelected: (_) {},
),

Configuration Options #

CalendarConfig #

CalendarConfig({
  // Navigation limits
  DateTime? minNavigableMonth,
  DateTime? maxNavigableMonth,

  // Selection limits
  DateTime? minSelectableDate,
  DateTime? maxSelectableDate,

  // Disabled dates
  Set<DateTime> disabledDates = const {},
  Set<DayOfWeek> disabledDaysOfWeek = const {},

  // Display options
  DayOfWeek firstDayOfWeek = DayOfWeek.monday,
  bool showAdjacentMonthDays = true,
  bool showHeader = true,
  bool showWeekDayLabels = true,

  // Features
  bool enableSwipe = false,
  bool mustActivateDateRanges = false,

  // Styling
  CalendarStyle style = const CalendarStyle(),
})

CalendarStyle #

CalendarStyle({
  // Colors
  Color borderColor = const Color(0xFFB9BBC6),
  Color selectedDateColor = const Color(0xFF1D1D1B),
  Color disabledDateColor = Colors.transparent,
  Color defaultDateColor = Colors.transparent,
  Color isInRangeDateColor = const Color.fromARGB(255, 204, 204, 207),
  Color arrowDisabledColor = Colors.grey,

  // Text Styles
  TextStyle selectedDateTextStyle = ...,
  TextStyle disabledDateTextStyle = ...,
  TextStyle defaultDateTextStyle = ...,
  TextStyle headerTextStyle = ...,
  TextStyle weekDayTextStyle = ...,

  // Icons
  IconData arrowLeftIcon = Icons.keyboard_arrow_left_outlined,
  IconData arrowRightIcon = Icons.keyboard_arrow_right_outlined,
  Color arrowLeftColor = Colors.black,
  Color arrowRightColor = Colors.black,
  double arrowSize = 24,

  // Sizing
  double dayCellSize = 38,
  double borderRadius = 15,
  EdgeInsets padding = const EdgeInsets.symmetric(horizontal: 16),
  EdgeInsets margin = const EdgeInsets.all(16),
})

Date Restrictions #

HybridCalendar(
  config: CalendarConfig(
    minSelectableDate: DateTime.now(),
    maxSelectableDate: DateTime.now().add(Duration(days: 90)),
    disabledDaysOfWeek: {DayOfWeek.saturday, DayOfWeek.sunday},
    disabledDates: {
      DateTime(2026, 2, 14), // Valentine's Day
      DateTime(2026, 12, 25), // Christmas
    },
  ),
  onDateSelected: (day) {
    print('Selected: ${day.date}');
  },
)

Architecture #

This package uses the BLoC (Business Logic Component) pattern for state management:

  • CalendarBloc: Manages calendar state and handles events
  • CalendarEvent: Defines all possible calendar interactions
  • CalendarState: Represents the current state of the calendar
  • CalendarWeeksBuilder: Service for generating calendar weeks

Localization #

The calendar automatically adapts to the device's locale for month and day names. Ensure you have easy_localization configured in your app:

import 'package:easy_localization/easy_localization.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await EasyLocalization.ensureInitialized();

  runApp(
    EasyLocalization(
      supportedLocales: [Locale('en'), Locale('es'), Locale('fr')],
      path: 'assets/translations',
      fallbackLocale: Locale('en'),
      child: MyApp(),
    ),
  );
}

Platform Support #

  • ✅ iOS
  • ✅ Android

Dependencies #

  • flutter_bloc: ^8.1.0 - State management
  • easy_localization: ^3.0.0 - Internationalization support

Author ✒️ #


With ❤️ by RudoApps Flutter Team 😊

Rudo Apps

1
likes
150
points
8
downloads

Documentation

Documentation
API reference

Publisher

verified publisherrudo.es

Weekly Downloads

HybridCalendar widget allows creating customized Calendar with various properties like padding, colors, limit days, etc.

Homepage
Repository (GitHub)
View/report issues

Topics

#calendar

License

MIT (license)

Dependencies

easy_localization, flutter, flutter_bloc

More

Packages that depend on hybrid_calendar