timely_x 0.0.11 copy "timely_x: ^0.0.11" to clipboard
timely_x: ^0.0.11 copied to clipboard

Timely X, a calendar plugin for Flutter.

Timely X Flutter #

pub package License: MIT PRs Welcome

A powerful and customizable calendar and resource scheduling library for Flutter applications. Timely X provides beautiful, responsive calendar views and resource scheduling components to help you build professional scheduling applications with ease.

📱 Screenshots #

Day View Week View Month View Resource View
Day View Week View Month View Resource View

✨ Features #

  • Multiple View Modes: Switch between Day, Week, and Month views
  • Resource Scheduling: Manage resources like rooms, employees, or equipment
  • Fully Customizable: Customize colors, layouts, and behaviors
  • Responsive Design: Works on mobile, tablet, and desktop
  • Interactive: Support for drag & drop, swipe gestures, and more
  • Localization: Built-in support for multiple languages
  • Theming: Seamlessly integrates with your app's theme

🚀 Installation #

Add the following to your pubspec.yaml file:

dependencies:
  timely_x: ^0.0.1  # Check for the latest version
  intl: ^0.18.0      # For date formatting
  jiffy: ^6.2.0      # For date manipulation

Then run:

flutter pub get

🎯 Quick Start #

Basic Calendar #

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Timely X Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: CalendarScreen(),
    );
  }
}

class CalendarScreen extends StatelessWidget {
  final List<TyxEvent> events = [
    TyxEvent(
      id: '1',
      title: 'Team Meeting',
      start: DateTime.now().add(Duration(hours: 10)),
      end: DateTime.now().add(Duration(hours: 11)),
      color: Colors.blue,
    ),
    // Add more events...
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Timely X Calendar'),
        actions: [
          IconButton(
            icon: Icon(Icons.today),
            onPressed: () {
              // Handle today button press
            },
          ),
        ],
      ),
      body:   Expanded(
              child: TyxCalendarView<AppointmentModel>(
                onViewChanged: (view) {
                  //  _activeView = view;
                },
                onDateChanged: (view, events) {},
                onBorderChanged: (border) {
                  _filter = (_filter ?? AppointmentFilter())
                      .copyWith(startDate: border.start, endDate: border.end);
                  _loadAppointments();
                },
                option: TyxCalendarOption<AppointmentModel>(
                  timesCellWidth: 60,
                  initialView: TyxView.day,
                  events: allEvents,
                  monthOption: TyxCalendarMonthOption<AppointmentModel>(
                    eventListTileBuilder: (context, event) {
                      var colorScheme = ColorScheme.fromSeed(
                        seedColor: event.provider!.appointmentColor != null
                            ? ColorsUtils.hexToColor(
                                event.provider!.appointmentColor!)
                            : event.color,
                      );
                      return Card(
                        margin: const EdgeInsets.only(bottom: 8),
                        elevation: 0.2,
                        surfaceTintColor: colorScheme.primaryContainer,
                        child: Padding(
                          padding: const EdgeInsets.all(12.0),
                          child: Row(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Container(
                                width: 4,
                                height: 50,
                                decoration: BoxDecoration(
                                  color: colorScheme.primary,
                                  borderRadius: BorderRadius.circular(2),
                                ),
                              ),
                              const SizedBox(width: 12),
                              Expanded(
                                child: Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: [
                                    Row(
                                      children: [
                                        Container(
                                          padding: EdgeInsets.symmetric(
                                              horizontal: 4, vertical: 4),
                                          decoration: BoxDecoration(
                                            color: colorScheme.primaryContainer,
                                            borderRadius:
                                                BorderRadius.circular(20),
                                          ),
                                          child: SelectableText(
                                            event.code ?? 'N/A',
                                            style: TextStyle(
                                              color: colorScheme
                                                  .onPrimaryContainer,
                                              fontWeight: FontWeight.w600,
                                              fontSize: 11,
                                            ),
                                          ),
                                        ),
                                        SizedBox(width: 8),
                                        Expanded(
                                          child: Text(
                                            AppointmentUtils
                                                .getAppointmentTitle(event),
                                            style: Theme.of(context)
                                                .textTheme
                                                .titleSmall
                                                ?.copyWith(
                                                  fontWeight: FontWeight.bold,
                                                ),
                                            maxLines: 1,
                                            overflow: TextOverflow.ellipsis,
                                          ),
                                        ),
                                      ],
                                    ),
                                    const SizedBox(height: 4),
                                    Text(
                                      '${TimeOfDay.fromDateTime(event.start).format(context)} - ${TimeOfDay.fromDateTime(event.end).format(context)}',
                                      style:
                                          Theme.of(context).textTheme.bodySmall,
                                    ),
                                    if (event.store != null)
                                      Padding(
                                        padding: const EdgeInsets.only(top: 4),
                                        child: Row(
                                          children: [
                                            Icon(
                                              Icons.location_on_outlined,
                                              size: 14,
                                              color: Theme.of(context)
                                                  .disabledColor,
                                            ),
                                            const SizedBox(width: 4),
                                            Expanded(
                                              child: Text(
                                                event.store!.name!,
                                                style: Theme.of(context)
                                                    .textTheme
                                                    .bodySmall
                                                    ?.copyWith(
                                                      color: Theme.of(context)
                                                          .disabledColor,
                                                    ),
                                                maxLines: 1,
                                                overflow: TextOverflow.ellipsis,
                                              ),
                                            ),
                                          ],
                                        ),
                                      ),
                                  ],
                                ),
                              ),
                            ],
                          ),
                        ),
                      );
                    },
                  ),
                ),
                onEventTapped: (event) {
                  context.router.push(AppointmentDetailsRoute(id: event.id));
                },
              ),
            ),,
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // Add new event
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

