UNPKG

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