From 4a6c48aa785f3bf102f4475e89c4df3b2e172fb9 Mon Sep 17 00:00:00 2001 From: ZhuchkaTriplesix Date: Tue, 28 Jul 2026 14:43:19 +0300 Subject: [PATCH] ui(motion): Extension Manager TabStrip + CrossFadeStack (#488) Align extension dialog tabs with workspace homes: sliding QueryaTabStrip and QueryaCrossFadeStack instead of SecondaryButton + IndexedStack. --- .../pages/extension_manager_dialog.dart | 33 +++++-------------- .../extensions/extension_manager_test.dart | 3 ++ 2 files changed, 12 insertions(+), 24 deletions(-) diff --git a/lib/features/extensions/presentation/pages/extension_manager_dialog.dart b/lib/features/extensions/presentation/pages/extension_manager_dialog.dart index 2fce9aca..7349b78c 100644 --- a/lib/features/extensions/presentation/pages/extension_manager_dialog.dart +++ b/lib/features/extensions/presentation/pages/extension_manager_dialog.dart @@ -6,6 +6,7 @@ import 'package:querya_desktop/core/extensions/local_extension_registry.dart'; import 'package:querya_desktop/core/extensions/models/extension_manifest.dart'; import 'package:querya_desktop/core/layout/window_layout.dart'; import 'package:querya_desktop/core/market/marketplace_repository.dart'; +import 'package:querya_desktop/core/motion/querya_cross_fade_stack.dart'; import 'package:querya_desktop/features/extensions/presentation/widgets/extension_card.dart'; import 'package:querya_desktop/features/extensions/presentation/widgets/extension_sideload_dialog.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; @@ -214,19 +215,19 @@ class _ExtensionManagerContentState material.Padding( padding: const material.EdgeInsets.symmetric( horizontal: 24.0, vertical: 8.0), - child: material.Wrap( - spacing: 8, - runSpacing: 8, - children: [ - _buildTabButton(0, 'Installed', count: _installed.length), - _buildTabButton(1, 'Marketplace'), - _buildTabButton(2, 'Updates'), + child: QueryaTabStrip( + labels: [ + 'Installed (${_installed.length})', + 'Marketplace', + 'Updates', ], + selectedIndex: _tabIndex, + onSelected: (index) => setState(() => _tabIndex = index), ), ), material.Divider(height: 1, color: theme.border), material.Expanded( - child: material.IndexedStack( + child: QueryaCrossFadeStack( index: _tabIndex, children: [ _buildInstalledTab(), @@ -243,22 +244,6 @@ class _ExtensionManagerContentState ); } - material.Widget _buildTabButton(int index, String label, {int? count}) { - final isSelected = _tabIndex == index; - final displayLabel = count != null ? '$label ($count)' : label; - return SecondaryButton( - onPressed: () => setState(() => _tabIndex = index), - child: material.Text( - displayLabel, - style: material.TextStyle( - color: isSelected ? Theme.of(context).colorScheme.primary : null, - fontWeight: - isSelected ? material.FontWeight.w600 : material.FontWeight.w400, - ), - ), - ); - } - material.Widget _buildInstalledTab() { if (_loading) { return const material.Center( diff --git a/test/features/extensions/extension_manager_test.dart b/test/features/extensions/extension_manager_test.dart index bc68c223..4905121a 100644 --- a/test/features/extensions/extension_manager_test.dart +++ b/test/features/extensions/extension_manager_test.dart @@ -6,6 +6,7 @@ import 'package:querya_desktop/core/extensions/local_extension_registry.dart'; import 'package:querya_desktop/core/extensions/models/extension_manifest.dart'; import 'package:querya_desktop/core/extensions/models/extension_type.dart'; import 'package:querya_desktop/core/market/marketplace_repository.dart'; +import 'package:querya_desktop/core/motion/querya_cross_fade_stack.dart'; import 'package:querya_desktop/features/extensions/presentation/pages/extension_manager_dialog.dart'; import 'package:querya_desktop/features/extensions/presentation/widgets/extension_card.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; @@ -114,6 +115,8 @@ void main() { expect(find.text('Installed (0)'), findsOneWidget); expect(find.text('Marketplace'), findsOneWidget); expect(find.text('Install from file…'), findsOneWidget); + expect(find.byType(QueryaTabStrip), findsOneWidget); + expect(find.byType(QueryaCrossFadeStack), findsOneWidget); // Switch to Marketplace tab await tester.tap(find.text('Marketplace'));