Simple Weekly Timetable

A clean and flexible weekly timetable widget built with Flutter.

simulator_screenshot_5FD7CF2C-CABB-47C7-8F19-69E30185F661

Features

  • Flexible column headers (days, classrooms, or any custom labels)
  • Automatic time range calculation based on event data
  • Customizable time ranges (manual or auto-calculated)
  • Color-coded events for easy identification
  • Responsive design with customizable dimensions
  • Rich customization options for styling
  • Event tap callbacks for user interaction
  • Support for 30-minute precision events

Usage

Basic Usage

import 'package:simple_weekly_timetable/simple_weekly_timetable.dart';

// Prepare event data
final Map<String, List<TimetableEvent>> events = {
  'Monday': [
    TimetableEvent(
      title: 'Software Engineering',
      startTime: DateTime(2024, 1, 1, 9, 0),
      endTime: DateTime(2024, 1, 1, 10, 0),
      color: Colors.blue,
    ),
    TimetableEvent(
      title: 'Operating Systems',
      startTime: DateTime(2024, 1, 1, 10, 0),
      endTime: DateTime(2024, 1, 1, 12, 0),
      color: Colors.amber,
    ),
  ],
  'Tuesday': [
    TimetableEvent(
      title: 'Algorithms',
      startTime: DateTime(2024, 1, 1, 14, 0),
      endTime: DateTime(2024, 1, 1, 16, 0),
      color: Colors.teal,
    ),
  ],
  // ... more events
};

// Use the widget
WeeklyTimetable(
  columnHeaders: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
  events: events,
)

Advanced Usage with Custom Styling

WeeklyTimetable(
  columnHeaders: ['Room A', 'Room B', 'Room C'],
  events: events,
  startTime: 8,  // Custom start time (8 AM)
  endTime: 20,   // Custom end time (8 PM)
  headerHeight: 50.0,
  timeHeaderWidth: 60.0,
  cellHeight: 80.0,
  gridColor: Colors.red,
  headerBackgroundColor: Colors.yellow,
  timeHeaderBackgroundColor: Colors.green,
  cellBackgroundColor: Colors.grey,
  borderRadius: BorderRadius.circular(12),
  onEventTap: (event) {
    // Handle event tap
    print('Tapped: ${event.title}');
    // Show event details, navigate, etc.
  },
  headerTextStyle: TextStyle(
    fontWeight: FontWeight.bold,
    fontSize: 18,
    color: Colors.blue[800],
  ),
  eventTextStyle: TextStyle(
    fontSize: 14,
    color: Colors.white,
    fontWeight: FontWeight.w600,
  ),
)

Automatic Time Range Calculation

The widget automatically calculates the optimal time range based on your events:

// No startTime/endTime specified - auto-calculated
WeeklyTimetable(
  columnHeaders: ['Monday', 'Tuesday'],
  events: events,
  // startTime and endTime will be automatically calculated
  // from the earliest start time and latest end time in your events
)

Event Interaction

Handle user taps on events:

WeeklyTimetable(
  columnHeaders: ['Monday', 'Tuesday'],
  events: events,
  onEventTap: (event) {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: Text(event.title),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('Start: ${event.startTime.hour}:${event.startTime.minute.toString().padLeft(2, '0')}'),
            Text('End: ${event.endTime.hour}:${event.endTime.minute.toString().padLeft(2, '0')}'),
            if (event.description != null) Text('Description: ${event.description}'),
          ],
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: Text('Close'),
          ),
        ],
      ),
    );
  },
)

API Reference

TimetableEvent

Property Type Required Description
title String Yes Event title
startTime DateTime Yes Event start time
endTime DateTime Yes Event end time
color Color? No Event background color
description String? No Event description

Computed Properties:

  • startMinutes: Start time in minutes from midnight
  • endMinutes: End time in minutes from midnight
  • durationMinutes: Event duration in minutes

WeeklyTimetable

