|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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}"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.example.example
|
package com.iconica.example
|
||||||
|
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -45,5 +45,7 @@
|
||||||
<false/>
|
<false/>
|
||||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||||
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -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)],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 101 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 520 B |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 2.2 KiB |
|
@ -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.
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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);
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -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")
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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}"/>
|
||||||
|
|
|
@ -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';
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
7
lib/src/enums/date_box_shape.dart
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
/// Defines the shape of a specific date.
|
||||||
|
enum DateBoxShape {
|
||||||
|
circle,
|
||||||
|
rectangle,
|
||||||
|
roundedRectangle
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
||||||
|
|
13
lib/src/extensions/time_of_day.dart
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
15
lib/src/models/date_box_base_theme.dart
Normal 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;
|
||||||
|
}
|
15
lib/src/models/date_box_current_theme.dart
Normal 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;
|
||||||
|
}
|
15
lib/src/models/date_box_disabled_theme.dart
Normal 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;
|
||||||
|
}
|
15
lib/src/models/date_box_highlight_theme.dart
Normal 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;
|
||||||
|
}
|
15
lib/src/models/date_box_selected_theme.dart
Normal 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;
|
||||||
|
}
|
54
lib/src/models/date_time_picker_theme.dart
Normal 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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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!,
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -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!,
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
75
test/date_time_extension_test.dart
Normal 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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -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();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
38
test/time_of_day_extension_test.dart
Normal 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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|