Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 38 additions & 9 deletions lib/features/main_screen/sql_editor_chrome.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,49 @@ class SqlEditorChrome extends StatelessWidget {

final Widget child;

static const double _outerRadius = 14;
static const double _innerRadius = 10;
static const double outerRadius = 14;
static const double innerRadius = 10;

/// Accent glow strength; slightly softer on light themes.
static double chromeGlowAlpha(Brightness brightness) =>
brightness == Brightness.light ? 0.08 : 0.1;

static double inlineGlowAlpha(Brightness brightness) =>
brightness == Brightness.light ? 0.05 : 0.07;

/// Toolbar strip above SQL editor (Postgres/MySQL workspaces).
static material.BoxDecoration sqlToolbarDecoration(
BuildContext context,
) {
final workbench = context.workbench;
return material.BoxDecoration(
color: workbench.surface.withValues(alpha: 0.85),
border: material.Border(
bottom: material.BorderSide(
color: workbench.borderSubtle.withValues(alpha: 0.35),
),
),
);
}

/// Decoration for compact SQL fields (dialogs) from theme tokens.
static material.BoxDecoration inlineFieldDecoration(
QueryaEditorTheme editor,
QueryaWorkbenchTheme workbench,
) {
QueryaWorkbenchTheme workbench, {
Brightness brightness = Brightness.dark,
}) {
final border = editor.widgetBorder ?? workbench.borderSubtle;
return material.BoxDecoration(
color: editor.background,
borderRadius: material.BorderRadius.circular(_innerRadius),
borderRadius: material.BorderRadius.circular(innerRadius),
border: material.Border.all(
color: border.withValues(alpha: 0.45),
),
boxShadow: [
material.BoxShadow(
color: workbench.accent.withValues(alpha: 0.07),
color: workbench.accent.withValues(
alpha: inlineGlowAlpha(brightness),
),
blurRadius: 18,
offset: const material.Offset(0, 6),
),
Expand All @@ -41,19 +66,23 @@ class SqlEditorChrome extends StatelessWidget {
return inlineFieldDecoration(
context.editorTheme,
context.workbench,
brightness: Theme.of(context).brightness,
);
}

@override
Widget build(BuildContext context) {
final editor = context.editorTheme;
final workbench = context.workbench;
final brightness = Theme.of(context).brightness;
final border = editor.widgetBorder ?? workbench.borderSubtle;
final glow = workbench.accent.withValues(alpha: 0.1);
final glow = workbench.accent.withValues(
alpha: chromeGlowAlpha(brightness),
);

return material.Container(
decoration: material.BoxDecoration(
borderRadius: material.BorderRadius.circular(_outerRadius),
borderRadius: material.BorderRadius.circular(outerRadius),
boxShadow: [
material.BoxShadow(
color: glow,
Expand All @@ -66,7 +95,7 @@ class SqlEditorChrome extends StatelessWidget {
child: material.Container(
decoration: material.BoxDecoration(
color: editor.background,
borderRadius: material.BorderRadius.circular(_outerRadius),
borderRadius: material.BorderRadius.circular(outerRadius),
border: material.Border.all(
color: border.withValues(alpha: 0.5),
),
Expand Down
6 changes: 2 additions & 4 deletions lib/features/mysql/mysql_sql_workspace.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ 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';
import 'package:querya_desktop/features/main_screen/results_tab.dart';
import 'package:querya_desktop/features/main_screen/sql_editor_chrome.dart';
import 'package:querya_desktop/features/main_screen/sql_query_history_dialog.dart';
import 'package:querya_desktop/shared/widgets/widgets.dart';

Expand Down Expand Up @@ -345,13 +346,10 @@ 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(
color: theme.colorScheme.muted.withValues(alpha: 0.6),
),
decoration: SqlEditorChrome.sqlToolbarDecoration(context),
child: material.Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: material.MainAxisSize.min,
Expand Down
6 changes: 2 additions & 4 deletions lib/features/postgresql/postgres_sql_workspace.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ 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';
import 'package:querya_desktop/features/main_screen/results_tab.dart';
import 'package:querya_desktop/features/main_screen/sql_editor_chrome.dart';
import 'package:querya_desktop/features/main_screen/sql_query_history_dialog.dart';
import 'package:querya_desktop/shared/widgets/widgets.dart';

Expand Down Expand Up @@ -518,13 +519,10 @@ 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(
color: theme.colorScheme.muted.withValues(alpha: 0.6),
),
decoration: SqlEditorChrome.sqlToolbarDecoration(context),
child: material.Column(
crossAxisAlignment: material.CrossAxisAlignment.stretch,
mainAxisSize: material.MainAxisSize.min,
Expand Down
65 changes: 65 additions & 0 deletions test/features/main_screen/sql_editor_chrome_test.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import 'package:flutter/material.dart' as material;
import 'package:flutter_test/flutter_test.dart';
import 'package:querya_desktop/core/theme/parser/querya_theme_from_vscode.dart';
import 'package:querya_desktop/core/theme/querya_editor_theme.dart';
import 'package:querya_desktop/core/theme/querya_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';

import '../../support/querya_theme_test_shell.dart';

void main() {
group('SqlEditorChrome.inlineFieldDecoration', () {
test('uses editor background and workbench accent glow', () {
Expand Down Expand Up @@ -66,9 +71,69 @@ void main() {
final deco = SqlEditorChrome.inlineFieldDecoration(
editor,
QueryaWorkbenchTheme.lightDefault,
brightness: Brightness.light,
);
final border = deco.border as Border;
expect(border.top.color, const Color(0xFFFF0000).withValues(alpha: 0.45));
expect(
deco.boxShadow!.single.color,
QueryaWorkbenchTheme.lightDefault.accent.withValues(alpha: 0.05),
);
});
});

group('SqlEditorChrome widget', () {
testWidgets('applies imported editor background and border', (tester) async {
final queryaTheme = buildQueryaThemeFromVsCodeColors(
brightness: Brightness.dark,
colors: const {
'editor.background': '#aabbcc',
'editorWidget.border': '#112233',
'focusBorder': '#00ffee',
},
fallback: QueryaTheme.darkDefault,
);

await tester.pumpWidget(
queryaThemeTestShell(
data: queryaTheme,
child: const material.SizedBox(
width: 320,
height: 200,
child: SqlEditorChrome(
child: material.SizedBox.expand(),
),
),
),
);
await tester.pump();

final containers = tester.widgetList<material.Container>(
find.descendant(
of: find.byType(SqlEditorChrome),
matching: find.byType(material.Container),
),
);

final inner = containers.firstWhere((c) {
final d = c.decoration;
return d is material.BoxDecoration &&
d.color == const Color(0xFFAABBCC);
});
final border = (inner.decoration! as material.BoxDecoration).border as Border;
expect(
border.top.color,
const Color(0xFF112233).withValues(alpha: 0.5),
);

final outerGlow = containers
.map((c) => c.decoration)
.whereType<material.BoxDecoration>()
.expand((d) => d.boxShadow ?? const <material.BoxShadow>[])
.map((s) => s.color)
.whereType<Color>()
.firstWhere((c) => c == const Color(0xFF00FFEE).withValues(alpha: 0.1));
expect(outerGlow, const Color(0xFF00FFEE).withValues(alpha: 0.1));
});
});
}
Loading