Merge pull request #1 from Iconica-Development/stable

Stable release
This commit is contained in:
Thomas Klein Langenhorst 2022-09-05 12:25:37 +02:00 committed by GitHub
commit c510ea5ec2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
45 changed files with 981 additions and 545 deletions

View file

@ -4,7 +4,7 @@
# This file should be version controlled. # This file should be version controlled.
version: version:
revision: f1875d570e39de09040c8f79aa13cc56baab8db1 revision: ffccd96b62ee8cec7740dab303538c5fc26ac543
channel: stable channel: stable
project_type: app project_type: app
@ -13,26 +13,26 @@ project_type: app
migration: migration:
platforms: platforms:
- platform: root - platform: root
create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 create_revision: ffccd96b62ee8cec7740dab303538c5fc26ac543
base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 base_revision: ffccd96b62ee8cec7740dab303538c5fc26ac543
- platform: android - platform: android
create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 create_revision: ffccd96b62ee8cec7740dab303538c5fc26ac543
base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 base_revision: ffccd96b62ee8cec7740dab303538c5fc26ac543
- platform: ios - platform: ios
create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 create_revision: ffccd96b62ee8cec7740dab303538c5fc26ac543
base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 base_revision: ffccd96b62ee8cec7740dab303538c5fc26ac543
- platform: linux - platform: linux
create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 create_revision: ffccd96b62ee8cec7740dab303538c5fc26ac543
base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 base_revision: ffccd96b62ee8cec7740dab303538c5fc26ac543
- platform: macos - platform: macos
create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 create_revision: ffccd96b62ee8cec7740dab303538c5fc26ac543
base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 base_revision: ffccd96b62ee8cec7740dab303538c5fc26ac543
- platform: web - platform: web
create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 create_revision: ffccd96b62ee8cec7740dab303538c5fc26ac543
base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 base_revision: ffccd96b62ee8cec7740dab303538c5fc26ac543
- platform: windows - platform: windows
create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 create_revision: ffccd96b62ee8cec7740dab303538c5fc26ac543
base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 base_revision: ffccd96b62ee8cec7740dab303538c5fc26ac543
# User provided section # User provided section

View file

@ -44,7 +44,7 @@ android {
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.example" applicationId "com.iconica.example"
// You can update the following values to match your application needs. // You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
minSdkVersion flutter.minSdkVersion minSdkVersion flutter.minSdkVersion

View file

@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.example"> package="com.iconica.example">
<!-- The INTERNET permission is required for development. Specifically, <!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.

View file

@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.example"> package="com.iconica.example">
<application <application
android:label="example" android:label="example"
android:name="${applicationName}" android:name="${applicationName}"

View file

@ -1,4 +1,4 @@
package com.example.example package com.iconica.example
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.android.FlutterActivity

View file

@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.example"> package="com.iconica.example">
<!-- The INTERNET permission is required for development. Specifically, <!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.

View file

@ -1,4 +1,3 @@
#Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

View file

@ -21,6 +21,6 @@
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0</string> <string>1.0</string>
<key>MinimumOSVersion</key> <key>MinimumOSVersion</key>
<string>9.0</string> <string>11.0</string>
</dict> </dict>
</plist> </plist>

View file

@ -272,7 +272,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;
@ -295,7 +295,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.example.example; PRODUCT_BUNDLE_IDENTIFIER = com.iconica.example;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@ -350,7 +350,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos; SDKROOT = iphoneos;
@ -399,7 +399,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;
@ -424,7 +424,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.example.example; PRODUCT_BUNDLE_IDENTIFIER = com.iconica.example;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@ -447,7 +447,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.example.example; PRODUCT_BUNDLE_IDENTIFIER = com.iconica.example;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;

View file

@ -45,5 +45,7 @@
<false/> <false/>
<key>CADisableMinimumFrameDurationOnPhone</key> <key>CADisableMinimumFrameDurationOnPhone</key>
<true/> <true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict> </dict>
</plist> </plist>

View file

@ -6,7 +6,7 @@ void main() {
} }
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key); const MyApp({super.key});
// This widget is the root of your application. // This widget is the root of your application.
@override @override
@ -14,90 +14,38 @@ class MyApp extends StatelessWidget {
return MaterialApp( return MaterialApp(
title: 'Flutter Demo', title: 'Flutter Demo',
theme: ThemeData( theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue, primarySwatch: Colors.blue,
), ),
home: MyHomePage(), home: Scaffold(
appBar: AppBar(
title: const Text('Roster'),
),
body: const DatePickerDemo(),
),
); );
} }
} }
class MyHomePage extends StatelessWidget { class DatePickerDemo extends StatelessWidget {
const DatePickerDemo({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return DateTimePicker(
appBar: AppBar(title: Text('Rooster')), dateTimePickerTheme: const DateTimePickerTheme(
body: DateTimePicker( markedIndicatorColor: Colors.red,
// header: Container( selectedTheme: DateBoxSelectedTheme(
// height: 100, Color(0x4BF44336),
// width: MediaQuery.of(context).size.width, TextStyle(
// padding: const EdgeInsets.only(bottom: 10), color: Colors.red,
// child: Row( ),
// crossAxisAlignment: CrossAxisAlignment.end,
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// const SizedBox(
// width: 160,
// height: 34,
// child: Center(
// child: Text(
// 'Persoonlijk',
// style: TextStyle(
// fontSize: 16,
// fontWeight: FontWeight.w900,
// ),
// ),
// ),
// ),
// const SizedBox(
// width: 4,
// ),
// Container(
// width: 160,
// height: 34,
// decoration: BoxDecoration(
// color: const Color(0xFF00273D),
// borderRadius: const BorderRadius.all(
// Radius.circular(10),
// ),
// boxShadow: [
// BoxShadow(
// color: const Color(0xFF000000).withOpacity(0.50),
// offset: const Offset(0, 6),
// blurRadius: 9,
// ),
// ],
// ),
// child: const Center(
// child: Text(
// 'Teamplanning',
// style: TextStyle(
// color: Colors.white,
// fontSize: 16,
// fontWeight: FontWeight.w900,
// ),
// ),
// ),
// ),
// ],
// ),
// ),
markedDates: [DateTime(2022, 8, 26)],
child: Container(
margin: const EdgeInsets.only(
top: 195,
), ),
child: Container(), highlightTheme: DateBoxHighlightTheme(
), Colors.red,
), TextStyle(
color: Colors.white,
),
)),
markedDates: [DateTime(2022, 9, 6)],
); );
} }
} }

View file

@ -7,7 +7,7 @@ project(runner LANGUAGES CXX)
set(BINARY_NAME "example") set(BINARY_NAME "example")
# The unique GTK application identifier for this application. See: # The unique GTK application identifier for this application. See:
# https://wiki.gnome.org/HowDoI/ChooseApplicationID # https://wiki.gnome.org/HowDoI/ChooseApplicationID
set(APPLICATION_ID "com.example.example") set(APPLICATION_ID "com.iconica.example")
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent # Explicitly opt in to modern CMake behaviors to avoid warnings with recent
# versions of CMake. # versions of CMake.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -8,7 +8,7 @@
PRODUCT_NAME = example PRODUCT_NAME = example
// The application's bundle identifier // The application's bundle identifier
PRODUCT_BUNDLE_IDENTIFIER = com.example.example PRODUCT_BUNDLE_IDENTIFIER = com.iconica.example
// The copyright displayed in application information // The copyright displayed in application information
PRODUCT_COPYRIGHT = Copyright © 2022 com.example. All rights reserved. PRODUCT_COPYRIGHT = Copyright © 2022 com.iconica. All rights reserved.

View file

