From a160450580eae58a2e1712a7f25fcec0914430e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kl=C3=BCpfel?= Date: Mon, 12 Aug 2024 09:00:47 +0200 Subject: [PATCH] 61: adds vertical() method to all switches --- example/ios/Runner.xcodeproj/project.pbxproj | 2 +- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- example/ios/Runner/AppDelegate.swift | 2 +- example/lib/crazy_switch.dart | 4 +- example/lib/load_switch.dart | 8 +- example/lib/main.dart | 241 +++++++++--------- example/pubspec.lock | 76 +++--- example/test/widget_test.dart | 2 +- lib/src/properties.dart | 4 + lib/src/widgets/animated_toggle_switch.dart | 15 +- .../custom_animated_toggle_switch.dart | 131 +++++++++- pubspec.lock | 241 ++++++------------ pubspec.yaml | 1 + test/vertical_test.dart | 27 ++ 14 files changed, 413 insertions(+), 343 deletions(-) create mode 100644 test/vertical_test.dart diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index c9f8f38..1f6541e 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -127,7 +127,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1430; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index b52b2e6..e67b280 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ { return CustomAnimatedToggleSwitch( current: current, spacing: 36.0, - values: [false, true], + values: const [false, true], animationDuration: const Duration(milliseconds: 350), animationCurve: Curves.bounceOut, iconBuilder: (context, local, global) => const SizedBox(), @@ -41,7 +41,7 @@ class _CrazySwitchState extends State { return Container( alignment: Alignment.center, decoration: - BoxDecoration(color: Colors.white, shape: BoxShape.circle), + const BoxDecoration(color: Colors.white, shape: BoxShape.circle), child: Container( width: innerIndicatorSize * 0.4 + global.position * innerIndicatorSize * 0.6, diff --git a/example/lib/load_switch.dart b/example/lib/load_switch.dart index d0b6748..a143004 100644 --- a/example/lib/load_switch.dart +++ b/example/lib/load_switch.dart @@ -19,9 +19,9 @@ class _LoadSwitchState extends State { const borderWidth = 5.0; return CustomAnimatedToggleSwitch( height: height, - indicatorSize: Size.square(height), + indicatorSize: const Size.square(height), current: value, - values: [false, true], + values: const [false, true], onChanged: (newValue) { setState(() => value = newValue); return Future.delayed(const Duration(seconds: 2)); @@ -42,8 +42,8 @@ class _LoadSwitchState extends State { return Stack( fit: StackFit.expand, children: [ - Padding( - padding: const EdgeInsets.all(borderWidth), + const Padding( + padding: EdgeInsets.all(borderWidth), child: DecoratedBox( decoration: BoxDecoration( shape: BoxShape.circle, color: Colors.white)), diff --git a/example/lib/main.dart b/example/lib/main.dart index 1dc36e7..ccd9449 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -9,27 +9,29 @@ import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher.dart'; void main() { - runApp(MyApp()); + runApp(const MyApp()); } class MyApp extends StatelessWidget { + const MyApp({super.key}); + @override Widget build(BuildContext context) { return MaterialApp( title: 'AnimatedToggleSwitch Demo', theme: ThemeData(scaffoldBackgroundColor: Colors.white), - home: MyHomePage(title: 'Example'), + home: const MyHomePage(title: 'AnimatedToggleSwitch'), ); } } class MyHomePage extends StatefulWidget { - MyHomePage({Key? key, required this.title}) : super(key: key); + const MyHomePage({Key? key, required this.title}) : super(key: key); final String title; @override - _MyHomePageState createState() => _MyHomePageState(); + State createState() => _MyHomePageState(); } class _MyHomePageState extends State { @@ -54,41 +56,43 @@ class _MyHomePageState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Padding( - padding: const EdgeInsets.all(8.0), + const Padding( + padding: EdgeInsets.all(8.0), child: Text( 'AnimatedToggleSwitch.dual:', ), ), - AnimatedToggleSwitch.dual( - current: positive, - first: false, - second: true, - spacing: 50.0, - style: const ToggleStyle( - borderColor: Colors.transparent, - boxShadow: const [ - BoxShadow( - color: Colors.black26, - spreadRadius: 1, - blurRadius: 2, - offset: Offset(0, 1.5), - ), - ], + SizedBox( + child: AnimatedToggleSwitch.dual( + current: positive, + first: false, + second: true, + spacing: 50.0, + style: const ToggleStyle( + borderColor: Colors.transparent, + boxShadow: [ + BoxShadow( + color: Colors.black26, + spreadRadius: 1, + blurRadius: 2, + offset: Offset(0, 1.5), + ), + ], + ), + borderWidth: 5.0, + height: 55, + onChanged: (b) => setState(() => positive = b), + styleBuilder: (b) => ToggleStyle( + indicatorColor: b ? Colors.red : Colors.green), + iconBuilder: (value) => value + ? const Icon(Icons.coronavirus_rounded) + : const Icon(Icons.tag_faces_rounded), + textBuilder: (value) => value + ? const Center(child: Text('Oh no...')) + : const Center(child: Text('Nice :)')), ), - borderWidth: 5.0, - height: 55, - onChanged: (b) => setState(() => positive = b), - styleBuilder: (b) => - ToggleStyle(indicatorColor: b ? Colors.red : Colors.green), - iconBuilder: (value) => value - ? Icon(Icons.coronavirus_rounded) - : Icon(Icons.tag_faces_rounded), - textBuilder: (value) => value - ? Center(child: Text('Oh no...')) - : Center(child: Text('Nice :)')), ), - SizedBox(height: 16.0), + const SizedBox(height: 16.0), AnimatedToggleSwitch.dual( current: positive, first: false, @@ -96,7 +100,7 @@ class _MyHomePageState extends State { spacing: 50.0, style: const ToggleStyle( borderColor: Colors.transparent, - boxShadow: const [ + boxShadow: [ BoxShadow( color: Colors.black26, spreadRadius: 1, @@ -130,28 +134,29 @@ class _MyHomePageState extends State { child: Text('Off', style: TextStyle(color: Colors.white))), ), - SizedBox(height: 16.0), + const SizedBox(height: 16.0), DefaultTextStyle.merge( style: const TextStyle( color: Colors.white, fontSize: 18.0, fontWeight: FontWeight.bold), child: IconTheme.merge( - data: IconThemeData(color: Colors.white), + data: const IconThemeData(color: Colors.white), child: AnimatedToggleSwitch.dual( current: positive, first: false, second: true, spacing: 45.0, animationDuration: const Duration(milliseconds: 600), - style: ToggleStyle( + style: const ToggleStyle( borderColor: Colors.transparent, indicatorColor: Colors.white, backgroundColor: Colors.black, ), customStyleBuilder: (context, local, global) { - if (global.position <= 0.0) + if (global.position <= 0.0) { return ToggleStyle(backgroundColor: Colors.red[800]); + } return ToggleStyle( backgroundGradient: LinearGradient( colors: [green, Colors.red[800]!], @@ -171,17 +176,17 @@ class _MyHomePageState extends State { Colors.red[800], green, global.position)), onChanged: (b) => setState(() => positive = b), iconBuilder: (value) => value - ? Icon(Icons.power_outlined, color: green, size: 32.0) + ? const Icon(Icons.power_outlined, color: green, size: 32.0) : Icon(Icons.power_settings_new_rounded, color: Colors.red[800], size: 32.0), textBuilder: (value) => value - ? Center(child: Text('Active')) - : Center(child: Text('Inactive')), + ? const Center(child: Text('Active')) + : const Center(child: Text('Inactive')), ), ), ), - Padding( - padding: const EdgeInsets.all(8.0), + const Padding( + padding: EdgeInsets.all(8.0), child: Text( 'AnimatedToggleSwitch.dual with loading animation:', ), @@ -189,7 +194,7 @@ class _MyHomePageState extends State { DefaultTextStyle.merge( style: const TextStyle(color: Colors.white), child: IconTheme.merge( - data: IconThemeData(color: Colors.white), + data: const IconThemeData(color: Colors.white), child: AnimatedToggleSwitch.dual( current: positive, first: false, @@ -199,7 +204,7 @@ class _MyHomePageState extends State { borderColor: Colors.transparent, backgroundColor: Colors.black, borderRadius: BorderRadius.all(Radius.circular(4.0)), - boxShadow: const [ + boxShadow: [ BoxShadow( color: Colors.purple, spreadRadius: 1, @@ -214,36 +219,36 @@ class _MyHomePageState extends State { const CupertinoActivityIndicator(color: Colors.white), onChanged: (b) { setState(() => positive = b); - return Future.delayed(Duration(seconds: 2)); + return Future.delayed(const Duration(seconds: 2)); }, styleBuilder: (b) => ToggleStyle( indicatorColor: b ? Colors.purple : Colors.green), iconBuilder: (value) => value - ? Icon(Icons.coronavirus_rounded) - : Icon(Icons.tag_faces_rounded), + ? const Icon(Icons.coronavirus_rounded) + : const Icon(Icons.tag_faces_rounded), textBuilder: (value) => value - ? Center( + ? const Center( child: Text('Oh no...', - style: const TextStyle(color: Colors.white))) - : Center(child: Text('Nice :)')), + style: TextStyle(color: Colors.white))) + : const Center(child: Text('Nice :)')), ), ), ), - SizedBox(height: 16.0), + const SizedBox(height: 16.0), AnimatedToggleSwitch.dual( current: positive, first: false, second: true, spacing: 45.0, animationDuration: const Duration(milliseconds: 600), - style: ToggleStyle( + style: const ToggleStyle( borderColor: Colors.transparent, indicatorColor: Colors.white, backgroundColor: Colors.amber, ), customStyleBuilder: (context, local, global) => ToggleStyle( backgroundGradient: LinearGradient( - colors: [Colors.green, Colors.red], + colors: const [Colors.green, Colors.red], stops: [ global.position - (1 - 2 * max(0, global.position - 0.5)) * 0.5, @@ -258,12 +263,12 @@ class _MyHomePageState extends State { Colors.red, Colors.green, global.position)), onChanged: (b) { setState(() => positive = b); - return Future.delayed(Duration(seconds: 2)); + return Future.delayed(const Duration(seconds: 2)); }, iconBuilder: (value) => value - ? Icon(Icons.power_outlined, + ? const Icon(Icons.power_outlined, color: Colors.green, size: 32.0) - : Icon(Icons.power_settings_new_rounded, + : const Icon(Icons.power_settings_new_rounded, color: Colors.red, size: 32.0), textBuilder: (value) => Center( child: Text( @@ -278,7 +283,7 @@ class _MyHomePageState extends State { padding: const EdgeInsets.all(8.0), child: Text.rich( TextSpan(children: [ - TextSpan(text: 'Switch inspired by package '), + const TextSpan(text: 'Switch inspired by package '), TextSpan( text: 'lite_rolling_switch', style: tappableTextStyle, @@ -293,7 +298,7 @@ class _MyHomePageState extends State { fontSize: 18.0, fontWeight: FontWeight.bold), child: IconTheme.merge( - data: IconThemeData(color: Colors.white), + data: const IconThemeData(color: Colors.white), child: AnimatedToggleSwitch.dual( current: positive, first: false, @@ -301,7 +306,7 @@ class _MyHomePageState extends State { spacing: 45.0, animationCurve: Curves.easeInOut, animationDuration: const Duration(milliseconds: 600), - style: ToggleStyle( + style: const ToggleStyle( borderColor: Colors.transparent, indicatorColor: Colors.white, backgroundColor: Colors.black, @@ -316,15 +321,15 @@ class _MyHomePageState extends State { Colors.red[800], green, global.position)), onChanged: (b) => setState(() => positive = b), iconBuilder: (value) => value - ? Icon(Icons.lightbulb_outline_rounded, + ? const Icon(Icons.lightbulb_outline_rounded, color: green, size: 28.0) : Icon(Icons.power_settings_new_rounded, color: Colors.red[800], size: 30.0), textBuilder: (value) => value - ? Align( + ? const Align( alignment: AlignmentDirectional.centerStart, child: Text('Active')) - : Align( + : const Align( alignment: AlignmentDirectional.centerEnd, child: Text('Inactive')), ), @@ -334,7 +339,7 @@ class _MyHomePageState extends State { padding: const EdgeInsets.all(8.0), child: Text.rich( TextSpan(children: [ - TextSpan(text: 'Switch inspired by package '), + const TextSpan(text: 'Switch inspired by package '), TextSpan( text: 'toggle_switch', style: tappableTextStyle, @@ -346,8 +351,8 @@ class _MyHomePageState extends State { AnimatedToggleSwitch.size( current: min(value, 2), style: ToggleStyle( - backgroundColor: Color(0xFF919191), - indicatorColor: Color(0xFFEC3345), + backgroundColor: const Color(0xFF919191), + indicatorColor: const Color(0xFFEC3345), borderColor: Colors.transparent, borderRadius: BorderRadius.circular(10.0), indicatorBorderRadius: BorderRadius.zero, @@ -383,7 +388,7 @@ class _MyHomePageState extends State { padding: const EdgeInsets.all(8.0), child: Text.rich( TextSpan(children: [ - TextSpan(text: 'Switch inspired by '), + const TextSpan(text: 'Switch inspired by '), TextSpan( text: 'Crazy Switch', style: tappableTextStyle, @@ -392,15 +397,15 @@ class _MyHomePageState extends State { ]), ), ), - Padding( - padding: const EdgeInsets.only(top: 8.0, bottom: 16.0), - child: const CrazySwitch(), + const Padding( + padding: EdgeInsets.only(top: 8.0, bottom: 16.0), + child: CrazySwitch(), ), Padding( padding: const EdgeInsets.all(8.0), child: Text.rich( TextSpan(children: [ - TextSpan(text: 'Switch inspired by '), + const TextSpan(text: 'Switch inspired by '), TextSpan( text: 'load_switch', style: tappableTextStyle, @@ -409,12 +414,12 @@ class _MyHomePageState extends State { ]), ), ), - Padding( - padding: const EdgeInsets.only(top: 8.0, bottom: 16.0), - child: const LoadSwitch(), + const Padding( + padding: EdgeInsets.only(top: 8.0, bottom: 16.0), + child: LoadSwitch(), ), - Padding( - padding: const EdgeInsets.all(8.0), + const Padding( + padding: EdgeInsets.all(8.0), child: Text( 'Standard AnimatedToggleSwitch.rolling:', ), @@ -425,12 +430,12 @@ class _MyHomePageState extends State { values: const [0, 1, 2, 3], onChanged: (i) { setState(() => value = i); - return Future.delayed(Duration(seconds: 3)); + return Future.delayed(const Duration(seconds: 3)); }, iconBuilder: rollingIconBuilder, ), - Padding( - padding: const EdgeInsets.all(8.0), + const Padding( + padding: EdgeInsets.all(8.0), child: Text( 'Switch with unselected value:', ), @@ -449,13 +454,13 @@ class _MyHomePageState extends State { return ToggleStyle(borderColor: color, indicatorColor: color); }, ), - Padding( - padding: const EdgeInsets.all(8.0), + const Padding( + padding: EdgeInsets.all(8.0), child: Text( 'Customized AnimatedToggleSwitch.rolling:', ), ), - SizedBox(height: 16.0), + const SizedBox(height: 16.0), AnimatedToggleSwitch.rolling( active: false, current: value, @@ -466,13 +471,13 @@ class _MyHomePageState extends State { value = i; loading = true; }); - return Future.delayed(Duration(seconds: 3)) + return Future.delayed(const Duration(seconds: 3)) .then((_) => setState(() => loading = false)); }, iconBuilder: rollingIconBuilder, - style: ToggleStyle( + style: const ToggleStyle( borderColor: Colors.transparent, - indicatorBoxShadow: const [ + indicatorBoxShadow: [ BoxShadow( color: Colors.black26, spreadRadius: 1, @@ -480,7 +485,7 @@ class _MyHomePageState extends State { offset: Offset(0, 1.5), ) ], - boxShadow: const [ + boxShadow: [ BoxShadow( color: Colors.black26, spreadRadius: 1, @@ -490,17 +495,17 @@ class _MyHomePageState extends State { ], ), ), - SizedBox(height: 16.0), + const SizedBox(height: 16.0), IconTheme.merge( - data: IconThemeData(color: Colors.white), + data: const IconThemeData(color: Colors.white), child: AnimatedToggleSwitch.rolling( current: value, values: const [0, 1, 2, 3], onChanged: (i) => setState(() => value = i), - style: ToggleStyle( + style: const ToggleStyle( indicatorColor: Colors.white, borderColor: Colors.transparent, - boxShadow: const [ + boxShadow: [ BoxShadow( color: Colors.black26, spreadRadius: 1, @@ -520,7 +525,7 @@ class _MyHomePageState extends State { ), ), ), - SizedBox(height: 16.0), + const SizedBox(height: 16.0), AnimatedToggleSwitch.rolling( current: value, allowUnlistedValues: true, @@ -543,7 +548,7 @@ class _MyHomePageState extends State { spacing: 20.0, loading: loading, ), - SizedBox(height: 16.0), + const SizedBox(height: 16.0), AnimatedToggleSwitch.rolling( current: nullableValue, allowUnlistedValues: true, @@ -556,34 +561,35 @@ class _MyHomePageState extends State { onChanged: (i) => setState(() => nullableValue = i), iconBuilder: rollingIconBuilder, borderWidth: 4.5, - style: ToggleStyle( + style: const ToggleStyle( indicatorColor: Colors.white, backgroundGradient: - const LinearGradient(colors: [Colors.red, Colors.blue]), + LinearGradient(colors: [Colors.red, Colors.blue]), borderColor: Colors.transparent, ), height: 55, spacing: 20.0, loading: loading, ), - Padding( - padding: const EdgeInsets.all(8.0), + const Padding( + padding: EdgeInsets.all(8.0), child: Text( 'You can make any other switch with CustomAnimatedToggleSwitch:', ), ), CustomAnimatedToggleSwitch( current: positive, - values: [false, true], + values: const [false, true], spacing: 0.0, - indicatorSize: Size.square(30.0), + indicatorSize: const Size.square(30.0), animationDuration: const Duration(milliseconds: 200), animationCurve: Curves.linear, onChanged: (b) => setState(() => positive = b), iconBuilder: (context, local, global) { return const SizedBox(); }, - cursors: ToggleCursors(defaultCursor: SystemMouseCursors.click), + cursors: const ToggleCursors( + defaultCursor: SystemMouseCursors.click), onTap: (_) => setState(() => positive = !positive), iconsTappable: false, wrapperBuilder: (context, global, child) { @@ -596,10 +602,8 @@ class _MyHomePageState extends State { height: 20.0, child: DecoratedBox( decoration: BoxDecoration( - color: Color.lerp( - Colors.black26, - theme.colorScheme.background, - global.position), + color: Color.lerp(Colors.black26, + theme.colorScheme.surface, global.position), borderRadius: const BorderRadius.all(Radius.circular(50.0)), ), @@ -615,7 +619,8 @@ class _MyHomePageState extends State { decoration: BoxDecoration( color: Color.lerp( Colors.white, theme.primaryColor, global.position), - borderRadius: BorderRadius.all(Radius.circular(50.0)), + borderRadius: + const BorderRadius.all(Radius.circular(50.0)), boxShadow: const [ BoxShadow( color: Colors.black38, @@ -628,8 +633,8 @@ class _MyHomePageState extends State { ); }, ), - Padding( - padding: const EdgeInsets.all(8.0), + const Padding( + padding: EdgeInsets.all(8.0), child: Text( 'AnimatedToggleSwitch.size with some custom settings:', ), @@ -643,7 +648,7 @@ class _MyHomePageState extends State { styleAnimationType: AnimationType.onHover, iconBuilder: (value) => Icon( value.isEven ? Icons.cancel : Icons.access_time_rounded), - style: ToggleStyle( + style: const ToggleStyle( borderColor: Colors.transparent, ), borderWidth: 0.0, @@ -656,7 +661,7 @@ class _MyHomePageState extends State { }, onChanged: (i) { setState(() => value = i); - return Future.delayed(Duration(seconds: 3)); + return Future.delayed(const Duration(seconds: 3)); }, ), const SizedBox(height: 16.0), @@ -673,7 +678,7 @@ class _MyHomePageState extends State { borderColor: Colors.transparent, borderRadius: BorderRadius.circular(10.0), boxShadow: [ - BoxShadow( + const BoxShadow( color: Colors.black26, spreadRadius: 1, blurRadius: 2, @@ -703,7 +708,7 @@ class _MyHomePageState extends State { borderColor: Colors.transparent, borderRadius: BorderRadius.circular(10.0), boxShadow: [ - BoxShadow( + const BoxShadow( color: Colors.black26, spreadRadius: 1, blurRadius: 2, @@ -714,8 +719,8 @@ class _MyHomePageState extends State { selectedIconScale: 1.0, onChanged: (b) => setState(() => positive = b), ), - Padding( - padding: const EdgeInsets.all(8.0), + const Padding( + padding: EdgeInsets.all(8.0), child: Text( 'AnimatedToggleSwitch.size with a more custom icon and TextDirection.rtl:', ), @@ -735,14 +740,14 @@ class _MyHomePageState extends State { ], ); }, - style: ToggleStyle(borderColor: Colors.transparent), + style: const ToggleStyle(borderColor: Colors.transparent), styleBuilder: (i) => ToggleStyle( indicatorColor: i.isEven == true ? Colors.amber : Colors.red), onChanged: (i) => setState(() => value = i), ), - Padding( - padding: const EdgeInsets.all(8.0), + const Padding( + padding: EdgeInsets.all(8.0), child: Text( 'AnimatedToggleSwitch.size with custom rotating animation:', ), @@ -778,8 +783,8 @@ class _MyHomePageState extends State { i.isEven == true ? Colors.green : Colors.tealAccent), onChanged: (i) => setState(() => value = i), ), - Padding( - padding: const EdgeInsets.all(8.0), + const Padding( + padding: EdgeInsets.all(8.0), child: Text( 'AnimatedToggleSwitch.rollingByHeight with custom indicatorSize and borderRadius:', ), @@ -792,7 +797,7 @@ class _MyHomePageState extends State { iconBuilder: rollingIconBuilder, indicatorSize: const Size.fromWidth(2), ), - SizedBox(height: 16.0), + const SizedBox(height: 16.0), AnimatedToggleSwitch.rollingByHeight( height: 50.0, current: value, diff --git a/example/pubspec.lock b/example/pubspec.lock index 9a178cc..3bf754a 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -75,26 +75,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" matcher: dependency: transitive description: @@ -107,18 +107,18 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.15.0" path: dependency: transitive description: @@ -131,10 +131,10 @@ packages: dependency: transitive description: name: plugin_platform_interface - sha256: "43798d895c929056255600343db8f049921cbec94d31ec87f1dc5c16c01935dd" + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.1.8" sky_engine: dependency: transitive description: flutter @@ -184,74 +184,74 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.2" url_launcher: dependency: "direct main" description: name: url_launcher - sha256: "781bd58a1eb16069412365c98597726cd8810ae27435f04b3b4d3a470bacd61e" + sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3" url: "https://pub.dev" source: hosted - version: "6.1.12" + version: "6.3.0" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: "3dd2388cc0c42912eee04434531a26a82512b9cb1827e0214430c9bcbddfe025" + sha256: "94d8ad05f44c6d4e2ffe5567ab4d741b82d62e3c8e288cc1fcea45965edf47c9" url: "https://pub.dev" source: hosted - version: "6.0.38" + version: "6.3.8" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2" + sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "6.3.1" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - sha256: "207f4ddda99b95b4d4868320a352d374b0b7e05eefad95a4a26f57da413443f5" + sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.2.0" url_launcher_macos: dependency: transitive description: name: url_launcher_macos - sha256: "1c4fdc0bfea61a70792ce97157e5cc17260f61abbe4f39354513f39ec6fd73b1" + sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de" url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "3.2.0" url_launcher_platform_interface: dependency: transitive description: name: url_launcher_platform_interface - sha256: bfdfa402f1f3298637d71ca8ecfe840b4696698213d5346e9d12d4ab647ee2ea + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.3.2" url_launcher_web: dependency: transitive description: name: url_launcher_web - sha256: cc26720eefe98c1b71d85f9dc7ef0cada5132617046369d9dc296b3ecaa5cbb4 + sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e" url: "https://pub.dev" source: hosted - version: "2.0.18" + version: "2.3.3" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - sha256: "7967065dd2b5fccc18c653b97958fdf839c5478c28e767c61ee879f4e7882422" + sha256: "49c10f879746271804767cb45551ec5592cdab00ee105c06dddde1a98f73b185" url: "https://pub.dev" source: hosted - version: "3.0.7" + version: "3.1.2" vector_math: dependency: transitive description: @@ -264,10 +264,18 @@ packages: dependency: transitive description: name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc + url: "https://pub.dev" + source: hosted + version: "14.2.4" + web: + dependency: transitive + description: + name: web + sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062 url: "https://pub.dev" source: hosted - version: "13.0.0" + version: "1.0.0" sdks: - dart: ">=3.2.0-0 <4.0.0" - flutter: ">=3.10.0" + dart: ">=3.4.0 <4.0.0" + flutter: ">=3.22.0" diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart index 49fe357..da833c4 100644 --- a/example/test/widget_test.dart +++ b/example/test/widget_test.dart @@ -3,6 +3,6 @@ import 'package:flutter_test/flutter_test.dart'; void main() { testWidgets('App starts successfully', (WidgetTester tester) async { - await tester.pumpWidget(MyApp()); + await tester.pumpWidget(const MyApp()); }); } diff --git a/lib/src/properties.dart b/lib/src/properties.dart index 59c042f..14eb976 100644 --- a/lib/src/properties.dart +++ b/lib/src/properties.dart @@ -55,6 +55,8 @@ class GlobalToggleProperties { final bool active; + final bool vertical; + /// This animation indicates whether the indicator is currently visible. /// /// [0.0] means it is not visible. @@ -77,6 +79,7 @@ class GlobalToggleProperties { required this.mode, required this.loadingAnimationValue, required this.active, + required this.vertical, required Animation indicatorAppearingAnimation, }) : _indicatorAppearingAnimation = indicatorAppearingAnimation; } @@ -112,6 +115,7 @@ class DetailedGlobalToggleProperties extends GlobalToggleProperties { required super.loadingAnimationValue, required super.active, required super.indicatorAppearingAnimation, + required super.vertical, }); } diff --git a/lib/src/widgets/animated_toggle_switch.dart b/lib/src/widgets/animated_toggle_switch.dart index 0b1311f..2f74f22 100644 --- a/lib/src/widgets/animated_toggle_switch.dart +++ b/lib/src/widgets/animated_toggle_switch.dart @@ -977,6 +977,8 @@ class AnimatedToggleSwitch AlignmentGeometry alignment = start ? AlignmentDirectional.centerStart : AlignmentDirectional.centerEnd; + final finalOffset = + global.vertical ? Offset(offset.dy, offset.dx) : offset; return Align( alignment: alignment, @@ -993,7 +995,7 @@ class AnimatedToggleSwitch child: Padding( padding: textMargin, child: Transform.translate( - offset: offset * local.animationValue * (left ? 1 : -1), + offset: (finalOffset * local.animationValue * (left ? 1 : -1)), child: Center( child: Opacity( opacity: opacityAnimation @@ -1017,6 +1019,13 @@ class AnimatedToggleSwitch }; } + /// {@macro animated_toggle_switch.method.vertical} + Widget vertical() { + return Builder(builder: (context) { + return _build(context).vertical(); + }); + } + static Widget _defaultLoadingIconBuilder(BuildContext context, DetailedGlobalToggleProperties properties) => const _MyLoading(); @@ -1043,6 +1052,10 @@ class AnimatedToggleSwitch @override Widget build(BuildContext context) { + return _build(context); + } + + CustomAnimatedToggleSwitch _build(BuildContext context) { ThemeData theme = Theme.of(context); BorderRadiusGeometry defaultBorderRadius = BorderRadius.circular(height / 2); diff --git a/lib/src/widgets/custom_animated_toggle_switch.dart b/lib/src/widgets/custom_animated_toggle_switch.dart index 7592a91..679e25d 100644 --- a/lib/src/widgets/custom_animated_toggle_switch.dart +++ b/lib/src/widgets/custom_animated_toggle_switch.dart @@ -193,6 +193,8 @@ class CustomAnimatedToggleSwitch extends StatefulWidget { /// Listener for the current position and [ToggleMode] of the indicator. final PositionListener? positionListener; + final bool _vertical; + const CustomAnimatedToggleSwitch({ Key? key, required this.current, @@ -228,15 +230,124 @@ class CustomAnimatedToggleSwitch extends StatefulWidget { this.allowUnlistedValues = false, this.active = true, this.positionListener, - }) : assert(foregroundIndicatorBuilder != null || + }) : _vertical = false, + assert(foregroundIndicatorBuilder != null || backgroundIndicatorBuilder != null), assert(separatorBuilder == null || (spacing > 0 && iconArrangement == IconArrangement.row)), super(key: key); + const CustomAnimatedToggleSwitch._({ + required this.current, + required this.values, + required this.wrapperBuilder, + required this.iconBuilder, + required this.foregroundIndicatorBuilder, + required this.backgroundIndicatorBuilder, + required this.indicatorAppearingBuilder, + required this.animationDuration, + required this.animationCurve, + required this.loadingAnimationDuration, + required this.loadingAnimationCurve, + required this.indicatorAppearingDuration, + required this.indicatorAppearingCurve, + required this.indicatorSize, + required this.onChanged, + required this.spacing, + required this.separatorBuilder, + required this.onTap, + required this.iconsTappable, + required this.iconArrangement, + required this.fittingMode, + required this.height, + required this.padding, + required this.minTouchTargetSize, + required this.dragStartDuration, + required this.dragStartCurve, + required this.textDirection, + required this.cursors, + required this.loading, + required this.allowUnlistedValues, + required this.active, + required this.positionListener, + required bool vertical, + }) : _vertical = vertical; + @override State> createState() => _CustomAnimatedToggleSwitchState(); + + /// {@template animated_toggle_switch.method.vertical} + /// Rotates this switch and its builders and returns a vertical version of itself. + /// {@endtemplate} + Widget vertical() { + if (_vertical) return this; + + return RotatedBox( + quarterTurns: 1, + child: CustomAnimatedToggleSwitch._( + vertical: true, + current: current, + values: values, + iconBuilder: (context, global, local) => RotatedBox( + quarterTurns: -1, + child: iconBuilder(context, global, local), + ), + indicatorAppearingBuilder: (context, value, indicator) => RotatedBox( + quarterTurns: -1, + child: indicatorAppearingBuilder( + context, + value, + RotatedBox(quarterTurns: 1, child: indicator), + ), + ), + animationDuration: animationDuration, + animationCurve: animationCurve, + indicatorAppearingDuration: indicatorAppearingDuration, + indicatorAppearingCurve: indicatorAppearingCurve, + indicatorSize: indicatorSize, + spacing: spacing, + iconsTappable: iconsTappable, + iconArrangement: iconArrangement, + fittingMode: fittingMode, + height: height, + padding: padding, + minTouchTargetSize: minTouchTargetSize, + dragStartDuration: dragStartDuration, + dragStartCurve: dragStartCurve, + cursors: cursors, + allowUnlistedValues: allowUnlistedValues, + active: active, + wrapperBuilder: wrapperBuilder, + foregroundIndicatorBuilder: foregroundIndicatorBuilder == null + ? null + : (BuildContext context, + DetailedGlobalToggleProperties global) { + return RotatedBox( + quarterTurns: -1, + child: foregroundIndicatorBuilder!(context, global), + ); + }, + backgroundIndicatorBuilder: backgroundIndicatorBuilder == null + ? null + : (BuildContext context, + DetailedGlobalToggleProperties global) { + return RotatedBox( + quarterTurns: -1, + child: backgroundIndicatorBuilder!(context, global), + ); + }, + loadingAnimationDuration: loadingAnimationDuration, + loadingAnimationCurve: loadingAnimationCurve, + onChanged: onChanged, + separatorBuilder: separatorBuilder, + onTap: onTap, + // by default the icons are ordered top down + textDirection: textDirection ?? TextDirection.ltr, + loading: loading, + positionListener: positionListener, + )); + } } class _CustomAnimatedToggleSwitchState @@ -457,7 +568,7 @@ class _CustomAnimatedToggleSwitchState @override Widget build(BuildContext context) { double spacing = widget.spacing; - final textDirection = _textDirectionOf(context); + final textDirection = widget.textDirection ?? _textDirectionOf(context); final loadingValue = _animationInfo.loading ? 1.0 : 0.0; final privateIndicatorAppearingAnimation = _PrivateAnimation(_appearingAnimation); @@ -507,6 +618,7 @@ class _CustomAnimatedToggleSwitchState active: widget.active, indicatorAppearingAnimation: privateIndicatorAppearingAnimation, + vertical: widget._vertical, ); Widget child = Padding( padding: widget.padding, @@ -620,6 +732,7 @@ class _CustomAnimatedToggleSwitchState active: widget.active, indicatorAppearingAnimation: privateIndicatorAppearingAnimation, + vertical: widget._vertical, ); List stack = [ @@ -758,7 +871,7 @@ class _CustomAnimatedToggleSwitchState double position = i * (properties.indicatorSize.width + properties.spacing); return Positioned.directional( - textDirection: _textDirectionOf(context), + textDirection: properties.textDirection, start: i == 0 ? position : position - properties.spacing, width: (i == 0 || i == widget.values.length - 1 ? 1 : 2) * properties.spacing + @@ -789,7 +902,7 @@ class _CustomAnimatedToggleSwitchState final length = properties.values.length; return [ Row( - textDirection: _textDirectionOf(context), + textDirection: properties.textDirection, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ for (int i = 0; i < length; i++) ...[ @@ -864,14 +977,12 @@ class _CustomAnimatedToggleSwitchState _setAnimationInfo(_animationInfo.none()); _checkValuePosition(); } - - /// Returns the [TextDirection] of the widget. - TextDirection _textDirectionOf(BuildContext context) => - widget.textDirection ?? - Directionality.maybeOf(context) ?? - TextDirection.ltr; } +/// Returns the [TextDirection] from the [BuildContext]. +TextDirection _textDirectionOf(BuildContext context) => + Directionality.maybeOf(context) ?? TextDirection.ltr; + /// The [Positioned] for an indicator. It is used as wrapper for /// [CustomAnimatedToggleSwitch.foregroundIndicatorBuilder] and /// [CustomAnimatedToggleSwitch.backgroundIndicatorBuilder]. diff --git a/pubspec.lock b/pubspec.lock index f463a74..5d36f9f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,26 +5,31 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a + sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834 url: "https://pub.dev" source: hosted - version: "61.0.0" + version: "72.0.0" + _macros: + dependency: transitive + description: dart + source: sdk + version: "0.3.2" analyzer: dependency: transitive description: name: analyzer - sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 + sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139 url: "https://pub.dev" source: hosted - version: "5.13.0" + version: "6.7.0" args: dependency: transitive description: name: args - sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 + sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.5.0" async: dependency: transitive description: @@ -73,14 +78,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.1" - coverage: - dependency: transitive - description: - name: coverage - sha256: "8acabb8306b57a409bf4c83522065672ee13179297a6bb0cb9ead73948df7c76" - url: "https://pub.dev" - source: hosted - version: "1.7.2" crypto: dependency: transitive description: @@ -89,6 +86,22 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.3" + csslib: + dependency: transitive + description: + name: csslib + sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + dartdoc: + dependency: "direct dev" + description: + name: dartdoc + sha256: c824d4691231964f8ba24e2fd6f573ac9878fa7a8c188c49f700da18eda79218 + url: "https://pub.dev" + source: hosted + version: "8.0.13" fake_async: dependency: transitive description: @@ -114,23 +127,15 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: "2118df84ef0c3ca93f96123a616ae8540879991b8b57af2f81b76a7ada49b2a4" + sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "2.0.3" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" - frontend_server_client: - dependency: transitive - description: - name: frontend_server_client - sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" - url: "https://pub.dev" - source: hosted - version: "3.2.0" glob: dependency: transitive description: @@ -139,62 +144,38 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" - http_multi_server: - dependency: transitive - description: - name: http_multi_server - sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" - url: "https://pub.dev" - source: hosted - version: "3.2.1" - http_parser: - dependency: transitive - description: - name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" - url: "https://pub.dev" - source: hosted - version: "4.0.2" - io: - dependency: transitive - description: - name: io - sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" - url: "https://pub.dev" - source: hosted - version: "1.0.4" - js: + html: dependency: transitive description: - name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + name: html + sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" url: "https://pub.dev" source: hosted - version: "0.6.7" + version: "0.15.4" leak_tracker: dependency: transitive description: name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" lints: dependency: transitive description: @@ -211,6 +192,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + macros: + dependency: transitive + description: + name: macros + sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" + url: "https://pub.dev" + source: hosted + version: "0.1.2-main.4" + markdown: + dependency: transitive + description: + name: markdown + sha256: ef2a1298144e3f985cc736b22e0ccdaf188b5b3970648f2d9dc13efd1d9df051 + url: "https://pub.dev" + source: hosted + version: "7.2.2" matcher: dependency: transitive description: @@ -223,42 +220,26 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 - url: "https://pub.dev" - source: hosted - version: "1.11.0" - mime: - dependency: transitive - description: - name: mime - sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.15.0" mocktail: dependency: "direct dev" description: name: mocktail - sha256: "9503969a7c2c78c7292022c70c0289ed6241df7a9ba720010c0b215af29a5a58" + sha256: "890df3f9688106f25755f26b1c60589a92b3ab91a22b8b224947ad041bf172d8" url: "https://pub.dev" source: hosted - version: "1.0.0" - node_preamble: - dependency: transitive - description: - name: node_preamble - sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" - url: "https://pub.dev" - source: hosted - version: "2.0.2" + version: "1.0.4" package_config: dependency: transitive description: @@ -275,14 +256,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.0" - pool: - dependency: transitive - description: - name: pool - sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" - url: "https://pub.dev" - source: hosted - version: "1.5.1" pub_semver: dependency: transitive description: @@ -291,59 +264,11 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" - shelf: - dependency: transitive - description: - name: shelf - sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 - url: "https://pub.dev" - source: hosted - version: "1.4.1" - shelf_packages_handler: - dependency: transitive - description: - name: shelf_packages_handler - sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" - url: "https://pub.dev" - source: hosted - version: "3.0.2" - shelf_static: - dependency: transitive - description: - name: shelf_static - sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e - url: "https://pub.dev" - source: hosted - version: "1.1.2" - shelf_web_socket: - dependency: transitive - description: - name: shelf_web_socket - sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" - url: "https://pub.dev" - source: hosted - version: "1.0.4" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" - source_map_stack_trace: - dependency: transitive - description: - name: source_map_stack_trace - sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - source_maps: - dependency: transitive - description: - name: source_maps - sha256: "708b3f6b97248e5781f493b765c3337db11c5d2c81c3094f10904bfa8004c703" - url: "https://pub.dev" - source: hosted - version: "0.10.12" source_span: dependency: transitive description: @@ -384,30 +309,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.1" - test: - dependency: transitive - description: - name: test - sha256: a1f7595805820fcc05e5c52e3a231aedd0b72972cb333e8c738a8b1239448b6f - url: "https://pub.dev" - source: hosted - version: "1.24.9" test_api: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" - url: "https://pub.dev" - source: hosted - version: "0.6.1" - test_core: - dependency: transitive - description: - name: test_core - sha256: a757b14fc47507060a162cc2530d9a4a2f92f5100a952c7443b5cad5ef5b106a + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.5.9" + version: "0.7.2" typed_data: dependency: transitive description: @@ -428,10 +337,10 @@ packages: dependency: transitive description: name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc url: "https://pub.dev" source: hosted - version: "13.0.0" + version: "14.2.4" watcher: dependency: transitive description: @@ -440,22 +349,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" - web_socket_channel: + web: dependency: transitive description: - name: web_socket_channel - sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b + name: web + sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062 url: "https://pub.dev" source: hosted - version: "2.4.0" - webkit_inspection_protocol: - dependency: transitive - description: - name: webkit_inspection_protocol - sha256: "67d3a8b6c79e1987d19d848b0892e582dbb0c66c57cc1fef58a177dd2aa2823d" - url: "https://pub.dev" - source: hosted - version: "1.2.0" + version: "1.0.0" yaml: dependency: transitive description: @@ -465,5 +366,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.2.0-0 <4.0.0" - flutter: ">=1.17.0" + dart: ">=3.4.0 <4.0.0" + flutter: ">=3.18.0-18.0.pre.54" diff --git a/pubspec.yaml b/pubspec.yaml index 3a3cf09..bc4fbd7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,6 +17,7 @@ dev_dependencies: flutter_test: sdk: flutter mocktail: ^1.0.0 + dartdoc: ^8.0.13 flutter: diff --git a/test/vertical_test.dart b/test/vertical_test.dart new file mode 100644 index 0000000..f27bd41 --- /dev/null +++ b/test/vertical_test.dart @@ -0,0 +1,27 @@ +import 'package:flutter_test/flutter_test.dart'; + +import 'helper.dart'; + +void _verifyVertical(WidgetTester tester, List values) { + final firstPos = tester.getCenter(find.byKey(iconKey(values.first))); + final lastPos = tester.getCenter(find.byKey(iconKey(values.last))); + expect((firstPos - lastPos).dx == 0, true, + reason: 'Icons do not have the same x-coordinate'); + expect((firstPos - lastPos).dy < 0, true, + reason: 'Icons should be ordered top down'); + +} + +void main() { + defaultTestAllSwitches('Switch respects TextDirection', + (tester, buildSwitch, type, values) async { + final current = values[1]; + await tester.pumpWidget(TestWrapper( + child: buildSwitch( + current: current, + iconBuilder: iconBuilder, + ).vertical(), + )); + _verifyVertical(tester, values); + }); +}