Skip to content

Commit

Permalink
feat(control): add time control implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
HammadAsiif committed Nov 19, 2024
1 parent d38d7c6 commit 2898cf4
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 0 deletions.
18 changes: 18 additions & 0 deletions apps/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,24 @@ var settingControls = <SettingsControlConfig>[
MyImageControl(key: "my_image", title: "Mikey"),
],
),
ControlConfig.group(
title: "Time Input",
children: [
ControlConfig.time(
key: "basic_time_picker",
title: "My Time Picker",
description: "Described.",
hintText: "Select Time",
),
ControlConfig.time(
key: "custom_time_picker",
title: "Time Picker - 12H Format",
description: "Described.",
hintText: "HH:mm AM/PM",
timeFormat: ["hh", ":", "mm", " ", "a"],
),
],
),
ControlConfig.group(
title: "Toggles",
children: [
Expand Down
23 changes: 23 additions & 0 deletions packages/flutter_settings/lib/src/config/controls/controls.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import "package:flutter/material.dart";
import "package:flutter_settings/flutter_settings.dart";
import "package:flutter_settings/src/config/controls/checkbox.dart";
import "package:flutter_settings/src/config/controls/radio.dart";
import "package:flutter_settings/src/config/controls/time.dart";
import "package:settings_repository/settings_repository.dart";

export "base.dart";
Expand All @@ -27,6 +29,27 @@ abstract final class ControlConfig {
wrapperBuilder: wrapperBuilder ?? defaultDescriptionTitleControlWrapper,
);

///
static TimeControlConfig time({
required String key,
required String title,
String? description,
String? hintText,
List<String> timeFormat = const ["HH", ":", "mm"],
Widget? suffixIcon,
InputDecoration? inputDecoration,
ControlWrapperBuilder<String, TimeControlConfig>? wrapperBuilder,
}) =>
TimeControlConfig(
title: title,
description: description,
hintText: hintText,
timeFormat: timeFormat,
suffixIcon: suffixIcon,
initialValue: SettingsControl(key: key),
wrapperBuilder: wrapperBuilder ?? defaultDescriptionTitleControlWrapper,
);

///
static SettingsControlConfig toggle({
required String key,
Expand Down
83 changes: 83 additions & 0 deletions packages/flutter_settings/lib/src/config/controls/time.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import "package:flutter/material.dart";
import "package:flutter_settings/flutter_settings.dart";
import "package:settings_repository/settings_repository.dart";

/// Time Control Configuration
class TimeControlConfig
extends DescriptiveTitleControlConfig<String, TimeControlConfig> {
/// Constructor for Time Control Config
TimeControlConfig({
required super.title,
required super.description,
required super.initialValue,
this.hintText,
this.suffixIcon,
this.timeFormat = const ["HH", ":", "mm"],
super.wrapperBuilder = defaultDescriptionTitleControlWrapper,
});

/// Hint text for the time picker
final String? hintText;

/// Icon to display as suffix in the input field
final Widget? suffixIcon;

/// Time format for displaying the picked time
final List<String> timeFormat;

@override
Widget buildSetting(
BuildContext context,
SettingsControl<String> control,
SettingsControlController controller,
) {
var initialTime =
control.value != null ? _parseTime(control.value!) : TimeOfDay.now();

return InkWell(
onTap: () async {
var pickedTime = await showTimePicker(
context: context,
initialTime: initialTime ?? TimeOfDay.now(),
);

if (pickedTime != null) {
var formattedTime = _formatTime(pickedTime, timeFormat);
await controller.updateControl(control.update(formattedTime));
}
},
child: Text(
control.value ?? hintText ?? "Select Time",
),
);
}

/// Format the `TimeOfDay` into a string using the given `timeFormat`.
String _formatTime(TimeOfDay time, List<String> format) {
var hour24 = time.hour.toString().padLeft(2, "0");
var hour12 =
(time.hour % 12 == 0 ? 12 : time.hour % 12).toString().padLeft(2, "0");
var minute = time.minute.toString().padLeft(2, "0");
var period = time.hour >= 12 ? "PM" : "AM";

return format
.join()
.replaceAll("HH", hour24)
.replaceAll("hh", hour12)
.replaceAll("mm", minute)
.replaceAll("a", period);
}

/// Parse a time string into a `TimeOfDay` object.
TimeOfDay? _parseTime(String value) {
try {
var parts = value.split(":");
return TimeOfDay(
hour: int.parse(parts[0]),
minute: int.parse(parts[1]),
);
} on Exception {
return null;
}
}
}

0 comments on commit 2898cf4

Please sign in to comment.