🛠️ Advanced Usage #

Custom Event Widget #

eventBuilder: (context, event) {
  return Container(
    margin: EdgeInsets.symmetric(horizontal: 2, vertical: 1),
    padding: EdgeInsets.all(4),
    decoration: BoxDecoration(
      color: event.color?.withOpacity(0.2) ?? Theme.of(context).primaryColor.withOpacity(0.2),
      borderRadius: BorderRadius.circular(4),
      border: Border.all(
        color: event.color ?? Theme.of(context).primaryColor,
        width: 1,
      ),
    ),
    child: Text(
      event.title ?? '',
      style: TextStyle(
        color: event.color ?? Theme.of(context).primaryColor,
        fontSize: 12,
        fontWeight: FontWeight.w500,
      ),
      maxLines: 2,
      overflow: TextOverflow.ellipsis,
    ),
  );
},

Localization #

import 'package:flutter_localizations/flutter_localizations.dart';

// In your MaterialApp
MaterialApp(
  localizationsDelegates: [
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
    GlobalCupertinoLocalizations.delegate,
  ],
  supportedLocales: [
    const Locale('en', ''), // English
    const Locale('fr', ''), // French
    // Add other locales
  ],
  // ...
)

📚 API Reference #

TyxCalendarView Properties #

Property Type Description
option TyxCalendarOption Required. Configuration options for the calendar
onDateChanged Function(DateTime) Callback when the selected date changes
onEventTapped Function(TyxEvent) Callback when an event is tapped
onViewChanged Function(TyxView) Callback when the view type changes

TyxCalendarOption Properties #

Property Type Default Description
initialView TyxView TyxView.month Initial view type (day, week, month)
initialDate DateTime DateTime.now() Initial selected date
events List<TyxEvent> [] List of events to display
timeslotHeight double 60.0 Height of each time slot in pixels
timeslotStartTime TimeOfDay TimeOfDay(hour: 0, minute: 0) Start time for day/week view
timeslotEndTime TimeOfDay TimeOfDay(hour: 23, minute: 59) End time for day/week view
showTrailingDays bool false Whether to show days from next/previous months
startWeekDay int 7 (Sunday) First day of week (1 = Monday, 7 = Sunday)

🤝 Contributing #

Contributions are welcome! Please read our contributing guidelines before submitting pull requests.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

📄 License #

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments #

  • Built with ❤️ using Flutter
  • Inspired by various calendar and scheduling applications
  • Special thanks to all contributors

Made with ❤️ by Loic NGOU

1
likes
120
points
510
downloads

Publisher

unverified uploader

Weekly Downloads

Timely X, a calendar plugin for Flutter.

Repository (GitHub)

Documentation

API reference

License

MIT (license)

Dependencies

flutter, flutter_web_plugins, gradient_borders, intl, jiffy, plugin_platform_interface

More

Packages that depend on timely_x