Skip to content

Commit

Permalink
Merge pull request #35 from NishiyamaPedro/input_action
Browse files Browse the repository at this point in the history
Implement input action
  • Loading branch information
TNorbury committed Oct 30, 2023
2 parents 0bd75a2 + a57f26e commit 655839e
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 21 deletions.
10 changes: 10 additions & 0 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@ class _MyHomePageState extends State<MyHomePage> {
),
],
),
CommandPaletteAction.input(
id: "new-user",
label: "New User",
shortcut: ["ctrl", "shift", "n"],
leading: Icon(Icons.add),
onConfirmInput: (value) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Created user: $value')));
},
),
CommandPaletteAction.nested(
id: 1, // or numbers (or really anything...)
label: "Set User",
Expand Down
26 changes: 23 additions & 3 deletions lib/src/controller/command_palette_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ class CommandPaletteController extends ChangeNotifier {

/// Listens to [textEditingController] and is called whenever it changes.
void _onTextControllerChange() {
if (currentlySelectedAction?.actionType == CommandPaletteActionType.input) {
return;
}

if (_enteredQuery != textEditingController.text) {
_enteredQuery = textEditingController.text;
_actionsNeedRefiltered = true;
Expand All @@ -96,7 +100,8 @@ class CommandPaletteController extends ChangeNotifier {
CommandPaletteAction? get currentlySelectedAction => _currentlySelectedAction;
set currentlySelectedAction(CommandPaletteAction? newAction) {
assert(newAction == null ||
newAction.actionType == CommandPaletteActionType.nested);
newAction.actionType == CommandPaletteActionType.nested ||
newAction.actionType == CommandPaletteActionType.input);
_currentlySelectedAction = newAction;
_actionsNeedRefiltered = true;
textEditingController.clear();
Expand All @@ -118,6 +123,9 @@ class CommandPaletteController extends ChangeNotifier {
if (currentlySelectedAction?.actionType ==
CommandPaletteActionType.nested) {
filteredActions = currentlySelectedAction!.childrenActions!;
} else if (currentlySelectedAction?.actionType ==
CommandPaletteActionType.input) {
filteredActions = [];
} else {
filteredActions = actions;
}
Expand Down Expand Up @@ -193,14 +201,26 @@ class CommandPaletteController extends ChangeNotifier {

// nested items we set this item as the selected which in turn
// will display its children.
else if (action.actionType == CommandPaletteActionType.nested) {
else {
currentlySelectedAction = action;
}
}

void handleActionInput(BuildContext context) {
_currentlySelectedAction?.onConfirmInput!(textEditingController.text);
if (Navigator.of(context).canPop()) {
Navigator.of(context).pop();
}
}

/// performs the action which is currently selected by [highlightedAction]
void performHighlightedAction(BuildContext context) {
handleAction(context, action: _filteredActionsCache[highlightedAction]);
if (_currentlySelectedAction?.actionType ==
CommandPaletteActionType.input) {
handleActionInput(context);
} else {
handleAction(context, action: _filteredActionsCache[highlightedAction]);
}
}
}

Expand Down
24 changes: 22 additions & 2 deletions lib/src/models/command_palette_action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ enum CommandPaletteActionType {

/// Upon being selected a nested action will change the state of the command
/// palette so that it only shows its children
nested
nested,

/// Upon being selected the user will be given a text field that they can enter text into and submit.
/// The entered text will then be passed to the relevant callback
input
}

/// Action that is presented in the command palette. These are the things the
Expand All @@ -25,6 +29,10 @@ class CommandPaletteAction {
/// Specifies what type of action this is
final CommandPaletteActionType actionType;

/// Required when [actionType] set to [CommandPaletteActionType.input]. This
/// function is called when the action is confirmed
ValueChanged<String>? onConfirmInput;

/// Required when [actionType] set to [CommandPaletteActionType.single]. This
/// function is called when the action is selected
VoidCallback? onSelect;
Expand Down Expand Up @@ -68,13 +76,16 @@ class CommandPaletteAction {
required this.actionType,
this.onSelect,
this.childrenActions,
this.onConfirmInput,
this.shortcut,
this.id,
this.leading,
}) : assert((actionType == CommandPaletteActionType.single &&
onSelect != null) ||
(actionType == CommandPaletteActionType.nested &&
(childrenActions?.isNotEmpty ?? false))) {
(childrenActions?.isNotEmpty ?? false)) ||
(actionType == CommandPaletteActionType.input &&
(onConfirmInput != null))) {
// give all our children "us" as a parent.
if (actionType == CommandPaletteActionType.nested) {
for (final child in childrenActions!) {
Expand Down Expand Up @@ -106,6 +117,15 @@ class CommandPaletteAction {
}
}

CommandPaletteAction.input({
required this.label,
this.description,
required this.onConfirmInput,
this.shortcut,
this.id,
this.leading,
}) : actionType = CommandPaletteActionType.input;

@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
Expand Down
1 change: 1 addition & 0 deletions lib/src/models/matched_command_palette_action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class MatchedCommandPaletteAction extends CommandPaletteAction {
childrenActions: action.childrenActions,
description: action.description,
onSelect: action.onSelect,
onConfirmInput: action.onConfirmInput,
shortcut: action.shortcut,
id: action.id,
leading: action.leading,
Expand Down
35 changes: 21 additions & 14 deletions lib/src/widgets/command_palette_instructions.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:command_palette/src/controller/command_palette_controller.dart';
import 'package:command_palette/src/models/command_palette_action.dart';
import 'package:command_palette/src/widgets/keyboard_key_icon.dart';
import 'package:flutter/material.dart';

Expand Down Expand Up @@ -34,21 +35,27 @@ class CommandPaletteInstructions extends StatelessWidget {
color: color,
),
],
instruction: "to select",
),
_KeyboardInstruction(
icons: [
KeyboardKeyIcon(
icon: Icons.arrow_upward,
color: color,
),
KeyboardKeyIcon(
icon: Icons.arrow_downward,
color: color,
),
],
instruction: "to navigate",
instruction:
(controller.currentlySelectedAction?.actionType ==
CommandPaletteActionType.input)
? "to confirm"
: "to select",
),
if (controller.currentlySelectedAction?.actionType !=
CommandPaletteActionType.input)
_KeyboardInstruction(
icons: [
KeyboardKeyIcon(
icon: Icons.arrow_upward,
color: color,
),
KeyboardKeyIcon(
icon: Icons.arrow_downward,
color: color,
),
],
instruction: "to navigate",
),
if (controller.currentlySelectedAction != null)
_KeyboardInstruction(
icons: [
Expand Down
6 changes: 4 additions & 2 deletions lib/src/widgets/command_palette_text_field.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ class _CommandPaletteTextFieldState extends State<CommandPaletteTextField> {
inputDecoration.prefixText == null;
if (styleHasNoPrefix &&
style.prefixNestedActions &&
controller.currentlySelectedAction?.actionType ==
CommandPaletteActionType.nested) {
(controller.currentlySelectedAction?.actionType ==
CommandPaletteActionType.nested ||
controller.currentlySelectedAction?.actionType ==
CommandPaletteActionType.input)) {
inputDecoration = inputDecoration.copyWith(
prefixText: "${controller.currentlySelectedAction!.label}: ",
hintText: "",
Expand Down

0 comments on commit 655839e

Please sign in to comment.