blob: be0ebf2bddbbdb36ae0d7fda8702c6b2b04871e6 [file] [log] [blame]
AviZi280f8012017-06-09 02:39:56 +03001/*!
2 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
13 * or implied. See the License for the specific language governing
14 * permissions and limitations under the License.
15 */
Michael Landoefa037d2017-02-19 12:57:33 +020016import React from 'react';
talig8e9c0652017-12-20 14:30:43 +020017import PropTypes from 'prop-types';
AviZi280f8012017-06-09 02:39:56 +030018import ReactDOM from 'react-dom';
Avi Zivb8e2faf2017-07-18 19:45:38 +030019import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
AviZi280f8012017-06-09 02:39:56 +030020import Input from 'nfvo-components/input/validation/InputWrapper.jsx';
Michael Landoefa037d2017-02-19 12:57:33 +020021
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020022const ExpandableInputClosed = ({ iconType, onClick }) => (
23 <SVGIcon
24 className="expandable-input-wrapper closed"
25 data-test-id="expandable-input-closed"
26 name={iconType}
27 onClick={onClick}
28 />
AviZi280f8012017-06-09 02:39:56 +030029);
Michael Landoefa037d2017-02-19 12:57:33 +020030
AviZi280f8012017-06-09 02:39:56 +030031class ExpandableInputOpened extends React.Component {
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020032 componentDidMount() {
33 this.rawDomNode = ReactDOM.findDOMNode(
34 this.searchInputNode.inputWrapper
35 );
36 this.rawDomNode.focus();
37 }
Michael Landoefa037d2017-02-19 12:57:33 +020038
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020039 componentWillReceiveProps(newProps) {
40 if (!newProps.value) {
41 if (!(document.activeElement === this.rawDomNode)) {
42 this.props.handleBlur();
43 }
44 }
45 }
AviZi280f8012017-06-09 02:39:56 +030046
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020047 handleClose() {
48 this.props.onChange('');
49 this.rawDomNode.focus();
50 }
AviZi280f8012017-06-09 02:39:56 +030051
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020052 handleKeyDown(e) {
53 if (e.key === 'Escape') {
54 e.preventDefault();
55 if (this.props.value) {
56 this.handleClose();
57 } else {
58 this.rawDomNode.blur();
59 }
60 }
61 }
AviZi280f8012017-06-09 02:39:56 +030062
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020063 render() {
64 let { iconType, value, onChange, handleBlur } = this.props;
65 return (
66 <div className="expandable-input-wrapper opened" key="expandable">
67 <Input
68 type="text"
69 data-test-id="expandable-input-opened"
70 value={value}
71 ref={input => (this.searchInputNode = input)}
72 className="expandable-active"
73 groupClassName="expandable-input-control"
74 onChange={e => onChange(e)}
75 onKeyDown={e => this.handleKeyDown(e)}
76 onBlur={handleBlur}
77 />
78 {value && (
79 <SVGIcon
80 data-test-id="expandable-input-close-btn"
81 onClick={() => this.handleClose()}
82 name="close"
83 />
84 )}
85 {!value && <SVGIcon name={iconType} onClick={handleBlur} />}
86 </div>
87 );
88 }
AviZi280f8012017-06-09 02:39:56 +030089}
90
91class ExpandableInput extends React.Component {
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020092 static propTypes = {
93 iconType: PropTypes.string,
94 onChange: PropTypes.func,
95 value: PropTypes.string
96 };
AviZi280f8012017-06-09 02:39:56 +030097
Yarin Dekel42b83b02018-11-29 10:24:07 +020098 constructor(props) {
99 super(props);
100 this.state = {
101 showInput: !!props.value || false
102 };
103 }
AviZi280f8012017-06-09 02:39:56 +0300104
Yarin Dekel42b83b02018-11-29 10:24:07 +0200105 showInputChange() {
106 if (this.props.value) {
107 this.setState({ showInput: true });
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200108 }
109 }
AviZi280f8012017-06-09 02:39:56 +0300110
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200111 getValue() {
112 return this.props.value;
113 }
Michael Landoefa037d2017-02-19 12:57:33 +0200114
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200115 render() {
116 let { iconType, value, onChange = false } = this.props;
117 return (
118 <div className="expandable-input-top">
119 {this.state.showInput && (
120 <ExpandableInputOpened
121 key="open"
122 iconType={iconType}
123 onChange={onChange}
124 value={value}
125 handleKeyDown={e => this.handleKeyDown(e)}
Yarin Dekel42b83b02018-11-29 10:24:07 +0200126 handleBlur={() => this.showInputChange()}
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200127 />
128 )}
129 {!this.state.showInput && (
130 <ExpandableInputClosed
131 key="closed"
132 iconType={iconType}
133 onClick={() => this.setState({ showInput: true })}
134 />
135 )}
136 </div>
137 );
138 }
Michael Landoefa037d2017-02-19 12:57:33 +0200139}
140
Michael Landoefa037d2017-02-19 12:57:33 +0200141export default ExpandableInput;