chore: date cell & header editor UI + move to theme.of(context).texttheme (#1473)

* chore: textstyles

* chore: sizing
This commit is contained in:
Richard Shiue 2022-11-27 17:24:04 +08:00 committed by GitHub
parent 8c7e2d341d
commit d6cbbf3c2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 105 additions and 133 deletions

View File

@ -1,4 +1,3 @@
import 'package:flowy_infra/size.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
@ -69,7 +68,7 @@ class _DateCellState extends GridCellState<GridDateCell> {
controller: _popover, controller: _popover,
triggerActions: PopoverTriggerFlags.none, triggerActions: PopoverTriggerFlags.none,
direction: PopoverDirection.bottomWithLeftAligned, direction: PopoverDirection.bottomWithLeftAligned,
constraints: BoxConstraints.loose(const Size(320, 520)), constraints: BoxConstraints.loose(const Size(260, 500)),
margin: EdgeInsets.zero, margin: EdgeInsets.zero,
child: SizedBox.expand( child: SizedBox.expand(
child: GestureDetector( child: GestureDetector(
@ -81,7 +80,7 @@ class _DateCellState extends GridCellState<GridDateCell> {
padding: GridSize.cellContentInsets, padding: GridSize.cellContentInsets,
child: FlowyText.medium( child: FlowyText.medium(
state.dateStr, state.dateStr,
fontSize: FontSizes.s14, overflow: TextOverflow.ellipsis,
), ),
), ),
), ),

View File

@ -9,7 +9,6 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/color_extension.dart'; import 'package:flowy_infra/color_extension.dart';
import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/image.dart';
import 'package:flowy_infra/size.dart'; import 'package:flowy_infra/size.dart';
import 'package:flowy_infra/text_style.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.dart';
@ -29,7 +28,6 @@ import '../../header/type_option/date.dart';
final kToday = DateTime.now(); final kToday = DateTime.now();
final kFirstDay = DateTime(kToday.year, kToday.month - 3, kToday.day); final kFirstDay = DateTime(kToday.year, kToday.month - 3, kToday.day);
final kLastDay = DateTime(kToday.year, kToday.month + 3, kToday.day); final kLastDay = DateTime(kToday.year, kToday.month + 3, kToday.day);
const kMargin = EdgeInsets.symmetric(horizontal: 6, vertical: 10);
class DateCellEditor extends StatefulWidget { class DateCellEditor extends StatefulWidget {
final VoidCallback onDismissed; final VoidCallback onDismissed;
@ -116,25 +114,25 @@ class _CellCalendarWidgetState extends State<_CellCalendarWidget> {
return BlocProvider.value( return BlocProvider.value(
value: bloc, value: bloc,
child: BlocBuilder<DateCalBloc, DateCalState>( child: BlocBuilder<DateCalBloc, DateCalState>(
buildWhen: (p, c) => false, buildWhen: (p, c) => p != c,
builder: (context, state) { builder: (context, state) {
List<Widget> children = [ List<Widget> children = [
_buildCalendar(context), _buildCalendar(context),
_TimeTextField( if (state.dateTypeOptionPB.includeTime)
bloc: context.read<DateCalBloc>(), _TimeTextField(
popoverMutex: popoverMutex, bloc: context.read<DateCalBloc>(),
), popoverMutex: popoverMutex,
Divider(height: 1, color: Theme.of(context).dividerColor), ),
Divider(height: 1.0, color: Theme.of(context).dividerColor),
const _IncludeTimeButton(), const _IncludeTimeButton(),
Divider(height: 1.0, color: Theme.of(context).dividerColor),
_DateTypeOptionButton(popoverMutex: popoverMutex) _DateTypeOptionButton(popoverMutex: popoverMutex)
]; ];
return ListView.separated( return ListView.separated(
shrinkWrap: true, shrinkWrap: true,
controller: ScrollController(), controller: ScrollController(),
separatorBuilder: (context, index) { separatorBuilder: (context, index) => VSpace(GridSize.cellVPadding),
return VSpace(GridSize.typeOptionSeparatorHeight);
},
itemCount: children.length, itemCount: children.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return children[index]; return children[index];
@ -155,17 +153,23 @@ class _CellCalendarWidgetState extends State<_CellCalendarWidget> {
Widget _buildCalendar(BuildContext context) { Widget _buildCalendar(BuildContext context) {
return BlocBuilder<DateCalBloc, DateCalState>( return BlocBuilder<DateCalBloc, DateCalState>(
builder: (context, state) { builder: (context, state) {
final textStyle = Theme.of(context).textTheme.bodyMedium!;
final boxDecoration = BoxDecoration(
color: Theme.of(context).colorScheme.surface,
shape: BoxShape.rectangle,
borderRadius: Corners.s6Border,
);
return TableCalendar( return TableCalendar(
firstDay: kFirstDay, firstDay: kFirstDay,
lastDay: kLastDay, lastDay: kLastDay,
focusedDay: state.focusedDay, focusedDay: state.focusedDay,
rowHeight: 40, rowHeight: GridSize.typeOptionItemHeight,
calendarFormat: state.format, calendarFormat: state.format,
daysOfWeekHeight: 40, daysOfWeekHeight: GridSize.typeOptionItemHeight,
headerStyle: HeaderStyle( headerStyle: HeaderStyle(
formatButtonVisible: false, formatButtonVisible: false,
titleCentered: true, titleCentered: true,
titleTextStyle: TextStyles.body1.size(FontSizes.s14), titleTextStyle: textStyle,
leftChevronMargin: EdgeInsets.zero, leftChevronMargin: EdgeInsets.zero,
leftChevronPadding: EdgeInsets.zero, leftChevronPadding: EdgeInsets.zero,
leftChevronIcon: svgWidget("home/arrow_left"), leftChevronIcon: svgWidget("home/arrow_left"),
@ -177,57 +181,25 @@ class _CellCalendarWidgetState extends State<_CellCalendarWidget> {
daysOfWeekStyle: DaysOfWeekStyle( daysOfWeekStyle: DaysOfWeekStyle(
dowTextFormatter: (date, locale) => dowTextFormatter: (date, locale) =>
DateFormat.E(locale).format(date).toUpperCase(), DateFormat.E(locale).format(date).toUpperCase(),
weekdayStyle: TextStyles.general( weekdayStyle: AFThemeExtension.of(context).caption,
fontSize: 13, weekendStyle: AFThemeExtension.of(context).caption,
fontWeight: FontWeight.w400,
color: Theme.of(context).hintColor,
),
weekendStyle: TextStyles.general(
fontSize: 13,
fontWeight: FontWeight.w400,
color: Theme.of(context).hintColor,
),
), ),
calendarStyle: CalendarStyle( calendarStyle: CalendarStyle(
cellMargin: const EdgeInsets.all(3), cellMargin: const EdgeInsets.all(3),
defaultDecoration: BoxDecoration( defaultDecoration: boxDecoration,
color: Theme.of(context).colorScheme.surface, selectedDecoration: boxDecoration.copyWith(
shape: BoxShape.rectangle, color: Theme.of(context).colorScheme.primary),
borderRadius: const BorderRadius.all(Radius.circular(6)), todayDecoration: boxDecoration.copyWith(
), color: AFThemeExtension.of(context).lightGreyHover),
selectedDecoration: BoxDecoration( weekendDecoration: boxDecoration,
color: Theme.of(context).colorScheme.primary, outsideDecoration: boxDecoration,
shape: BoxShape.rectangle, defaultTextStyle: textStyle,
borderRadius: const BorderRadius.all(Radius.circular(6)), weekendTextStyle: textStyle,
), selectedTextStyle:
todayDecoration: BoxDecoration( textStyle.textColor(Theme.of(context).colorScheme.surface),
color: AFThemeExtension.of(context).lightGreyHover, todayTextStyle: textStyle,
shape: BoxShape.rectangle, outsideTextStyle:
borderRadius: const BorderRadius.all(Radius.circular(6)), textStyle.textColor(Theme.of(context).disabledColor),
),
weekendDecoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
shape: BoxShape.rectangle,
borderRadius: const BorderRadius.all(Radius.circular(6)),
),
outsideDecoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
shape: BoxShape.rectangle,
borderRadius: const BorderRadius.all(Radius.circular(6)),
),
defaultTextStyle: TextStyles.body1.size(FontSizes.s14),
weekendTextStyle: TextStyles.body1.size(FontSizes.s14),
selectedTextStyle: TextStyles.general(
fontSize: FontSizes.s14,
color: Theme.of(context).colorScheme.surface,
),
todayTextStyle: TextStyles.general(
fontSize: FontSizes.s14,
),
outsideTextStyle: TextStyles.general(
fontSize: FontSizes.s14,
color: Theme.of(context).disabledColor,
),
), ),
selectedDayPredicate: (day) { selectedDayPredicate: (day) {
return state.calData.fold( return state.calData.fold(
@ -263,9 +235,9 @@ class _IncludeTimeButton extends StatelessWidget {
selector: (state) => state.dateTypeOptionPB.includeTime, selector: (state) => state.dateTypeOptionPB.includeTime,
builder: (context, includeTime) { builder: (context, includeTime) {
return SizedBox( return SizedBox(
height: 50, height: GridSize.typeOptionItemHeight,
child: Padding( child: Padding(
padding: kMargin, padding: GridSize.typeOptionContentInsets,
child: Row( child: Row(
children: [ children: [
svgWidget( svgWidget(
@ -273,10 +245,7 @@ class _IncludeTimeButton extends StatelessWidget {
color: Theme.of(context).colorScheme.onSurface, color: Theme.of(context).colorScheme.onSurface,
), ),
const HSpace(4), const HSpace(4),
FlowyText.medium( FlowyText.medium(LocaleKeys.grid_field_includeTime.tr()),
LocaleKeys.grid_field_includeTime.tr(),
fontSize: FontSizes.s14,
),
const Spacer(), const Spacer(),
Toggle( Toggle(
value: includeTime, value: includeTime,
@ -298,6 +267,7 @@ class _IncludeTimeButton extends StatelessWidget {
class _TimeTextField extends StatefulWidget { class _TimeTextField extends StatefulWidget {
final DateCalBloc bloc; final DateCalBloc bloc;
final PopoverMutex popoverMutex; final PopoverMutex popoverMutex;
const _TimeTextField({ const _TimeTextField({
required this.bloc, required this.bloc,
required this.popoverMutex, required this.popoverMutex,
@ -316,58 +286,51 @@ class _TimeTextFieldState extends State<_TimeTextField> {
void initState() { void initState() {
_focusNode = FocusNode(); _focusNode = FocusNode();
_controller = TextEditingController(text: widget.bloc.state.time); _controller = TextEditingController(text: widget.bloc.state.time);
if (widget.bloc.state.dateTypeOptionPB.includeTime) {
_focusNode.addListener(() {
if (mounted) {
widget.bloc.add(DateCalEvent.setTime(_controller.text));
}
if (_focusNode.hasFocus) { _focusNode.addListener(() {
widget.popoverMutex.close(); if (mounted) {
} widget.bloc.add(DateCalEvent.setTime(_controller.text));
}); }
});
_focusNode.addListener(() {
if (_focusNode.hasFocus) {
widget.popoverMutex.close();
}
});
widget.popoverMutex.listenOnPopoverChanged(() {
if (_focusNode.hasFocus) {
_focusNode.unfocus();
}
});
widget.popoverMutex.listenOnPopoverChanged(() {
if (_focusNode.hasFocus) {
_focusNode.unfocus();
}
});
}
super.initState(); super.initState();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocConsumer<DateCalBloc, DateCalState>( _controller.text = widget.bloc.state.time ?? "";
listener: (context, state) { _controller.selection =
_controller.text = state.time ?? ""; TextSelection.collapsed(offset: _controller.text.length);
}, return Padding(
listenWhen: (p, c) => p.time != c.time, padding: GridSize.typeOptionContentInsets,
builder: (context, state) { child: RoundedInputField(
if (state.dateTypeOptionPB.includeTime) { height: GridSize.typeOptionItemHeight,
return Padding( focusNode: _focusNode,
padding: kMargin, autoFocus: true,
child: RoundedInputField( hintText: widget.bloc.state.timeHintText,
height: 40, controller: _controller,
focusNode: _focusNode, style: Theme.of(context).textTheme.bodyMedium!,
autoFocus: true, normalBorderColor: Theme.of(context).colorScheme.outline,
hintText: state.timeHintText, errorBorderColor: Theme.of(context).colorScheme.error,
controller: _controller, focusBorderColor: Theme.of(context).colorScheme.primary,
style: TextStyles.body1.size(FontSizes.s14), cursorColor: Theme.of(context).colorScheme.primary,
normalBorderColor: Theme.of(context).colorScheme.outline, errorText:
errorBorderColor: Theme.of(context).colorScheme.error, widget.bloc.state.timeFormatError.fold(() => "", (error) => error),
focusBorderColor: Theme.of(context).colorScheme.primary, onEditingComplete: (value) =>
cursorColor: Theme.of(context).colorScheme.primary, widget.bloc.add(DateCalEvent.setTime(value)),
errorText: state.timeFormatError.fold(() => "", (error) => error), ),
onEditingComplete: (value) {
widget.bloc.add(DateCalEvent.setTime(value));
},
),
);
} else {
return const SizedBox();
}
},
); );
} }
@ -397,12 +360,14 @@ class _DateTypeOptionButton extends StatelessWidget {
triggerActions: PopoverTriggerFlags.hover | PopoverTriggerFlags.click, triggerActions: PopoverTriggerFlags.hover | PopoverTriggerFlags.click,
offset: const Offset(20, 0), offset: const Offset(20, 0),
constraints: BoxConstraints.loose(const Size(140, 100)), constraints: BoxConstraints.loose(const Size(140, 100)),
child: FlowyButton( child: SizedBox(
text: FlowyText.medium(title, fontSize: 14), height: GridSize.typeOptionItemHeight,
margin: kMargin, child: FlowyButton(
rightIcon: svgWidget( text: FlowyText.medium(title),
"grid/more", rightIcon: svgWidget(
color: Theme.of(context).colorScheme.onSurface, "grid/more",
color: Theme.of(context).colorScheme.onSurface,
),
), ),
), ),
popupBuilder: (BuildContext popContext) { popupBuilder: (BuildContext popContext) {
@ -476,9 +441,8 @@ class _CalDateTimeSettingState extends State<_CalDateTimeSetting> {
child: ListView.separated( child: ListView.separated(
shrinkWrap: true, shrinkWrap: true,
controller: ScrollController(), controller: ScrollController(),
separatorBuilder: (context, index) { separatorBuilder: (context, index) =>
return VSpace(GridSize.typeOptionSeparatorHeight); VSpace(GridSize.typeOptionSeparatorHeight),
},
itemCount: children.length, itemCount: children.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return children[index]; return children[index];

View File

@ -53,13 +53,22 @@ class DateTypeOptionWidget extends TypeOptionWidget {
listener: (context, state) => listener: (context, state) =>
typeOptionContext.typeOption = state.typeOption, typeOptionContext.typeOption = state.typeOption,
builder: (context, state) { builder: (context, state) {
return Column( final List<Widget> children = [
children: [ const TypeOptionSeparator(),
const TypeOptionSeparator(), _renderDateFormatButton(context, state.typeOption.dateFormat),
_renderDateFormatButton(context, state.typeOption.dateFormat), _renderTimeFormatButton(context, state.typeOption.timeFormat),
_renderTimeFormatButton(context, state.typeOption.timeFormat), const _IncludeTimeButton(),
const _IncludeTimeButton(), ];
],
return ListView.separated(
shrinkWrap: true,
controller: ScrollController(),
separatorBuilder: (context, index) =>
VSpace(GridSize.typeOptionSeparatorHeight),
itemCount: children.length,
itemBuilder: (BuildContext context, int index) {
return children[index];
},
); );
}, },
), ),

View File

@ -118,7 +118,7 @@ class _RoundedInputFieldState extends State<RoundedInputField> {
contentPadding: widget.contentPadding, contentPadding: widget.contentPadding,
hintText: widget.hintText, hintText: widget.hintText,
hintStyle: hintStyle:
Theme.of(context).textTheme.bodyMedium!.textColor(borderColor), Theme.of(context).textTheme.bodySmall!.textColor(borderColor),
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: borderColor, color: borderColor,