From 6f9722473555e4c78f825adddd90c573ca886fc2 Mon Sep 17 00:00:00 2001 From: ZhuchkaTriplesix Date: Thu, 28 May 2026 10:46:00 +0300 Subject: [PATCH 1/2] feat(theme): SqlEditorChrome and editor tokens from QueryaTheme (#60) Use QueryaEditorTheme for SQL editor chrome, background, and text; extend VS Code color map for selection/lineNumber/bracket/border keys; align PG/MySQL SQL toolbar icons with workbench accent. Closes #60 --- docs/theme-import.md | 4 + .../parser/querya_theme_from_vscode.dart | 8 ++ lib/core/theme/parser/vscode_color_map.dart | 20 +++++ lib/core/theme/querya_editor_theme.dart | 29 ++++++++ .../main_screen/query_editor_tab.dart | 8 +- .../main_screen/sql_editor_chrome.dart | 49 ++++++++---- .../mysql/mysql_sql_editor_dialog.dart | 10 +-- lib/features/mysql/mysql_sql_workspace.dart | 13 +++- .../postgres_sql_editor_dialog.dart | 10 +-- .../postgresql/postgres_sql_workspace.dart | 13 +++- .../theme/parser/vscode_color_map_test.dart | 15 ++++ .../main_screen/query_editor_tab_test.dart | 13 ++-- .../main_screen/sql_editor_chrome_test.dart | 74 +++++++++++++++++++ .../workspace_homes_and_preferences_test.dart | 9 +-- .../workspace_panel_layout_test.dart | 16 ++-- test/support/querya_theme_test_shell.dart | 22 ++++++ 16 files changed, 254 insertions(+), 59 deletions(-) create mode 100644 test/features/main_screen/sql_editor_chrome_test.dart create mode 100644 test/support/querya_theme_test_shell.dart diff --git a/docs/theme-import.md b/docs/theme-import.md index b4e2cdaa..2c899d26 100644 --- a/docs/theme-import.md +++ b/docs/theme-import.md @@ -11,6 +11,10 @@ Syntax highlighting (`tokenColors`) is tracked separately (issue #46). |-------------|---------------| | `editor.background` | `workbench.editorBackground`, `editor.background` | | `editor.foreground` | `editor.foreground`, `ColorScheme.foreground` | +| `editor.selectionBackground` | `editor.selection` | +| `editorLineNumber.foreground` | `editor.lineNumber` | +| `editorBracketMatch.background` | `editor.bracketMatch` | +| `editorWidget.border` | `editor.widgetBorder` (chrome border) | | `sideBar.background` | `workbench.sidebarBackground` | | `sideBar.foreground` | `workbench.mutedForeground` | | `activityBar.background` | `workbench.canvas` | diff --git a/lib/core/theme/parser/querya_theme_from_vscode.dart b/lib/core/theme/parser/querya_theme_from_vscode.dart index 0b5c4c99..f82551e1 100644 --- a/lib/core/theme/parser/querya_theme_from_vscode.dart +++ b/lib/core/theme/parser/querya_theme_from_vscode.dart @@ -185,6 +185,14 @@ QueryaEditorTheme _applyEditorField( return e.copyWith(background: color); case VsCodeEditorField.foreground: return e.copyWith(foreground: color); + case VsCodeEditorField.selection: + return e.copyWith(selection: color); + case VsCodeEditorField.lineNumber: + return e.copyWith(lineNumber: color); + case VsCodeEditorField.bracketMatch: + return e.copyWith(bracketMatch: color); + case VsCodeEditorField.widgetBorder: + return e.copyWith(widgetBorder: color); } } diff --git a/lib/core/theme/parser/vscode_color_map.dart b/lib/core/theme/parser/vscode_color_map.dart index bc910627..ec19292b 100644 --- a/lib/core/theme/parser/vscode_color_map.dart +++ b/lib/core/theme/parser/vscode_color_map.dart @@ -18,6 +18,10 @@ enum VsCodeWorkbenchField { enum VsCodeEditorField { background, foreground, + selection, + lineNumber, + bracketMatch, + widgetBorder, } /// Optional direct [ColorScheme] fields (shadcn) beyond workbench derivation. @@ -57,6 +61,18 @@ const Map kVsCodeColorMap = { VsCodeWorkbenchField.editorBackground, ), 'editor.foreground': VsCodeColorTarget.editor(VsCodeEditorField.foreground), + 'editor.selectionBackground': VsCodeColorTarget.editor( + VsCodeEditorField.selection, + ), + 'editorLineNumber.foreground': VsCodeColorTarget.editor( + VsCodeEditorField.lineNumber, + ), + 'editorBracketMatch.background': VsCodeColorTarget.editor( + VsCodeEditorField.bracketMatch, + ), + 'editorWidget.border': VsCodeColorTarget.editor( + VsCodeEditorField.widgetBorder, + ), 'sideBar.background': VsCodeColorTarget.workbench( VsCodeWorkbenchField.sidebarBackground, ), @@ -92,6 +108,10 @@ const Map kVsCodeColorMap = { const List kSupportedVsCodeColorKeys = [ 'editor.background', 'editor.foreground', + 'editor.selectionBackground', + 'editorLineNumber.foreground', + 'editorBracketMatch.background', + 'editorWidget.border', 'sideBar.background', 'sideBar.foreground', 'activityBar.background', diff --git a/lib/core/theme/querya_editor_theme.dart b/lib/core/theme/querya_editor_theme.dart index 30e653f6..af71671c 100644 --- a/lib/core/theme/querya_editor_theme.dart +++ b/lib/core/theme/querya_editor_theme.dart @@ -10,6 +10,8 @@ class QueryaEditorTheme { required this.foreground, required this.lineHighlight, required this.selection, + required this.lineNumber, + required this.bracketMatch, required this.comment, required this.keyword, required this.string, @@ -17,6 +19,7 @@ class QueryaEditorTheme { required this.operator, required this.function, required this.type, + this.widgetBorder, this.fontFamily = QueryaTypography.mono, this.fontSize = 13, }); @@ -25,6 +28,11 @@ class QueryaEditorTheme { final Color foreground; final Color lineHighlight; final Color selection; + final Color lineNumber; + final Color bracketMatch; + + /// Chrome border around editor widgets; falls back to workbench [borderSubtle]. + final Color? widgetBorder; final Color comment; final Color keyword; final Color string; @@ -41,6 +49,8 @@ class QueryaEditorTheme { foreground: Color(0xFFF8FAFC), lineHighlight: Color(0xFF18181B), selection: Color(0xFF264F78), + lineNumber: Color(0xFF858585), + bracketMatch: Color(0x33006400), comment: Color(0xFF6A9955), keyword: Color(0xFF569CD6), string: Color(0xFFCE9178), @@ -55,6 +65,8 @@ class QueryaEditorTheme { foreground: Color(0xFF1E293B), lineHighlight: Color(0xFFF1F5F9), selection: Color(0xFFADD6FF), + lineNumber: Color(0xFF237893), + bracketMatch: Color(0x33006400), comment: Color(0xFF008000), keyword: Color(0xFF0000FF), string: Color(0xFFA31515), @@ -69,6 +81,10 @@ class QueryaEditorTheme { Color? foreground, Color? lineHighlight, Color? selection, + Color? lineNumber, + Color? bracketMatch, + Color? widgetBorder, + bool clearWidgetBorder = false, Color? comment, Color? keyword, Color? string, @@ -84,6 +100,10 @@ class QueryaEditorTheme { foreground: foreground ?? this.foreground, lineHighlight: lineHighlight ?? this.lineHighlight, selection: selection ?? this.selection, + lineNumber: lineNumber ?? this.lineNumber, + bracketMatch: bracketMatch ?? this.bracketMatch, + widgetBorder: + clearWidgetBorder ? null : (widgetBorder ?? this.widgetBorder), comment: comment ?? this.comment, keyword: keyword ?? this.keyword, string: string ?? this.string, @@ -107,6 +127,9 @@ class QueryaEditorTheme { foreground: c(a.foreground, b.foreground), lineHighlight: c(a.lineHighlight, b.lineHighlight), selection: c(a.selection, b.selection), + lineNumber: c(a.lineNumber, b.lineNumber), + bracketMatch: c(a.bracketMatch, b.bracketMatch), + widgetBorder: t < 0.5 ? a.widgetBorder : b.widgetBorder, comment: c(a.comment, b.comment), keyword: c(a.keyword, b.keyword), string: c(a.string, b.string), @@ -127,6 +150,9 @@ class QueryaEditorTheme { foreground == other.foreground && lineHighlight == other.lineHighlight && selection == other.selection && + lineNumber == other.lineNumber && + bracketMatch == other.bracketMatch && + widgetBorder == other.widgetBorder && comment == other.comment && keyword == other.keyword && string == other.string && @@ -143,6 +169,9 @@ class QueryaEditorTheme { foreground, lineHighlight, selection, + lineNumber, + bracketMatch, + widgetBorder, comment, keyword, string, diff --git a/lib/features/main_screen/query_editor_tab.dart b/lib/features/main_screen/query_editor_tab.dart index ea76336a..484d5f98 100644 --- a/lib/features/main_screen/query_editor_tab.dart +++ b/lib/features/main_screen/query_editor_tab.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart' as material show EdgeInsets, Padding, TextEditingController, TextStyle; -import 'package:querya_desktop/core/theme/querya_typography.dart'; +import 'package:querya_desktop/core/theme/querya_theme_scope.dart'; import 'package:querya_desktop/features/main_screen/sql_editor_chrome.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; @@ -78,7 +78,7 @@ class _QueryEditorBodyState extends State<_QueryEditorBody> { @override Widget build(BuildContext context) { - final theme = Theme.of(context); + final editor = context.editorTheme; return material.Padding( padding: const material.EdgeInsets.all(12), child: SqlEditorChrome( @@ -87,9 +87,9 @@ class _QueryEditorBodyState extends State<_QueryEditorBody> { maxLines: null, expands: true, style: material.TextStyle( - fontFamily: QueryaTypography.mono, + fontFamily: editor.fontFamily, fontSize: widget.fontSize, - color: theme.colorScheme.foreground, + color: editor.foreground, ), placeholder: const Text('-- Enter SQL here…\nSELECT 1;'), ), diff --git a/lib/features/main_screen/sql_editor_chrome.dart b/lib/features/main_screen/sql_editor_chrome.dart index e4441b5b..6be04c0c 100644 --- a/lib/features/main_screen/sql_editor_chrome.dart +++ b/lib/features/main_screen/sql_editor_chrome.dart @@ -1,23 +1,33 @@ import 'package:flutter/material.dart' as material; +import 'package:querya_desktop/core/theme/querya_editor_theme.dart'; +import 'package:querya_desktop/core/theme/querya_theme_scope.dart'; +import 'package:querya_desktop/core/theme/querya_workbench_theme.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; -/// Outer chrome for SQL editors: subtle border, surface fill, soft cyan glow. +/// Outer chrome for SQL editors: border, surface, brand accent glow. class SqlEditorChrome extends StatelessWidget { const SqlEditorChrome({super.key, required this.child}); final Widget child; - static material.BoxDecoration inlineFieldDecoration(ThemeData theme) { - final cs = theme.colorScheme; + static const double _outerRadius = 14; + static const double _innerRadius = 10; + + /// Decoration for compact SQL fields (dialogs) from theme tokens. + static material.BoxDecoration inlineFieldDecoration( + QueryaEditorTheme editor, + QueryaWorkbenchTheme workbench, + ) { + final border = editor.widgetBorder ?? workbench.borderSubtle; return material.BoxDecoration( - color: cs.card, - borderRadius: material.BorderRadius.circular(10), + color: editor.background, + borderRadius: material.BorderRadius.circular(_innerRadius), border: material.Border.all( - color: cs.border.withValues(alpha: 0.45), + color: border.withValues(alpha: 0.45), ), boxShadow: [ material.BoxShadow( - color: cs.primary.withValues(alpha: 0.07), + color: workbench.accent.withValues(alpha: 0.07), blurRadius: 18, offset: const material.Offset(0, 6), ), @@ -25,14 +35,25 @@ class SqlEditorChrome extends StatelessWidget { ); } + static material.BoxDecoration inlineFieldDecorationFromContext( + BuildContext context, + ) { + return inlineFieldDecoration( + context.editorTheme, + context.workbench, + ); + } + @override Widget build(BuildContext context) { - final theme = Theme.of(context); - final cs = theme.colorScheme; - final glow = cs.primary.withValues(alpha: 0.1); + final editor = context.editorTheme; + final workbench = context.workbench; + final border = editor.widgetBorder ?? workbench.borderSubtle; + final glow = workbench.accent.withValues(alpha: 0.1); + return material.Container( decoration: material.BoxDecoration( - borderRadius: material.BorderRadius.circular(14), + borderRadius: material.BorderRadius.circular(_outerRadius), boxShadow: [ material.BoxShadow( color: glow, @@ -44,10 +65,10 @@ class SqlEditorChrome extends StatelessWidget { ), child: material.Container( decoration: material.BoxDecoration( - color: cs.card, - borderRadius: material.BorderRadius.circular(14), + color: editor.background, + borderRadius: material.BorderRadius.circular(_outerRadius), border: material.Border.all( - color: cs.border.withValues(alpha: 0.5), + color: border.withValues(alpha: 0.5), ), ), clipBehavior: material.Clip.antiAlias, diff --git a/lib/features/mysql/mysql_sql_editor_dialog.dart b/lib/features/mysql/mysql_sql_editor_dialog.dart index 72dba9e5..f49148fd 100644 --- a/lib/features/mysql/mysql_sql_editor_dialog.dart +++ b/lib/features/mysql/mysql_sql_editor_dialog.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart' as material; import 'package:querya_desktop/core/layout/window_layout.dart'; -import 'package:querya_desktop/core/theme/querya_typography.dart'; +import 'package:querya_desktop/core/theme/querya_theme_scope.dart'; import 'package:querya_desktop/features/main_screen/sql_editor_chrome.dart'; import 'package:querya_desktop/features/mysql/mysql_table_utils.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; @@ -113,8 +113,8 @@ class _MysqlSqlEditorDialogState extends material.State<_MysqlSqlEditorDialog> { child: material.SizedBox( height: 280, child: material.Container( - decoration: SqlEditorChrome.inlineFieldDecoration( - Theme.of(context), + decoration: SqlEditorChrome.inlineFieldDecorationFromContext( + context, ), child: material.TextField( controller: _controller, @@ -122,9 +122,9 @@ class _MysqlSqlEditorDialogState extends material.State<_MysqlSqlEditorDialog> { expands: true, textAlignVertical: material.TextAlignVertical.top, style: material.TextStyle( - fontFamily: QueryaTypography.mono, + fontFamily: context.editorTheme.fontFamily, fontSize: 12, - color: theme.foreground, + color: context.editorTheme.foreground, ), decoration: const material.InputDecoration( border: material.InputBorder.none, diff --git a/lib/features/mysql/mysql_sql_workspace.dart b/lib/features/mysql/mysql_sql_workspace.dart index 1d959bc2..4fcc70fc 100644 --- a/lib/features/mysql/mysql_sql_workspace.dart +++ b/lib/features/mysql/mysql_sql_workspace.dart @@ -5,6 +5,7 @@ import 'package:flutter/services.dart' show LogicalKeyboardKey; import 'package:querya_desktop/core/database/mysql_service.dart'; import 'package:querya_desktop/core/storage/app_settings.dart'; import 'package:querya_desktop/core/storage/local_db.dart'; +import 'package:querya_desktop/core/theme/querya_theme_scope.dart'; import 'package:querya_desktop/features/settings/preferences_dialog.dart'; import 'package:querya_desktop/features/settings/sql_statement_timeout_dropdown.dart'; import 'package:querya_desktop/features/main_screen/query_editor_tab.dart'; @@ -345,6 +346,7 @@ class _MysqlSqlToolbar extends material.StatelessWidget { @override material.Widget build(material.BuildContext context) { final theme = Theme.of(context); + final accent = context.workbench.accent; return material.Container( padding: const material.EdgeInsets.symmetric(horizontal: 12, vertical: 8), decoration: material.BoxDecoration( @@ -361,9 +363,10 @@ class _MysqlSqlToolbar extends material.StatelessWidget { OutlineButton( size: ButtonSize.small, onPressed: onOpenHistory, - leading: const material.Icon( + leading: material.Icon( material.Icons.history_rounded, size: 16, + color: accent, ), child: const Text('History'), ), @@ -376,12 +379,13 @@ class _MysqlSqlToolbar extends material.StatelessWidget { height: 16, child: material.CircularProgressIndicator( strokeWidth: 2, - color: theme.colorScheme.primary, + color: accent, ), ) - : const material.Icon( + : material.Icon( material.Icons.play_arrow_rounded, size: 18, + color: accent, ), child: const Text('Execute (F5)'), ), @@ -406,9 +410,10 @@ class _MysqlSqlToolbar extends material.StatelessWidget { const Gap(4), IconButton.ghost( onPressed: running ? null : onOpenPreferences, - icon: const material.Icon( + icon: material.Icon( material.Icons.settings_rounded, size: 20, + color: accent, ), ), ], diff --git a/lib/features/postgresql/postgres_sql_editor_dialog.dart b/lib/features/postgresql/postgres_sql_editor_dialog.dart index 9f2bcd20..e119be5b 100644 --- a/lib/features/postgresql/postgres_sql_editor_dialog.dart +++ b/lib/features/postgresql/postgres_sql_editor_dialog.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart' as material; import 'package:querya_desktop/core/layout/window_layout.dart'; -import 'package:querya_desktop/core/theme/querya_typography.dart'; +import 'package:querya_desktop/core/theme/querya_theme_scope.dart'; import 'package:querya_desktop/features/main_screen/sql_editor_chrome.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; @@ -140,8 +140,8 @@ class _PostgresSqlEditorDialogState extends material.State<_PostgresSqlEditorDia child: material.SizedBox( height: 280, child: material.Container( - decoration: SqlEditorChrome.inlineFieldDecoration( - Theme.of(context), + decoration: SqlEditorChrome.inlineFieldDecorationFromContext( + context, ), child: material.TextField( controller: _controller, @@ -149,9 +149,9 @@ class _PostgresSqlEditorDialogState extends material.State<_PostgresSqlEditorDia expands: true, textAlignVertical: material.TextAlignVertical.top, style: material.TextStyle( - fontFamily: QueryaTypography.mono, + fontFamily: context.editorTheme.fontFamily, fontSize: 12, - color: theme.foreground, + color: context.editorTheme.foreground, ), decoration: const material.InputDecoration( border: material.InputBorder.none, diff --git a/lib/features/postgresql/postgres_sql_workspace.dart b/lib/features/postgresql/postgres_sql_workspace.dart index 6df37479..20df05f8 100644 --- a/lib/features/postgresql/postgres_sql_workspace.dart +++ b/lib/features/postgresql/postgres_sql_workspace.dart @@ -7,6 +7,7 @@ import 'package:querya_desktop/core/database/postgres_service.dart'; import 'package:querya_desktop/core/database/postgres_sql.dart'; import 'package:querya_desktop/core/storage/app_settings.dart'; import 'package:querya_desktop/core/storage/local_db.dart'; +import 'package:querya_desktop/core/theme/querya_theme_scope.dart'; import 'package:querya_desktop/features/postgresql/postgres_object_kind.dart'; import 'package:querya_desktop/features/postgresql/postgres_table_utils.dart'; import 'package:querya_desktop/features/settings/preferences_dialog.dart'; @@ -518,6 +519,7 @@ class _SqlToolbar extends material.StatelessWidget { @override material.Widget build(material.BuildContext context) { final theme = Theme.of(context); + final accent = context.workbench.accent; return material.Container( padding: const material.EdgeInsets.symmetric(horizontal: 12, vertical: 8), decoration: material.BoxDecoration( @@ -538,9 +540,10 @@ class _SqlToolbar extends material.StatelessWidget { OutlineButton( size: ButtonSize.small, onPressed: onOpenHistory, - leading: const material.Icon( + leading: material.Icon( material.Icons.history_rounded, size: 16, + color: accent, ), child: const Text('History'), ), @@ -553,12 +556,13 @@ class _SqlToolbar extends material.StatelessWidget { height: 16, child: material.CircularProgressIndicator( strokeWidth: 2, - color: theme.colorScheme.primary, + color: accent, ), ) - : const material.Icon( + : material.Icon( material.Icons.play_arrow_rounded, size: 18, + color: accent, ), child: const Text('Execute (F5)'), ), @@ -594,9 +598,10 @@ class _SqlToolbar extends material.StatelessWidget { const Gap(4), IconButton.ghost( onPressed: running ? null : onOpenPreferences, - icon: const material.Icon( + icon: material.Icon( material.Icons.settings_rounded, size: 20, + color: accent, ), ), ], diff --git a/test/core/theme/parser/vscode_color_map_test.dart b/test/core/theme/parser/vscode_color_map_test.dart index 9f556af2..d11181d6 100644 --- a/test/core/theme/parser/vscode_color_map_test.dart +++ b/test/core/theme/parser/vscode_color_map_test.dart @@ -37,6 +37,21 @@ void main() { expect(theme.workbench.gitModified, const Color(0xFFE2C08D)); expect(theme.workbench.gitUntracked, const Color(0xFF73C991)); expect(theme.colorScheme.foreground, const Color(0xFFD4D4D4)); + expect(theme.editor.background, const Color(0xFF1E1E1E)); + }); + + test('editor.selectionBackground maps to editor.selection', () async { + const src = ''' +{ + "type": "dark", + "colors": { + "editor.selectionBackground": "#123456" + } +} +'''; + final manifest = VsCodeThemeManifest.fromJsonString(src); + final theme = buildQueryaThemeFromVsCodeManifest(manifest); + expect(theme.editor.selection, const Color(0xFF123456)); }); test('light_subset fixture uses light brightness', () async { diff --git a/test/features/main_screen/query_editor_tab_test.dart b/test/features/main_screen/query_editor_tab_test.dart index 1104700f..47a80e22 100644 --- a/test/features/main_screen/query_editor_tab_test.dart +++ b/test/features/main_screen/query_editor_tab_test.dart @@ -1,15 +1,15 @@ import 'package:flutter/material.dart' as material; import 'package:flutter_test/flutter_test.dart'; -import 'package:querya_desktop/core/theme/app_theme.dart'; import 'package:querya_desktop/features/main_screen/query_editor_tab.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; +import '../../support/querya_theme_test_shell.dart'; + void main() { testWidgets('QueryEditorTab applies fontSize to EditableText', (tester) async { await tester.pumpWidget( - ShadcnApp( - theme: AppTheme.dark, - home: const material.Scaffold( + queryaThemeTestShell( + child: const material.Scaffold( body: SizedBox( width: 600, height: 400, @@ -29,9 +29,8 @@ void main() { testWidgets('QueryEditorTab default fontSize is 13', (tester) async { await tester.pumpWidget( - ShadcnApp( - theme: AppTheme.dark, - home: const material.Scaffold( + queryaThemeTestShell( + child: const material.Scaffold( body: SizedBox( width: 600, height: 400, diff --git a/test/features/main_screen/sql_editor_chrome_test.dart b/test/features/main_screen/sql_editor_chrome_test.dart new file mode 100644 index 00000000..c8aaa5fc --- /dev/null +++ b/test/features/main_screen/sql_editor_chrome_test.dart @@ -0,0 +1,74 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:querya_desktop/core/theme/querya_editor_theme.dart'; +import 'package:querya_desktop/core/theme/querya_workbench_theme.dart'; +import 'package:querya_desktop/features/main_screen/sql_editor_chrome.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; + +void main() { + group('SqlEditorChrome.inlineFieldDecoration', () { + test('uses editor background and workbench accent glow', () { + const editor = QueryaEditorTheme( + background: Color(0xFF111111), + foreground: Color(0xFFFFFFFF), + lineHighlight: Color(0xFF000000), + selection: Color(0xFF222222), + lineNumber: Color(0xFF333333), + bracketMatch: Color(0xFF444444), + comment: Color(0xFF555555), + keyword: Color(0xFF666666), + string: Color(0xFF777777), + number: Color(0xFF888888), + operator: Color(0xFF999999), + function: Color(0xFFAAAAAA), + type: Color(0xFFBBBBBB), + ); + const workbench = QueryaWorkbenchTheme( + canvas: Color(0xFF000000), + surface: Color(0xFF000001), + sidebarBackground: Color(0xFF000002), + editorBackground: Color(0xFF111111), + borderSubtle: Color(0xFFCCCCCC), + accent: Color(0xFF00FFFF), + onAccent: Color(0xFF000000), + mutedForeground: Color(0xFF888888), + destructive: Color(0xFFFF0000), + success: Color(0xFF00FF00), + warning: Color(0xFFFFFF00), + gitModified: Color(0xFFFF8800), + gitUntracked: Color(0xFF00FF88), + ); + + final deco = SqlEditorChrome.inlineFieldDecoration(editor, workbench); + expect(deco.color, const Color(0xFF111111)); + expect( + deco.boxShadow!.single.color, + const Color(0xFF00FFFF).withValues(alpha: 0.07), + ); + }); + + test('widgetBorder overrides workbench border', () { + const editor = QueryaEditorTheme( + background: Color(0xFFFFFFFF), + foreground: Color(0xFF000000), + lineHighlight: Color(0xFFF0F0F0), + selection: Color(0xFFADD6FF), + lineNumber: Color(0xFF237893), + bracketMatch: Color(0x33006400), + widgetBorder: Color(0xFFFF0000), + comment: Color(0xFF008000), + keyword: Color(0xFF0000FF), + string: Color(0xFFA31515), + number: Color(0xFF098658), + operator: Color(0xFF000000), + function: Color(0xFF795E26), + type: Color(0xFF267F99), + ); + final deco = SqlEditorChrome.inlineFieldDecoration( + editor, + QueryaWorkbenchTheme.lightDefault, + ); + final border = deco.border as Border; + expect(border.top.color, const Color(0xFFFF0000).withValues(alpha: 0.45)); + }); + }); +} diff --git a/test/features/main_screen/workspace_homes_and_preferences_test.dart b/test/features/main_screen/workspace_homes_and_preferences_test.dart index 59e71b0e..5f60927f 100644 --- a/test/features/main_screen/workspace_homes_and_preferences_test.dart +++ b/test/features/main_screen/workspace_homes_and_preferences_test.dart @@ -10,6 +10,8 @@ import 'package:querya_desktop/features/mysql/mysql_workspace_home.dart'; import 'package:querya_desktop/features/settings/preferences_dialog.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; +import '../../support/querya_theme_test_shell.dart'; + class _FakePathProvider extends PathProviderPlatform { _FakePathProvider(this._root); final String _root; @@ -58,11 +60,8 @@ void main() { group('MysqlWorkspaceHome', () { testWidgets('shows tabs and SQL tab exposes Execute control', (tester) async { await tester.pumpWidget( - ShadcnApp( - theme: AppTheme.dark, - darkTheme: AppTheme.dark, - themeMode: ThemeMode.dark, - home: const material.Scaffold( + queryaThemeTestShell( + child: const material.Scaffold( body: material.SizedBox( width: 700, height: 500, diff --git a/test/features/main_screen/workspace_panel_layout_test.dart b/test/features/main_screen/workspace_panel_layout_test.dart index d65f43e1..92943780 100644 --- a/test/features/main_screen/workspace_panel_layout_test.dart +++ b/test/features/main_screen/workspace_panel_layout_test.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart' as material; import 'package:flutter_test/flutter_test.dart'; import 'package:querya_desktop/core/storage/local_db.dart'; -import 'package:querya_desktop/core/theme/app_theme.dart'; import 'package:querya_desktop/features/main_screen/workspace_panel.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; import '../../support/layout_overflow.dart'; +import '../../support/querya_theme_test_shell.dart'; void main() { /// Type must not be postgresql/mysql/mongodb/redis so [WorkspacePanel] uses the @@ -35,11 +35,8 @@ void main() { await pumpWidgetWithSurfaceSize( tester, entry.value, - ShadcnApp( - theme: AppTheme.dark, - darkTheme: AppTheme.dark, - themeMode: ThemeMode.dark, - home: const material.SizedBox.expand( + queryaThemeTestShell( + child: const material.SizedBox.expand( child: WorkspacePanel(), ), ), @@ -53,11 +50,8 @@ void main() { await pumpWidgetWithSurfaceSize( tester, const material.Size(800, 600), - ShadcnApp( - theme: AppTheme.dark, - darkTheme: AppTheme.dark, - themeMode: ThemeMode.dark, - home: const material.SizedBox.expand( + queryaThemeTestShell( + child: const material.SizedBox.expand( child: WorkspacePanel(activeConnection: stubSplitWorkspaceConnection), ), ), diff --git a/test/support/querya_theme_test_shell.dart b/test/support/querya_theme_test_shell.dart new file mode 100644 index 00000000..565a3d2c --- /dev/null +++ b/test/support/querya_theme_test_shell.dart @@ -0,0 +1,22 @@ +import 'package:flutter/widgets.dart'; +import 'package:querya_desktop/core/theme/querya_theme.dart'; +import 'package:querya_desktop/core/theme/querya_theme_scope.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; + +/// Wraps [child] with [ShadcnApp] and [QueryaThemeScope] for widget tests. +Widget queryaThemeTestShell({ + required Widget child, + QueryaTheme data = QueryaTheme.darkDefault, + ThemeData? theme, +}) { + final td = theme ?? data.toShadcnThemeData(); + return ShadcnApp( + theme: td, + darkTheme: td, + themeMode: ThemeMode.dark, + home: QueryaThemeScope( + data: data, + child: child, + ), + ); +} From 19d6a7178421a41558140103982b15d1d2f29a35 Mon Sep 17 00:00:00 2001 From: ZhuchkaTriplesix Date: Thu, 28 May 2026 10:47:43 +0300 Subject: [PATCH 2/2] fix(test): remove unnecessary widgets import in theme test shell --- test/support/querya_theme_test_shell.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/test/support/querya_theme_test_shell.dart b/test/support/querya_theme_test_shell.dart index 565a3d2c..c3acc186 100644 --- a/test/support/querya_theme_test_shell.dart +++ b/test/support/querya_theme_test_shell.dart @@ -1,4 +1,3 @@ -import 'package:flutter/widgets.dart'; import 'package:querya_desktop/core/theme/querya_theme.dart'; import 'package:querya_desktop/core/theme/querya_theme_scope.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart';