├── lib ├── utils │ ├── IpsModeCamera.dart │ ├── IpsMediaType.dart │ ├── IpsCameraButton.dart │ ├── colors.dart │ └── HandlePermission.dart ├── inputs │ ├── IpsInput.dart │ ├── IpsInputDate │ │ ├── controller.dart │ │ ├── controller.g.dart │ │ └── index.dart │ ├── IpsInputLongtext.dart │ ├── IpsInputTime.dart │ ├── IpsInputOptions.dart │ ├── IpsInputDatetime.dart │ ├── IpsInputText.dart │ ├── IpsInputMask.dart │ ├── IpsInputNumber.dart │ └── IpsInputMultioptions.dart ├── components │ ├── IpsIcon.dart │ ├── IpsLabel.dart │ ├── IpsValue.dart │ ├── IpsError.dart │ ├── IpsCard.dart │ ├── IpsPhoto.dart │ └── IpsVideo.dart ├── sheet.dart └── input_sheet.dart ├── example ├── ios │ ├── Runner │ │ ├── Runner-Bridging-Header.h │ │ ├── Assets.xcassets │ │ │ ├── LaunchImage.imageset │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ ├── README.md │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ └── Contents.json │ │ ├── AppDelegate.swift │ │ ├── Base.lproj │ │ │ ├── Main.storyboard │ │ │ └── LaunchScreen.storyboard │ │ └── Info.plist │ ├── Flutter │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── AppFrameworkInfo.plist │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── xcschemes │ │ │ │ └── Runner.xcscheme │ │ └── project.pbxproj │ ├── Runner.xcworkspace │ │ └── contents.xcworkspacedata │ ├── .gitignore │ ├── Podfile.lock │ └── Podfile ├── android │ ├── gradle.properties │ ├── .gitignore │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── values │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── drawable │ │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── kotlin │ │ │ │ │ └── com │ │ │ │ │ │ └── example │ │ │ │ │ │ └── example │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ └── AndroidManifest.xml │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ └── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── .settings │ │ └── org.eclipse.buildship.core.prefs │ ├── .project │ ├── settings.gradle │ └── build.gradle ├── .metadata ├── README.md ├── lib │ ├── utils │ │ └── formatter.dart │ ├── example_tab_bottom.dart │ └── main.dart ├── .gitignore ├── pubspec.yaml └── pubspec.lock ├── .metadata ├── test └── input_sheet_test.dart ├── .vscode └── launch.json ├── pubspec.yaml ├── CHANGELOG.md ├── LICENSE ├── .gitignore ├── pubspec.lock └── README.md /lib/utils/IpsModeCamera.dart: -------------------------------------------------------------------------------- 1 | enum IpsModeCamera { FRONT, BACK } 2 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" -------------------------------------------------------------------------------- /lib/utils/IpsMediaType.dart: -------------------------------------------------------------------------------- 1 | enum IpsMediaType { 2 | PHOTO, 3 | VIDEO, 4 | } 5 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreciornavei/flutter-input-sheet/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 7 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /lib/inputs/IpsInput.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class IpsInput extends StatefulWidget { 4 | @required 5 | onDone() { 6 | return null; 7 | } 8 | 9 | @required 10 | onCancel() { 11 | return null; 12 | } 13 | 14 | @override 15 | State createState() { 16 | return null; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: f139b11009aeb8ed2a3a3aa8b0066e482709dde3 8 | channel: stable 9 | 10 | project_type: package 11 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: f139b11009aeb8ed2a3a3aa8b0066e482709dde3 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /lib/components/IpsIcon.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../utils/colors.dart'; 4 | 5 | class IpsIcon extends StatelessWidget { 6 | final IconData icon; 7 | 8 | IpsIcon(this.icon); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return Icon( 13 | this.icon, 14 | color: IpsColors.mute, 15 | size: 26, 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /test/input_sheet_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | 3 | void main() { 4 | test('adds one to input values', () { 5 | /* 6 | final calculator = new Ips(context).text(); 7 | expect(calculator.addOne(2), 3); 8 | expect(calculator.addOne(-7), -6); 9 | expect(calculator.addOne(0), 1); 10 | expect(() => calculator.addOne(null), throwsNoSuchMethodError); 11 | */ 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Flutter", 9 | "request": "launch", 10 | "type": "dart" 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /example/android/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | arguments= 2 | auto.sync=false 3 | build.scans.enabled=false 4 | connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) 5 | connection.project.dir= 6 | eclipse.preferences.version=1 7 | gradle.user.home= 8 | java.home=/Library/Java/JavaVirtualMachines/openjdk-14.jdk/Contents/Home 9 | jvm.arguments= 10 | offline.mode=false 11 | override.workspace.settings=true 12 | show.console.view=true 13 | show.executions.view=true 14 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/android/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | android 4 | Project android created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.buildship.core.gradleprojectbuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.buildship.core.gradleprojectnature 16 | 17 | 18 | -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/example/example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.example 2 | 3 | import androidx.annotation.NonNull; 4 | import io.flutter.embedding.android.FlutterActivity 5 | import io.flutter.embedding.engine.FlutterEngine 6 | import io.flutter.plugins.GeneratedPluginRegistrant 7 | 8 | class MainActivity: FlutterActivity() { 9 | override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { 10 | GeneratedPluginRegistrant.registerWith(flutterEngine); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /lib/components/IpsLabel.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../utils/colors.dart'; 4 | 5 | class IpsLabel extends StatelessWidget { 6 | final String value; 7 | 8 | IpsLabel(this.value); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return Text( 13 | this.value, 14 | style: TextStyle( 15 | color: IpsColors.mute, 16 | fontWeight: FontWeight.bold, 17 | fontFamily: 'Montserrat', 18 | fontSize: 12, 19 | ), 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/components/IpsValue.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../utils/colors.dart'; 4 | 5 | class IpsValue extends StatelessWidget { 6 | final String value; 7 | 8 | IpsValue(this.value); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return Text( 13 | this.value, 14 | style: TextStyle( 15 | color: IpsColors.dark, 16 | fontWeight: FontWeight.bold, 17 | fontFamily: 'Montserrat', 18 | fontSize: 16, 19 | ), 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # example 2 | 3 | A new Flutter project. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /lib/inputs/IpsInputDate/controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:intl/intl.dart'; 2 | import 'package:mobx/mobx.dart'; 3 | 4 | part "controller.g.dart"; 5 | 6 | class IpsInputDateController = _IpsInputDateController 7 | with _$IpsInputDateController; 8 | 9 | abstract class _IpsInputDateController with Store { 10 | _IpsInputDateController(String format, String value) { 11 | currentDate = 12 | value == null ? DateTime.now() : new DateFormat(format).parse(value); 13 | } 14 | 15 | @observable 16 | DateTime currentDate; 17 | 18 | @action 19 | setCurrentDate(DateTime newValue, List ints) => currentDate = newValue; 20 | } 21 | -------------------------------------------------------------------------------- /lib/components/IpsError.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../utils/colors.dart'; 4 | 5 | class IpsError extends StatelessWidget { 6 | final String message; 7 | 8 | IpsError(this.message); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return this.message == null 13 | ? SizedBox.shrink() 14 | : Text( 15 | this.message, 16 | style: TextStyle( 17 | color: IpsColors.red, 18 | fontWeight: FontWeight.w600, 19 | fontFamily: 'Montserrat', 20 | fontSize: 11, 21 | ), 22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /example/lib/utils/formatter.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_money_formatter/flutter_money_formatter.dart'; 2 | import 'package:intl/intl.dart'; 3 | 4 | class Formatters { 5 | 6 | static String dateToYMD(DateTime date) { 7 | return new DateFormat("yyyy/MM/dd").format(date); 8 | } 9 | 10 | static MoneyFormatterOutput formatUS(double currency) { 11 | return new FlutterMoneyFormatter( 12 | amount: currency, 13 | settings: MoneyFormatterSettings( 14 | symbol: 'U\$', 15 | thousandSeparator: ',', 16 | decimalSeparator: '.', 17 | symbolAndNumberSeparator: ' ', 18 | fractionDigits: 2, 19 | compactFormatType: CompactFormatType.short, 20 | ), 21 | ).output; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | /build/ 32 | 33 | # Web related 34 | lib/generated_plugin_registrant.dart 35 | 36 | # Exceptions to above rules. 37 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 38 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /lib/utils/IpsCameraButton.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class IpsCameraButton extends StatelessWidget { 4 | final double size; 5 | final Function onPress; 6 | final Color color; 7 | final Icon icon; 8 | 9 | IpsCameraButton({ 10 | this.size = 60, 11 | this.color: Colors.transparent, 12 | this.onPress, 13 | this.icon, 14 | }); 15 | 16 | Widget build(BuildContext context) { 17 | return RawMaterialButton( 18 | onPressed: onPress, 19 | constraints: BoxConstraints( 20 | minHeight: size, 21 | maxHeight: size, 22 | minWidth: size, 23 | maxWidth: size, 24 | ), 25 | fillColor: color, 26 | shape: RoundedRectangleBorder( 27 | side: BorderSide( 28 | color: Colors.white, 29 | width: 1, 30 | ), 31 | borderRadius: BorderRadius.all( 32 | Radius.circular(size), 33 | ), 34 | ), 35 | child: icon ?? SizedBox.shrink(), 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: input_sheet 2 | description: A flutter package to help apps with extensive forms, implementing inputs as BottomSheet to make it enjoyable. 3 | version: 0.2.1 4 | homepage: https://github.com/andreciornavei/flutter-input-sheet 5 | 6 | environment: 7 | sdk: ">=2.1.0 <3.0.0" 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | 13 | mobx: ^1.2.1 14 | uuid: ^2.0.4 15 | intl: "^0.16.1" 16 | quiver: ^2.0.5 17 | camera: ^0.5.8+1 18 | flutter_mobx: ^1.1.0 19 | path_provider: ^1.6.8 20 | keyboard_utils: ^1.2.1 21 | after_layout: ^1.0.7+2 22 | video_compress: ^2.0.0 23 | video_player: ^0.10.11 24 | flutter_masked_text: ^0.8.0 25 | permission_handler: ^5.0.1+1 26 | flutter_feather_icons: ^1.0.3 27 | cached_network_image: ^2.2.0+1 28 | flutter_keyboard_size: ^0.1.2+2 29 | flutter_cupertino_date_picker: ^1.0.24 30 | 31 | dev_dependencies: 32 | mobx_codegen: ^1.1.0 33 | build_runner: ^1.10.0 34 | flutter_test: 35 | sdk: flutter 36 | 37 | flutter: 38 | uses-material-design: true 39 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.2.1] 2 | 3 | - [x] Fix filename syntax and format file contents. 4 | 5 | ## [0.2.0] 6 | 7 | - [x] Implemented multioptions feature. 8 | - [x] Updated handler permissions to latest version. 9 | 10 | ## [0.1.3] 11 | 12 | - [x] Updated mobx dependency versions. 13 | 14 | ## [0.1.2] 15 | 16 | - [x] Fixed issue where longtext input needs TextInputType.multiline. 17 | - [x] Fixed IpsInputDate bug where it got error and do not update state. 18 | 19 | ## [0.1.1] 20 | 21 | - [x] Setted default autofocus keyboard to true. 22 | - [x] Fix issue where keyboard do not show in a child widget tree context. 23 | 24 | ## [0.1.0] 25 | 26 | - [x] Update dependencies to latest versions. 27 | - [x] Added `color`, `highlightColor`, `splashColor` and `shape` properties to `IpsCard` Widget. 28 | - [x] Fix Health issues and suggestions. 29 | - [x] Maintenance issues and suggestions. 30 | 31 | ## [0.0.2] - Increase documentation 32 | 33 | - Some fixes in README.md. 34 | 35 | ## [0.0.1] - First release 36 | 37 | - Provides access to most input types used on forms. -------------------------------------------------------------------------------- /lib/utils/colors.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class IpsColors { 4 | static MaterialColor dark = IpsColors.factoryColor(0xff2A2A2A); 5 | static MaterialColor gray = IpsColors.factoryColor(0xff707070); 6 | static MaterialColor mute = IpsColors.factoryColor(0xff9EA4B9); 7 | static MaterialColor red = IpsColors.factoryColor(0xffF98E81); 8 | static MaterialColor light = IpsColors.factoryColor(0xfff4f4f4); 9 | static MaterialColor shadow = IpsColors.factoryColor(0xffE7EAF0); 10 | static MaterialColor border = IpsColors.factoryColor(0xffD8D8D8); 11 | static MaterialColor white = IpsColors.factoryColor(0xffffffff); 12 | static MaterialColor factoryColor(int color) { 13 | return MaterialColor( 14 | color, 15 | { 16 | 50: Color(color), 17 | 100: Color(color), 18 | 200: Color(color), 19 | 300: Color(color), 20 | 400: Color(color), 21 | 500: Color(color), 22 | 600: Color(color), 23 | 700: Color(color), 24 | 800: Color(color), 25 | 900: Color(color), 26 | }, 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 André Ciornavei 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /lib/utils/HandlePermission.dart: -------------------------------------------------------------------------------- 1 | import 'package:permission_handler/permission_handler.dart'; 2 | 3 | class HandlePermission { 4 | static Future enable( 5 | List enablePermissions, 6 | Function onSuccess, 7 | ) async { 8 | bool granted = true; 9 | enablePermissions.forEach((Permission enablePermission) async { 10 | bool permissionGranted = await enablePermission.isGranted; 11 | granted = granted == false ? false : permissionGranted; 12 | }); 13 | if (granted) { 14 | onSuccess(); 15 | } else { 16 | granted = true; 17 | Map permissionsStatus = 18 | await enablePermissions.request(); 19 | permissionsStatus.forEach((permission, permissionStatus) { 20 | granted = permissionStatus.isGranted == false ? false : granted; 21 | }); 22 | if (granted) { 23 | onSuccess(); 24 | } else { 25 | openAppSettings(); 26 | } 27 | } 28 | } 29 | 30 | static Future location(Function onSuccess) async { 31 | if (await Permission.location.isGranted && 32 | await Permission.location.serviceStatus.isEnabled) { 33 | onSuccess(); 34 | } else { 35 | if (await Permission.location.request().isGranted) { 36 | onSuccess(); 37 | } else { 38 | openAppSettings(); 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/inputs/IpsInputDate/controller.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'controller.dart'; 4 | 5 | // ************************************************************************** 6 | // StoreGenerator 7 | // ************************************************************************** 8 | 9 | // ignore_for_file: non_constant_identifier_names, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic 10 | 11 | mixin _$IpsInputDateController on _IpsInputDateController, Store { 12 | final _$currentDateAtom = Atom(name: '_IpsInputDateController.currentDate'); 13 | 14 | @override 15 | DateTime get currentDate { 16 | _$currentDateAtom.reportRead(); 17 | return super.currentDate; 18 | } 19 | 20 | @override 21 | set currentDate(DateTime value) { 22 | _$currentDateAtom.reportWrite(value, super.currentDate, () { 23 | super.currentDate = value; 24 | }); 25 | } 26 | 27 | final _$_IpsInputDateControllerActionController = 28 | ActionController(name: '_IpsInputDateController'); 29 | 30 | @override 31 | dynamic setCurrentDate(DateTime newValue, List ints) { 32 | final _$actionInfo = _$_IpsInputDateControllerActionController.startAction( 33 | name: '_IpsInputDateController.setCurrentDate'); 34 | try { 35 | return super.setCurrentDate(newValue, ints); 36 | } finally { 37 | _$_IpsInputDateControllerActionController.endAction(_$actionInfo); 38 | } 39 | } 40 | 41 | @override 42 | String toString() { 43 | return ''' 44 | currentDate: $currentDate 45 | '''; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | build/ 32 | 33 | # Android related 34 | **/android/**/gradle-wrapper.jar 35 | **/android/.gradle 36 | **/android/captures/ 37 | **/android/gradlew 38 | **/android/gradlew.bat 39 | **/android/local.properties 40 | **/android/**/GeneratedPluginRegistrant.java 41 | 42 | # iOS/XCode related 43 | **/ios/**/*.mode1v3 44 | **/ios/**/*.mode2v3 45 | **/ios/**/*.moved-aside 46 | **/ios/**/*.pbxuser 47 | **/ios/**/*.perspectivev3 48 | **/ios/**/*sync/ 49 | **/ios/**/.sconsign.dblite 50 | **/ios/**/.tags* 51 | **/ios/**/.vagrant/ 52 | **/ios/**/DerivedData/ 53 | **/ios/**/Icon? 54 | **/ios/**/Pods/ 55 | **/ios/**/.symlinks/ 56 | **/ios/**/profile 57 | **/ios/**/xcuserdata 58 | **/ios/.generated/ 59 | **/ios/Flutter/App.framework 60 | **/ios/Flutter/Flutter.framework 61 | **/ios/Flutter/Flutter.podspec 62 | **/ios/Flutter/Generated.xcconfig 63 | **/ios/Flutter/app.flx 64 | **/ios/Flutter/app.zip 65 | **/ios/Flutter/flutter_assets/ 66 | **/ios/Flutter/flutter_export_environment.sh 67 | **/ios/ServiceDefinitions.json 68 | **/ios/Runner/GeneratedPluginRegistrant.* 69 | 70 | # Exceptions to above rules. 71 | !**/ios/**/default.mode1v3 72 | !**/ios/**/default.mode2v3 73 | !**/ios/**/default.pbxuser 74 | !**/ios/**/default.perspectivev3 75 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 76 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSCameraUsageDescription 6 | Can I use the camera please? 7 | NSMicrophoneUsageDescription 8 | Can I use the mic please? 9 | CFBundleDevelopmentRegion 10 | $(DEVELOPMENT_LANGUAGE) 11 | CFBundleExecutable 12 | $(EXECUTABLE_NAME) 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | example 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | $(FLUTTER_BUILD_NAME) 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | $(FLUTTER_BUILD_NUMBER) 27 | LSRequiresIPhoneOS 28 | 29 | UILaunchStoryboardName 30 | LaunchScreen 31 | UIMainStoryboardFile 32 | Main 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | UIViewControllerBasedStatusBarAppearance 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /lib/inputs/IpsInputDate/index.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart'; 3 | import 'package:flutter_mobx/flutter_mobx.dart'; 4 | import 'package:input_sheet/inputs/IpsInput.dart'; 5 | import 'package:intl/intl.dart'; 6 | 7 | import 'controller.dart'; 8 | 9 | class IpsInputDate extends IpsInput { 10 | final Function(String) _onDone; 11 | final String value; 12 | final String format; 13 | final String pickerFormat; 14 | final DateTimePickerLocale locale; 15 | final DateTime minDateTime; 16 | final DateTime maxDateTime; 17 | 18 | final _IpsInputDate state = _IpsInputDate(); 19 | 20 | IpsInputDate( 21 | this._onDone, { 22 | this.value, 23 | this.minDateTime, 24 | this.maxDateTime, 25 | this.locale = DateTimePickerLocale.en_us, 26 | this.format = "yyyy-MM-dd", 27 | this.pickerFormat = "yyyy|MMMM|dd", 28 | }); 29 | 30 | @override 31 | onDone() { 32 | if (_onDone != null) { 33 | state.done(); 34 | } 35 | } 36 | 37 | @override 38 | State createState() => state; 39 | } 40 | 41 | class _IpsInputDate extends State { 42 | IpsInputDateController controller; 43 | 44 | void done() { 45 | this.widget._onDone( 46 | new DateFormat(this.widget.format).format(controller.currentDate)); 47 | } 48 | 49 | @override 50 | void initState() { 51 | super.initState(); 52 | controller = 53 | new IpsInputDateController(this.widget.format, this.widget.value); 54 | } 55 | 56 | @override 57 | Widget build(BuildContext context) { 58 | return Observer( 59 | builder: (_) => DatePickerWidget( 60 | locale: this.widget.locale, 61 | pickerTheme: DateTimePickerTheme(showTitle: false), 62 | dateFormat: this.widget.pickerFormat, 63 | minDateTime: this.widget.minDateTime, 64 | maxDateTime: this.widget.maxDateTime, 65 | initialDateTime: controller.currentDate, 66 | onMonthChangeStartWithFirstDate: false, 67 | onChange: controller.setCurrentDate, 68 | ), 69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /lib/inputs/IpsInputLongtext.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | 4 | import '../utils/colors.dart'; 5 | import 'IpsInput.dart'; 6 | 7 | class IpsInputLongtext extends IpsInput { 8 | final bool autofocus; 9 | final String value; 10 | final String placeholder; 11 | final Function(String) _onDone; 12 | 13 | final _IpsInputLongtext state = _IpsInputLongtext(); 14 | 15 | IpsInputLongtext( 16 | this._onDone, { 17 | this.autofocus = false, 18 | this.value, 19 | this.placeholder, 20 | }); 21 | 22 | @override 23 | onDone() { 24 | if (_onDone != null) { 25 | state.done(); 26 | } 27 | } 28 | 29 | @override 30 | State createState() => state; 31 | } 32 | 33 | class _IpsInputLongtext extends State { 34 | TextEditingController inputController; 35 | 36 | void done() { 37 | this.widget._onDone(inputController.value.text); 38 | } 39 | 40 | @override 41 | void initState() { 42 | super.initState(); 43 | this.inputController = new TextEditingController( 44 | text: this.widget.value ?? "", 45 | ); 46 | } 47 | 48 | @override 49 | Widget build(BuildContext context) { 50 | return TextField( 51 | autofocus: this.widget.autofocus, 52 | textAlign: TextAlign.left, 53 | keyboardType: TextInputType.multiline, 54 | textInputAction: TextInputAction.newline, 55 | minLines: 1, 56 | maxLines: 8, 57 | controller: this.inputController, 58 | style: TextStyle( 59 | fontSize: 19, 60 | fontWeight: FontWeight.bold, 61 | fontFamily: 'Montserrat', 62 | color: IpsColors.dark, 63 | ), 64 | decoration: InputDecoration( 65 | contentPadding: EdgeInsets.symmetric(horizontal: 15, vertical: 0), 66 | border: InputBorder.none, 67 | hintText: this.widget.placeholder, 68 | hintStyle: TextStyle( 69 | fontSize: 26, 70 | fontWeight: FontWeight.bold, 71 | fontFamily: 'Montserrat', 72 | color: IpsColors.mute, 73 | ), 74 | ), 75 | ); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /lib/inputs/IpsInputTime.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart'; 3 | import 'package:input_sheet/inputs/IpsInput.dart'; 4 | import 'package:intl/intl.dart'; 5 | 6 | class IpsInputTime extends IpsInput { 7 | final Function(String) _onDone; 8 | final String value; 9 | final String format; 10 | final String pickerFormat; 11 | final int minuteDivider; 12 | final DateTimePickerLocale locale; 13 | final DateTime minDateTime; 14 | final DateTime maxDateTime; 15 | 16 | final _IpsInputTime state = _IpsInputTime(); 17 | 18 | IpsInputTime( 19 | this._onDone, { 20 | this.value, 21 | this.minDateTime, 22 | this.maxDateTime, 23 | this.locale = DateTimePickerLocale.en_us, 24 | this.format = "HH:mm:ss", 25 | this.pickerFormat = "HH|mm|ss", 26 | this.minuteDivider = 1, 27 | }); 28 | 29 | @override 30 | onDone() { 31 | if (_onDone != null) { 32 | state.done(); 33 | } 34 | } 35 | 36 | @override 37 | State createState() => state; 38 | } 39 | 40 | class _IpsInputTime extends State { 41 | DateTime _currentDatetime; 42 | 43 | void done() { 44 | this 45 | .widget 46 | ._onDone(new DateFormat(this.widget.format).format(_currentDatetime)); 47 | } 48 | 49 | @override 50 | void initState() { 51 | super.initState(); 52 | _currentDatetime = this.widget.value == null 53 | ? DateTime.now() 54 | : new DateFormat(this.widget.format).parse(this.widget.value); 55 | } 56 | 57 | @override 58 | Widget build(BuildContext context) { 59 | return TimePickerWidget( 60 | locale: this.widget.locale, 61 | pickerTheme: DateTimePickerTheme( 62 | showTitle: false, 63 | ), 64 | dateFormat: this.widget.pickerFormat, 65 | minDateTime: this.widget.minDateTime, 66 | maxDateTime: this.widget.maxDateTime, 67 | minuteDivider: this.widget.minuteDivider, 68 | initDateTime: this._currentDatetime, 69 | onChange: (DateTime newValue, List ints) { 70 | setState(() { 71 | _currentDatetime = newValue; 72 | }); 73 | }, 74 | ); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /lib/inputs/IpsInputOptions.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import 'IpsInput.dart'; 5 | 6 | class IpsInputOptions extends IpsInput { 7 | final Function(String) _onDone; 8 | final Map options; 9 | final String value; 10 | 11 | final _IpsInputOptions ipsInputOptions = new _IpsInputOptions(); 12 | 13 | IpsInputOptions( 14 | this._onDone, { 15 | this.value, 16 | this.options = const {}, 17 | }); 18 | 19 | @override 20 | onDone() { 21 | if (_onDone != null) { 22 | this.ipsInputOptions.done(); 23 | } 24 | } 25 | 26 | @override 27 | State createState() => this.ipsInputOptions; 28 | } 29 | 30 | class _IpsInputOptions extends State { 31 | FixedExtentScrollController scrollCtrl; 32 | 33 | void done() { 34 | this.widget._onDone( 35 | this.widget.options.length > 0 36 | ? this.widget.options.keys.toList()[scrollCtrl.selectedItem] 37 | : null, 38 | ); 39 | } 40 | 41 | @override 42 | void initState() { 43 | super.initState(); 44 | scrollCtrl = FixedExtentScrollController( 45 | initialItem: this.widget.value == null 46 | ? 0 47 | : this.widget.options.keys.toList().indexOf(this.widget.value), 48 | ); 49 | } 50 | 51 | @override 52 | Widget build(BuildContext context) { 53 | return Container( 54 | padding: EdgeInsets.all(8.0), 55 | height: 210, 56 | decoration: BoxDecoration(color: Colors.white), 57 | child: CupertinoPicker.builder( 58 | backgroundColor: Colors.white, 59 | scrollController: this.scrollCtrl, 60 | itemExtent: 36, 61 | onSelectedItemChanged: (int) => {}, 62 | childCount: this.widget.options.length, 63 | itemBuilder: (context, index) => Container( 64 | height: 36, 65 | alignment: Alignment.center, 66 | child: Text( 67 | this.widget.options[this.widget.options.keys.toList()[index]], 68 | style: TextStyle( 69 | color: Color(0xFF000046), 70 | fontSize: 16.0, 71 | ), 72 | ), 73 | ), 74 | ), 75 | ); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /lib/inputs/IpsInputDatetime.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart'; 3 | import 'package:input_sheet/inputs/IpsInput.dart'; 4 | import 'package:intl/intl.dart'; 5 | 6 | class IpsInputDatetime extends IpsInput { 7 | final Function(String) _onDone; 8 | final String value; 9 | final String format; 10 | final String pickerFormat; 11 | final int minuteDivider; 12 | final DateTimePickerLocale locale; 13 | final DateTime minDateTime; 14 | final DateTime maxDateTime; 15 | 16 | final _IpsInputDatetime state = _IpsInputDatetime(); 17 | 18 | IpsInputDatetime( 19 | this._onDone, { 20 | this.value, 21 | this.minDateTime, 22 | this.maxDateTime, 23 | this.locale = DateTimePickerLocale.en_us, 24 | this.format = "yyyy-MM-dd HH:mm", 25 | this.pickerFormat = "yyyy/MM/dd|HH|mm", 26 | this.minuteDivider = 1, 27 | }); 28 | 29 | @override 30 | onDone() { 31 | if (_onDone != null) { 32 | state.done(); 33 | } 34 | } 35 | 36 | @override 37 | State createState() => state; 38 | } 39 | 40 | class _IpsInputDatetime extends State { 41 | DateTime _currentDatetime; 42 | 43 | void done() { 44 | this 45 | .widget 46 | ._onDone(new DateFormat(this.widget.format).format(_currentDatetime)); 47 | } 48 | 49 | @override 50 | void initState() { 51 | super.initState(); 52 | _currentDatetime = this.widget.value == null 53 | ? DateTime.now() 54 | : new DateFormat(this.widget.format).parse(this.widget.value); 55 | } 56 | 57 | @override 58 | Widget build(BuildContext context) { 59 | return DateTimePickerWidget( 60 | locale: this.widget.locale, 61 | pickerTheme: DateTimePickerTheme( 62 | showTitle: false, 63 | ), 64 | dateFormat: this.widget.pickerFormat, 65 | minDateTime: this.widget.minDateTime, 66 | maxDateTime: this.widget.maxDateTime, 67 | minuteDivider: this.widget.minuteDivider, 68 | initDateTime: this._currentDatetime, 69 | onChange: (DateTime newValue, List ints) { 70 | setState(() { 71 | _currentDatetime = newValue; 72 | }); 73 | }, 74 | ); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 28 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.example.example" 42 | minSdkVersion 21 43 | targetSdkVersion 28 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 47 | } 48 | 49 | buildTypes { 50 | release { 51 | // TODO: Add your own signing config for the release build. 52 | // Signing with the debug keys for now, so `flutter run --release` works. 53 | signingConfig signingConfigs.debug 54 | } 55 | } 56 | } 57 | 58 | flutter { 59 | source '../..' 60 | } 61 | 62 | dependencies { 63 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 64 | testImplementation 'junit:junit:4.12' 65 | androidTestImplementation 'androidx.test:runner:1.1.1' 66 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' 67 | } 68 | -------------------------------------------------------------------------------- /lib/components/IpsCard.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../utils/colors.dart'; 4 | 5 | class IpsCard extends StatelessWidget { 6 | final Widget label; 7 | final Widget value; 8 | final Widget icon; 9 | final Widget error; 10 | final Function onClick; 11 | final Color color; 12 | final Color highlightColor; 13 | final Color splashColor; 14 | final ShapeBorder shape; 15 | 16 | IpsCard({ 17 | @required this.label, 18 | @required this.value, 19 | @required this.onClick, 20 | this.icon, 21 | this.error, 22 | this.color, 23 | this.highlightColor, 24 | this.splashColor, 25 | this.shape, 26 | }); 27 | 28 | @override 29 | Widget build(BuildContext context) { 30 | return FlatButton( 31 | onPressed: this.onClick, 32 | color: this.color ?? Colors.white, 33 | highlightColor: this.highlightColor ?? Color.fromARGB(10, 0, 0, 0), 34 | splashColor: this.splashColor ?? Color.fromARGB(10, 0, 0, 0), 35 | shape: this.shape ?? 36 | RoundedRectangleBorder( 37 | side: BorderSide(color: IpsColors.border, width: 1), 38 | borderRadius: BorderRadius.all( 39 | Radius.circular(8), 40 | ), 41 | ), 42 | child: Row( 43 | children: [ 44 | Expanded( 45 | child: Padding( 46 | padding: EdgeInsets.symmetric(horizontal: 10, vertical: 20), 47 | child: Row( 48 | crossAxisAlignment: CrossAxisAlignment.center, 49 | children: [ 50 | Expanded( 51 | child: IntrinsicHeight( 52 | child: Column( 53 | crossAxisAlignment: CrossAxisAlignment.start, 54 | mainAxisAlignment: MainAxisAlignment.center, 55 | children: [ 56 | this.label, 57 | SizedBox( 58 | height: 5, 59 | ), 60 | this.value, 61 | this.error ?? SizedBox.shrink() 62 | ], 63 | ), 64 | ), 65 | ), 66 | SizedBox(width: 10), 67 | this.icon ?? SizedBox.shrink() 68 | ], 69 | ), 70 | ), 71 | ), 72 | ], 73 | ), 74 | ); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /lib/inputs/IpsInputText.dart: -------------------------------------------------------------------------------- 1 | import 'package:after_layout/after_layout.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter/services.dart'; 4 | import 'package:flutter/widgets.dart'; 5 | 6 | import '../utils/colors.dart'; 7 | import 'IpsInput.dart'; 8 | 9 | class IpsInputText extends IpsInput { 10 | final TextInputType _textInputType; 11 | final String _value; 12 | final String _placeholder; 13 | final Function(String) _onDone; 14 | final bool autofocus; 15 | 16 | final _IpsInputText state = _IpsInputText(); 17 | 18 | IpsInputText( 19 | this._textInputType, 20 | this._placeholder, 21 | this._value, 22 | this._onDone, { 23 | this.autofocus = false, 24 | }); 25 | 26 | @override 27 | onDone() { 28 | if (_onDone != null) { 29 | state.done(); 30 | } 31 | } 32 | 33 | @override 34 | State createState() => state; 35 | } 36 | 37 | class _IpsInputText extends State 38 | with AfterLayoutMixin { 39 | TextEditingController inputController; 40 | 41 | void done() { 42 | this.widget._onDone(inputController.value.text); 43 | } 44 | 45 | @override 46 | void initState() { 47 | super.initState(); 48 | this.inputController = new TextEditingController( 49 | text: this.widget._value ?? "", 50 | ); 51 | } 52 | 53 | @override 54 | void afterFirstLayout(BuildContext context) { 55 | SystemChannels.textInput.invokeMethod('TextInput.show'); 56 | } 57 | 58 | @override 59 | void dispose() { 60 | SystemChannels.textInput.invokeMethod('TextInput.hide'); 61 | super.dispose(); 62 | } 63 | 64 | @override 65 | Widget build(BuildContext context) { 66 | return TextField( 67 | autofocus: this.widget.autofocus, 68 | textAlign: TextAlign.center, 69 | keyboardType: this.widget._textInputType, 70 | textInputAction: TextInputAction.done, 71 | controller: this.inputController, 72 | style: TextStyle( 73 | fontSize: 19, 74 | fontWeight: FontWeight.bold, 75 | fontFamily: 'Montserrat', 76 | color: IpsColors.dark, 77 | ), 78 | decoration: InputDecoration( 79 | border: InputBorder.none, 80 | hintText: this.widget._placeholder, 81 | hintStyle: TextStyle( 82 | fontSize: 26, 83 | fontWeight: FontWeight.bold, 84 | fontFamily: 'Montserrat', 85 | color: IpsColors.mute, 86 | ), 87 | ), 88 | ); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /lib/components/IpsPhoto.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_feather_icons/flutter_feather_icons.dart'; 5 | 6 | import '../utils/colors.dart'; 7 | 8 | class IpsPhoto extends StatelessWidget { 9 | final File file; 10 | final Function onClick; 11 | final double radius; 12 | final bool readOnly; 13 | 14 | IpsPhoto({ 15 | this.radius: 10, 16 | this.onClick, 17 | this.file, 18 | this.readOnly: false, 19 | }); 20 | 21 | Widget build(BuildContext context) { 22 | return Stack( 23 | overflow: Overflow.visible, 24 | children: [ 25 | Padding( 26 | padding: EdgeInsets.only( 27 | right: readOnly ? 0 : 15, 28 | bottom: readOnly ? 0 : 15, 29 | ), 30 | child: AspectRatio( 31 | aspectRatio: 1, 32 | child: Container( 33 | decoration: BoxDecoration( 34 | color: IpsColors.light, 35 | border: Border.all(color: IpsColors.border, width: 1), 36 | borderRadius: BorderRadius.circular(10), 37 | image: file != null 38 | ? DecorationImage( 39 | image: FileImage(file), 40 | fit: BoxFit.cover, 41 | ) 42 | : null, 43 | ), 44 | alignment: Alignment.center, 45 | child: Visibility( 46 | visible: file == null, 47 | child: Icon( 48 | FeatherIcons.instagram, 49 | size: 26, 50 | color: IpsColors.border, 51 | ), 52 | ), 53 | ), 54 | ), 55 | ), 56 | Visibility( 57 | visible: readOnly == false, 58 | child: Positioned( 59 | right: -5, 60 | bottom: -5, 61 | child: RawMaterialButton( 62 | onPressed: onClick, 63 | fillColor: IpsColors.dark, 64 | shape: CircleBorder(), 65 | constraints: BoxConstraints( 66 | minWidth: 30, 67 | maxWidth: 30, 68 | minHeight: 30, 69 | maxHeight: 30, 70 | ), 71 | child: Icon( 72 | file != null ? FeatherIcons.instagram : FeatherIcons.plus, 73 | size: 14, 74 | color: IpsColors.white, 75 | ), 76 | ), 77 | ), 78 | ) 79 | ], 80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /lib/components/IpsVideo.dart: -------------------------------------------------------------------------------- 1 | import 'dart:typed_data'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_feather_icons/flutter_feather_icons.dart'; 4 | import 'package:input_sheet/utils/colors.dart'; 5 | 6 | class IpsVideo extends StatelessWidget { 7 | final Uint8List thumbnail; 8 | final Function onClick; 9 | final double radius; 10 | final bool readOnly; 11 | 12 | IpsVideo({ 13 | this.radius: 10, 14 | this.onClick, 15 | this.thumbnail, 16 | this.readOnly: false, 17 | }); 18 | 19 | Widget build(BuildContext context) { 20 | return Stack( 21 | overflow: Overflow.visible, 22 | children: [ 23 | Padding( 24 | padding: EdgeInsets.only( 25 | right: readOnly ? 0 : 15, 26 | bottom: readOnly ? 0 : 15, 27 | ), 28 | child: AspectRatio( 29 | aspectRatio: 1, 30 | child: Container( 31 | decoration: BoxDecoration( 32 | color: IpsColors.light, 33 | border: Border.all(color: IpsColors.border, width: 1), 34 | borderRadius: BorderRadius.circular(10), 35 | image: thumbnail != null 36 | ? DecorationImage( 37 | image: MemoryImage(thumbnail), 38 | fit: BoxFit.cover, 39 | ) 40 | : null, 41 | ), 42 | alignment: Alignment.center, 43 | child: Visibility( 44 | visible: thumbnail == null, 45 | child: Icon( 46 | FeatherIcons.video, 47 | size: 26, 48 | color: IpsColors.border, 49 | ), 50 | ), 51 | ), 52 | ), 53 | ), 54 | Visibility( 55 | visible: readOnly == false, 56 | child: Positioned( 57 | right: -5, 58 | bottom: -5, 59 | child: RawMaterialButton( 60 | onPressed: onClick, 61 | fillColor: IpsColors.dark, 62 | shape: CircleBorder(), 63 | constraints: BoxConstraints( 64 | minWidth: 30, 65 | maxWidth: 30, 66 | minHeight: 30, 67 | maxHeight: 30, 68 | ), 69 | child: Icon( 70 | thumbnail != null ? FeatherIcons.video : FeatherIcons.plus, 71 | size: 14, 72 | color: IpsColors.white, 73 | ), 74 | ), 75 | ), 76 | ) 77 | ], 78 | ); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /lib/inputs/IpsInputMask.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | import 'package:flutter_masked_text/flutter_masked_text.dart'; 4 | 5 | import '../utils/colors.dart'; 6 | import 'IpsInput.dart'; 7 | 8 | class IpsInputMask extends IpsInput { 9 | final TextInputType _textInputType; 10 | final String _value; 11 | final String _placeholder; 12 | final List _masks; 13 | final Function(String) _onDone; 14 | final bool autofocus; 15 | 16 | final _IpsInputMask state = _IpsInputMask(); 17 | 18 | IpsInputMask( 19 | this._textInputType, 20 | this._placeholder, 21 | this._masks, 22 | this._value, 23 | this._onDone, { 24 | this.autofocus = false, 25 | }); 26 | 27 | @override 28 | onDone() { 29 | if (_onDone != null) { 30 | state.done(); 31 | } 32 | } 33 | 34 | @override 35 | State createState() => state; 36 | } 37 | 38 | class _IpsInputMask extends State { 39 | MaskedTextController maskedController; 40 | 41 | void done() { 42 | this.widget._onDone(maskedController.value.text); 43 | } 44 | 45 | String identify(int length) { 46 | for (String mask in this.widget._masks) { 47 | if (length <= mask.length) { 48 | return mask; 49 | } 50 | } 51 | return this.widget._masks[this.widget._masks.length - 1]; 52 | } 53 | 54 | @override 55 | void initState() { 56 | super.initState(); 57 | maskedController = new MaskedTextController( 58 | mask: identify(this.widget._value?.length ?? 0), 59 | text: this.widget._value ?? "", 60 | ); 61 | maskedController.beforeChange = (String previous, String next) { 62 | maskedController.updateMask(identify(next.length), moveCursorToEnd: true); 63 | return true; 64 | }; 65 | } 66 | 67 | @override 68 | Widget build(BuildContext context) { 69 | return TextField( 70 | autofocus: this.widget.autofocus, 71 | textAlign: TextAlign.center, 72 | keyboardType: this.widget._textInputType, 73 | textInputAction: TextInputAction.done, 74 | controller: this.maskedController, 75 | style: TextStyle( 76 | fontSize: 19, 77 | fontWeight: FontWeight.bold, 78 | fontFamily: 'Montserrat', 79 | color: IpsColors.dark, 80 | ), 81 | decoration: InputDecoration( 82 | border: InputBorder.none, 83 | hintText: this.widget._placeholder, 84 | hintStyle: TextStyle( 85 | fontSize: 26, 86 | fontWeight: FontWeight.bold, 87 | fontFamily: 'Montserrat', 88 | color: IpsColors.mute, 89 | ), 90 | ), 91 | ); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /lib/inputs/IpsInputNumber.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | import 'package:flutter_masked_text/flutter_masked_text.dart'; 4 | 5 | import '../utils/colors.dart'; 6 | import 'IpsInput.dart'; 7 | 8 | class IpsInputNumber extends IpsInput { 9 | final Function(double) _onDone; 10 | final double value; 11 | final String placeholder; 12 | final String decimalSeparator; 13 | final String thousandSeparator; 14 | final String leftSymbol; 15 | final String rightSymbol; 16 | final int precision; 17 | final bool autofocus; 18 | 19 | final _IpsInputNumber state = _IpsInputNumber(); 20 | 21 | IpsInputNumber(this._onDone, 22 | {this.placeholder, 23 | this.value, 24 | this.decimalSeparator = "", 25 | this.thousandSeparator = "", 26 | this.leftSymbol = "", 27 | this.rightSymbol = "", 28 | this.precision = 0, 29 | this.autofocus = false}); 30 | 31 | @override 32 | onDone() { 33 | if (_onDone != null) { 34 | state.done(); 35 | } 36 | } 37 | 38 | @override 39 | State createState() => state; 40 | } 41 | 42 | class _IpsInputNumber extends State { 43 | MoneyMaskedTextController inputController; 44 | 45 | void done() { 46 | this.widget._onDone(inputController.numberValue); 47 | } 48 | 49 | @override 50 | void initState() { 51 | super.initState(); 52 | this.inputController = inputController = new MoneyMaskedTextController( 53 | decimalSeparator: this.widget.decimalSeparator, 54 | thousandSeparator: this.widget.thousandSeparator, 55 | leftSymbol: this.widget.leftSymbol, 56 | rightSymbol: this.widget.rightSymbol, 57 | precision: this.widget.precision, 58 | initialValue: this.widget.value == null ? 0 : this.widget.value, 59 | ); 60 | } 61 | 62 | @override 63 | Widget build(BuildContext context) { 64 | return TextField( 65 | autofocus: this.widget.autofocus, 66 | textAlign: TextAlign.center, 67 | keyboardType: TextInputType.number, 68 | textInputAction: TextInputAction.done, 69 | controller: this.inputController, 70 | style: TextStyle( 71 | fontSize: 19, 72 | fontWeight: FontWeight.bold, 73 | fontFamily: 'Montserrat', 74 | color: IpsColors.dark, 75 | ), 76 | decoration: InputDecoration( 77 | border: InputBorder.none, 78 | hintText: this.widget.placeholder, 79 | hintStyle: TextStyle( 80 | fontSize: 26, 81 | fontWeight: FontWeight.bold, 82 | fontFamily: 'Montserrat', 83 | color: IpsColors.mute, 84 | ), 85 | ), 86 | ); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /lib/inputs/IpsInputMultioptions.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_feather_icons/flutter_feather_icons.dart'; 3 | 4 | import 'IpsInput.dart'; 5 | 6 | class IpsInputMultioptions extends IpsInput { 7 | final Function(List) _onDone; 8 | final Map options; 9 | final List value; 10 | final TextStyle optionTextStyle; 11 | final Icon optionSelectedIcon; 12 | final Icon optionUnselectedIcon; 13 | 14 | final _IpsInputMultioptions ipsInputMultioptions = 15 | new _IpsInputMultioptions(); 16 | 17 | IpsInputMultioptions( 18 | this._onDone, { 19 | this.value, 20 | this.options = const {}, 21 | this.optionTextStyle, 22 | this.optionSelectedIcon, 23 | this.optionUnselectedIcon, 24 | }); 25 | 26 | @override 27 | onDone() { 28 | if (_onDone != null) { 29 | this.ipsInputMultioptions.done(); 30 | } 31 | } 32 | 33 | @override 34 | State createState() => this.ipsInputMultioptions; 35 | } 36 | 37 | class _IpsInputMultioptions extends State { 38 | final List _selectedOptions = new List(); 39 | 40 | void done() { 41 | this.widget._onDone(_selectedOptions); 42 | } 43 | 44 | void _toggleOption(String option) { 45 | if (_selectedOptions.contains(option)) { 46 | setState(() { 47 | _selectedOptions.remove(option); 48 | }); 49 | } else { 50 | setState(() { 51 | _selectedOptions.add(option); 52 | }); 53 | } 54 | } 55 | 56 | @override 57 | void initState() { 58 | super.initState(); 59 | _selectedOptions.addAll(this.widget.value ?? []); 60 | } 61 | 62 | @override 63 | Widget build(BuildContext context) { 64 | return Container( 65 | padding: EdgeInsets.only(top: 8.0), 66 | height: 210, 67 | decoration: BoxDecoration(color: Colors.white), 68 | child: ListView.separated( 69 | itemCount: this.widget.options.length, 70 | separatorBuilder: (_, __) => Divider( 71 | height: 1, 72 | ), 73 | itemBuilder: (_, index) { 74 | String key = this.widget.options.keys.toList().elementAt(index); 75 | return ListTile( 76 | onTap: () => _toggleOption(key), 77 | dense: true, 78 | title: Text( 79 | this.widget.options[key], 80 | style: this.widget.optionTextStyle ?? 81 | TextStyle( 82 | fontSize: 14, 83 | ), 84 | ), 85 | trailing: Visibility( 86 | visible: _selectedOptions.contains(key), 87 | replacement: this.widget.optionSelectedIcon ?? 88 | Icon( 89 | FeatherIcons.square, 90 | size: 21, 91 | ), 92 | child: this.widget.optionUnselectedIcon ?? 93 | Icon(FeatherIcons.checkSquare, size: 21), 94 | ), 95 | ); 96 | }, 97 | ), 98 | ); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - camera (0.0.1): 3 | - Flutter 4 | - Flutter (1.0.0) 5 | - flutter_money_formatter (0.0.1): 6 | - Flutter 7 | - FMDB (2.7.5): 8 | - FMDB/standard (= 2.7.5) 9 | - FMDB/standard (2.7.5) 10 | - keyboard_utils (0.0.1): 11 | - Flutter 12 | - path_provider (0.0.1): 13 | - Flutter 14 | - path_provider_macos (0.0.1): 15 | - Flutter 16 | - "permission_handler (4.4.0+hotfix.4)": 17 | - Flutter 18 | - sqflite (0.0.1): 19 | - Flutter 20 | - FMDB (~> 2.7.2) 21 | - video_compress (0.3.0): 22 | - Flutter 23 | - video_player (0.0.1): 24 | - Flutter 25 | - video_player_web (0.0.1): 26 | - Flutter 27 | 28 | DEPENDENCIES: 29 | - camera (from `.symlinks/plugins/camera/ios`) 30 | - Flutter (from `Flutter`) 31 | - flutter_money_formatter (from `.symlinks/plugins/flutter_money_formatter/ios`) 32 | - keyboard_utils (from `.symlinks/plugins/keyboard_utils/ios`) 33 | - path_provider (from `.symlinks/plugins/path_provider/ios`) 34 | - path_provider_macos (from `.symlinks/plugins/path_provider_macos/ios`) 35 | - permission_handler (from `.symlinks/plugins/permission_handler/ios`) 36 | - sqflite (from `.symlinks/plugins/sqflite/ios`) 37 | - video_compress (from `.symlinks/plugins/video_compress/ios`) 38 | - video_player (from `.symlinks/plugins/video_player/ios`) 39 | - video_player_web (from `.symlinks/plugins/video_player_web/ios`) 40 | 41 | SPEC REPOS: 42 | trunk: 43 | - FMDB 44 | 45 | EXTERNAL SOURCES: 46 | camera: 47 | :path: ".symlinks/plugins/camera/ios" 48 | Flutter: 49 | :path: Flutter 50 | flutter_money_formatter: 51 | :path: ".symlinks/plugins/flutter_money_formatter/ios" 52 | keyboard_utils: 53 | :path: ".symlinks/plugins/keyboard_utils/ios" 54 | path_provider: 55 | :path: ".symlinks/plugins/path_provider/ios" 56 | path_provider_macos: 57 | :path: ".symlinks/plugins/path_provider_macos/ios" 58 | permission_handler: 59 | :path: ".symlinks/plugins/permission_handler/ios" 60 | sqflite: 61 | :path: ".symlinks/plugins/sqflite/ios" 62 | video_compress: 63 | :path: ".symlinks/plugins/video_compress/ios" 64 | video_player: 65 | :path: ".symlinks/plugins/video_player/ios" 66 | video_player_web: 67 | :path: ".symlinks/plugins/video_player_web/ios" 68 | 69 | SPEC CHECKSUMS: 70 | camera: 38cc83ae9a5667bb5a71c7d9edaf60a91920fd4e 71 | Flutter: 0e3d915762c693b495b44d77113d4970485de6ec 72 | flutter_money_formatter: d0d18ddc5be333fad8d09964d741b59fa11a91dc 73 | FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a 74 | keyboard_utils: ab24bc711be9e91a5937c20489056b8dd650fecc 75 | path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c 76 | path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0 77 | permission_handler: 8278954f2382902f63f00dd8828769c0bd6d511b 78 | sqflite: 4001a31ff81d210346b500c55b17f4d6c7589dd0 79 | video_compress: fce97e4fb1dfd88175aa07d2ffc8a2f297f87fbe 80 | video_player: 9cc823b1d9da7e8427ee591e8438bfbcde500e6e 81 | video_player_web: da8cadb8274ed4f8dbee8d7171b420dedd437ce7 82 | 83 | PODFILE CHECKSUM: 1b66dae606f75376c5f2135a8290850eeb09ae83 84 | 85 | COCOAPODS: 1.9.1 86 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: InputSheetDemo 2 | description: A Flutter example to implement input_sheet. 3 | 4 | # The following defines the version and build number for your application. 5 | # A version number is three numbers separated by dots, like 1.2.43 6 | # followed by an optional build number separated by a +. 7 | # Both the version and the builder number may be overridden in flutter 8 | # build by specifying --build-name and --build-number, respectively. 9 | # In Android, build-name is used as versionName while build-number used as versionCode. 10 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 11 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 12 | # Read more about iOS versioning at 13 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 14 | version: 1.0.0+1 15 | 16 | environment: 17 | sdk: ">=2.1.0 <3.0.0" 18 | 19 | dependencies: 20 | flutter: 21 | sdk: flutter 22 | 23 | # The following adds the Cupertino Icons font to your application. 24 | # Use with the CupertinoIcons class for iOS style icons. 25 | cupertino_icons: ^0.1.2 26 | flutter_feather_icons: ^1.0.3 27 | flutter_money_formatter: ^0.8.3 28 | intl: ^0.15.8 29 | input_sheet: 30 | path: ../ 31 | 32 | dependency_overrides: 33 | intl: ^0.15.8 34 | 35 | dev_dependencies: 36 | flutter_test: 37 | sdk: flutter 38 | 39 | 40 | # For information on the generic Dart part of this file, see the 41 | # following page: https://dart.dev/tools/pub/pubspec 42 | 43 | # The following section is specific to Flutter. 44 | flutter: 45 | 46 | # The following line ensures that the Material Icons font is 47 | # included with your application, so that you can use the icons in 48 | # the material Icons class. 49 | uses-material-design: true 50 | 51 | # To add assets to your application, add an assets section, like this: 52 | # assets: 53 | # - images/a_dot_burr.jpeg 54 | # - images/a_dot_ham.jpeg 55 | 56 | # An image asset can refer to one or more resolution-specific "variants", see 57 | # https://flutter.dev/assets-and-images/#resolution-aware. 58 | 59 | # For details regarding adding assets from package dependencies, see 60 | # https://flutter.dev/assets-and-images/#from-packages 61 | 62 | # To add custom fonts to your application, add a fonts section here, 63 | # in this "flutter" section. Each entry in this list should have a 64 | # "family" key with the font family name, and a "fonts" key with a 65 | # list giving the asset and other descriptors for the font. For 66 | # example: 67 | # fonts: 68 | # - family: Schyler 69 | # fonts: 70 | # - asset: fonts/Schyler-Regular.ttf 71 | # - asset: fonts/Schyler-Italic.ttf 72 | # style: italic 73 | # - family: Trajan Pro 74 | # fonts: 75 | # - asset: fonts/TrajanPro.ttf 76 | # - asset: fonts/TrajanPro_Bold.ttf 77 | # weight: 700 78 | # 79 | # For details regarding fonts from package dependencies, 80 | # see https://flutter.dev/custom-fonts/#from-packages 81 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def parse_KV_file(file, separator='=') 14 | file_abs_path = File.expand_path(file) 15 | if !File.exists? file_abs_path 16 | return []; 17 | end 18 | generated_key_values = {} 19 | skip_line_start_symbols = ["#", "/"] 20 | File.foreach(file_abs_path) do |line| 21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 22 | plugin = line.split(pattern=separator) 23 | if plugin.length == 2 24 | podname = plugin[0].strip() 25 | path = plugin[1].strip() 26 | podpath = File.expand_path("#{path}", file_abs_path) 27 | generated_key_values[podname] = podpath 28 | else 29 | puts "Invalid plugin specification: #{line}" 30 | end 31 | end 32 | generated_key_values 33 | end 34 | 35 | target 'Runner' do 36 | use_frameworks! 37 | use_modular_headers! 38 | 39 | # Flutter Pod 40 | 41 | copied_flutter_dir = File.join(__dir__, 'Flutter') 42 | copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') 43 | copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') 44 | unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) 45 | # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. 46 | # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. 47 | # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. 48 | 49 | generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') 50 | unless File.exist?(generated_xcode_build_settings_path) 51 | raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" 52 | end 53 | generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) 54 | cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; 55 | 56 | unless File.exist?(copied_framework_path) 57 | FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) 58 | end 59 | unless File.exist?(copied_podspec_path) 60 | FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) 61 | end 62 | end 63 | 64 | # Keep pod path relative so it can be checked into Podfile.lock. 65 | pod 'Flutter', :path => 'Flutter' 66 | 67 | # Plugin Pods 68 | 69 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 70 | # referring to absolute paths on developers' machines. 71 | system('rm -rf .symlinks') 72 | system('mkdir -p .symlinks/plugins') 73 | plugin_pods = parse_KV_file('../.flutter-plugins') 74 | plugin_pods.each do |name, path| 75 | symlink = File.join('.symlinks', 'plugins', name) 76 | File.symlink(path, symlink) 77 | pod name, :path => File.join(symlink, 'ios') 78 | end 79 | end 80 | 81 | # Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. 82 | install! 'cocoapods', :disable_input_output_paths => true 83 | 84 | post_install do |installer| 85 | installer.pods_project.targets.each do |target| 86 | target.build_configurations.each do |config| 87 | config.build_settings['ENABLE_BITCODE'] = 'NO' 88 | end 89 | end 90 | end 91 | -------------------------------------------------------------------------------- /example/lib/example_tab_bottom.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:input_sheet/components/IpsCard.dart'; 4 | import 'package:input_sheet/components/IpsError.dart'; 5 | import 'package:input_sheet/components/IpsIcon.dart'; 6 | import 'package:input_sheet/components/IpsLabel.dart'; 7 | import 'package:input_sheet/components/IpsValue.dart'; 8 | import 'package:input_sheet/input_sheet.dart'; 9 | import 'package:flutter_feather_icons/flutter_feather_icons.dart'; 10 | import 'package:input_sheet/utils/colors.dart'; 11 | 12 | void main() => runApp(BottomBarApp()); 13 | 14 | class BottomBarApp extends StatelessWidget { 15 | @override 16 | Widget build(BuildContext context) { 17 | return MaterialApp( 18 | title: 'Keyboard Tree Demo', 19 | theme: ThemeData( 20 | primarySwatch: IpsColors.dark, 21 | ), 22 | home: DefaultTabController( 23 | length: 4, 24 | child: SafeArea( 25 | child: Scaffold( 26 | appBar: AppBar( 27 | title: Text("Keyboard Tree Demo"), 28 | ), 29 | body: TabBarView( 30 | children: [ 31 | new FirstPage(), 32 | new Container(color: Color(0xffe5e5e5)), 33 | new Container(color: Color(0xffd5d5d5)), 34 | new Container(color: Color(0xffc5c5c5)), 35 | ], 36 | ), 37 | bottomNavigationBar: new TabBar( 38 | tabs: [ 39 | Tab(icon: new Icon(Icons.home)), 40 | Tab(icon: new Icon(Icons.rss_feed)), 41 | Tab(icon: new Icon(Icons.perm_identity)), 42 | Tab(icon: new Icon(Icons.settings)) 43 | ], 44 | labelColor: Colors.blue, 45 | unselectedLabelColor: Color(0xff3A3A3A), 46 | indicatorSize: TabBarIndicatorSize.label, 47 | indicatorPadding: EdgeInsets.all(5.0), 48 | indicatorColor: Colors.blue, 49 | ), 50 | ), 51 | ), 52 | ), 53 | ); 54 | } 55 | } 56 | 57 | class FirstPage extends StatefulWidget { 58 | @override 59 | State createState() => _FirstPage(); 60 | } 61 | 62 | class _FirstPage extends State { 63 | String _name; 64 | Map _errors = new Map(); 65 | 66 | @override 67 | Widget build(BuildContext context) { 68 | return Container( 69 | color: Color(0xfff5f5f5), 70 | child: SingleChildScrollView( 71 | child: Padding( 72 | padding: EdgeInsets.all(25), 73 | child: Column( 74 | crossAxisAlignment: CrossAxisAlignment.start, 75 | children: [ 76 | Text( 77 | 'Text example:', 78 | ), 79 | SizedBox(height: 15), 80 | IpsCard( 81 | label: IpsLabel("Name"), 82 | value: IpsValue(_name ?? "Touch to edit..."), 83 | icon: IpsIcon(FeatherIcons.user), 84 | error: IpsError(_errors['_name']), 85 | onClick: () => InputSheet( 86 | context, 87 | label: "Name", 88 | cancelText: "Cancel", 89 | doneText: "Confirm", 90 | ).longtext( 91 | placeholder: "Type here...", 92 | value: _name, 93 | onDone: (dynamic value) => setState(() { 94 | _name = value; 95 | }), 96 | ), 97 | ), 98 | ], 99 | ), 100 | ), 101 | ), 102 | ); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /lib/sheet.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | import 'package:flutter_feather_icons/flutter_feather_icons.dart'; 4 | import 'package:flutter_keyboard_size/flutter_keyboard_size.dart'; 5 | import 'package:keyboard_utils/widgets.dart'; 6 | 7 | import 'inputs/IpsInput.dart'; 8 | import 'utils/colors.dart'; 9 | 10 | class Sheet { 11 | final BuildContext _context; 12 | final String _label; 13 | final String _cancelText; 14 | final String _doneText; 15 | final double paddingVertical; 16 | final bool showDoneButton; 17 | 18 | Sheet( 19 | this._context, 20 | this._label, 21 | this._cancelText, 22 | this._doneText, { 23 | this.paddingVertical: 25, 24 | this.showDoneButton: true, 25 | }); 26 | 27 | open(IpsInput ipsInput) { 28 | showModalBottomSheet( 29 | backgroundColor: Colors.white, 30 | context: _context, 31 | isScrollControlled: true, 32 | shape: RoundedRectangleBorder( 33 | borderRadius: BorderRadius.only( 34 | topLeft: Radius.circular(10), 35 | topRight: Radius.circular(10), 36 | ), 37 | ), 38 | builder: (BuildContext context) { 39 | return KeyboardSizeProvider( 40 | child: Column( 41 | mainAxisSize: MainAxisSize.min, 42 | children: [ 43 | Container( 44 | padding: EdgeInsets.all(0), 45 | height: 45, 46 | width: double.maxFinite, 47 | decoration: BoxDecoration( 48 | color: Colors.white, 49 | border: Border( 50 | bottom: BorderSide(color: IpsColors.border, width: 1), 51 | ), 52 | ), 53 | child: Row( 54 | crossAxisAlignment: CrossAxisAlignment.stretch, 55 | children: [ 56 | RawMaterialButton( 57 | onPressed: () { 58 | Navigator.pop(_context); 59 | ipsInput.onCancel(); 60 | }, 61 | padding: EdgeInsets.symmetric(horizontal: 10), 62 | child: Row( 63 | children: [ 64 | Icon( 65 | FeatherIcons.x, 66 | size: 21, 67 | color: IpsColors.dark, 68 | ), 69 | SizedBox( 70 | width: 5, 71 | ), 72 | Text( 73 | _cancelText, 74 | style: TextStyle( 75 | fontFamily: 'Montserrat', 76 | fontWeight: FontWeight.bold, 77 | fontSize: 14, 78 | color: IpsColors.dark, 79 | ), 80 | ) 81 | ], 82 | ), 83 | ), 84 | Expanded( 85 | child: SizedBox.shrink(), 86 | ), 87 | Visibility( 88 | visible: showDoneButton == true, 89 | child: RawMaterialButton( 90 | onPressed: () { 91 | Navigator.pop(context); 92 | ipsInput.onDone(); 93 | }, 94 | padding: EdgeInsets.symmetric(horizontal: 10), 95 | child: Row( 96 | children: [ 97 | Text( 98 | _doneText, 99 | style: TextStyle( 100 | fontFamily: 'Montserrat', 101 | fontWeight: FontWeight.bold, 102 | fontSize: 14, 103 | color: IpsColors.dark, 104 | ), 105 | ), 106 | SizedBox( 107 | width: 5, 108 | ), 109 | Icon( 110 | FeatherIcons.check, 111 | size: 21, 112 | color: IpsColors.dark, 113 | ), 114 | ], 115 | ), 116 | ), 117 | ), 118 | ], 119 | ), 120 | ), 121 | Padding( 122 | padding: EdgeInsets.symmetric( 123 | vertical: paddingVertical, 124 | ), 125 | child: Column( 126 | children: [ 127 | Visibility( 128 | visible: _label != null, 129 | child: Padding( 130 | padding: EdgeInsets.only(bottom: 5), 131 | child: Text( 132 | _label ?? "", 133 | textAlign: TextAlign.center, 134 | style: TextStyle( 135 | fontFamily: 'Montserrat', 136 | fontSize: 16, 137 | color: IpsColors.gray, 138 | fontWeight: FontWeight.bold, 139 | ), 140 | ), 141 | ), 142 | ), 143 | ipsInput 144 | ], 145 | ), 146 | ), 147 | KeyboardAware( 148 | builder: (context, keyboardConfig) { 149 | return Consumer( 150 | builder: (context, _res, child) { 151 | return SizedBox( 152 | height: _res.keyboardHeight > 0 153 | ? _res.keyboardHeight 154 | : keyboardConfig.keyboardHeight > 0 155 | ? keyboardConfig.keyboardHeight 156 | : MediaQuery.of(_context).viewInsets.bottom != 157 | null && 158 | MediaQuery.of(_context) 159 | .viewInsets 160 | .bottom > 161 | 0 162 | ? MediaQuery.of(_context).viewInsets.bottom 163 | : 0, 164 | ); 165 | }, 166 | ); 167 | }, 168 | ), 169 | ], 170 | ), 171 | ); 172 | }, 173 | ); 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /lib/input_sheet.dart: -------------------------------------------------------------------------------- 1 | library input_sheet; 2 | 3 | import 'dart:io'; 4 | import 'dart:typed_data'; 5 | 6 | import 'package:camera/camera.dart'; 7 | import 'package:flutter/material.dart'; 8 | import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart'; 9 | import 'package:input_sheet/inputs/IpsInputCamera.dart'; 10 | import 'package:input_sheet/inputs/IpsInputDatetime.dart'; 11 | import 'package:input_sheet/inputs/IpsInputMultioptions.dart'; 12 | import 'package:input_sheet/inputs/IpsInputTime.dart'; 13 | import 'package:input_sheet/utils/IpsMediaType.dart'; 14 | import 'package:input_sheet/utils/IpsModeCamera.dart'; 15 | import 'package:video_compress/video_compress.dart'; 16 | 17 | import 'inputs/IpsInputDate/index.dart'; 18 | import 'inputs/IpsInputLongtext.dart'; 19 | import 'inputs/IpsInputMask.dart'; 20 | import 'inputs/IpsInputNumber.dart'; 21 | import 'inputs/IpsInputOptions.dart'; 22 | import 'inputs/IpsInputText.dart'; 23 | import 'sheet.dart'; 24 | 25 | class InputSheet { 26 | final BuildContext _context; 27 | final String label; 28 | final String cancelText; 29 | final String doneText; 30 | final bool keyboardAutofocus; 31 | 32 | InputSheet( 33 | this._context, { 34 | this.label = "Label", 35 | this.cancelText = "Cancel", 36 | this.doneText = "Done", 37 | this.keyboardAutofocus = true, 38 | }); 39 | 40 | text({ 41 | TextInputType textInputType = TextInputType.text, 42 | String placeholder = "Placeholder", 43 | dynamic value, 44 | Function(String) onDone, 45 | }) { 46 | Sheet( 47 | this._context, 48 | this.label, 49 | this.cancelText, 50 | this.doneText, 51 | ).open(new IpsInputText( 52 | textInputType, 53 | placeholder, 54 | value, 55 | onDone, 56 | autofocus: keyboardAutofocus, 57 | )); 58 | } 59 | 60 | longtext({ 61 | String placeholder = "Placeholder", 62 | String value, 63 | Function(String) onDone, 64 | }) { 65 | Sheet( 66 | this._context, 67 | this.label, 68 | this.cancelText, 69 | this.doneText, 70 | ).open(new IpsInputLongtext( 71 | onDone, 72 | placeholder: placeholder, 73 | value: value, 74 | autofocus: keyboardAutofocus, 75 | )); 76 | } 77 | 78 | mask({ 79 | TextInputType textInputType = TextInputType.text, 80 | String placeholder = "Placeholder", 81 | dynamic value, 82 | List masks, 83 | Function(dynamic) onDone, 84 | }) { 85 | Sheet( 86 | this._context, 87 | this.label, 88 | this.cancelText, 89 | this.doneText, 90 | ).open(new IpsInputMask( 91 | textInputType, 92 | placeholder, 93 | masks, 94 | value, 95 | onDone, 96 | autofocus: keyboardAutofocus, 97 | )); 98 | } 99 | 100 | number({ 101 | String decimalSeparator = "", 102 | String thousandSeparator = "", 103 | String leftSymbol = "", 104 | String rightSymbol = "", 105 | int precision = 0, 106 | String placeholder = "Placeholder", 107 | double value, 108 | Function(double) onDone, 109 | }) { 110 | Sheet( 111 | this._context, 112 | this.label, 113 | this.cancelText, 114 | this.doneText, 115 | ).open(new IpsInputNumber( 116 | onDone, 117 | placeholder: placeholder, 118 | value: value, 119 | autofocus: keyboardAutofocus, 120 | decimalSeparator: decimalSeparator, 121 | thousandSeparator: thousandSeparator, 122 | leftSymbol: leftSymbol, 123 | rightSymbol: rightSymbol, 124 | precision: precision, 125 | )); 126 | } 127 | 128 | date({ 129 | String value, 130 | Function(String) onDone, 131 | DateTime minDateTime, 132 | DateTime maxDateTime, 133 | DateTimePickerLocale locale = DateTimePickerLocale.en_us, 134 | String format = "yyyy-MM-dd", 135 | String pickerFormat = "yyyy|MMMM|dd", 136 | }) { 137 | Sheet( 138 | this._context, 139 | this.label, 140 | this.cancelText, 141 | this.doneText, 142 | ).open( 143 | new IpsInputDate( 144 | onDone, 145 | value: value, 146 | locale: locale, 147 | format: format, 148 | pickerFormat: pickerFormat, 149 | minDateTime: minDateTime, 150 | maxDateTime: maxDateTime, 151 | ), 152 | ); 153 | } 154 | 155 | time({ 156 | String value, 157 | Function(String) onDone, 158 | DateTime minDateTime, 159 | DateTime maxDateTime, 160 | DateTimePickerLocale locale = DateTimePickerLocale.en_us, 161 | String format = "HH:mm:ss", 162 | String pickerFormat = "HH|mm|ss", 163 | int minuteDivider = 1, 164 | }) { 165 | Sheet( 166 | this._context, 167 | this.label, 168 | this.cancelText, 169 | this.doneText, 170 | ).open( 171 | new IpsInputTime( 172 | onDone, 173 | value: value, 174 | locale: locale, 175 | format: format, 176 | pickerFormat: pickerFormat, 177 | minDateTime: minDateTime, 178 | maxDateTime: maxDateTime, 179 | minuteDivider: minuteDivider, 180 | ), 181 | ); 182 | } 183 | 184 | datetime({ 185 | String value, 186 | Function(String) onDone, 187 | DateTime minDateTime, 188 | DateTime maxDateTime, 189 | DateTimePickerLocale locale = DateTimePickerLocale.en_us, 190 | String format = "yyyy/MM/dd HH:mm", 191 | String pickerFormat = "yyyy/MM/dd|HH|mm", 192 | int minuteDivider = 1, 193 | }) { 194 | Sheet( 195 | this._context, 196 | this.label, 197 | this.cancelText, 198 | this.doneText, 199 | ).open( 200 | new IpsInputDatetime( 201 | onDone, 202 | value: value, 203 | locale: locale, 204 | format: format, 205 | pickerFormat: pickerFormat, 206 | minDateTime: minDateTime, 207 | maxDateTime: maxDateTime, 208 | minuteDivider: minuteDivider, 209 | ), 210 | ); 211 | } 212 | 213 | options({ 214 | dynamic value, 215 | Map options, 216 | Function(String) onDone, 217 | }) { 218 | Sheet( 219 | this._context, 220 | this.label, 221 | this.cancelText, 222 | this.doneText, 223 | ).open( 224 | new IpsInputOptions( 225 | onDone, 226 | value: value, 227 | options: options, 228 | ), 229 | ); 230 | } 231 | 232 | multioptions({ 233 | List value, 234 | Map options, 235 | Function(List) onDone, 236 | TextStyle optionTextStyle, 237 | Icon optionSelectedIcon, 238 | Icon optionUnselectedIcon, 239 | }) { 240 | Sheet( 241 | this._context, 242 | this.label, 243 | this.cancelText, 244 | this.doneText, 245 | ).open( 246 | new IpsInputMultioptions( 247 | onDone, 248 | value: value, 249 | options: options, 250 | optionTextStyle: optionTextStyle, 251 | optionSelectedIcon: optionSelectedIcon, 252 | optionUnselectedIcon: optionUnselectedIcon, 253 | ), 254 | ); 255 | } 256 | 257 | photo({ 258 | File file, 259 | String url, 260 | double height, 261 | ResolutionPreset resolution = ResolutionPreset.high, 262 | String labelInitializingCamera = "Camera is not initialized yet", 263 | String labelNoCameraAvailable = 264 | "There is no camera available on this device", 265 | @required Function(File, Uint8List) onDone, 266 | }) { 267 | Sheet( 268 | this._context, 269 | null, 270 | this.cancelText, 271 | this.doneText, 272 | paddingVertical: 0, 273 | showDoneButton: false, 274 | ).open( 275 | new IpsInputCamera( 276 | onDone, 277 | IpsMediaType.PHOTO, 278 | IpsModeCamera.BACK, 279 | MediaQuery.of(_context).padding.top, 280 | url: url, 281 | file: file, 282 | height: height, 283 | resolution: resolution, 284 | labelInitializingCamera: labelInitializingCamera, 285 | labelNoCameraAvailable: labelNoCameraAvailable, 286 | ), 287 | ); 288 | } 289 | 290 | video({ 291 | File file, 292 | String url, 293 | double height, 294 | VideoQuality compress, 295 | int timeRecordLimit = 60, 296 | String sufixRecordTimeout = "Sec", 297 | String labelCompressing = "Compressing...", 298 | ResolutionPreset resolution = ResolutionPreset.high, 299 | String labelInitializingCamera = "Camera is not initialized yet", 300 | String labelNoCameraAvailable = 301 | "There is no camera available on this device", 302 | @required Function(File, Uint8List) onDone, 303 | }) { 304 | Sheet( 305 | this._context, 306 | null, 307 | this.cancelText, 308 | this.doneText, 309 | paddingVertical: 0, 310 | showDoneButton: false, 311 | ).open( 312 | new IpsInputCamera( 313 | onDone, 314 | IpsMediaType.VIDEO, 315 | IpsModeCamera.BACK, 316 | MediaQuery.of(_context).padding.top, 317 | url: url, 318 | file: file, 319 | height: height, 320 | compress: compress, 321 | resolution: resolution, 322 | timeRecordLimit: timeRecordLimit, 323 | sufixRecordTimeout: sufixRecordTimeout, 324 | labelCompressing: labelCompressing, 325 | labelInitializingCamera: labelInitializingCamera, 326 | labelNoCameraAvailable: labelNoCameraAvailable, 327 | ), 328 | ); 329 | } 330 | 331 | //TO-DO 332 | //slider() {} 333 | //colors() {} 334 | } 335 | -------------------------------------------------------------------------------- /example/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | after_layout: 5 | dependency: transitive 6 | description: 7 | name: after_layout 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "1.0.7+2" 11 | archive: 12 | dependency: transitive 13 | description: 14 | name: archive 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "2.0.13" 18 | args: 19 | dependency: transitive 20 | description: 21 | name: args 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "1.6.0" 25 | async: 26 | dependency: transitive 27 | description: 28 | name: async 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "2.4.1" 32 | boolean_selector: 33 | dependency: transitive 34 | description: 35 | name: boolean_selector 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "2.0.0" 39 | cached_network_image: 40 | dependency: transitive 41 | description: 42 | name: cached_network_image 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "2.2.0+1" 46 | camera: 47 | dependency: transitive 48 | description: 49 | name: camera 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "0.5.8+1" 53 | charcode: 54 | dependency: transitive 55 | description: 56 | name: charcode 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "1.1.3" 60 | clock: 61 | dependency: transitive 62 | description: 63 | name: clock 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "1.0.1" 67 | collection: 68 | dependency: transitive 69 | description: 70 | name: collection 71 | url: "https://pub.dartlang.org" 72 | source: hosted 73 | version: "1.14.12" 74 | convert: 75 | dependency: transitive 76 | description: 77 | name: convert 78 | url: "https://pub.dartlang.org" 79 | source: hosted 80 | version: "2.1.1" 81 | crypto: 82 | dependency: transitive 83 | description: 84 | name: crypto 85 | url: "https://pub.dartlang.org" 86 | source: hosted 87 | version: "2.1.4" 88 | cupertino_icons: 89 | dependency: "direct main" 90 | description: 91 | name: cupertino_icons 92 | url: "https://pub.dartlang.org" 93 | source: hosted 94 | version: "0.1.3" 95 | file: 96 | dependency: transitive 97 | description: 98 | name: file 99 | url: "https://pub.dartlang.org" 100 | source: hosted 101 | version: "5.1.0" 102 | flutter: 103 | dependency: "direct main" 104 | description: flutter 105 | source: sdk 106 | version: "0.0.0" 107 | flutter_cache_manager: 108 | dependency: transitive 109 | description: 110 | name: flutter_cache_manager 111 | url: "https://pub.dartlang.org" 112 | source: hosted 113 | version: "1.2.2" 114 | flutter_cupertino_date_picker: 115 | dependency: transitive 116 | description: 117 | name: flutter_cupertino_date_picker 118 | url: "https://pub.dartlang.org" 119 | source: hosted 120 | version: "1.0.24" 121 | flutter_feather_icons: 122 | dependency: "direct main" 123 | description: 124 | name: flutter_feather_icons 125 | url: "https://pub.dartlang.org" 126 | source: hosted 127 | version: "1.0.3" 128 | flutter_keyboard_size: 129 | dependency: transitive 130 | description: 131 | name: flutter_keyboard_size 132 | url: "https://pub.dartlang.org" 133 | source: hosted 134 | version: "0.1.2+2" 135 | flutter_masked_text: 136 | dependency: transitive 137 | description: 138 | name: flutter_masked_text 139 | url: "https://pub.dartlang.org" 140 | source: hosted 141 | version: "0.8.0" 142 | flutter_mobx: 143 | dependency: transitive 144 | description: 145 | name: flutter_mobx 146 | url: "https://pub.dartlang.org" 147 | source: hosted 148 | version: "1.1.0" 149 | flutter_money_formatter: 150 | dependency: "direct main" 151 | description: 152 | name: flutter_money_formatter 153 | url: "https://pub.dartlang.org" 154 | source: hosted 155 | version: "0.8.3" 156 | flutter_test: 157 | dependency: "direct dev" 158 | description: flutter 159 | source: sdk 160 | version: "0.0.0" 161 | flutter_web_plugins: 162 | dependency: transitive 163 | description: flutter 164 | source: sdk 165 | version: "0.0.0" 166 | http: 167 | dependency: transitive 168 | description: 169 | name: http 170 | url: "https://pub.dartlang.org" 171 | source: hosted 172 | version: "0.12.1" 173 | http_parser: 174 | dependency: transitive 175 | description: 176 | name: http_parser 177 | url: "https://pub.dartlang.org" 178 | source: hosted 179 | version: "3.1.4" 180 | image: 181 | dependency: transitive 182 | description: 183 | name: image 184 | url: "https://pub.dartlang.org" 185 | source: hosted 186 | version: "2.1.12" 187 | input_sheet: 188 | dependency: "direct main" 189 | description: 190 | path: ".." 191 | relative: true 192 | source: path 193 | version: "0.2.1" 194 | intl: 195 | dependency: "direct main" 196 | description: 197 | name: intl 198 | url: "https://pub.dartlang.org" 199 | source: hosted 200 | version: "0.15.8" 201 | keyboard_utils: 202 | dependency: transitive 203 | description: 204 | name: keyboard_utils 205 | url: "https://pub.dartlang.org" 206 | source: hosted 207 | version: "1.2.1" 208 | matcher: 209 | dependency: transitive 210 | description: 211 | name: matcher 212 | url: "https://pub.dartlang.org" 213 | source: hosted 214 | version: "0.12.6" 215 | meta: 216 | dependency: transitive 217 | description: 218 | name: meta 219 | url: "https://pub.dartlang.org" 220 | source: hosted 221 | version: "1.1.8" 222 | mobx: 223 | dependency: transitive 224 | description: 225 | name: mobx 226 | url: "https://pub.dartlang.org" 227 | source: hosted 228 | version: "1.2.1" 229 | nested: 230 | dependency: transitive 231 | description: 232 | name: nested 233 | url: "https://pub.dartlang.org" 234 | source: hosted 235 | version: "0.0.4" 236 | path: 237 | dependency: transitive 238 | description: 239 | name: path 240 | url: "https://pub.dartlang.org" 241 | source: hosted 242 | version: "1.6.4" 243 | path_provider: 244 | dependency: transitive 245 | description: 246 | name: path_provider 247 | url: "https://pub.dartlang.org" 248 | source: hosted 249 | version: "1.6.8" 250 | path_provider_macos: 251 | dependency: transitive 252 | description: 253 | name: path_provider_macos 254 | url: "https://pub.dartlang.org" 255 | source: hosted 256 | version: "0.0.4+2" 257 | path_provider_platform_interface: 258 | dependency: transitive 259 | description: 260 | name: path_provider_platform_interface 261 | url: "https://pub.dartlang.org" 262 | source: hosted 263 | version: "1.0.2" 264 | pedantic: 265 | dependency: transitive 266 | description: 267 | name: pedantic 268 | url: "https://pub.dartlang.org" 269 | source: hosted 270 | version: "1.8.0+1" 271 | permission_handler: 272 | dependency: transitive 273 | description: 274 | name: permission_handler 275 | url: "https://pub.dartlang.org" 276 | source: hosted 277 | version: "5.0.1+1" 278 | permission_handler_platform_interface: 279 | dependency: transitive 280 | description: 281 | name: permission_handler_platform_interface 282 | url: "https://pub.dartlang.org" 283 | source: hosted 284 | version: "2.0.1" 285 | petitparser: 286 | dependency: transitive 287 | description: 288 | name: petitparser 289 | url: "https://pub.dartlang.org" 290 | source: hosted 291 | version: "2.4.0" 292 | platform: 293 | dependency: transitive 294 | description: 295 | name: platform 296 | url: "https://pub.dartlang.org" 297 | source: hosted 298 | version: "2.2.1" 299 | plugin_platform_interface: 300 | dependency: transitive 301 | description: 302 | name: plugin_platform_interface 303 | url: "https://pub.dartlang.org" 304 | source: hosted 305 | version: "1.0.2" 306 | provider: 307 | dependency: transitive 308 | description: 309 | name: provider 310 | url: "https://pub.dartlang.org" 311 | source: hosted 312 | version: "4.0.5+1" 313 | quiver: 314 | dependency: transitive 315 | description: 316 | name: quiver 317 | url: "https://pub.dartlang.org" 318 | source: hosted 319 | version: "2.1.3" 320 | rxdart: 321 | dependency: transitive 322 | description: 323 | name: rxdart 324 | url: "https://pub.dartlang.org" 325 | source: hosted 326 | version: "0.24.0" 327 | sky_engine: 328 | dependency: transitive 329 | description: flutter 330 | source: sdk 331 | version: "0.0.99" 332 | source_span: 333 | dependency: transitive 334 | description: 335 | name: source_span 336 | url: "https://pub.dartlang.org" 337 | source: hosted 338 | version: "1.7.0" 339 | sqflite: 340 | dependency: transitive 341 | description: 342 | name: sqflite 343 | url: "https://pub.dartlang.org" 344 | source: hosted 345 | version: "1.3.0+1" 346 | sqflite_common: 347 | dependency: transitive 348 | description: 349 | name: sqflite_common 350 | url: "https://pub.dartlang.org" 351 | source: hosted 352 | version: "1.0.1" 353 | stack_trace: 354 | dependency: transitive 355 | description: 356 | name: stack_trace 357 | url: "https://pub.dartlang.org" 358 | source: hosted 359 | version: "1.9.3" 360 | stream_channel: 361 | dependency: transitive 362 | description: 363 | name: stream_channel 364 | url: "https://pub.dartlang.org" 365 | source: hosted 366 | version: "2.0.0" 367 | string_scanner: 368 | dependency: transitive 369 | description: 370 | name: string_scanner 371 | url: "https://pub.dartlang.org" 372 | source: hosted 373 | version: "1.0.5" 374 | synchronized: 375 | dependency: transitive 376 | description: 377 | name: synchronized 378 | url: "https://pub.dartlang.org" 379 | source: hosted 380 | version: "2.2.0" 381 | term_glyph: 382 | dependency: transitive 383 | description: 384 | name: term_glyph 385 | url: "https://pub.dartlang.org" 386 | source: hosted 387 | version: "1.1.0" 388 | test_api: 389 | dependency: transitive 390 | description: 391 | name: test_api 392 | url: "https://pub.dartlang.org" 393 | source: hosted 394 | version: "0.2.15" 395 | typed_data: 396 | dependency: transitive 397 | description: 398 | name: typed_data 399 | url: "https://pub.dartlang.org" 400 | source: hosted 401 | version: "1.1.6" 402 | uuid: 403 | dependency: transitive 404 | description: 405 | name: uuid 406 | url: "https://pub.dartlang.org" 407 | source: hosted 408 | version: "2.0.4" 409 | vector_math: 410 | dependency: transitive 411 | description: 412 | name: vector_math 413 | url: "https://pub.dartlang.org" 414 | source: hosted 415 | version: "2.0.8" 416 | video_compress: 417 | dependency: transitive 418 | description: 419 | name: video_compress 420 | url: "https://pub.dartlang.org" 421 | source: hosted 422 | version: "2.0.0" 423 | video_player: 424 | dependency: transitive 425 | description: 426 | name: video_player 427 | url: "https://pub.dartlang.org" 428 | source: hosted 429 | version: "0.10.11" 430 | video_player_platform_interface: 431 | dependency: transitive 432 | description: 433 | name: video_player_platform_interface 434 | url: "https://pub.dartlang.org" 435 | source: hosted 436 | version: "2.0.2" 437 | video_player_web: 438 | dependency: transitive 439 | description: 440 | name: video_player_web 441 | url: "https://pub.dartlang.org" 442 | source: hosted 443 | version: "0.1.3" 444 | xml: 445 | dependency: transitive 446 | description: 447 | name: xml 448 | url: "https://pub.dartlang.org" 449 | source: hosted 450 | version: "3.6.1" 451 | sdks: 452 | dart: ">=2.7.0 <3.0.0" 453 | flutter: ">=1.12.13+hotfix.5 <2.0.0" 454 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:typed_data'; 3 | 4 | import 'package:flutter/cupertino.dart'; 5 | import 'package:flutter/material.dart'; 6 | 7 | import 'package:input_sheet/components/IpsCard.dart'; 8 | import 'package:input_sheet/components/IpsError.dart'; 9 | import 'package:input_sheet/components/IpsIcon.dart'; 10 | import 'package:input_sheet/components/IpsLabel.dart'; 11 | import 'package:input_sheet/components/IpsPhoto.dart'; 12 | import 'package:input_sheet/components/IpsVideo.dart'; 13 | import 'package:input_sheet/components/IpsValue.dart'; 14 | import 'package:input_sheet/input_sheet.dart'; 15 | 16 | import 'package:flutter_feather_icons/flutter_feather_icons.dart'; 17 | import 'package:input_sheet/utils/colors.dart'; 18 | 19 | import 'utils/formatter.dart'; 20 | 21 | 22 | 23 | void main() => runApp(MyApp()); 24 | 25 | class MyApp extends StatelessWidget { 26 | @override 27 | Widget build(BuildContext context) { 28 | return MaterialApp( 29 | title: 'Input Sheet Demo', 30 | theme: ThemeData( 31 | primarySwatch: IpsColors.dark, 32 | ), 33 | home: MyHomePage(title: 'Input Sheet Demo'), 34 | ); 35 | } 36 | } 37 | 38 | class MyHomePage extends StatefulWidget { 39 | MyHomePage({Key key, this.title}) : super(key: key); 40 | 41 | final String title; 42 | 43 | @override 44 | _MyHomePageState createState() => _MyHomePageState(); 45 | } 46 | 47 | class _MyHomePageState extends State { 48 | String _name; 49 | String _about; 50 | String _phone; 51 | double _currency; 52 | String _flavor; 53 | List _selectedCategories; 54 | String _birth; 55 | String _dinner; 56 | String _appointment; 57 | File _photo; 58 | File _video; 59 | Uint8List _thumbnailVideo; 60 | 61 | Map _errors = new Map(); 62 | 63 | Map _flavors = { 64 | "0": "Chocolate", 65 | "1": "Vanilla", 66 | "2": "Strawberry", 67 | }; 68 | 69 | Map _categories = { 70 | "comedy" : "Comedy", 71 | "romance" : "Romance", 72 | "horror" : "Horror", 73 | "action" : "Action", 74 | "adventure" : "Adventure", 75 | "dramaturgy": "Dramaturgy", 76 | }; 77 | 78 | String get _selectedCategoriesLabel { 79 | List selecteds = (_selectedCategories??[]).map((value) => _categories[value]).toList(); 80 | return selecteds.length == 0 ? "Touch to select..." : selecteds.join(", "); 81 | } 82 | 83 | @override 84 | Widget build(BuildContext context) { 85 | return Scaffold( 86 | appBar: AppBar( 87 | title: Text(widget.title), 88 | ), 89 | body: SingleChildScrollView( 90 | child: Padding( 91 | padding: EdgeInsets.all(25), 92 | child: Column( 93 | crossAxisAlignment: CrossAxisAlignment.start, 94 | children: [ 95 | Text( 96 | 'Text example:', 97 | ), 98 | SizedBox(height: 15), 99 | IpsCard( 100 | label: IpsLabel("Name"), 101 | value: IpsValue(_name ?? "Touch to edit..."), 102 | icon: IpsIcon(FeatherIcons.user), 103 | error: IpsError(_errors['_name']), 104 | onClick: () => InputSheet( 105 | context, 106 | label: "Name", 107 | cancelText: "Cancel", 108 | doneText: "Confirm", 109 | ).text( 110 | placeholder: "Type here...", 111 | value: _name, 112 | onDone: (dynamic value) => setState(() { 113 | _name = value; 114 | }), 115 | ), 116 | ), 117 | SizedBox(height: 25), 118 | Text( 119 | 'Long text example:', 120 | ), 121 | SizedBox(height: 15), 122 | IpsCard( 123 | label: IpsLabel("Describe about you"), 124 | value: IpsValue(_about ?? "Touch to edit..."), 125 | icon: IpsIcon(FeatherIcons.fileText), 126 | error: IpsError(_errors['_about']), 127 | onClick: () => InputSheet( 128 | context, 129 | label: "About you", 130 | cancelText: "Cancel", 131 | doneText: "Confirm", 132 | ).longtext( 133 | placeholder: "Type here...", 134 | value: _about, 135 | onDone: (dynamic value) => setState(() { 136 | _about = value; 137 | }), 138 | ), 139 | ), 140 | SizedBox(height: 25), 141 | Text( 142 | 'Mask example:', 143 | ), 144 | SizedBox(height: 15), 145 | IpsCard( 146 | label: IpsLabel("Phone"), 147 | value: IpsValue(_phone ?? "Touch to edit..."), 148 | icon: IpsIcon(FeatherIcons.phone), 149 | error: IpsError(_errors['_phone']), 150 | onClick: () => InputSheet( 151 | context, 152 | label: "Phone", 153 | cancelText: "Cancel", 154 | doneText: "Confirm", 155 | ).mask( 156 | textInputType: TextInputType.number, 157 | placeholder: "Type here...", 158 | masks: ["(00) 0000-0000", "(00) 0 0000-0000"], 159 | value: _phone, 160 | onDone: (dynamic value) => setState(() { 161 | _phone = value; 162 | }), 163 | ), 164 | ), 165 | SizedBox(height: 25), 166 | Text( 167 | 'Number example:', 168 | ), 169 | SizedBox(height: 15), 170 | IpsCard( 171 | label: IpsLabel("Set your salary"), 172 | value: IpsValue(_currency == null 173 | ? "Touch to edit..." 174 | : Formatters.formatUS(_currency).symbolOnLeft), 175 | icon: IpsIcon(FeatherIcons.dollarSign), 176 | error: IpsError(_errors['_currency']), 177 | onClick: () => InputSheet( 178 | context, 179 | label: "Set your salary", 180 | cancelText: "Cancel", 181 | doneText: "Confirm", 182 | ).number( 183 | leftSymbol: "my salary is: ", 184 | rightSymbol: " U\$", 185 | decimalSeparator: ".", 186 | thousandSeparator: ",", 187 | precision: 2, 188 | placeholder: "Type here...", 189 | value: _currency ?? 0, 190 | onDone: (double value) => setState(() { 191 | _currency = value; 192 | }), 193 | ), 194 | ), 195 | SizedBox(height: 25), 196 | Text( 197 | 'Options example:', 198 | ), 199 | SizedBox(height: 15), 200 | IpsCard( 201 | label: IpsLabel("Your preferred flavor"), 202 | value: IpsValue(_flavors.containsKey(_flavor) 203 | ? _flavors[_flavor] 204 | : "Touch to select..."), 205 | icon: IpsIcon(FeatherIcons.menu), 206 | error: IpsError(_errors['_currency']), 207 | onClick: () => InputSheet( 208 | context, 209 | label: "Choose a flavor", 210 | cancelText: "Cancel", 211 | doneText: "Confirm", 212 | ).options( 213 | value: _flavor, 214 | options: _flavors, 215 | onDone: (String value) => setState(() { 216 | _flavor = value; 217 | }), 218 | ), 219 | ), 220 | SizedBox(height: 25), 221 | Text( 222 | 'Multiple Options example:', 223 | ), 224 | SizedBox(height: 15), 225 | IpsCard( 226 | label: IpsLabel("Movie categories you like"), 227 | value: IpsValue(_selectedCategoriesLabel), 228 | icon: IpsIcon(FeatherIcons.menu), 229 | error: IpsError(_errors['_currency']), 230 | onClick: () => InputSheet( 231 | context, 232 | label: "Choose many categories", 233 | cancelText: "Cancel", 234 | doneText: "Confirm", 235 | ).multioptions( 236 | value: _selectedCategories, 237 | options: _categories, 238 | onDone: (List value) => setState(() { 239 | _selectedCategories = value; 240 | }), 241 | ), 242 | ), 243 | SizedBox(height: 25), 244 | Text( 245 | 'Date example:', 246 | ), 247 | SizedBox(height: 15), 248 | IpsCard( 249 | label: IpsLabel("Your birth date"), 250 | value: IpsValue(_birth ?? "Touch to select..."), 251 | icon: IpsIcon(FeatherIcons.calendar), 252 | error: IpsError(_errors['_birth']), 253 | onClick: () => InputSheet( 254 | context, 255 | label: "Select a date", 256 | cancelText: "Cancel", 257 | doneText: "Confirm", 258 | ).date( 259 | value: _birth, 260 | minDateTime: 261 | DateTime.now().subtract(Duration(days: 365 * 100)), 262 | maxDateTime: DateTime.now(), 263 | format: "yyyy/MM/dd", 264 | pickerFormat: "yyyy|MMMM|dd", 265 | onDone: (String value) => setState(() { 266 | _birth = value; 267 | }), 268 | ), 269 | ), 270 | SizedBox(height: 25), 271 | Text( 272 | 'Time example:', 273 | ), 274 | SizedBox(height: 15), 275 | IpsCard( 276 | label: IpsLabel("Your dinner time"), 277 | value: IpsValue(_dinner ?? "Touch to select..."), 278 | icon: IpsIcon(FeatherIcons.clock), 279 | error: IpsError(_errors['_dinner']), 280 | onClick: () => InputSheet( 281 | context, 282 | label: "Select a time", 283 | cancelText: "Cancel", 284 | doneText: "Confirm", 285 | ).time( 286 | value: _dinner, 287 | format: "HH:mm", 288 | pickerFormat: "HH|mm", 289 | minuteDivider: 10, 290 | onDone: (String value) => setState(() { 291 | _dinner = value; 292 | }), 293 | ), 294 | ), 295 | SizedBox(height: 25), 296 | Text( 297 | 'Date and Time example:', 298 | ), 299 | SizedBox(height: 15), 300 | IpsCard( 301 | label: IpsLabel("Schedule an appointment"), 302 | value: IpsValue(_appointment ?? "Touch to select..."), 303 | icon: IpsIcon(FeatherIcons.calendar), 304 | error: IpsError(_errors['_appointment']), 305 | onClick: () => InputSheet( 306 | context, 307 | label: "Set your appointment", 308 | cancelText: "Cancel", 309 | doneText: "Confirm", 310 | ).datetime( 311 | value: _appointment, 312 | minDateTime: DateTime.now(), 313 | maxDateTime: DateTime.now().add(Duration(days: 7)), 314 | format: "yyyy/MM/dd HH:mm", 315 | pickerFormat: "yyyy/MM/dd|HH|mm", 316 | minuteDivider: 5, 317 | onDone: (String value) => setState(() { 318 | _appointment = value; 319 | }), 320 | ), 321 | ), 322 | SizedBox(height: 25), 323 | Text( 324 | 'Media example:', 325 | ), 326 | SizedBox(height: 15), 327 | Row( 328 | children: [ 329 | Expanded( 330 | child: IpsPhoto( 331 | file: _photo, 332 | onClick: () => InputSheet( 333 | context, 334 | cancelText: "Cancel", 335 | doneText: "Confirm", 336 | ).photo( 337 | file: _photo, 338 | onDone: (File file, Uint8List thumbnail) => 339 | setState(() { 340 | _photo = file; 341 | }), 342 | ), 343 | ), 344 | ), 345 | Expanded( 346 | child: IpsVideo( 347 | thumbnail: _thumbnailVideo, 348 | onClick: () => InputSheet( 349 | context, 350 | cancelText: "Cancel", 351 | doneText: "Confirm", 352 | ).video( 353 | file: _video, 354 | onDone: (File file, Uint8List thumbnail) => 355 | setState(() { 356 | _video = file; 357 | _thumbnailVideo = thumbnail; 358 | }), 359 | ), 360 | ), 361 | ), 362 | ], 363 | ) 364 | ], 365 | ), 366 | ), 367 | ), 368 | ); 369 | } 370 | } 371 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | _fe_analyzer_shared: 5 | dependency: transitive 6 | description: 7 | name: _fe_analyzer_shared 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "4.0.0" 11 | after_layout: 12 | dependency: "direct main" 13 | description: 14 | name: after_layout 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "1.0.7+2" 18 | analyzer: 19 | dependency: transitive 20 | description: 21 | name: analyzer 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "0.39.10" 25 | archive: 26 | dependency: transitive 27 | description: 28 | name: archive 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "2.0.13" 32 | args: 33 | dependency: transitive 34 | description: 35 | name: args 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "1.6.0" 39 | async: 40 | dependency: transitive 41 | description: 42 | name: async 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "2.4.1" 46 | boolean_selector: 47 | dependency: transitive 48 | description: 49 | name: boolean_selector 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "2.0.0" 53 | build: 54 | dependency: transitive 55 | description: 56 | name: build 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "1.3.0" 60 | build_config: 61 | dependency: transitive 62 | description: 63 | name: build_config 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "0.4.2" 67 | build_daemon: 68 | dependency: transitive 69 | description: 70 | name: build_daemon 71 | url: "https://pub.dartlang.org" 72 | source: hosted 73 | version: "2.1.4" 74 | build_resolvers: 75 | dependency: transitive 76 | description: 77 | name: build_resolvers 78 | url: "https://pub.dartlang.org" 79 | source: hosted 80 | version: "1.3.9" 81 | build_runner: 82 | dependency: "direct dev" 83 | description: 84 | name: build_runner 85 | url: "https://pub.dartlang.org" 86 | source: hosted 87 | version: "1.10.0" 88 | build_runner_core: 89 | dependency: transitive 90 | description: 91 | name: build_runner_core 92 | url: "https://pub.dartlang.org" 93 | source: hosted 94 | version: "5.2.0" 95 | built_collection: 96 | dependency: transitive 97 | description: 98 | name: built_collection 99 | url: "https://pub.dartlang.org" 100 | source: hosted 101 | version: "4.3.2" 102 | built_value: 103 | dependency: transitive 104 | description: 105 | name: built_value 106 | url: "https://pub.dartlang.org" 107 | source: hosted 108 | version: "7.1.0" 109 | cached_network_image: 110 | dependency: "direct main" 111 | description: 112 | name: cached_network_image 113 | url: "https://pub.dartlang.org" 114 | source: hosted 115 | version: "2.2.0+1" 116 | camera: 117 | dependency: "direct main" 118 | description: 119 | name: camera 120 | url: "https://pub.dartlang.org" 121 | source: hosted 122 | version: "0.5.8+1" 123 | charcode: 124 | dependency: transitive 125 | description: 126 | name: charcode 127 | url: "https://pub.dartlang.org" 128 | source: hosted 129 | version: "1.1.3" 130 | checked_yaml: 131 | dependency: transitive 132 | description: 133 | name: checked_yaml 134 | url: "https://pub.dartlang.org" 135 | source: hosted 136 | version: "1.0.2" 137 | clock: 138 | dependency: transitive 139 | description: 140 | name: clock 141 | url: "https://pub.dartlang.org" 142 | source: hosted 143 | version: "1.0.1" 144 | code_builder: 145 | dependency: transitive 146 | description: 147 | name: code_builder 148 | url: "https://pub.dartlang.org" 149 | source: hosted 150 | version: "3.3.0" 151 | collection: 152 | dependency: transitive 153 | description: 154 | name: collection 155 | url: "https://pub.dartlang.org" 156 | source: hosted 157 | version: "1.14.12" 158 | convert: 159 | dependency: transitive 160 | description: 161 | name: convert 162 | url: "https://pub.dartlang.org" 163 | source: hosted 164 | version: "2.1.1" 165 | crypto: 166 | dependency: transitive 167 | description: 168 | name: crypto 169 | url: "https://pub.dartlang.org" 170 | source: hosted 171 | version: "2.1.4" 172 | csslib: 173 | dependency: transitive 174 | description: 175 | name: csslib 176 | url: "https://pub.dartlang.org" 177 | source: hosted 178 | version: "0.16.1" 179 | dart_style: 180 | dependency: transitive 181 | description: 182 | name: dart_style 183 | url: "https://pub.dartlang.org" 184 | source: hosted 185 | version: "1.3.6" 186 | file: 187 | dependency: transitive 188 | description: 189 | name: file 190 | url: "https://pub.dartlang.org" 191 | source: hosted 192 | version: "5.1.0" 193 | fixnum: 194 | dependency: transitive 195 | description: 196 | name: fixnum 197 | url: "https://pub.dartlang.org" 198 | source: hosted 199 | version: "0.10.11" 200 | flutter: 201 | dependency: "direct main" 202 | description: flutter 203 | source: sdk 204 | version: "0.0.0" 205 | flutter_cache_manager: 206 | dependency: transitive 207 | description: 208 | name: flutter_cache_manager 209 | url: "https://pub.dartlang.org" 210 | source: hosted 211 | version: "1.2.2" 212 | flutter_cupertino_date_picker: 213 | dependency: "direct main" 214 | description: 215 | name: flutter_cupertino_date_picker 216 | url: "https://pub.dartlang.org" 217 | source: hosted 218 | version: "1.0.24" 219 | flutter_feather_icons: 220 | dependency: "direct main" 221 | description: 222 | name: flutter_feather_icons 223 | url: "https://pub.dartlang.org" 224 | source: hosted 225 | version: "1.0.3" 226 | flutter_keyboard_size: 227 | dependency: "direct main" 228 | description: 229 | name: flutter_keyboard_size 230 | url: "https://pub.dartlang.org" 231 | source: hosted 232 | version: "0.1.2+2" 233 | flutter_masked_text: 234 | dependency: "direct main" 235 | description: 236 | name: flutter_masked_text 237 | url: "https://pub.dartlang.org" 238 | source: hosted 239 | version: "0.8.0" 240 | flutter_mobx: 241 | dependency: "direct main" 242 | description: 243 | name: flutter_mobx 244 | url: "https://pub.dartlang.org" 245 | source: hosted 246 | version: "1.1.0" 247 | flutter_test: 248 | dependency: "direct dev" 249 | description: flutter 250 | source: sdk 251 | version: "0.0.0" 252 | flutter_web_plugins: 253 | dependency: transitive 254 | description: flutter 255 | source: sdk 256 | version: "0.0.0" 257 | glob: 258 | dependency: transitive 259 | description: 260 | name: glob 261 | url: "https://pub.dartlang.org" 262 | source: hosted 263 | version: "1.2.0" 264 | graphs: 265 | dependency: transitive 266 | description: 267 | name: graphs 268 | url: "https://pub.dartlang.org" 269 | source: hosted 270 | version: "0.2.0" 271 | html: 272 | dependency: transitive 273 | description: 274 | name: html 275 | url: "https://pub.dartlang.org" 276 | source: hosted 277 | version: "0.14.0+3" 278 | http: 279 | dependency: transitive 280 | description: 281 | name: http 282 | url: "https://pub.dartlang.org" 283 | source: hosted 284 | version: "0.12.1" 285 | http_multi_server: 286 | dependency: transitive 287 | description: 288 | name: http_multi_server 289 | url: "https://pub.dartlang.org" 290 | source: hosted 291 | version: "2.2.0" 292 | http_parser: 293 | dependency: transitive 294 | description: 295 | name: http_parser 296 | url: "https://pub.dartlang.org" 297 | source: hosted 298 | version: "3.1.4" 299 | image: 300 | dependency: transitive 301 | description: 302 | name: image 303 | url: "https://pub.dartlang.org" 304 | source: hosted 305 | version: "2.1.12" 306 | intl: 307 | dependency: "direct main" 308 | description: 309 | name: intl 310 | url: "https://pub.dartlang.org" 311 | source: hosted 312 | version: "0.16.1" 313 | io: 314 | dependency: transitive 315 | description: 316 | name: io 317 | url: "https://pub.dartlang.org" 318 | source: hosted 319 | version: "0.3.4" 320 | js: 321 | dependency: transitive 322 | description: 323 | name: js 324 | url: "https://pub.dartlang.org" 325 | source: hosted 326 | version: "0.6.2" 327 | json_annotation: 328 | dependency: transitive 329 | description: 330 | name: json_annotation 331 | url: "https://pub.dartlang.org" 332 | source: hosted 333 | version: "3.0.1" 334 | keyboard_utils: 335 | dependency: "direct main" 336 | description: 337 | name: keyboard_utils 338 | url: "https://pub.dartlang.org" 339 | source: hosted 340 | version: "1.2.1" 341 | logging: 342 | dependency: transitive 343 | description: 344 | name: logging 345 | url: "https://pub.dartlang.org" 346 | source: hosted 347 | version: "0.11.4" 348 | matcher: 349 | dependency: transitive 350 | description: 351 | name: matcher 352 | url: "https://pub.dartlang.org" 353 | source: hosted 354 | version: "0.12.6" 355 | meta: 356 | dependency: transitive 357 | description: 358 | name: meta 359 | url: "https://pub.dartlang.org" 360 | source: hosted 361 | version: "1.1.8" 362 | mime: 363 | dependency: transitive 364 | description: 365 | name: mime 366 | url: "https://pub.dartlang.org" 367 | source: hosted 368 | version: "0.9.6+3" 369 | mobx: 370 | dependency: "direct main" 371 | description: 372 | name: mobx 373 | url: "https://pub.dartlang.org" 374 | source: hosted 375 | version: "1.2.1" 376 | mobx_codegen: 377 | dependency: "direct dev" 378 | description: 379 | name: mobx_codegen 380 | url: "https://pub.dartlang.org" 381 | source: hosted 382 | version: "1.1.0" 383 | nested: 384 | dependency: transitive 385 | description: 386 | name: nested 387 | url: "https://pub.dartlang.org" 388 | source: hosted 389 | version: "0.0.4" 390 | node_interop: 391 | dependency: transitive 392 | description: 393 | name: node_interop 394 | url: "https://pub.dartlang.org" 395 | source: hosted 396 | version: "1.1.1" 397 | node_io: 398 | dependency: transitive 399 | description: 400 | name: node_io 401 | url: "https://pub.dartlang.org" 402 | source: hosted 403 | version: "1.1.1" 404 | package_config: 405 | dependency: transitive 406 | description: 407 | name: package_config 408 | url: "https://pub.dartlang.org" 409 | source: hosted 410 | version: "1.9.3" 411 | path: 412 | dependency: transitive 413 | description: 414 | name: path 415 | url: "https://pub.dartlang.org" 416 | source: hosted 417 | version: "1.6.4" 418 | path_provider: 419 | dependency: "direct main" 420 | description: 421 | name: path_provider 422 | url: "https://pub.dartlang.org" 423 | source: hosted 424 | version: "1.6.8" 425 | path_provider_macos: 426 | dependency: transitive 427 | description: 428 | name: path_provider_macos 429 | url: "https://pub.dartlang.org" 430 | source: hosted 431 | version: "0.0.4+2" 432 | path_provider_platform_interface: 433 | dependency: transitive 434 | description: 435 | name: path_provider_platform_interface 436 | url: "https://pub.dartlang.org" 437 | source: hosted 438 | version: "1.0.2" 439 | pedantic: 440 | dependency: transitive 441 | description: 442 | name: pedantic 443 | url: "https://pub.dartlang.org" 444 | source: hosted 445 | version: "1.8.0+1" 446 | permission_handler: 447 | dependency: "direct main" 448 | description: 449 | name: permission_handler 450 | url: "https://pub.dartlang.org" 451 | source: hosted 452 | version: "5.0.1+1" 453 | permission_handler_platform_interface: 454 | dependency: transitive 455 | description: 456 | name: permission_handler_platform_interface 457 | url: "https://pub.dartlang.org" 458 | source: hosted 459 | version: "2.0.1" 460 | petitparser: 461 | dependency: transitive 462 | description: 463 | name: petitparser 464 | url: "https://pub.dartlang.org" 465 | source: hosted 466 | version: "2.4.0" 467 | platform: 468 | dependency: transitive 469 | description: 470 | name: platform 471 | url: "https://pub.dartlang.org" 472 | source: hosted 473 | version: "2.2.1" 474 | plugin_platform_interface: 475 | dependency: transitive 476 | description: 477 | name: plugin_platform_interface 478 | url: "https://pub.dartlang.org" 479 | source: hosted 480 | version: "1.0.2" 481 | pool: 482 | dependency: transitive 483 | description: 484 | name: pool 485 | url: "https://pub.dartlang.org" 486 | source: hosted 487 | version: "1.4.0" 488 | provider: 489 | dependency: transitive 490 | description: 491 | name: provider 492 | url: "https://pub.dartlang.org" 493 | source: hosted 494 | version: "4.0.5+1" 495 | pub_semver: 496 | dependency: transitive 497 | description: 498 | name: pub_semver 499 | url: "https://pub.dartlang.org" 500 | source: hosted 501 | version: "1.4.4" 502 | pubspec_parse: 503 | dependency: transitive 504 | description: 505 | name: pubspec_parse 506 | url: "https://pub.dartlang.org" 507 | source: hosted 508 | version: "0.1.5" 509 | quiver: 510 | dependency: "direct main" 511 | description: 512 | name: quiver 513 | url: "https://pub.dartlang.org" 514 | source: hosted 515 | version: "2.1.3" 516 | rxdart: 517 | dependency: transitive 518 | description: 519 | name: rxdart 520 | url: "https://pub.dartlang.org" 521 | source: hosted 522 | version: "0.24.0" 523 | shelf: 524 | dependency: transitive 525 | description: 526 | name: shelf 527 | url: "https://pub.dartlang.org" 528 | source: hosted 529 | version: "0.7.5" 530 | shelf_web_socket: 531 | dependency: transitive 532 | description: 533 | name: shelf_web_socket 534 | url: "https://pub.dartlang.org" 535 | source: hosted 536 | version: "0.2.3" 537 | sky_engine: 538 | dependency: transitive 539 | description: flutter 540 | source: sdk 541 | version: "0.0.99" 542 | source_gen: 543 | dependency: transitive 544 | description: 545 | name: source_gen 546 | url: "https://pub.dartlang.org" 547 | source: hosted 548 | version: "0.9.5" 549 | source_span: 550 | dependency: transitive 551 | description: 552 | name: source_span 553 | url: "https://pub.dartlang.org" 554 | source: hosted 555 | version: "1.7.0" 556 | sqflite: 557 | dependency: transitive 558 | description: 559 | name: sqflite 560 | url: "https://pub.dartlang.org" 561 | source: hosted 562 | version: "1.3.0+1" 563 | sqflite_common: 564 | dependency: transitive 565 | description: 566 | name: sqflite_common 567 | url: "https://pub.dartlang.org" 568 | source: hosted 569 | version: "1.0.1" 570 | stack_trace: 571 | dependency: transitive 572 | description: 573 | name: stack_trace 574 | url: "https://pub.dartlang.org" 575 | source: hosted 576 | version: "1.9.3" 577 | stream_channel: 578 | dependency: transitive 579 | description: 580 | name: stream_channel 581 | url: "https://pub.dartlang.org" 582 | source: hosted 583 | version: "2.0.0" 584 | stream_transform: 585 | dependency: transitive 586 | description: 587 | name: stream_transform 588 | url: "https://pub.dartlang.org" 589 | source: hosted 590 | version: "1.2.0" 591 | string_scanner: 592 | dependency: transitive 593 | description: 594 | name: string_scanner 595 | url: "https://pub.dartlang.org" 596 | source: hosted 597 | version: "1.0.5" 598 | synchronized: 599 | dependency: transitive 600 | description: 601 | name: synchronized 602 | url: "https://pub.dartlang.org" 603 | source: hosted 604 | version: "2.2.0" 605 | term_glyph: 606 | dependency: transitive 607 | description: 608 | name: term_glyph 609 | url: "https://pub.dartlang.org" 610 | source: hosted 611 | version: "1.1.0" 612 | test_api: 613 | dependency: transitive 614 | description: 615 | name: test_api 616 | url: "https://pub.dartlang.org" 617 | source: hosted 618 | version: "0.2.15" 619 | timing: 620 | dependency: transitive 621 | description: 622 | name: timing 623 | url: "https://pub.dartlang.org" 624 | source: hosted 625 | version: "0.1.1+2" 626 | typed_data: 627 | dependency: transitive 628 | description: 629 | name: typed_data 630 | url: "https://pub.dartlang.org" 631 | source: hosted 632 | version: "1.1.6" 633 | uuid: 634 | dependency: "direct main" 635 | description: 636 | name: uuid 637 | url: "https://pub.dartlang.org" 638 | source: hosted 639 | version: "2.0.4" 640 | vector_math: 641 | dependency: transitive 642 | description: 643 | name: vector_math 644 | url: "https://pub.dartlang.org" 645 | source: hosted 646 | version: "2.0.8" 647 | video_compress: 648 | dependency: "direct main" 649 | description: 650 | name: video_compress 651 | url: "https://pub.dartlang.org" 652 | source: hosted 653 | version: "2.0.0" 654 | video_player: 655 | dependency: "direct main" 656 | description: 657 | name: video_player 658 | url: "https://pub.dartlang.org" 659 | source: hosted 660 | version: "0.10.11" 661 | video_player_platform_interface: 662 | dependency: transitive 663 | description: 664 | name: video_player_platform_interface 665 | url: "https://pub.dartlang.org" 666 | source: hosted 667 | version: "2.0.2" 668 | video_player_web: 669 | dependency: transitive 670 | description: 671 | name: video_player_web 672 | url: "https://pub.dartlang.org" 673 | source: hosted 674 | version: "0.1.3" 675 | watcher: 676 | dependency: transitive 677 | description: 678 | name: watcher 679 | url: "https://pub.dartlang.org" 680 | source: hosted 681 | version: "0.9.7+15" 682 | web_socket_channel: 683 | dependency: transitive 684 | description: 685 | name: web_socket_channel 686 | url: "https://pub.dartlang.org" 687 | source: hosted 688 | version: "1.1.0" 689 | xml: 690 | dependency: transitive 691 | description: 692 | name: xml 693 | url: "https://pub.dartlang.org" 694 | source: hosted 695 | version: "3.6.1" 696 | yaml: 697 | dependency: transitive 698 | description: 699 | name: yaml 700 | url: "https://pub.dartlang.org" 701 | source: hosted 702 | version: "2.2.1" 703 | sdks: 704 | dart: ">=2.7.0 <3.0.0" 705 | flutter: ">=1.12.13+hotfix.5 <2.0.0" 706 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 13 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 14 | 438719799D2662C7F040ECD9 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7EF1A3360DAA2AE881BF3E4 /* Pods_Runner.framework */; }; 15 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 16 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; 17 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 18 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 19 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 20 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXCopyFilesBuildPhase section */ 24 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 25 | isa = PBXCopyFilesBuildPhase; 26 | buildActionMask = 2147483647; 27 | dstPath = ""; 28 | dstSubfolderSpec = 10; 29 | files = ( 30 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, 31 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, 32 | ); 33 | name = "Embed Frameworks"; 34 | runOnlyForDeploymentPostprocessing = 0; 35 | }; 36 | /* End PBXCopyFilesBuildPhase section */ 37 | 38 | /* Begin PBXFileReference section */ 39 | 0B762D0203C8453CEE7ECD56 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 40 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 41 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 42 | 2B06F30D3C0F59B51B39AD78 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 43 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 44 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 45 | 693E90E192DBEE6A8AB67B37 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 46 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 47 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 48 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 49 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 50 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 51 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 52 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 54 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 55 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 56 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57 | F7EF1A3360DAA2AE881BF3E4 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | /* End PBXFileReference section */ 59 | 60 | /* Begin PBXFrameworksBuildPhase section */ 61 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 62 | isa = PBXFrameworksBuildPhase; 63 | buildActionMask = 2147483647; 64 | files = ( 65 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, 66 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, 67 | 438719799D2662C7F040ECD9 /* Pods_Runner.framework in Frameworks */, 68 | ); 69 | runOnlyForDeploymentPostprocessing = 0; 70 | }; 71 | /* End PBXFrameworksBuildPhase section */ 72 | 73 | /* Begin PBXGroup section */ 74 | 9740EEB11CF90186004384FC /* Flutter */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | 3B80C3931E831B6300D905FE /* App.framework */, 78 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 79 | 9740EEBA1CF902C7004384FC /* Flutter.framework */, 80 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 81 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 82 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 83 | ); 84 | name = Flutter; 85 | sourceTree = ""; 86 | }; 87 | 97C146E51CF9000F007C117D = { 88 | isa = PBXGroup; 89 | children = ( 90 | 9740EEB11CF90186004384FC /* Flutter */, 91 | 97C146F01CF9000F007C117D /* Runner */, 92 | 97C146EF1CF9000F007C117D /* Products */, 93 | D84BE0F3CA99B16FE9273DE8 /* Pods */, 94 | FA48E7CC1A871E1EAA84314E /* Frameworks */, 95 | ); 96 | sourceTree = ""; 97 | }; 98 | 97C146EF1CF9000F007C117D /* Products */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 97C146EE1CF9000F007C117D /* Runner.app */, 102 | ); 103 | name = Products; 104 | sourceTree = ""; 105 | }; 106 | 97C146F01CF9000F007C117D /* Runner */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 110 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 111 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 112 | 97C147021CF9000F007C117D /* Info.plist */, 113 | 97C146F11CF9000F007C117D /* Supporting Files */, 114 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 115 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 116 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 117 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 118 | ); 119 | path = Runner; 120 | sourceTree = ""; 121 | }; 122 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | ); 126 | name = "Supporting Files"; 127 | sourceTree = ""; 128 | }; 129 | D84BE0F3CA99B16FE9273DE8 /* Pods */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | 693E90E192DBEE6A8AB67B37 /* Pods-Runner.debug.xcconfig */, 133 | 2B06F30D3C0F59B51B39AD78 /* Pods-Runner.release.xcconfig */, 134 | 0B762D0203C8453CEE7ECD56 /* Pods-Runner.profile.xcconfig */, 135 | ); 136 | name = Pods; 137 | path = Pods; 138 | sourceTree = ""; 139 | }; 140 | FA48E7CC1A871E1EAA84314E /* Frameworks */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | F7EF1A3360DAA2AE881BF3E4 /* Pods_Runner.framework */, 144 | ); 145 | name = Frameworks; 146 | sourceTree = ""; 147 | }; 148 | /* End PBXGroup section */ 149 | 150 | /* Begin PBXNativeTarget section */ 151 | 97C146ED1CF9000F007C117D /* Runner */ = { 152 | isa = PBXNativeTarget; 153 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 154 | buildPhases = ( 155 | 0DCE464DBA2049373ECF0E0D /* [CP] Check Pods Manifest.lock */, 156 | 9740EEB61CF901F6004384FC /* Run Script */, 157 | 97C146EA1CF9000F007C117D /* Sources */, 158 | 97C146EB1CF9000F007C117D /* Frameworks */, 159 | 97C146EC1CF9000F007C117D /* Resources */, 160 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 161 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 162 | 4FE6461CC868D82637596FC2 /* [CP] Embed Pods Frameworks */, 163 | ); 164 | buildRules = ( 165 | ); 166 | dependencies = ( 167 | ); 168 | name = Runner; 169 | productName = Runner; 170 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 171 | productType = "com.apple.product-type.application"; 172 | }; 173 | /* End PBXNativeTarget section */ 174 | 175 | /* Begin PBXProject section */ 176 | 97C146E61CF9000F007C117D /* Project object */ = { 177 | isa = PBXProject; 178 | attributes = { 179 | LastUpgradeCheck = 1020; 180 | ORGANIZATIONNAME = "The Chromium Authors"; 181 | TargetAttributes = { 182 | 97C146ED1CF9000F007C117D = { 183 | CreatedOnToolsVersion = 7.3.1; 184 | LastSwiftMigration = 1100; 185 | }; 186 | }; 187 | }; 188 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 189 | compatibilityVersion = "Xcode 3.2"; 190 | developmentRegion = en; 191 | hasScannedForEncodings = 0; 192 | knownRegions = ( 193 | en, 194 | Base, 195 | ); 196 | mainGroup = 97C146E51CF9000F007C117D; 197 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 198 | projectDirPath = ""; 199 | projectRoot = ""; 200 | targets = ( 201 | 97C146ED1CF9000F007C117D /* Runner */, 202 | ); 203 | }; 204 | /* End PBXProject section */ 205 | 206 | /* Begin PBXResourcesBuildPhase section */ 207 | 97C146EC1CF9000F007C117D /* Resources */ = { 208 | isa = PBXResourcesBuildPhase; 209 | buildActionMask = 2147483647; 210 | files = ( 211 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 212 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 213 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 214 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 215 | ); 216 | runOnlyForDeploymentPostprocessing = 0; 217 | }; 218 | /* End PBXResourcesBuildPhase section */ 219 | 220 | /* Begin PBXShellScriptBuildPhase section */ 221 | 0DCE464DBA2049373ECF0E0D /* [CP] Check Pods Manifest.lock */ = { 222 | isa = PBXShellScriptBuildPhase; 223 | buildActionMask = 2147483647; 224 | files = ( 225 | ); 226 | inputFileListPaths = ( 227 | ); 228 | inputPaths = ( 229 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 230 | "${PODS_ROOT}/Manifest.lock", 231 | ); 232 | name = "[CP] Check Pods Manifest.lock"; 233 | outputFileListPaths = ( 234 | ); 235 | outputPaths = ( 236 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 237 | ); 238 | runOnlyForDeploymentPostprocessing = 0; 239 | shellPath = /bin/sh; 240 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 241 | showEnvVarsInLog = 0; 242 | }; 243 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 244 | isa = PBXShellScriptBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | ); 248 | inputPaths = ( 249 | ); 250 | name = "Thin Binary"; 251 | outputPaths = ( 252 | ); 253 | runOnlyForDeploymentPostprocessing = 0; 254 | shellPath = /bin/sh; 255 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; 256 | }; 257 | 4FE6461CC868D82637596FC2 /* [CP] Embed Pods Frameworks */ = { 258 | isa = PBXShellScriptBuildPhase; 259 | buildActionMask = 2147483647; 260 | files = ( 261 | ); 262 | inputPaths = ( 263 | ); 264 | name = "[CP] Embed Pods Frameworks"; 265 | outputPaths = ( 266 | ); 267 | runOnlyForDeploymentPostprocessing = 0; 268 | shellPath = /bin/sh; 269 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 270 | showEnvVarsInLog = 0; 271 | }; 272 | 9740EEB61CF901F6004384FC /* Run Script */ = { 273 | isa = PBXShellScriptBuildPhase; 274 | buildActionMask = 2147483647; 275 | files = ( 276 | ); 277 | inputPaths = ( 278 | ); 279 | name = "Run Script"; 280 | outputPaths = ( 281 | ); 282 | runOnlyForDeploymentPostprocessing = 0; 283 | shellPath = /bin/sh; 284 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 285 | }; 286 | /* End PBXShellScriptBuildPhase section */ 287 | 288 | /* Begin PBXSourcesBuildPhase section */ 289 | 97C146EA1CF9000F007C117D /* Sources */ = { 290 | isa = PBXSourcesBuildPhase; 291 | buildActionMask = 2147483647; 292 | files = ( 293 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 294 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 295 | ); 296 | runOnlyForDeploymentPostprocessing = 0; 297 | }; 298 | /* End PBXSourcesBuildPhase section */ 299 | 300 | /* Begin PBXVariantGroup section */ 301 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 302 | isa = PBXVariantGroup; 303 | children = ( 304 | 97C146FB1CF9000F007C117D /* Base */, 305 | ); 306 | name = Main.storyboard; 307 | sourceTree = ""; 308 | }; 309 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 310 | isa = PBXVariantGroup; 311 | children = ( 312 | 97C147001CF9000F007C117D /* Base */, 313 | ); 314 | name = LaunchScreen.storyboard; 315 | sourceTree = ""; 316 | }; 317 | /* End PBXVariantGroup section */ 318 | 319 | /* Begin XCBuildConfiguration section */ 320 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 321 | isa = XCBuildConfiguration; 322 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 323 | buildSettings = { 324 | ALWAYS_SEARCH_USER_PATHS = NO; 325 | CLANG_ANALYZER_NONNULL = YES; 326 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 327 | CLANG_CXX_LIBRARY = "libc++"; 328 | CLANG_ENABLE_MODULES = YES; 329 | CLANG_ENABLE_OBJC_ARC = YES; 330 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 331 | CLANG_WARN_BOOL_CONVERSION = YES; 332 | CLANG_WARN_COMMA = YES; 333 | CLANG_WARN_CONSTANT_CONVERSION = YES; 334 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 335 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 336 | CLANG_WARN_EMPTY_BODY = YES; 337 | CLANG_WARN_ENUM_CONVERSION = YES; 338 | CLANG_WARN_INFINITE_RECURSION = YES; 339 | CLANG_WARN_INT_CONVERSION = YES; 340 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 341 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 342 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 343 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 344 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 345 | CLANG_WARN_STRICT_PROTOTYPES = YES; 346 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 347 | CLANG_WARN_UNREACHABLE_CODE = YES; 348 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 349 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 350 | COPY_PHASE_STRIP = NO; 351 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 352 | ENABLE_NS_ASSERTIONS = NO; 353 | ENABLE_STRICT_OBJC_MSGSEND = YES; 354 | GCC_C_LANGUAGE_STANDARD = gnu99; 355 | GCC_NO_COMMON_BLOCKS = YES; 356 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 357 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 358 | GCC_WARN_UNDECLARED_SELECTOR = YES; 359 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 360 | GCC_WARN_UNUSED_FUNCTION = YES; 361 | GCC_WARN_UNUSED_VARIABLE = YES; 362 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 363 | MTL_ENABLE_DEBUG_INFO = NO; 364 | SDKROOT = iphoneos; 365 | SUPPORTED_PLATFORMS = iphoneos; 366 | TARGETED_DEVICE_FAMILY = "1,2"; 367 | VALIDATE_PRODUCT = YES; 368 | }; 369 | name = Profile; 370 | }; 371 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 372 | isa = XCBuildConfiguration; 373 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 374 | buildSettings = { 375 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 376 | CLANG_ENABLE_MODULES = YES; 377 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 378 | ENABLE_BITCODE = NO; 379 | FRAMEWORK_SEARCH_PATHS = ( 380 | "$(inherited)", 381 | "$(PROJECT_DIR)/Flutter", 382 | ); 383 | INFOPLIST_FILE = Runner/Info.plist; 384 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 385 | LIBRARY_SEARCH_PATHS = ( 386 | "$(inherited)", 387 | "$(PROJECT_DIR)/Flutter", 388 | ); 389 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 390 | PRODUCT_NAME = "$(TARGET_NAME)"; 391 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 392 | SWIFT_VERSION = 5.0; 393 | VERSIONING_SYSTEM = "apple-generic"; 394 | }; 395 | name = Profile; 396 | }; 397 | 97C147031CF9000F007C117D /* Debug */ = { 398 | isa = XCBuildConfiguration; 399 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 400 | buildSettings = { 401 | ALWAYS_SEARCH_USER_PATHS = NO; 402 | CLANG_ANALYZER_NONNULL = YES; 403 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 404 | CLANG_CXX_LIBRARY = "libc++"; 405 | CLANG_ENABLE_MODULES = YES; 406 | CLANG_ENABLE_OBJC_ARC = YES; 407 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 408 | CLANG_WARN_BOOL_CONVERSION = YES; 409 | CLANG_WARN_COMMA = YES; 410 | CLANG_WARN_CONSTANT_CONVERSION = YES; 411 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 412 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 413 | CLANG_WARN_EMPTY_BODY = YES; 414 | CLANG_WARN_ENUM_CONVERSION = YES; 415 | CLANG_WARN_INFINITE_RECURSION = YES; 416 | CLANG_WARN_INT_CONVERSION = YES; 417 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 418 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 419 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 420 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 421 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 422 | CLANG_WARN_STRICT_PROTOTYPES = YES; 423 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 424 | CLANG_WARN_UNREACHABLE_CODE = YES; 425 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 426 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 427 | COPY_PHASE_STRIP = NO; 428 | DEBUG_INFORMATION_FORMAT = dwarf; 429 | ENABLE_STRICT_OBJC_MSGSEND = YES; 430 | ENABLE_TESTABILITY = YES; 431 | GCC_C_LANGUAGE_STANDARD = gnu99; 432 | GCC_DYNAMIC_NO_PIC = NO; 433 | GCC_NO_COMMON_BLOCKS = YES; 434 | GCC_OPTIMIZATION_LEVEL = 0; 435 | GCC_PREPROCESSOR_DEFINITIONS = ( 436 | "DEBUG=1", 437 | "$(inherited)", 438 | ); 439 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 440 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 441 | GCC_WARN_UNDECLARED_SELECTOR = YES; 442 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 443 | GCC_WARN_UNUSED_FUNCTION = YES; 444 | GCC_WARN_UNUSED_VARIABLE = YES; 445 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 446 | MTL_ENABLE_DEBUG_INFO = YES; 447 | ONLY_ACTIVE_ARCH = YES; 448 | SDKROOT = iphoneos; 449 | TARGETED_DEVICE_FAMILY = "1,2"; 450 | }; 451 | name = Debug; 452 | }; 453 | 97C147041CF9000F007C117D /* Release */ = { 454 | isa = XCBuildConfiguration; 455 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 456 | buildSettings = { 457 | ALWAYS_SEARCH_USER_PATHS = NO; 458 | CLANG_ANALYZER_NONNULL = YES; 459 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 460 | CLANG_CXX_LIBRARY = "libc++"; 461 | CLANG_ENABLE_MODULES = YES; 462 | CLANG_ENABLE_OBJC_ARC = YES; 463 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 464 | CLANG_WARN_BOOL_CONVERSION = YES; 465 | CLANG_WARN_COMMA = YES; 466 | CLANG_WARN_CONSTANT_CONVERSION = YES; 467 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 468 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 469 | CLANG_WARN_EMPTY_BODY = YES; 470 | CLANG_WARN_ENUM_CONVERSION = YES; 471 | CLANG_WARN_INFINITE_RECURSION = YES; 472 | CLANG_WARN_INT_CONVERSION = YES; 473 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 474 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 475 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 476 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 477 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 478 | CLANG_WARN_STRICT_PROTOTYPES = YES; 479 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 480 | CLANG_WARN_UNREACHABLE_CODE = YES; 481 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 482 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 483 | COPY_PHASE_STRIP = NO; 484 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 485 | ENABLE_NS_ASSERTIONS = NO; 486 | ENABLE_STRICT_OBJC_MSGSEND = YES; 487 | GCC_C_LANGUAGE_STANDARD = gnu99; 488 | GCC_NO_COMMON_BLOCKS = YES; 489 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 490 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 491 | GCC_WARN_UNDECLARED_SELECTOR = YES; 492 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 493 | GCC_WARN_UNUSED_FUNCTION = YES; 494 | GCC_WARN_UNUSED_VARIABLE = YES; 495 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 496 | MTL_ENABLE_DEBUG_INFO = NO; 497 | SDKROOT = iphoneos; 498 | SUPPORTED_PLATFORMS = iphoneos; 499 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 500 | TARGETED_DEVICE_FAMILY = "1,2"; 501 | VALIDATE_PRODUCT = YES; 502 | }; 503 | name = Release; 504 | }; 505 | 97C147061CF9000F007C117D /* Debug */ = { 506 | isa = XCBuildConfiguration; 507 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 508 | buildSettings = { 509 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 510 | CLANG_ENABLE_MODULES = YES; 511 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 512 | ENABLE_BITCODE = NO; 513 | FRAMEWORK_SEARCH_PATHS = ( 514 | "$(inherited)", 515 | "$(PROJECT_DIR)/Flutter", 516 | ); 517 | INFOPLIST_FILE = Runner/Info.plist; 518 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 519 | LIBRARY_SEARCH_PATHS = ( 520 | "$(inherited)", 521 | "$(PROJECT_DIR)/Flutter", 522 | ); 523 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 524 | PRODUCT_NAME = "$(TARGET_NAME)"; 525 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 526 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 527 | SWIFT_VERSION = 5.0; 528 | VERSIONING_SYSTEM = "apple-generic"; 529 | }; 530 | name = Debug; 531 | }; 532 | 97C147071CF9000F007C117D /* Release */ = { 533 | isa = XCBuildConfiguration; 534 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 535 | buildSettings = { 536 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 537 | CLANG_ENABLE_MODULES = YES; 538 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 539 | ENABLE_BITCODE = NO; 540 | FRAMEWORK_SEARCH_PATHS = ( 541 | "$(inherited)", 542 | "$(PROJECT_DIR)/Flutter", 543 | ); 544 | INFOPLIST_FILE = Runner/Info.plist; 545 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 546 | LIBRARY_SEARCH_PATHS = ( 547 | "$(inherited)", 548 | "$(PROJECT_DIR)/Flutter", 549 | ); 550 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 551 | PRODUCT_NAME = "$(TARGET_NAME)"; 552 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 553 | SWIFT_VERSION = 5.0; 554 | VERSIONING_SYSTEM = "apple-generic"; 555 | }; 556 | name = Release; 557 | }; 558 | /* End XCBuildConfiguration section */ 559 | 560 | /* Begin XCConfigurationList section */ 561 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 562 | isa = XCConfigurationList; 563 | buildConfigurations = ( 564 | 97C147031CF9000F007C117D /* Debug */, 565 | 97C147041CF9000F007C117D /* Release */, 566 | 249021D3217E4FDB00AE95B9 /* Profile */, 567 | ); 568 | defaultConfigurationIsVisible = 0; 569 | defaultConfigurationName = Release; 570 | }; 571 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 572 | isa = XCConfigurationList; 573 | buildConfigurations = ( 574 | 97C147061CF9000F007C117D /* Debug */, 575 | 97C147071CF9000F007C117D /* Release */, 576 | 249021D4217E4FDB00AE95B9 /* Profile */, 577 | ); 578 | defaultConfigurationIsVisible = 0; 579 | defaultConfigurationName = Release; 580 | }; 581 | /* End XCConfigurationList section */ 582 | }; 583 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 584 | } 585 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flutter-input-sheet 2 | 3 | [![Pub](https://img.shields.io/pub/v/input_sheet.svg)](https://pub.dev/packages/input_sheet) 4 | [![License: MIT](https://img.shields.io/badge/license-MIT-purple.svg)](LICENSE) 5 | 6 | A pack of input types implemented as a sheet! 🚀 7 | 8 | ![](https://github.com/andreciornavei/images/blob/master/flutter-input-sheet/FlutterInputSheet.gif?raw=true) 9 | 10 | ## Overview 11 | 12 | flutter-input-sheet is a package that shows inputs on sheets. 13 | 14 | It was created with the purpose of make simple and pleasant extensive forms. You can create custom components to present your data and edit them in sheets for each one. 15 | 16 | It was developed by abstracting and implementing great packages in pub.dev to create a single and simple pack for forms. 17 | 18 | ## Installation 19 | 20 | add this line to pubspec.yaml 21 | 22 | ```yaml 23 | input_sheet: 24 | ``` 25 | ### Dependencies 26 | 27 | Also, this package uses some other libraries that need to be imported in your project to work, this libraries is used in some input types that need constants informed at params. 28 | 29 | ```yaml 30 | camera: ^0.5.8+1 31 | video_compress: ^2.0.0 32 | flutter_cupertino_date_picker: ^1.0.12 33 | ``` 34 | 35 | ### IOS 36 | You will need to add permissions in your Info.plist to use camera and microphone once the package has an input for photos and videos 37 | 38 | ```xml 39 | NSCameraUsageDescription 40 | Can I use the camera please? 41 | NSMicrophoneUsageDescription 42 | Can I use the mic please? 43 | ``` 44 | 45 | ### Android 46 | You will need to add permissions in your AndroidManifest.xml to read and write external storage and manage the camera once the package has an input for photos and videos 47 | 48 | ```xml 49 | 50 | 51 | 52 | ``` 53 | 54 | ## ✨ Features 55 | 56 | - [x] Text 57 | - [x] Longtext 58 | - [x] Masked 59 | - [x] Number 60 | - [x] Date 61 | - [x] Time 62 | - [x] DateTime 63 | - [x] Photo 64 | - [x] Video 65 | - [x] MultiOption 66 | - [ ] Slider 67 | - [ ] Color 68 | - [ ] Qrcode 69 | - [ ] Map 70 | 71 | ## ⭐ Basic components 72 | 73 | Was created some basic components to show data information on screen before open the input sheet. 74 | 75 | - IpsCard 76 | 77 | ![](https://github.com/andreciornavei/images/blob/master/flutter-input-sheet/IpsCard.png?raw=true) 78 | 79 | - IpsLabel 80 | 81 | ![](https://github.com/andreciornavei/images/blob/master/flutter-input-sheet/IpsLabel.png?raw=true) 82 | 83 | - IpsError 84 | 85 | ![](https://github.com/andreciornavei/images/blob/master/flutter-input-sheet/IpsError.png?raw=true) 86 | 87 | - IpsIcon 88 | 89 | ![](https://github.com/andreciornavei/images/blob/master/flutter-input-sheet/IpsIcon.png?raw=true) 90 | 91 | - IpsValue 92 | 93 | ![](https://github.com/andreciornavei/images/blob/master/flutter-input-sheet/IpsValue.png?raw=true) 94 | 95 | - IpsPhoto 96 | 97 | ![](https://github.com/andreciornavei/images/blob/master/flutter-input-sheet/IpsPhoto.png?raw=true) 98 | 99 | - IpsVideo 100 | 101 | ![](https://github.com/andreciornavei/images/blob/master/flutter-input-sheet/IpsVideo.png?raw=true) 102 | 103 | 104 | ## Examples 105 | 106 | ### Basic card component: 107 | 108 | This library implements a basic and optional card component to simplify its forms when presenting data. 109 | 110 | ```dart 111 | //Your component to show data 112 | IpsCard( 113 | label: IpsLabel("Name"), 114 | value: IpsValue(_name ?? "Touch to edit..."), 115 | icon: IpsIcon(FeatherIcons.user), 116 | error: IpsError(_errors['name']), 117 | onClick: () { 118 | //Your sheet implementation 119 | }, 120 | ); 121 | ``` 122 | 123 | --- 124 | 125 | ### Basic media component: 126 | 127 | Also for media types, you may want to preview the media, so I created a simple component to show Photo and Video. 128 | 129 | ```dart 130 | //Photo component preview file 131 | IpsPhoto( 132 | file: _photo, 133 | onClick: (){ 134 | //Your sheet implementation 135 | } 136 | ); 137 | 138 | //Video component preview thumbnail 139 | IpsVideo( 140 | thumbnail: _thumbnailVideo, 141 | onClick: (){ 142 | //Your sheet implementation 143 | }, 144 | ); 145 | ``` 146 | 147 | --- 148 | 149 | ### Opening a sheet: 150 | 151 | ```dart 152 | InputSheet( 153 | //InputSheet implements the scope information of sheet 154 | context, 155 | label: "Name", 156 | cancelText: "Cancel", 157 | doneText: "Confirm", 158 | ).text( 159 | //.text or any other option available type implemets the input type 160 | placeholder: "Type here...", 161 | value: _name, 162 | onDone: (dynamic value) => setState(() { 163 | _name = value; 164 | }), 165 | ); 166 | ``` 167 | 168 | --- 169 | 170 | ### Complete simple example: 171 | 172 | ```dart 173 | class _MyHomePageState extends State { 174 | String _name; 175 | @override 176 | Widget build(BuildContext context) { 177 | return Scaffold( 178 | appBar: AppBar( 179 | title: Text(widget.title), 180 | ), 181 | body: SingleChildScrollView( 182 | child: Padding( 183 | padding: EdgeInsets.all(25), 184 | child: IpsCard( 185 | label: IpsLabel("Name"), 186 | value: IpsValue(_name ?? "Touch to edit..."), 187 | icon: IpsIcon(FeatherIcons.user), 188 | error: IpsError(_errors['name']), 189 | onClick: () => InputSheet( 190 | context, 191 | label: "Name", 192 | cancelText: "Cancel", 193 | doneText: "Confirm", 194 | ).text( 195 | placeholder: "Type here...", 196 | value: _name, 197 | onDone: (dynamic value) => setState(() { 198 | _name = value; 199 | }), 200 | ), 201 | ), 202 | ), 203 | ), 204 | ); 205 | } 206 | } 207 | 208 | ``` 209 | 210 | --- 211 | 212 | ## The InputSheet factory 213 | 214 | It will be instanced for each input sheet type you want to invoke, on this Factory you can pass some scope parameters of your sheet. 215 | 216 | ```dart 217 | InputSheet(context, 218 | label: "Your name", 219 | cancelText: "Cancel button", 220 | doneText: "Done button", 221 | keyboardAutofocus: true, 222 | ); 223 | ``` 224 | 225 | | Parameters | Type | Description | 226 | | ----------------- | ------ | ------------------------------------------- | 227 | | label | String | The message showing above input | 228 | | cancelText | String | The cancel button text | 229 | | doneText | String | The confirmation button text | 230 | | keyboardAutofocus | bool | Auto-focus editable inputs after open sheet | 231 | 232 | --- 233 | 234 | ## The input types 235 | 236 | ### **Text** 237 | 238 | _This input implements a simple text input._ 239 | 240 | ```dart 241 | InputSheet(context).text( 242 | textInputType: TextInputType.text, 243 | placeholder: "Type here...", 244 | value: _value, 245 | onDone: (String value) => setState(() { 246 | _value = value; 247 | }), 248 | ); 249 | ``` 250 | 251 | | Parameters | Type | Description | 252 | | ------------- | ---------------- | ----------------------------------------------------- | 253 | | textInputType | TextInputType | The default keyboard input type | 254 | | placeholder | String | Add a placeholder to input | 255 | | value | String | Add a default value to input | 256 | | onDone | Function(String) | Callback function called when done ediding input text | 257 | 258 | --- 259 | 260 | ### **Longtext** 261 | 262 | _This input implements a long text input that break lines and increase the sheet height according the value length._ 263 | 264 | ```dart 265 | InputSheet(context).longtext( 266 | placeholder: "Type here...", 267 | value: _value, 268 | onDone: (String value) => setState(() { 269 | _value = value; 270 | }), 271 | ); 272 | ``` 273 | 274 | | Parameters | Type | Description | 275 | | ----------- | ---------------- | ----------------------------------------------------- | 276 | | placeholder | String | Add a placeholder to input | 277 | | value | String | Add a default value to input | 278 | | onDone | Function(String) | Callback function called when done ediding input text | 279 | 280 | --- 281 | 282 | ### **Mask** 283 | 284 | _This input uses [flutter_masked_text](https://pub.dev/packages/flutter_masked_text) package to manage the mask patterns and switch from pattern to pattern according the value length, see the package to learn about this patterns._ 285 | 286 | ```dart 287 | InputSheet(context).mask( 288 | masks: ['(00) 0000-0000', '(00) 0 0000-0000'], 289 | textInputType: TextInputType.text, 290 | placeholder: "Type here...", 291 | value: _value, 292 | onDone: (String value) => setState(() { 293 | _value = value; 294 | }), 295 | ); 296 | ``` 297 | 298 | | Parameters | Type | Description | 299 | | ------------- | ---------------- | --------------------------------------------------------------------------------- | 300 | | masks | List<\String> | The mask pattern that the input will use according the number of characters value | 301 | | textInputType | TextInputType | The default keyboard input type | 302 | | placeholder | String | Add a placeholder to input | 303 | | value | String | Add a default value to input | 304 | | onDone | Function(String) | Callback function called when done ediding input text | 305 | 306 | --- 307 | 308 | ### **Number** 309 | 310 | _This input uses [flutter_masked_text](https://pub.dev/packages/flutter_masked_text) package to manage symbols and separators, then you can configure it to implement `number` or `currency` inputs._ 311 | 312 | ```dart 313 | InputSheet(context).number( 314 | leftSymbol: "to pay:", 315 | rightSymbol: "U\$", 316 | decimalSeparator: ".", 317 | thousandSeparator: ",", 318 | precision: 2, 319 | placeholder: "Type here...", 320 | value: _value, 321 | onDone: (double value) => setState(() { 322 | _value = value; 323 | }), 324 | ); 325 | ``` 326 | 327 | | Parameters | Type | Description | 328 | | ----------------- | ---------------- | ----------------------------------------------------- | 329 | | leftSymbol | String | Blank default, is used only on input | 330 | | rightSymbol | String | Blank default, is used only on input | 331 | | decimalSeparator | String | Default " . " is used only on input | 332 | | thousandSeparator | String | Default " , " is used only on input | 333 | | precision | int | The number of decimal places | 334 | | placeholder | String | Add a placeholder to input | 335 | | value | String | Add a default value to input | 336 | | onDone | Function(String) | Callback function called when done ediding input text | 337 | 338 | --- 339 | 340 | ### **Date** 341 | 342 | _This input uses [flutter_cupertino_date_picker](https://pub.dev/packages/flutter_cupertino_date_picker) to manage state and formatters on Date picker._ 343 | 344 | ```dart 345 | InputSheet(context).date( 346 | minDateTime: DateTime.now().subtract(Duration(days: 365 * 100)), 347 | maxDateTime: DateTime.now(), 348 | locale: DateTimePickerLocale.en_us, 349 | format: "yyyy-MM-dd", 350 | pickerFormat: "yyyy|MMMM|dd", 351 | value: _value, 352 | onDone: (String value) => setState(() { 353 | _value = value; 354 | }), 355 | ); 356 | ``` 357 | 358 | | Parameters | Type | Description | 359 | | ------------ | -------------------- | -------------------------------------------------------------------------------------------- | 360 | | minDateTime | DateTime | Min date available to select | 361 | | maxDateTime | DateTime | Max date abailable to select | 362 | | locale | DateTimePickerLocale | `locale` is used to translate labels and must to be imported from [flutter_cupertino_date_picker](https://pub.dev/packages/flutter_cupertino_date_picker) package | 363 | | format | String | The format of value inserted in 'value' param | 364 | | pickerFormat | String | Add a placeholder to input | 365 | | value | String | Add a default value to input | 366 | | onDone | Function(String) | Callback function called when select date. It will return with same format of param 'format' | 367 | 368 | --- 369 | 370 | ### **Time** 371 | 372 | _This input uses [flutter_cupertino_date_picker](https://pub.dev/packages/flutter_cupertino_date_picker) to manage state and formatters on Time picker._ 373 | 374 | ```dart 375 | InputSheet(context).time( 376 | minDateTime: DateTime.now().subtract(Duration(hours: 5)), 377 | maxDateTime: DateTime.now().add(Duration(hours: 5)), 378 | locale: DateTimePickerLocale.en_us, 379 | format: "HH:mm", 380 | pickerFormat: "HH|mm", 381 | minuteDivider: 15, 382 | value: _value, 383 | onDone: (String value) => setState(() { 384 | _value = value; 385 | }), 386 | ); 387 | ``` 388 | 389 | | Parameters | Type | Description | 390 | | ------------- | -------------------- | -------------------------------------------------------------------------------------------- | 391 | | minDateTime | DateTime | Min date available to select | 392 | | maxDateTime | DateTime | Max date abailable to select | 393 | | locale | DateTimePickerLocale | `locale` is used to translate labels and must to be imported from [flutter_cupertino_date_picker](https://pub.dev/packages/flutter_cupertino_date_picker) package | 394 | | format | String | The format of value inserted in 'value' param | 395 | | pickerFormat | String | Add a placeholder to input | 396 | | minuteDivider | int | Time between each minute option | 397 | | value | String | Add a default value to input | 398 | | onDone | Function(String) | Callback function called when select date. It will return with same format of param 'format' | 399 | 400 | --- 401 | 402 | ### **Date and Time** 403 | 404 | _This input uses [flutter_cupertino_date_picker](https://pub.dev/packages/flutter_cupertino_date_picker) to manage state and formatters on DateTime picker._ 405 | 406 | ```dart 407 | InputSheet(context).datetime( 408 | minDateTime: DateTime.now(), 409 | maxDateTime: DateTime.now().add(Duration(days: 7)), 410 | locale: DateTimePickerLocale.en_us, 411 | format: "yyyy-MM-dd HH:mm", 412 | pickerFormat: "yyyy/MM/dd|HH|mm", 413 | minuteDivider: 15, 414 | value: _value, 415 | onDone: (String value) => setState(() { 416 | _value = value; 417 | }), 418 | ); 419 | ``` 420 | 421 | | Parameters | Type | Description | 422 | | ------------- | -------------------- | -------------------------------------------------------------------------------------------- | 423 | | minDateTime | DateTime | Min date available to select | 424 | | maxDateTime | DateTime | Max date abailable to select | 425 | | locale | DateTimePickerLocale | `locale` is used to translate labels and must to be imported from [flutter_cupertino_date_picker](https://pub.dev/packages/flutter_cupertino_date_picker) package | 426 | | format | String | The format of value inserted in 'value' param | 427 | | pickerFormat | String | Add a placeholder to input | 428 | | minuteDivider | int | Time between each minute option | 429 | | value | String | Add a default value to input | 430 | | onDone | Function(String) | Callback function called when select date. It will return with same format of param 'format' | 431 | 432 | --- 433 | 434 | ### **Options** 435 | 436 | _This input implements options to select_ 437 | 438 | ```dart 439 | 440 | InputSheet(context).options( 441 | options: { '0':'Chocolate' ,'1':'Vanilla', '2':'Strawberry'}, 442 | value: _value, 443 | onDone: (String value) => setState(() { 444 | _value = value; 445 | }), 446 | ); 447 | ``` 448 | 449 | | Parameters | Type | Description | 450 | | ---------- | --------------------- | -------------------------------------------------------------------------------------- | 451 | | options | Map\ | A map with value-key pair to be selected as an option | 452 | | value | String | A default selected key of options | 453 | | onDone | Function(String) | Callback function called when select an option. It will return the selected key option | 454 | 455 | --- 456 | 457 | ### **Multi Options** 458 | 459 | _This input implements options to multiple selections_ 460 | 461 | ```dart 462 | 463 | InputSheet(context).multioptions( 464 | options: { '0':'Comedy' ,'1':'Romance', '2':'Action'}, 465 | value: _value, 466 | onDone: (List value) => setState(() { 467 | _value = value; 468 | }), 469 | ); 470 | ``` 471 | 472 | | Parameters | Type | Description | 473 | | ---------- | --------------------- | -------------------------------------------------------------------------------------- | 474 | | options | Map\ | A map with value-key pair to be selected as an option | 475 | | value | List\ | A list of selected keys of options | 476 | | onDone | Function(List\) | Callback function called when select an option. It will return the list of selected keys options | 477 | | optionTextStyle | TextStyle | A customized style to list tile option label 478 | | optionSelectedIcon | Icon | A customized icon for selected option 479 | | optionUnselectedIcon | Icon | A customized icon for unselected option 480 | 481 | --- 482 | 483 | ### **Photo** 484 | 485 | _This input use [camera](https://pub.dev/packages/camera) to handle camera and need to be imported in your project to pass the parameter `resolution` and perform your camera quality._ 486 | 487 | The photo input already handler user permission to access camera. 488 | 489 | ```dart 490 | InputSheet(context).photo( 491 | url: "url/to/preview/image", 492 | file: new File("path/to/your/photo"), 493 | height: 300, 494 | resolution: ResolutionPreset.high, 495 | labelInitializingCamera: "Unitializing camera...", 496 | labelNoCameraAvailable: "There is no camera available on this device", 497 | onDone: (File file, Uint8List thumbnail) => setState(() { 498 | _value = file; 499 | _thumb = thumbnail; 500 | }), 501 | ); 502 | ``` 503 | 504 | | Parameters | Type | Description | 505 | | ----------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | 506 | | url | String | The uploaded url file to preview the input photo | 507 | | file | File | The local file who will be edited and used as local preview | 508 | | height | double | The height of sheet, by default it uses all screen height | 509 | | resolution | ResolutionPreset | ResolutionPreset is uset to manage camera quality and must to be imported from [camera](https://pub.dev/packages/camera) package | 510 | | labelInitializingCamera | String | A default message to show until camera initialize | 511 | | labelNoCameraAvailable | String | A default message to show when has no camera available | 512 | | onDone | Function(File, file, Uint8List thumbnail) | Callback function called when photo is captured. It will return the file of image and an Uint8List as memory thumbnail | 513 | 514 | --- 515 | 516 | ### **Video** 517 | 518 | _This input use [camera](https://pub.dev/packages/camera) to handle camera and need to be imported in your project to pass the parameter `resolution` and perform your camera quality._ 519 | 520 | _The video input also use [video_compress](https://pub.dev/packages/video_compress) to convert video if neccessary and perform it to reproduce in any web codec environment._ 521 | 522 | _The video input already handle user permission to access `camera` and `mic`._ 523 | 524 | ```dart 525 | InputSheet(context).video( 526 | url: "url/to/preview/video", 527 | file: new File("path/to/your/video"), 528 | height: 300, 529 | resolution: ResolutionPreset.high, 530 | labelInitializingCamera: "Unitializing camera...", 531 | labelNoCameraAvailable: "There is no camera available on this device", 532 | timeRecordLimit: 60, 533 | sufixRecordTimeout: "Sec remaining " 534 | compress: VideoQuality.DefaultQuality, 535 | labelCompressing: "Converting video...", 536 | onDone: (File file, Uint8List thumbnail) => setState(() { 537 | _value = file; 538 | _thumb = thumbnail; 539 | }), 540 | ); 541 | ``` 542 | 543 | | Parameters | Type | Description | 544 | | ----------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 545 | | url | String | The uploaded url file to preview the input video | 546 | | file | File | The local file who will be edited and used as local preview | 547 | | height | double | The height of sheet, by default it uses all screen height | 548 | | resolution | ResolutionPreset | ResolutionPreset is uset to manage camera quality and must to be imported from [camera](https://pub.dev/packages/camera) package | 549 | | labelInitializingCamera | String | A default message to show until camera initialize | 550 | | labelNoCameraAvailable | String | A default message to show when has no camera available | 551 | | timeRecordLimit | int | The time limit to record video | 552 | | sufixRecordTimeout | String | The label suffix to remaining record time | 553 | | compress | VideoQuality | VideoQuality is optional. Is used to convert video after stop recording and must to be imported from [video_compress](https://pub.dev/packages/video_compress) package | 554 | | labelCompressing | String | If compress is informed, this message will apper on screen to inform the video conversion. | 555 | | onDone | Function(File, file, Uint8List thumbnail) | Callback function called when photo is captured. It will return the file of image and an Uint8List as memory thumbnail | 556 | 557 | --- 558 | 559 | ## 🎉 Acknowledgment 560 | 561 | Thanks to all the projects that make this package possible. Especially those that facilitate the management of inputs: 562 | 563 | - https://pub.dev/packages/camera 564 | - https://pub.dev/packages/video_compress 565 | - https://pub.dev/packages/video_player 566 | - https://pub.dev/packages/flutter_masked_text 567 | - https://pub.dev/packages/permission_handler 568 | - https://pub.dev/packages/flutter_cupertino_date_picker 569 | 570 | --- 571 | 572 | ## License 573 | 574 | [![License: MIT](https://img.shields.io/badge/license-MIT-purple.svg)](LICENSE) 575 | 576 | Copyright (c) 2020 André Ciornavei 577 | 578 | Permission is hereby granted, free of charge, to any person obtaining a copy 579 | of this software and associated documentation files (the "Software"), to deal 580 | in the Software without restriction, including without limitation the rights 581 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 582 | copies of the Software, and to permit persons to whom the Software is 583 | furnished to do so, subject to the following conditions: 584 | 585 | The above copyright notice and this permission notice shall be included in all 586 | copies or substantial portions of the Software. 587 | 588 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 589 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 590 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 591 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 592 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 593 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 594 | SOFTWARE. 595 | --------------------------------------------------------------------------------