Property Type Default Description
columnHeaders List - Column headers (days, rooms, etc.)
events Map<String, List - Events organized by column
startTime int? null Start hour (0-23), auto-calculated if null
endTime int? null End hour (0-23), auto-calculated if null
headerHeight double 30.0 Header row height
timeHeaderWidth double 30.0 Time column width
cellHeight double 60.0 Time slot height
gridColor Color Color(0xFFE0E0E0) Grid line color
headerBackgroundColor Color? null Header background color
timeHeaderBackgroundColor Color? null Time column background color
cellBackgroundColor Color? null Empty cell background color
borderRadius BorderRadius? null Container border radius
onEventTap Function(TimetableEvent)? null Event tap callback

TimeTable

The underlying widget that WeeklyTimetable wraps. It provides additional customization options:

Property Type Default Description
headerDecoration BoxDecoration? null Custom header decoration
timeHeaderDecoration BoxDecoration? null Custom time header decoration
cellDecoration BoxDecoration? null Custom cell decoration
eventCellDecoration BoxDecoration? null Custom event cell decoration
headerTextStyle TextStyle? null Header text style
timeTextStyle TextStyle? null Time text style
eventTextStyle TextStyle? null Event text style

Examples

School Timetable

final schoolEvents = {
  'Monday': [
    TimetableEvent(
      title: 'Math',
      startTime: DateTime(2024, 1, 1, 8, 30),
      endTime: DateTime(2024, 1, 1, 9, 30),
      color: Colors.red,
    ),
    TimetableEvent(
      title: 'Science',
      startTime: DateTime(2024, 1, 1, 9, 30),
      endTime: DateTime(2024, 1, 1, 10, 30),
      color: Colors.blue,
    ),
  ],
  'Tuesday': [
    TimetableEvent(
      title: 'English',
      startTime: DateTime(2024, 1, 1, 8, 0),
      endTime: DateTime(2024, 1, 1, 9, 0),
      color: Colors.green,
    ),
  ],
};

WeeklyTimetable(
  columnHeaders: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
  events: schoolEvents,
  startTime: 8,
  endTime: 15,
  cellHeight: 70.0,
)

Meeting Room Schedule

final meetingEvents = {
  'Conference Room A': [
    TimetableEvent(
      title: 'Team Standup',
      startTime: DateTime(2024, 1, 1, 9, 0),
      endTime: DateTime(2024, 1, 1, 9, 15),
      color: Colors.orange,
    ),
    TimetableEvent(
      title: 'Project Review',
      startTime: DateTime(2024, 1, 1, 14, 0),
      endTime: DateTime(2024, 1, 1, 15, 0),
      color: Colors.purple,
    ),
  ],
  'Meeting Room B': [
    TimetableEvent(
      title: 'Client Call',
      startTime: DateTime(2024, 1, 1, 10, 0),
      endTime: DateTime(2024, 1, 1, 11, 0),
      color: Colors.teal,
    ),
  ],
};

WeeklyTimetable(
  columnHeaders: ['Conference Room A', 'Meeting Room B', 'Breakout Area'],
  events: meetingEvents,
  headerHeight: 40.0,
  cellHeight: 50.0,
)

Installation

Add to your pubspec.yaml:

dependencies:
  simple_weekly_timetable: ^0.0.1

Features in Detail

Automatic Time Range Calculation

When startTime and endTime are not specified, the widget automatically calculates the optimal time range:

  1. Finds the earliest start time among all events
  2. Finds the latest end time among all events
  3. Uses these values to create the time slots
  4. Ensures all events are visible within the calculated range

Flexible Column Headers

The widget supports any type of column headers:

  • Days of the week: ['Monday', 'Tuesday', 'Wednesday']
  • Room names: ['Room 101', 'Room 102', 'Lab A']
  • Custom labels: ['Team A', 'Team B', 'Group 1']

Precise Time Handling

Events support 30-minute precision:

  • Start time: 9:30 AM
  • End time: 10:15 AM
  • Duration: 45 minutes

Responsive Design

The widget automatically adjusts to available space:

  • Column widths are calculated based on available width
  • Time slots are generated dynamically
  • Events are positioned precisely based on their timing

Contributing

This package was created for my personal project needs. If you need additional features, please feel free to:

I'll implement the requested features right away! 🚀

License

This project is licensed under the MIT License.