From 7aedb79820624bcaf25aca18e8309fcccff7d3cb Mon Sep 17 00:00:00 2001 From: ZhuchkaTriplesix Date: Sun, 11 Oct 2026 15:59:42 +0300 Subject: [PATCH] fix(ui): toolbar rows set one control size through QueryaControlScope The ERD toolbar was md buttons next to a dense (28 px) detail strip, and the chart toolbar mixed a dense strip with lg dropdowns. Each toolbar now says its size once (ERD md, chart and results sm) and its controls follow. Refs #1439 --- lib/features/erd/erd_view.dart | 7 ++- .../results/charts/quick_chart_view.dart | 6 +- lib/features/workspace/results_tab.dart | 9 ++- .../querya_control_row_height_test.dart | 60 +++++++++++++++++++ 4 files changed, 73 insertions(+), 9 deletions(-) diff --git a/lib/features/erd/erd_view.dart b/lib/features/erd/erd_view.dart index 9bb95213..71c1a119 100644 --- a/lib/features/erd/erd_view.dart +++ b/lib/features/erd/erd_view.dart @@ -40,6 +40,7 @@ import 'package:querya_desktop/features/erd/widgets/erd_table_card.dart'; import 'package:querya_desktop/core/export/image_pdf.dart'; import 'package:querya_desktop/core/export/svg_png.dart'; import 'package:querya_desktop/core/storage/app_settings.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; import 'package:querya_desktop/shared/widgets/app_toast.dart'; import 'package:querya_desktop/features/workspace/sql_editor_chrome.dart'; import 'package:querya_desktop/shared/widgets/querya_button.dart'; @@ -1688,7 +1689,9 @@ class _ErdViewState extends material.State { material.Container( decoration: SqlEditorChrome.sqlToolbarDecoration(context), padding: const material.EdgeInsets.all(8), - child: material.Wrap( + child: QueryaControlScope( + size: QueryaControlSize.md, + child: material.Wrap( spacing: 8, runSpacing: 8, crossAxisAlignment: material.WrapCrossAlignment.center, @@ -1709,7 +1712,6 @@ class _ErdViewState extends material.State { message: 'Table names only, key columns, or every column', child: QueryaTabStrip( key: const material.ValueKey('erd_detail'), - dense: true, labels: const ['Names', 'Keys', 'All'], selectedIndex: ErdDetail.values.indexOf(_detail), onSelected: (i) { @@ -1772,6 +1774,7 @@ class _ErdViewState extends material.State { ), ), ], + ), ), ), material.Expanded(child: material.ClipRect(child: body)), diff --git a/lib/features/results/charts/quick_chart_view.dart b/lib/features/results/charts/quick_chart_view.dart index 145b2f24..e03afaf2 100644 --- a/lib/features/results/charts/quick_chart_view.dart +++ b/lib/features/results/charts/quick_chart_view.dart @@ -290,13 +290,14 @@ class _QuickChartViewState extends material.State { padding: const material.EdgeInsets.all(8), // Wrap, not Row: on a narrow chart the controls move to a second // line instead of overflowing and pushing the export buttons away. - child: material.Wrap( + child: QueryaControlScope( + size: QueryaControlSize.sm, + child: material.Wrap( spacing: 12, runSpacing: 8, crossAxisAlignment: material.WrapCrossAlignment.center, children: [ QueryaTabStrip( - dense: true, labels: const ['Bar', 'Line', 'Pie'], selectedIndex: QuickChartType.values.indexOf(_type), onSelected: (i) => setState(() { @@ -413,6 +414,7 @@ class _QuickChartViewState extends material.State { size: QueryaControlSize.sm, ), ], + ), ), ), material.Expanded( diff --git a/lib/features/workspace/results_tab.dart b/lib/features/workspace/results_tab.dart index f286455b..3626fba2 100644 --- a/lib/features/workspace/results_tab.dart +++ b/lib/features/workspace/results_tab.dart @@ -406,7 +406,9 @@ class _ResultsTabState extends material.State { ), child: material.SingleChildScrollView( scrollDirection: material.Axis.horizontal, - child: material.Row( + child: QueryaControlScope( + size: QueryaControlSize.sm, + child: material.Row( mainAxisSize: material.MainAxisSize.min, children: [ // Grid / Groupings View Selector @@ -414,7 +416,6 @@ class _ResultsTabState extends material.State { // let "Groupings" run into its neighbours at larger UI // scales. QueryaTabStrip( - dense: true, labels: const ['Grid', 'Groupings', 'Charts'], selectedIndex: ResultViewMode.values.indexOf(_viewMode), onSelected: (i) => @@ -440,7 +441,6 @@ class _ResultsTabState extends material.State { // Toggle Quick Filter QueryaIconButton( - size: QueryaControlSize.sm, icon: material.Icon( _showFilterBar ? material.Icons.filter_alt : material.Icons.filter_alt_outlined, size: 15, @@ -461,7 +461,6 @@ class _ResultsTabState extends material.State { builder: (context, _) { final masked = PiiMaskingController.instance.enabled; return QueryaIconButton( - size: QueryaControlSize.sm, key: const material.Key( 'results_mask_sensitive_toggle'), icon: material.Icon( @@ -484,7 +483,6 @@ class _ResultsTabState extends material.State { // Toggle Value Side Panel QueryaIconButton( - size: QueryaControlSize.sm, icon: material.Icon( _showValuePanel ? material.Icons.dock : material.Icons.data_object_rounded, size: 15, @@ -533,6 +531,7 @@ class _ResultsTabState extends material.State { }, ), ], + ), ), ), ), diff --git a/test/shared/widgets/querya_control_row_height_test.dart b/test/shared/widgets/querya_control_row_height_test.dart index 7a1fd2b0..6974cffd 100644 --- a/test/shared/widgets/querya_control_row_height_test.dart +++ b/test/shared/widgets/querya_control_row_height_test.dart @@ -2,8 +2,10 @@ import 'package:flutter/material.dart' as material; import 'package:flutter_test/flutter_test.dart'; import 'package:querya_desktop/core/layout/ui_scale.dart'; import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; +import 'package:querya_desktop/shared/widgets/querya_button.dart'; import 'package:querya_desktop/shared/widgets/querya_dropdown.dart'; import 'package:querya_desktop/shared/widgets/querya_icon_button.dart'; +import 'package:querya_desktop/shared/widgets/querya_menu_button.dart'; import 'package:querya_desktop/shared/widgets/querya_search_field.dart'; import 'package:querya_desktop/shared/widgets/querya_tab_strip.dart'; @@ -128,5 +130,63 @@ void main() { ); } }); + + testWidgets('buttons, menus, dropdowns and tabs in one scope share a height', + (tester) async { + // A toolbar like the ERD one: nothing sets its own size. + await tester.pumpWidget( + queryaThemeTestShell( + child: material.Center( + child: QueryaControlScope( + size: QueryaControlSize.md, + child: material.Row( + mainAxisSize: material.MainAxisSize.min, + crossAxisAlignment: material.CrossAxisAlignment.start, + children: [ + QueryaButton.secondary( + key: const material.ValueKey('button'), + label: 'Refresh', + onPressed: () {}, + ), + QueryaTabStrip( + key: const material.ValueKey('tabs'), + labels: const ['Names', 'Keys', 'All'], + selectedIndex: 0, + onSelected: (_) {}, + ), + QueryaMenuButton( + key: const material.ValueKey('menu'), + label: 'Views', + items: const [], + onSelected: (_) {}, + ), + material.SizedBox( + width: 160, + child: QueryaDropdown( + key: const material.ValueKey('dropdown'), + value: 'a', + items: const [ + QueryaDropdownItem(value: 'a', label: 'Alpha'), + ], + onSelected: (_) {}, + ), + ), + ], + ), + ), + ), + ), + ); + await tester.pump(); + await tester.pumpAndSettle(); + + for (final k in ['button', 'tabs', 'menu', 'dropdown']) { + expect( + tester.getSize(find.byKey(material.ValueKey(k))).height, + QueryaControlSize.md.height, + reason: k, + ); + } + }); }); }