[0.1.0]
This commit is contained in:
219
lib/src/sheet/sheet_helper.astromic.dart
Normal file
219
lib/src/sheet/sheet_helper.astromic.dart
Normal file
@@ -0,0 +1,219 @@
|
||||
//s1 Imports
|
||||
//s2 Core Package Imports
|
||||
import 'package:flutter/material.dart';
|
||||
//s2 1st-party Package Imports
|
||||
//s2 3rd-party Package Imports
|
||||
//s2 Dependancies Imports
|
||||
//s3 Routes
|
||||
//s3 Services
|
||||
import '../../dependencies/vsync-provider/vsync_provider.dart';
|
||||
//s3 Models
|
||||
import '../form/form_helper.astromic.dart';
|
||||
import '../sheet/src/models/models.exports.dart';
|
||||
import '../sheet/src/enums/enums.exports.dart';
|
||||
import '../sheet/src/widgets/widgets.exports.dart';
|
||||
//s1 Exports
|
||||
export '../sheet/src/models/models.exports.dart';
|
||||
export '../form/form_helper.astromic.dart' show AstromicFormController;
|
||||
|
||||
class AstromicSheetHelper {
|
||||
static VsyncProviderState? _vsyncState;
|
||||
|
||||
/// A wrapper to initialize the vSync plugin for the sheets' animations.
|
||||
static Widget vSyncBuilder(Widget child) {
|
||||
return VsyncProvider(child: child);
|
||||
}
|
||||
|
||||
/// An initializer method to initialize the vSync state.
|
||||
static _initializevSync(BuildContext context) {
|
||||
_vsyncState = VsyncProvider.of(context);
|
||||
}
|
||||
|
||||
/// Show FLEX sheet, a flexible sheet that hugs the height of it's content.
|
||||
static Future<T?> flex<T extends Object?>(
|
||||
BuildContext context, {
|
||||
//
|
||||
Widget? headSection,
|
||||
required Widget contentSection,
|
||||
Widget? footerSection,
|
||||
//
|
||||
AstromicSheetConfiguration? configuration,
|
||||
AstromicSheetStyle? style,
|
||||
//
|
||||
}) async {
|
||||
if (_vsyncState == null) {
|
||||
_initializevSync(context);
|
||||
}
|
||||
|
||||
AstromicSheetConfiguration sheetConfigs = configuration ?? const AstromicSheetConfiguration();
|
||||
AstromicSheetStyle sheetStyle = style ?? const AstromicSheetStyle();
|
||||
|
||||
return await BasicSheet.show<T>(
|
||||
context: context,
|
||||
vsyncState: _vsyncState!,
|
||||
//
|
||||
useRootNavigator: sheetConfigs.useRootNavigator,
|
||||
enableOutsideInteraction: sheetConfigs.enableOutsideInteraction,
|
||||
enableSheetInteraction: sheetConfigs.enableSheetInteraction,
|
||||
//
|
||||
forwardAnimationDuration: sheetConfigs.forwardAnimationDuration ?? const Duration(milliseconds: 250),
|
||||
reverseAnimationDuration: sheetConfigs.reverseAnimationDuration ?? const Duration(milliseconds: 250),
|
||||
animationCurve: sheetConfigs.animationCurve ?? Curves.easeOut,
|
||||
//
|
||||
barrierColor: sheetStyle.maskColor ,
|
||||
radius: sheetStyle.radius,
|
||||
//
|
||||
child: BaseSheetWidget<T?>(
|
||||
sheetConfiguration: sheetConfigs,
|
||||
sheetStyle: sheetStyle,
|
||||
//
|
||||
headSection: headSection,
|
||||
contentSection: contentSection,
|
||||
footerSection: footerSection,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Show FLEX sheet using a pre-set FlexSheetTemplate.
|
||||
static Future<T?> flexTemplate<T extends Object?>(BuildContext context, AstromicFlexSheetTemplate<T> template) async => await flex<T>(
|
||||
context,
|
||||
headSection: template.headSection,
|
||||
contentSection: template.contentSection,
|
||||
footerSection: template.footerSection,
|
||||
//
|
||||
configuration: template.configuration,
|
||||
style: template.style,
|
||||
);
|
||||
|
||||
/// Show Form sheet, a FLEX sheet but with an integrated form controller.
|
||||
static Future<T?> form<T extends Object?>(
|
||||
BuildContext context, {
|
||||
//
|
||||
Widget Function(AstromicFormController)? headSectionBuilder,
|
||||
required Widget Function(AstromicFormController) contentSectionBuilder,
|
||||
Widget Function(AstromicFormController)? footerSectionBuilder,
|
||||
//
|
||||
AstromicSheetConfiguration? configuration,
|
||||
AstromicSheetStyle? style,
|
||||
}) async {
|
||||
if (_vsyncState == null) {
|
||||
_initializevSync(context);
|
||||
}
|
||||
|
||||
AstromicSheetConfiguration sheetConfigs = configuration ?? const AstromicSheetConfiguration();
|
||||
AstromicSheetStyle sheetStyle = style ?? const AstromicSheetStyle();
|
||||
|
||||
return await BasicSheet.show<T>(
|
||||
context: context,
|
||||
vsyncState: _vsyncState!,
|
||||
//
|
||||
useRootNavigator: sheetConfigs.useRootNavigator,
|
||||
enableOutsideInteraction: sheetConfigs.enableOutsideInteraction,
|
||||
enableSheetInteraction: sheetConfigs.enableSheetInteraction,
|
||||
//
|
||||
forwardAnimationDuration: sheetConfigs.forwardAnimationDuration ?? const Duration(milliseconds: 250),
|
||||
reverseAnimationDuration: sheetConfigs.reverseAnimationDuration ?? const Duration(milliseconds: 250),
|
||||
animationCurve: sheetConfigs.animationCurve ?? Curves.easeOut,
|
||||
//
|
||||
barrierColor: sheetStyle.maskColor,
|
||||
radius: sheetStyle.radius,
|
||||
//
|
||||
child: BaseSheetWidget<T?>(
|
||||
sheetType: SheetType.form,
|
||||
//
|
||||
sheetConfiguration: sheetConfigs,
|
||||
sheetStyle: sheetStyle,
|
||||
//
|
||||
headSectionFormBuilder: headSectionBuilder,
|
||||
contentSectionFormBuilder: contentSectionBuilder,
|
||||
footerSectionFormBuilder: footerSectionBuilder,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Show Form sheet using a pre-set FormSheetTemplate.
|
||||
static Future<T?> formTemplate<T extends Object?>(BuildContext c, AstromicFormSheetTemplate<T> template) async => await form<T>(
|
||||
c,
|
||||
headSectionBuilder: template.headSectionBuilder,
|
||||
contentSectionBuilder: template.contentSectionBuilder,
|
||||
footerSectionBuilder: template.footerSectionBuilder,
|
||||
//
|
||||
configuration: template.configuration,
|
||||
style: template.style,
|
||||
//
|
||||
);
|
||||
|
||||
/// Show Scroller sheet, a sheet that contains a vertically scrollable elements with some tweeks for animation.
|
||||
static Future<T?> scroller<T extends Object?>(
|
||||
BuildContext context, {
|
||||
//
|
||||
Widget Function(ScrollController)? headSectionBuilder,
|
||||
required Widget Function(ScrollController, ScrollPhysics) contentSectionBuilder,
|
||||
Widget Function(ScrollController)? footerSectionBuilder,
|
||||
//
|
||||
AstromicSheetConfiguration? configuration,
|
||||
AstromicSheetStyle? style,
|
||||
}) async {
|
||||
if (_vsyncState == null) {
|
||||
_initializevSync(context);
|
||||
}
|
||||
|
||||
AstromicSheetConfiguration sheetConfigs = configuration ?? const AstromicSheetConfiguration();
|
||||
AstromicSheetStyle sheetStyle = style ?? const AstromicSheetStyle();
|
||||
|
||||
return await ScrollerSheet.show<T>(
|
||||
context: context,
|
||||
vsyncState: _vsyncState!,
|
||||
//
|
||||
useRootNavigator: sheetConfigs.useRootNavigator,
|
||||
enableOutsideInteraction: sheetConfigs.enableOutsideInteraction,
|
||||
enableSheetInteraction: sheetConfigs.enableSheetInteraction,
|
||||
respectKeyboardInset: sheetConfigs.respectKeyboardInset,
|
||||
//
|
||||
forwardAnimationDuration: sheetConfigs.forwardAnimationDuration ?? const Duration(milliseconds: 250),
|
||||
reverseAnimationDuration: sheetConfigs.reverseAnimationDuration ?? const Duration(milliseconds: 250),
|
||||
animationCurve: sheetConfigs.animationCurve ?? Curves.easeOut,
|
||||
dragThreshold: sheetConfigs.dragThreshold ?? 25,
|
||||
//
|
||||
physics: sheetConfigs.physics,
|
||||
stops: sheetConfigs.expandedHeightFactor != null && (sheetConfigs.expandedHeightFactor! > sheetConfigs.initialHeightFactor)
|
||||
? <double?>[sheetConfigs.initialHeightFactor, sheetConfigs.expandedHeightFactor].map((double? s) {
|
||||
double r = sheetConfigs.safeAreaAware ? ((s! * MediaQuery.of(context).size.height) - MediaQuery.of(context).viewPadding.top) : (s! * MediaQuery.of(context).size.height);
|
||||
return r;
|
||||
}).toList()
|
||||
: <double>[
|
||||
sheetConfigs.initialHeightFactor,
|
||||
].map((double s) {
|
||||
double r = sheetConfigs.safeAreaAware ? ((s * MediaQuery.of(context).size.height) - MediaQuery.of(context).viewPadding.top) : (s * MediaQuery.of(context).size.height);
|
||||
return r;
|
||||
}).toList(),
|
||||
// s2 -- Styling
|
||||
barrierColor: sheetStyle.maskColor,
|
||||
topInset: sheetStyle.topInset,
|
||||
// s2 -- Child
|
||||
builder: (BuildContext context, ScrollController scrollController, ScrollPhysics scrollPhysics, int stop) {
|
||||
return BaseSheetWidget<T?>(
|
||||
sheetType: SheetType.scroller,
|
||||
sheetConfiguration: sheetConfigs,
|
||||
sheetStyle: sheetStyle,
|
||||
headSectionScrollerBuilder: headSectionBuilder,
|
||||
contentSectionScrollBuilder: contentSectionBuilder,
|
||||
footerSectionScrollerBuilder: footerSectionBuilder,
|
||||
scrollController: scrollController,
|
||||
scrollPhysics: scrollPhysics,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Show Scroller sheet using a pre-set ScrollerSheetTemplate.
|
||||
static Future<T?> scrollerTemplate<T extends Object?>(BuildContext context, AstromicScrollerSheetTemplate<T> template) async => await scroller<T>(
|
||||
context,
|
||||
headSectionBuilder: template.headSectionBuilder,
|
||||
contentSectionBuilder: template.contentSectionBuilder,
|
||||
footerSectionBuilder: template.footerSectionBuilder,
|
||||
//
|
||||
configuration: template.configuration,
|
||||
style: template.style,
|
||||
);
|
||||
}
|
||||
1
lib/src/sheet/src/enums/enums.exports.dart
Normal file
1
lib/src/sheet/src/enums/enums.exports.dart
Normal file
@@ -0,0 +1 @@
|
||||
export 'type.enum.dart';
|
||||
5
lib/src/sheet/src/enums/type.enum.dart
Normal file
5
lib/src/sheet/src/enums/type.enum.dart
Normal file
@@ -0,0 +1,5 @@
|
||||
enum SheetType {
|
||||
flex,
|
||||
form,
|
||||
scroller,
|
||||
}
|
||||
45
lib/src/sheet/src/models/Templates/flex_sheet.template.dart
Normal file
45
lib/src/sheet/src/models/Templates/flex_sheet.template.dart
Normal file
@@ -0,0 +1,45 @@
|
||||
//s1 Imports
|
||||
//s2 Core Package Imports
|
||||
import 'package:flutter/widgets.dart';
|
||||
//s2 1st-party Package Imports
|
||||
//s2 3rd-party Package Imports
|
||||
//s2 Dependancies Imports
|
||||
//s3 Routes
|
||||
//s3 Services
|
||||
//s3 Models & Widgets
|
||||
import 'template_base.dart';
|
||||
import '../models.exports.dart';
|
||||
//s1 Exports
|
||||
|
||||
class AstromicFlexSheetTemplate<T> extends AstromicSheetTemplate<T> {
|
||||
final Widget? headSection;
|
||||
final Widget contentSection;
|
||||
final Widget? footerSection;
|
||||
//
|
||||
final AstromicSheetConfiguration? configuration;
|
||||
final AstromicSheetStyle? style;
|
||||
|
||||
AstromicFlexSheetTemplate({
|
||||
this.headSection,
|
||||
required this.contentSection,
|
||||
this.footerSection,
|
||||
this.configuration,
|
||||
this.style,
|
||||
});
|
||||
|
||||
AstromicFlexSheetTemplate<T> copyWith({
|
||||
Widget? headSection,
|
||||
Widget? contentSection,
|
||||
Widget? footerSection,
|
||||
AstromicSheetConfiguration? configuration,
|
||||
AstromicSheetStyle? style,
|
||||
}) {
|
||||
return AstromicFlexSheetTemplate<T>(
|
||||
headSection: headSection ?? this.headSection,
|
||||
contentSection: contentSection ?? this.contentSection,
|
||||
footerSection: footerSection ?? this.footerSection,
|
||||
configuration: configuration ?? this.configuration,
|
||||
style: style ?? this.style,
|
||||
);
|
||||
}
|
||||
}
|
||||
46
lib/src/sheet/src/models/Templates/form_sheet.template.dart
Normal file
46
lib/src/sheet/src/models/Templates/form_sheet.template.dart
Normal file
@@ -0,0 +1,46 @@
|
||||
//s1 Imports
|
||||
//s2 Core Package Imports
|
||||
import 'package:flutter/widgets.dart';
|
||||
//s2 1st-party Package Imports
|
||||
//s2 3rd-party Package Imports
|
||||
//s2 Dependancies Imports
|
||||
//s3 Routes
|
||||
//s3 Services
|
||||
//s3 Models
|
||||
import 'template_base.dart';
|
||||
import '../models.exports.dart';
|
||||
import '../../../../form/form_helper.astromic.dart';
|
||||
//s1 Exports
|
||||
|
||||
class AstromicFormSheetTemplate<T> extends AstromicSheetTemplate<T> {
|
||||
final Widget Function(AstromicFormController)? headSectionBuilder;
|
||||
final Widget Function(AstromicFormController) contentSectionBuilder;
|
||||
final Widget Function(AstromicFormController)? footerSectionBuilder;
|
||||
//
|
||||
final AstromicSheetConfiguration? configuration;
|
||||
final AstromicSheetStyle? style;
|
||||
|
||||
AstromicFormSheetTemplate({
|
||||
this.headSectionBuilder,
|
||||
required this.contentSectionBuilder,
|
||||
this.footerSectionBuilder,
|
||||
this.configuration,
|
||||
this.style,
|
||||
});
|
||||
|
||||
AstromicFormSheetTemplate<T> copyWith({
|
||||
Widget Function(AstromicFormController)? headSectionBuilder,
|
||||
Widget Function(AstromicFormController)? contentSectionBuilder,
|
||||
Widget Function(AstromicFormController)? footerSectionBuilder,
|
||||
AstromicSheetConfiguration? configuration,
|
||||
AstromicSheetStyle? style,
|
||||
}) {
|
||||
return AstromicFormSheetTemplate<T>(
|
||||
headSectionBuilder: headSectionBuilder ?? this.headSectionBuilder,
|
||||
contentSectionBuilder: contentSectionBuilder ?? this.contentSectionBuilder,
|
||||
footerSectionBuilder: footerSectionBuilder ?? this.footerSectionBuilder,
|
||||
configuration: configuration ?? this.configuration,
|
||||
style: style ?? this.style,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
//s1 Imports
|
||||
//s2 Core Package Imports
|
||||
import 'package:flutter/widgets.dart';
|
||||
//s2 1st-party Package Imports
|
||||
//s2 3rd-party Package Imports
|
||||
//s2 Dependancies Imports
|
||||
//s3 Routes
|
||||
//s3 Services
|
||||
//s3 Models
|
||||
import 'template_base.dart';
|
||||
import '../models.exports.dart';
|
||||
//s1 Exports
|
||||
|
||||
class AstromicScrollerSheetTemplate<T> extends AstromicSheetTemplate<T> {
|
||||
final Widget Function(ScrollController)? headSectionBuilder;
|
||||
final Widget Function(ScrollController, ScrollPhysics) contentSectionBuilder;
|
||||
final Widget Function(ScrollController)? footerSectionBuilder;
|
||||
//
|
||||
final AstromicSheetConfiguration? configuration;
|
||||
final AstromicSheetStyle? style;
|
||||
|
||||
AstromicScrollerSheetTemplate({
|
||||
this.headSectionBuilder,
|
||||
required this.contentSectionBuilder,
|
||||
this.footerSectionBuilder,
|
||||
this.configuration,
|
||||
this.style,
|
||||
});
|
||||
|
||||
AstromicScrollerSheetTemplate<T> copyWith({
|
||||
Widget Function(ScrollController)? headSection,
|
||||
Widget Function(ScrollController, ScrollPhysics)? contentSectionBuilder,
|
||||
Widget Function(ScrollController)? footerSection,
|
||||
AstromicSheetConfiguration? configuration,
|
||||
AstromicSheetStyle? style,
|
||||
}) {
|
||||
return AstromicScrollerSheetTemplate<T>(
|
||||
headSectionBuilder: headSection ?? this.headSectionBuilder,
|
||||
contentSectionBuilder: contentSectionBuilder ?? this.contentSectionBuilder,
|
||||
footerSectionBuilder: footerSection ?? this.footerSectionBuilder,
|
||||
configuration: configuration ?? this.configuration,
|
||||
style: style ?? this.style,
|
||||
);
|
||||
}
|
||||
}
|
||||
1
lib/src/sheet/src/models/Templates/template_base.dart
Normal file
1
lib/src/sheet/src/models/Templates/template_base.dart
Normal file
@@ -0,0 +1 @@
|
||||
abstract class AstromicSheetTemplate<T> {}
|
||||
@@ -0,0 +1,3 @@
|
||||
export 'flex_sheet.template.dart';
|
||||
export 'form_sheet.template.dart';
|
||||
export 'scroller_sheet.template.dart';
|
||||
73
lib/src/sheet/src/models/configuration.model.dart
Normal file
73
lib/src/sheet/src/models/configuration.model.dart
Normal file
@@ -0,0 +1,73 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class AstromicSheetConfiguration {
|
||||
//s1 -- Shared
|
||||
final bool useRootNavigator;
|
||||
//
|
||||
final Duration? closeDelay;
|
||||
final Duration? forwardAnimationDuration;
|
||||
final Duration? reverseAnimationDuration;
|
||||
final Curve? animationCurve;
|
||||
//
|
||||
final bool enableOutsideInteraction;
|
||||
final bool enableSheetInteraction;
|
||||
final bool dismissOnBack;
|
||||
//s1 -- Scroller Specific
|
||||
final double initialHeightFactor;
|
||||
final double? expandedHeightFactor;
|
||||
final bool respectKeyboardInset;
|
||||
final bool safeAreaAware;
|
||||
final ScrollPhysics? physics;
|
||||
final double? dragThreshold;
|
||||
|
||||
const AstromicSheetConfiguration({
|
||||
this.useRootNavigator = true,
|
||||
this.closeDelay,
|
||||
this.forwardAnimationDuration = const Duration(milliseconds: 300),
|
||||
this.reverseAnimationDuration = const Duration(milliseconds: 300),
|
||||
this.animationCurve = Curves.ease,
|
||||
this.enableOutsideInteraction = true,
|
||||
this.enableSheetInteraction = true,
|
||||
this.dismissOnBack = false,
|
||||
this.respectKeyboardInset = true,
|
||||
this.safeAreaAware = false,
|
||||
this.expandedHeightFactor,
|
||||
this.initialHeightFactor = 0.5,
|
||||
this.physics,
|
||||
this.dragThreshold,
|
||||
});
|
||||
|
||||
AstromicSheetConfiguration copyWith({
|
||||
bool? useRootNavigator,
|
||||
Duration? closeDelay,
|
||||
Duration? forwardAnimationDuration,
|
||||
Duration? reverseAnimationDuration,
|
||||
Curve? animationCurve,
|
||||
bool? enableOutsideInteraction,
|
||||
bool? enableSheetInteraction,
|
||||
bool? dismissOnBack,
|
||||
double? initialHeightFactor,
|
||||
double? expandedHeightFactor,
|
||||
bool? respectKeyboardInset,
|
||||
bool? safeAreaAware,
|
||||
ScrollPhysics? physics,
|
||||
double? dragThreshold,
|
||||
}) {
|
||||
return AstromicSheetConfiguration(
|
||||
useRootNavigator: useRootNavigator ?? this.useRootNavigator,
|
||||
closeDelay: closeDelay ?? this.closeDelay,
|
||||
forwardAnimationDuration: forwardAnimationDuration ?? this.forwardAnimationDuration,
|
||||
reverseAnimationDuration: reverseAnimationDuration ?? this.reverseAnimationDuration,
|
||||
animationCurve: animationCurve ?? this.animationCurve,
|
||||
enableOutsideInteraction: enableOutsideInteraction ?? this.enableOutsideInteraction,
|
||||
enableSheetInteraction: enableSheetInteraction ?? this.enableSheetInteraction,
|
||||
dismissOnBack: dismissOnBack ?? this.dismissOnBack,
|
||||
initialHeightFactor: initialHeightFactor ?? this.initialHeightFactor,
|
||||
expandedHeightFactor: expandedHeightFactor ?? this.expandedHeightFactor,
|
||||
respectKeyboardInset: respectKeyboardInset ?? this.respectKeyboardInset,
|
||||
safeAreaAware: safeAreaAware ?? this.safeAreaAware,
|
||||
physics: physics ?? this.physics,
|
||||
dragThreshold: dragThreshold ?? this.dragThreshold,
|
||||
);
|
||||
}
|
||||
}
|
||||
3
lib/src/sheet/src/models/models.exports.dart
Normal file
3
lib/src/sheet/src/models/models.exports.dart
Normal file
@@ -0,0 +1,3 @@
|
||||
export 'configuration.model.dart';
|
||||
export 'style.model.dart';
|
||||
export 'templates/templates.exports.dart';
|
||||
51
lib/src/sheet/src/models/style.model.dart
Normal file
51
lib/src/sheet/src/models/style.model.dart
Normal file
@@ -0,0 +1,51 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class AstromicSheetStyle {
|
||||
final Color maskColor;
|
||||
final Color headSectionColor;
|
||||
final Color contentSectionColor;
|
||||
final Color footerSectionColor;
|
||||
//
|
||||
final EdgeInsets headSectionPadding;
|
||||
final EdgeInsets contentSectionPadding;
|
||||
final EdgeInsets footerSectionPadding;
|
||||
//
|
||||
final double radius;
|
||||
final double topInset;
|
||||
//
|
||||
const AstromicSheetStyle({
|
||||
this.maskColor = Colors.black38,
|
||||
this.headSectionColor = Colors.white,
|
||||
this.contentSectionColor = Colors.white,
|
||||
this.footerSectionColor = Colors.white,
|
||||
this.headSectionPadding = const EdgeInsets.symmetric(horizontal: 12.0, vertical: 16.0),
|
||||
this.contentSectionPadding = const EdgeInsets.symmetric(horizontal: 16.0, vertical: 18.0),
|
||||
this.footerSectionPadding = const EdgeInsets.symmetric(horizontal: 16.0, vertical: 18.0),
|
||||
this.radius = 24,
|
||||
this.topInset = 0,
|
||||
});
|
||||
|
||||
AstromicSheetStyle copyWith({
|
||||
Color? maskColor,
|
||||
Color? headSectionColor,
|
||||
Color? contentSectionColor,
|
||||
Color? footerSectionColor,
|
||||
EdgeInsets? headSectionPadding,
|
||||
EdgeInsets? contentSectionPadding,
|
||||
EdgeInsets? footerSectionPadding,
|
||||
double? radius,
|
||||
double? topInset,
|
||||
}) {
|
||||
return AstromicSheetStyle(
|
||||
maskColor: maskColor ?? this.maskColor,
|
||||
headSectionColor: headSectionColor ?? this.headSectionColor,
|
||||
contentSectionColor: contentSectionColor ?? this.contentSectionColor,
|
||||
footerSectionColor: footerSectionColor ?? this.footerSectionColor,
|
||||
headSectionPadding: headSectionPadding ?? this.headSectionPadding,
|
||||
contentSectionPadding: contentSectionPadding ?? this.contentSectionPadding,
|
||||
footerSectionPadding: footerSectionPadding ?? this.footerSectionPadding,
|
||||
radius: radius ?? this.radius,
|
||||
topInset: topInset ?? this.topInset,
|
||||
);
|
||||
}
|
||||
}
|
||||
263
lib/src/sheet/src/widgets/base.dart
Normal file
263
lib/src/sheet/src/widgets/base.dart
Normal file
@@ -0,0 +1,263 @@
|
||||
//s1 Imports
|
||||
//s2 Core Package Imports
|
||||
import 'package:flutter/material.dart';
|
||||
//s2 1st-party Package Imports
|
||||
//s2 3rd-party Package Imports
|
||||
//s2 Dependancies Imports
|
||||
//s3 Routes
|
||||
//s3 Services
|
||||
//s3 Models & Widgets
|
||||
import '../../../form/form_helper.astromic.dart';
|
||||
import '../enums/enums.exports.dart';
|
||||
import '../models/models.exports.dart';
|
||||
//s1 Exports
|
||||
|
||||
class BaseSheetWidget<T> extends StatefulWidget {
|
||||
//SECTION - Widget Arguments
|
||||
final SheetType sheetType;
|
||||
//
|
||||
final AstromicSheetConfiguration? sheetConfiguration;
|
||||
final AstromicSheetStyle? sheetStyle;
|
||||
//
|
||||
final Widget? headSection;
|
||||
final Widget? contentSection;
|
||||
final Widget? footerSection;
|
||||
//
|
||||
final Widget Function(AstromicFormController)? headSectionFormBuilder;
|
||||
final Widget Function(AstromicFormController)? contentSectionFormBuilder;
|
||||
final Widget Function(AstromicFormController)? footerSectionFormBuilder;
|
||||
//
|
||||
final ScrollController? scrollController;
|
||||
final ScrollPhysics? scrollPhysics;
|
||||
final Widget Function(ScrollController)? headSectionScrollerBuilder;
|
||||
final Widget Function(ScrollController, ScrollPhysics)? contentSectionScrollBuilder;
|
||||
final Widget Function(ScrollController)? footerSectionScrollerBuilder;
|
||||
//!SECTION
|
||||
|
||||
const BaseSheetWidget({
|
||||
super.key,
|
||||
this.sheetType = SheetType.flex,
|
||||
this.sheetConfiguration,
|
||||
this.sheetStyle,
|
||||
this.headSection,
|
||||
this.contentSection,
|
||||
this.footerSection,
|
||||
this.contentSectionFormBuilder,
|
||||
this.footerSectionFormBuilder,
|
||||
this.headSectionFormBuilder,
|
||||
this.scrollController,
|
||||
this.scrollPhysics,
|
||||
this.headSectionScrollerBuilder,
|
||||
this.contentSectionScrollBuilder,
|
||||
this.footerSectionScrollerBuilder,
|
||||
//
|
||||
}) : assert(sheetType != SheetType.flex || (sheetType == SheetType.flex && contentSection != null)),
|
||||
assert(sheetType != SheetType.form || (sheetType == SheetType.form && contentSectionFormBuilder != null)),
|
||||
assert(sheetType != SheetType.scroller || (sheetType == SheetType.scroller && contentSectionScrollBuilder != null && scrollController != null && scrollPhysics != null));
|
||||
|
||||
@override
|
||||
State<BaseSheetWidget<T>> createState() => _BaseSheetWidgetState<T>();
|
||||
}
|
||||
|
||||
class _BaseSheetWidgetState<T> extends State<BaseSheetWidget<T>> {
|
||||
//
|
||||
//SECTION - State Variables
|
||||
//s1 --Controllers
|
||||
late AstromicFormController _formController;
|
||||
late AstromicSheetConfiguration _config;
|
||||
late AstromicSheetStyle _style;
|
||||
//s1 --Controllers
|
||||
//
|
||||
//s1 --State
|
||||
//s1 --State
|
||||
//
|
||||
//s1 --Constants
|
||||
//s1 --Constants
|
||||
//!SECTION
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
//
|
||||
//SECTION - State Variables initializations & Listeners
|
||||
//s1 --Controllers & Listeners
|
||||
_formController = AstromicFormController();
|
||||
//s1 --Controllers & Listeners
|
||||
//
|
||||
//s1 --State
|
||||
//s1 --State
|
||||
//!SECTION
|
||||
}
|
||||
|
||||
//SECTION - Stateless functions
|
||||
//!SECTION
|
||||
|
||||
//SECTION - Action Callbacks
|
||||
//!SECTION
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
//SECTION - Build Setup
|
||||
//s1 -Values
|
||||
_config = widget.sheetConfiguration ?? const AstromicSheetConfiguration();
|
||||
_style = widget.sheetStyle ?? const AstromicSheetStyle();
|
||||
//s1 -Values
|
||||
|
||||
//s1 -Widgets
|
||||
List<Widget> flexChildren = <Widget>[
|
||||
widget.headSection != null
|
||||
? ClipRRect(
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(_style.radius),
|
||||
),
|
||||
child: Container(
|
||||
padding: _style.headSectionPadding,
|
||||
child: widget.headSection,
|
||||
),
|
||||
)
|
||||
: Container(),
|
||||
Container(
|
||||
color: _style.contentSectionColor,
|
||||
padding: _style.contentSectionPadding,
|
||||
child: widget.contentSection != null ? widget.contentSection! : Container(),
|
||||
),
|
||||
widget.footerSection != null
|
||||
? Container(
|
||||
color: _style.footerSectionColor,
|
||||
padding: _style.footerSectionPadding,
|
||||
child: widget.footerSection,
|
||||
)
|
||||
: Container()
|
||||
];
|
||||
|
||||
List<Widget> formChildren = <Widget>[
|
||||
widget.headSectionFormBuilder != null
|
||||
? ClipRRect(
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(_style.radius),
|
||||
),
|
||||
child: Container(
|
||||
padding: _style.headSectionPadding,
|
||||
child: widget.headSectionFormBuilder!(_formController),
|
||||
),
|
||||
)
|
||||
: Container(),
|
||||
Container(
|
||||
color: _style.contentSectionColor,
|
||||
padding: _style.contentSectionPadding,
|
||||
child: widget.contentSectionFormBuilder != null ? widget.contentSectionFormBuilder!(_formController) : Container(),
|
||||
),
|
||||
widget.footerSectionFormBuilder != null
|
||||
? Container(
|
||||
color: _style.footerSectionColor,
|
||||
padding: _style.footerSectionPadding,
|
||||
child: widget.footerSectionFormBuilder != null ? widget.footerSectionFormBuilder!(_formController) : Container(),
|
||||
)
|
||||
: Container()
|
||||
];
|
||||
|
||||
List<Widget> scrollerChildren = <Widget>[
|
||||
widget.headSectionScrollerBuilder != null
|
||||
? ClipRRect(
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(_style.radius),
|
||||
),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: _style.headSectionColor,
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(_style.radius),
|
||||
),
|
||||
),
|
||||
padding: _style.headSectionPadding,
|
||||
width: double.infinity,
|
||||
child: widget.headSectionScrollerBuilder!(widget.scrollController!),
|
||||
),
|
||||
)
|
||||
: Container(),
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: _style.contentSectionPadding,
|
||||
width: double.infinity,
|
||||
color: _style.contentSectionColor,
|
||||
child: widget.contentSectionScrollBuilder != null ? widget.contentSectionScrollBuilder!(widget.scrollController!, widget.scrollPhysics!) : Container(),
|
||||
),
|
||||
),
|
||||
widget.footerSectionScrollerBuilder != null
|
||||
? Container(
|
||||
color: _style.footerSectionColor,
|
||||
padding: _style.footerSectionPadding,
|
||||
child: widget.footerSectionScrollerBuilder!(widget.scrollController!),
|
||||
)
|
||||
: Container()
|
||||
];
|
||||
//s1 -Widgets
|
||||
//!SECTION
|
||||
|
||||
//SECTION - Build Return
|
||||
return PopScope(
|
||||
canPop: _config.dismissOnBack || _config.enableOutsideInteraction || _config.enableSheetInteraction,
|
||||
child: Container(
|
||||
child:
|
||||
//FLEX
|
||||
widget.sheetType == SheetType.flex
|
||||
? Container(
|
||||
padding: EdgeInsets.only(bottom: _config.respectKeyboardInset ? MediaQuery.of(context).viewInsets.bottom : 0),
|
||||
color: Colors.transparent,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: _style.headSectionColor,
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(_style.radius),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
children: flexChildren,
|
||||
),
|
||||
),
|
||||
)
|
||||
:
|
||||
//FORM
|
||||
widget.sheetType == SheetType.form
|
||||
? Container(
|
||||
padding: EdgeInsets.only(bottom: _config.respectKeyboardInset ? MediaQuery.of(context).viewInsets.bottom : 0),
|
||||
color: Colors.transparent,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: _style.headSectionColor,
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(_style.radius),
|
||||
),
|
||||
),
|
||||
child: Form(
|
||||
key: _formController.key,
|
||||
child: Column(
|
||||
children: formChildren,
|
||||
),
|
||||
),
|
||||
))
|
||||
:
|
||||
//Scroller
|
||||
widget.sheetType == SheetType.scroller
|
||||
? ClipRRect(
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(_style.radius),
|
||||
),
|
||||
child: Column(
|
||||
children: scrollerChildren,
|
||||
),
|
||||
)
|
||||
: Container(),
|
||||
),
|
||||
);
|
||||
//!SECTION
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
//SECTION - Disposable variables
|
||||
_formController.dispose();
|
||||
//!SECTION
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
63
lib/src/sheet/src/widgets/basic.sheet.dart
Normal file
63
lib/src/sheet/src/widgets/basic.sheet.dart
Normal file
@@ -0,0 +1,63 @@
|
||||
//s1 Imports
|
||||
//s2 Core Package Imports
|
||||
import 'package:flutter/material.dart';
|
||||
//s2 1st-party Package Imports
|
||||
//s2 3rd-party Package Imports
|
||||
//s2 Dependancies Imports
|
||||
//s3 Routes
|
||||
//s3 Services
|
||||
import '../../../../dependencies/vsync-provider/vsync_provider.dart';
|
||||
//s3 Models
|
||||
//s1 Exports
|
||||
|
||||
@immutable
|
||||
class BasicSheet {
|
||||
//
|
||||
static Future<T?> show<T extends Object?>({
|
||||
required BuildContext context,
|
||||
required VsyncProviderState vsyncState,
|
||||
required Widget child,
|
||||
//
|
||||
bool useRootNavigator = false,
|
||||
bool enableSheetInteraction = true,
|
||||
bool enableOutsideInteraction = true,
|
||||
//
|
||||
Color barrierColor = const Color(0xb3212121),
|
||||
double radius = 24,
|
||||
//
|
||||
Duration forwardAnimationDuration = const Duration(milliseconds: 250),
|
||||
Duration reverseAnimationDuration = const Duration(milliseconds: 250),
|
||||
Curve? animationCurve,
|
||||
//
|
||||
}) async {
|
||||
AnimationController controller = AnimationController(
|
||||
vsync: vsyncState,
|
||||
);
|
||||
|
||||
// Animation duration for displaying the BottomSheet
|
||||
controller.duration = forwardAnimationDuration;
|
||||
|
||||
// Animation duration for retracting the BottomSheet
|
||||
controller.reverseDuration = reverseAnimationDuration;
|
||||
|
||||
// Set animation curve duration for the BottomSheet
|
||||
controller.drive(CurveTween(curve: animationCurve ?? Curves.easeOut));
|
||||
|
||||
return await showModalBottomSheet<T?>(
|
||||
backgroundColor: Colors.transparent,
|
||||
barrierColor: barrierColor,
|
||||
//
|
||||
enableDrag: enableSheetInteraction,
|
||||
isDismissible: enableOutsideInteraction,
|
||||
useRootNavigator: useRootNavigator,
|
||||
//
|
||||
isScrollControlled: true,
|
||||
transitionAnimationController: controller,
|
||||
//
|
||||
context: context,
|
||||
builder: (BuildContext c) {
|
||||
return Wrap(children: <Widget>[ClipRRect(borderRadius: BorderRadius.vertical(top: Radius.circular(radius)), child: child)]);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
286
lib/src/sheet/src/widgets/scroller.sheet.dart
Normal file
286
lib/src/sheet/src/widgets/scroller.sheet.dart
Normal file
@@ -0,0 +1,286 @@
|
||||
//s1 Imports
|
||||
//s2 Core Package Imports
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
//s2 1st-party Package Imports
|
||||
//s2 3rd-party Package Imports
|
||||
//s2 Dependancies Imports
|
||||
//s3 Routes
|
||||
//s3 Services
|
||||
import '../../../../dependencies/vsync-provider/vsync_provider.dart';
|
||||
//s3 Models
|
||||
//s1 Exports
|
||||
|
||||
typedef StopperBuilder = Widget Function(
|
||||
BuildContext context,
|
||||
ScrollController controller,
|
||||
ScrollPhysics physics,
|
||||
int stop,
|
||||
);
|
||||
|
||||
class ScrollerSheet<T extends Object?> extends StatefulWidget {
|
||||
//
|
||||
final List<double>? stops;
|
||||
final StopperBuilder? builder;
|
||||
final int initialStop;
|
||||
final double dragThreshold;
|
||||
final Color? barrierColor;
|
||||
final double? topInset;
|
||||
//
|
||||
final ScrollPhysics? physics;
|
||||
final bool? enableSheetInteraction;
|
||||
//
|
||||
ScrollerSheet({
|
||||
super.key,
|
||||
required this.builder,
|
||||
required this.stops,
|
||||
this.initialStop = 0,
|
||||
this.barrierColor = Colors.black38,
|
||||
this.dragThreshold = 25,
|
||||
this.topInset,
|
||||
this.physics,
|
||||
this.enableSheetInteraction = true,
|
||||
//
|
||||
}) : assert(initialStop < stops!.length);
|
||||
|
||||
@override
|
||||
ScrollerSheetState<T> createState() => ScrollerSheetState<T>();
|
||||
|
||||
static Future<T?> show<T extends Object?>({
|
||||
Key? key,
|
||||
required BuildContext context,
|
||||
required VsyncProviderState vsyncState,
|
||||
required StopperBuilder? builder,
|
||||
//
|
||||
bool useRootNavigator = true,
|
||||
bool enableSheetInteraction = true,
|
||||
bool enableOutsideInteraction = true,
|
||||
bool respectKeyboardInset = true,
|
||||
ScrollPhysics? physics = const BouncingScrollPhysics(),
|
||||
//
|
||||
required List<double>? stops,
|
||||
int initialStop = 0,
|
||||
double dragThreshold = 25,
|
||||
//
|
||||
Duration? forwardAnimationDuration = const Duration(milliseconds: 250),
|
||||
Duration? reverseAnimationDuration = const Duration(milliseconds: 250),
|
||||
Curve? animationCurve,
|
||||
//
|
||||
Color barrierColor = const Color(0xb3212121),
|
||||
double? topInset,
|
||||
}) async {
|
||||
Future<T?>? ret;
|
||||
AnimationController controller = AnimationController(
|
||||
vsync: vsyncState,
|
||||
);
|
||||
|
||||
controller.duration = forwardAnimationDuration;
|
||||
controller.reverseDuration = reverseAnimationDuration;
|
||||
controller.drive(CurveTween(curve: animationCurve ?? Curves.easeOut));
|
||||
|
||||
ret = showModalBottomSheet<T?>(
|
||||
backgroundColor: Colors.transparent,
|
||||
barrierColor: barrierColor,
|
||||
//
|
||||
enableDrag: enableSheetInteraction,
|
||||
isDismissible: enableOutsideInteraction,
|
||||
//
|
||||
isScrollControlled: true,
|
||||
useRootNavigator: useRootNavigator,
|
||||
transitionAnimationController: controller,
|
||||
//
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: respectKeyboardInset ? MediaQuery.of(context).viewInsets.bottom : 0,
|
||||
),
|
||||
child: ScrollerSheet<T>(
|
||||
key: key,
|
||||
builder: builder,
|
||||
stops: stops,
|
||||
initialStop: initialStop,
|
||||
dragThreshold: dragThreshold,
|
||||
physics: physics,
|
||||
topInset: topInset,
|
||||
enableSheetInteraction: enableSheetInteraction,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
class ScrollerSheetState<T> extends State<ScrollerSheet<T>> with SingleTickerProviderStateMixin {
|
||||
List<double>? _stops;
|
||||
int? _currentStop;
|
||||
int? _targetStop;
|
||||
bool _dragging = false;
|
||||
bool _closing = false;
|
||||
double? _dragOffset;
|
||||
double? _closingHeight;
|
||||
ScrollController? _scrollController;
|
||||
ScrollPhysics? _scrollPhysics;
|
||||
Animation<double>? _animation;
|
||||
AnimationController? _animationController;
|
||||
Tween<double>? _tween;
|
||||
|
||||
ScrollPhysics _getScrollPhysicsForStop(dynamic s) {
|
||||
if (s == _stops!.length - 1) {
|
||||
return widget.physics ?? const BouncingScrollPhysics();
|
||||
} else {
|
||||
return const NeverScrollableScrollPhysics();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_stops = widget.stops;
|
||||
_currentStop = widget.initialStop;
|
||||
_targetStop = _currentStop;
|
||||
_scrollController = ScrollController();
|
||||
_scrollPhysics = _getScrollPhysicsForStop(_currentStop);
|
||||
_animationController = AnimationController(vsync: this, duration: const Duration(seconds: 2));
|
||||
final CurvedAnimation curveAnimation = CurvedAnimation(parent: _animationController!, curve: Curves.linear);
|
||||
_tween = Tween<double>(begin: _stops?[_currentStop!], end: _stops?[_targetStop!]);
|
||||
_animation = _tween?.animate(curveAnimation);
|
||||
_scrollController?.addListener(() {
|
||||
if (_scrollController!.offset < -widget.dragThreshold) {
|
||||
if (_currentStop != _targetStop || _dragging) return;
|
||||
if (_currentStop! > 0) {
|
||||
double h0 = height;
|
||||
_targetStop = _currentStop! - 1;
|
||||
_animate(h0, _stops![_targetStop!]);
|
||||
} else if (!_closing) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(ScrollerSheet<T> oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
_stops = widget.stops;
|
||||
_currentStop = min(_currentStop!, _stops!.length - 1);
|
||||
_targetStop = min(_currentStop!, _stops!.length - 1);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
_animationController!.dispose();
|
||||
_scrollController!.dispose();
|
||||
}
|
||||
|
||||
get stop => _currentStop;
|
||||
|
||||
set stop(dynamic nextStop) {
|
||||
_targetStop = max(0, min(_stops!.length - 1, nextStop));
|
||||
_animate(height, nextStop);
|
||||
}
|
||||
|
||||
bool get canClose {
|
||||
return widget.enableSheetInteraction!;
|
||||
}
|
||||
|
||||
void close({T? result}) {
|
||||
if (!_closing && canClose) {
|
||||
_closingHeight = height;
|
||||
_animationController!.stop();
|
||||
_dragging = false;
|
||||
_closing = true;
|
||||
Navigator.pop(context);
|
||||
}
|
||||
}
|
||||
|
||||
void _animate(double from, double to) {
|
||||
_tween!.begin = from;
|
||||
_tween!.end = to;
|
||||
_animationController!.value = 0;
|
||||
WidgetsBinding.instance.addPostFrameCallback((Duration timeStamp) {
|
||||
if (_scrollController != null && _scrollController!.hasClients) {
|
||||
if (_scrollController!.offset < 0) {
|
||||
_scrollController!.animateTo(0, duration: const Duration(seconds: 200), curve: Curves.linear);
|
||||
}
|
||||
}
|
||||
});
|
||||
_animationController!.fling().then((_) {
|
||||
_currentStop = _targetStop;
|
||||
setState(() {
|
||||
_scrollPhysics = _getScrollPhysicsForStop(_currentStop);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
get height {
|
||||
if (_closing) {
|
||||
return _closingHeight;
|
||||
} else if (_dragging) {
|
||||
return _stops![_currentStop!] + _dragOffset!;
|
||||
} else if (_animationController!.isAnimating) {
|
||||
return _animation!.value;
|
||||
} else {
|
||||
return _stops![_currentStop!];
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(
|
||||
top: widget.topInset ?? 0,
|
||||
),
|
||||
child: AnimatedBuilder(
|
||||
animation: _animation!,
|
||||
child: GestureDetector(
|
||||
onVerticalDragStart: (DragStartDetails details) {
|
||||
if (_currentStop != _targetStop) return;
|
||||
WidgetsBinding.instance.addPostFrameCallback((Duration timeStamp) {
|
||||
if (_scrollController != null && _scrollController!.hasClients) {
|
||||
_scrollController!.jumpTo(0);
|
||||
}
|
||||
});
|
||||
_dragging = true;
|
||||
_dragOffset = 0;
|
||||
setState(() {});
|
||||
},
|
||||
onVerticalDragUpdate: (DragUpdateDetails details) {
|
||||
if (_dragging) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((Duration timeStamp) {
|
||||
if (_scrollController != null && _scrollController!.hasClients) {
|
||||
_scrollController!.jumpTo(0);
|
||||
}
|
||||
});
|
||||
|
||||
_dragOffset = _dragOffset! - details.delta.dy;
|
||||
setState(() {});
|
||||
}
|
||||
},
|
||||
onVerticalDragEnd: (DragEndDetails details) {
|
||||
if (!_dragging || _closing) return;
|
||||
if (_dragOffset! > widget.dragThreshold) {
|
||||
_targetStop = min(_currentStop! + 1, _stops!.length - 1);
|
||||
} else if (_dragOffset! < -widget.dragThreshold) {
|
||||
_targetStop = max(canClose ? -1 : 0, _currentStop! - 1);
|
||||
}
|
||||
if (_targetStop! < 0) {
|
||||
close();
|
||||
} else {
|
||||
_dragging = false;
|
||||
_animate(_stops![_currentStop!] + _dragOffset!, _stops![_targetStop!]);
|
||||
}
|
||||
},
|
||||
child: widget.builder!(context, _scrollController!, _scrollPhysics!, _currentStop!),
|
||||
),
|
||||
builder: (BuildContext context, Widget? child) {
|
||||
return SizedBox(
|
||||
height: min(_stops![_stops!.length - 1], max(0, height)),
|
||||
child: ClipRRect(child: Container(color: Colors.transparent, child: child)),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
3
lib/src/sheet/src/widgets/widgets.exports.dart
Normal file
3
lib/src/sheet/src/widgets/widgets.exports.dart
Normal file
@@ -0,0 +1,3 @@
|
||||
export 'base.dart';
|
||||
export 'basic.sheet.dart';
|
||||
export 'scroller.sheet.dart';
|
||||
Reference in New Issue
Block a user