diff --git a/lib/core/sdui/sdui_form_builder.dart b/lib/core/sdui/sdui_form_builder.dart index 9a20bdbd..f1ff3858 100644 --- a/lib/core/sdui/sdui_form_builder.dart +++ b/lib/core/sdui/sdui_form_builder.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart' as material; import 'package:file_selector/file_selector.dart'; import 'package:querya_desktop/core/sdui/sdui_form_schema.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Renders a connection / settings form from an SDUI JSON schema (Block A). /// @@ -275,9 +276,10 @@ class SduiFormBuilderState extends material.State { ), ), const Gap(8), - OutlineButton( + QueryaButton.secondary( + label: 'Browse', onPressed: () => _pickFile(field), - child: const Text('Browse'), + size: QueryaControlSize.md, ), ], ), diff --git a/lib/core/unsaved_work_guard.dart b/lib/core/unsaved_work_guard.dart index 7f745245..5eb4a9ba 100644 --- a/lib/core/unsaved_work_guard.dart +++ b/lib/core/unsaved_work_guard.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart' as material; import 'package:querya_desktop/core/unsaved_work_registry.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Confirms before Home / Close / tree navigation discards SQL, staged grid /// edits, or a dirty document editor. Returns true when it is safe to tear @@ -40,13 +41,15 @@ Future showDiscardUnsavedWorkDialog(material.BuildContext context) { spacing: 8, runSpacing: 8, children: [ - OutlineButton( + QueryaButton.ghost( + label: 'Cancel', onPressed: () => material.Navigator.of(ctx).pop(false), - child: const Text('Cancel'), + size: QueryaControlSize.lg, ), - DestructiveButton( + QueryaButton.destructive( + label: 'Discard', onPressed: () => material.Navigator.of(ctx).pop(true), - child: const Text('Discard'), + size: QueryaControlSize.lg, ), ], ), diff --git a/lib/features/connections/driver_manager_dialog.dart b/lib/features/connections/driver_manager_dialog.dart index a52e780c..40ddb41b 100644 --- a/lib/features/connections/driver_manager_dialog.dart +++ b/lib/features/connections/driver_manager_dialog.dart @@ -6,6 +6,7 @@ import 'package:querya_desktop/features/connections/connection_type_choice.dart' import 'package:querya_desktop/features/connections/driver_icon.dart'; import 'package:querya_desktop/features/connections/new_connection_dialog.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// One row in the driver list. typedef _DriverInfo = ({ @@ -138,9 +139,10 @@ class _DriverManagerDialogContent extends material.StatelessWidget { child: material.Row( mainAxisAlignment: material.MainAxisAlignment.end, children: [ - PrimaryButton( + QueryaButton.primary( + label: 'Close', onPressed: () => material.Navigator.of(context).pop(), - child: const Text('Close'), + size: QueryaControlSize.lg, ), ], ), diff --git a/lib/features/connections/new_connection_dialog.dart b/lib/features/connections/new_connection_dialog.dart index 56b9e11c..26ddf8aa 100644 --- a/lib/features/connections/new_connection_dialog.dart +++ b/lib/features/connections/new_connection_dialog.dart @@ -8,6 +8,7 @@ import 'package:querya_desktop/core/layout/window_layout.dart'; import 'package:querya_desktop/core/motion/querya_hover_surface.dart'; import 'package:querya_desktop/features/connections/driver_icon.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; export 'package:querya_desktop/core/database/connection_type.dart'; export 'package:querya_desktop/core/database/connection_type_choice.dart'; @@ -237,16 +238,18 @@ class _NewConnectionDialogContentState child: material.Row( mainAxisAlignment: material.MainAxisAlignment.end, children: [ - GhostButton( + QueryaButton.ghost( + label: 'Cancel', onPressed: () => material.Navigator.of(context).pop(), - child: const Text('Cancel'), + size: QueryaControlSize.lg, ), const material.SizedBox(width: 12), - PrimaryButton( + QueryaButton.primary( + label: 'Next', onPressed: _selected == null ? null : () => material.Navigator.of(context).pop(_selected), - child: const Text('Next'), + size: QueryaControlSize.lg, ), ], ), diff --git a/lib/features/connections/new_connection_url_dialog.dart b/lib/features/connections/new_connection_url_dialog.dart index 077897e6..a57d1175 100644 --- a/lib/features/connections/new_connection_url_dialog.dart +++ b/lib/features/connections/new_connection_url_dialog.dart @@ -3,6 +3,7 @@ import 'package:querya_desktop/core/layout/window_layout.dart'; import 'package:querya_desktop/core/storage/local_db.dart'; import 'package:querya_desktop/features/connections/connection_url_parser.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Shows a dialog to create a new database connection from a URI. /// Returns the ConnectionRow or null if cancelled. @@ -208,14 +209,16 @@ class _NewConnectionUrlDialogContentState child: material.Row( mainAxisAlignment: material.MainAxisAlignment.end, children: [ - GhostButton( + QueryaButton.ghost( + label: 'Cancel', onPressed: () => material.Navigator.of(context).pop(), - child: const Text('Cancel'), + size: QueryaControlSize.lg, ), const material.SizedBox(width: 12), - PrimaryButton( + QueryaButton.primary( + label: 'Create', onPressed: _validateAndSubmit, - child: const Text('Create'), + size: QueryaControlSize.lg, ), ], ), diff --git a/lib/features/connections/new_folder_dialog.dart b/lib/features/connections/new_folder_dialog.dart index f7cc9ced..cd3d97e5 100644 --- a/lib/features/connections/new_folder_dialog.dart +++ b/lib/features/connections/new_folder_dialog.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart' as material; import 'package:querya_desktop/core/layout/window_layout.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Shows a dialog to create a new folder (same style as new connection). /// Returns the folder name or null if cancelled. @@ -100,18 +101,20 @@ class _NewFolderDialogContentState child: material.Row( mainAxisAlignment: material.MainAxisAlignment.end, children: [ - GhostButton( + QueryaButton.ghost( + label: 'Cancel', onPressed: () => material.Navigator.of(context).pop(), - child: const Text('Cancel'), + size: QueryaControlSize.lg, ), const material.SizedBox(width: 12), ListenableBuilder( listenable: _nameController, - builder: (context, __) => PrimaryButton( + builder: (context, __) => QueryaButton.primary( + label: 'Create', onPressed: _name.isEmpty ? null : () => material.Navigator.of(context).pop(_name), - child: const Text('Create'), + size: QueryaControlSize.lg, ), ), ], diff --git a/lib/features/connections/ssh_tunnel_section.dart b/lib/features/connections/ssh_tunnel_section.dart index e94c4527..e44def2d 100644 --- a/lib/features/connections/ssh_tunnel_section.dart +++ b/lib/features/connections/ssh_tunnel_section.dart @@ -346,18 +346,14 @@ class _SshTunnelSectionState extends material.State { placeholder: const Text('••••••••'), features: [ InputFeature.trailing( - IconButton.ghost( - size: ButtonSize.small, - icon: material.Icon( - _obscurePassword - ? material.Icons.visibility_off_outlined - : material.Icons.visibility_outlined, - size: 16, - ), + QueryaButton.icon( + icon: _obscurePassword + ? material.Icons.visibility_off_outlined + : material.Icons.visibility_outlined, + tooltip: _obscurePassword ? 'Show password' : 'Hide password', + size: QueryaControlSize.sm, onPressed: () { - setState( - () => _obscurePassword = !_obscurePassword, - ); + setState(() => _obscurePassword = !_obscurePassword); }, ), ), @@ -404,18 +400,14 @@ class _SshTunnelSectionState extends material.State { placeholder: const Text('Passphrase if key is encrypted'), features: [ InputFeature.trailing( - IconButton.ghost( - size: ButtonSize.small, - icon: material.Icon( - _obscurePassphrase - ? material.Icons.visibility_off_outlined - : material.Icons.visibility_outlined, - size: 16, - ), + QueryaButton.icon( + icon: _obscurePassphrase + ? material.Icons.visibility_off_outlined + : material.Icons.visibility_outlined, + tooltip: _obscurePassphrase ? 'Show passphrase' : 'Hide passphrase', + size: QueryaControlSize.sm, onPressed: () { - setState( - () => _obscurePassphrase = !_obscurePassphrase, - ); + setState(() => _obscurePassphrase = !_obscurePassphrase); }, ), ), diff --git a/lib/features/erd/erd_group_dialog.dart b/lib/features/erd/erd_group_dialog.dart index e5826803..f52fb3f8 100644 --- a/lib/features/erd/erd_group_dialog.dart +++ b/lib/features/erd/erd_group_dialog.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart' as material; import 'package:querya_desktop/core/layout/window_layout.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Name and note of a diagram group (#1282), as the user typed them. typedef ErdGroupText = ({String name, String? note}); @@ -116,17 +117,19 @@ class _ErdGroupDialogState extends material.State<_ErdGroupDialog> { child: material.Row( mainAxisAlignment: material.MainAxisAlignment.end, children: [ - GhostButton( + QueryaButton.ghost( + label: 'Cancel', onPressed: () => material.Navigator.of(context).pop(), - child: const Text('Cancel'), + size: QueryaControlSize.lg, ), const material.SizedBox(width: 12), ListenableBuilder( listenable: _name, - builder: (context, _) => PrimaryButton( + builder: (context, _) => QueryaButton.primary( key: const material.ValueKey('erd_group_submit'), + label: widget.action, onPressed: _name.text.trim().isEmpty ? null : _submit, - child: Text(widget.action), + size: QueryaControlSize.lg, ), ), ], diff --git a/lib/features/erd/erd_note_dialog.dart b/lib/features/erd/erd_note_dialog.dart index 7a97525c..02e42217 100644 --- a/lib/features/erd/erd_note_dialog.dart +++ b/lib/features/erd/erd_note_dialog.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart' as material; import 'package:querya_desktop/core/layout/window_layout.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Asks for the text of a sticky note (#1283); null when cancelled. Future showErdNoteDialog( @@ -92,20 +93,22 @@ class _ErdNoteDialogState extends material.State<_ErdNoteDialog> { child: material.Row( mainAxisAlignment: material.MainAxisAlignment.end, children: [ - GhostButton( + QueryaButton.ghost( + label: 'Cancel', onPressed: () => material.Navigator.of(context).pop(), - child: const Text('Cancel'), + size: QueryaControlSize.lg, ), const material.SizedBox(width: 12), ListenableBuilder( listenable: _text, - builder: (context, _) => PrimaryButton( + builder: (context, _) => QueryaButton.primary( key: const material.ValueKey('erd_note_submit'), + label: widget.action, onPressed: _text.text.trim().isEmpty ? null : () => material.Navigator.of(context) .pop(_text.text.trim()), - child: Text(widget.action), + size: QueryaControlSize.lg, ), ), ], diff --git a/lib/features/erd/erd_view_name_dialog.dart b/lib/features/erd/erd_view_name_dialog.dart index 378de7f8..24b30890 100644 --- a/lib/features/erd/erd_view_name_dialog.dart +++ b/lib/features/erd/erd_view_name_dialog.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart' as material; import 'package:querya_desktop/core/layout/window_layout.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Asks for the name of a saved diagram view (#1284); null when cancelled. Future showErdViewNameDialog( @@ -98,17 +99,19 @@ class _ErdViewNameDialogState extends material.State<_ErdViewNameDialog> { child: material.Row( mainAxisAlignment: material.MainAxisAlignment.end, children: [ - GhostButton( + QueryaButton.ghost( + label: 'Cancel', onPressed: () => material.Navigator.of(context).pop(), - child: const Text('Cancel'), + size: QueryaControlSize.lg, ), const material.SizedBox(width: 12), ListenableBuilder( listenable: _name, - builder: (context, _) => PrimaryButton( + builder: (context, _) => QueryaButton.primary( key: const material.ValueKey('erd_view_submit'), + label: widget.action, onPressed: _name.text.trim().isEmpty ? null : _submit, - child: Text(widget.action), + size: QueryaControlSize.lg, ), ), ], diff --git a/lib/features/extensions/extension_connection_picker_dialog.dart b/lib/features/extensions/extension_connection_picker_dialog.dart index 4919c330..070b3adf 100644 --- a/lib/features/extensions/extension_connection_picker_dialog.dart +++ b/lib/features/extensions/extension_connection_picker_dialog.dart @@ -4,6 +4,7 @@ import 'package:querya_desktop/core/storage/local_db.dart'; import 'package:querya_desktop/core/ui/querya_icons.dart'; import 'package:querya_desktop/features/connections/driver_icon.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Prompts the user to pick which of several equally-live connections an /// ambiguous extension command should target (#892), instead of silently @@ -101,9 +102,10 @@ class _ExtensionConnectionPickerDialog extends material.StatelessWidget { const Gap(12), material.Align( alignment: material.Alignment.centerRight, - child: OutlineButton( + child: QueryaButton.ghost( + label: 'Cancel', onPressed: () => material.Navigator.of(context).pop(), - child: const Text('Cancel'), + size: QueryaControlSize.lg, ), ), ], diff --git a/lib/features/extensions/extension_sql_workspace.dart b/lib/features/extensions/extension_sql_workspace.dart index 4103a659..127cbc05 100644 --- a/lib/features/extensions/extension_sql_workspace.dart +++ b/lib/features/extensions/extension_sql_workspace.dart @@ -7,6 +7,7 @@ import 'package:querya_desktop/core/storage/local_db.dart'; import 'package:querya_desktop/features/extensions/extension_driver_recovery_banner.dart'; import 'package:querya_desktop/features/workspace/workspace.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Table/view selected in the sidebar tree of an extension connection. typedef ExtensionSelectedObject = ({String database, String name}); @@ -216,7 +217,6 @@ class _ExtensionSqlWorkspaceState extends material.State @override material.Widget build(material.BuildContext context) { - final accent = context.workbench.accent; return GenericSqlWorkspace( key: _workspaceKey, connectionRow: widget.connectionRow, @@ -241,41 +241,31 @@ class _ExtensionSqlWorkspaceState extends material.State return material.Row( mainAxisSize: material.MainAxisSize.min, children: [ - IconButton.ghost( + QueryaButton.icon( + icon: material.Icons.restart_alt_rounded, + tooltip: 'Restart driver', + loading: _restartingDriver, + size: QueryaControlSize.md, onPressed: session.running || _restartingDriver ? null : () => unawaited(_restartDriver()), - icon: _restartingDriver - ? QueryaSpinner( - size: QueryaSpinnerSize.sm, - color: accent, - ) - : material.Icon( - material.Icons.restart_alt_rounded, - size: 18, - color: accent, - ), ), const Gap(4), - IconButton.ghost( + QueryaButton.icon( + icon: material.Icons.folder_open_rounded, + tooltip: 'Open .sql file', + size: QueryaControlSize.md, onPressed: session.running ? null : () => unawaited(_workspaceKey.currentState?.openSqlFile()), - icon: material.Icon( - material.Icons.folder_open_rounded, - size: 18, - color: accent, - ), ), const Gap(4), - IconButton.ghost( + QueryaButton.icon( + icon: material.Icons.save_outlined, + tooltip: 'Save .sql file', + size: QueryaControlSize.md, onPressed: () => unawaited(_workspaceKey.currentState?.saveSqlFile()), - icon: material.Icon( - material.Icons.save_outlined, - size: 18, - color: accent, - ), ), ], ); diff --git a/lib/features/extensions/extension_stats_view.dart b/lib/features/extensions/extension_stats_view.dart index aa199ba0..d091cb2d 100644 --- a/lib/features/extensions/extension_stats_view.dart +++ b/lib/features/extensions/extension_stats_view.dart @@ -9,6 +9,7 @@ import 'package:querya_desktop/core/storage/local_db.dart'; import 'package:querya_desktop/core/util/deep_collection_equals.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' as shadcn; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; const _pollInterval = Duration(seconds: 5); const _summaryChipHeight = 88.0; @@ -151,11 +152,11 @@ class _ExtensionStatsViewState extends material.State { style: material.TextStyle( color: cs.mutedForeground, fontSize: 13)), const Gap(24), - OutlineButton( + QueryaButton.secondary( + label: 'Retry', + icon: material.Icons.refresh_rounded, onPressed: _load, - leading: const material.Icon(material.Icons.refresh_rounded, - size: 18), - child: const Text('Retry'), + size: QueryaControlSize.md, ), ], ), @@ -243,11 +244,11 @@ class _ExtensionStatsViewState extends material.State { ), ], ), - OutlineButton( + QueryaButton.secondary( + label: 'Refresh', + icon: material.Icons.refresh_rounded, onPressed: _load, - leading: const material.Icon(material.Icons.refresh_rounded, - size: 18), - child: const Text('Refresh'), + size: QueryaControlSize.md, ), ], ), diff --git a/lib/features/extensions/extension_workspace_home.dart b/lib/features/extensions/extension_workspace_home.dart index 1cc9cb91..8149b7e0 100644 --- a/lib/features/extensions/extension_workspace_home.dart +++ b/lib/features/extensions/extension_workspace_home.dart @@ -6,6 +6,7 @@ import 'package:querya_desktop/core/storage/local_db.dart'; import 'package:querya_desktop/features/extensions/extension_sql_workspace.dart'; import 'package:querya_desktop/features/extensions/extension_stats_view.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// When an extension database driver connection is selected without a table or view: /// provides level 2 Universal UI Standard tabs: Server Stats (Overview) or SQL editor. @@ -109,14 +110,11 @@ class _ExtensionWorkspaceHomeState if (widget.lastSelectedExtensionObject != null && widget.onRestoreLastSelectedObject != null) ...[ const Gap(12), - OutlineButton( - size: ButtonSize.small, + QueryaButton.secondary( + label: 'Return to ${widget.lastSelectedExtensionObject!.name}', + icon: material.Icons.table_chart_outlined, onPressed: widget.onRestoreLastSelectedObject, - leading: const material.Icon( - material.Icons.table_chart_outlined, - size: 14, - ), - child: Text('Return to ${widget.lastSelectedExtensionObject!.name}'), + size: QueryaControlSize.sm, ), ], material.Expanded( diff --git a/lib/features/extensions/presentation/pages/extension_manager_dialog.dart b/lib/features/extensions/presentation/pages/extension_manager_dialog.dart index 5781c635..e8bf9d50 100644 --- a/lib/features/extensions/presentation/pages/extension_manager_dialog.dart +++ b/lib/features/extensions/presentation/pages/extension_manager_dialog.dart @@ -12,6 +12,7 @@ import 'package:querya_desktop/core/motion/querya_cross_fade_stack.dart'; import 'package:querya_desktop/features/extensions/presentation/widgets/extension_card.dart'; import 'package:querya_desktop/features/extensions/presentation/widgets/extension_sideload_dialog.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Pause after the last keystroke before the marketplace is queried. const kMarketplaceSearchDebounce = Duration(milliseconds: 250); @@ -232,9 +233,10 @@ class _ExtensionManagerContentState ), ), const material.SizedBox(width: 16), - PrimaryButton( + QueryaButton.primary( + label: 'Close', onPressed: () => material.Navigator.of(context).pop(), - child: const Text('Close'), + size: QueryaControlSize.lg, ), ], ), @@ -283,11 +285,10 @@ class _ExtensionManagerContentState padding: const material.EdgeInsets.fromLTRB(24, 16, 24, 0), child: material.Row( children: [ - OutlineButton( + QueryaButton.secondary( + label: _sideloading ? 'Installing…' : 'Install from file…', onPressed: _sideloading ? null : _installFromLocalFile, - child: Text( - _sideloading ? 'Installing…' : 'Install from file…', - ), + size: QueryaControlSize.lg, ), const material.SizedBox(width: 12), material.Expanded( diff --git a/lib/features/extensions/presentation/widgets/extension_sideload_dialog.dart b/lib/features/extensions/presentation/widgets/extension_sideload_dialog.dart index 842921ca..ce8d2552 100644 --- a/lib/features/extensions/presentation/widgets/extension_sideload_dialog.dart +++ b/lib/features/extensions/presentation/widgets/extension_sideload_dialog.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart' as material; import 'package:path/path.dart' as p; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; class ExtensionSideloadRequest { const ExtensionSideloadRequest({ @@ -114,13 +115,15 @@ class _ExtensionSideloadDialogState ), ), actions: [ - OutlineButton( + QueryaButton.ghost( + label: 'Cancel', onPressed: () => material.Navigator.pop(context), - child: const material.Text('Cancel'), + size: QueryaControlSize.lg, ), - PrimaryButton( + QueryaButton.primary( + label: 'Install', onPressed: _submit, - child: const material.Text('Install'), + size: QueryaControlSize.lg, ), ], ); diff --git a/lib/features/extensions/presentation/widgets/unsandboxed_driver_consent_dialog.dart b/lib/features/extensions/presentation/widgets/unsandboxed_driver_consent_dialog.dart index 727c2afe..44811a35 100644 --- a/lib/features/extensions/presentation/widgets/unsandboxed_driver_consent_dialog.dart +++ b/lib/features/extensions/presentation/widgets/unsandboxed_driver_consent_dialog.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart' as material; import 'package:querya_desktop/core/extensions/sandbox/sandbox_os_isolation.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; Future showUnsandboxedDriverConsentDialog( material.BuildContext context, @@ -37,13 +38,15 @@ Future showUnsandboxedDriverConsentDialog( ), ), actions: [ - OutlineButton( + QueryaButton.ghost( + label: 'Cancel', onPressed: () => material.Navigator.pop(dialogContext, false), - child: const material.Text('Cancel'), + size: QueryaControlSize.lg, ), - PrimaryButton( + QueryaButton.primary( + label: 'Run without OS sandbox', onPressed: () => material.Navigator.pop(dialogContext, true), - child: const material.Text('Run without OS sandbox'), + size: QueryaControlSize.lg, ), ], ), diff --git a/lib/features/help/about_dialog.dart b/lib/features/help/about_dialog.dart index e39c82d5..275937f9 100644 --- a/lib/features/help/about_dialog.dart +++ b/lib/features/help/about_dialog.dart @@ -4,6 +4,7 @@ import 'package:querya_desktop/core/app/external_link.dart'; import 'package:querya_desktop/core/layout/window_layout.dart'; import 'package:querya_desktop/core/ui/querya_icons.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Shows the About Querya dialog. Future showAboutDialog(material.BuildContext context) { @@ -71,9 +72,10 @@ class _AboutDialogContentState extends material.State<_AboutDialogContent> { 'Licensed under the MIT License.', ).small(), const material.SizedBox(height: 16), - GhostButton( + QueryaButton.ghost( + label: 'View repository', onPressed: () => launchRepositoryUrl(), - child: const Text('View repository'), + size: QueryaControlSize.lg, ), ], ), @@ -93,9 +95,10 @@ class _AboutDialogContentState extends material.State<_AboutDialogContent> { child: material.Row( mainAxisAlignment: material.MainAxisAlignment.end, children: [ - PrimaryButton( + QueryaButton.primary( + label: 'Close', onPressed: () => material.Navigator.of(context).pop(), - child: const Text('Close'), + size: QueryaControlSize.lg, ), ], ), diff --git a/lib/features/main_screen/safe_mode_unlock_dialog.dart b/lib/features/main_screen/safe_mode_unlock_dialog.dart index cff3b8c7..f506ca84 100644 --- a/lib/features/main_screen/safe_mode_unlock_dialog.dart +++ b/lib/features/main_screen/safe_mode_unlock_dialog.dart @@ -3,6 +3,7 @@ import 'package:querya_desktop/core/security/connection_environment.dart'; import 'package:querya_desktop/core/security/safe_mode.dart'; import 'package:querya_desktop/shared/widgets/connection_environment_badge.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Asks the user to type the connection name before a Production connection /// is made writable. Resolves to `true` only after a matching confirmation. @@ -76,14 +77,16 @@ class _SafeModeUnlockDialogState extends material.State { ], ), actions: [ - OutlineButton( + QueryaButton.ghost( + label: 'Cancel', onPressed: () => material.Navigator.of(context).pop(false), - child: const Text('Cancel'), + size: QueryaControlSize.lg, ), - DestructiveButton( + QueryaButton.destructive( key: const material.Key('safe_mode_unlock_confirm'), + label: 'Unlock for $minutes minutes', onPressed: _valid ? _confirm : null, - child: Text('Unlock for $minutes minutes'), + size: QueryaControlSize.lg, ), ], ); diff --git a/lib/features/mongodb/mongo_add_document_dialog.dart b/lib/features/mongodb/mongo_add_document_dialog.dart index 4f004a24..35c02e48 100644 --- a/lib/features/mongodb/mongo_add_document_dialog.dart +++ b/lib/features/mongodb/mongo_add_document_dialog.dart @@ -4,6 +4,7 @@ import 'package:querya_desktop/core/editor/querya_code_language.dart'; import 'package:querya_desktop/core/layout/window_layout.dart'; import 'package:querya_desktop/features/mongodb/mongo_ejson.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; const kDefaultDraftMongoDocument = '{\n \n}'; @@ -178,16 +179,17 @@ class _MongoAddDocumentDialogState extends material.State material.Navigator.of(context).pop(), - child: const Text('Cancel'), + size: QueryaControlSize.lg, ), const Gap(12), - PrimaryButton( + QueryaButton.primary( + label: 'Insert Document', + icon: material.Icons.add_rounded, onPressed: _submit, - leading: - const material.Icon(material.Icons.add_rounded, size: 16), - child: const Text('Insert Document'), + size: QueryaControlSize.lg, ), ], ), diff --git a/lib/features/mongodb/mongo_database_dialog.dart b/lib/features/mongodb/mongo_database_dialog.dart index 7c9221c4..84cc14ac 100644 --- a/lib/features/mongodb/mongo_database_dialog.dart +++ b/lib/features/mongodb/mongo_database_dialog.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart' as material; import 'package:querya_desktop/core/layout/window_layout.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Shows dialog to create a new MongoDB database. Future showCreateMongoDBDialog(material.BuildContext context) async { @@ -92,16 +93,18 @@ class _CreateMongoDBDialogContentState child: material.Row( mainAxisAlignment: material.MainAxisAlignment.end, children: [ - GhostButton( + QueryaButton.ghost( + label: 'Cancel', onPressed: () => material.Navigator.of(context).pop(), - child: const Text('Cancel'), + size: QueryaControlSize.lg, ), const Gap(12), ListenableBuilder( listenable: _nameController, - builder: (context, __) => PrimaryButton( + builder: (context, __) => QueryaButton.primary( + label: 'Create', onPressed: _formValid ? _save : null, - child: const Text('Create'), + size: QueryaControlSize.lg, ), ), ], diff --git a/lib/features/mongodb/mongo_databases_view.dart b/lib/features/mongodb/mongo_databases_view.dart index 7a87de66..3211d454 100644 --- a/lib/features/mongodb/mongo_databases_view.dart +++ b/lib/features/mongodb/mongo_databases_view.dart @@ -6,6 +6,7 @@ import 'package:querya_desktop/core/storage/local_db.dart'; import 'package:querya_desktop/features/workspace/destructive_query_dialog.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' as shadcn; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// View that displays MongoDB databases list and server status. class MongoDatabasesView extends StatefulWidget { @@ -247,11 +248,11 @@ class _MongoDatabasesViewState extends State { material.TextStyle(color: cs.mutedForeground, fontSize: 13), ), const Gap(24), - OutlineButton( + QueryaButton.secondary( + label: 'Retry', + icon: material.Icons.refresh_rounded, onPressed: _connectAndLoad, - leading: const material.Icon(material.Icons.refresh_rounded, - size: 18), - child: const Text('Retry'), + size: QueryaControlSize.md, ), ], ), @@ -309,12 +310,11 @@ class _MongoDatabasesViewState extends State { ), ), const Gap(8), - PrimaryButton( + QueryaButton.primary( + label: 'Create', + icon: material.Icons.add_rounded, onPressed: _createDatabase, - size: ButtonSize.small, - leading: - const material.Icon(material.Icons.add_rounded, size: 16), - child: const Text('Create'), + size: QueryaControlSize.sm, ), ], ), diff --git a/lib/features/mongodb/mongo_documents_json_view.dart b/lib/features/mongodb/mongo_documents_json_view.dart index 9794835f..9d6e8b72 100644 --- a/lib/features/mongodb/mongo_documents_json_view.dart +++ b/lib/features/mongodb/mongo_documents_json_view.dart @@ -5,6 +5,8 @@ import 'package:querya_desktop/core/editor/querya_code_language.dart'; import 'package:querya_desktop/features/mongodb/mongo_ejson.dart'; import 'package:querya_desktop/shared/widgets/app_toast.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; +import 'package:querya_desktop/shared/widgets/querya_button.dart'; /// Full-page formatted Extended JSON viewer using [QueryaCodeEditor]. class MongoDocumentsJsonView extends StatefulWidget { @@ -92,14 +94,11 @@ class _MongoDocumentsJsonViewState extends State { .muted() .small(), const Spacer(), - OutlineButton( + QueryaButton.secondary( + label: 'Copy JSON', + icon: material.Icons.copy_rounded, onPressed: _copyJson, - size: ButtonSize.small, - leading: const material.Icon( - material.Icons.copy_rounded, - size: 13, - ), - child: const Text('Copy JSON'), + size: QueryaControlSize.sm, ), ], ), diff --git a/lib/features/mongodb/mongo_explorer_view.dart b/lib/features/mongodb/mongo_explorer_view.dart index 0a82e695..22a4fca8 100644 --- a/lib/features/mongodb/mongo_explorer_view.dart +++ b/lib/features/mongodb/mongo_explorer_view.dart @@ -17,6 +17,7 @@ import 'mongo_document_editor.dart'; import 'mongo_indexes_view.dart'; import 'mongo_query_workspace.dart'; import 'mongo_stats_view.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; // ─── Navigation path model ────────────────────────────────────────────────── @@ -331,11 +332,11 @@ class _MongoExplorerViewState extends material.State { style: material.TextStyle( color: cs.mutedForeground, fontSize: 13)), const Gap(24), - OutlineButton( + QueryaButton.secondary( + label: 'Retry', + icon: material.Icons.refresh_rounded, onPressed: _connect, - leading: const material.Icon(material.Icons.refresh_rounded, - size: 18), - child: const Text('Retry'), + size: QueryaControlSize.md, ), ], ), diff --git a/lib/features/mysql/mysql_routine_view.dart b/lib/features/mysql/mysql_routine_view.dart index de493d4e..2aeb4445 100644 --- a/lib/features/mysql/mysql_routine_view.dart +++ b/lib/features/mysql/mysql_routine_view.dart @@ -6,6 +6,7 @@ import 'package:querya_desktop/core/storage/local_db.dart'; import 'package:querya_desktop/core/widgets/virtual_selectable_text_view.dart'; import 'package:querya_desktop/features/workspace/sql_editor_chrome.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Displays MySQL routine DDL (`SHOW CREATE PROCEDURE` / `SHOW CREATE FUNCTION`). class MysqlRoutineView extends material.StatefulWidget { @@ -153,14 +154,11 @@ class _MysqlRoutineViewState extends material.State { .semiBold() .small(), ), - OutlineButton( - size: ButtonSize.small, + QueryaButton.secondary( + label: 'Refresh', + icon: material.Icons.refresh_rounded, onPressed: _loading ? null : _loadRoutine, - leading: const material.Icon( - material.Icons.refresh_rounded, - size: 14, - ), - child: const Text('Refresh'), + size: QueryaControlSize.sm, ), ], ), diff --git a/lib/features/mysql/mysql_stats_view.dart b/lib/features/mysql/mysql_stats_view.dart index 327e1bc3..9181b5bd 100644 --- a/lib/features/mysql/mysql_stats_view.dart +++ b/lib/features/mysql/mysql_stats_view.dart @@ -10,6 +10,7 @@ import 'package:querya_desktop/core/storage/local_db.dart'; import 'package:querya_desktop/shared/widgets/querya_sparkline.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' as shadcn; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; const _pollInterval = Duration(seconds: 5); const _summaryChipHeight = 88.0; @@ -200,11 +201,11 @@ class _MysqlStatsViewState extends material.State { material.TextStyle(color: cs.mutedForeground, fontSize: 13), ), const Gap(24), - OutlineButton( + QueryaButton.secondary( + label: 'Retry', + icon: material.Icons.refresh_rounded, onPressed: _load, - leading: const material.Icon(material.Icons.refresh_rounded, - size: 18), - child: const Text('Retry'), + size: QueryaControlSize.md, ), ], ), @@ -299,11 +300,11 @@ class _MysqlStatsViewState extends material.State { ], ), ), - OutlineButton( + QueryaButton.secondary( + label: 'Refresh', + icon: material.Icons.refresh_rounded, onPressed: _load, - leading: - const material.Icon(material.Icons.refresh_rounded, size: 18), - child: const Text('Refresh'), + size: QueryaControlSize.md, ), ], ); diff --git a/lib/features/mysql/mysql_workspace_home.dart b/lib/features/mysql/mysql_workspace_home.dart index 62999548..d903e337 100644 --- a/lib/features/mysql/mysql_workspace_home.dart +++ b/lib/features/mysql/mysql_workspace_home.dart @@ -8,6 +8,7 @@ import 'package:querya_desktop/features/mysql/mysql_sql_tx_guard.dart'; import 'package:querya_desktop/features/mysql/mysql_sql_workspace.dart'; import 'package:querya_desktop/features/mysql/mysql_stats_view.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// When a MySQL connection is selected but no tree object: server summary or SQL editor. class MysqlWorkspaceHome extends material.StatefulWidget { @@ -109,15 +110,11 @@ class _MysqlWorkspaceHomeState extends material.State { if (widget.lastSelectedMysqlObject != null && widget.onRestoreLastSelectedObject != null) ...[ const Gap(12), - OutlineButton( - size: ButtonSize.small, + QueryaButton.secondary( + label: 'Return to ${widget.lastSelectedMysqlObject!.name}', + icon: material.Icons.table_chart_outlined, onPressed: widget.onRestoreLastSelectedObject, - leading: const material.Icon( - material.Icons.table_chart_outlined, - size: 14, - ), - child: - Text('Return to ${widget.lastSelectedMysqlObject!.name}'), + size: QueryaControlSize.sm, ), ], material.Expanded( diff --git a/lib/features/postgresql/postgres_browser_views.dart b/lib/features/postgresql/postgres_browser_views.dart index 8b4aa8c0..3572faf9 100644 --- a/lib/features/postgresql/postgres_browser_views.dart +++ b/lib/features/postgresql/postgres_browser_views.dart @@ -3,6 +3,7 @@ import 'package:querya_desktop/core/database/postgres_service.dart'; import 'package:querya_desktop/core/database/postgres_metadata.dart'; import 'package:querya_desktop/core/storage/local_db.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; String _formatBytes(int? b) { if (b == null) return '—'; @@ -832,12 +833,11 @@ material.Widget _browserToolbar( material.Expanded( child: Text(title).semiBold().small(), ), - OutlineButton( - size: ButtonSize.small, + QueryaButton.secondary( + label: 'Refresh', + icon: material.Icons.refresh_rounded, onPressed: onRefresh, - leading: - const material.Icon(material.Icons.refresh_rounded, size: 14), - child: const Text('Refresh'), + size: QueryaControlSize.sm, ), ], ), diff --git a/lib/features/postgresql/postgres_routine_view.dart b/lib/features/postgresql/postgres_routine_view.dart index be35ce52..fee87286 100644 --- a/lib/features/postgresql/postgres_routine_view.dart +++ b/lib/features/postgresql/postgres_routine_view.dart @@ -6,6 +6,7 @@ import 'package:querya_desktop/core/editor/querya_code_language.dart'; import 'package:querya_desktop/core/storage/local_db.dart'; import 'package:querya_desktop/features/workspace/sql_editor_chrome.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Shows [pg_get_functiondef] for each overload of a PostgreSQL function. class PostgresRoutineView extends material.StatefulWidget { @@ -159,11 +160,11 @@ class _PostgresRoutineViewState extends material.State { style: material.TextStyle( color: cs.mutedForeground, fontSize: 13)), const Gap(24), - OutlineButton( + QueryaButton.secondary( + label: 'Retry', + icon: material.Icons.refresh_rounded, onPressed: _connectAndLoad, - leading: const material.Icon(material.Icons.refresh_rounded, - size: 18), - child: const Text('Retry'), + size: QueryaControlSize.md, ), ], ), @@ -202,12 +203,11 @@ class _PostgresRoutineViewState extends material.State { overflow: material.TextOverflow.ellipsis, ), ), - OutlineButton( - size: ButtonSize.small, + QueryaButton.secondary( + label: 'Refresh', + icon: material.Icons.refresh_rounded, onPressed: _connectAndLoad, - leading: const material.Icon(material.Icons.refresh_rounded, - size: 14), - child: const Text('Refresh'), + size: QueryaControlSize.sm, ), ], ), diff --git a/lib/features/postgresql/postgres_sequence_view.dart b/lib/features/postgresql/postgres_sequence_view.dart index 5dfeb6bb..2159c73d 100644 --- a/lib/features/postgresql/postgres_sequence_view.dart +++ b/lib/features/postgresql/postgres_sequence_view.dart @@ -3,6 +3,7 @@ import 'package:querya_desktop/core/database/postgres_connection.dart'; import 'package:querya_desktop/core/database/postgres_service.dart'; import 'package:querya_desktop/core/storage/local_db.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Shows [pg_sequences] metadata, current value, and generated DDL. class PostgresSequenceView extends material.StatefulWidget { @@ -144,11 +145,11 @@ class _PostgresSequenceViewState extends material.State { color: cs.mutedForeground, fontSize: 13), ), const Gap(24), - OutlineButton( + QueryaButton.secondary( + label: 'Retry', + icon: material.Icons.refresh_rounded, onPressed: _connectAndLoad, - leading: const material.Icon(material.Icons.refresh_rounded, - size: 18), - child: const Text('Retry'), + size: QueryaControlSize.md, ), ], ), @@ -189,12 +190,11 @@ class _PostgresSequenceViewState extends material.State { overflow: material.TextOverflow.ellipsis, ), ), - OutlineButton( - size: ButtonSize.small, + QueryaButton.secondary( + label: 'Refresh', + icon: material.Icons.refresh_rounded, onPressed: _connectAndLoad, - leading: const material.Icon(material.Icons.refresh_rounded, - size: 14), - child: const Text('Refresh'), + size: QueryaControlSize.sm, ), ], ), diff --git a/lib/features/postgresql/postgres_stats_view.dart b/lib/features/postgresql/postgres_stats_view.dart index 4222e4be..aed1ee57 100644 --- a/lib/features/postgresql/postgres_stats_view.dart +++ b/lib/features/postgresql/postgres_stats_view.dart @@ -11,6 +11,7 @@ import 'package:querya_desktop/core/storage/local_db.dart'; import 'package:querya_desktop/shared/widgets/querya_sparkline.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' as shadcn; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; const _pollInterval = Duration(seconds: 5); const _summaryChipHeight = 88.0; @@ -234,11 +235,11 @@ class _PostgresStatsViewState extends material.State { style: material.TextStyle( color: cs.mutedForeground, fontSize: 13)), const Gap(24), - OutlineButton( + QueryaButton.secondary( + label: 'Retry', + icon: material.Icons.refresh_rounded, onPressed: _load, - leading: const material.Icon(material.Icons.refresh_rounded, - size: 18), - child: const Text('Retry'), + size: QueryaControlSize.md, ), ], ), @@ -355,11 +356,11 @@ class _PostgresStatsViewState extends material.State { ), ], ), - OutlineButton( + QueryaButton.secondary( + label: 'Refresh', + icon: material.Icons.refresh_rounded, onPressed: _load, - leading: const material.Icon(material.Icons.refresh_rounded, - size: 18), - child: const Text('Refresh'), + size: QueryaControlSize.md, ), ], ), diff --git a/lib/features/postgresql/postgres_workspace_home.dart b/lib/features/postgresql/postgres_workspace_home.dart index adf0ae6c..c17657fd 100644 --- a/lib/features/postgresql/postgres_workspace_home.dart +++ b/lib/features/postgresql/postgres_workspace_home.dart @@ -8,6 +8,7 @@ import 'package:querya_desktop/features/postgresql/postgres_sql_tx_guard.dart'; import 'package:querya_desktop/features/postgresql/postgres_sql_workspace.dart'; import 'package:querya_desktop/features/postgresql/postgres_stats_view.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// When a PostgreSQL connection is selected but no tree object: Server stats or SQL editor. class PostgresWorkspaceHome extends material.StatefulWidget { @@ -124,14 +125,11 @@ class _PostgresWorkspaceHomeState if (widget.lastSelectedPostgresObject != null && widget.onRestoreLastSelectedObject != null) ...[ const Gap(12), - OutlineButton( - size: ButtonSize.small, + QueryaButton.secondary( + label: 'Return to ${widget.lastSelectedPostgresObject!.name}', + icon: material.Icons.table_chart_outlined, onPressed: widget.onRestoreLastSelectedObject, - leading: const material.Icon( - material.Icons.table_chart_outlined, - size: 14, - ), - child: Text('Return to ${widget.lastSelectedPostgresObject!.name}'), + size: QueryaControlSize.sm, ), ], material.Expanded( diff --git a/lib/features/redis/editors/redis_hash_editor.dart b/lib/features/redis/editors/redis_hash_editor.dart index b0ad2a15..6233ce2f 100644 --- a/lib/features/redis/editors/redis_hash_editor.dart +++ b/lib/features/redis/editors/redis_hash_editor.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart' as material; import 'package:querya_desktop/core/database/redis_bulk.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' as shadcn; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Editor for a Redis hash: HSET add bar plus a field/value list. class RedisHashEditor extends material.StatefulWidget { @@ -66,7 +67,8 @@ class _RedisHashEditorState extends material.State { ), ), const Gap(8), - PrimaryButton( + QueryaButton.primary( + label: 'HSET', onPressed: () { final f = _fieldController.text.trim(); final v = _valueController.text; @@ -75,8 +77,7 @@ class _RedisHashEditorState extends material.State { _fieldController.clear(); _valueController.clear(); }, - size: ButtonSize.small, - child: const Text('HSET'), + size: QueryaControlSize.sm, ), ], ), diff --git a/lib/features/redis/editors/redis_set_editor.dart b/lib/features/redis/editors/redis_set_editor.dart index a164bc2b..ca7b23cc 100644 --- a/lib/features/redis/editors/redis_set_editor.dart +++ b/lib/features/redis/editors/redis_set_editor.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart' as material; import 'package:querya_desktop/core/database/redis_bulk.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' as shadcn; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Editor for a Redis set: SADD add bar plus a member list. class RedisSetEditor extends material.StatefulWidget { @@ -57,15 +58,15 @@ class _RedisSetEditorState extends material.State { ), ), const Gap(8), - PrimaryButton( + QueryaButton.primary( + label: 'SADD', onPressed: () { final v = _valueController.text.trim(); if (v.isEmpty) return; widget.onAdd(v); _valueController.clear(); }, - size: ButtonSize.small, - child: const Text('SADD'), + size: QueryaControlSize.sm, ), ], ), diff --git a/lib/features/redis/editors/redis_string_editor.dart b/lib/features/redis/editors/redis_string_editor.dart index d508c82b..6c4d7d09 100644 --- a/lib/features/redis/editors/redis_string_editor.dart +++ b/lib/features/redis/editors/redis_string_editor.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart' as material; import 'package:querya_desktop/core/database/redis_bulk.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Editor for a Redis string key. Binary (non-UTF-8) values are shown as /// read-only hex / base64. The [controller] is owned by the parent so it can @@ -64,12 +65,11 @@ class RedisStringEditor extends material.StatelessWidget { const Text('Value').semiBold(), if (!isReadOnly) ...[ const Spacer(), - PrimaryButton( + QueryaButton.primary( + label: 'Save', + icon: material.Icons.save_rounded, onPressed: onSave, - size: ButtonSize.small, - leading: - const material.Icon(material.Icons.save_rounded, size: 14), - child: const Text('Save'), + size: QueryaControlSize.sm, ), ], ], diff --git a/lib/features/redis/editors/redis_zset_editor.dart b/lib/features/redis/editors/redis_zset_editor.dart index bb1d6c07..6a493319 100644 --- a/lib/features/redis/editors/redis_zset_editor.dart +++ b/lib/features/redis/editors/redis_zset_editor.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart' as material; import 'package:querya_desktop/core/database/redis_bulk.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' as shadcn; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Editor for a Redis sorted set: ZADD add bar plus a scored member list. class RedisZsetEditor extends material.StatefulWidget { @@ -67,7 +68,8 @@ class _RedisZsetEditorState extends material.State { ), ), const Gap(8), - PrimaryButton( + QueryaButton.primary( + label: 'ZADD', onPressed: () { final m = _memberController.text.trim(); final s = double.tryParse(_scoreController.text.trim()); @@ -76,8 +78,7 @@ class _RedisZsetEditorState extends material.State { _memberController.clear(); _scoreController.clear(); }, - size: ButtonSize.small, - child: const Text('ZADD'), + size: QueryaControlSize.sm, ), ], ), diff --git a/lib/features/redis/redis_databases_view.dart b/lib/features/redis/redis_databases_view.dart index de236139..2b06d166 100644 --- a/lib/features/redis/redis_databases_view.dart +++ b/lib/features/redis/redis_databases_view.dart @@ -4,6 +4,7 @@ import 'package:querya_desktop/core/database/redis_info.dart'; import 'package:querya_desktop/core/storage/local_db.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' as shadcn; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Shows all Redis databases (db0–dbN) with key counts. class RedisDatabasesView extends material.StatefulWidget { @@ -119,9 +120,10 @@ class _RedisDatabasesViewState extends material.State { style: material.TextStyle(color: cs.destructive, fontSize: 13)), const Gap(16), - OutlineButton( + QueryaButton.secondary( + label: 'Retry', onPressed: _load, - child: const Text('Retry'), + size: QueryaControlSize.md, ), ], ), diff --git a/lib/features/redis/redis_explorer_view.dart b/lib/features/redis/redis_explorer_view.dart index 1a685c71..0a434502 100644 --- a/lib/features/redis/redis_explorer_view.dart +++ b/lib/features/redis/redis_explorer_view.dart @@ -13,6 +13,7 @@ import 'redis_keys_view.dart'; import 'redis_key_editor.dart'; import 'redis_view.dart'; import 'redis_cli_workspace.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; // ─── Navigation path model ────────────────────────────────────────────────── @@ -262,11 +263,11 @@ class _RedisExplorerViewState extends material.State { style: material.TextStyle( color: cs.mutedForeground, fontSize: 13)), const Gap(24), - OutlineButton( + QueryaButton.secondary( + label: 'Retry', + icon: material.Icons.refresh_rounded, onPressed: _connect, - leading: const material.Icon(material.Icons.refresh_rounded, - size: 18), - child: const Text('Retry'), + size: QueryaControlSize.md, ), ], ), diff --git a/lib/features/settings/preferences_dialog.dart b/lib/features/settings/preferences_dialog.dart index 0747faa0..3f35f263 100644 --- a/lib/features/settings/preferences_dialog.dart +++ b/lib/features/settings/preferences_dialog.dart @@ -14,6 +14,7 @@ import 'package:querya_desktop/features/settings/preferences_mcp_section.dart'; import 'package:querya_desktop/features/settings/preferences_shortcuts_section.dart'; import 'package:querya_desktop/features/settings/sql_statement_timeout_dropdown.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; export 'preferences_category.dart'; @@ -427,9 +428,10 @@ class PreferencesDialogContentState 'Changes apply immediately and persist locally.', ), ), - PrimaryButton( + QueryaButton.primary( + label: 'Close', onPressed: () => material.Navigator.of(context).pop(), - child: const Text('Close'), + size: QueryaControlSize.lg, ), ], ), diff --git a/lib/features/settings/theme_editor_section.dart b/lib/features/settings/theme_editor_section.dart index 4a7bf9bc..f8cc93d1 100644 --- a/lib/features/settings/theme_editor_section.dart +++ b/lib/features/settings/theme_editor_section.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:flutter/material.dart' as material; import 'package:querya_desktop/features/settings/theme_editor_dialog.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; export 'package:querya_desktop/features/settings/theme_editor_dialog.dart' show showThemeEditorDialog, ThemeEditorDialog; @@ -55,19 +56,11 @@ class ThemeEditorSection extends material.StatelessWidget { ), ), const material.SizedBox(width: 12), - OutlineButton( + QueryaButton.secondary( + label: 'Edit theme colors…', + icon: material.Icons.tune_rounded, onPressed: () => unawaited(showThemeEditorDialog(context)), - child: const material.Row( - mainAxisSize: material.MainAxisSize.min, - children: [ - material.Icon( - material.Icons.tune_rounded, - size: 14, - ), - material.SizedBox(width: 6), - material.Text('Edit theme colors…'), - ], - ), + size: QueryaControlSize.md, ), ], ), diff --git a/lib/features/sqlite/sqlite_overview_tab.dart b/lib/features/sqlite/sqlite_overview_tab.dart index aa8eb03a..637321ca 100644 --- a/lib/features/sqlite/sqlite_overview_tab.dart +++ b/lib/features/sqlite/sqlite_overview_tab.dart @@ -6,6 +6,7 @@ import 'package:querya_desktop/core/database/sqlite_connection.dart'; import 'package:querya_desktop/core/database/sqlite_service.dart'; import 'package:querya_desktop/core/storage/local_db.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; const _summaryChipHeight = 88.0; @@ -160,11 +161,11 @@ class _SqliteOverviewTabState extends material.State { style: material.TextStyle( color: cs.mutedForeground, fontSize: 13)), const Gap(24), - OutlineButton( + QueryaButton.secondary( + label: 'Retry', + icon: material.Icons.refresh_rounded, onPressed: _load, - leading: const material.Icon(material.Icons.refresh_rounded, - size: 18), - child: const Text('Retry'), + size: QueryaControlSize.md, ), ], ), @@ -261,10 +262,11 @@ class _SqliteOverviewTabState extends material.State { ], ), ), - OutlineButton( + QueryaButton.secondary( + label: 'Refresh', + icon: material.Icons.refresh_rounded, onPressed: _fetch, - leading: const material.Icon(material.Icons.refresh_rounded, size: 16), - child: const Text('Refresh'), + size: QueryaControlSize.md, ), ], ); diff --git a/lib/features/sqlite/sqlite_workspace_home.dart b/lib/features/sqlite/sqlite_workspace_home.dart index d66cf6ac..122fb877 100644 --- a/lib/features/sqlite/sqlite_workspace_home.dart +++ b/lib/features/sqlite/sqlite_workspace_home.dart @@ -7,6 +7,7 @@ import 'package:querya_desktop/features/sqlite/sqlite_overview_tab.dart'; import 'package:querya_desktop/features/sqlite/sqlite_sql_tx_guard.dart'; import 'package:querya_desktop/features/sqlite/sqlite_sql_workspace.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; class SqliteWorkspaceHome extends material.StatefulWidget { const SqliteWorkspaceHome({ @@ -101,15 +102,11 @@ class _SqliteWorkspaceHomeState extends material.State { if (widget.lastSelectedSqliteObject != null && widget.onRestoreLastSelectedObject != null) ...[ const Gap(12), - OutlineButton( - size: ButtonSize.small, + QueryaButton.secondary( + label: 'Return to ${widget.lastSelectedSqliteObject!.name}', + icon: material.Icons.table_chart_outlined, onPressed: widget.onRestoreLastSelectedObject, - leading: const material.Icon( - material.Icons.table_chart_outlined, - size: 14, - ), - child: Text( - 'Return to ${widget.lastSelectedSqliteObject!.name}'), + size: QueryaControlSize.sm, ), ], material.Expanded( diff --git a/lib/features/workspace/destructive_query_dialog.dart b/lib/features/workspace/destructive_query_dialog.dart index 29a6cb2d..24d7471d 100644 --- a/lib/features/workspace/destructive_query_dialog.dart +++ b/lib/features/workspace/destructive_query_dialog.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart' as material; import 'package:flutter/services.dart'; import 'package:querya_desktop/core/database/destructive_sql_detector.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Opens a confirmation dialog when destructive SQL statements (DROP, TRUNCATE, etc.) /// are detected before execution. @@ -316,20 +317,19 @@ class _DestructiveQueryDialogState alignment: material.WrapAlignment.end, crossAxisAlignment: material.WrapCrossAlignment.center, children: [ - GhostButton( + QueryaButton.ghost( + label: 'Cancel', onPressed: () => material.Navigator.of(context).pop(false), - child: const Text('Cancel'), + size: QueryaControlSize.lg, ), - DestructiveButton( + QueryaButton.destructive( + label: 'Execute Destructive Statement', + icon: material.Icons.delete_forever_rounded, onPressed: _acknowledged ? () => material.Navigator.of(context).pop(true) : null, - leading: const material.Icon( - material.Icons.delete_forever_rounded, - size: 16, - ), - child: const Text('Execute Destructive Statement'), + size: QueryaControlSize.lg, ), ], ), diff --git a/lib/features/workspace/dml_preview_dialog.dart b/lib/features/workspace/dml_preview_dialog.dart index 43212736..d99fc430 100644 --- a/lib/features/workspace/dml_preview_dialog.dart +++ b/lib/features/workspace/dml_preview_dialog.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart' as material; import 'package:flutter/services.dart'; import 'package:querya_desktop/core/database/table_mutation_engine.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Opens the DML Preview and Confirmation dialog before executing staged changes. /// @@ -314,18 +315,17 @@ class _DmlPreviewDialogState extends material.State<_DmlPreviewDialog> { material.Row( mainAxisAlignment: material.MainAxisAlignment.end, children: [ - OutlineButton( + QueryaButton.ghost( + label: 'Cancel', onPressed: () => material.Navigator.of(context).pop(false), - child: const Text('Cancel'), + size: QueryaControlSize.lg, ), const Gap(8), - PrimaryButton( + QueryaButton.primary( + label: 'Apply Changes', + icon: material.Icons.save_outlined, onPressed: () => material.Navigator.of(context).pop(true), - leading: const material.Icon( - material.Icons.save_outlined, - size: 16, - ), - child: const Text('Apply Changes'), + size: QueryaControlSize.lg, ), ], ), diff --git a/lib/features/workspace/grid_cell_popover_inspector.dart b/lib/features/workspace/grid_cell_popover_inspector.dart index edcf34b7..6ff292b9 100644 --- a/lib/features/workspace/grid_cell_popover_inspector.dart +++ b/lib/features/workspace/grid_cell_popover_inspector.dart @@ -320,13 +320,11 @@ class _GridCellInspectorDialogState ), const Gap(6), ], - IconButton.ghost( - density: ButtonDensity.compact, + QueryaButton.icon( + icon: material.Icons.close_rounded, + tooltip: 'Close', + size: QueryaControlSize.sm, onPressed: () => material.Navigator.of(context).pop(null), - icon: const material.Icon( - material.Icons.close_rounded, - size: 16, - ), ), if (_isHex()) ...[ QueryaButton.ghost( diff --git a/lib/features/workspace/results_tab.dart b/lib/features/workspace/results_tab.dart index e8f84a9e..7313cd84 100644 --- a/lib/features/workspace/results_tab.dart +++ b/lib/features/workspace/results_tab.dart @@ -17,6 +17,7 @@ import 'package:querya_desktop/features/workspace/grid_selection_calc_engine.dar import 'package:querya_desktop/features/workspace/result_grid_view.dart'; import 'package:querya_desktop/shared/services/data_export_service.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; enum ResultViewMode { grid, @@ -665,9 +666,10 @@ Future _showSaveFileErrorDialog(material.BuildContext context) { const Gap(20), material.Align( alignment: material.Alignment.centerRight, - child: PrimaryButton( + child: QueryaButton.primary( + label: 'OK', onPressed: () => material.Navigator.of(ctx).pop(), - child: const Text('OK'), + size: QueryaControlSize.md, ), ), ], diff --git a/lib/features/workspace/sql_query_history_dialog.dart b/lib/features/workspace/sql_query_history_dialog.dart index 577d05dc..ae8134bd 100644 --- a/lib/features/workspace/sql_query_history_dialog.dart +++ b/lib/features/workspace/sql_query_history_dialog.dart @@ -356,31 +356,19 @@ class _SqlQueryHistoryDialogContentState ), ), const Gap(8), - material.Tooltip( - message: 'Copy to clipboard', - child: IconButton.ghost( - density: ButtonDensity.compact, - onPressed: () => - unawaited(_copyToClipboard(e.sqlText)), - icon: const material.Icon( - material.Icons.copy_rounded, - size: 15, - ), - ), + QueryaButton.icon( + icon: material.Icons.copy_rounded, + tooltip: 'Copy to clipboard', + size: QueryaControlSize.sm, + onPressed: () => unawaited(_copyToClipboard(e.sqlText)), ), if (widget.onOpenInNewTab != null) ...[ const Gap(4), - material.Tooltip( - message: 'Open in new tab', - child: IconButton.ghost( - density: ButtonDensity.compact, - onPressed: () => - _openInNewTab(e.sqlText), - icon: const material.Icon( - material.Icons.open_in_new_rounded, - size: 15, - ), - ), + QueryaButton.icon( + icon: material.Icons.open_in_new_rounded, + tooltip: 'Open in new tab', + size: QueryaControlSize.sm, + onPressed: () => _openInNewTab(e.sqlText), ), ], ], diff --git a/lib/features/workspace/sql_query_tab_bar.dart b/lib/features/workspace/sql_query_tab_bar.dart index 029095be..a77e5dd7 100644 --- a/lib/features/workspace/sql_query_tab_bar.dart +++ b/lib/features/workspace/sql_query_tab_bar.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart' as material; import 'package:querya_desktop/features/workspace/sql_query_tab_session.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Lightweight query tab strip rendered above the SQL editor workspace. class SqlQueryTabBar extends material.StatelessWidget { @@ -91,13 +92,15 @@ Future showUnsavedTabChangesDialog({ spacing: 8, runSpacing: 8, children: [ - OutlineButton( + QueryaButton.ghost( + label: 'Cancel', onPressed: () => material.Navigator.of(ctx).pop(false), - child: const Text('Cancel'), + size: QueryaControlSize.md, ), - DestructiveButton( + QueryaButton.destructive( + label: 'Discard & Close', onPressed: () => material.Navigator.of(ctx).pop(true), - child: const Text('Discard & Close'), + size: QueryaControlSize.md, ), ], ), diff --git a/lib/shared/widgets/ssl_certificate_fields.dart b/lib/shared/widgets/ssl_certificate_fields.dart index 492744ad..d4d81873 100644 --- a/lib/shared/widgets/ssl_certificate_fields.dart +++ b/lib/shared/widgets/ssl_certificate_fields.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart' as material; import 'package:querya_desktop/core/security/ssl_certificate_support.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Optional SSL certificate path fields (Root CA, client cert, client key). class SslCertificateFields extends material.StatelessWidget { @@ -85,7 +86,10 @@ class _SslFileField extends material.StatelessWidget { ), ), const Gap(8), - GhostButton( + QueryaButton.icon( + icon: material.Icons.folder_open_rounded, + tooltip: 'Browse…', + size: QueryaControlSize.lg, onPressed: () async { await pickSslCertificateFile( onPicked: (path) { @@ -94,7 +98,6 @@ class _SslFileField extends material.StatelessWidget { }, ); }, - child: const Icon(material.Icons.folder_open_rounded), ), ], ), diff --git a/lib/shared/widgets/tree_load_error.dart b/lib/shared/widgets/tree_load_error.dart index bd90de68..3a481bfa 100644 --- a/lib/shared/widgets/tree_load_error.dart +++ b/lib/shared/widgets/tree_load_error.dart @@ -3,6 +3,7 @@ import 'package:querya_desktop/core/ui/querya_icon_sizes.dart'; import 'package:querya_desktop/core/ui/querya_icons.dart'; import 'package:querya_desktop/core/ui/querya_tree_tokens.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Inline error block for connection tree lazy-load failures. /// @@ -74,9 +75,10 @@ class TreeLoadError extends material.StatelessWidget { ), if (onRetry != null) ...[ const material.SizedBox(height: 6), - GhostButton( + QueryaButton.ghost( + label: retryLabel, onPressed: onRetry, - child: Text(retryLabel), + size: QueryaControlSize.md, ), ], ],