-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(cat-voices): Date & Time input widget #1224
base: mve3
Are you sure you want to change the base?
Conversation
…ntroller handling in text fields
✅ Test Report | |
catalyst_voices/apps/voices/lib/widgets/text_field/date_picker/voices_time_picker.dart
Outdated
Show resolved
Hide resolved
catalyst_voices/apps/voices/lib/widgets/text_field/date_picker/voices_time_picker.dart
Outdated
Show resolved
Hide resolved
catalyst_voices/apps/voices/lib/widgets/text_field/date_picker/voices_time_picker.dart
Outdated
Show resolved
Hide resolved
catalyst_voices/apps/voices/lib/widgets/text_field/date_picker/voices_time_picker.dart
Outdated
Show resolved
Hide resolved
catalyst_voices/apps/voices/lib/widgets/text_field/date_picker/voices_time_picker.dart
Outdated
Show resolved
Hide resolved
catalyst_voices/apps/voices/lib/widgets/text_field/date_picker/date_picker_controller.dart
Outdated
Show resolved
Hide resolved
catalyst_voices/apps/voices/lib/widgets/text_field/date_picker/date_picker_controller.dart
Outdated
Show resolved
Hide resolved
catalyst_voices/apps/voices/lib/widgets/text_field/date_picker/date_picker_controller.dart
Outdated
Show resolved
Hide resolved
catalyst_voices/apps/voices/lib/widgets/text_field/date_picker/voices_date_picker_field.dart
Outdated
Show resolved
Hide resolved
class VoicesDatePicker extends StatefulWidget { | ||
final DatePickerController controller; | ||
final String timeZone; | ||
const VoicesDatePicker({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Idea for moving / renaming classes.
Let's say we have VoicesDateTimeTextField
which have ValueChanged<DateTime> onChanged
and simple controller(VoicesDateTimeController
) which maybe extends TextEditingController
or simply ValueNotifier<DateTime>
.
Goal here is for VoicesDateTimeTextField
to output only DateTime
and accept it as input for VoicesDateTimeController
.
This widget builds two childs in a row (will be more complex with decoration), VoicesDateTextField
and VoicesTimeOfDayTextField
both of which are stateless and accept TextEditingController
from VoicesDateTimeTextField
and have onCalendarTap
/ onClockTap
respectively.
Now VoicesDateTimeTextField
can launch correct picker and global keys can be private.
Ofc. VoicesDateTimeTextField
is watching changes in both fields and merging them into final DateTime
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's good idea, but in this case, we have two possibilities about from where data come from: either textfield or picker. We also need to validate this data. If we want to separate controllers then your approach is better and I'm happy to do it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3 controllers even. I think it will be easier to read and maintain
VoicesDateTimeTextField
will have to open OverlayEntry
and update respective controller, yes, and VoicesDateTextField
/ VoicesTimeOfDayTextField
will have to watch changes in its controller and validate them but it's happening automatically i believe.
Pseudo code
// voices_date_time_text_field.dart
class VoicesDateTimeTextFieldController extends ValueNotifier<DateTime?> {
VoicesDateTimeTextFieldController([super._value]);
}
class VoicesDateTimeTextField extends StatefulWidget {
final VoicesDateTimeTextFieldController? controller;
final ValueChanged<DateTime?>? onChanged;
const VoicesDateTimeTextField({
super.key,
this.controller,
this.onChanged,
});
@override
State<VoicesDateTimeTextField> createState() {
return _VoicesDateTimeTextFieldState();
}
}
class _VoicesDateTimeTextFieldState extends State<VoicesDateTimeTextField> {
late final VoicesDateTextFieldController _dateController;
late final VoicesTimeOfDayTextFieldController _timeOfDayController;
@override
void initState() {
super.initState();
_dateController = VoicesDateTextFieldController()..addListener(_xxx);
_timeOfDayController = VoicesTimeOfDayTextFieldController()
..addListener(_xxx);
}
@override
Widget build(BuildContext context) {
return Row(
children: [],
);
}
void _xxx() {
//
}
}
// voices_date_text_field.dart
class VoicesDateTextFieldController extends ValueNotifier<DateTime?> {
VoicesDateTextFieldController([super._value]);
}
class VoicesDateTextField extends StatefulWidget {
final VoicesDateTextFieldController controller;
const VoicesDateTextField({
super.key,
required this.controller,
});
@override
State<VoicesDateTextField> createState() => _VoicesDateTextFieldState();
}
class _VoicesDateTextFieldState extends State<VoicesDateTextField> {
late final TextEditingController _textEditingController;
@override
void initState() {
super.initState();
_textEditingController = TextEditingController();
}
@override
Widget build(BuildContext context) {
return VoicesTextField(
controller: _textEditingController,
onFieldSubmitted: (value) {},
);
}
// listen _textEditingController, validate, parse and pass result to widget.controller
}
// voices_time_of_day_text_field.dart
class VoicesTimeOfDayTextFieldController extends ValueNotifier<TimeOfDay?> {
VoicesTimeOfDayTextFieldController([super._value]);
}
class VoicesTimeOfDayTextField extends StatefulWidget {
const VoicesTimeOfDayTextField({super.key});
@override
State<VoicesTimeOfDayTextField> createState() =>
_VoicesTimeOfDayTextFieldState();
}
class _VoicesTimeOfDayTextFieldState extends State<VoicesTimeOfDayTextField> {
@override
Widget build(BuildContext context) {
return VoicesTextField(
onFieldSubmitted: (value) {},
);
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sure this will be harded to implement then what i just shown so we may discuss this with frontend team before committing to it
One more thing, make sure to you can jump focus from one text field to next with tab, probably exclude calendar/clock from focus or implement focus travel |
…stency and state management across the application
), | ||
), | ||
), | ||
onFieldSubmitted: (String value) {}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nothing should happen here?
class VoicesDatePicker extends StatefulWidget { | ||
final DatePickerController controller; | ||
final String timeZone; | ||
const VoicesDatePicker({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3 controllers even. I think it will be easier to read and maintain
VoicesDateTimeTextField
will have to open OverlayEntry
and update respective controller, yes, and VoicesDateTextField
/ VoicesTimeOfDayTextField
will have to watch changes in its controller and validate them but it's happening automatically i believe.
Pseudo code
// voices_date_time_text_field.dart
class VoicesDateTimeTextFieldController extends ValueNotifier<DateTime?> {
VoicesDateTimeTextFieldController([super._value]);
}
class VoicesDateTimeTextField extends StatefulWidget {
final VoicesDateTimeTextFieldController? controller;
final ValueChanged<DateTime?>? onChanged;
const VoicesDateTimeTextField({
super.key,
this.controller,
this.onChanged,
});
@override
State<VoicesDateTimeTextField> createState() {
return _VoicesDateTimeTextFieldState();
}
}
class _VoicesDateTimeTextFieldState extends State<VoicesDateTimeTextField> {
late final VoicesDateTextFieldController _dateController;
late final VoicesTimeOfDayTextFieldController _timeOfDayController;
@override
void initState() {
super.initState();
_dateController = VoicesDateTextFieldController()..addListener(_xxx);
_timeOfDayController = VoicesTimeOfDayTextFieldController()
..addListener(_xxx);
}
@override
Widget build(BuildContext context) {
return Row(
children: [],
);
}
void _xxx() {
//
}
}
// voices_date_text_field.dart
class VoicesDateTextFieldController extends ValueNotifier<DateTime?> {
VoicesDateTextFieldController([super._value]);
}
class VoicesDateTextField extends StatefulWidget {
final VoicesDateTextFieldController controller;
const VoicesDateTextField({
super.key,
required this.controller,
});
@override
State<VoicesDateTextField> createState() => _VoicesDateTextFieldState();
}
class _VoicesDateTextFieldState extends State<VoicesDateTextField> {
late final TextEditingController _textEditingController;
@override
void initState() {
super.initState();
_textEditingController = TextEditingController();
}
@override
Widget build(BuildContext context) {
return VoicesTextField(
controller: _textEditingController,
onFieldSubmitted: (value) {},
);
}
// listen _textEditingController, validate, parse and pass result to widget.controller
}
// voices_time_of_day_text_field.dart
class VoicesTimeOfDayTextFieldController extends ValueNotifier<TimeOfDay?> {
VoicesTimeOfDayTextFieldController([super._value]);
}
class VoicesTimeOfDayTextField extends StatefulWidget {
const VoicesTimeOfDayTextField({super.key});
@override
State<VoicesTimeOfDayTextField> createState() =>
_VoicesTimeOfDayTextFieldState();
}
class _VoicesTimeOfDayTextFieldState extends State<VoicesTimeOfDayTextField> {
@override
Widget build(BuildContext context) {
return VoicesTextField(
onFieldSubmitted: (value) {},
);
}
}
class VoicesDatePicker extends StatefulWidget { | ||
final DatePickerController controller; | ||
final String timeZone; | ||
const VoicesDatePicker({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sure this will be harded to implement then what i just shown so we may discuss this with frontend team before committing to it
…controllers for better UI interaction
✅ Test Report | |
✅ Test Report | |
✅ Test Report | |
Description
This is a new component that uses two standard text-fields bonded together to provide a date/time selection widgets to setup the most important campaign dates.
Related Issue(s)
Resolves #1181
Description of Changes
Adding new widget with controllers to select date and time.
Nagranie.z.ekranu.2024-11-18.o.14.32.23.mov
Requirements
Manual input requirements / date
Manual input requirements / time
Widget guided select date
Widget guided select time
Screenshots
If applicable, add screenshots to help explain your changes.
Please confirm the following checks