summaryrefslogtreecommitdiffstats
path: root/devtools/client/shared/components/search-box.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/shared/components/search-box.js')
-rw-r--r--devtools/client/shared/components/search-box.js110
1 files changed, 110 insertions, 0 deletions
diff --git a/devtools/client/shared/components/search-box.js b/devtools/client/shared/components/search-box.js
new file mode 100644
index 000000000..bd572f8b2
--- /dev/null
+++ b/devtools/client/shared/components/search-box.js
@@ -0,0 +1,110 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* global window */
+
+"use strict";
+
+const { DOM: dom, createClass, PropTypes } = require("devtools/client/shared/vendor/react");
+const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
+
+/**
+ * A generic search box component for use across devtools
+ */
+module.exports = createClass({
+ displayName: "SearchBox",
+
+ propTypes: {
+ delay: PropTypes.number,
+ keyShortcut: PropTypes.string,
+ onChange: PropTypes.func,
+ placeholder: PropTypes.string,
+ type: PropTypes.string
+ },
+
+ getInitialState() {
+ return {
+ value: ""
+ };
+ },
+
+ componentDidMount() {
+ if (!this.props.keyShortcut) {
+ return;
+ }
+
+ this.shortcuts = new KeyShortcuts({
+ window
+ });
+ this.shortcuts.on(this.props.keyShortcut, (name, event) => {
+ event.preventDefault();
+ this.refs.input.focus();
+ });
+ },
+
+ componentWillUnmount() {
+ if (this.shortcuts) {
+ this.shortcuts.destroy();
+ }
+
+ // Clean up an existing timeout.
+ if (this.searchTimeout) {
+ clearTimeout(this.searchTimeout);
+ }
+ },
+
+ onChange() {
+ if (this.state.value !== this.refs.input.value) {
+ this.setState({ value: this.refs.input.value });
+ }
+
+ if (!this.props.delay) {
+ this.props.onChange(this.state.value);
+ return;
+ }
+
+ // Clean up an existing timeout before creating a new one.
+ if (this.searchTimeout) {
+ clearTimeout(this.searchTimeout);
+ }
+
+ // Execute the search after a timeout. It makes the UX
+ // smoother if the user is typing quickly.
+ this.searchTimeout = setTimeout(() => {
+ this.searchTimeout = null;
+ this.props.onChange(this.state.value);
+ }, this.props.delay);
+ },
+
+ onClearButtonClick() {
+ this.refs.input.value = "";
+ this.onChange();
+ },
+
+ render() {
+ let { type = "search", placeholder } = this.props;
+ let { value } = this.state;
+ let divClassList = ["devtools-searchbox", "has-clear-btn"];
+ let inputClassList = [`devtools-${type}input`];
+
+ if (value !== "") {
+ inputClassList.push("filled");
+ }
+ return dom.div(
+ { className: divClassList.join(" ") },
+ dom.input({
+ className: inputClassList.join(" "),
+ onChange: this.onChange,
+ placeholder,
+ ref: "input",
+ value
+ }),
+ dom.button({
+ className: "devtools-searchinput-clear",
+ hidden: value == "",
+ onClick: this.onClearButtonClick
+ })
+ );
+ }
+});