Skip to content

Commit 89cafbe

Browse files
committed
Merge branch 'development'
Release 0.6.0
2 parents 4472fd7 + 25d1b34 commit 89cafbe

File tree

11 files changed

+160
-114
lines changed

11 files changed

+160
-114
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## 0.6.0 - 2022-12-10
8+
### Fixed
9+
- Semi-Breaking: Changed the type of `CommandPaletteConfig.openKeySet` and `CommandPaletteConfig.closeKeySet` from `LogicalKeySet` to `ShortcutActivator` (note: `LogicalKeySet` already implements `ShortcutActivator`, so existing custom shortcuts should still work, but a proposed solution is discussed below). This was done to fix an issue on Web builds for MacOS (discussed [here](https://github.com/TNorbury/command_palette/issues/22)). If you don't set custom values for the open and close key sets (or if you're not targeting Web), then no change will be required on your part. But if you are, the following change is suggested to make sure everything works well: If you're opening the palette with a keyboard shortcut, such as CTRL/CMD+U, then you could go from `LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyU)`/`LogicalKeySet(LogicalKeyboardKey.meta, LogicalKeyboardKey.keyU)` to `SingleActivator(LogicalKeyboardKey.keyU, control: true)`/`SingleActivator(LogicalKeyboardKey.keyU, meta: true)`. This also changes how the command palette control shortcuts (Up/down/enter/backspace) are handled (from `LogicalKeySet` to `SingleActivator`). This should make things a bit cleaner on my end, and more stable going forward.
10+
- Escape query correctly so that single a '' don't cause filtering to crash
11+
712
## 0.5.1 - 2022-12-02
813
### Added
914
- Optional `leading` widget for `CommandPaletteAction`s which will display a Widget at the left-side of the different command palette options

example/lib/main.dart

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import 'dart:math';
33
import 'package:command_palette/command_palette.dart';
44
import 'package:flutter/foundation.dart';
55
import 'package:flutter/material.dart';
6-
import 'package:flutter_lorem/flutter_lorem.dart';
76

87
void main() {
98
runApp(const MyApp());
@@ -56,10 +55,7 @@ class _MyHomePageState extends State<MyHomePage> {
5655
),
5756

5857
// Setting custom keyboard shortcuts
59-
// openKeySet: LogicalKeySet(
60-
// LogicalKeyboardKey.alt,
61-
// LogicalKeyboardKey.keyO,
62-
// ),
58+
// openKeySet: SingleActivator(LogicalKeyboardKey.keyP, meta: true),
6359
// closeKeySet: LogicalKeySet(
6460
// LogicalKeyboardKey.control,
6561
// LogicalKeyboardKey.keyC,

example/pubspec.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ packages:
4242
path: ".."
4343
relative: true
4444
source: path
45-
version: "0.5.1"
45+
version: "0.6.0"
4646
fake_async:
4747
dependency: transitive
4848
description:

lib/src/command_palette.dart

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,16 @@ class _CommandPaletteInnerState extends State<_CommandPaletteInner> {
138138
void didUpdateWidget(covariant _CommandPaletteInner oldWidget) {
139139
super.didUpdateWidget(oldWidget);
140140

141-
if (oldWidget.config != widget.config ||
142-
oldWidget.actions != widget.actions) {
141+
final bool actionsChanged = !listEquals(oldWidget.actions, widget.actions);
142+
143+
if (oldWidget.config != widget.config || actionsChanged) {
143144
_initStyle();
144145
}
145146

147+
// if (actionsChanged) {
148+
// widget.controller.actions = widget.actions;
149+
// }
150+
146151
// refresh toggler listeners if need be
147152
if (oldWidget.toggler != widget.toggler) {
148153
oldWidget.toggler.removeListener(_handleToggle);
@@ -221,24 +226,23 @@ class _CommandPaletteInnerState extends State<_CommandPaletteInner> {
221226
controller: widget.controller,
222227
child: Builder(
223228
builder: (context) {
224-
return Focus(
225-
autofocus: true,
226-
onKey: (node, event) {
227-
KeyEventResult result = KeyEventResult.ignored;
228-
229-
// if ctrl-c is pressed, and the command palette isn't open,
230-
// open it
231-
if (widget.config.openKeySet
232-
.accepts(event, RawKeyboard.instance) &&
233-
!_commandPaletteOpen) {
234-
_openCommandPalette(context);
235-
236-
result = KeyEventResult.handled;
237-
}
238-
239-
return result;
229+
return Shortcuts(
230+
shortcuts: {
231+
widget.config.openKeySet: const _OpenCommandPaletteIntent()
240232
},
241-
child: widget.child,
233+
child: Actions(
234+
actions: {
235+
_OpenCommandPaletteIntent:
236+
CallbackAction<_OpenCommandPaletteIntent>(
237+
// ignore: body_might_complete_normally_nullable
238+
onInvoke: (_) => _openCommandPalette(context),
239+
)
240+
},
241+
child: Focus(
242+
autofocus: true,
243+
child: widget.child,
244+
),
245+
),
242246
);
243247
},
244248
),
@@ -282,3 +286,7 @@ class _CommandPaletteInnerState extends State<_CommandPaletteInner> {
282286
Navigator.of(context).pop();
283287
}
284288
}
289+
290+
class _OpenCommandPaletteIntent extends Intent {
291+
const _OpenCommandPaletteIntent();
292+
}

lib/src/controller/command_palette_controller.dart

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -134,19 +134,19 @@ class CommandPaletteController extends ChangeNotifier {
134134
return filteredActions;
135135
}
136136

137-
/// Handles backspace being pressed. The order of actions is as follows
138-
/// 1. If there is text in the controller, the backspace works as expected
139-
/// there (i.e. deletes the character right behind the cursor)
140-
/// 2. If an action is currently selected, we'll pop one level
141-
bool handleBackspace() {
142-
bool handled = false;
143-
137+
/// Determines if the backspace will be handled by the command palette.
138+
/// The following things determine if it'll be handled:
139+
/// 1. If there is text in the text field, the backspace won't be handled here
140+
/// and instead be passed on, behaving as a backspace is expected to (i.e.
141+
/// deletes a character). False will be returned
142+
/// 2. If no text is present, and an action is selected, this will return true.
143+
/// otherwise false.
144+
bool backspaceWillBeHandled() {
144145
if (textEditingController.text.isNotEmpty) {
145-
handled = false;
146+
return false;
146147
} else {
147-
handled = gotoParentAction();
148+
return currentlySelectedAction != null;
148149
}
149-
return handled;
150150
}
151151

152152
/// Goes a level up in the action tree, and sets the selected action as the

lib/src/models/command_palette_config.dart

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import 'package:flutter/services.dart';
77

88
import '../../command_palette.dart';
99

10-
final _defaultOpenKeySet = defaultTargetPlatform == TargetPlatform.macOS
11-
? LogicalKeySet(LogicalKeyboardKey.meta, LogicalKeyboardKey.keyK)
12-
: LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyK);
13-
final _defaultCloseKeySet = LogicalKeySet(LogicalKeyboardKey.escape);
10+
final _defaultOpenKeySet = SingleActivator(LogicalKeyboardKey.keyK,
11+
meta: defaultTargetPlatform == TargetPlatform.macOS,
12+
control: defaultTargetPlatform != TargetPlatform.macOS);
13+
const _defaultCloseKeySet = SingleActivator(LogicalKeyboardKey.escape);
1414

1515
/// Configuration options for the command palette
1616
class CommandPaletteConfig {
@@ -47,7 +47,7 @@ class CommandPaletteConfig {
4747
/// The set of keys used to open the command palette.
4848
///
4949
/// Defaults to Ctrl-/Cmd- C
50-
final LogicalKeySet openKeySet;
50+
final ShortcutActivator openKeySet;
5151

5252
/// The set of keys used to close the command palette.
5353
///
@@ -57,7 +57,7 @@ class CommandPaletteConfig {
5757
/// App-level. If you want to prevent this, see: https://stackoverflow.com/questions/63763478/disable-escape-key-navigation-in-flutter-web
5858
///
5959
/// Defaults to Esc.
60-
final LogicalKeySet closeKeySet;
60+
final ShortcutActivator closeKeySet;
6161

6262
/// The offset of the modal from the top of the screen.
6363
///
@@ -103,8 +103,8 @@ class CommandPaletteConfig {
103103
ActionFilter? filter,
104104
Key? key,
105105
ActionBuilder? builder,
106-
LogicalKeySet? openKeySet,
107-
LogicalKeySet? closeKeySet,
106+
ShortcutActivator? openKeySet,
107+
ShortcutActivator? closeKeySet,
108108
this.hintText = "Begin typing to search for something",
109109
this.transitionDuration = const Duration(milliseconds: 150),
110110
this.transitionCurve = Curves.linear,

lib/src/utils/filter.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ class Filter {
8989
}
9090

9191
static String convertToRegExpPattern(String word) {
92-
return word
92+
return RegExp.escape(word
9393
.replaceAll(r'/[\-\\\{\}\+\?\|\^\$\.\,\[\]\(\)\#\s]/g', '\\\$&')
94-
.replaceAll(r"/[\*]/g", ".*");
94+
.replaceAll(r"/[\*]/g", ".*"));
9595
}
9696

9797
/// Matches a non-contiguous sub-string

lib/src/widgets/command_palette_modal.dart

Lines changed: 88 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// ignore_for_file: body_might_complete_normally_nullable
2+
13
import 'package:command_palette/src/controller/command_palette_controller.dart';
24
import 'package:flutter/material.dart';
35
import 'package:flutter/services.dart';
@@ -23,7 +25,7 @@ class CommandPaletteModal extends ModalRoute<void> {
2325

2426
final Curve _transitionCurve;
2527

26-
final LogicalKeySet closeKeySet;
28+
final ShortcutActivator closeKeySet;
2729

2830
@override
2931
void dispose() {
@@ -100,70 +102,62 @@ class CommandPaletteModal extends ModalRoute<void> {
100102
bottom: bottom,
101103
left: left,
102104
right: right,
103-
child: Focus(
104-
// not sure why but this seems to make things play nice lol
105-
onKeyEvent: (node, event) => KeyEventResult.ignored,
106-
onKey: (node, event) {
107-
KeyEventResult result = KeyEventResult.ignored;
108-
109-
if (LogicalKeySet(LogicalKeyboardKey.backspace)
110-
.accepts(event, RawKeyboard.instance)) {
111-
if (commandPaletteController.handleBackspace()) {
112-
result = KeyEventResult.handled;
113-
}
114-
}
115-
116-
// down, move selector down
117-
else if (LogicalKeySet(LogicalKeyboardKey.arrowDown)
118-
.accepts(event, RawKeyboard.instance)) {
119-
commandPaletteController.movedHighlightedAction(
120-
down: true,
121-
);
122-
result = KeyEventResult.handled;
123-
}
124-
125-
// up, move selector up
126-
else if (LogicalKeySet(LogicalKeyboardKey.arrowUp)
127-
.accepts(event, RawKeyboard.instance)) {
128-
commandPaletteController.movedHighlightedAction(
129-
down: false,
130-
);
131-
result = KeyEventResult.handled;
132-
}
133-
134-
// enter makes selection
135-
else if (LogicalKeySet(LogicalKeyboardKey.enter)
136-
.accepts(event, RawKeyboard.instance)) {
137-
commandPaletteController
138-
.performHighlightedAction(context);
139-
result = KeyEventResult.handled;
140-
}
141-
142-
// close the command palette
143-
else if (closeKeySet.accepts(
144-
event,
145-
RawKeyboard.instance,
146-
)) {
147-
Navigator.of(context).pop();
148-
result = KeyEventResult.handled;
149-
}
150-
151-
return result;
105+
child: Shortcuts(
106+
shortcuts: {
107+
const SingleActivator(LogicalKeyboardKey.backspace):
108+
const _BackspaceIntent(),
109+
const SingleActivator(LogicalKeyboardKey.arrowDown):
110+
const _DownArrowIntent(),
111+
const SingleActivator(LogicalKeyboardKey.arrowUp):
112+
const _UpArrowIntent(),
113+
const SingleActivator(LogicalKeyboardKey.enter):
114+
const _EnterIntent(),
115+
closeKeySet: const _CloseIntent(),
152116
},
153-
child: SizedBox(
154-
height: height,
155-
width: width,
156-
child: Column(
157-
children: [
158-
CommandPaletteTextField(
159-
hintText: hintText,
160-
onSubmit: () => commandPaletteController
161-
.performHighlightedAction(context),
117+
child: Actions(
118+
actions: {
119+
_BackspaceIntent: _BackspaceAction(
120+
onInvoke: (intent) =>
121+
commandPaletteController.gotoParentAction(),
122+
controller: commandPaletteController,
123+
),
124+
_DownArrowIntent: CallbackAction<_DownArrowIntent>(
125+
onInvoke: (intent) =>
126+
commandPaletteController.movedHighlightedAction(
127+
down: true,
128+
),
129+
),
130+
_UpArrowIntent: CallbackAction<_UpArrowIntent>(
131+
onInvoke: (intent) =>
132+
commandPaletteController.movedHighlightedAction(
133+
down: false,
162134
),
163-
const Flexible(
164-
child: CommandPaletteBody(),
135+
),
136+
_EnterIntent: CallbackAction<_EnterIntent>(
137+
onInvoke: (intent) => commandPaletteController
138+
.performHighlightedAction(context),
139+
),
140+
_CloseIntent: CallbackAction<_CloseIntent>(
141+
onInvoke: (intent) => Navigator.of(context).pop(),
142+
),
143+
},
144+
child: Focus(
145+
child: SizedBox(
146+
height: height,
147+
width: width,
148+
child: Column(
149+
children: [
150+
CommandPaletteTextField(
151+
hintText: hintText,
152+
onSubmit: () => commandPaletteController
153+
.performHighlightedAction(context),
154+
),
155+
const Flexible(
156+
child: CommandPaletteBody(),
157+
),
158+
],
165159
),
166-
],
160+
),
167161
),
168162
),
169163
),
@@ -176,3 +170,35 @@ class CommandPaletteModal extends ModalRoute<void> {
176170
);
177171
}
178172
}
173+
174+
// intents for the different control keys
175+
class _BackspaceIntent extends Intent {
176+
const _BackspaceIntent();
177+
}
178+
179+
class _DownArrowIntent extends Intent {
180+
const _DownArrowIntent();
181+
}
182+
183+
class _UpArrowIntent extends Intent {
184+
const _UpArrowIntent();
185+
}
186+
187+
class _EnterIntent extends Intent {
188+
const _EnterIntent();
189+
}
190+
191+
class _CloseIntent extends Intent {
192+
const _CloseIntent();
193+
}
194+
195+
class _BackspaceAction extends CallbackAction<_BackspaceIntent> {
196+
CommandPaletteController controller;
197+
_BackspaceAction({
198+
required OnInvokeCallback<_BackspaceIntent> onInvoke,
199+
required this.controller,
200+
}) : super(onInvoke: onInvoke);
201+
202+
@override
203+
bool isEnabled(_) => controller.backspaceWillBeHandled();
204+
}

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: command_palette
22
description: Flutter implementation of the Command Palette. Can be brought up via a keyboard shortcut.
3-
version: 0.5.1
3+
version: 0.6.0
44
homepage: https://github.com/TNorbury/command_palette
55
issue_tracker: https://github.com/TNorbury/command_palette/issues
66
repository: https://github.com/TNorbury/command_palette

0 commit comments

Comments
 (0)