mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: date picker ui revamp (#4044)
* feat: date picker editor * feat: refactor date picker on mobile * chore: update background color * feat: date picker UI revamp * feat: optimize the scroll behavior * chore: remove unused code
This commit is contained in:
parent
551e012147
commit
8665a25b39
@ -202,4 +202,4 @@ SPEC CHECKSUMS:
|
||||
|
||||
PODFILE CHECKSUM: 8c681999c7764593c94846b2a64b44d86f7a27ac
|
||||
|
||||
COCOAPODS: 1.11.3
|
||||
COCOAPODS: 1.12.1
|
||||
|
@ -2,6 +2,7 @@ import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
||||
import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_bloc.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/protobuf.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart' hide WidgetBuilder;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
@ -18,7 +19,13 @@ Future<void> showMobileBottomSheet({
|
||||
isScrollControlled: true,
|
||||
enableDrag: isDragEnabled,
|
||||
useSafeArea: true,
|
||||
shape: shape,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
shape: shape ??
|
||||
const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Corners.s12Radius,
|
||||
),
|
||||
),
|
||||
builder: builder,
|
||||
);
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ import 'package:appflowy/plugins/database_view/widgets/row/accessory/cell_access
|
||||
import 'package:appflowy/plugins/database_view/widgets/row/cell_builder.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/row/cells/cells.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/row/row_property.dart';
|
||||
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
|
@ -1,7 +1,5 @@
|
||||
export 'mobile_text_cell.dart';
|
||||
export 'mobile_number_cell.dart';
|
||||
export 'mobile_timestamp_cell.dart';
|
||||
export 'mobile_checkbox_cell.dart';
|
||||
export 'mobile_number_cell.dart';
|
||||
export 'mobile_text_cell.dart';
|
||||
export 'mobile_timestamp_cell.dart';
|
||||
export 'mobile_url_cell.dart';
|
||||
export 'date_cell/mobile_date_cell.dart';
|
||||
export 'date_cell/mobile_date_cell_edit_screen.dart';
|
||||
|
@ -1,103 +0,0 @@
|
||||
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/row/cell_builder.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/row/cells/date_cell/date_cell_bloc.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'mobile_date_cell_edit_screen.dart';
|
||||
|
||||
class MobileDateCell extends GridCellWidget {
|
||||
MobileDateCell({
|
||||
super.key,
|
||||
required this.cellControllerBuilder,
|
||||
required this.hintText,
|
||||
});
|
||||
|
||||
final CellControllerBuilder cellControllerBuilder;
|
||||
final String? hintText;
|
||||
|
||||
@override
|
||||
GridCellState<MobileDateCell> createState() => _DateCellState();
|
||||
}
|
||||
|
||||
class _DateCellState extends GridCellState<MobileDateCell> {
|
||||
late final DateCellBloc _cellBloc;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
final cellController =
|
||||
widget.cellControllerBuilder.build() as DateCellController;
|
||||
_cellBloc = DateCellBloc(cellController: cellController)
|
||||
..add(const DateCellEvent.initial());
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider.value(
|
||||
value: _cellBloc,
|
||||
child: BlocBuilder<DateCellBloc, DateCellState>(
|
||||
builder: (context, state) {
|
||||
// full screen show the date edit screen
|
||||
return GestureDetector(
|
||||
onTap: () => context.push(
|
||||
MobileDateCellEditScreen.routeName,
|
||||
extra: {
|
||||
MobileDateCellEditScreen.argCellController:
|
||||
widget.cellControllerBuilder.build() as DateCellController,
|
||||
},
|
||||
),
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
child: MobileDateCellText(
|
||||
dateStr: state.dateStr,
|
||||
placeholder: widget.hintText ?? "",
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
_cellBloc.close();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void requestBeginFocus() {}
|
||||
|
||||
@override
|
||||
String? onCopy() => _cellBloc.state.dateStr;
|
||||
}
|
||||
|
||||
class MobileDateCellText extends StatelessWidget {
|
||||
const MobileDateCellText({
|
||||
super.key,
|
||||
required this.dateStr,
|
||||
required this.placeholder,
|
||||
});
|
||||
|
||||
final String dateStr;
|
||||
final String placeholder;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isPlaceholder = dateStr.isEmpty;
|
||||
final text = isPlaceholder ? placeholder : dateStr;
|
||||
return Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
text,
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||
color: isPlaceholder
|
||||
? Theme.of(context).hintColor
|
||||
: Theme.of(context).colorScheme.onBackground,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/widgets/widgets.dart';
|
||||
import 'package:appflowy/plugins/base/drag_handler.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/type_option/date.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/row/cells/date_cell/date_cal_bloc.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/row/cells/date_cell/date_editor.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/row/cells/date_cell/mobile_date_editor.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/date_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
@ -13,19 +14,24 @@ import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import 'widgets/widgets.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class MobileDateCellEditScreen extends StatefulWidget {
|
||||
static const routeName = '/MobileDateCellEditScreen';
|
||||
static const argCellController = 'cellController';
|
||||
static const routeName = '/edit_date_cell';
|
||||
|
||||
const MobileDateCellEditScreen(
|
||||
this.cellController, {
|
||||
// the type is DateCellController
|
||||
static const dateCellController = 'date_cell_controller';
|
||||
// bool value, default is true
|
||||
static const fullScreen = 'full_screen';
|
||||
|
||||
const MobileDateCellEditScreen({
|
||||
super.key,
|
||||
required this.controller,
|
||||
this.showAsFullScreen = true,
|
||||
});
|
||||
|
||||
final DateCellController cellController;
|
||||
final DateCellController controller;
|
||||
final bool showAsFullScreen;
|
||||
|
||||
@override
|
||||
State<MobileDateCellEditScreen> createState() =>
|
||||
@ -33,42 +39,116 @@ class MobileDateCellEditScreen extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _MobileDateCellEditScreenState extends State<MobileDateCellEditScreen> {
|
||||
late final Future<Either<dynamic, FlowyError>> typeOptionFuture;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
typeOptionFuture = widget.controller.getTypeOption(
|
||||
DateTypeOptionDataParser(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return widget.showAsFullScreen ? _buildFullScreen() : _buildNotFullScreen();
|
||||
}
|
||||
|
||||
Widget _buildFullScreen() {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(LocaleKeys.button_edit.tr()),
|
||||
title: Text(LocaleKeys.titleBar_date.tr()),
|
||||
),
|
||||
body: FutureBuilder<Either<dynamic, FlowyError>>(
|
||||
future: widget.cellController.getTypeOption(
|
||||
DateTypeOptionDataParser(),
|
||||
body: _buildBody(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildNotFullScreen() {
|
||||
return DraggableScrollableSheet(
|
||||
expand: false,
|
||||
snap: true,
|
||||
initialChildSize: 0.6,
|
||||
minChildSize: 0.6,
|
||||
builder: (_, controller) => Material(
|
||||
child: SingleChildScrollView(
|
||||
controller: controller,
|
||||
child: Column(
|
||||
children: [
|
||||
const DragHandler(),
|
||||
_buildHeader(),
|
||||
const Divider(),
|
||||
_buildBody(),
|
||||
],
|
||||
),
|
||||
),
|
||||
builder: (BuildContext context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
return snapshot.data!.fold(
|
||||
(dateTypeOptionPB) {
|
||||
return _DateCellEditBody(
|
||||
dateCellController: widget.cellController,
|
||||
dateTypeOptionPB: dateTypeOptionPB,
|
||||
);
|
||||
},
|
||||
(err) {
|
||||
Log.error(err);
|
||||
return FlowyMobileStateContainer.error(
|
||||
title: LocaleKeys.grid_field_failedToLoadDate.tr(),
|
||||
errorMsg: err.toString(),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBody() {
|
||||
return FutureBuilder<Either<dynamic, FlowyError>>(
|
||||
future: typeOptionFuture,
|
||||
builder: (context, snapshot) {
|
||||
final data = snapshot.data;
|
||||
if (data == null) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator.adaptive(),
|
||||
);
|
||||
}
|
||||
|
||||
return data.fold(
|
||||
(dateTypeOptionPB) {
|
||||
return _DateCellEditBody(
|
||||
dateCellController: widget.controller,
|
||||
dateTypeOptionPB: dateTypeOptionPB,
|
||||
);
|
||||
}
|
||||
return const Center(child: CircularProgressIndicator.adaptive());
|
||||
},
|
||||
},
|
||||
(err) {
|
||||
Log.error(err);
|
||||
return FlowyMobileStateContainer.error(
|
||||
title: LocaleKeys.grid_field_failedToLoadDate.tr(),
|
||||
errorMsg: err.toString(),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildHeader() {
|
||||
const iconWidth = 36.0;
|
||||
const height = 44.0;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Stack(
|
||||
children: [
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: FlowyIconButton(
|
||||
icon: const FlowySvg(
|
||||
FlowySvgs.close_s,
|
||||
size: Size.square(iconWidth),
|
||||
),
|
||||
width: iconWidth,
|
||||
iconPadding: EdgeInsets.zero,
|
||||
onPressed: () => context.pop(),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: FlowyText.medium(
|
||||
LocaleKeys.grid_field_dateFieldName.tr(),
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
].map((e) => SizedBox(height: height, child: e)).toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _DateCellEditBody extends StatefulWidget {
|
||||
class _DateCellEditBody extends StatelessWidget {
|
||||
const _DateCellEditBody({
|
||||
required this.dateCellController,
|
||||
required this.dateTypeOptionPB,
|
||||
@ -77,48 +157,48 @@ class _DateCellEditBody extends StatefulWidget {
|
||||
final DateCellController dateCellController;
|
||||
final DateTypeOptionPB dateTypeOptionPB;
|
||||
|
||||
@override
|
||||
State<_DateCellEditBody> createState() => _DateCellEditBodyState();
|
||||
}
|
||||
|
||||
class _DateCellEditBodyState extends State<_DateCellEditBody> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => DateCellCalendarBloc(
|
||||
dateTypeOptionPB: widget.dateTypeOptionPB,
|
||||
cellData: widget.dateCellController.getCellData(),
|
||||
cellController: widget.dateCellController,
|
||||
dateTypeOptionPB: dateTypeOptionPB,
|
||||
cellData: dateCellController.getCellData(),
|
||||
cellController: dateCellController,
|
||||
)..add(const DateCellCalendarEvent.initial()),
|
||||
child: BlocBuilder<DateCellCalendarBloc, DateCellCalendarState>(
|
||||
builder: (context, state) {
|
||||
final widgetsList = [
|
||||
DateAndTimeDisplay(state),
|
||||
const DatePicker(),
|
||||
const _EndDateSwitch(),
|
||||
const _IncludeTimeSwitch(),
|
||||
const _StartDayTime(),
|
||||
const _EndDayTime(),
|
||||
const Divider(),
|
||||
const _DateFormatOption(),
|
||||
const _TimeFormatOption(),
|
||||
const Divider(),
|
||||
const _ClearDateButton(),
|
||||
];
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: ListView.separated(
|
||||
itemBuilder: (context, index) => widgetsList[index],
|
||||
separatorBuilder: (_, __) => const VSpace(8),
|
||||
itemCount: widgetsList.length,
|
||||
),
|
||||
);
|
||||
},
|
||||
child: const Column(
|
||||
children: [
|
||||
FlowyOptionDecorateBox(
|
||||
showTopBorder: false,
|
||||
child: MobileDatePicker(),
|
||||
),
|
||||
_ColoredDivider(),
|
||||
_EndDateSwitch(),
|
||||
_IncludeTimeSwitch(),
|
||||
_StartDayTime(),
|
||||
_EndDayTime(),
|
||||
_ColoredDivider(),
|
||||
_DateFormatOption(),
|
||||
_TimeFormatOption(),
|
||||
_ClearDateButton(),
|
||||
_ColoredDivider(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ColoredDivider extends StatelessWidget {
|
||||
const _ColoredDivider();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return VSpace(
|
||||
20.0,
|
||||
color: Theme.of(context).colorScheme.secondaryContainer,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _EndDateSwitch extends StatelessWidget {
|
||||
const _EndDateSwitch();
|
||||
|
||||
@ -127,23 +207,17 @@ class _EndDateSwitch extends StatelessWidget {
|
||||
return BlocSelector<DateCellCalendarBloc, DateCellCalendarState, bool>(
|
||||
selector: (state) => state.isRange,
|
||||
builder: (context, isRange) {
|
||||
return Row(
|
||||
children: [
|
||||
Text(
|
||||
LocaleKeys.grid_field_isRange.tr(),
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
const Spacer(),
|
||||
Switch.adaptive(
|
||||
value: isRange,
|
||||
activeColor: Theme.of(context).colorScheme.primary,
|
||||
onChanged: (value) {
|
||||
context
|
||||
.read<DateCellCalendarBloc>()
|
||||
.add(DateCellCalendarEvent.setIsRange(value));
|
||||
},
|
||||
),
|
||||
],
|
||||
return FlowyOptionTile(
|
||||
text: LocaleKeys.grid_field_isRange.tr(),
|
||||
leftIcon: const FlowySvg(FlowySvgs.date_s),
|
||||
leading: _Switcher(
|
||||
value: isRange,
|
||||
onChanged: (value) {
|
||||
context
|
||||
.read<DateCellCalendarBloc>()
|
||||
.add(DateCellCalendarEvent.setIsRange(value));
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
@ -158,13 +232,18 @@ class _IncludeTimeSwitch extends StatelessWidget {
|
||||
return BlocSelector<DateCellCalendarBloc, DateCellCalendarState, bool>(
|
||||
selector: (state) => state.includeTime,
|
||||
builder: (context, includeTime) {
|
||||
return IncludeTimeSwitch(
|
||||
switchValue: includeTime,
|
||||
onChanged: (value) {
|
||||
context
|
||||
.read<DateCellCalendarBloc>()
|
||||
.add(DateCellCalendarEvent.setIncludeTime(value));
|
||||
},
|
||||
return FlowyOptionTile(
|
||||
showTopBorder: false,
|
||||
text: LocaleKeys.grid_field_includeTime.tr(),
|
||||
leftIcon: const FlowySvg(FlowySvgs.clock_alarm_s),
|
||||
leading: _Switcher(
|
||||
value: includeTime,
|
||||
onChanged: (value) {
|
||||
context
|
||||
.read<DateCellCalendarBloc>()
|
||||
.add(DateCellCalendarEvent.setIncludeTime(value));
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
@ -300,14 +379,9 @@ class _ClearDateButton extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
LocaleKeys.grid_field_clearDate.tr(),
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
),
|
||||
return FlowyOptionTile(
|
||||
showTopBorder: false,
|
||||
text: LocaleKeys.grid_field_clearDate.tr(),
|
||||
onTap: () => context
|
||||
.read<DateCellCalendarBloc>()
|
||||
.add(const DateCellCalendarEvent.clearDate()),
|
||||
@ -324,20 +398,25 @@ class _TimeFormatOption extends StatelessWidget {
|
||||
TimeFormatPB>(
|
||||
selector: (state) => state.dateTypeOptionPB.timeFormat,
|
||||
builder: (context, state) {
|
||||
return TimeFormatListTile(
|
||||
currentFormatStr: state.title(),
|
||||
groupValue: context
|
||||
.watch<DateCellCalendarBloc>()
|
||||
.state
|
||||
.dateTypeOptionPB
|
||||
.timeFormat,
|
||||
onChanged: (newFormat) {
|
||||
if (newFormat == null) return;
|
||||
context
|
||||
.read<DateCellCalendarBloc>()
|
||||
.add(DateCellCalendarEvent.setTimeFormat(newFormat));
|
||||
},
|
||||
return FlowyOptionTile(
|
||||
showTopBorder: false,
|
||||
text: LocaleKeys.settings_appearance_timeFormat_label.tr(),
|
||||
leftIcon: const FlowySvg(FlowySvgs.time_s),
|
||||
);
|
||||
// TimeFormatListTile(
|
||||
// currentFormatStr: state.title(),
|
||||
// groupValue: context
|
||||
// .watch<DateCellCalendarBloc>()
|
||||
// .state
|
||||
// .dateTypeOptionPB
|
||||
// .timeFormat,
|
||||
// onChanged: (newFormat) {
|
||||
// if (newFormat == null) return;
|
||||
// context
|
||||
// .read<DateCellCalendarBloc>()
|
||||
// .add(DateCellCalendarEvent.setTimeFormat(newFormat));
|
||||
// },
|
||||
// );
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -352,21 +431,50 @@ class _DateFormatOption extends StatelessWidget {
|
||||
DateFormatPB>(
|
||||
selector: (state) => state.dateTypeOptionPB.dateFormat,
|
||||
builder: (context, state) {
|
||||
return DateFormatListTile(
|
||||
currentFormatStr: state.title(),
|
||||
groupValue: context
|
||||
.watch<DateCellCalendarBloc>()
|
||||
.state
|
||||
.dateTypeOptionPB
|
||||
.dateFormat,
|
||||
onChanged: (newFormat) {
|
||||
if (newFormat == null) return;
|
||||
context
|
||||
.read<DateCellCalendarBloc>()
|
||||
.add(DateCellCalendarEvent.setDateFormat(newFormat));
|
||||
},
|
||||
return FlowyOptionTile(
|
||||
text: LocaleKeys.settings_appearance_dateFormat_label.tr(),
|
||||
leftIcon: const FlowySvg(FlowySvgs.clock_alarm_s),
|
||||
);
|
||||
// DateFormatListTile(
|
||||
// currentFormatStr: state.title(),
|
||||
// groupValue: context
|
||||
// .watch<DateCellCalendarBloc>()
|
||||
// .state
|
||||
// .dateTypeOptionPB
|
||||
// .dateFormat,
|
||||
// onChanged: (newFormat) {
|
||||
// if (newFormat == null) return;
|
||||
// context
|
||||
// .read<DateCellCalendarBloc>()
|
||||
// .add(DateCellCalendarEvent.setDateFormat(newFormat));
|
||||
// },
|
||||
// );
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _Switcher extends StatelessWidget {
|
||||
const _Switcher({
|
||||
required this.value,
|
||||
required this.onChanged,
|
||||
});
|
||||
|
||||
final bool value;
|
||||
final void Function(bool value) onChanged;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
width: 48,
|
||||
child: FittedBox(
|
||||
fit: BoxFit.fill,
|
||||
child: Switch.adaptive(
|
||||
value: value,
|
||||
activeColor: const Color(0xFF00BCF0),
|
||||
onChanged: onChanged,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class FlowyOptionDecorateBox extends StatelessWidget {
|
||||
const FlowyOptionDecorateBox({
|
||||
super.key,
|
||||
this.showTopBorder = true,
|
||||
this.showBottomBorder = true,
|
||||
required this.child,
|
||||
});
|
||||
|
||||
final bool showTopBorder;
|
||||
final bool showBottomBorder;
|
||||
final Widget child;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
top: showTopBorder
|
||||
? BorderSide(
|
||||
color: Theme.of(context).dividerColor,
|
||||
)
|
||||
: BorderSide.none,
|
||||
bottom: showBottomBorder
|
||||
? BorderSide(
|
||||
color: Theme.of(context).dividerColor,
|
||||
)
|
||||
: BorderSide.none,
|
||||
),
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
import 'package:appflowy/mobile/presentation/widgets/widgets.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
// used in cell editor
|
||||
class FlowyOptionTile extends StatelessWidget {
|
||||
const FlowyOptionTile({
|
||||
super.key,
|
||||
this.showTopBorder = true,
|
||||
this.showBottomBorder = true,
|
||||
required this.text,
|
||||
this.leftIcon,
|
||||
this.onTap,
|
||||
this.leading,
|
||||
});
|
||||
|
||||
final bool showTopBorder;
|
||||
final bool showBottomBorder;
|
||||
final String text;
|
||||
final void Function()? onTap;
|
||||
final Widget? leftIcon;
|
||||
final Widget? leading;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FlowyOptionDecorateBox(
|
||||
showTopBorder: showTopBorder,
|
||||
showBottomBorder: showBottomBorder,
|
||||
child: Row(
|
||||
children: [
|
||||
FlowyButton(
|
||||
useIntrinsicWidth: true,
|
||||
text: FlowyText(
|
||||
text,
|
||||
fontSize: 16.0,
|
||||
),
|
||||
margin: const EdgeInsets.symmetric(
|
||||
horizontal: 12.0,
|
||||
vertical: 16.0,
|
||||
),
|
||||
leftIcon: leftIcon,
|
||||
leftIconSize: const Size.square(24.0),
|
||||
iconPadding: 8.0,
|
||||
onTap: onTap,
|
||||
),
|
||||
const Spacer(),
|
||||
leading ?? const SizedBox.shrink(),
|
||||
const HSpace(12.0),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
export 'show_flowy_mobile_confirm_dialog.dart';
|
||||
export 'show_flowy_mobile_bottom_sheet.dart';
|
||||
export 'flowy_mobile_option_decorate_box.dart';
|
||||
export 'flowy_mobile_state_container.dart';
|
||||
export 'flowy_option_tile.dart';
|
||||
export 'show_flowy_mobile_bottom_sheet.dart';
|
||||
export 'show_flowy_mobile_confirm_dialog.dart';
|
||||
|
@ -155,10 +155,9 @@ GridCellWidget _getMobileCardCellWidget(
|
||||
);
|
||||
case FieldType.DateTime:
|
||||
style as DateCellStyle?;
|
||||
return MobileDateCell(
|
||||
return GridDateCell(
|
||||
cellControllerBuilder: cellControllerBuilder,
|
||||
hintText: style?.placeholder,
|
||||
key: key,
|
||||
style: style,
|
||||
);
|
||||
case FieldType.URL:
|
||||
style as GridURLCellStyle?;
|
||||
@ -167,7 +166,6 @@ GridCellWidget _getMobileCardCellWidget(
|
||||
hintText: style?.placeholder,
|
||||
key: key,
|
||||
);
|
||||
// TODO(yijing): implement the following mobile select option cell
|
||||
case FieldType.SingleSelect:
|
||||
return GridSingleSelectCell(
|
||||
cellControllerBuilder: cellControllerBuilder,
|
||||
|
@ -1,4 +1,7 @@
|
||||
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/date_picker/mobile_date_picker_screen.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
@ -66,34 +69,55 @@ class _DateCellState extends GridCellState<GridDateCell> {
|
||||
final alignment = widget.cellStyle != null
|
||||
? widget.cellStyle!.alignment
|
||||
: Alignment.centerLeft;
|
||||
|
||||
return BlocProvider.value(
|
||||
value: _cellBloc,
|
||||
child: BlocBuilder<DateCellBloc, DateCellState>(
|
||||
builder: (context, state) {
|
||||
return AppFlowyPopover(
|
||||
controller: _popover,
|
||||
triggerActions: PopoverTriggerFlags.none,
|
||||
direction: PopoverDirection.bottomWithLeftAligned,
|
||||
constraints: BoxConstraints.loose(const Size(260, 620)),
|
||||
margin: EdgeInsets.zero,
|
||||
child: GridDateCellText(
|
||||
dateStr: state.dateStr,
|
||||
placeholder: widget.cellStyle?.placeholder ?? "",
|
||||
alignment: alignment,
|
||||
cellPadding:
|
||||
widget.cellStyle?.cellPadding ?? GridSize.cellContentInsets,
|
||||
),
|
||||
popupBuilder: (BuildContext popoverContent) {
|
||||
return DateCellEditor(
|
||||
cellController:
|
||||
widget.cellControllerBuilder.build() as DateCellController,
|
||||
onDismissed: () => widget.cellContainerNotifier.isFocus = false,
|
||||
);
|
||||
},
|
||||
onClose: () {
|
||||
widget.cellContainerNotifier.isFocus = false;
|
||||
},
|
||||
final child = GridDateCellText(
|
||||
dateStr: state.dateStr,
|
||||
placeholder: widget.cellStyle?.placeholder ?? "",
|
||||
alignment: alignment,
|
||||
cellPadding:
|
||||
widget.cellStyle?.cellPadding ?? GridSize.cellContentInsets,
|
||||
);
|
||||
if (PlatformExtension.isDesktopOrWeb) {
|
||||
return AppFlowyPopover(
|
||||
controller: _popover,
|
||||
triggerActions: PopoverTriggerFlags.none,
|
||||
direction: PopoverDirection.bottomWithLeftAligned,
|
||||
constraints: BoxConstraints.loose(const Size(260, 620)),
|
||||
margin: EdgeInsets.zero,
|
||||
child: child,
|
||||
popupBuilder: (BuildContext popoverContent) {
|
||||
return DateCellEditor(
|
||||
cellController: widget.cellControllerBuilder.build()
|
||||
as DateCellController,
|
||||
onDismissed: () =>
|
||||
widget.cellContainerNotifier.isFocus = false,
|
||||
);
|
||||
},
|
||||
onClose: () {
|
||||
widget.cellContainerNotifier.isFocus = false;
|
||||
},
|
||||
);
|
||||
} else {
|
||||
return FlowyButton(
|
||||
text: child,
|
||||
onTap: () {
|
||||
showMobileBottomSheet(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return MobileDateCellEditScreen(
|
||||
controller: widget.cellControllerBuilder.build()
|
||||
as DateCellController,
|
||||
showAsFullScreen: false,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
|
@ -0,0 +1,193 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/date_picker/appflowy_calendar.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:table_calendar/table_calendar.dart';
|
||||
|
||||
import 'date_cal_bloc.dart';
|
||||
|
||||
class MobileDatePicker extends StatefulWidget {
|
||||
const MobileDatePicker({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MobileDatePicker> createState() => _MobileDatePickerState();
|
||||
}
|
||||
|
||||
class _MobileDatePickerState extends State<MobileDatePicker> {
|
||||
DateTime _focusedDay = DateTime.now();
|
||||
CalendarFormat _calendarFormat = CalendarFormat.month;
|
||||
|
||||
final ValueNotifier<(DateTime, dynamic)> _currentDateNotifier = ValueNotifier(
|
||||
(DateTime.now(), null),
|
||||
);
|
||||
PageController? _pageController;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
const VSpace(8.0),
|
||||
_buildHeader(context),
|
||||
const VSpace(8.0),
|
||||
_buildCalendar(context),
|
||||
const VSpace(16.0),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCalendar(BuildContext context) {
|
||||
const selectedColor = Color(0xFF00BCF0);
|
||||
final textStyle = Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
fontSize: 16.0,
|
||||
);
|
||||
const boxDecoration = BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
);
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: BlocBuilder<DateCellCalendarBloc, DateCellCalendarState>(
|
||||
builder: (context, state) {
|
||||
return TableCalendar(
|
||||
firstDay: kFirstDay,
|
||||
lastDay: kLastDay,
|
||||
focusedDay: _focusedDay,
|
||||
rowHeight: 48.0,
|
||||
calendarFormat: _calendarFormat,
|
||||
daysOfWeekHeight: 48.0,
|
||||
rangeSelectionMode: state.isRange
|
||||
? RangeSelectionMode.enforced
|
||||
: RangeSelectionMode.disabled,
|
||||
rangeStartDay: state.isRange ? state.startDay : null,
|
||||
rangeEndDay: state.isRange ? state.endDay : null,
|
||||
onCalendarCreated: (pageController) =>
|
||||
_pageController = pageController,
|
||||
headerVisible: false,
|
||||
availableGestures: AvailableGestures.horizontalSwipe,
|
||||
calendarStyle: CalendarStyle(
|
||||
cellMargin: const EdgeInsets.all(3.5),
|
||||
defaultDecoration: boxDecoration,
|
||||
selectedDecoration: boxDecoration.copyWith(
|
||||
color: selectedColor,
|
||||
),
|
||||
todayDecoration: boxDecoration.copyWith(
|
||||
color: Colors.transparent,
|
||||
border: Border.all(color: selectedColor),
|
||||
),
|
||||
weekendDecoration: boxDecoration,
|
||||
outsideDecoration: boxDecoration,
|
||||
rangeStartDecoration: boxDecoration.copyWith(
|
||||
color: selectedColor,
|
||||
),
|
||||
rangeEndDecoration: boxDecoration.copyWith(
|
||||
color: selectedColor,
|
||||
),
|
||||
defaultTextStyle: textStyle,
|
||||
weekendTextStyle: textStyle,
|
||||
selectedTextStyle: textStyle.copyWith(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
),
|
||||
rangeStartTextStyle: textStyle.copyWith(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
),
|
||||
rangeEndTextStyle: textStyle.copyWith(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
),
|
||||
todayTextStyle: textStyle,
|
||||
outsideTextStyle: textStyle.copyWith(
|
||||
color: Theme.of(context).disabledColor,
|
||||
),
|
||||
rangeHighlightColor:
|
||||
Theme.of(context).colorScheme.secondaryContainer,
|
||||
),
|
||||
calendarBuilders: CalendarBuilders(
|
||||
dowBuilder: (context, day) {
|
||||
final locale = context.locale.toLanguageTag();
|
||||
final label = DateFormat.E(locale).format(day).substring(0, 2);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 8.0),
|
||||
child: Center(
|
||||
child: Text(
|
||||
label,
|
||||
style: textStyle.copyWith(
|
||||
color: Theme.of(context).hintColor,
|
||||
fontSize: 14.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
selectedDayPredicate: (day) =>
|
||||
state.isRange ? false : isSameDay(state.dateTime, day),
|
||||
onDaySelected: (selectedDay, focusedDay) {
|
||||
context.read<DateCellCalendarBloc>().add(
|
||||
DateCellCalendarEvent.selectDay(selectedDay),
|
||||
);
|
||||
},
|
||||
onRangeSelected: (start, end, focusedDay) {
|
||||
context.read<DateCellCalendarBloc>().add(
|
||||
DateCellCalendarEvent.selectDateRange(start, end),
|
||||
);
|
||||
},
|
||||
onFormatChanged: (calendarFormat) => setState(() {
|
||||
_calendarFormat = calendarFormat;
|
||||
}),
|
||||
onPageChanged: (focusedDay) => setState(() {
|
||||
_focusedDay = focusedDay;
|
||||
_currentDateNotifier.value = (focusedDay, null);
|
||||
}),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildHeader(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
const HSpace(16.0),
|
||||
ValueListenableBuilder(
|
||||
valueListenable: _currentDateNotifier,
|
||||
builder: (_, value, ___) {
|
||||
return FlowyText(
|
||||
DateFormat.yMMMM(value.$2).format(value.$1),
|
||||
fontSize: 16.0,
|
||||
);
|
||||
},
|
||||
),
|
||||
const Spacer(),
|
||||
FlowyButton(
|
||||
useIntrinsicWidth: true,
|
||||
text: FlowySvg(
|
||||
FlowySvgs.arrow_left_s,
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
size: const Size.square(24.0),
|
||||
),
|
||||
onTap: () => _pageController?.previousPage(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeOut,
|
||||
),
|
||||
),
|
||||
const HSpace(24.0),
|
||||
FlowyButton(
|
||||
useIntrinsicWidth: true,
|
||||
text: FlowySvg(
|
||||
FlowySvgs.arrow_right_s,
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
size: const Size.square(24.0),
|
||||
),
|
||||
onTap: () => _pageController?.nextPage(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeOut,
|
||||
),
|
||||
),
|
||||
const HSpace(8.0),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/widgets/widgets.dart';
|
||||
import 'package:appflowy/plugins/base/drag_handler.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/layout/sizes.dart';
|
||||
@ -49,7 +50,7 @@ class _MobileSelectOptionEditorState extends State<MobileSelectOptionEditor> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
return ConstrainedBox(
|
||||
constraints: const BoxConstraints.tightFor(height: 420),
|
||||
child: BlocProvider(
|
||||
create: (context) => SelectOptionCellEditorBloc(
|
||||
@ -504,23 +505,36 @@ class _MoreOptions extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final color = Theme.of(context).colorScheme.secondaryContainer;
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const VSpace(8.0),
|
||||
VSpace(8.0, color: color),
|
||||
_buildRenameTextField(context),
|
||||
const VSpace(16.0),
|
||||
VSpace(
|
||||
16.0,
|
||||
color: color,
|
||||
),
|
||||
_buildDeleteButton(context),
|
||||
const VSpace(16.0),
|
||||
VSpace(
|
||||
16.0,
|
||||
color: color,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 12.0),
|
||||
child: FlowyText(
|
||||
LocaleKeys.grid_field_optionTitle.tr(),
|
||||
color: Theme.of(context).hintColor,
|
||||
child: ColoredBox(
|
||||
color: color,
|
||||
child: FlowyText(
|
||||
LocaleKeys.grid_field_optionTitle.tr(),
|
||||
color: Theme.of(context).hintColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
const VSpace(4.0),
|
||||
VSpace(
|
||||
4.0,
|
||||
color: color,
|
||||
),
|
||||
_buildColorOptions(context),
|
||||
],
|
||||
),
|
||||
@ -530,7 +544,7 @@ class _MoreOptions extends StatelessWidget {
|
||||
Widget _buildRenameTextField(BuildContext context) {
|
||||
return ConstrainedBox(
|
||||
constraints: const BoxConstraints.tightFor(height: 52.0),
|
||||
child: _DefaultDecorateBox(
|
||||
child: FlowyOptionDecorateBox(
|
||||
showTopBorder: true,
|
||||
showBottomBorder: true,
|
||||
child: TextField(
|
||||
@ -549,28 +563,15 @@ class _MoreOptions extends StatelessWidget {
|
||||
}
|
||||
|
||||
Widget _buildDeleteButton(BuildContext context) {
|
||||
return _DefaultDecorateBox(
|
||||
showTopBorder: true,
|
||||
showBottomBorder: true,
|
||||
child: FlowyButton(
|
||||
text: FlowyText(
|
||||
LocaleKeys.button_delete.tr(),
|
||||
fontSize: 16.0,
|
||||
),
|
||||
margin: const EdgeInsets.symmetric(
|
||||
horizontal: 12.0,
|
||||
vertical: 16.0,
|
||||
),
|
||||
leftIcon: const FlowySvg(FlowySvgs.delete_s),
|
||||
leftIconSize: const Size.square(24.0),
|
||||
iconPadding: 8.0,
|
||||
onTap: onDelete,
|
||||
),
|
||||
return FlowyOptionTile(
|
||||
text: LocaleKeys.button_delete.tr(),
|
||||
leftIcon: const FlowySvg(FlowySvgs.delete_s),
|
||||
onTap: onDelete,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildColorOptions(BuildContext context) {
|
||||
return _DefaultDecorateBox(
|
||||
return FlowyOptionDecorateBox(
|
||||
showTopBorder: true,
|
||||
showBottomBorder: true,
|
||||
child: Padding(
|
||||
@ -606,33 +607,3 @@ class _MoreOptions extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _DefaultDecorateBox extends StatelessWidget {
|
||||
const _DefaultDecorateBox({
|
||||
this.showTopBorder = true,
|
||||
this.showBottomBorder = true,
|
||||
required this.child,
|
||||
});
|
||||
|
||||
final bool showTopBorder;
|
||||
final bool showBottomBorder;
|
||||
final Widget child;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.secondaryContainer,
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
color: Theme.of(context).dividerColor,
|
||||
),
|
||||
bottom: BorderSide(
|
||||
color: Theme.of(context).dividerColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import 'package:appflowy/plugins/database_view/widgets/row/cells/select_option_c
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/select_option.pb.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
@ -209,11 +208,6 @@ class _SelectOptionWrapState extends State<SelectOptionWrap> {
|
||||
onTap: () {
|
||||
showMobileBottomSheet(
|
||||
context: context,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Corners.s12Radius,
|
||||
),
|
||||
),
|
||||
builder: (context) {
|
||||
return MobileSelectOptionEditor(
|
||||
cellController: cellController,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'package:appflowy/mobile/presentation/database/card/card.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_detail/mobile_create_row_field_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_property_edit/card_property_edit_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/row/cells/cells.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/date_picker/mobile_date_picker_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/mobile_board_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/mobile_calendar_events_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/mobile_calendar_screen.dart';
|
||||
@ -539,11 +539,18 @@ GoRoute _mobileDateCellEditScreenRoute() {
|
||||
path: MobileDateCellEditScreen.routeName,
|
||||
pageBuilder: (context, state) {
|
||||
final args = state.extra as Map<String, dynamic>;
|
||||
final cellController = args[MobileDateCellEditScreen.argCellController];
|
||||
|
||||
return MaterialPage(
|
||||
child: MobileDateCellEditScreen(cellController),
|
||||
final controller = args[MobileDateCellEditScreen.dateCellController];
|
||||
final fullScreen = args[MobileDateCellEditScreen.fullScreen];
|
||||
return CustomTransitionPage(
|
||||
transitionsBuilder: (_, __, ___, child) => child,
|
||||
fullscreenDialog: true,
|
||||
opaque: false,
|
||||
barrierDismissible: true,
|
||||
barrierColor: Theme.of(context).bottomSheetTheme.modalBarrierColor,
|
||||
child: MobileDateCellEditScreen(
|
||||
controller: controller,
|
||||
showAsFullScreen: fullScreen ?? true,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
@ -62,6 +62,7 @@ class FlowyButton extends StatelessWidget {
|
||||
return InkWell(
|
||||
onTap: disable ? null : onTap,
|
||||
onSecondaryTap: disable ? null : onSecondaryTap,
|
||||
borderRadius: radius ?? Corners.s6Border,
|
||||
child: _render(context),
|
||||
);
|
||||
}
|
||||
|
@ -11,12 +11,29 @@ class Space extends StatelessWidget {
|
||||
}
|
||||
|
||||
class VSpace extends StatelessWidget {
|
||||
final double size;
|
||||
const VSpace(
|
||||
this.size, {
|
||||
super.key,
|
||||
this.color,
|
||||
});
|
||||
|
||||
const VSpace(this.size, {Key? key}) : super(key: key);
|
||||
final double size;
|
||||
final Color? color;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Space(0, size);
|
||||
Widget build(BuildContext context) {
|
||||
if (color != null) {
|
||||
return SizedBox(
|
||||
height: size,
|
||||
width: double.infinity,
|
||||
child: ColoredBox(
|
||||
color: color!,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Space(0, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class HSpace extends StatelessWidget {
|
||||
|
@ -1124,6 +1124,7 @@
|
||||
"pageIcon": "Page icon",
|
||||
"language": "Language",
|
||||
"font": "Font",
|
||||
"actions": "Actions"
|
||||
"actions": "Actions",
|
||||
"date": "Date"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user