From 81a0c45c89df2dc94f7d97c4367f0e549495e4d0 Mon Sep 17 00:00:00 2001
From: Jason <jason.daurus@gmail.com>
Date: Thu, 9 Jun 2016 20:34:57 +0800
Subject: [web] header.js -> Header.js

---
 web/src/js/components/Header/FilterInput.jsx | 133 +++++++++++++++++++++++++++
 1 file changed, 133 insertions(+)
 create mode 100644 web/src/js/components/Header/FilterInput.jsx

(limited to 'web/src/js/components/Header/FilterInput.jsx')

diff --git a/web/src/js/components/Header/FilterInput.jsx b/web/src/js/components/Header/FilterInput.jsx
new file mode 100644
index 00000000..5b49b788
--- /dev/null
+++ b/web/src/js/components/Header/FilterInput.jsx
@@ -0,0 +1,133 @@
+import React, { PropTypes, Component } from 'react'
+import ReactDOM from 'react-dom'
+import classnames from 'classnames'
+import { Key } from '../../utils.js'
+import Filt from '../../filt/filt'
+import FilterDocs from './FilterDocs'
+
+export default class FilterInput extends Component {
+
+    static contextTypes = {
+        returnFocus: React.PropTypes.func,
+    }
+
+    constructor(props, context) {
+        super(props, context)
+
+        // Consider both focus and mouseover for showing/hiding the tooltip,
+        // because onBlur of the input is triggered before the click on the tooltip
+        // finalized, hiding the tooltip just as the user clicks on it.
+        this.state = { value: this.props.value, focus: false, mousefocus: false }
+
+        this.onChange = this.onChange.bind(this)
+        this.onFocus = this.onFocus.bind(this)
+        this.onBlur = this.onBlur.bind(this)
+        this.onKeyDown = this.onKeyDown.bind(this)
+        this.onMouseEnter = this.onMouseEnter.bind(this)
+        this.onMouseLeave = this.onMouseLeave.bind(this)
+    }
+
+    componentWillReceiveProps(nextProps) {
+        this.setState({ value: nextProps.value })
+    }
+
+    isValid(filt) {
+        try {
+            const str = filt == null ? this.state.value : filt
+            if (str) {
+                Filt.parse(str)
+            }
+            return true
+        } catch (e) {
+            return false
+        }
+    }
+
+    getDesc() {
+        if (!this.state.value) {
+            return <FilterDocs/>
+        }
+        try {
+            return Filt.parse(this.state.value).desc
+        } catch (e) {
+            return '' + e
+        }
+    }
+
+    onChange(e) {
+        const value = e.target.value
+        this.setState({ value })
+
+        // Only propagate valid filters upwards.
+        if (this.isValid(value)) {
+            this.props.onChange(value)
+        }
+    }
+
+    onFocus() {
+        this.setState({ focus: true })
+    }
+
+    onBlur() {
+        this.setState({ focus: false })
+    }
+
+    onMouseEnter() {
+        this.setState({ mousefocus: true })
+    }
+
+    onMouseLeave() {
+        this.setState({ mousefocus: false })
+    }
+
+    onKeyDown(e) {
+        if (e.keyCode === Key.ESC || e.keyCode === Key.ENTER) {
+            this.blur()
+            // If closed using ESC/ENTER, hide the tooltip.
+            this.setState({mousefocus: false})
+        }
+        e.stopPropagation()
+    }
+
+    blur() {
+        ReactDOM.findDOMNode(this.refs.input).blur()
+        this.context.returnFocus()
+    }
+
+    select() {
+        ReactDOM.findDOMNode(this.refs.input).select()
+    }
+
+    render() {
+        const { type, color, placeholder } = this.props
+        const { value, focus, mousefocus } = this.state
+        return (
+            <div className={classnames('filter-input input-group', { 'has-error': !this.isValid() })}>
+                <span className="input-group-addon">
+                    <i className={'fa fa-fw fa-' + type} style={{ color }}></i>
+                </span>
+                <input
+                    type="text"
+                    ref="input"
+                    placeholder={placeholder}
+                    className="form-control"
+                    value={value}
+                    onChange={this.onChange}
+                    onFocus={this.onFocus}
+                    onBlur={this.onBlur}
+                    onKeyDown={this.onKeyDown}
+                />
+                {(focus || mousefocus) && (
+                    <div className="popover bottom"
+                         onMouseEnter={this.onMouseEnter}
+                         onMouseLeave={this.onMouseLeave}>
+                        <div className="arrow"></div>
+                        <div className="popover-content">
+                        {this.getDesc()}
+                        </div>
+                    </div>
+                )}
+            </div>
+        )
+    }
+}
-- 
cgit v1.2.3