@ -7,7 +7,7 @@ packages:
name: async name: async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.8.2" version: "2.9.0"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
@ -21,21 +21,14 @@ packages:
name: characters name: characters
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.2.1"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
clock: clock:
dependency: transitive dependency: transitive
description: description:
name: clock name: clock
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.1.1"
collection: collection:
dependency: transitive dependency: transitive
description: description:
@ -56,7 +49,7 @@ packages:
name: fake_async name: fake_async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0" version: "1.3.1"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -101,28 +94,28 @@ packages:
name: matcher name: matcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.11" version: "0.12.12"
material_color_utilities: material_color_utilities:
dependency: transitive dependency: transitive
description: description:
name: material_color_utilities name: material_color_utilities
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.4" version: "0.1.5"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.7.0" version: "1.8.0"
path: path:
dependency: transitive dependency: transitive
description: description:
name: path name: path
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.1" version: "1.8.2"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -134,7 +127,7 @@ packages:
name: source_span name: source_span
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.2" version: "1.9.0"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
@ -155,21 +148,21 @@ packages:
name: string_scanner name: string_scanner
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.1.1"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
name: term_glyph name: term_glyph
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.2.1"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.9" version: "0.4.12"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:

View file

@ -1,91 +1,24 @@
name: example name: datetime_picker_example
description: A new Flutter project. description: DateTimePicker Widget
# The following line prevents the package from being accidentally published to publish_to: 'none'
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1 version: 1.0.0+1
environment: environment:
sdk: ">=2.17.6 <3.0.0" sdk: ">=2.17.6 <3.0.0"
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
cupertino_icons: ^1.0.2
flutter_date_time_picker: flutter_date_time_picker:
path: ../ path: ../
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^2.0.0 flutter_lints: ^2.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter: flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages

View file

@ -1,30 +0,0 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:example/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const MyApp());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
}

View file

@ -20,6 +20,13 @@ add_executable(${BINARY_NAME} WIN32
# that need different build settings. # that need different build settings.
apply_standard_settings(${BINARY_NAME}) apply_standard_settings(${BINARY_NAME})
# Add preprocessor definitions for the build version.
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"")
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}")
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}")
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}")
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}")
# Disable Windows macros that collide with C++ standard library functions. # Disable Windows macros that collide with C++ standard library functions.
target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")

View file

@ -60,14 +60,14 @@ IDI_APP_ICON ICON "resources\\app_icon.ico"
// Version // Version
// //
#ifdef FLUTTER_BUILD_NUMBER #if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD)
#define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER #define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD
#else #else
#define VERSION_AS_NUMBER 1,0,0 #define VERSION_AS_NUMBER 1,0,0,0
#endif #endif
#ifdef FLUTTER_BUILD_NAME #if defined(FLUTTER_VERSION)
#define VERSION_AS_STRING #FLUTTER_BUILD_NAME #define VERSION_AS_STRING FLUTTER_VERSION
#else #else
#define VERSION_AS_STRING "1.0.0" #define VERSION_AS_STRING "1.0.0"
#endif #endif
@ -89,11 +89,11 @@ BEGIN
BEGIN BEGIN
BLOCK "040904e4" BLOCK "040904e4"
BEGIN BEGIN
VALUE "CompanyName", "com.example" "\0" VALUE "CompanyName", "com.iconica" "\0"
VALUE "FileDescription", "example" "\0" VALUE "FileDescription", "example" "\0"
VALUE "FileVersion", VERSION_AS_STRING "\0" VALUE "FileVersion", VERSION_AS_STRING "\0"
VALUE "InternalName", "example" "\0" VALUE "InternalName", "example" "\0"
VALUE "LegalCopyright", "Copyright (C) 2022 com.example. All rights reserved." "\0" VALUE "LegalCopyright", "Copyright (C) 2022 com.iconica. All rights reserved." "\0"
VALUE "OriginalFilename", "example.exe" "\0" VALUE "OriginalFilename", "example.exe" "\0"
VALUE "ProductName", "example" "\0" VALUE "ProductName", "example" "\0"
VALUE "ProductVersion", VERSION_AS_STRING "\0" VALUE "ProductVersion", VERSION_AS_STRING "\0"

View file

@ -7,7 +7,7 @@
</application> </application>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application> <application>
<!-- Windows 10 --> <!-- Windows 10 and Windows 11 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
<!-- Windows 8.1 --> <!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>

View file

@ -1,3 +1,9 @@
library flutter_date_time_picker; library flutter_date_time_picker;
export 'src/date_time_picker.dart'; export 'src/date_time_picker.dart' show DateTimePicker;
export 'src/enums/date_box_shape.dart';
export 'src/models/date_box_base_theme.dart';
export 'src/models/date_box_disabled_theme.dart';
export 'src/models/date_box_highlight_theme.dart';
export 'src/models/date_box_selected_theme.dart';
export 'src/models/date_time_picker_theme.dart';

View file

