Skip to content

Commit

Permalink
fix/sheet-height (#117)
Browse files Browse the repository at this point in the history
  • Loading branch information
nank1ro authored Aug 1, 2024
1 parent 24f0974 commit 31face8
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 68 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
## 0.7.3

- Add `header` and `footer` to `ShadSelect` and `ShadSelectFormField`.
- Fix unintentional disposal of `controller` in `ShadSelect`.
- Add `mainAxisAlignment` and `crossAxisAlignment` to `ShadAlert`.
- Fix unintentional disposal of `controller` in `ShadSelect`.
- Remove assert about `icon` and `iconSrc` in `ShadAlert`, you can avoid using an icon now.
- Fix height of Sheet.

## 0.7.2

Expand Down
1 change: 1 addition & 0 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import 'package:flutter_solidart/flutter_solidart.dart';
import 'package:shadcn_ui/shadcn_ui.dart';

void main() {
SolidartConfig.devToolsEnabled = false;
runApp(const App());
}

Expand Down
8 changes: 8 additions & 0 deletions example/lib/pages/sheet.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:example/common/base_scaffold.dart';
import 'package:example/common/properties/bool_property.dart';
import 'package:example/common/properties/enum_property.dart';
import 'package:flutter/material.dart';
import 'package:shadcn_ui/shadcn_ui.dart';
Expand All @@ -17,6 +18,7 @@ class SheetPage extends StatefulWidget {

class _SheetPageState extends State<SheetPage> {
var side = ShadSheetSide.bottom;
var draggable = false;

@override
Widget build(BuildContext context) {
Expand All @@ -30,6 +32,11 @@ class _SheetPageState extends State<SheetPage> {
values: ShadSheetSide.values,
onChanged: (value) => setState(() => side = value),
),
MyBoolProperty(
label: 'Draggable',
value: draggable,
onChanged: (value) => setState(() => draggable = value),
),
],
children: [
ShadButton.outline(
Expand All @@ -40,6 +47,7 @@ class _SheetPageState extends State<SheetPage> {
side: side,
builder: (context) {
return ShadSheet(
draggable: draggable,
constraints:
side == ShadSheetSide.left || side == ShadSheetSide.right
? const BoxConstraints(maxWidth: 512)
Expand Down
170 changes: 105 additions & 65 deletions lib/src/components/sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,11 @@ class ShadSheet extends StatefulWidget {
this.onDragEnd,
this.animationController,
this.isScrollControlled = false,
this.minFlingVelocity = 700,
this.closeProgressThreshold = 0.5,
this.minFlingVelocity,
this.closeProgressThreshold,
this.enterDuration = const Duration(milliseconds: 250),
this.exitDuration = const Duration(milliseconds: 200),
this.disabledScrollControlMaxRatio,
});

final Widget? title;
Expand Down Expand Up @@ -247,26 +248,40 @@ class ShadSheet extends StatefulWidget {
/// is not just a passive observer.
final AnimationController? animationController;

/// {@template ShadSheet.minFlingVelocity}
/// The minimum velocity to initiate a fling.
///
/// Defaults to 700.
final double minFlingVelocity;
/// {@endtemplate}
final double? minFlingVelocity;

/// {@template ShadSheet.closeProgressThreshold}
/// The threshold for determining whether the sheet is closing.
///
/// Defaults to 0.5.
final double closeProgressThreshold;
/// {@endtemplate}
final double? closeProgressThreshold;

/// {@template ShadSheet.enterDuration}
/// The duration of the sheet's entrance animation.
///
/// Defaults to 250ms.
/// {@endtemplate}
final Duration enterDuration;

/// {@template ShadSheet.exitDuration}
/// The duration of the sheet's exit animation.
///
/// Defaults to 200ms.
/// {@endtemplate}
final Duration exitDuration;

/// {@template ShadSheet.disabledScrollControlMaxRatio}
/// The maximum ratio of the sheet's height when is not scroll controlled.
/// Defaults to 9/16. Has no effect when [draggable] is false.
/// {@endtemplate}
final double? disabledScrollControlMaxRatio;

@override
State<ShadSheet> createState() => _ShadSheetState();
}
Expand All @@ -275,7 +290,7 @@ class _ShadSheetState extends State<ShadSheet>
with SingleTickerProviderStateMixin {
AnimationController? _animationController;
final dragHandleMaterialState = <WidgetState>{};
final GlobalKey _childKey = GlobalKey(debugLabel: 'ShadSheet child');
final GlobalKey childKey = GlobalKey(debugLabel: 'ShadSheet child');

@override
void dispose() {
Expand All @@ -293,9 +308,8 @@ class _ShadSheetState extends State<ShadSheet>
value: 1,
));

double get _childHeight {
final renderBox =
_childKey.currentContext!.findRenderObject()! as RenderBox;
double get childHeight {
final renderBox = childKey.currentContext!.findRenderObject()! as RenderBox;
return renderBox.size.height;
}

Expand All @@ -318,17 +332,22 @@ class _ShadSheetState extends State<ShadSheet>

switch (side) {
case ShadSheetSide.bottom:
animationController.value -= details.primaryDelta! / _childHeight;
animationController.value -= details.primaryDelta! / childHeight;
case ShadSheetSide.top:
animationController.value += details.primaryDelta! / _childHeight;
animationController.value += details.primaryDelta! / childHeight;
case ShadSheetSide.left:
animationController.value += details.primaryDelta! / _childHeight;
animationController.value += details.primaryDelta! / childHeight;
case ShadSheetSide.right:
animationController.value -= details.primaryDelta! / _childHeight;
animationController.value -= details.primaryDelta! / childHeight;
}
}

void _handleDragEnd(DragEndDetails details, ShadSheetSide side) {
void _handleDragEnd(
DragEndDetails details, {
required ShadSheetSide side,
required double minFlingVelocity,
required double closeProgressThreshold,
}) {
if (_dismissUnderway) {
return;
}
Expand All @@ -339,15 +358,16 @@ class _ShadSheetState extends State<ShadSheet>
final velocity = side == ShadSheetSide.top
? details.velocity.pixelsPerSecond.dy
: -details.velocity.pixelsPerSecond.dy;
if (velocity.abs() > widget.minFlingVelocity) {
final flingVelocity = velocity / _childHeight;

if (velocity.abs() > minFlingVelocity) {
final flingVelocity = velocity / childHeight;
if (animationController.value > 0.0) {
animationController.fling(velocity: flingVelocity);
}
if (flingVelocity < 0.0) {
isClosing = true;
}
} else if (animationController.value < widget.closeProgressThreshold) {
} else if (animationController.value < closeProgressThreshold) {
if (animationController.value > 0.0) {
animationController.fling(velocity: -1);
}
Expand Down Expand Up @@ -475,60 +495,80 @@ class _ShadSheetState extends State<ShadSheet>
theme.sheetTheme.scrollPadding ??
MediaQuery.viewInsetsOf(context);

Widget child = AnimatedBuilder(
animation: animationController,
builder: (context, child) {
final animationValue = Easing.legacyDecelerate.transform(
animationController.view.value,
);
return ShadSheetLayoutWithSizeListener(
animationValue: animationValue,
onChildSizeChanged: (_) {},
scrollControlDisabledMaxRatio: 9.0 / 16.0,
isScrollControlled: widget.isScrollControlled,
side: side,
child: ShadDialog(
key: _childKey,
title: widget.title,
description: widget.description,
alignment: side.toAlignment(),
constraints: effectiveConstraints,
actions: widget.actions,
radius: effectiveRadius,
closeIcon: widget.closeIcon,
closeIconSrc: effectiveCloseIconSrc,
closeIconPosition: effectiveCloseIconPosition,
backgroundColor: effectiveBackgroundColor,
expandActionsWhenTiny: effectiveExpandActionsWhenTiny,
padding: effectivePadding,
gap: effectiveGap,
actionsAxis: effectiveActionsAxis,
actionsMainAxisSize: effectiveActionsMainAxisSize,
actionsMainAxisAlignment: effectiveActionsMainAxisAlignment,
actionsVerticalDirection: effectiveActionsVerticalDirection,
border: effectiveBorder,
shadows: effectiveShadows,
removeBorderRadiusWhenTiny: effectiveRemoveBorderRadiusWhenTiny,
titleStyle: effectiveTitleStyle,
descriptionStyle: effectiveDescriptionStyle,
titleTextAlign: effectiveTitleTextAlign,
descriptionTextAlign: effectiveDescriptionTextAlign,
crossAxisAlignment: effectiveCrossAxisAlignment,
mainAxisAlignment: effectiveMainAxisAlignment,
scrollable: effectiveScrollable,
scrollPadding: effectiveScrollPadding,
child: widget.child,
),
);
},
Widget child = ShadDialog(
key: childKey,
title: widget.title,
description: widget.description,
alignment: side.toAlignment(),
constraints: effectiveConstraints,
actions: widget.actions,
radius: effectiveRadius,
closeIcon: widget.closeIcon,
closeIconSrc: effectiveCloseIconSrc,
closeIconPosition: effectiveCloseIconPosition,
backgroundColor: effectiveBackgroundColor,
expandActionsWhenTiny: effectiveExpandActionsWhenTiny,
padding: effectivePadding,
gap: effectiveGap,
actionsAxis: effectiveActionsAxis,
actionsMainAxisSize: effectiveActionsMainAxisSize,
actionsMainAxisAlignment: effectiveActionsMainAxisAlignment,
actionsVerticalDirection: effectiveActionsVerticalDirection,
border: effectiveBorder,
shadows: effectiveShadows,
removeBorderRadiusWhenTiny: effectiveRemoveBorderRadiusWhenTiny,
titleStyle: effectiveTitleStyle,
descriptionStyle: effectiveDescriptionStyle,
titleTextAlign: effectiveTitleTextAlign,
descriptionTextAlign: effectiveDescriptionTextAlign,
crossAxisAlignment: effectiveCrossAxisAlignment,
mainAxisAlignment: effectiveMainAxisAlignment,
scrollable: effectiveScrollable,
scrollPadding: effectiveScrollPadding,
child: widget.child,
);

if (effectiveDraggable) {
final effectiveDisabledScrollControlMaxRatio =
widget.disabledScrollControlMaxRatio ??
theme.sheetTheme.disabledScrollControlMaxRatio ??
9 / 16;

final effectiveMinFlingVelocity =
widget.minFlingVelocity ?? theme.sheetTheme.minFlingVelocity ?? 700;

final effectiveCloseProgressThreshold = widget.closeProgressThreshold ??
theme.sheetTheme.closeProgressThreshold ??
0.5;

child = ShadSheetGestureDetector(
onDragStart: _handleDragStart,
onDragUpdate: (details) => _handleDragUpdate(details, side),
onDragEnd: (details) => _handleDragEnd(details, side),
onDragEnd: (details) => _handleDragEnd(
details,
side: side,
minFlingVelocity: effectiveMinFlingVelocity,
closeProgressThreshold: effectiveCloseProgressThreshold,
),
side: side,
child: child,
child: AnimatedBuilder(
animation: animationController,
builder: (context, child) {
final animationValue = Easing.legacyDecelerate.transform(
animationController.view.value,
);
return ShadSheetLayoutWithSizeListener(
animationValue: animationValue,
onChildSizeChanged: (_) {},
scrollControlDisabledMaxRatio:
effectiveDisabledScrollControlMaxRatio,
isScrollControlled: widget.isScrollControlled,
side: side,
child: child,
);
},
child: child,
),
);
}

Expand Down
Loading

0 comments on commit 31face8

Please sign in to comment.