From 8054fb70e90fe2603fa7b17689803717f9ff0cf0 Mon Sep 17 00:00:00 2001 From: ZhuchkaTriplesix Date: Sat, 17 Oct 2026 06:35:15 +0300 Subject: [PATCH] ui(theme): use editorBackground and semantic palette tokens in SQL previews and document tree (#1644) --- .../mongodb/mongo_document_tree_view.dart | 23 +++++--- .../workspace/destructive_query_dialog.dart | 8 +-- .../workspace/dml_preview_dialog.dart | 8 +-- .../mongo_documents_view_modes_test.dart | 51 +++++++++++++++++ .../destructive_query_dialog_test.dart | 55 +++++++++++++++++++ .../workspace/dml_preview_dialog_test.dart | 43 ++++++++++++++- 6 files changed, 167 insertions(+), 21 deletions(-) diff --git a/lib/features/mongodb/mongo_document_tree_view.dart b/lib/features/mongodb/mongo_document_tree_view.dart index a8523626..c4d88bc9 100644 --- a/lib/features/mongodb/mongo_document_tree_view.dart +++ b/lib/features/mongodb/mongo_document_tree_view.dart @@ -3,6 +3,8 @@ import 'dart:convert'; import 'package:flutter/material.dart' as material; import 'package:flutter/services.dart'; import 'package:mongo_dart/mongo_dart.dart' show ObjectId; +import 'package:querya_desktop/core/theme/querya_semantic_palette.dart'; +import 'package:querya_desktop/core/theme/querya_theme_scope.dart'; import 'package:querya_desktop/core/theme/querya_typography.dart'; import 'package:querya_desktop/features/mongodb/mongo_ejson.dart'; import 'package:querya_desktop/features/mongodb/mongo_field_codec.dart'; @@ -599,7 +601,8 @@ class _MongoDocumentTreeViewState extends State { }) { final keyLabel = keyOrIndex is int ? '[$keyOrIndex]' : keyOrIndex.toString(); final valueDisplay = _formatLeafDisplay(value); - final valueColor = _leafValueColor(value, cs); + final palette = context.semanticPalette; + final valueColor = _leafValueColor(value, cs, palette); final typeName = _leafTypeName(value); final isMatch = _searchQuery.isNotEmpty && @@ -705,13 +708,17 @@ class _MongoDocumentTreeViewState extends State { return value.toString(); } - Color _leafValueColor(Object? value, ColorScheme cs) { - if (value == null) return cs.mutedForeground; - if (value is String) return const Color(0xFF22C55E); // Green - if (value is num) return const Color(0xFF3B82F6); // Blue - if (value is bool) return const Color(0xFFF97316); // Orange - if (value is ObjectId) return cs.primary; // Primary / Purple - if (value is DateTime) return const Color(0xFF06B6D4); // Cyan + Color _leafValueColor( + Object? value, + ColorScheme cs, + QueryaSemanticPalette palette, + ) { + if (value == null) return palette.muted; + if (value is String) return palette.type1; + if (value is num) return palette.type2; + if (value is bool) return palette.type3; + if (value is ObjectId) return cs.primary; + if (value is DateTime) return palette.type4; return cs.foreground; } diff --git a/lib/features/workspace/destructive_query_dialog.dart b/lib/features/workspace/destructive_query_dialog.dart index ac00096b..794cbd89 100644 --- a/lib/features/workspace/destructive_query_dialog.dart +++ b/lib/features/workspace/destructive_query_dialog.dart @@ -262,9 +262,7 @@ class _DestructiveQueryDialogState child: material.Container( padding: const material.EdgeInsets.all(12), decoration: material.BoxDecoration( - color: isDark - ? const material.Color(0xFF141416) - : const material.Color(0xFFF4F4F6), + color: context.workbench.editorBackground, borderRadius: material.BorderRadius.circular(8), border: material.Border.all( color: cs.border.withValues(alpha: 0.6), @@ -279,9 +277,7 @@ class _DestructiveQueryDialogState QueryaTypography.monoFontFamilyFallback, fontSize: 12.5, height: 1.45, - color: isDark - ? const material.Color(0xFFE2E8F0) - : const material.Color(0xFF1E293B), + color: cs.foreground, ), ), ), diff --git a/lib/features/workspace/dml_preview_dialog.dart b/lib/features/workspace/dml_preview_dialog.dart index 620527c0..46b6f419 100644 --- a/lib/features/workspace/dml_preview_dialog.dart +++ b/lib/features/workspace/dml_preview_dialog.dart @@ -259,9 +259,7 @@ class _DmlPreviewDialogState extends material.State<_DmlPreviewDialog> { child: material.Container( padding: const material.EdgeInsets.all(12), decoration: material.BoxDecoration( - color: isDark - ? const material.Color(0xFF141416) - : const material.Color(0xFFF4F4F6), + color: context.workbench.editorBackground, borderRadius: material.BorderRadius.circular(8), border: material.Border.all( color: cs.border.withValues(alpha: 0.6), @@ -276,9 +274,7 @@ class _DmlPreviewDialogState extends material.State<_DmlPreviewDialog> { QueryaTypography.monoFontFamilyFallback, fontSize: 12.5, height: 1.45, - color: isDark - ? const material.Color(0xFFE2E8F0) - : const material.Color(0xFF1E293B), + color: cs.foreground, ), ), ), diff --git a/test/features/mongodb/mongo_documents_view_modes_test.dart b/test/features/mongodb/mongo_documents_view_modes_test.dart index 8541c5ea..c3041c1d 100644 --- a/test/features/mongodb/mongo_documents_view_modes_test.dart +++ b/test/features/mongodb/mongo_documents_view_modes_test.dart @@ -1,8 +1,11 @@ +import 'package:flutter/material.dart' as material; import 'package:flutter_test/flutter_test.dart'; import 'package:mongo_dart/mongo_dart.dart' show ObjectId; import 'package:querya_desktop/core/editor/querya_code_editor.dart'; import 'package:querya_desktop/core/editor/querya_highlight_controller.dart'; import 'package:querya_desktop/core/editor/syntax_highlight_service.dart'; +import 'package:querya_desktop/core/theme/querya_semantic_palette.dart'; +import 'package:querya_desktop/core/theme/querya_theme.dart'; import 'package:querya_desktop/features/mongodb/mongo_document_tree_view.dart'; import 'package:querya_desktop/features/mongodb/mongo_documents_json_view.dart'; import 'package:querya_desktop/features/mongodb/mongo_documents_table_view.dart'; @@ -193,6 +196,54 @@ void main() { await tester.pumpAndSettle(); expect(find.text('address'), findsOneWidget); }); + + testWidgets('colors leaf values using semantic palette tokens (#1644)', + (tester) async { + final id = ObjectId.fromHexString('507f1f77bcf86cd799439011'); + final date = DateTime.utc(2026, 1, 1); + final docs = [ + { + '_id': id, + 'strField': 'hello', + 'numField': 42, + 'boolField': true, + 'dateField': date, + 'nullField': null, + }, + ]; + + const theme = QueryaTheme.darkDefault; + final palette = QueryaSemanticPalette.fromTheme(theme); + + await tester.pumpWidget( + queryaThemeTestShell( + data: theme, + child: MongoDocumentTreeView( + documents: docs, + ), + ), + ); + await tester.pumpAndSettle(); + + final strText = tester.widget(find.text('"hello"')); + expect(strText.style?.color, palette.type1); + + final numText = tester.widget(find.text('42')); + expect(numText.style?.color, palette.type2); + + final boolText = tester.widget(find.text('true')); + expect(boolText.style?.color, palette.type3); + + final nullText = tester.widget( + find.byWidgetPredicate( + (w) => + w is material.Text && + w.data == 'null' && + w.style?.fontStyle == material.FontStyle.italic, + ), + ); + expect(nullText.style?.color, palette.muted); + }); }); group('MongoDocumentsJsonView widget', () { diff --git a/test/features/workspace/destructive_query_dialog_test.dart b/test/features/workspace/destructive_query_dialog_test.dart index 890fa390..748088d4 100644 --- a/test/features/workspace/destructive_query_dialog_test.dart +++ b/test/features/workspace/destructive_query_dialog_test.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart' as material; import 'package:flutter_test/flutter_test.dart'; import 'package:querya_desktop/core/database/destructive_sql_detector.dart'; +import 'package:querya_desktop/core/theme/querya_theme.dart'; import 'package:querya_desktop/features/workspace/destructive_query_dialog.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' hide TextExtension; @@ -275,5 +276,59 @@ void main() { await tester.pumpAndSettle(); expect(confirmed, isTrue); }); + + testWidgets( + 'SQL preview uses workbench editorBackground and foreground (#1644)', + (tester) async { + await tester.binding.setSurfaceSize(const Size(800, 700)); + final inspection = + DestructiveSqlDetector.inspect('DROP TABLE legacy_users;'); + + material.Widget buildDialog(QueryaTheme theme) => queryaThemeTestShell( + data: theme, + child: material.Builder( + builder: (context) => material.ElevatedButton( + onPressed: () => showDestructiveQueryDialog( + context: context, + result: inspection, + sql: 'DROP TABLE legacy_users;', + ), + child: const material.Text('Open'), + ), + ), + ); + + // Light theme verification + await tester.pumpWidget(buildDialog(QueryaTheme.lightDefault)); + await tester.tap(find.text('Open')); + await tester.pumpAndSettle(); + + final selectableTextFinder = find.widgetWithText( + material.SelectableText, + 'DROP TABLE legacy_users;', + ); + expect(selectableTextFinder, findsOneWidget); + + final container = tester.widget( + find + .ancestor( + of: selectableTextFinder, + matching: find.byType(material.Container), + ) + .first, + ); + final deco = container.decoration! as material.BoxDecoration; + expect( + deco.color, + QueryaTheme.lightDefault.workbench.editorBackground, + ); + + final selectableText = + tester.widget(selectableTextFinder); + expect( + selectableText.style?.color, + QueryaTheme.lightDefault.colorScheme.foreground, + ); + }); }); } diff --git a/test/features/workspace/dml_preview_dialog_test.dart b/test/features/workspace/dml_preview_dialog_test.dart index 4b70f425..7044d9cf 100644 --- a/test/features/workspace/dml_preview_dialog_test.dart +++ b/test/features/workspace/dml_preview_dialog_test.dart @@ -1,14 +1,20 @@ import 'package:flutter/material.dart' as material; import 'package:flutter_test/flutter_test.dart'; import 'package:querya_desktop/core/database/table_mutation_engine.dart'; +import 'package:querya_desktop/core/theme/querya_theme.dart'; import 'package:querya_desktop/features/workspace/dml_preview_dialog.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' hide TextExtension; import '../../support/querya_theme_test_shell.dart'; void main() { - material.Widget buildTestDialog({required TableMutationPlan plan, void Function(bool?)? onResult}) { + material.Widget buildTestDialog({ + required TableMutationPlan plan, + void Function(bool?)? onResult, + QueryaTheme data = QueryaTheme.darkDefault, + }) { return queryaThemeTestShell( + data: data, child: material.Material( child: material.Builder( builder: (context) { @@ -123,5 +129,40 @@ void main() { expect(find.textContaining('No Primary Key detected'), findsOneWidget); }); + + testWidgets( + 'SQL preview uses workbench editorBackground and foreground (#1644)', + (tester) async { + await tester.pumpWidget(buildTestDialog( + plan: samplePlan, + data: QueryaTheme.lightDefault, + )); + await tester.tap(find.text('Open Dialog')); + await tester.pumpAndSettle(); + + final selectableTextFinder = find.byType(material.SelectableText); + expect(selectableTextFinder, findsOneWidget); + + final container = tester.widget( + find + .ancestor( + of: selectableTextFinder, + matching: find.byType(material.Container), + ) + .first, + ); + final deco = container.decoration! as material.BoxDecoration; + expect( + deco.color, + QueryaTheme.lightDefault.workbench.editorBackground, + ); + + final selectableText = + tester.widget(selectableTextFinder); + expect( + selectableText.style?.color, + QueryaTheme.lightDefault.colorScheme.foreground, + ); + }); }); }