UNPKG

14.9 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.default = void 0;
7
8var _react = _interopRequireDefault(require("react"));
9
10var _propTypes = _interopRequireDefault(require("prop-types"));
11
12var _bind = _interopRequireDefault(require("classnames/bind"));
13
14var _terraButton = _interopRequireDefault(require("terra-button"));
15
16var KeyCode = _interopRequireWildcard(require("keycode-js"));
17
18var _IconSearch = _interopRequireDefault(require("terra-icon/lib/icon/IconSearch"));
19
20var _terraFormInput = _interopRequireDefault(require("terra-form-input"));
21
22var _reactIntl = require("react-intl");
23
24var _SearchFieldModule = _interopRequireDefault(require("./SearchField.module.scss"));
25
26function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
27
28function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
29
30function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
31
32function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
33
34function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
35
36function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
37
38function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
39
40function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
41
42function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
43
44function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
45
46function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
47
48function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
49
50function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
51
52function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
53
54function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
55
56function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
57
58function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
59
60var cx = _bind.default.bind(_SearchFieldModule.default);
61
62var Icon = _react.default.createElement(_IconSearch.default, null);
63
64var propTypes = {
65 /**
66 * The defaultValue of the search field. Use this to create an uncontrolled search field.
67 */
68 defaultValue: _propTypes.default.string,
69
70 /**
71 * When true, will disable the auto-search.
72 */
73 disableAutoSearch: _propTypes.default.bool,
74
75 /**
76 * Callback ref to pass into the inner input component.
77 */
78 inputRefCallback: _propTypes.default.func,
79
80 /**
81 * Custom input attributes to apply to the input field such as aria-label.
82 */
83 // eslint-disable-next-line react/forbid-prop-types
84 inputAttributes: _propTypes.default.object,
85
86 /**
87 * @private
88 * The intl object containing translations. This is retrieved from the context automatically by injectIntl.
89 */
90 intl: _reactIntl.intlShape.isRequired,
91
92 /**
93 * Whether or not the field should display as a block.
94 */
95 isBlock: _propTypes.default.bool,
96
97 /**
98 * When true, will disable the field.
99 */
100 isDisabled: _propTypes.default.bool,
101
102 /**
103 * The minimum number of characters to perform a search.
104 */
105 minimumSearchTextLength: _propTypes.default.number,
106
107 /**
108 * Function to trigger when user changes the input value. Provide a function to create a controlled input.
109 */
110 onChange: _propTypes.default.func,
111
112 /**
113 * A callback to indicate an invalid search. Sends parameter {String} searchText.
114 */
115 onInvalidSearch: _propTypes.default.func,
116
117 /**
118 * A callback to perform search. Sends parameter {String} searchText.
119 */
120 onSearch: _propTypes.default.func,
121
122 /**
123 * Placeholder text to show while the search field is empty.
124 */
125 placeholder: _propTypes.default.string,
126
127 /**
128 * How long the component should wait (in milliseconds) after input before performing an automatic search.
129 */
130 searchDelay: _propTypes.default.number,
131
132 /**
133 * The value of search field. Use this to create a controlled search field.
134 */
135 value: _propTypes.default.string
136};
137var defaultProps = {
138 defaultValue: undefined,
139 disableAutoSearch: false,
140 isBlock: false,
141 isDisabled: false,
142 minimumSearchTextLength: 2,
143 placeholder: '',
144 searchDelay: 250,
145 value: undefined,
146 inputAttributes: undefined
147};
148
149var SearchField =
150/*#__PURE__*/
151function (_React$Component) {
152 _inherits(SearchField, _React$Component);
153
154 function SearchField(props) {
155 var _this;
156
157 _classCallCheck(this, SearchField);
158
159 _this = _possibleConstructorReturn(this, _getPrototypeOf(SearchField).call(this, props));
160 _this.handleClear = _this.handleClear.bind(_assertThisInitialized(_this));
161 _this.handleTextChange = _this.handleTextChange.bind(_assertThisInitialized(_this));
162 _this.handleSearch = _this.handleSearch.bind(_assertThisInitialized(_this));
163 _this.handleKeyDown = _this.handleKeyDown.bind(_assertThisInitialized(_this));
164 _this.setInputRef = _this.setInputRef.bind(_assertThisInitialized(_this));
165 _this.updateSearchText = _this.updateSearchText.bind(_assertThisInitialized(_this));
166 _this.searchTimeout = null;
167 _this.state = {
168 searchText: _this.props.defaultValue || _this.props.value
169 };
170 return _this;
171 }
172
173 _createClass(SearchField, [{
174 key: "componentDidUpdate",
175 value: function componentDidUpdate() {
176 // if consumer updates the value prop with onChange, need to update state to match
177 this.updateSearchText(this.props.value);
178 }
179 }, {
180 key: "componentWillUnmount",
181 value: function componentWillUnmount() {
182 this.clearSearchTimeout();
183 }
184 }, {
185 key: "setInputRef",
186 value: function setInputRef(node) {
187 this.inputRef = node;
188
189 if (this.props.inputRefCallback) {
190 this.props.inputRefCallback(node);
191 }
192 }
193 }, {
194 key: "handleClear",
195 value: function handleClear(event) {
196 // Pass along changes to consuming components using associated props
197 if (this.props.onChange) {
198 this.props.onChange(event, '');
199 }
200
201 if (this.props.onInvalidSearch) {
202 this.props.onInvalidSearch('');
203 }
204
205 this.setState({
206 searchText: ''
207 }); // Clear input field
208
209 if (this.inputRef) {
210 this.inputRef.value = '';
211 this.inputRef.focus();
212 }
213 }
214 }, {
215 key: "handleTextChange",
216 value: function handleTextChange(event) {
217 var textValue = event.target.value;
218 this.updateSearchText(textValue);
219
220 if (this.props.onChange) {
221 this.props.onChange(event, textValue);
222 }
223
224 if (!this.searchTimeout && !this.props.disableAutoSearch) {
225 this.searchTimeout = setTimeout(this.handleSearch, this.props.searchDelay);
226 }
227 }
228 }, {
229 key: "updateSearchText",
230 value: function updateSearchText(searchText) {
231 if (searchText !== undefined && searchText !== this.state.searchText) {
232 this.setState({
233 searchText: searchText
234 });
235 }
236 }
237 }, {
238 key: "handleKeyDown",
239 value: function handleKeyDown(event) {
240 if (event.nativeEvent.keyCode === KeyCode.KEY_RETURN) {
241 this.handleSearch();
242 }
243
244 if (event.nativeEvent.keyCode === KeyCode.KEY_ESCAPE) {
245 this.handleClear(event);
246 }
247 }
248 }, {
249 key: "handleSearch",
250 value: function handleSearch() {
251 this.clearSearchTimeout();
252 var searchText = this.state.searchText || '';
253
254 if (searchText.length >= this.props.minimumSearchTextLength && this.props.onSearch) {
255 this.props.onSearch(searchText);
256 } else if (this.props.onInvalidSearch) {
257 this.props.onInvalidSearch(searchText);
258 }
259 }
260 }, {
261 key: "clearSearchTimeout",
262 value: function clearSearchTimeout() {
263 if (this.searchTimeout) {
264 clearTimeout(this.searchTimeout);
265 this.searchTimeout = null;
266 }
267 }
268 }, {
269 key: "render",
270 value: function render() {
271 var _this$props = this.props,
272 defaultValue = _this$props.defaultValue,
273 disableAutoSearch = _this$props.disableAutoSearch,
274 inputRefCallback = _this$props.inputRefCallback,
275 inputAttributes = _this$props.inputAttributes,
276 intl = _this$props.intl,
277 isBlock = _this$props.isBlock,
278 isDisabled = _this$props.isDisabled,
279 minimumSearchTextLength = _this$props.minimumSearchTextLength,
280 onChange = _this$props.onChange,
281 onInvalidSearch = _this$props.onInvalidSearch,
282 onSearch = _this$props.onSearch,
283 placeholder = _this$props.placeholder,
284 searchDelay = _this$props.searchDelay,
285 value = _this$props.value,
286 customProps = _objectWithoutProperties(_this$props, ["defaultValue", "disableAutoSearch", "inputRefCallback", "inputAttributes", "intl", "isBlock", "isDisabled", "minimumSearchTextLength", "onChange", "onInvalidSearch", "onSearch", "placeholder", "searchDelay", "value"]);
287
288 var searchFieldClassNames = cx(['search-field', {
289 block: isBlock
290 }, customProps.className]);
291 var inputText = inputAttributes && Object.prototype.hasOwnProperty.call(inputAttributes, 'aria-label') ? inputAttributes['aria-label'] : intl.formatMessage({
292 id: 'Terra.searchField.search'
293 });
294 var buttonText = intl.formatMessage({
295 id: 'Terra.searchField.submit-search'
296 });
297 var clearText = intl.formatMessage({
298 id: 'Terra.searchField.clear'
299 });
300
301 var additionalInputAttributes = _objectSpread({}, inputAttributes);
302
303 var clearIcon = _react.default.createElement("span", {
304 className: cx('clear-icon')
305 });
306
307 if (value !== undefined) {
308 additionalInputAttributes.value = value;
309 } else {
310 additionalInputAttributes.defaultValue = defaultValue;
311 }
312
313 var clearButton = this.state.searchText && !isDisabled ? _react.default.createElement(_terraButton.default, {
314 className: cx('clear'),
315 onClick: this.handleClear,
316 text: clearText,
317 variant: "utility",
318 icon: clearIcon,
319 isIconOnly: true
320 }) : undefined;
321 return _react.default.createElement("div", _extends({}, customProps, {
322 className: searchFieldClassNames
323 }), _react.default.createElement("div", {
324 className: cx('input-group')
325 }, _react.default.createElement(_terraFormInput.default, _extends({
326 className: cx('input'),
327 type: "search",
328 placeholder: placeholder,
329 onChange: this.handleTextChange,
330 disabled: isDisabled,
331 ariaLabel: inputText,
332 "aria-disabled": isDisabled,
333 onKeyDown: this.handleKeyDown,
334 refCallback: this.setInputRef
335 }, additionalInputAttributes)), clearButton), _react.default.createElement(_terraButton.default, {
336 className: cx('button'),
337 text: buttonText,
338 onClick: this.handleSearch,
339 isDisabled: isDisabled,
340 icon: Icon,
341 isIconOnly: true,
342 isCompact: true
343 }));
344 }
345 }]);
346
347 return SearchField;
348}(_react.default.Component);
349
350SearchField.propTypes = propTypes;
351SearchField.defaultProps = defaultProps;
352
353var _default = (0, _reactIntl.injectIntl)(SearchField);
354
355exports.default = _default;
\No newline at end of file