@ -1,130 +1,168 @@
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_date_time_picker/src/models/date_time_picker_theme.dart';
import 'package:flutter_date_time_picker/src/utils/date_time_picker_controller.dart'; import 'package:flutter_date_time_picker/src/utils/date_time_picker_controller.dart';
import 'package:flutter_date_time_picker/src/widgets/month_date_time_picker.dart/month_date_time_picker_sheet.dart'; import 'package:flutter_date_time_picker/src/widgets/month_date_time_picker.dart/month_date_time_picker_sheet.dart';
import 'package:flutter_date_time_picker/src/widgets/week_date_time_picker/week_date_time_picker_sheet.dart'; import 'package:flutter_date_time_picker/src/widgets/week_date_time_picker/week_date_time_picker_sheet.dart';
import 'package:intl/date_symbol_data_local.dart'; import 'package:intl/date_symbol_data_local.dart';
/// A widget that displays a date picker from a sheet form the top of the screen.
/// This sheet displays initialy displays a week of days but can be dragged down to show full months.
/// Both views can be dragged sideways to show the next or previous wweek/month.
///
/// The child will be the [Widget] that is displayed underneath the date picker in the stack.
///
/// The header [Widget] will be displayed above the date picker in the modal sheet in a column.
///
/// onTapDay is a callback that provides the taped date as a [DateTime] object.
///
/// highlightToday is a [bool] that determines which day shall we highlighted.
/// true will always highlight the current date. This is standard.
/// false will highlight the currently selected date by either the initial date or the one chosen by the user.
/// [highlighColor] is used as background for the highlighted day.
/// [toggleableActiveColor] is used for the text color when highlighted.
/// [disabledColor] is used for the text color when not highlighted.
///
/// markedDates contain the dates [DateTime] that will be marked in the picker by a small dot.
/// [indicatorColor] is used for the color of the dot.
///
/// Example:
/// ```dart
/// ShellDatePicker(
/// initialDate: selectedDate,
/// highlightToday: false,
/// onTapDay: (date) {
/// setState(() {
/// selectedDate = date;
/// });
/// },
/// markedDates: [
/// DateTime(2022, 7, 22),
/// ],
/// header: Container(
/// height: 100,
/// width: MediaQuery.of(context).size.width,
/// padding: const EdgeInsets.only(bottom: 10),
/// child: Row(
/// crossAxisAlignment: CrossAxisAlignment.end,
/// mainAxisAlignment: MainAxisAlignment.center,
/// children: [
/// const SizedBox(
/// width: 160,
/// height: 34,
/// child: Center(
/// child: Text(
/// 'Persoonlijk',
/// style: TextStyle(
/// fontSize: 16,
/// fontWeight: FontWeight.w900,
/// ),
/// ),
/// ),
/// ),
/// const SizedBox(
/// width: 4,
/// ),
/// Container(
/// width: 160,
/// height: 34,
/// decoration: BoxDecoration(
/// color: const Color(0xFF00273D),
/// borderRadius: const BorderRadius.all(
/// Radius.circular(10),
/// ),
/// boxShadow: [
/// BoxShadow(
/// color: const Color(0xFF000000).withOpacity(0.50),
/// offset: const Offset(0, 6),
/// blurRadius: 9,
/// ),
/// ],
/// ),
/// child: const Center(
/// child: Text(
/// 'Teamplanning',
/// style: TextStyle(
/// color: Colors.white,
/// fontSize: 16,
/// fontWeight: FontWeight.w900,
/// ),
/// ),
/// ),
/// ),
/// ],
/// ),
/// ),
/// child: Container(
/// margin: const EdgeInsets.only(
/// top: 195,
/// ),
/// child: ShellRoster(
/// startHour: 0,
/// endHour: 24,
/// blocks: [
/// for (Map<String, TimeOfDay> block in blocks) ...[
/// getBlock(block),
/// ],
/// ],
/// ),
/// ),
/// ),
///```
class DateTimePicker extends StatefulWidget { class DateTimePicker extends StatefulWidget {
const DateTimePicker({ /// A widget that displays a date picker from a sheet form the top of the screen.
required this.child, /// This sheet displays initially displays a week but can be dragged down to show a full month.
/// Both views can be dragged sideways to show the next or previous week/month.
///
/// Example:
/// ```dart
/// DatePicker(
/// dateTimePickerTheme: const DateTimePickerTheme()
/// initialDate: selectedDate,
/// highlightToday: true,
/// onTapDay: (date) {
/// setState(() {
/// selectedDate = date;
/// });
/// },
/// markedDates: [
/// DateTime(2022, 3, 14),
/// ],
/// wrongTimeDialog:
/// AlertDialog(
/// title: const Text('Invalid Time'),
/// content: SingleChildScrollView(
/// child: ListBody(
/// children: const <Widget>[
/// Text(
/// 'The time you try to choose is diabled, try to pick another time.'),
/// ],
/// ),
/// ),
/// actions: <Widget>[
/// TextButton(
/// child: const Text('OK'),
/// onPressed: () {
/// Navigator.pop(context);
/// },
/// ),
/// ],
/// ),
/// header: Container(
/// height: 100,
/// width: MediaQuery.of(context).size.width,
/// padding: const EdgeInsets.only(bottom: 10),
/// child: Row(
/// crossAxisAlignment: CrossAxisAlignment.end,
/// mainAxisAlignment: MainAxisAlignment.center,
/// children: [
/// const SizedBox(
/// width: 160,
/// height: 34,
/// child: Center(
/// child: Text(
/// 'Personal calendar',
/// style: TextStyle(
/// fontSize: 16,
/// fontWeight: FontWeight.w900,
/// ),
/// ),
/// ),
/// ),
/// const SizedBox(
/// width: 4,
/// ),
/// Container(
/// width: 160,
/// height: 34,
/// decoration: BoxDecoration(
/// color: const Color(0xFF00273D),
/// borderRadius: const BorderRadius.all(
/// Radius.circular(10),
/// ),
/// boxShadow: [
/// BoxShadow(
/// color: const Color(0xFF000000).withOpacity(0.50),
/// offset: const Offset(0, 6),
/// blurRadius: 9,
/// ),
/// ],
/// ),
/// child: const Center(
/// child: Text(
/// 'Work calendar',
/// style: TextStyle(
/// color: Colors.white,
/// fontSize: 16,
/// fontWeight: FontWeight.w900,
/// ),
/// ),
/// ),
/// ),
/// ],
/// ),
/// ),
/// child: Container(
/// margin: const EdgeInsets.only(
/// top: 195,
/// ),
/// child: HolidayRoster(),
/// ),
/// ),
///```
DateTimePicker({
this.dateTimePickerTheme = const DateTimePickerTheme(),
this.header, this.header,
this.onTapDay, this.onTapDay,
this.highlightToday = true, this.highlightToday = true,
this.wrongTimeDialog,
bool? use24HourFormat,
this.pickTime = false,
this.initialDate, this.initialDate,
this.markedDates, this.markedDates,
Key? key, this.disabledDates,
}) : super(key: key); this.disabledTimes,
this.child,
super.key,
}) {
alwaysUse24HourFormat = use24HourFormat ?? _useTimeFormatBasedOnLocale();
}
final Widget child; /// The child contained by the DatePicker.
final Widget? child;
/// A [Widget] to display when the user picks a disabled time in the [TimePickerDialog]
final Widget? wrongTimeDialog;
/// Visual properties for the [DateTimePicker]
final DateTimePickerTheme dateTimePickerTheme;
/// Widget shown at the top of the [DateTimePicker]
final Widget? header; final Widget? header;
/// Callback that provides the date tapped on as a [DateTime] object.
final Function(DateTime)? onTapDay; final Function(DateTime)? onTapDay;
/// Whether the current day should be highlighted in the [DateTimePicker]
final bool highlightToday; final bool highlightToday;
/// a [bool] to set de clock on [TimePickerDialog] to a fixed 24 or 12-hour format.
/// By default this gets determined by the [Locale] on the device.
late final bool alwaysUse24HourFormat;
/// [pickTime] is a [bool] that determines if the user is able to pick a time after picking a date usring the [TimePickerDialog].
final bool pickTime;
/// indicates the starting date. Default is [DateTime.now()]
final DateTime? initialDate; final DateTime? initialDate;
/// [markedDates] contain the dates [DateTime] that will be marked in the [DateTimePicker] by a small dot.
final List<DateTime>? markedDates; final List<DateTime>? markedDates;
/// a [List] of [DateTime] objects that will be disabled and cannot be interacted with whatsoever.
final List<DateTime>? disabledDates;
/// a [List] of [TimeOfDay] objects that cannot be picked in the [TimePickerDialog].
final List<TimeOfDay>? disabledTimes;
@override @override
State<StatefulWidget> createState() => _DateTimePickerState(); State<StatefulWidget> createState() => _DateTimePickerState();
} }
@ -132,6 +170,9 @@ class DateTimePicker extends StatefulWidget {
class _DateTimePickerState extends State<DateTimePicker> { class _DateTimePickerState extends State<DateTimePicker> {
late DateTimePickerController _dateTimePickerController; late DateTimePickerController _dateTimePickerController;
final DraggableScrollableController _dragController =
DraggableScrollableController();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -139,16 +180,19 @@ class _DateTimePickerState extends State<DateTimePicker> {
_dateTimePickerController = DateTimePickerController( _dateTimePickerController = DateTimePickerController(
highlightToday: widget.highlightToday, highlightToday: widget.highlightToday,
alwaysUse24HourFormat: widget.alwaysUse24HourFormat,
pickTime: widget.pickTime,
theme: widget.dateTimePickerTheme,
header: widget.header, header: widget.header,
markedDates: widget.markedDates, markedDates: widget.markedDates,
disabledDates: widget.disabledDates,
disabledTimes: widget.disabledTimes,
onTapDayCallBack: widget.onTapDay, onTapDayCallBack: widget.onTapDay,
browsingDate: widget.initialDate ?? DateTime.now(), browsingDate: widget.initialDate ?? DateTime.now(),
selectedDate: widget.initialDate ?? DateTime.now(), selectedDate: widget.initialDate ?? DateTime.now(),
); );
_dateTimePickerController.addListener(() { _dateTimePickerController.addListener(() {
print('BROWSING DATE: ${_dateTimePickerController.browsingDate}');
print('SELECTED DATE: ${_dateTimePickerController.selectedDate}');
setState(() {}); setState(() {});
}); });
} }
@ -156,6 +200,7 @@ class _DateTimePickerState extends State<DateTimePicker> {
@override @override
void dispose() { void dispose() {
_dateTimePickerController.dispose(); _dateTimePickerController.dispose();
_dragController.dispose();
super.dispose(); super.dispose();
} }
@ -163,16 +208,20 @@ class _DateTimePickerState extends State<DateTimePicker> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Stack( return Stack(
children: [ children: [
widget.child, if (widget.child != null) ...[
widget.child!,
],
RotatedBox( RotatedBox(
quarterTurns: 2, quarterTurns: 2,
child: DraggableScrollableSheet( child: DraggableScrollableSheet(
controller: _dateTimePickerController.getDragController(), controller: _dragController,
snap: true, snap: true,
minChildSize: 0.26, minChildSize: 0.2,
initialChildSize: 0.26, initialChildSize: 0.2,
maxChildSize: 0.68, maxChildSize: 0.6,
builder: (context, scrollController) { builder: (context, scrollController) {
double dragSize =
_dragController.isAttached ? _dragController.size : 0;
return RotatedBox( return RotatedBox(
quarterTurns: 2, quarterTurns: 2,
child: Stack( child: Stack(
@ -197,17 +246,18 @@ class _DateTimePickerState extends State<DateTimePicker> {
), ),
], ],
), ),
child: _dateTimePickerController child: dragSize < 0.3
.getDragController()
.size <
0.3
? WeekDateTimePickerSheet( ? WeekDateTimePickerSheet(
dateTimePickerController: dateTimePickerController:
_dateTimePickerController, _dateTimePickerController,
weekDateBoxSize: widget
.dateTimePickerTheme.weekDateBoxSize,
) )
: MonthDateTimePickerSheet( : MonthDateTimePickerSheet(
dateTimePickerController: dateTimePickerController:
_dateTimePickerController, _dateTimePickerController,
monthDateBoxSize: widget
.dateTimePickerTheme.monthDateBoxSize,
), ),
), ),
), ),
@ -222,3 +272,24 @@ class _DateTimePickerState extends State<DateTimePicker> {
); );
} }
} }
bool _useTimeFormatBasedOnLocale() {
// Get LocaleName of current platform and split language- and countryCode in 2 List values.
List<String> deviceLocale = Platform.localeName.split('_');
// Make LocaleName of current platform in a Locale Object
Locale defaultLocale = Locale.fromSubtags(
languageCode: deviceLocale[0],
countryCode: deviceLocale[1],
);
// Determine Country.
switch (defaultLocale.countryCode) {
case 'NL':
return true;
case 'US':
return false;
default:
return true;
}
}

View file

@ -0,0 +1,7 @@
/// Defines the shape of a specific date.
enum DateBoxShape {
circle,
rectangle,
roundedRectangle
}

View file

@ -1,16 +1,17 @@
extension DatePickerUtil on DateTime { extension DateTimeExtension on DateTime {
// Check if the current date is the same as the given date /// Check if the current [DateTime] is the same as the given [selectedDate]
bool sameDayAs(DateTime selectedDate) { bool equals(DateTime selectedDate) {
return selectedDate.day == day && return selectedDate.day == day &&
selectedDate.month == month && selectedDate.month == month &&
selectedDate.year == year; selectedDate.year == year;
} }
// Check if the current date is contained in the given list /// Check if the current [DateTime] contains any the given [dates]
bool isContainedIn(List<DateTime> dates) { bool containsAny(List<DateTime> dates) {
return dates.any((element) => element.sameDayAs(this)); return dates.any((element) => element.equals(this));
} }
// Return a [List] of [DateTime] objects of the week the current [DateTime] is in.
List<DateTime> daysOfWeek() { List<DateTime> daysOfWeek() {
var startFrom = subtract(Duration(days: weekday)); var startFrom = subtract(Duration(days: weekday));
return List.generate( return List.generate(
@ -22,9 +23,11 @@ extension DatePickerUtil on DateTime {
); );
} }
/// Determine if a certain [year] of a [DateTime] object is a leap year.
bool get isLeapYear => bool get isLeapYear =>
(year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0); (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0);
/// Returns the amount of days in the current month of the [DateTime] object
int daysInMonth() { int daysInMonth() {
late int amountOfDays; late int amountOfDays;

View file

@ -0,0 +1,13 @@
import 'package:flutter/material.dart';
extension TimeOfDayExtension on TimeOfDay {
/// Check if the current [TimeOfDay] contains any the given [times]
bool containsAny(List<TimeOfDay> times) {
return times.any((element) => element.equals(this));
}
/// Check if the current [TimeOfDay] is the same as the given [selectedTime]
bool equals(TimeOfDay selectedTime) {
return selectedTime.hour == hour && selectedTime.minute == minute;
}
}

View file

@ -0,0 +1,15 @@
import 'package:flutter/widgets.dart' show Color, TextStyle;
class DateBoxBaseTheme {
/// Default date theme.
const DateBoxBaseTheme(
this.backgroundColor,
this.textStyle,
);
/// Background color of default date
final Color? backgroundColor;
/// The style of the date number.
final TextStyle? textStyle;
}

View file

@ -0,0 +1,15 @@
import 'package:flutter/widgets.dart' show Color, TextStyle;
class DateBoxCurrentTheme {
/// Default date theme.
const DateBoxCurrentTheme(
this.backgroundColor,
this.textStyle,
);
/// Background color of default date
final Color backgroundColor;
/// The style of the date number.
final TextStyle textStyle;
}

View file

@ -0,0 +1,15 @@
import 'package:flutter/widgets.dart' show Color, TextStyle;
class DateBoxDisabledTheme {
/// Disabled date theme.
const DateBoxDisabledTheme(
this.backgroundColor,
this.textStyle,
);
/// Background color of selected date.
final Color? backgroundColor;
/// The style of the date number.
final TextStyle? textStyle;
}

View file

@ -0,0 +1,15 @@
import 'package:flutter/widgets.dart' show Color, TextStyle;
class DateBoxHighlightTheme {
/// Highlighted date theme.
const DateBoxHighlightTheme(
this.backgroundColor,
this.textStyle,
);
/// Background color of highlighted date.
final Color? backgroundColor;
/// The style of the date number.
final TextStyle? textStyle;
}

View file

@ -0,0 +1,15 @@
import 'package:flutter/widgets.dart' show Color, TextStyle;
class DateBoxSelectedTheme {
/// Selected date theme.
const DateBoxSelectedTheme(
this.backgroundColor,
this.textStyle,
);
/// Background color of selected date.
final Color? backgroundColor;
/// The style of the date number.
final TextStyle? textStyle;
}

View file

@ -0,0 +1,54 @@
import 'package:flutter/material.dart';
import 'package:flutter_date_time_picker/flutter_date_time_picker.dart';
class DateTimePickerTheme {
/// The [DateTimePickerTheme] to style [DateTimePicker] in. Define a custom shape for the dates and specifically style
/// a basic, hightlighted, selected and disabled date.
const DateTimePickerTheme({
this.weekDateBoxSize = 35,
this.monthDateBoxSize = 45,
this.markedIndicatorColor,
this.dateBoxShape = DateBoxShape.roundedRectangle,
this.baseTheme = const DateBoxBaseTheme(
Colors.white,
TextStyle(color: Colors.black),
),
this.highlightTheme = const DateBoxHighlightTheme(
Colors.blue,
TextStyle(color: Colors.white),
),
this.selectedTheme = const DateBoxSelectedTheme(
Color(0xFFBBDEFB),
TextStyle(color: Colors.blue),
),
this.disabledTheme = const DateBoxDisabledTheme(
Colors.grey,
TextStyle(color: Colors.white),
),
});
/// enum to define a shape dor the date. use [DateBoxShape.circle].
/// For a ciruclar date, [DateBoxShape.rectangle] for a plain box and [DateBoxShape.roundedRectangle] to het a rectangle with small rounded borders.
final DateBoxShape dateBoxShape;
/// This theme is used to style a default look for the dates.
final DateBoxBaseTheme baseTheme;
/// This theme is used for when a specific date is highlighted.
final DateBoxHighlightTheme highlightTheme;
/// This theme is used for when a specific date is slected by the user.
final DateBoxSelectedTheme selectedTheme;
/// This theme is used for when a specific date is disabled.
final DateBoxDisabledTheme disabledTheme;
/// Size of date box in a week view.
final double weekDateBoxSize;
/// Size of date box in a month view.
final double monthDateBoxSize;
/// The color used for a indicator for a marked date.
final Color? markedIndicatorColor;
}

View file

@ -1,24 +1,37 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_date_time_picker/src/models/date_time_picker_theme.dart';
class DateTimePickerController extends ChangeNotifier { class DateTimePickerController extends ChangeNotifier {
DateTimePickerController({ DateTimePickerController({
required this.theme,
required this.highlightToday, required this.highlightToday,
this.header, required this.alwaysUse24HourFormat,
this.markedDates, required this.pickTime,
this.onTapDayCallBack,
required this.browsingDate, required this.browsingDate,
required this.selectedDate, required this.selectedDate,
this.header,
this.wrongTimeDialog,
this.markedDates,
this.disabledDates,
this.disabledTimes,
this.onTapDayCallBack,
}); });
final DraggableScrollableController _dragController =
DraggableScrollableController();
final PageController _pageController = PageController(initialPage: 1); final PageController _pageController = PageController(initialPage: 1);
final bool highlightToday; final bool highlightToday;
final bool? alwaysUse24HourFormat;
final Widget? header; final Widget? header;
final Widget? wrongTimeDialog;
final DateTimePickerTheme theme;
final List<DateTime>? markedDates; final List<DateTime>? markedDates;
final List<DateTime>? disabledDates;
final List<TimeOfDay>? disabledTimes;
final bool pickTime;
final Function(DateTime)? onTapDayCallBack; final Function(DateTime)? onTapDayCallBack;
@ -28,7 +41,6 @@ class DateTimePickerController extends ChangeNotifier {
@override @override
void dispose() { void dispose() {
_pageController.dispose(); _pageController.dispose();
_dragController.dispose();
super.dispose(); super.dispose();
} }
@ -45,7 +57,7 @@ class DateTimePickerController extends ChangeNotifier {
); );
} }
void onTapDay(date) { void onTapDay(DateTime date) {
browsingDate = date; browsingDate = date;
selectedDate = date; selectedDate = date;
@ -58,13 +70,7 @@ class DateTimePickerController extends ChangeNotifier {
} }
} }
DraggableScrollableController getDragController() { PageController get pageController => _pageController;
return _dragController;
}
PageController getPageController() {
return _pageController;
}
void setBrowsingDate(DateTime date) { void setBrowsingDate(DateTime date) {
browsingDate = date; browsingDate = date;

View file

@ -1,16 +1,22 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_date_time_picker/src/enums/date_box_shape.dart';
import 'package:flutter_date_time_picker/src/extensions/date_time.dart'; import 'package:flutter_date_time_picker/src/extensions/date_time.dart';
import 'package:flutter_date_time_picker/src/extensions/time_of_day.dart';
import 'package:flutter_date_time_picker/src/models/date_box_current_theme.dart';
import 'package:flutter_date_time_picker/src/models/date_time_picker_theme.dart';
import 'package:flutter_date_time_picker/src/utils/date_time_picker_controller.dart'; import 'package:flutter_date_time_picker/src/utils/date_time_picker_controller.dart';
class MonthDateTimePicker extends StatelessWidget { class MonthDateTimePicker extends StatelessWidget {
const MonthDateTimePicker({ const MonthDateTimePicker({
required this.date, required this.date,
required this.dateTimePickerController, required this.dateTimePickerController,
required this.monthDateBoxSize,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
final DateTime date; final DateTime date;
final DateTimePickerController dateTimePickerController; final DateTimePickerController dateTimePickerController;
final double monthDateBoxSize;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -26,101 +32,104 @@ class MonthDateTimePicker extends StatelessWidget {
margin: const EdgeInsets.symmetric(horizontal: 30), margin: const EdgeInsets.symmetric(horizontal: 30),
child: Center( child: Center(
child: GridView.count( child: GridView.count(
physics: const NeverScrollableScrollPhysics(),
crossAxisSpacing: 5, crossAxisSpacing: 5,
crossAxisCount: 7, crossAxisCount: 7,
children: List.generate( children: List.generate(
DateTime(date.year, date.month).daysInMonth() + daysToSkip, DateTime(date.year, date.month).daysInMonth() +
(daysToSkip >= 7 ? 0 : daysToSkip),
(index) { (index) {
if (index < daysToSkip) { late DateBoxCurrentTheme currentDateBoxTheme;
return Container(
decoration: BoxDecoration( int addedIndex = index;
color: Colors.red.withOpacity(0.4),
border: Border.all(color: Colors.black, width: 1.5), if (daysToSkip >= 7) {
), addedIndex = index + 7;
margin: }
const EdgeInsets.symmetric(vertical: 5, horizontal: 5), if (addedIndex < daysToSkip) {
height: 45, return const SizedBox.shrink();
width: 45,
child: Center(
child: Text(
(index + 1 - daysToSkip).toString(),
style: Theme.of(context).textTheme.bodyText1!.copyWith(
color: Colors.black,
),
),
),
);
} }
currentDateBoxTheme = determineCurrentDateBoxTheme(context,
addedIndex, daysToSkip, dateTimePickerController.theme);
return GestureDetector( return GestureDetector(
onTap: isDisabled(
addedIndex,
daysToSkip,
)
? null
: () async {
TimeOfDay? timeOfDay;
onTap: () async { DateTime selectedDate = DateTime(
// await dateTimePickerController.getDragController().animateTo( date.year,
// 0.26, date.month,
// duration: const Duration( addedIndex + 1 - daysToSkip,
// milliseconds: 350, );
// ),
// curve: Curves.ease,
// );
dateTimePickerController.onTapDay(DateTime( timeOfDay = const TimeOfDay(hour: 0, minute: 0);
date.year,
date.month, if (dateTimePickerController.pickTime) {
index + 1 - daysToSkip, timeOfDay = await displayTimePicker(
date.hour, context, dateTimePickerController);
date.minute, }
date.second,
)); if (dateTimePickerController.wrongTimeDialog != null) {
}, if (timeOfDay != null &&
timeOfDay.containsAny(
dateTimePickerController.disabledTimes ?? [],
)) {
showDialog(
context: context,
builder: (context) =>
dateTimePickerController.wrongTimeDialog!);
}
}
DateTime selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
timeOfDay!.hour,
timeOfDay.minute,
);
dateTimePickerController.onTapDay(selectedDateTime);
},
child: Container( child: Container(
margin: margin:
const EdgeInsets.symmetric(vertical: 5, horizontal: 5), const EdgeInsets.symmetric(vertical: 5, horizontal: 5),
decoration: BoxDecoration( decoration: BoxDecoration(
color: color: currentDateBoxTheme.backgroundColor,
// isDisabled() borderRadius:
// ? Theme.of(context).disabledColor _determineBorderRadius(dateTimePickerController),
// : Colors.transparent,
// isSelected(index, daysToSkip)
// ? Theme.of(context).primaryColor.withOpacity(0.2)
// : Colors.transparent,
shouldHighlight(index, daysToSkip)
? Theme.of(context).primaryColor
: Colors.transparent,
borderRadius: BorderRadius.circular(
10,
),
), ),
height: 45, height: monthDateBoxSize,
width: 45, width: monthDateBoxSize,
child: Stack( child: Stack(
children: [ children: [
Center( Center(
child: Text( child: Text((addedIndex + 1 - daysToSkip).toString(),
(index + 1 - daysToSkip).toString(), style: currentDateBoxTheme.textStyle),
style:
Theme.of(context).textTheme.bodyText1!.copyWith(
color:
// isDisabled()
// ? Colors.white
// : Colors.transparent,
// isSelected(index, daysToSkip)
// ? Theme.of(context).primaryColor
// : Colors.black,
shouldHighlight(index, daysToSkip)
? Colors.white
: Colors.black,
),
),
), ),
if (shouldMark(index, daysToSkip)) ...[ if (shouldMark(
addedIndex,
daysToSkip,
)) ...[
Align( Align(
alignment: Alignment.bottomRight, alignment: Alignment.bottomRight,
child: Container( child: IgnorePointer(
width: 12, child: Container(
height: 12, width: monthDateBoxSize / 4,
decoration: BoxDecoration( height: monthDateBoxSize / 4,
color: Theme.of(context).indicatorColor, decoration: BoxDecoration(
borderRadius: BorderRadius.circular(45), color: dateTimePickerController
.theme.markedIndicatorColor ??
Theme.of(context).indicatorColor,
borderRadius: BorderRadius.circular(
(monthDateBoxSize / 4) * 2),
),
), ),
), ),
), ),
@ -141,15 +150,56 @@ class MonthDateTimePicker extends StatelessWidget {
date.year, date.year,
date.month, date.month,
index + 1 - daysToSkip, index + 1 - daysToSkip,
).sameDayAs( ).equals(
dateTimePickerController.highlightToday dateTimePickerController.highlightToday
? DateTime.now() ? DateTime.now()
: dateTimePickerController.selectedDate, : dateTimePickerController.selectedDate,
); );
} }
bool isDisabled() { DateBoxCurrentTheme determineCurrentDateBoxTheme(
return true; BuildContext context,
int index,
int daysToSkip,
DateTimePickerTheme theme,
) {
DateBoxCurrentTheme determinedTheme = DateBoxCurrentTheme(
theme.baseTheme.backgroundColor ?? Colors.transparent,
theme.baseTheme.textStyle ?? const TextStyle(color: Colors.black),
);
if (isDisabled(index, daysToSkip)) {
determinedTheme = DateBoxCurrentTheme(
theme.disabledTheme.backgroundColor ?? Theme.of(context).disabledColor,
theme.disabledTheme.textStyle ?? const TextStyle(color: Colors.white),
);
}
if (isSelected(index, daysToSkip)) {
determinedTheme = DateBoxCurrentTheme(
theme.selectedTheme.backgroundColor ??
Theme.of(context).primaryColor.withOpacity(0.3),
theme.selectedTheme.textStyle ??
TextStyle(color: Theme.of(context).primaryColor));
}
if (shouldHighlight(index, daysToSkip)) {
determinedTheme = DateBoxCurrentTheme(
theme.highlightTheme.backgroundColor ??
Theme.of(context).primaryColor,
theme.highlightTheme.textStyle ??
const TextStyle(color: Colors.white));
}
return determinedTheme;
}
bool isDisabled(int index, int daysToSkip) {
return DateTime(
date.year,
date.month,
index + 1 - daysToSkip,
).containsAny(
dateTimePickerController.disabledDates ?? [],
);
} }
bool isSelected(int index, int daysToSkip) { bool isSelected(int index, int daysToSkip) {
@ -157,7 +207,7 @@ class MonthDateTimePicker extends StatelessWidget {
date.year, date.year,
date.month, date.month,
index + 1 - daysToSkip, index + 1 - daysToSkip,
).sameDayAs(dateTimePickerController.selectedDate); ).equals(dateTimePickerController.selectedDate);
} }
bool shouldMark(int index, int daysToSkip) { bool shouldMark(int index, int daysToSkip) {
@ -165,7 +215,7 @@ class MonthDateTimePicker extends StatelessWidget {
date.year, date.year,
date.month, date.month,
index + 1 - daysToSkip, index + 1 - daysToSkip,
).sameDayAs( ).equals(
dateTimePickerController.highlightToday dateTimePickerController.highlightToday
? DateTime.now() ? DateTime.now()
: dateTimePickerController.selectedDate, : dateTimePickerController.selectedDate,
@ -174,8 +224,35 @@ class MonthDateTimePicker extends StatelessWidget {
date.year, date.year,
date.month, date.month,
index + 1 - daysToSkip, index + 1 - daysToSkip,
).isContainedIn( ).containsAny(
dateTimePickerController.markedDates ?? [], dateTimePickerController.markedDates ?? [],
); );
} }
BorderRadius _determineBorderRadius(
DateTimePickerController dateTimePickerController) {
switch (dateTimePickerController.theme.dateBoxShape) {
case DateBoxShape.circle:
return BorderRadius.circular(monthDateBoxSize * 2);
case DateBoxShape.rectangle:
return BorderRadius.zero;
case DateBoxShape.roundedRectangle:
return BorderRadius.circular(monthDateBoxSize / 4.5);
}
}
}
displayTimePicker(BuildContext context,
DateTimePickerController dateTimePickerController) async {
return await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
builder: (BuildContext context, Widget? child) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
alwaysUse24HourFormat:
dateTimePickerController.alwaysUse24HourFormat),
child: child!,
);
});
} }

View file

@ -7,10 +7,12 @@ import 'package:intl/intl.dart';
class MonthDateTimePickerSheet extends StatelessWidget { class MonthDateTimePickerSheet extends StatelessWidget {
const MonthDateTimePickerSheet({ const MonthDateTimePickerSheet({
required this.dateTimePickerController, required this.dateTimePickerController,
required this.monthDateBoxSize,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
final DateTimePickerController dateTimePickerController; final DateTimePickerController dateTimePickerController;
final double monthDateBoxSize;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -28,16 +30,14 @@ class MonthDateTimePickerSheet extends StatelessWidget {
DateFormat.yMMMM().format( DateFormat.yMMMM().format(
dateTimePickerController.browsingDate, dateTimePickerController.browsingDate,
), ),
style: Theme.of(context) style: dateTimePickerController.theme.baseTheme.textStyle!
.textTheme .copyWith(fontSize: 25),
.headlineMedium!
.copyWith(color: Colors.black),
), ),
SizedBox( SizedBox(
width: MediaQuery.of(context).size.width, width: MediaQuery.of(context).size.width,
height: 300, height: MediaQuery.of(context).size.height * 0.33,
child: PageView( child: PageView(
controller: dateTimePickerController.getPageController(), controller: dateTimePickerController.pageController,
onPageChanged: (i) { onPageChanged: (i) {
if (i == 0) { if (i == 0) {
dateTimePickerController.onPageChanged( dateTimePickerController.onPageChanged(
@ -68,21 +68,27 @@ class MonthDateTimePickerSheet extends StatelessWidget {
dateTimePickerController.browsingDate.year - 1, 12, 1) dateTimePickerController.browsingDate.year - 1, 12, 1)
: DateTime(dateTimePickerController.browsingDate.year, : DateTime(dateTimePickerController.browsingDate.year,
dateTimePickerController.browsingDate.month - 1, 1), dateTimePickerController.browsingDate.month - 1, 1),
monthDateBoxSize: monthDateBoxSize,
dateTimePickerController: dateTimePickerController), dateTimePickerController: dateTimePickerController),
MonthDateTimePicker( MonthDateTimePicker(
date: dateTimePickerController.browsingDate, date: DateTime(
dateTimePickerController: dateTimePickerController), dateTimePickerController.browsingDate.year,
dateTimePickerController.browsingDate.month,
1,
),
dateTimePickerController: dateTimePickerController,
monthDateBoxSize: monthDateBoxSize),
MonthDateTimePicker( MonthDateTimePicker(
date: dateTimePickerController.browsingDate.month == 12 date: dateTimePickerController.browsingDate.month == 12
? DateTime( ? DateTime(
dateTimePickerController.browsingDate.year + 1, dateTimePickerController.browsingDate.year + 1,
1, 1,
1, 1,
) )
: DateTime(dateTimePickerController.browsingDate.year, : DateTime(dateTimePickerController.browsingDate.year,
dateTimePickerController.browsingDate.month + 1, 1), dateTimePickerController.browsingDate.month + 1, 1),
dateTimePickerController: dateTimePickerController, dateTimePickerController: dateTimePickerController,
), monthDateBoxSize: monthDateBoxSize),
], ],
), ),
), ),

View file

@ -1,5 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_date_time_picker/flutter_date_time_picker.dart';
import 'package:flutter_date_time_picker/src/extensions/date_time.dart'; import 'package:flutter_date_time_picker/src/extensions/date_time.dart';
import 'package:flutter_date_time_picker/src/extensions/time_of_day.dart';
import 'package:flutter_date_time_picker/src/models/date_box_current_theme.dart';
import 'package:flutter_date_time_picker/src/utils/date_time_picker_controller.dart'; import 'package:flutter_date_time_picker/src/utils/date_time_picker_controller.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
@ -7,6 +10,7 @@ class WeekDateTimePicker extends StatelessWidget {
const WeekDateTimePicker({ const WeekDateTimePicker({
required this.dateTimePickerController, required this.dateTimePickerController,
required this.date, required this.date,
required this.weekDateBoxSize,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -14,82 +18,155 @@ class WeekDateTimePicker extends StatelessWidget {
final DateTime date; final DateTime date;
final double weekDateBoxSize;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: List.generate( children: List.generate(
date.daysOfWeek().length, date.daysOfWeek().length,
(index) => GestureDetector( (index) {
onTap: () { late DateBoxCurrentTheme currentDateBoxTheme;
dateTimePickerController.onTapDay(date.daysOfWeek()[index]);
}, currentDateBoxTheme = determineCurrentDateBoxTheme(
child: SizedBox( context, index, dateTimePickerController.theme);
width: 40, return GestureDetector(
height: 60, onTap: isDisabled(
child: Column( index,
children: [ )
const Spacer(), ? null
Text( : () async {
DateFormat.E() TimeOfDay? timeOfDay;
.format(
date.daysOfWeek().elementAt(index), DateTime selectedDate = date.daysOfWeek()[index];
)
.toUpperCase()[0], timeOfDay = const TimeOfDay(hour: 0, minute: 0);
style: Theme.of(context).textTheme.titleSmall,
), if (dateTimePickerController.pickTime) {
const Spacer(), timeOfDay = await displayTimePicker(
Container( context, dateTimePickerController);
height: 35, }
width: 35,
decoration: BoxDecoration( if (dateTimePickerController.wrongTimeDialog != null) {
color: shouldHighlight(index) if (timeOfDay != null &&
? Theme.of(context).primaryColor timeOfDay.containsAny(
: Colors.transparent, dateTimePickerController.disabledTimes ?? [],
borderRadius: BorderRadius.circular( )) {
10, showDialog(
), context: context,
builder: (context) =>
dateTimePickerController.wrongTimeDialog!,
);
}
}
DateTime selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
timeOfDay!.hour,
timeOfDay.minute,
);
dateTimePickerController.onTapDay(selectedDateTime);
},
child: SizedBox(
width: 40,
height: 60,
child: Column(
children: [
const Spacer(),
Text(
DateFormat.E()
.format(
date.daysOfWeek().elementAt(index),
)
.toUpperCase()[0],
style: dateTimePickerController.theme.baseTheme.textStyle,
), ),
child: Stack( const Spacer(),
children: [ Container(
Center( height: weekDateBoxSize,
child: Text( width: weekDateBoxSize,
date.daysOfWeek().elementAt(index).day.toString(), decoration: BoxDecoration(
style: color: currentDateBoxTheme.backgroundColor,
Theme.of(context).textTheme.bodyMedium!.copyWith( borderRadius:
color: shouldHighlight(index) _determineBorderRadius(dateTimePickerController),
? Colors.white ),
: Colors.black, child: Stack(
), children: [
), Center(
), child: Text(
if (shouldMark(index)) ...[ date.daysOfWeek().elementAt(index).day.toString(),
Align( style: currentDateBoxTheme.textStyle,
alignment: Alignment.bottomRight,
child: Container(
width: 10,
height: 10,
decoration: BoxDecoration(
color: Theme.of(context).indicatorColor,
borderRadius: BorderRadius.circular(45),
),
), ),
), ),
if (shouldMark(index)) ...[
Align(
alignment: Alignment.bottomRight,
child: Container(
width: weekDateBoxSize / 3,
height: weekDateBoxSize / 3,
decoration: BoxDecoration(
color: dateTimePickerController
.theme.markedIndicatorColor ??
Theme.of(context).indicatorColor,
borderRadius:
BorderRadius.circular(weekDateBoxSize * 2),
),
),
),
],
], ],
], ),
), ),
), const Spacer(),
const Spacer(), ],
], ),
), ),
), );
), },
), ),
); );
} }
DateBoxCurrentTheme determineCurrentDateBoxTheme(
BuildContext context,
int index,
DateTimePickerTheme theme,
) {
DateBoxCurrentTheme determinedTheme = DateBoxCurrentTheme(
theme.baseTheme.backgroundColor ?? Colors.transparent,
theme.baseTheme.textStyle ?? const TextStyle(color: Colors.black),
);
if (isDisabled(index)) {
determinedTheme = DateBoxCurrentTheme(
theme.disabledTheme.backgroundColor ?? Theme.of(context).disabledColor,
theme.disabledTheme.textStyle ?? const TextStyle(color: Colors.white),
);
}
if (isSelected(index)) {
determinedTheme = DateBoxCurrentTheme(
theme.selectedTheme.backgroundColor ??
Theme.of(context).primaryColor.withOpacity(0.3),
theme.selectedTheme.textStyle ??
TextStyle(color: Theme.of(context).primaryColor));
}
if (shouldHighlight(index)) {
determinedTheme = DateBoxCurrentTheme(
theme.highlightTheme.backgroundColor ??
Theme.of(context).primaryColor,
theme.highlightTheme.textStyle ??
const TextStyle(color: Colors.white));
}
return determinedTheme;
}
bool shouldHighlight(int index) { bool shouldHighlight(int index) {
return date.daysOfWeek().elementAt(index).sameDayAs( return date.daysOfWeek().elementAt(index).equals(
dateTimePickerController.highlightToday dateTimePickerController.highlightToday
? DateTime.now() ? DateTime.now()
: dateTimePickerController.selectedDate, : dateTimePickerController.selectedDate,
@ -100,11 +177,18 @@ class WeekDateTimePicker extends StatelessWidget {
return date return date
.daysOfWeek() .daysOfWeek()
.elementAt(index) .elementAt(index)
.sameDayAs(dateTimePickerController.selectedDate); .equals(dateTimePickerController.selectedDate);
}
bool isDisabled(int index) {
return date
.daysOfWeek()
.elementAt(index)
.containsAny(dateTimePickerController.disabledDates ?? []);
} }
bool shouldMark(int index) { bool shouldMark(int index) {
return !date.daysOfWeek().elementAt(index).sameDayAs( return !date.daysOfWeek().elementAt(index).equals(
dateTimePickerController.highlightToday dateTimePickerController.highlightToday
? DateTime.now() ? DateTime.now()
: dateTimePickerController.selectedDate, : dateTimePickerController.selectedDate,
@ -112,6 +196,33 @@ class WeekDateTimePicker extends StatelessWidget {
date date
.daysOfWeek() .daysOfWeek()
.elementAt(index) .elementAt(index)
.isContainedIn(dateTimePickerController.markedDates ?? []); .containsAny(dateTimePickerController.markedDates ?? []);
}
BorderRadius _determineBorderRadius(
DateTimePickerController dateTimePickerController) {
switch (dateTimePickerController.theme.dateBoxShape) {
case DateBoxShape.circle:
return BorderRadius.circular(weekDateBoxSize * 2);
case DateBoxShape.rectangle:
return BorderRadius.zero;
case DateBoxShape.roundedRectangle:
return BorderRadius.circular(weekDateBoxSize / 4.5);
}
}
displayTimePicker(BuildContext context,
DateTimePickerController dateTimePickerController) async {
return await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
builder: (BuildContext context, Widget? child) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
alwaysUse24HourFormat:
dateTimePickerController.alwaysUse24HourFormat),
child: child!,
);
});
} }
} }

View file

@ -7,12 +7,14 @@ import 'package:intl/intl.dart';
class WeekDateTimePickerSheet extends StatelessWidget { class WeekDateTimePickerSheet extends StatelessWidget {
const WeekDateTimePickerSheet({ const WeekDateTimePickerSheet({
required this.dateTimePickerController, required this.dateTimePickerController,
required this.weekDateBoxSize,
this.showHeader = false, this.showHeader = false,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
final DateTimePickerController dateTimePickerController; final DateTimePickerController dateTimePickerController;
final bool showHeader; final bool showHeader;
final double weekDateBoxSize;
String getDateHeader() { String getDateHeader() {
List<DateTime> weekDays = List<DateTime> weekDays =
@ -43,7 +45,8 @@ class WeekDateTimePickerSheet extends StatelessWidget {
if (showHeader) ...[ if (showHeader) ...[
Text( Text(
getDateHeader(), getDateHeader(),
style: Theme.of(context).textTheme.headlineSmall, style: dateTimePickerController.theme.baseTheme.textStyle!
.copyWith(fontSize: 9),
), ),
const SizedBox( const SizedBox(
height: 10, height: 10,
@ -53,7 +56,7 @@ class WeekDateTimePickerSheet extends StatelessWidget {
width: MediaQuery.of(context).size.width, width: MediaQuery.of(context).size.width,
height: 60, height: 60,
child: PageView( child: PageView(
controller: dateTimePickerController.getPageController(), controller: dateTimePickerController.pageController,
onPageChanged: (i) { onPageChanged: (i) {
if (i == 0) { if (i == 0) {
dateTimePickerController.onPageChanged( dateTimePickerController.onPageChanged(
@ -75,16 +78,19 @@ class WeekDateTimePickerSheet extends StatelessWidget {
date: dateTimePickerController.browsingDate.subtract( date: dateTimePickerController.browsingDate.subtract(
const Duration(days: 7), const Duration(days: 7),
), ),
weekDateBoxSize: weekDateBoxSize,
), ),
WeekDateTimePicker( WeekDateTimePicker(
dateTimePickerController: dateTimePickerController, dateTimePickerController: dateTimePickerController,
date: dateTimePickerController.browsingDate, date: dateTimePickerController.browsingDate,
weekDateBoxSize: weekDateBoxSize,
), ),
WeekDateTimePicker( WeekDateTimePicker(
dateTimePickerController: dateTimePickerController, dateTimePickerController: dateTimePickerController,
date: dateTimePickerController.browsingDate.add( date: dateTimePickerController.browsingDate.add(
const Duration(days: 7), const Duration(days: 7),
), ),
weekDateBoxSize: weekDateBoxSize,
), ),
], ],
), ),

View file

@ -0,0 +1,75 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_date_time_picker/src/extensions/date_time.dart';
void main() {
group('DateTimeExtension', () {
test('equals() should return true if the same date, if not false', () {
expect(DateTime(2022, 01, 01).equals(DateTime(2022, 01, 01)), true);
expect(DateTime(2022, 01, 01).equals(DateTime(2022, 01, 02)), false);
});
test(
'containsAny() should return a boolean if the date is found in a list of dates or not',
() {
expect(
DateTime(2022, 01, 01).containsAny([
DateTime(2022, 01, 01),
DateTime(2022, 01, 02),
DateTime(2022, 01, 03)
]),
true);
expect(
DateTime(2022, 01, 01).containsAny([
DateTime(2022, 01, 02),
DateTime(2022, 01, 03),
DateTime(2022, 01, 04)
]),
false);
});
test(
'isLeapYear should return a boolean if the given year is a leap year or not',
() {
expect(DateTime(2016, 01, 01).isLeapYear, true); // A leap year
expect(DateTime(2017, 01, 01).isLeapYear, false); // Not a leap year
expect(DateTime(2018, 01, 01).isLeapYear, false); // Not a leap year
expect(DateTime(2019, 01, 01).isLeapYear, false); // Not a leap year
expect(DateTime(2020, 01, 01).isLeapYear, true); // A leap year
});
test(
'daysInMonth() should return the amount of days in the month relative on the date',
() {
var monthOfJanuary = DateTime(2022, 01, 01);
var monthOfFebruary = DateTime(2022, 02, 01);
var monthOfMarch = DateTime(2022, 03, 01);
var monthOfApril = DateTime(2022, 04, 01);
var monthOfMay = DateTime(2022, 05, 01);
var monthOfJune = DateTime(2022, 06, 01);
var monthOfJuly = DateTime(2022, 07, 01);
var monthOfAugust = DateTime(2022, 08, 01);
var monthOfSeptember = DateTime(2022, 09, 01);
var monthOfOctober = DateTime(2022, 10, 01);
var monthOfNovember = DateTime(2022, 11, 01);
var monthOfDecember = DateTime(2022, 12, 01);
expect(monthOfJanuary.daysInMonth(), 31);
// 2022 is not a leap year so this should return 28
expect(monthOfFebruary.daysInMonth(), 28);
expect(monthOfMarch.daysInMonth(), 31);
expect(monthOfApril.daysInMonth(), 30);
expect(monthOfMay.daysInMonth(), 31);
expect(monthOfJune.daysInMonth(), 30);
expect(monthOfJuly.daysInMonth(), 31);
expect(monthOfAugust.daysInMonth(), 31);
expect(monthOfSeptember.daysInMonth(), 30);
expect(monthOfOctober.daysInMonth(), 31);
expect(monthOfNovember.daysInMonth(), 30);
expect(monthOfDecember.daysInMonth(), 31);
// 2020 is a leap year so this should return 29
expect(DateTime(2020, 02, 01).daysInMonth(), 29);
});
});
}

View file

@ -1,12 +1,48 @@
import 'package:flutter/material.dart';
import 'package:flutter_date_time_picker/flutter_date_time_picker.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_date_time_picker/flutter_date_time_picker.dart';
void main() { void main() {
test('adds one to input values', () { testWidgets('Render App with DateTimePicker Widget', (tester) async {
final calculator = Calculator(); // Render App
expect(calculator.addOne(2), 3); await tester.pumpWidget(MaterialApp(
expect(calculator.addOne(-7), -6); home: Scaffold(
expect(calculator.addOne(0), 1); appBar: AppBar(),
body: DateTimePicker(
pickTime: false,
child: Container(),
),
),
));
await tester.pump();
});
testWidgets('Test if DateTimePicker Widget swipes', (tester) async {
// Render App
await tester.pumpWidget(MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: DateTimePicker(
pickTime: false,
child: Container(),
),
),
));
await tester.pump();
// Forward
await tester.drag(
find.byType(SingleChildScrollView), const Offset(500.0, 0.0));
await tester.pumpAndSettle();
// Return
await tester.drag(
find.byType(SingleChildScrollView), const Offset(-500.0, 0.0));
await tester.pumpAndSettle();
// Backward
await tester.drag(
find.byType(SingleChildScrollView), const Offset(-500.0, 0.0));
await tester.pumpAndSettle();
}); });
} }

View file

@ -0,0 +1,38 @@
import 'package:flutter/material.dart';
import 'package:flutter_date_time_picker/src/extensions/time_of_day.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('TimeOfDayExtension', () {
test('equals() should return true if the same time, if not false', () {
expect(
const TimeOfDay(hour: 12, minute: 0)
.equals(const TimeOfDay(hour: 12, minute: 0)),
true);
expect(
const TimeOfDay(hour: 13, minute: 0)
.equals(const TimeOfDay(hour: 12, minute: 0)),
false);
});
test(
'containsAny() should return a boolean if the time is found in a list of times or not',
() {
expect(
const TimeOfDay(hour: 12, minute: 0).containsAny(const [
TimeOfDay(hour: 10, minute: 0),
TimeOfDay(hour: 11, minute: 0),
TimeOfDay(hour: 12, minute: 0)
]),
true);
expect(
const TimeOfDay(hour: 12, minute: 0).containsAny(const [
TimeOfDay(hour: 9, minute: 0),
TimeOfDay(hour: 10, minute: 0),
TimeOfDay(hour: 11, minute: 0)
]),
false);
});
});
}