-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
254 additions
and
329 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:uni_ui/calendar/calendar_item.dart'; | ||
|
||
class CalendarLine extends StatelessWidget { | ||
const CalendarLine({ | ||
super.key, | ||
required this.calendarItemsCount, | ||
}); | ||
|
||
final int calendarItemsCount; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
if (calendarItemsCount == 0) return Container(); | ||
|
||
return Container( | ||
margin: EdgeInsets.only(top: 44), | ||
child: Row( | ||
children: [ | ||
Container( | ||
width: 60, | ||
height: 4, | ||
margin: EdgeInsets.only(right: 15), | ||
decoration: BoxDecoration( | ||
color: Theme.of(context).colorScheme.primary, | ||
borderRadius: BorderRadius.only( | ||
topRight: Radius.circular(2), | ||
bottomRight: Radius.circular(2), | ||
), | ||
), | ||
), | ||
...List.filled( | ||
calendarItemsCount - 1, | ||
Container( | ||
width: 120, | ||
height: 4, | ||
margin: EdgeInsets.symmetric(horizontal: 15), | ||
decoration: BoxDecoration( | ||
color: Theme.of(context).colorScheme.primary, | ||
borderRadius: BorderRadius.circular(2)), | ||
), | ||
), | ||
Container( | ||
width: 60, | ||
height: 4, | ||
margin: EdgeInsets.only(left: 15), | ||
decoration: BoxDecoration( | ||
color: Theme.of(context).colorScheme.primary, | ||
borderRadius: BorderRadius.only( | ||
topLeft: Radius.circular(2), | ||
bottomLeft: Radius.circular(2), | ||
), | ||
), | ||
), | ||
], | ||
), | ||
); | ||
} | ||
} | ||
|
||
class Calendar extends StatelessWidget { | ||
const Calendar({ | ||
super.key, | ||
required this.items, | ||
}); | ||
|
||
final List<CalendarItem> items; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
// Row + SingleChildScrollView is used, instead of ListView, to avoid | ||
// the widget from expanding vertically | ||
return SingleChildScrollView( | ||
scrollDirection: Axis.horizontal, | ||
child: Stack( | ||
children: [ | ||
Row( | ||
crossAxisAlignment: CrossAxisAlignment.start, | ||
children: items, | ||
), | ||
CalendarLine( | ||
calendarItemsCount: items.length, | ||
), | ||
], | ||
)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
import 'package:figma_squircle/figma_squircle.dart'; | ||
import 'package:flutter/material.dart'; | ||
|
||
class _CalendarItemDate extends StatelessWidget { | ||
const _CalendarItemDate({this.eventPeriod, this.endYear}); | ||
|
||
final String? eventPeriod; | ||
final String? endYear; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
if (eventPeriod != null) { | ||
return Column( | ||
children: [ | ||
Text( | ||
eventPeriod!, | ||
style: TextStyle( | ||
fontSize: 15, | ||
height: 1, | ||
fontWeight: FontWeight.w500, | ||
), | ||
), | ||
Text( | ||
endYear ?? '', | ||
style: TextStyle( | ||
color: Theme.of(context).colorScheme.outline, | ||
fontSize: 11, | ||
), | ||
), | ||
], | ||
); | ||
} else { | ||
return Padding( | ||
padding: EdgeInsets.only(top: 10), | ||
child: Text( | ||
"TBD", | ||
style: TextStyle( | ||
fontSize: 15, | ||
fontWeight: FontWeight.w500, | ||
), | ||
), | ||
); | ||
} | ||
} | ||
|
||
/* TODO: move this to uni_app later | ||
static String monthToString(int month) { | ||
// TODO: Support Portuguese | ||
const strMonths = [ | ||
"Jan", | ||
"Feb", | ||
"Mar", | ||
"Apr", | ||
"May", | ||
"Jun", | ||
"Jul", | ||
"Aug", | ||
"Sep", | ||
"Oct", | ||
"Nov", | ||
"Dec" | ||
]; | ||
return strMonths[month - 1]; | ||
} | ||
static String parsePeriod(DateTimeRange period) { | ||
final start = period.start, end = period.end; | ||
if (start.month == end.month) { | ||
return start.day == end.day | ||
? "${start.day} ${monthToString(start.month)}" | ||
: "${start.day} - ${end.day} ${monthToString(start.month)}"; | ||
} else { | ||
return "${start.day} ${monthToString(start.month)} - ${end.day} ${monthToString(end.month)}"; | ||
} | ||
} | ||
*/ | ||
} | ||
|
||
class CalendarItem extends StatelessWidget { | ||
const CalendarItem({ | ||
super.key, | ||
required this.eventName, | ||
this.eventPeriod, | ||
this.endYear, | ||
this.onTap, | ||
}); | ||
|
||
final String eventName; | ||
final String? eventPeriod; | ||
final String? endYear; | ||
final void Function()? onTap; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Column( | ||
mainAxisSize: MainAxisSize.min, | ||
children: [ | ||
_CalendarItemDate( | ||
eventPeriod: eventPeriod, | ||
endYear: endYear, | ||
), | ||
Stack( | ||
alignment: Alignment.bottomCenter, | ||
children: [ | ||
Container( | ||
margin: EdgeInsets.only(top: 5, bottom: 10), | ||
width: 20, | ||
height: 20, | ||
decoration: BoxDecoration( | ||
shape: BoxShape.circle, | ||
border: Border.all( | ||
color: Theme.of(context).colorScheme.primary, | ||
width: 4.0, | ||
), | ||
), | ||
), | ||
Container( | ||
width: 4, | ||
height: 12, | ||
decoration: BoxDecoration( | ||
borderRadius: BorderRadius.only( | ||
bottomLeft: Radius.circular(2), | ||
bottomRight: Radius.circular(2)), | ||
shape: BoxShape.rectangle, | ||
color: Theme.of(context).primaryColor, | ||
), | ||
), | ||
], | ||
), | ||
GestureDetector( | ||
onTap: onTap, | ||
child: Container( | ||
margin: const EdgeInsets.only(left: 5, right: 5, bottom: 5), | ||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 15), | ||
width: 140, | ||
decoration: ShapeDecoration( | ||
color: Theme.of(context).colorScheme.secondary, | ||
shape: SmoothRectangleBorder( | ||
borderRadius: SmoothBorderRadius( | ||
cornerRadius: 12, | ||
cornerSmoothing: 1, | ||
), | ||
), | ||
shadows: [ | ||
BoxShadow( | ||
color: Theme.of(context).colorScheme.shadow.withAlpha(0x3f), | ||
blurRadius: 6, | ||
) | ||
], | ||
), | ||
child: Text( | ||
eventName, | ||
style: TextStyle( | ||
color: Theme.of(context).colorScheme.primary, | ||
fontSize: 16, | ||
fontWeight: FontWeight.w500, | ||
height: 1, | ||
), | ||
), | ||
), | ||
), | ||
], | ||
); | ||
} | ||
} |
Oops, something went wrong.