search-box.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  3. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. /* global window */
  5. "use strict";
  6. const { DOM: dom, createClass, PropTypes } = require("devtools/client/shared/vendor/react");
  7. const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
  8. /**
  9. * A generic search box component for use across devtools
  10. */
  11. module.exports = createClass({
  12. displayName: "SearchBox",
  13. propTypes: {
  14. delay: PropTypes.number,
  15. keyShortcut: PropTypes.string,
  16. onChange: PropTypes.func,
  17. placeholder: PropTypes.string,
  18. type: PropTypes.string
  19. },
  20. getInitialState() {
  21. return {
  22. value: ""
  23. };
  24. },
  25. componentDidMount() {
  26. if (!this.props.keyShortcut) {
  27. return;
  28. }
  29. this.shortcuts = new KeyShortcuts({
  30. window
  31. });
  32. this.shortcuts.on(this.props.keyShortcut, (name, event) => {
  33. event.preventDefault();
  34. this.refs.input.focus();
  35. });
  36. },
  37. componentWillUnmount() {
  38. if (this.shortcuts) {
  39. this.shortcuts.destroy();
  40. }
  41. // Clean up an existing timeout.
  42. if (this.searchTimeout) {
  43. clearTimeout(this.searchTimeout);
  44. }
  45. },
  46. onChange() {
  47. if (this.state.value !== this.refs.input.value) {
  48. this.setState({ value: this.refs.input.value });
  49. }
  50. if (!this.props.delay) {
  51. this.props.onChange(this.state.value);
  52. return;
  53. }
  54. // Clean up an existing timeout before creating a new one.
  55. if (this.searchTimeout) {
  56. clearTimeout(this.searchTimeout);
  57. }
  58. // Execute the search after a timeout. It makes the UX
  59. // smoother if the user is typing quickly.
  60. this.searchTimeout = setTimeout(() => {
  61. this.searchTimeout = null;
  62. this.props.onChange(this.state.value);
  63. }, this.props.delay);
  64. },
  65. onClearButtonClick() {
  66. this.refs.input.value = "";
  67. this.onChange();
  68. },
  69. render() {
  70. let { type = "search", placeholder } = this.props;
  71. let { value } = this.state;
  72. let divClassList = ["devtools-searchbox", "has-clear-btn"];
  73. let inputClassList = [`devtools-${type}input`];
  74. if (value !== "") {
  75. inputClassList.push("filled");
  76. }
  77. return dom.div(
  78. { className: divClassList.join(" ") },
  79. dom.input({
  80. className: inputClassList.join(" "),
  81. onChange: this.onChange,
  82. placeholder,
  83. ref: "input",
  84. value
  85. }),
  86. dom.button({
  87. className: "devtools-searchinput-clear",
  88. hidden: value == "",
  89. onClick: this.onClearButtonClick
  90. })
  91. );
  92. }
  93. });