diff --git a/CHANGELOG.md b/CHANGELOG.md index db63fd4..00a6b60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ The package is available from ## 1.5 Login and Register ++ Login page buttons are all the same width [1.5.8 20261015 av] + Show a saved security key in the status bar at once [1.5.7 20261014 gjw] + Keep the security key after a Session Expired login [1.5.6 20261013 gjw] + Bump file_picker 13.1.0 [1.5.5 20261011 gjw] diff --git a/lib/src/widgets/solid_login_panel.dart b/lib/src/widgets/solid_login_panel.dart index 2c3e4ff..1da8281 100644 --- a/lib/src/widgets/solid_login_panel.dart +++ b/lib/src/widgets/solid_login_panel.dart @@ -100,10 +100,12 @@ class SolidLoginPanel { mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded(child: buttons[i]), - if (i + 1 < buttons.length) ...[ - const SizedBox(width: 15.0), - Expanded(child: buttons[i + 1]), - ] else + // Make button sizes similar for 1, 2, 3, and 4 + // button layouts. + const SizedBox(width: 15.0), + if (i + 1 < buttons.length) + Expanded(child: buttons[i + 1]) + else const Expanded(child: SizedBox.shrink()), ], ), diff --git a/pubspec.yaml b/pubspec.yaml index 797ca4c..745610c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: solidui description: 'A UI library for building Solid applications with Flutter.' -version: 1.5.7 +version: 1.5.8 homepage: https://github.com/anusii/solidui # Scaffold a new Solid Pod file-browser app (a pod browser, with navigation diff --git a/test/solid_login_button_sizes_test.dart b/test/solid_login_button_sizes_test.dart new file mode 100644 index 0000000..7db8a29 --- /dev/null +++ b/test/solid_login_button_sizes_test.dart @@ -0,0 +1,97 @@ +/// Tests that the login page's buttons are all the same width. +/// +/// Copyright (C) 2026, Software Innovation Institute, ANU. +/// +/// Licensed under the MIT License (the "License"). +/// +/// License: https://choosealicense.com/licenses/mit/. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +/// +/// Authors: Anushka Vidanage + +library; + +import 'package:flutter/material.dart'; + +import 'package:flutter_test/flutter_test.dart'; + +import 'package:solidui/src/widgets/solid_login_helper.dart'; +import 'package:solidui/src/widgets/solid_login_panel.dart'; + +/// Pump the login panel's content with buttons named [names], two to a row. + +Future _pump(WidgetTester tester, List names) async { + tester.view.physicalSize = const Size(600, 1000); + tester.view.devicePixelRatio = 1; + addTearDown(tester.view.reset); + final webId = TextEditingController(); + addTearDown(webId.dispose); + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: SingleChildScrollView( + child: Builder( + builder: (context) => SolidLoginPanel.buildPanelContent( + context: context, + logo: const AssetImage('assets/images/app_icon.png'), + title: 'App', + appVersion: '1.0.0', + webIdController: webId, + buttons: [ + for (final name in names) + ElevatedButton( + key: ValueKey(name), + onPressed: () {}, + child: Text(name), + ), + ], + currentTheme: const SolidLoginThemeMode(), + ), + ), + ), + ), + ), + ); +} + +double _width(WidgetTester tester, String name) => + tester.getSize(find.byKey(ValueKey(name))).width; + +void main() { + testWidgets('a button alone on its row is as wide as one in a pair', + (tester) async { + await _pump(tester, ['LOGIN', 'CONTINUE', 'REGISTER']); + + final paired = _width(tester, 'LOGIN'); + expect(_width(tester, 'CONTINUE'), paired); + expect(_width(tester, 'REGISTER'), paired); + // Lined up with the button above it, not just the same size. + expect( + tester.getTopLeft(find.byKey(const ValueKey('REGISTER'))).dx, + tester.getTopLeft(find.byKey(const ValueKey('LOGIN'))).dx, + ); + }); + + testWidgets('two buttons share a row equally', (tester) async { + await _pump(tester, ['LOGIN', 'REGISTER']); + + expect(_width(tester, 'LOGIN'), _width(tester, 'REGISTER')); + }); +}