diff --git a/.storybook/config.js b/.storybook/config.js
index e34ae993..21edff7e 100644
--- a/.storybook/config.js
+++ b/.storybook/config.js
@@ -1,7 +1,7 @@
import { configure } from '@kadira/storybook';
+import '../src/index.css';
function loadStories() {
- require('../src/index.css');
require('../src/containers/stories/');
require('../src/components/stories/');
}
diff --git a/src/actions/findbar.js b/src/actions/findbar.js
index e8cd6917..91f38c30 100644
--- a/src/actions/findbar.js
+++ b/src/actions/findbar.js
@@ -1,5 +1,5 @@
export const RUN_COMMAND = 'RUN_COMMAND';
-export function runCommand(commandName, paramName, paramValue) {
- return { type: RUN_COMMAND, command: commandName, payload: { [paramName]: paramValue } };
+export function runCommand(commandName, payload) {
+ return { type: RUN_COMMAND, command: commandName, payload };
}
diff --git a/src/containers/FindBar.js b/src/containers/FindBar.js
index 3d91e090..132a99ee 100644
--- a/src/containers/FindBar.js
+++ b/src/containers/FindBar.js
@@ -49,20 +49,29 @@ class FindBar extends Component {
return result.charAt(0).toUpperCase() + result.slice(1);
}
+ // Generates a regexp and splits a token and param details for a command
compileCommand(command) {
let regexp = '';
- let param;
+ let param = null;
const matcher = /\(:([a-zA-Z_$][a-zA-Z0-9_$]*)(?:(?: as )(.*))?\)/g;
const match = matcher.exec(command.pattern);
- const token = command.pattern.slice(0, match.index) || command.token;
- regexp += this._escapeRegExp(command.pattern.slice(0, match.index));
+ const matchIndex = match ? match.index : command.pattern.length;
- if (match[1]) {
+ const token = command.pattern.slice(0, matchIndex) || command.token;
+ regexp += this._escapeRegExp(command.pattern.slice(0, matchIndex));
+
+ if (match && match[1]) {
regexp += '(.*)';
param = { name:match[1], display:match[2] || this._camelCaseToSpace(match[1]) };
}
+ console.log(Object.assign({}, command, {
+ regexp,
+ token,
+ param
+ }));
+
return Object.assign({}, command, {
regexp,
token,
@@ -70,6 +79,8 @@ class FindBar extends Component {
});
}
+ // Check if the entered string matches any command.
+ // adds a scope (so user can type param value) and dispatches action for fully matched commands
matchCommand() {
const string = this.state.activeScope ? this.state.activeScope + this.state.value : this.state.value;
let match;
@@ -78,18 +89,27 @@ class FindBar extends Component {
return match;
});
- const param = match[1] && match[1].trim();
+ const paramName = command.param ? command.param.name : null;
+ const enteredParamValue = command.param && match[1] ? match[1].trim() : null;
if (!command) {
+ // No matched command
return null;
- } else if (command && !param) {
+ } else if (command.param && !enteredParamValue) {
+ // Partial Match
+ // Command was partially matched: It requires a param, but param wasn't entered
+ // Set a scope so user can fill the param
this.setState({
value: '',
activeScope: command.token,
placeholder: command.param.display
});
} else {
- this.props.dispatch(runCommand(command.token, command.param.name, param));
+ // Match
+ // Command was matched and either it doesn't require a param or it's required param was entered
+ // Dispatch action
+ const payload = paramName ? { [paramName]: enteredParamValue } : null;
+ this.props.dispatch(runCommand(command.token, payload));
}
}
@@ -102,10 +122,18 @@ class FindBar extends Component {
}
}
- handleChange(event) {
- this.setState({
- value: event.target.value,
+ getSuggestions() {
+ return this._getSuggestions(this.state.value, this.state.activeScope, this._compiledCommands);
+ }
+ // Memoized version
+ _getSuggestions(value, scope, commands) {
+ if (scope) return []; // No autocomplete for scoped input
+ const results = fuzzy.filter(value, commands, {
+ //pre: '',
+ //post: '',
+ extract: el => el.token
});
+ return results.slice(0, 5).map(result => result.original);
}
handleKeyDown(event) {
@@ -171,6 +199,12 @@ class FindBar extends Component {
}
}
+ handleChange(event) {
+ this.setState({
+ value: event.target.value,
+ });
+ }
+
handleInputBlur() {
if (this._ignoreBlur) return;
this.setState({
@@ -189,20 +223,6 @@ class FindBar extends Component {
this.setState({ isOpen: true });
}
- _getSuggestions(value, scope, commands) {
- if (scope) return []; // TODO: Prepare for multiple params & search suggestions
- const results = fuzzy.filter(value, commands, {
- //pre: '',
- //post: '',
- extract: el => el.token
- });
- return results.slice(0, 5).map(result => result.original);
- }
-
- getSuggestions() {
- return this._getSuggestions(this.state.value, this.state.activeScope, this._compiledCommands);
- }
-
highlightCommandFromMouse(index) {
this.setState({ highlightedIndex: index });
}
diff --git a/src/containers/stories/FindBar.js b/src/containers/stories/FindBar.js
index b512d61d..fbd5b580 100644
--- a/src/containers/stories/FindBar.js
+++ b/src/containers/stories/FindBar.js
@@ -10,7 +10,8 @@ const commands = [
{ pattern: 'Create new FAQ item(:faqName as FAQ item name)' },
{ pattern: 'Add news item(:headline)' },
{ pattern: 'Add new User(:userName as User name)' },
- { pattern: 'Search(:seachTerm as what?)' },
+ { pattern: 'Search(:searchTerm as what?)' },
+ { pattern: 'Go to Settings' },
{ pattern: 'Find(:seachTerm as what?)' },
{ pattern: '(:searchTerm as Find...)', token:'Find' }
];