From e9ff9430796906cb9b6c029f7c8a754c6b99a3d5 Mon Sep 17 00:00:00 2001 From: ZhuchkaTriplesix Date: Sun, 18 Oct 2026 17:56:43 +0300 Subject: [PATCH] refactor(settings, workspace): read colours through context.colors; theme_picker_button drops its shadcn import (#1731) --- .../settings/preferences_about_section.dart | 15 +++---- .../preferences_appearance_section.dart | 10 ++--- .../settings/preferences_controls.dart | 5 ++- lib/features/settings/preferences_dialog.dart | 15 ++++--- .../preferences_shortcuts_section.dart | 26 +++++------ .../settings/theme_editor_dialog.dart | 9 ++-- .../settings/theme_editor_section.dart | 3 +- .../settings/theme_picker_button.dart | 43 ++++++++++--------- lib/features/settings/theme_preview_card.dart | 10 ++--- .../settings/theme_remote_install_dialog.dart | 2 +- .../workspace/data_grid_calc_bar.dart | 5 ++- .../workspace/data_grid_filter_bar.dart | 8 ++-- .../workspace/data_grid_groupings_view.dart | 2 +- .../workspace/data_grid_staging_toolbar.dart | 4 +- .../workspace/data_grid_value_panel.dart | 3 +- .../workspace/destructive_query_dialog.dart | 2 +- .../workspace/dml_preview_dialog.dart | 2 +- .../workspace/generic_table_view.dart | 4 +- .../workspace/grid/grid_cell_actions.dart | 2 +- .../workspace/grid/grid_cell_renderer.dart | 20 ++++----- .../workspace/grid/grid_header_renderer.dart | 20 ++++----- .../workspace/grid/grid_row_renderer.dart | 8 ++-- .../workspace/grid/grid_view_builder.dart | 6 +-- lib/features/workspace/grid_cell_editor.dart | 3 +- .../grid_cell_popover_inspector.dart | 2 +- lib/features/workspace/plan_tree_view.dart | 2 +- lib/features/workspace/result_grid_view.dart | 4 +- lib/features/workspace/results_tab.dart | 6 +-- .../workspace/sql_query_history_dialog.dart | 2 +- .../workspace/table_view_staging.dart | 2 +- test/guards/colors_through_context_test.dart | 7 ++- test/guards/shadcn_imports_ratchet_test.dart | 1 - 32 files changed, 130 insertions(+), 123 deletions(-) diff --git a/lib/features/settings/preferences_about_section.dart b/lib/features/settings/preferences_about_section.dart index db425c59..45f35fb2 100644 --- a/lib/features/settings/preferences_about_section.dart +++ b/lib/features/settings/preferences_about_section.dart @@ -33,7 +33,6 @@ class _PreferencesAboutSectionState @override Widget build(BuildContext context) { - final theme = Theme.of(context); return material.Column( crossAxisAlignment: material.CrossAxisAlignment.start, @@ -42,10 +41,10 @@ class _PreferencesAboutSectionState material.Container( padding: const material.EdgeInsets.all(16), decoration: material.BoxDecoration( - color: theme.colorScheme.muted.withValues(alpha: 0.18), + color: context.colors.muted.withValues(alpha: 0.18), borderRadius: material.BorderRadius.circular(8), border: material.Border.all( - color: theme.colorScheme.border.withValues(alpha: 0.25), + color: context.colors.border.withValues(alpha: 0.25), ), ), child: material.Row( @@ -54,10 +53,10 @@ class _PreferencesAboutSectionState width: 48, height: 48, decoration: material.BoxDecoration( - color: theme.colorScheme.primary.withValues(alpha: 0.12), + color: context.colors.primary.withValues(alpha: 0.12), borderRadius: material.BorderRadius.circular(8), border: material.Border.all( - color: theme.colorScheme.primary.withValues(alpha: 0.3), + color: context.colors.primary.withValues(alpha: 0.3), ), ), child: material.Center( @@ -69,7 +68,7 @@ class _PreferencesAboutSectionState errorBuilder: (_, __, ___) => material.Icon( QueryaIcons.database, size: 24, - color: theme.colorScheme.primary, + color: context.colors.primary, ), ), ), @@ -120,10 +119,10 @@ class _PreferencesAboutSectionState margin: const material.EdgeInsets.only(bottom: 12), padding: const material.EdgeInsets.all(12), decoration: material.BoxDecoration( - color: theme.colorScheme.muted.withValues(alpha: 0.25), + color: context.colors.muted.withValues(alpha: 0.25), borderRadius: material.BorderRadius.circular(6), border: material.Border.all( - color: theme.colorScheme.primary.withValues(alpha: 0.3), + color: context.colors.primary.withValues(alpha: 0.3), ), ), child: material.Row( diff --git a/lib/features/settings/preferences_appearance_section.dart b/lib/features/settings/preferences_appearance_section.dart index a5c7e115..7acc0987 100644 --- a/lib/features/settings/preferences_appearance_section.dart +++ b/lib/features/settings/preferences_appearance_section.dart @@ -202,7 +202,7 @@ class _PreferencesAppearanceSectionState c.selectedThemeLoadError!, style: material.TextStyle( fontSize: 12, - color: Theme.of(context).colorScheme.destructive, + color: context.colors.destructive, ), ), ), @@ -273,10 +273,10 @@ class _PreferencesAppearanceSectionState material.Container( padding: const material.EdgeInsets.all(14), decoration: material.BoxDecoration( - color: Theme.of(context).colorScheme.muted.withValues(alpha: 0.14), + color: context.colors.muted.withValues(alpha: 0.14), borderRadius: material.BorderRadius.circular(8), border: material.Border.all( - color: Theme.of(context).colorScheme.border.withValues(alpha: 0.25), + color: context.colors.border.withValues(alpha: 0.25), ), ), child: material.Column( @@ -340,7 +340,7 @@ class _PreferencesAppearanceSectionState _importError!, style: material.TextStyle( fontSize: 12, - color: Theme.of(context).colorScheme.destructive, + color: context.colors.destructive, ), ), ], @@ -350,7 +350,7 @@ class _PreferencesAppearanceSectionState _folderOpenError!, style: material.TextStyle( fontSize: 12, - color: Theme.of(context).colorScheme.destructive, + color: context.colors.destructive, ), ), ], diff --git a/lib/features/settings/preferences_controls.dart b/lib/features/settings/preferences_controls.dart index c3b03514..1efefdb1 100644 --- a/lib/features/settings/preferences_controls.dart +++ b/lib/features/settings/preferences_controls.dart @@ -2,6 +2,7 @@ import 'dart:async' show unawaited; import 'package:flutter/material.dart' as material; import 'package:flutter/services.dart'; +import 'package:querya_desktop/core/theme/querya_theme_scope.dart'; import 'package:querya_desktop/core/layout/ui_scale_controller.dart'; import 'package:querya_desktop/core/layout/ui_scale.dart'; import 'package:querya_desktop/core/storage/app_settings.dart'; @@ -17,7 +18,7 @@ class PreferencesHint extends StatelessWidget { @override Widget build(BuildContext context) { - final cs = Theme.of(context).colorScheme; + final cs = context.colors; return Text( text, style: TextStyle( @@ -289,7 +290,7 @@ class _InterfaceScaleSliderState extends material.State { @override material.Widget build(material.BuildContext context) { - final cs = Theme.of(context).colorScheme; + final cs = context.colors; final displayScale = _displayScale; final pct = (displayScale * 100).round(); final fine = _fineControl; diff --git a/lib/features/settings/preferences_dialog.dart b/lib/features/settings/preferences_dialog.dart index 78f52686..25622a80 100644 --- a/lib/features/settings/preferences_dialog.dart +++ b/lib/features/settings/preferences_dialog.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:flutter/material.dart' as material; import 'package:flutter/services.dart' show LogicalKeyboardKey; +import 'package:querya_desktop/core/theme/querya_ui_colors.dart'; import 'package:querya_desktop/core/layout/ui_scale.dart'; import 'package:querya_desktop/core/layout/window_layout.dart'; import 'package:querya_desktop/core/storage/app_settings.dart'; @@ -237,7 +238,7 @@ class PreferencesDialogContentState @override material.Widget build(material.BuildContext context) { _visited.add(_selectedCategory); - final theme = Theme.of(context).colorScheme; + final theme = context.colors; final onPopover = theme.popoverForeground; return material.CallbackShortcuts( @@ -437,7 +438,7 @@ class PreferencesDialogContentState ); } - material.Widget _buildPaneHost(PreferencesCategory cat, ColorScheme theme) { + material.Widget _buildPaneHost(PreferencesCategory cat, QueryaUiColors theme) { final selected = cat == _selectedCategory; return material.Offstage( key: material.ValueKey('preferences_pane_${cat.name}'), @@ -460,7 +461,7 @@ class PreferencesDialogContentState material.Widget _buildCategoryRailTile( PreferencesCategory cat, - ColorScheme theme, + QueryaUiColors theme, ) { final isSelected = _selectedCategory == cat; final matches = _matchCountForCategory(cat); @@ -535,7 +536,7 @@ class PreferencesDialogContentState ); } - material.Widget _buildPane(PreferencesCategory cat, ColorScheme theme) { + material.Widget _buildPane(PreferencesCategory cat, QueryaUiColors theme) { switch (cat) { case PreferencesCategory.general: return _buildGeneralSection(theme); @@ -556,7 +557,7 @@ class PreferencesDialogContentState } } - material.Widget _buildGeneralSection(ColorScheme theme) { + material.Widget _buildGeneralSection(QueryaUiColors theme) { return material.Column( crossAxisAlignment: material.CrossAxisAlignment.start, children: [ @@ -609,7 +610,7 @@ class PreferencesDialogContentState ); } - material.Widget _buildSqlSection(ColorScheme theme) { + material.Widget _buildSqlSection(QueryaUiColors theme) { return material.Column( crossAxisAlignment: material.CrossAxisAlignment.start, children: [ @@ -701,7 +702,7 @@ class PreferencesDialogContentState ); } - material.Widget _buildDataGridSection(ColorScheme theme) { + material.Widget _buildDataGridSection(QueryaUiColors theme) { return material.Column( crossAxisAlignment: material.CrossAxisAlignment.start, children: [ diff --git a/lib/features/settings/preferences_shortcuts_section.dart b/lib/features/settings/preferences_shortcuts_section.dart index ca53338b..aecd9b4b 100644 --- a/lib/features/settings/preferences_shortcuts_section.dart +++ b/lib/features/settings/preferences_shortcuts_section.dart @@ -250,13 +250,13 @@ class _PreferencesShortcutsSectionState ), decoration: material.BoxDecoration( color: _selectedCategory == cat - ? theme.colorScheme.primary.withValues(alpha: 0.16) - : theme.colorScheme.muted.withValues(alpha: 0.3), + ? context.colors.primary.withValues(alpha: 0.16) + : context.colors.muted.withValues(alpha: 0.3), borderRadius: material.BorderRadius.circular(16), border: material.Border.all( color: _selectedCategory == cat - ? theme.colorScheme.primary.withValues(alpha: 0.5) - : theme.colorScheme.border.withValues(alpha: 0.25), + ? context.colors.primary.withValues(alpha: 0.5) + : context.colors.border.withValues(alpha: 0.25), ), ), child: material.Row( @@ -270,8 +270,8 @@ class _PreferencesShortcutsSectionState ? material.FontWeight.w600 : material.FontWeight.w400, color: _selectedCategory == cat - ? theme.colorScheme.primary - : theme.colorScheme.foreground, + ? context.colors.primary + : context.colors.foreground, ), ), const material.SizedBox(width: 4), @@ -280,8 +280,8 @@ class _PreferencesShortcutsSectionState style: material.TextStyle( fontSize: 10, color: _selectedCategory == cat - ? theme.colorScheme.primary.withValues(alpha: 0.8) - : theme.colorScheme.mutedForeground, + ? context.colors.primary.withValues(alpha: 0.8) + : context.colors.mutedForeground, ), ), ], @@ -333,10 +333,10 @@ class _PreferencesShortcutsSectionState ), material.Container( decoration: material.BoxDecoration( - color: theme.colorScheme.muted.withValues(alpha: 0.16), + color: context.colors.muted.withValues(alpha: 0.16), borderRadius: material.BorderRadius.circular(8), border: material.Border.all( - color: theme.colorScheme.border.withValues(alpha: 0.25), + color: context.colors.border.withValues(alpha: 0.25), ), ), child: material.Column( @@ -345,7 +345,7 @@ class _PreferencesShortcutsSectionState if (i > 0) QueryaDivider( height: 1, - color: theme.colorScheme.border.withValues(alpha: 0.18), + color: context.colors.border.withValues(alpha: 0.18), ), _buildShortcutRow(context, entry.value[i], theme), ], @@ -426,7 +426,7 @@ class _PreferencesShortcutsSectionState color: wb.surface, borderRadius: material.BorderRadius.circular(4), border: material.Border.all( - color: theme.colorScheme.border.withValues(alpha: 0.4), + color: context.colors.border.withValues(alpha: 0.4), ), boxShadow: [ material.BoxShadow( @@ -443,7 +443,7 @@ class _PreferencesShortcutsSectionState fontFamilyFallback: QueryaTypography.monoFontFamilyFallback, fontSize: 11, fontWeight: material.FontWeight.w600, - color: theme.colorScheme.foreground, + color: context.colors.foreground, ), ), ), diff --git a/lib/features/settings/theme_editor_dialog.dart b/lib/features/settings/theme_editor_dialog.dart index 66420771..167479d9 100644 --- a/lib/features/settings/theme_editor_dialog.dart +++ b/lib/features/settings/theme_editor_dialog.dart @@ -94,9 +94,9 @@ class _ThemeEditorDialogState extends material.State { try { initial = currentHex != null ? parseQueryaThemeColor(currentHex) - : Theme.of(context).colorScheme.primary; + : context.colors.primary; } on FormatException { - initial = Theme.of(context).colorScheme.primary; + initial = context.colors.primary; } final picked = await showThemeColorPickerDialog( @@ -147,8 +147,7 @@ class _ThemeEditorDialogState extends material.State { @override material.Widget build(material.BuildContext context) { - final theme = Theme.of(context); - final cs = theme.colorScheme; + final cs = context.colors; return QueryaModalDialog( constraints: WindowLayout.dialogConstraints( @@ -294,7 +293,7 @@ class _ThemeEditorColorRow extends material.StatelessWidget { @override material.Widget build(material.BuildContext context) { - final cs = Theme.of(context).colorScheme; + final cs = context.colors; Color? swatchColor; if (hex != null) { try { diff --git a/lib/features/settings/theme_editor_section.dart b/lib/features/settings/theme_editor_section.dart index f8cc93d1..f1d306c4 100644 --- a/lib/features/settings/theme_editor_section.dart +++ b/lib/features/settings/theme_editor_section.dart @@ -14,8 +14,7 @@ class ThemeEditorSection extends material.StatelessWidget { @override material.Widget build(material.BuildContext context) { - final theme = Theme.of(context); - final cs = theme.colorScheme; + final cs = context.colors; return material.Container( margin: const material.EdgeInsets.only(top: 12), diff --git a/lib/features/settings/theme_picker_button.dart b/lib/features/settings/theme_picker_button.dart index 73729a06..15e0d0ec 100644 --- a/lib/features/settings/theme_picker_button.dart +++ b/lib/features/settings/theme_picker_button.dart @@ -1,6 +1,8 @@ import 'dart:async'; import 'package:flutter/material.dart' as material; +import 'package:querya_desktop/core/theme/querya_theme_scope.dart'; +import 'package:querya_desktop/core/theme/querya_ui_colors.dart'; import 'package:querya_desktop/core/layout/ui_scale.dart'; import 'package:querya_desktop/core/motion/querya_motion.dart'; import 'package:querya_desktop/core/motion/querya_motion_context.dart'; @@ -8,7 +10,6 @@ import 'package:querya_desktop/core/theme/querya_theme.dart'; import 'package:querya_desktop/core/theme/theme_definition.dart'; import 'package:querya_desktop/features/settings/theme_preview_card.dart'; import 'package:querya_desktop/shared/widgets/querya_dropdown_tokens.dart'; -import 'package:shadcn_flutter/shadcn_flutter.dart' hide Gap, TextExtension; /// Debounce delay before requesting a hover preview load. const Duration themePreviewDebounce = Duration(milliseconds: 120); @@ -216,7 +217,7 @@ class _ThemePickerButtonState extends material.State { @override material.Widget build(material.BuildContext context) { - final cs = Theme.of(context).colorScheme; + final cs = context.colors; final fieldWidth = widget.expandToParent ? null : (widget.width != null ? context.scaled(widget.width!) : null); @@ -297,7 +298,7 @@ class _ThemePickerButtonState extends material.State { } material.Widget _buildMenuPanel( - material.BuildContext context, ColorScheme cs) { + material.BuildContext context, QueryaUiColors cs) { final filteredThemes = _filteredThemes; final radius = context.scaled(QueryaDropdownTokens.menuBorderRadius); @@ -393,7 +394,7 @@ class _ThemePickerButtonState extends material.State { return _ThemePickerRow( definition: theme, selected: theme.id == widget.selectedThemeId, - colorScheme: cs, + colors: cs, onHover: widget.onPreviewTheme == null ? null : () => _schedulePreview(theme), @@ -415,7 +416,7 @@ class _ThemePickerButtonState extends material.State { material.Widget _buildTrigger({ required material.BuildContext context, required material.MenuController controller, - required ColorScheme cs, + required QueryaUiColors cs, required double? fieldWidth, }) { final borderColor = _enabled @@ -492,7 +493,7 @@ class _ThemePickerButtonState extends material.State { material.Widget _triggerLabelText({ required material.BuildContext context, - required ColorScheme cs, + required QueryaUiColors cs, required bool expand, }) { final text = material.Text( @@ -574,14 +575,14 @@ class _ThemePickerRow extends material.StatefulWidget { const _ThemePickerRow({ required this.definition, required this.selected, - required this.colorScheme, + required this.colors, required this.onSelected, this.onHover, }); final ThemeDefinition definition; final bool selected; - final ColorScheme colorScheme; + final QueryaUiColors colors; final material.VoidCallback onSelected; final material.VoidCallback? onHover; @@ -594,7 +595,7 @@ class _ThemePickerRowState extends material.State<_ThemePickerRow> { @override material.Widget build(material.BuildContext context) { - final cs = widget.colorScheme; + final cs = widget.colors; final bg = _hovered ? cs.accent.withValues(alpha: 0.14) : widget.selected @@ -648,18 +649,18 @@ class _ThemePickerRowState extends material.State<_ThemePickerRow> { material.Expanded( child: _ThemePickerRowTitle( definition: widget.definition, - colorScheme: cs, + colors: cs, selected: widget.selected, ), ), material.SizedBox(width: context.scaled(6)), _SourceBadge( label: _sourceBadgeLabel(widget.definition.source), - colorScheme: cs, + colors: cs, ), material.SizedBox(width: context.scaled(6)), _BrightnessLabel( - isDark: widget.definition.isDark, colorScheme: cs), + isDark: widget.definition.isDark, colors: cs), ], ), ), @@ -672,17 +673,17 @@ class _ThemePickerRowState extends material.State<_ThemePickerRow> { class _ThemePickerRowTitle extends material.StatelessWidget { const _ThemePickerRowTitle({ required this.definition, - required this.colorScheme, + required this.colors, required this.selected, }); final ThemeDefinition definition; - final ColorScheme colorScheme; + final QueryaUiColors colors; final bool selected; @override material.Widget build(material.BuildContext context) { - final cs = colorScheme; + final cs = colors; final subtitle = definition.metadata?.pickerSubtitle; if (subtitle == null) { @@ -730,15 +731,15 @@ class _ThemePickerRowTitle extends material.StatelessWidget { class _SourceBadge extends material.StatelessWidget { const _SourceBadge({ required this.label, - required this.colorScheme, + required this.colors, }); final String label; - final ColorScheme colorScheme; + final QueryaUiColors colors; @override material.Widget build(material.BuildContext context) { - final cs = colorScheme; + final cs = colors; return material.Container( padding: material.EdgeInsets.symmetric( horizontal: context.scaled(6), @@ -767,15 +768,15 @@ class _SourceBadge extends material.StatelessWidget { class _BrightnessLabel extends material.StatelessWidget { const _BrightnessLabel({ required this.isDark, - required this.colorScheme, + required this.colors, }); final bool isDark; - final ColorScheme colorScheme; + final QueryaUiColors colors; @override material.Widget build(material.BuildContext context) { - final cs = colorScheme; + final cs = colors; return material.Row( mainAxisSize: material.MainAxisSize.min, children: [ diff --git a/lib/features/settings/theme_preview_card.dart b/lib/features/settings/theme_preview_card.dart index 2fd0ff8c..b20f55d0 100644 --- a/lib/features/settings/theme_preview_card.dart +++ b/lib/features/settings/theme_preview_card.dart @@ -44,7 +44,7 @@ class ThemePreviewCard extends material.StatelessWidget { @override material.Widget build(material.BuildContext context) { - final appScheme = Theme.of(context).colorScheme; + final appScheme = context.colors; final radius = context.scaled(QueryaDropdownTokens.menuBorderRadius); if (isLoading) { @@ -105,7 +105,7 @@ class ThemePreviewCard extends material.StatelessWidget { ); } - final scheme = previewTheme.colorScheme; + final scheme = previewTheme.colors; final workbench = previewTheme.workbench; final editor = previewTheme.editor; @@ -193,7 +193,7 @@ class ThemePreviewCard extends material.StatelessWidget { width: double.infinity, padding: material.EdgeInsets.all(context.scaled(8)), decoration: material.BoxDecoration( - color: Theme.of(context).colorScheme.muted.withValues(alpha: 0.12), + color: context.colors.muted.withValues(alpha: 0.12), borderRadius: material.BorderRadius.circular(radius), border: material.Border.all(color: borderColor), ), @@ -223,7 +223,7 @@ class _Swatch extends material.StatelessWidget { color: color, borderRadius: material.BorderRadius.circular(radius), border: material.Border.all( - color: Theme.of(context).colorScheme.border.withValues(alpha: 0.6), + color: context.colors.border.withValues(alpha: 0.6), ), ), ), @@ -232,7 +232,7 @@ class _Swatch extends material.StatelessWidget { label, style: material.TextStyle( fontSize: context.scaled(9), - color: Theme.of(context).colorScheme.mutedForeground, + color: context.colors.mutedForeground, ), ), ], diff --git a/lib/features/settings/theme_remote_install_dialog.dart b/lib/features/settings/theme_remote_install_dialog.dart index c8f7ea68..b513b551 100644 --- a/lib/features/settings/theme_remote_install_dialog.dart +++ b/lib/features/settings/theme_remote_install_dialog.dart @@ -72,7 +72,7 @@ class _ThemeRemoteInstallDialogState @override material.Widget build(material.BuildContext context) { - final cs = Theme.of(context).colorScheme; + final cs = context.colors; final host = Uri.tryParse(_urlController.text.trim())?.host; return QueryaModalDialog( diff --git a/lib/features/workspace/data_grid_calc_bar.dart b/lib/features/workspace/data_grid_calc_bar.dart index f4767d57..329e0343 100644 --- a/lib/features/workspace/data_grid_calc_bar.dart +++ b/lib/features/workspace/data_grid_calc_bar.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart' as material; import 'package:flutter/services.dart'; +import 'package:querya_desktop/core/theme/querya_theme_scope.dart'; import 'package:querya_desktop/core/motion/querya_animated_expand.dart'; import 'package:querya_desktop/core/theme/querya_typography.dart'; import 'package:querya_desktop/features/workspace/grid_selection_calc_engine.dart'; @@ -18,7 +19,7 @@ class DataGridCalcBar extends StatelessWidget { @override Widget build(BuildContext context) { final visible = stats.totalCount > 1 || stats.hasNumericStats; - final cs = Theme.of(context).colorScheme; + final cs = context.colors; return QueryaAnimatedExpand( expanded: visible, @@ -135,7 +136,7 @@ class _StatBadge extends StatelessWidget { @override Widget build(BuildContext context) { - final cs = Theme.of(context).colorScheme; + final cs = context.colors; return material.Tooltip( message: 'Click to copy $label: $value', diff --git a/lib/features/workspace/data_grid_filter_bar.dart b/lib/features/workspace/data_grid_filter_bar.dart index 4b3d8056..fe299020 100644 --- a/lib/features/workspace/data_grid_filter_bar.dart +++ b/lib/features/workspace/data_grid_filter_bar.dart @@ -1,6 +1,8 @@ import 'dart:async' show Timer; import 'package:flutter/material.dart' as material; import 'package:flutter/services.dart' show KeyDownEvent, LogicalKeyboardKey; +import 'package:querya_desktop/core/theme/querya_theme_scope.dart'; +import 'package:querya_desktop/core/theme/querya_ui_colors.dart'; import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; import 'package:querya_desktop/shared/widgets/querya_icon_button.dart'; import 'package:querya_desktop/shared/widgets/querya_text.dart'; @@ -216,7 +218,7 @@ class _DataGridFilterBarState extends material.State { _overlayEntry = material.OverlayEntry( builder: (context) { - final cs = Theme.of(context).colorScheme; + final cs = context.colors; return material.Positioned( width: 320, @@ -280,7 +282,7 @@ class _DataGridFilterBarState extends material.State { overlay.insert(_overlayEntry!); } - material.Widget _buildSuggestionIcon(FilterSuggestionKind kind, ColorScheme cs) { + material.Widget _buildSuggestionIcon(FilterSuggestionKind kind, QueryaUiColors cs) { switch (kind) { case FilterSuggestionKind.column: return material.Icon( @@ -334,7 +336,7 @@ class _DataGridFilterBarState extends material.State { @override material.Widget build(material.BuildContext context) { - final cs = Theme.of(context).colorScheme; + final cs = context.colors; final isFiltered = widget.filterText.trim().isNotEmpty; return material.CompositedTransformTarget( diff --git a/lib/features/workspace/data_grid_groupings_view.dart b/lib/features/workspace/data_grid_groupings_view.dart index a83284f2..aac300d9 100644 --- a/lib/features/workspace/data_grid_groupings_view.dart +++ b/lib/features/workspace/data_grid_groupings_view.dart @@ -110,7 +110,7 @@ class _DataGridGroupingsViewState ); } - final cs = Theme.of(context).colorScheme; + final cs = context.colors; final groups = _cachedGroups; return material.Column( diff --git a/lib/features/workspace/data_grid_staging_toolbar.dart b/lib/features/workspace/data_grid_staging_toolbar.dart index 9d514843..b14e45c1 100644 --- a/lib/features/workspace/data_grid_staging_toolbar.dart +++ b/lib/features/workspace/data_grid_staging_toolbar.dart @@ -24,7 +24,7 @@ class DataGridStagingToolbar extends StatelessWidget { @override Widget build(BuildContext context) { - final cs = Theme.of(context).colorScheme; + final cs = context.colors; return ListenableBuilder( listenable: stagingBuffer, @@ -165,7 +165,7 @@ class _PendingBadge extends StatelessWidget { @override Widget build(BuildContext context) { - final cs = Theme.of(context).colorScheme; + final cs = context.colors; final label = compact ? '$count' : '$count pending ${count == 1 ? 'change' : 'changes'}'; diff --git a/lib/features/workspace/data_grid_value_panel.dart b/lib/features/workspace/data_grid_value_panel.dart index ef187eec..08185c91 100644 --- a/lib/features/workspace/data_grid_value_panel.dart +++ b/lib/features/workspace/data_grid_value_panel.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:convert'; import 'package:flutter/material.dart' as material; import 'package:flutter/services.dart'; +import 'package:querya_desktop/core/theme/querya_theme_scope.dart'; import 'package:querya_desktop/core/editor/querya_code_editor.dart'; import 'package:querya_desktop/core/editor/querya_code_language.dart'; import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; @@ -275,7 +276,7 @@ class _DataGridValuePanelState extends material.State { @override material.Widget build(material.BuildContext context) { - final cs = Theme.of(context).colorScheme; + final cs = context.colors; final activeLang = _effectiveLanguage; return material.Container( diff --git a/lib/features/workspace/destructive_query_dialog.dart b/lib/features/workspace/destructive_query_dialog.dart index 5b6cc08c..e2dd1641 100644 --- a/lib/features/workspace/destructive_query_dialog.dart +++ b/lib/features/workspace/destructive_query_dialog.dart @@ -103,7 +103,7 @@ class _DestructiveQueryDialogState @override material.Widget build(material.BuildContext context) { final theme = Theme.of(context); - final cs = theme.colorScheme; + final cs = context.colors; final isDark = theme.brightness == Brightness.dark; final isCritical = widget.result.maxRiskLevel == 'CRITICAL'; diff --git a/lib/features/workspace/dml_preview_dialog.dart b/lib/features/workspace/dml_preview_dialog.dart index 4c1e777f..8ab5b588 100644 --- a/lib/features/workspace/dml_preview_dialog.dart +++ b/lib/features/workspace/dml_preview_dialog.dart @@ -62,7 +62,7 @@ class _DmlPreviewDialogState extends material.State<_DmlPreviewDialog> { @override material.Widget build(material.BuildContext context) { final theme = Theme.of(context); - final cs = theme.colorScheme; + final cs = context.colors; final wb = context.workbench; final isDark = theme.brightness == Brightness.dark; final sql = widget.plan.toTransactionSql(); diff --git a/lib/features/workspace/generic_table_view.dart b/lib/features/workspace/generic_table_view.dart index 5c2d987b..b0562241 100644 --- a/lib/features/workspace/generic_table_view.dart +++ b/lib/features/workspace/generic_table_view.dart @@ -677,7 +677,7 @@ class GenericTableViewState extends material.State { } material.Widget _buildDefaultToolbar() { - final cs = Theme.of(context).colorScheme; + final cs = context.colors; final title = '$effectiveTableTitle${widget.isMaterializedView ? ' (materialized view)' : widget.isView ? ' (view)' : ''}'; return material.Container( @@ -807,7 +807,7 @@ class GenericTableViewState extends material.State { @override material.Widget build(material.BuildContext context) { - final cs = Theme.of(context).colorScheme; + final cs = context.colors; final buffer = _stagingBuffer; final toolbar = widget.customToolbarBuilder != null diff --git a/lib/features/workspace/grid/grid_cell_actions.dart b/lib/features/workspace/grid/grid_cell_actions.dart index 6dae9a29..10d53df1 100644 --- a/lib/features/workspace/grid/grid_cell_actions.dart +++ b/lib/features/workspace/grid/grid_cell_actions.dart @@ -123,7 +123,7 @@ extension _GridCellActions on _VirtualResultGridState { StagedRowStatus.unchanged; final cellStatus = widget.stagingBuffer?.getCellStatus(modelRow, column) ?? StagedCellStatus.clean; - final cs = Theme.of(context).colorScheme; + final cs = context.colors; return [ MenuButton( diff --git a/lib/features/workspace/grid/grid_cell_renderer.dart b/lib/features/workspace/grid/grid_cell_renderer.dart index 4d9c889c..562f7ccc 100644 --- a/lib/features/workspace/grid/grid_cell_renderer.dart +++ b/lib/features/workspace/grid/grid_cell_renderer.dart @@ -8,7 +8,7 @@ class _GridCell extends material.StatelessWidget { this.columnName = '', required this.text, required this.width, - required this.colorScheme, + required this.colors, required this.striped, this.rowStatus = StagedRowStatus.unchanged, this.cellStatus = StagedCellStatus.clean, @@ -29,7 +29,7 @@ class _GridCell extends material.StatelessWidget { final String columnName; final String text; final double width; - final ColorScheme colorScheme; + final QueryaUiColors colors; final bool striped; final StagedRowStatus rowStatus; final StagedCellStatus cellStatus; @@ -61,7 +61,7 @@ class _GridCell extends material.StatelessWidget { columnName == other.columnName && text == other.text && width == other.width && - colorScheme == other.colorScheme && + colors == other.colors && striped == other.striped && rowStatus == other.rowStatus && cellStatus == other.cellStatus && @@ -110,12 +110,12 @@ class _GridCell extends material.StatelessWidget { final isModified = cellStatus == StagedCellStatus.modified; final style = _CellLook.style( - colorScheme, + colors, isNull: isNull, isDeleted: isDeleted, ); final decoration = _CellLook.decoration( - colorScheme, + colors, background: isSelected ? _CellBackground.selected : (isDeleted @@ -160,7 +160,7 @@ class _GridCell extends material.StatelessWidget { right: -8, child: material.CustomPaint( size: const material.Size(6, 6), - painter: _TriangleCornerPainter(color: colorScheme.primary), + painter: _TriangleCornerPainter(color: colors.primary), ), ), ], @@ -176,12 +176,12 @@ enum _CellBackground { selected, deleted, modified, inserted, striped, none } /// and shared (#1519): a scroll that builds a new row reuses them instead of /// allocating a style, a decoration, a border and four sides per cell. abstract final class _CellLook { - static ColorScheme? _scheme; + static QueryaUiColors? _scheme; static final _styles = List.filled(4, null); static final _decorations = {}; /// A new colour scheme (theme switch) drops what was built for the old one. - static void _forget(ColorScheme scheme) { + static void _forget(QueryaUiColors scheme) { if (identical(_scheme, scheme)) return; _scheme = scheme; _styles.fillRange(0, _styles.length, null); @@ -189,7 +189,7 @@ abstract final class _CellLook { } static material.TextStyle style( - ColorScheme scheme, { + QueryaUiColors scheme, { required bool isNull, required bool isDeleted, }) { @@ -213,7 +213,7 @@ abstract final class _CellLook { } static material.BoxDecoration decoration( - ColorScheme scheme, { + QueryaUiColors scheme, { required _CellBackground background, required bool right, required bool left, diff --git a/lib/features/workspace/grid/grid_header_renderer.dart b/lib/features/workspace/grid/grid_header_renderer.dart index ebb92cb4..83d94db4 100644 --- a/lib/features/workspace/grid/grid_header_renderer.dart +++ b/lib/features/workspace/grid/grid_header_renderer.dart @@ -6,7 +6,7 @@ class _HeaderRow extends material.StatelessWidget { required this.columnWidths, required this.window, required this.height, - required this.colorScheme, + required this.colors, this.sortColumnIndex, this.sortOrder, this.onSortColumn, @@ -18,7 +18,7 @@ class _HeaderRow extends material.StatelessWidget { final List columnWidths; final ResultGridColumnWindow window; final double height; - final ColorScheme colorScheme; + final QueryaUiColors colors; final int? sortColumnIndex; final ResultGridSortOrder? sortOrder; final material.ValueChanged? onSortColumn; @@ -30,10 +30,10 @@ class _HeaderRow extends material.StatelessWidget { return material.Container( height: height, decoration: material.BoxDecoration( - color: colorScheme.muted.withValues(alpha: 0.35), + color: colors.muted.withValues(alpha: 0.35), border: material.Border( bottom: material.BorderSide( - color: colorScheme.border.withValues(alpha: 0.5), + color: colors.border.withValues(alpha: 0.5), ), ), ), @@ -45,7 +45,7 @@ class _HeaderRow extends material.StatelessWidget { _HeaderCell( text: columns[i], width: columnWidths[i], - colorScheme: colorScheme, + colors: colors, sortOrder: sortColumnIndex == i ? sortOrder : null, onSort: onSortColumn != null ? () => onSortColumn!(i) : null, onResize: onResizeColumn != null @@ -66,7 +66,7 @@ class _HeaderCell extends material.StatelessWidget { const _HeaderCell({ required this.text, required this.width, - required this.colorScheme, + required this.colors, this.sortOrder, this.onSort, this.onResize, @@ -75,7 +75,7 @@ class _HeaderCell extends material.StatelessWidget { final String text; final double width; - final ColorScheme colorScheme; + final QueryaUiColors colors; final ResultGridSortOrder? sortOrder; final material.VoidCallback? onSort; final material.ValueChanged? onResize; @@ -87,7 +87,7 @@ class _HeaderCell extends material.StatelessWidget { final style = material.TextStyle( fontSize: 12, fontWeight: material.FontWeight.w600, - color: isSorted ? colorScheme.primary : colorScheme.foreground, + color: isSorted ? colors.primary : colors.foreground, ); return material.Container( @@ -96,7 +96,7 @@ class _HeaderCell extends material.StatelessWidget { decoration: material.BoxDecoration( border: material.Border( right: material.BorderSide( - color: colorScheme.border.withValues(alpha: 0.3), + color: colors.border.withValues(alpha: 0.3), ), ), ), @@ -138,7 +138,7 @@ class _HeaderCell extends material.StatelessWidget { child: material.Icon( material.Icons.arrow_upward_rounded, size: 14, - color: colorScheme.primary, + color: colors.primary, ), ), ], diff --git a/lib/features/workspace/grid/grid_row_renderer.dart b/lib/features/workspace/grid/grid_row_renderer.dart index f8986092..9c610bb2 100644 --- a/lib/features/workspace/grid/grid_row_renderer.dart +++ b/lib/features/workspace/grid/grid_row_renderer.dart @@ -10,7 +10,7 @@ class _DataRow extends material.StatefulWidget { required this.columnWidths, required this.window, required this.height, - required this.colorScheme, + required this.colors, required this.striped, this.selection, this.stagingBuffer, @@ -30,7 +30,7 @@ class _DataRow extends material.StatefulWidget { final List columnWidths; final ResultGridColumnWindow window; final double height; - final ColorScheme colorScheme; + final QueryaUiColors colors; final bool striped; final ResultGridSelection? selection; final DataGridStagingBuffer? stagingBuffer; @@ -69,7 +69,7 @@ class _DataRow extends material.StatefulWidget { foundation.listEquals(columnWidths, other.columnWidths)) && window == other.window && height == other.height && - colorScheme == other.colorScheme && + colors == other.colors && striped == other.striped && selection == other.selection && identical(stagingBuffer, other.stagingBuffer) && @@ -122,7 +122,7 @@ class _DataRow extends material.StatefulWidget { columnName: columnName, text: c < row.length ? _maskCellText(piiKinds, c, row[c]) : '', width: columnWidths[c], - colorScheme: colorScheme, + colors: colors, striped: striped, rowStatus: rowStatus, cellStatus: stagingBuffer?.getCellStatus(modelRowIndex, c) ?? diff --git a/lib/features/workspace/grid/grid_view_builder.dart b/lib/features/workspace/grid/grid_view_builder.dart index e720a3b9..cfc8e852 100644 --- a/lib/features/workspace/grid/grid_view_builder.dart +++ b/lib/features/workspace/grid/grid_view_builder.dart @@ -10,7 +10,7 @@ extension _GridViewBuilder on _VirtualResultGridState { _columnOffsets = computeResultGridColumnOffsets(_columnWidths); _widthsNeedUpdate = false; } - final cs = Theme.of(context).colorScheme; + final cs = context.colors; final piiKinds = _activePiiKinds; return material.CallbackShortcuts( @@ -354,7 +354,7 @@ extension _GridViewBuilder on _VirtualResultGridState { columnWidths: displayWidths, window: window, height: headerHeight, - colorScheme: cs, + colors: cs, sortColumnIndex: _sortColumnIndex, sortOrder: _sortOrder, onSortColumn: _toggleSort, @@ -403,7 +403,7 @@ extension _GridViewBuilder on _VirtualResultGridState { columnWidths: displayWidths, window: window, height: rowHeight, - colorScheme: cs, + colors: cs, striped: !isEven, selection: _selectionForRow(rowIndex), stagingBuffer: widget.stagingBuffer, diff --git a/lib/features/workspace/grid_cell_editor.dart b/lib/features/workspace/grid_cell_editor.dart index cb8737a3..7b55a26f 100644 --- a/lib/features/workspace/grid_cell_editor.dart +++ b/lib/features/workspace/grid_cell_editor.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart' as material; import 'package:flutter/services.dart'; +import 'package:querya_desktop/core/theme/querya_theme_scope.dart'; import 'package:querya_desktop/core/motion/querya_motion.dart'; import 'package:querya_desktop/core/motion/querya_motion_context.dart'; import 'package:querya_desktop/core/theme/querya_typography.dart'; @@ -158,7 +159,7 @@ class _GridCellEditorState extends material.State { @override material.Widget build(material.BuildContext context) { - final cs = Theme.of(context).colorScheme; + final cs = context.colors; final hasError = _validationError != null; return material.AnimatedContainer( diff --git a/lib/features/workspace/grid_cell_popover_inspector.dart b/lib/features/workspace/grid_cell_popover_inspector.dart index d00f7de4..bf2981ae 100644 --- a/lib/features/workspace/grid_cell_popover_inspector.dart +++ b/lib/features/workspace/grid_cell_popover_inspector.dart @@ -321,7 +321,7 @@ class _GridCellInspectorDialogState @override material.Widget build(material.BuildContext context) { - final cs = Theme.of(context).colorScheme; + final cs = context.colors; final rowLabel = widget.rowIndex != null ? ' (Row ${widget.rowIndex! + 1})' : ''; final text = _isNull ? '' : _controller.text; diff --git a/lib/features/workspace/plan_tree_view.dart b/lib/features/workspace/plan_tree_view.dart index 0a35525b..b61434bf 100644 --- a/lib/features/workspace/plan_tree_view.dart +++ b/lib/features/workspace/plan_tree_view.dart @@ -97,7 +97,7 @@ class _PlanRow extends material.StatelessWidget { color: hottest ? wb.accent.withValues(alpha: 0.12) : null, border: material.Border.all( color: selected - ? Theme.of(context).colorScheme.foreground + ? context.colors.foreground : hottest ? wb.accent : wb.borderSubtle, diff --git a/lib/features/workspace/result_grid_view.dart b/lib/features/workspace/result_grid_view.dart index fc3202c4..12cd6ae0 100644 --- a/lib/features/workspace/result_grid_view.dart +++ b/lib/features/workspace/result_grid_view.dart @@ -11,6 +11,7 @@ import 'package:flutter/gestures.dart' import 'package:flutter/material.dart' as material; import 'package:flutter/services.dart' show Clipboard, ClipboardData, HardwareKeyboard, LogicalKeyboardKey; +import 'package:querya_desktop/core/theme/querya_theme_scope.dart'; import 'package:querya_desktop/core/layout/ui_scale.dart'; import 'package:querya_desktop/core/motion/querya_motion.dart'; import 'package:querya_desktop/core/motion/querya_motion_context.dart'; @@ -25,6 +26,7 @@ import 'package:querya_desktop/features/workspace/grid/grid_column_sizer.dart'; import 'package:querya_desktop/features/workspace/grid/grid_selection_manager.dart'; import 'package:querya_desktop/features/workspace/grid/grid_sorting.dart'; import 'package:gap/gap.dart'; +import 'package:querya_desktop/core/theme/querya_ui_colors.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' hide Gap, TextExtension; export 'package:querya_desktop/features/workspace/grid/grid_column_sizer.dart'; @@ -330,7 +332,7 @@ class _VirtualResultGridState extends material.State { if (overlay == null || !mounted) return; final theme = Theme.of(context); - final cs = theme.colorScheme; + final cs = context.colors; final media = material.MediaQuery.maybeOf(context); final screenW = media?.size.width ?? 1920.0; final screenH = media?.size.height ?? 1080.0; diff --git a/lib/features/workspace/results_tab.dart b/lib/features/workspace/results_tab.dart index 5fc6abfc..f1af2c61 100644 --- a/lib/features/workspace/results_tab.dart +++ b/lib/features/workspace/results_tab.dart @@ -512,12 +512,10 @@ class _ResultsTabState extends material.State { vertical: 4, ), decoration: material.BoxDecoration( - color: Theme.of(context).colorScheme.card, + color: context.colors.card, border: material.Border( bottom: material.BorderSide( - color: Theme.of(context) - .colorScheme - .border + color: context.colors.border .withValues(alpha: 0.35), ), ), diff --git a/lib/features/workspace/sql_query_history_dialog.dart b/lib/features/workspace/sql_query_history_dialog.dart index 4e7bb8aa..460a0a00 100644 --- a/lib/features/workspace/sql_query_history_dialog.dart +++ b/lib/features/workspace/sql_query_history_dialog.dart @@ -250,7 +250,7 @@ class _SqlQueryHistoryDialogContentState @override material.Widget build(material.BuildContext context) { - final scheme = Theme.of(context).colorScheme; + final scheme = context.colors; return QueryaDialogCard( constraints: WindowLayout.dialogConstraints( context, diff --git a/lib/features/workspace/table_view_staging.dart b/lib/features/workspace/table_view_staging.dart index 37acfea7..4fcc7f9f 100644 --- a/lib/features/workspace/table_view_staging.dart +++ b/lib/features/workspace/table_view_staging.dart @@ -287,7 +287,7 @@ class _SaveFailedDialogState extends material.State<_SaveFailedDialog> { @override material.Widget build(material.BuildContext context) { - final cs = Theme.of(context).colorScheme; + final cs = context.colors; final info = widget.info; return QueryaDialogCard( constraints: const material.BoxConstraints(maxWidth: 480), diff --git a/test/guards/colors_through_context_test.dart b/test/guards/colors_through_context_test.dart index c7371f7b..7f806430 100644 --- a/test/guards/colors_through_context_test.dart +++ b/test/guards/colors_through_context_test.dart @@ -3,16 +3,19 @@ import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; /// Epic #1465, #1731: colours are read through `context.colors` -/// (`QueryaUiColors`), not through a theme's `colorScheme`. A folder joins +/// (`QueryaUiColors`), not through a theme's `colorScheme`. `Theme.of` itself +/// stays allowed for what is not a colour (brightness, radius) until #1735. A folder joins /// [migrated] in the PR that moves it; at the end the list is all of `lib/`. void main() { const migrated = [ 'lib/features/connections', 'lib/features/mongodb', 'lib/features/redis', + 'lib/features/settings', + 'lib/features/workspace', ]; - final banned = RegExp(r'\bcolorScheme\b|\bTheme\.of\(|\bColorScheme\b'); + final banned = RegExp(r'\bcolorScheme\b|\bColorScheme\b'); test('migrated folders read colours through context.colors', () { final offenders = []; diff --git a/test/guards/shadcn_imports_ratchet_test.dart b/test/guards/shadcn_imports_ratchet_test.dart index dd9d88a2..a651eced 100644 --- a/test/guards/shadcn_imports_ratchet_test.dart +++ b/test/guards/shadcn_imports_ratchet_test.dart @@ -38,7 +38,6 @@ void main() { 'lib/features/mysql/mysql_stats_view.dart', 'lib/features/postgresql/postgres_stats_view.dart', 'lib/features/settings/preferences_controls.dart', - 'lib/features/settings/theme_picker_button.dart', 'lib/features/updater/update_changelog_view.dart', 'lib/features/workspace/data_grid_calc_bar.dart', 'lib/features/workspace/data_grid_filter_bar.dart',