-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* LenraToggle added Co-authored-by: Louis G <louis@lenra.me>
- Loading branch information
Showing
4 changed files
with
256 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"dart.lineLength": 120 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:lenra_components/lenra_components.dart'; | ||
import 'package:lenra_components/theme/lenra_color_theme_data.dart'; | ||
|
||
//TODO: move this value in Theme | ||
const double THUMB_RADIUS_RATIO = 3; | ||
const double TRACK_WIDTH_RATIO = 5; | ||
const double TRACK_HEIGHT_RATIO = 3; | ||
const double THUMB_PADDING_RATIO = 0.25; | ||
|
||
class LenraToggle extends StatefulWidget { | ||
final bool value; | ||
final Function() onPressed; | ||
final Color activeColor = LenraColorThemeData.LENRA_FUN_GREEN_BASE; | ||
final Color inactiveColor = LenraColorThemeData.GREY_NATURE; | ||
final Color disabledColor = LenraColorThemeData.GREY_LIGHT; | ||
final String? label; | ||
final Color labelColor = LenraColorThemeData.BLACK_MOON; | ||
final Color disabledLabelColor = LenraColorThemeData.GREY_NATURE; | ||
final bool disabled; | ||
|
||
const LenraToggle({ | ||
required this.value, | ||
required this.onPressed, | ||
this.label, | ||
this.disabled = false, | ||
Key? key, | ||
}) : super(key: key); | ||
|
||
@override | ||
_LenraToggleState createState() => _LenraToggleState(); | ||
} | ||
|
||
class _LenraToggleState extends State<LenraToggle> with SingleTickerProviderStateMixin { | ||
late AnimationController _animationController; | ||
late CurvedAnimation animation; | ||
|
||
@override | ||
void initState() { | ||
super.initState(); | ||
_animationController = AnimationController(vsync: this, duration: Duration(milliseconds: 150)); | ||
animation = CurvedAnimation( | ||
parent: _animationController, | ||
curve: Curves.easeIn, | ||
reverseCurve: Curves.easeOut, | ||
); | ||
} | ||
|
||
@override | ||
void didUpdateWidget(LenraToggle oldWidget) { | ||
super.didUpdateWidget(oldWidget); | ||
if (oldWidget.value != widget.value) { | ||
if (widget.value) { | ||
_animationController.reverse(); | ||
} else { | ||
_animationController.forward(); | ||
} | ||
} | ||
} | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return widget.disabled ? _buildWidget() : _buildInteractiveWidget(); | ||
} | ||
|
||
Widget _buildInteractiveWidget() { | ||
return MouseRegion( | ||
cursor: SystemMouseCursors.click, | ||
child: GestureDetector( | ||
onTap: widget.onPressed, | ||
child: _buildWidget(), | ||
), | ||
); | ||
} | ||
|
||
Widget _buildWidget() { | ||
var lenraSwitch = _LenraSwitch(animation: animation, toggle: widget); | ||
if (widget.label == null) return lenraSwitch; | ||
return LenraRow( | ||
children: [ | ||
_buildLabel(), | ||
lenraSwitch, | ||
], | ||
); | ||
} | ||
|
||
Widget _buildLabel() { | ||
return Text( | ||
widget.label!, | ||
style: TextStyle( | ||
color: widget.disabled ? widget.disabledLabelColor : widget.labelColor, | ||
fontWeight: FontWeight.w400, | ||
fontSize: 15.0, | ||
), | ||
); | ||
} | ||
} | ||
|
||
class _LenraSwitch extends AnimatedWidget { | ||
final LenraToggle toggle; | ||
final Animation<double> animation; | ||
|
||
const _LenraSwitch({ | ||
Key? key, | ||
required this.animation, | ||
required this.toggle, | ||
}) : super(key: key, listenable: animation); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final LenraThemeData finalLenraThemeData = LenraTheme.of(context); | ||
|
||
final int thumbPadding = (finalLenraThemeData.baseSize * THUMB_PADDING_RATIO).toInt(); | ||
final double thumbRadius = (finalLenraThemeData.baseSize * THUMB_RADIUS_RATIO) - thumbPadding * 2; | ||
final double trackWidth = finalLenraThemeData.baseSize * TRACK_WIDTH_RATIO; | ||
final double trackHeight = finalLenraThemeData.baseSize * TRACK_HEIGHT_RATIO; | ||
final ColorTween colorTween = ColorTween(begin: toggle.inactiveColor, end: toggle.activeColor); | ||
final AlignmentTween alignTween = AlignmentTween(begin: Alignment.centerLeft, end: Alignment.centerRight); | ||
|
||
return Container( | ||
width: trackWidth, | ||
height: trackHeight, | ||
padding: EdgeInsets.only(left: thumbPadding.toDouble(), right: thumbPadding.toDouble()), | ||
decoration: BoxDecoration( | ||
borderRadius: BorderRadius.circular(trackHeight / 2), | ||
color: toggle.disabled ? toggle.disabledColor : colorTween.evaluate(this.animation)), | ||
child: Align( | ||
alignment: alignTween.evaluate(animation), | ||
child: Container( | ||
width: thumbRadius, | ||
height: thumbRadius, | ||
decoration: BoxDecoration( | ||
shape: BoxShape.circle, | ||
color: LenraColorThemeData.LENRA_WHITE, | ||
boxShadow: [ | ||
BoxShadow( | ||
offset: Offset(0, 2.0), | ||
blurRadius: 4.0, | ||
color: Colors.black.withOpacity(0.16), | ||
spreadRadius: 0, | ||
) | ||
], | ||
), | ||
), | ||
), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import 'package:flutter/cupertino.dart'; | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter/widgets.dart'; | ||
import 'package:flutter_test/flutter_test.dart'; | ||
import 'package:lenra_components/lenra_components.dart'; | ||
import '../../lib/component/lenra_toggle.dart'; | ||
|
||
import '../utils/lenra_page_test_help.dart'; | ||
|
||
void main() { | ||
test('LenraToggle test', () { | ||
LenraToggle component = LenraToggle(value: true, onPressed: () {}); | ||
expect(component is LenraToggle, true); | ||
}); | ||
|
||
testWidgets('LenraToggle without label', (WidgetTester tester) async { | ||
await tester.pumpWidget(createComponentTestWidgets( | ||
LenraToggle( | ||
value: true, | ||
onPressed: () {}, | ||
), | ||
)); | ||
|
||
expect((tester.widget(find.byType(LenraToggle))) is LenraToggle, true); | ||
expect((find.byType(Text)), findsNothing); | ||
}); | ||
testWidgets('LenraToggle with label', (WidgetTester tester) async { | ||
await tester.pumpWidget(createComponentTestWidgets( | ||
LenraToggle( | ||
value: true, | ||
onPressed: () {}, | ||
label: "test", | ||
), | ||
)); | ||
|
||
expect((tester.widget(find.byType(LenraRow)) as LenraRow).children.first is Text, true); | ||
}); | ||
testWidgets('LenraToggle size', (WidgetTester tester) async { | ||
await tester.pumpWidget(createComponentTestWidgets( | ||
LenraToggle( | ||
value: true, | ||
onPressed: () {}, | ||
), | ||
)); | ||
|
||
expect((tester.getSize(find.byType(LenraToggle)).width), equals(40)); | ||
expect((tester.getSize(find.byType(LenraToggle)).height), equals(24)); | ||
}); | ||
|
||
testWidgets('LenraToggle tap should change the state', (WidgetTester tester) async { | ||
bool value = false; | ||
await tester.pumpWidget(createComponentTestWidgets( | ||
LenraToggle( | ||
value: value, | ||
onPressed: () { | ||
value = !value; | ||
}, | ||
), | ||
)); | ||
expect(value, false); | ||
|
||
await tester.tap(find.byType(LenraToggle)); | ||
await tester.pumpAndSettle(); | ||
|
||
expect(value, true); | ||
}); | ||
} |