diff --git a/README.md b/README.md
index f810cf73..2c39d769 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,9 @@
+
[![Pub][pub_badge]][pub] [![BuyMeACoffee][buy_me_a_coffee_badge]][buy_me_a_coffee]
[
][flutter_favorite] **Slidable is a [Flutter Favorite][flutter_favorite] package!**
-
# flutter_slidable
A Flutter implementation of slidable list item with directional slide actions that can be dismissed.
@@ -12,12 +12,12 @@ A Flutter implementation of slidable list item with directional slide actions th
Our top sponsors are shown below! [[Become a Sponsor](https://github.com/sponsors/letsar)]
-
+
@@ -28,16 +28,16 @@ You can read this small guide to migrate from the 0.6 to the 1.0 version: https:
## Features
-* Accepts start (left/top) and end (right/bottom) action panes.
-* Can be dismissed.
-* 4 built-in action panes.
-* 2 built-in slide action widgets.
-* 1 built-in dismiss animation.
-* You can easily create custom layouts and animations.
-* You can use a builder to create your slide actions if you want special effects during animation.
-* Closes when a slide action has been tapped (overridable).
-* Closes when the nearest `Scrollable` starts to scroll (overridable).
-* Option to disable the slide effect easily.
+- Accepts start (left/top) and end (right/bottom) action panes.
+- Can be dismissed.
+- 4 built-in action panes.
+- 2 built-in slide action widgets.
+- 1 built-in dismiss animation.
+- You can easily create custom layouts and animations.
+- You can use a builder to create your slide actions if you want special effects during animation.
+- Closes when a slide action has been tapped (overridable).
+- Closes when the nearest `Scrollable` starts to scroll (overridable).
+- Option to disable the slide effect easily.
## Install
@@ -78,14 +78,14 @@ Slidable(
onPressed: doNothing,
backgroundColor: Color(0xFFFE4A49),
foregroundColor: Colors.white,
- icon: Icons.delete,
+ icon: const Icon(Icons.delete),
label: 'Delete',
),
SlidableAction(
onPressed: doNothing,
backgroundColor: Color(0xFF21B7CA),
foregroundColor: Colors.white,
- icon: Icons.share,
+ icon: const Icon(Icons.share),
label: 'Share',
),
],
@@ -101,14 +101,14 @@ Slidable(
onPressed: doNothing,
backgroundColor: Color(0xFF7BC043),
foregroundColor: Colors.white,
- icon: Icons.archive,
+ icon: const Icon(Icons.archive),
label: 'Archive',
),
SlidableAction(
onPressed: doNothing,
backgroundColor: Color(0xFF0392CF),
foregroundColor: Colors.white,
- icon: Icons.save,
+ icon: const Icon(Icons.save),
label: 'Save',
),
],
@@ -188,10 +188,11 @@ I'm working on my packages on my free-time, but I don't have as much time as I w
Feel free to contribute to this project.
-If you find a bug or want a feature, but don't know how to fix/implement it, please fill an [issue][issue].
+If you find a bug or want a feature, but don't know how to fix/implement it, please fill an [issue][issue].
If you fixed a bug or implemented a feature, please send a [pull request][pr].
+
[github_action_badge]: https://github.com/letsar/flutter_slidable/workflows/Build/badge.svg
[github_action]: https://github.com/letsar/flutter_slidable/actions
[pub_badge]: https://img.shields.io/pub/v/flutter_slidable.svg
diff --git a/example/lib/main.dart b/example/lib/main.dart
index 4f0f48db..774f1d27 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -41,14 +41,14 @@ class _MyAppState extends State with SingleTickerProviderStateMixin {
onPressed: doNothing,
backgroundColor: Color(0xFFFE4A49),
foregroundColor: Colors.white,
- icon: Icons.delete,
+ icon: Icon(Icons.delete),
label: 'Delete',
),
SlidableAction(
onPressed: doNothing,
backgroundColor: Color(0xFF21B7CA),
foregroundColor: Colors.white,
- icon: Icons.share,
+ icon: Icon(Icons.share),
label: 'Share',
),
],
@@ -64,14 +64,14 @@ class _MyAppState extends State with SingleTickerProviderStateMixin {
onPressed: (_) => controller.openEndActionPane(),
backgroundColor: const Color(0xFF7BC043),
foregroundColor: Colors.white,
- icon: Icons.archive,
+ icon: Icon(Icons.archive),
label: 'Archive',
),
SlidableAction(
onPressed: (_) => controller.close(),
backgroundColor: const Color(0xFF0392CF),
foregroundColor: Colors.white,
- icon: Icons.save,
+ icon: Icon(Icons.save),
label: 'Save',
),
],
@@ -98,14 +98,14 @@ class _MyAppState extends State with SingleTickerProviderStateMixin {
onPressed: doNothing,
backgroundColor: Color(0xFFFE4A49),
foregroundColor: Colors.white,
- icon: Icons.delete,
+ icon: Icon(Icons.delete),
label: 'Delete',
),
SlidableAction(
onPressed: doNothing,
backgroundColor: Color(0xFF21B7CA),
foregroundColor: Colors.white,
- icon: Icons.share,
+ icon: Icon(Icons.share),
label: 'Share',
),
],
@@ -122,14 +122,14 @@ class _MyAppState extends State with SingleTickerProviderStateMixin {
onPressed: doNothing,
backgroundColor: Color(0xFF7BC043),
foregroundColor: Colors.white,
- icon: Icons.archive,
+ icon: Icon(Icons.archive),
label: 'Archive',
),
SlidableAction(
onPressed: doNothing,
backgroundColor: Color(0xFF0392CF),
foregroundColor: Colors.white,
- icon: Icons.save,
+ icon: Icon(Icons.save),
label: 'Save',
),
],
diff --git a/example/lib/main_demo.dart b/example/lib/main_demo.dart
index afb1b97d..825799fb 100644
--- a/example/lib/main_demo.dart
+++ b/example/lib/main_demo.dart
@@ -269,7 +269,7 @@ class SlideAction extends StatelessWidget {
onPressed: (_) {
print(icon);
},
- icon: icon,
+ icon: Icon(icon),
label: 'hello',
);
}
@@ -291,7 +291,7 @@ class Tile extends StatelessWidget {
return ActionTypeListener(
child: GestureDetector(
onTap: () {
- print('$text');
+ print(text);
},
onLongPress: () => Slidable.of(context)!.openEndActionPane(),
child: Container(
diff --git a/example/lib/main_example.dart b/example/lib/main_example.dart
index c782adf3..4c690047 100644
--- a/example/lib/main_example.dart
+++ b/example/lib/main_example.dart
@@ -218,7 +218,7 @@ class SlideAction extends StatelessWidget {
backgroundColor: color,
foregroundColor: Colors.white,
onPressed: (_) {},
- icon: icon,
+ icon: Icon(icon),
label: label,
);
}
diff --git a/example/lib/main_outside_list.dart b/example/lib/main_outside_list.dart
index cc5ede90..77e36242 100644
--- a/example/lib/main_outside_list.dart
+++ b/example/lib/main_outside_list.dart
@@ -202,7 +202,7 @@ class SlideAction extends StatelessWidget {
backgroundColor: color,
foregroundColor: Colors.white,
onPressed: (_) {},
- icon: icon,
+ icon: Icon(icon),
label: 'hello',
);
}
diff --git a/lib/src/actions.dart b/lib/src/actions.dart
index 418a9fb8..eb49ebd0 100644
--- a/lib/src/actions.dart
+++ b/lib/src/actions.dart
@@ -85,11 +85,8 @@ class CustomSlidableAction extends StatelessWidget {
@override
Widget build(BuildContext context) {
- final effectiveForegroundColor = foregroundColor ??
- (ThemeData.estimateBrightnessForColor(backgroundColor) ==
- Brightness.light
- ? Colors.black
- : Colors.white);
+ final effectiveForegroundColor =
+ foregroundColor ?? (ThemeData.estimateBrightnessForColor(backgroundColor) == Brightness.light ? Colors.black : Colors.white);
return Expanded(
flex: flex,
@@ -142,6 +139,7 @@ class SlidableAction extends StatelessWidget {
this.label,
this.borderRadius = BorderRadius.zero,
this.padding,
+ this.labelStyle,
}) : assert(flex > 0),
assert(icon != null || label != null),
super(key: key);
@@ -162,7 +160,7 @@ class SlidableAction extends StatelessWidget {
final SlidableActionCallback? onPressed;
/// An icon to display above the [label].
- final IconData? icon;
+ final Widget? icon;
/// The space between [icon] and [label] if both set.
///
@@ -178,13 +176,16 @@ class SlidableAction extends StatelessWidget {
/// Padding of the OutlinedButton
final EdgeInsets? padding;
+ /// The style to use for the [label].
+ final TextStyle? labelStyle;
+
@override
Widget build(BuildContext context) {
final children = [];
if (icon != null) {
children.add(
- Icon(icon),
+ icon!,
);
}
@@ -199,6 +200,7 @@ class SlidableAction extends StatelessWidget {
Text(
label!,
overflow: TextOverflow.ellipsis,
+ style: labelStyle,
),
);
}
diff --git a/test/actions_test.dart b/test/actions_test.dart
index 745a17a3..4cb84e83 100644
--- a/test/actions_test.dart
+++ b/test/actions_test.dart
@@ -80,7 +80,7 @@ void main() {
children: [
SlidableAction(
onPressed: (_) => logs.add('pressed'),
- icon: Icons.ac_unit,
+ icon: const Icon(Icons.ac_unit),
)
],
),
@@ -99,7 +99,7 @@ void main() {
children: [
SlidableAction(
onPressed: (_) => logs.add('pressed'),
- icon: Icons.ac_unit,
+ icon: const Icon(Icons.ac_unit),
label: 'my_label',
)
],
diff --git a/test/dismissible_pane_test.dart b/test/dismissible_pane_test.dart
index c63f7a20..1cc29670 100644
--- a/test/dismissible_pane_test.dart
+++ b/test/dismissible_pane_test.dart
@@ -1,4 +1,3 @@
-import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_slidable/src/action_pane_motions.dart';
import 'package:flutter_slidable/src/actions.dart';
@@ -34,8 +33,8 @@ void main() {
),
motion: const BehindMotion(),
children: [
- SlidableAction(onPressed: (_) {}, icon: Icons.share),
- SlidableAction(onPressed: (_) {}, icon: Icons.delete),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.share)),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.delete)),
],
),
child: const SizedBox.expand(),
@@ -77,8 +76,8 @@ void main() {
),
motion: const BehindMotion(),
children: [
- SlidableAction(onPressed: (_) {}, icon: Icons.share),
- SlidableAction(onPressed: (_) {}, icon: Icons.delete),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.share)),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.delete)),
],
),
child: const SizedBox.expand(),
@@ -124,8 +123,8 @@ void main() {
),
motion: const BehindMotion(),
children: [
- SlidableAction(onPressed: (_) {}, icon: Icons.share),
- SlidableAction(onPressed: (_) {}, icon: Icons.delete),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.share)),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.delete)),
],
),
child: const SizedBox.expand(),
@@ -149,9 +148,7 @@ void main() {
expect(dismissed, isTrue);
});
- testWidgets(
- 'startActionPane cannot be drag dismissed if dragDismissible is false',
- (tester) async {
+ testWidgets('startActionPane cannot be drag dismissed if dragDismissible is false', (tester) async {
bool dismissed = false;
void handleDismissed() {
dismissed = true;
@@ -174,8 +171,8 @@ void main() {
),
motion: const BehindMotion(),
children: [
- SlidableAction(onPressed: (_) {}, icon: Icons.share),
- SlidableAction(onPressed: (_) {}, icon: Icons.delete),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.share)),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.delete)),
],
),
child: const SizedBox.expand(),
@@ -199,9 +196,7 @@ void main() {
expect(dismissed, isFalse);
});
- testWidgets(
- 'when the drag is not past the dismissThreshold, the Slidable stays open',
- (tester) async {
+ testWidgets('when the drag is not past the dismissThreshold, the Slidable stays open', (tester) async {
bool dismissed = false;
void handleDismissed() {
dismissed = true;
@@ -226,8 +221,8 @@ void main() {
),
motion: const BehindMotion(),
children: [
- SlidableAction(onPressed: (_) {}, icon: Icons.share),
- SlidableAction(onPressed: (_) {}, icon: Icons.delete),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.share)),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.delete)),
],
),
child: const SizedBox.expand(),
@@ -282,8 +277,8 @@ void main() {
),
motion: const BehindMotion(),
children: [
- SlidableAction(onPressed: (_) {}, icon: Icons.share),
- SlidableAction(onPressed: (_) {}, icon: Icons.delete),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.share)),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.delete)),
],
),
child: const SizedBox.expand(),
@@ -340,8 +335,8 @@ void main() {
),
motion: const BehindMotion(),
children: [
- SlidableAction(onPressed: (_) {}, icon: Icons.share),
- SlidableAction(onPressed: (_) {}, icon: Icons.delete),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.share)),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.delete)),
],
),
child: Builder(
diff --git a/test/slidable_test.dart b/test/slidable_test.dart
index f2a5a477..48c7523e 100644
--- a/test/slidable_test.dart
+++ b/test/slidable_test.dart
@@ -1,4 +1,3 @@
-import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_slidable/src/action_pane_motions.dart';
import 'package:flutter_slidable/src/actions.dart';
@@ -7,9 +6,7 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('Slidable', () {
- testWidgets(
- 'child should be able to open the horitzontal start action pane',
- (tester) async {
+ testWidgets('child should be able to open the horitzontal start action pane', (tester) async {
const gestureDetectorKey = ValueKey('gesture_detector');
const startActionPaneKey = ValueKey('start');
const endActionPaneKey = ValueKey('end');
@@ -21,16 +18,16 @@ void main() {
key: startActionPaneKey,
motion: const BehindMotion(),
children: [
- SlidableAction(onPressed: (_) {}, icon: Icons.share),
- SlidableAction(onPressed: (_) {}, icon: Icons.delete),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.share)),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.delete)),
],
),
endActionPane: ActionPane(
key: endActionPaneKey,
motion: const ScrollMotion(),
children: [
- SlidableAction(onPressed: (_) {}, icon: Icons.share),
- SlidableAction(onPressed: (_) {}, icon: Icons.delete),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.share)),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.delete)),
],
),
child: Builder(builder: (context) {
@@ -55,8 +52,7 @@ void main() {
expect(find.byKey(endActionPaneKey), findsNothing);
});
- testWidgets('child should be able to open the horizontal end action pane',
- (tester) async {
+ testWidgets('child should be able to open the horizontal end action pane', (tester) async {
const gestureDetectorKey = ValueKey('gesture_detector');
const startActionPaneKey = ValueKey('start');
const endActionPaneKey = ValueKey('end');
@@ -68,16 +64,16 @@ void main() {
key: startActionPaneKey,
motion: const BehindMotion(),
children: [
- SlidableAction(onPressed: (_) {}, icon: Icons.share),
- SlidableAction(onPressed: (_) {}, icon: Icons.delete),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.share)),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.delete)),
],
),
endActionPane: ActionPane(
key: endActionPaneKey,
motion: const ScrollMotion(),
children: [
- SlidableAction(onPressed: (_) {}, icon: Icons.share),
- SlidableAction(onPressed: (_) {}, icon: Icons.delete),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.share)),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.delete)),
],
),
child: Builder(builder: (context) {
@@ -102,8 +98,7 @@ void main() {
expect(find.byKey(endActionPaneKey), findsOneWidget);
});
- testWidgets('child should be able to open the vertical start action pane',
- (tester) async {
+ testWidgets('child should be able to open the vertical start action pane', (tester) async {
const gestureDetectorKey = ValueKey('gesture_detector');
const startActionPaneKey = ValueKey('start');
const endActionPaneKey = ValueKey('end');
@@ -116,16 +111,16 @@ void main() {
key: startActionPaneKey,
motion: const BehindMotion(),
children: [
- SlidableAction(onPressed: (_) {}, icon: Icons.share),
- SlidableAction(onPressed: (_) {}, icon: Icons.delete),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.share)),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.delete)),
],
),
endActionPane: ActionPane(
key: endActionPaneKey,
motion: const ScrollMotion(),
children: [
- SlidableAction(onPressed: (_) {}, icon: Icons.share),
- SlidableAction(onPressed: (_) {}, icon: Icons.delete),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.share)),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.delete)),
],
),
child: Builder(builder: (context) {
@@ -150,8 +145,7 @@ void main() {
expect(find.byKey(endActionPaneKey), findsNothing);
});
- testWidgets('child should be able to open the vertical end action pane',
- (tester) async {
+ testWidgets('child should be able to open the vertical end action pane', (tester) async {
const gestureDetectorKey = ValueKey('gesture_detector');
const startActionPaneKey = ValueKey('start');
const endActionPaneKey = ValueKey('end');
@@ -164,16 +158,16 @@ void main() {
key: startActionPaneKey,
motion: const BehindMotion(),
children: [
- SlidableAction(onPressed: (_) {}, icon: Icons.share),
- SlidableAction(onPressed: (_) {}, icon: Icons.delete),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.share)),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.delete)),
],
),
endActionPane: ActionPane(
key: endActionPaneKey,
motion: const ScrollMotion(),
children: [
- SlidableAction(onPressed: (_) {}, icon: Icons.share),
- SlidableAction(onPressed: (_) {}, icon: Icons.delete),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.share)),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.delete)),
],
),
child: Builder(builder: (context) {
@@ -213,8 +207,8 @@ void main() {
key: endActionPaneKey,
motion: const ScrollMotion(),
children: [
- SlidableAction(onPressed: (_) {}, icon: Icons.share),
- SlidableAction(onPressed: (_) {}, icon: Icons.delete),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.share)),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.delete)),
],
),
child: Builder(
@@ -253,8 +247,8 @@ void main() {
key: startActionPaneKey,
motion: const ScrollMotion(),
children: [
- SlidableAction(onPressed: (_) {}, icon: Icons.share),
- SlidableAction(onPressed: (_) {}, icon: Icons.delete),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.share)),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.delete)),
],
),
child: Builder(
@@ -279,17 +273,15 @@ void main() {
expect(tester.getTopLeft(find.byKey(childKey)), const Offset(0, 0));
});
- testWidgets(
- 'should work if TextDirection.rtl and only startActionPane is set',
- (tester) async {
+ testWidgets('should work if TextDirection.rtl and only startActionPane is set', (tester) async {
const gestureDetectorKey = ValueKey('gesture_detector');
const actionPaneKey = ValueKey('action_pane');
final actionPane = ActionPane(
key: actionPaneKey,
motion: const BehindMotion(),
children: [
- SlidableAction(onPressed: (_) {}, icon: Icons.share),
- SlidableAction(onPressed: (_) {}, icon: Icons.delete),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.share)),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.delete)),
],
);
@@ -318,16 +310,15 @@ void main() {
expect(find.byKey(actionPaneKey), findsOneWidget);
});
- testWidgets('should work if TextDirection.rtl and only endActionPane is set',
- (tester) async {
+ testWidgets('should work if TextDirection.rtl and only endActionPane is set', (tester) async {
const gestureDetectorKey = ValueKey('gesture_detector');
const actionPaneKey = ValueKey('action_pane');
final actionPane = ActionPane(
key: actionPaneKey,
motion: const BehindMotion(),
children: [
- SlidableAction(onPressed: (_) {}, icon: Icons.share),
- SlidableAction(onPressed: (_) {}, icon: Icons.delete),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.share)),
+ SlidableAction(onPressed: (_) {}, icon: const Icon(Icons.delete)),
],
);