Simple Weekly Timetable
A clean and flexible weekly timetable widget built with Flutter.
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 midnightendMinutes: End time in minutes from midnightdurationMinutes: 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:
- Finds the earliest start time among all events
- Finds the latest end time among all events
- Uses these values to create the time slots
- 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:
- Send an email to: swuhalee@gmail.com
- Create an issue on GitHub
- Submit a Pull Request
I'll implement the requested features right away! 🚀
License
This project is licensed under the MIT License.