react-textarea-with-suggest 1.1.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # react-textarea-with-suggest
2
- Textarea with suggest for React app
2
+ Textarea with suggest for React app v2.0.0
3
+
4
+ ### Last changes:
5
+ - supports TypeScript and new React versions
6
+ - fixed bug with installing
3
7
 
4
8
  ## Install
5
9
  If you use npm
@@ -60,8 +64,6 @@ item =>
60
64
  |any else params for `<textarea>`| - | - |https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#Attributes|
61
65
 
62
66
  ## Using libraries
63
- - "prop-types"
64
- - "lodash.once"
65
67
  - "react-textarea-autosize" (optionally)
66
68
 
67
69
  ## License
@@ -0,0 +1,20 @@
1
+ # Example application with react-textarea-with-suggest
2
+
3
+ This small application was created to present use cases of react-textarea-with-suggest package
4
+
5
+ ## Available Scripts
6
+
7
+ In the project directory, you can run:
8
+
9
+ ### `npm start`
10
+
11
+ Runs the app in the development mode.\
12
+ Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
13
+
14
+ The page will reload when you make changes.\
15
+ You may also see any lint errors in the console.
16
+
17
+ ## Learn More
18
+
19
+ To learn more, check out the [Readme](https://github.com/marylorian/react-textarea-with-suggest).
20
+
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "example",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "dependencies": {
6
+ "react": "^16.14.0",
7
+ "react-dom": "^16.14.0",
8
+ "react-scripts": "5.0.1",
9
+ "react-textarea-with-suggest": "latest"
10
+ },
11
+ "scripts": {
12
+ "start": "react-scripts start",
13
+ "test": "react-scripts test"
14
+ },
15
+ "eslintConfig": {
16
+ "extends": [
17
+ "react-app",
18
+ "react-app/jest"
19
+ ]
20
+ },
21
+ "browserslist": {
22
+ "production": [
23
+ ">0.2%",
24
+ "not dead",
25
+ "not op_mini all"
26
+ ],
27
+ "development": [
28
+ "last 1 chrome version",
29
+ "last 1 firefox version",
30
+ "last 1 safari version"
31
+ ]
32
+ },
33
+ "devDependencies": {
34
+ "lodash.once": "^4.1.1",
35
+ "react-textarea-autosize": "^8.4.0"
36
+ }
37
+ }
@@ -0,0 +1,43 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ <meta name="theme-color" content="#000000" />
8
+ <meta
9
+ name="description"
10
+ content="Web site created using create-react-app"
11
+ />
12
+ <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
13
+ <!--
14
+ manifest.json provides metadata used when your web app is installed on a
15
+ user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
16
+ -->
17
+ <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
18
+ <!--
19
+ Notice the use of %PUBLIC_URL% in the tags above.
20
+ It will be replaced with the URL of the `public` folder during the build.
21
+ Only files inside the `public` folder can be referenced from the HTML.
22
+
23
+ Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
24
+ work correctly both with client-side routing and a non-root public URL.
25
+ Learn how to configure a non-root public URL by running `npm run build`.
26
+ -->
27
+ <title>React App</title>
28
+ </head>
29
+ <body>
30
+ <noscript>You need to enable JavaScript to run this app.</noscript>
31
+ <div id="root"></div>
32
+ <!--
33
+ This HTML file is a template.
34
+ If you open it directly in the browser, you will see an empty page.
35
+
36
+ You can add webfonts, meta tags, or analytics to this file.
37
+ The build step will place the bundled scripts into the <body> tag.
38
+
39
+ To begin the development, run `npm start` or `yarn start`.
40
+ To create a production bundle, use `npm run build` or `yarn build`.
41
+ -->
42
+ </body>
43
+ </html>
@@ -0,0 +1,15 @@
1
+ .example {
2
+ text-align: center;
3
+ font-family: Arial, Helvetica, sans-serif;
4
+ }
5
+
6
+ .example__textarea {
7
+ border-radius: 4px;
8
+ padding: 12px;
9
+ font-family: Arial, Helvetica, sans-serif;
10
+ }
11
+
12
+ .example__textarea__results {
13
+ border-radius: 4px;
14
+ border: 1px solid;
15
+ }
@@ -0,0 +1,74 @@
1
+ import { useState } from "react";
2
+ import Textarea from "react-textarea-with-suggest";
3
+ import "./App.css";
4
+
5
+ const randomResults = [
6
+ "Hello",
7
+ "The Result",
8
+ "Harry Potter",
9
+ "The Lord Of The Rings",
10
+ "The Matrix",
11
+ "The Truman Show",
12
+ "Home Alone",
13
+ "Cat In The Hat",
14
+ "Alice In Worderland",
15
+ "The Night Knight",
16
+ "The Dark Knight",
17
+ "Dark Night",
18
+ "The Long Night",
19
+ "Good bye",
20
+ ];
21
+
22
+ function App() {
23
+ const [results, setResults] = useState(undefined);
24
+
25
+ const onSearch = (searchPhrase) => {
26
+ console.log("onSearch", searchPhrase);
27
+
28
+ const start = Math.floor(Math.random() * 10);
29
+ const length = Math.floor(Math.random() * 10);
30
+ const newResults = randomResults
31
+ .slice(start, start + length)
32
+ .filter(Boolean);
33
+
34
+ setResults(newResults);
35
+ };
36
+
37
+ const onChange = (e) => {
38
+ console.log("onChange", e.target.value);
39
+ };
40
+
41
+ return (
42
+ <div className="example">
43
+ <h1>TextareaWithSuggest Example</h1>
44
+ <p>Default</p>
45
+ <Textarea
46
+ className="example__textarea"
47
+ onChange={onChange}
48
+ onSearch={onSearch}
49
+ suggestList={results}
50
+ />
51
+
52
+ <p>Autosizable</p>
53
+ <Textarea
54
+ autosizable
55
+ className="example__textarea"
56
+ onChange={onChange}
57
+ onSearch={onSearch}
58
+ suggestList={results}
59
+ />
60
+
61
+ <p>With initial value</p>
62
+ <Textarea
63
+ autosizable
64
+ className="example__textarea"
65
+ value="Initial Value"
66
+ onChange={onChange}
67
+ onSearch={onSearch}
68
+ suggestList={results}
69
+ />
70
+ </div>
71
+ );
72
+ }
73
+
74
+ export default App;
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import ReactDOM from "react-dom";
3
+ import App from "./App";
4
+
5
+ ReactDOM.render(
6
+ <React.StrictMode>
7
+ <App />
8
+ </React.StrictMode>,
9
+ document.getElementById("root")
10
+ );
package/lib/index.d.ts ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * React textarea with suggest v2.0.0
3
+ *
4
+ *
5
+ * Copyright (c) 2019-present,
6
+ * by Mariia Lobareva (marialobareva97@gmail.com).
7
+ *
8
+ * LICENSE MIT.
9
+ */
10
+ import React, { ReactNode } from "react";
11
+ import "../styles.css";
12
+ interface TextareaSuggestProps<SuggestItemType> {
13
+ className?: string;
14
+ autosizable?: boolean;
15
+ searchMarker?: string;
16
+ searchRegexp?: RegExp;
17
+ suggestList?: SuggestItemType[];
18
+ value?: string;
19
+ onChange?: Function;
20
+ onSearch: Function;
21
+ customSuggestItemRenderer?: (suggestItem: SuggestItemType, defaultOnClick: (item: SuggestItemType) => void) => ReactNode;
22
+ }
23
+ declare const TextareaSuggest: <SuggestItemType extends React.ReactNode>({ autosizable, value, searchMarker, searchRegexp: searchRegexpProp, suggestList, onSearch, onChange, customSuggestItemRenderer, ...props }: TextareaSuggestProps<SuggestItemType>) => JSX.Element;
24
+ export default TextareaSuggest;
package/lib/index.js CHANGED
@@ -1,273 +1,2 @@
1
- "use strict";
2
-
3
- var _react = _interopRequireDefault(require("react"));
4
-
5
- var _propTypes = _interopRequireDefault(require("prop-types"));
6
-
7
- var _lodash = _interopRequireDefault(require("lodash.once"));
8
-
9
- var _reactTextareaAutosize = _interopRequireDefault(require("react-textarea-autosize"));
10
-
11
- require("../styles.css");
12
-
13
- var _class, _temp;
14
-
15
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
-
17
- function _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); }
18
-
19
- function _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; }
20
-
21
- function _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; }
22
-
23
- function 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; }
24
-
25
- function _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; }
26
-
27
- function _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; }
28
-
29
- function _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); }
30
-
31
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
32
-
33
- function _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); } }
34
-
35
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
36
-
37
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
38
-
39
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
40
-
41
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
42
-
43
- function _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); }
44
-
45
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
46
-
47
- module.exports = (_temp = _class =
48
- /*#__PURE__*/
49
- function (_React$Component) {
50
- _inherits(TextareaSuggest, _React$Component);
51
-
52
- function TextareaSuggest() {
53
- var _getPrototypeOf2;
54
-
55
- var _this;
56
-
57
- _classCallCheck(this, TextareaSuggest);
58
-
59
- for (var _len = arguments.length, _args = new Array(_len), _key = 0; _key < _len; _key++) {
60
- _args[_key] = arguments[_key];
61
- }
62
-
63
- _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(TextareaSuggest)).call.apply(_getPrototypeOf2, [this].concat(_args)));
64
- _this._textarea = null;
65
- _this._element = null;
66
- _this.state = {
67
- needStartSearch: _this.props.value && _this.props.value.includes(_this.props.searchMarker),
68
- text: _this.props.value || ""
69
- };
70
- _this.defaultProps = {
71
- autosizable: false,
72
- searchMarker: "@",
73
- searchRegexp: /@([a-z0\d\-.]+[a-z\d])/gim,
74
- suggestList: []
75
- };
76
-
77
- _this._mobileAndTabletCheck = function () {
78
- var check = false;
79
-
80
- (function (a) {
81
- if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw-(n|u)|c55\/|capi|ccwa|cdm-|cell|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do(c|p)o|ds(12|-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(-|_)|g1 u|g560|gene|gf-5|g-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd-(m|p|t)|hei-|hi(pt|ta)|hp( i|ip)|hs-c|ht(c(-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac( |-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h-|oo|p-)|sdk\/|se(c(-|0|1)|47|mc|nd|ri)|sgh-|shar|sie(-|m)|sk-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel(i|m)|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-|your|zeto|zte-/i.test(a.substr(0, 4))) check = true;
82
- })(navigator.userAgent || navigator.vendor || window.opera);
83
-
84
- return check;
85
- };
86
-
87
- _this.onChange = function (_ref) {
88
- var args = _extends({}, _ref);
89
-
90
- var _this$props = _this.props,
91
- searchMarker = _this$props.searchMarker,
92
- searchRegexp = _this$props.searchRegexp;
93
- var needStartSearch = _this.state.needStartSearch;
94
- var _args$currentTarget = args.currentTarget,
95
- currentTarget = _args$currentTarget === void 0 ? {} : _args$currentTarget,
96
- _args$isTrusted = args.isTrusted,
97
- isTrusted = _args$isTrusted === void 0 ? true : _args$isTrusted;
98
- var _currentTarget$value = currentTarget.value,
99
- value = _currentTarget$value === void 0 ? _this.state.text : _currentTarget$value;
100
- var selectionEnd = _this._textarea.selectionEnd;
101
- var last = selectionEnd ? value.slice(selectionEnd - 1, selectionEnd) : value.slice(-1);
102
-
103
- _this.setState({
104
- text: value
105
- });
106
-
107
- if (last === searchMarker) {
108
- _this.setState({
109
- needStartSearch: true
110
- }); //TODO: clear suggestList here
111
-
112
- }
113
-
114
- if (!value.includes(searchMarker) && needStartSearch) {
115
- _this.setState({
116
- needStartSearch: false
117
- });
118
- }
119
-
120
- if (last !== searchMarker && needStartSearch) {
121
- var textWithResults = value.slice(0, selectionEnd);
122
- var results = textWithResults.slice(textWithResults.lastIndexOf(searchMarker)).match(new RegExp(searchRegexp));
123
- var result = results ? results[0].slice(1) : last;
124
-
125
- _this.props.onSearch(result);
126
- }
127
-
128
- if (isTrusted) return _this.props.onChange(args);
129
- return _this.props.onChange(_objectSpread({}, args, {
130
- currentTarget: _this._textarea,
131
- target: _this._textarea
132
- }));
133
- };
134
-
135
- _this.setResult = function (result) {
136
- var searchMarker = _this.props.searchMarker;
137
- var currentText = _this.state.text;
138
- var selectionEnd = _this._textarea.selectionEnd;
139
- var position = currentText.slice(0, selectionEnd).lastIndexOf(searchMarker);
140
- var textWithResult = currentText.slice(position);
141
-
142
- if (position !== -1) {
143
- var endPosition = (textWithResult.includes(" ") ? textWithResult.indexOf(" ") : currentText.length) + position;
144
- var newValue;
145
-
146
- if (textWithResult.lastIndexOf(searchMarker) > 0) {
147
- endPosition = textWithResult.lastIndexOf(searchMarker) + position;
148
- }
149
-
150
- if (!endPosition || endPosition < position) {
151
- endPosition = currentText.length;
152
- }
153
-
154
- newValue = currentText.slice(0, position || 0) + currentText.slice(position).replace(currentText.slice(position, endPosition), "".concat(searchMarker).concat(result, " "));
155
- _this._textarea.value = newValue;
156
-
157
- _this._textarea.focus();
158
-
159
- if (_this._mobileAndTabletCheck()) {
160
- var endCaretPosition = newValue.slice(position).indexOf(" ") + position + 1;
161
-
162
- _this._textarea.setSelectionRange(endCaretPosition, endCaretPosition);
163
- }
164
-
165
- var event = new Event("onchange", {
166
- bubbles: true,
167
- cancelable: false
168
- });
169
-
170
- _this._element._onChange(event);
171
-
172
- _this.setState({
173
- needStartSearch: false,
174
- text: newValue
175
- });
176
- }
177
- };
178
-
179
- _this.renderSuggestItem = function (item, index) {
180
- if (_this.props.onSuggestItemRender) return _this.props.onSuggestItemRender(item);
181
- return _react.default.createElement("div", {
182
- key: index,
183
- className: "textarea-suggest-item",
184
- onClick: function onClick() {
185
- return _this.setResult(item);
186
- }
187
- }, _react.default.createElement("div", {
188
- className: "textarea-suggest-item--info"
189
- }, _react.default.createElement("div", null, item)));
190
- };
191
-
192
- _this.renderSearchResults = function () {
193
- var suggestList = _this.props.suggestList;
194
-
195
- if (_this.state.needStartSearch && suggestList && suggestList.length && _this._textare) {
196
- var curHeight = _this._textarea.getBoundingClientRect().height;
197
-
198
- return _react.default.createElement("div", {
199
- className: "textarea-suggest--results",
200
- style: {
201
- top: curHeight
202
- }
203
- }, suggestList.map(function (item, index) {
204
- return _this.renderSuggestItem(item, index);
205
- }));
206
- }
207
-
208
- return null;
209
- };
210
-
211
- return _this;
212
- }
213
-
214
- _createClass(TextareaSuggest, [{
215
- key: "componentDidMount",
216
- value: function componentDidMount() {
217
- var _this2 = this;
218
-
219
- this.initialize = (0, _lodash.default)(function (el) {
220
- var className = _this2.props.className;
221
- var elem = document.getElementsByClassName(className)[0];
222
- _this2._textarea = elem;
223
- _this2._element = el;
224
- });
225
-
226
- if (this.props.searchMarker.length > 1) {
227
- throw new TypeError("Max length of searchMarker is 1 symbol. Please change your searchMarker to char");
228
- }
229
- }
230
- }, {
231
- key: "componentDidUpdate",
232
- value: function componentDidUpdate(prevProps, prevState, snapshot) {
233
- if (prevState.text !== this.props.value && prevProps.value !== this.props.value) {
234
- this.setState({
235
- text: this.props.value
236
- });
237
- }
238
- }
239
- }, {
240
- key: "render",
241
- value: function render() {
242
- var _this$props2 = this.props,
243
- autosizable = _this$props2.autosizable,
244
- value = _this$props2.value,
245
- props = _objectWithoutProperties(_this$props2, ["autosizable", "value"]);
246
-
247
- var searchResults = this.renderSearchResults();
248
- return _react.default.createElement("div", {
249
- className: "textarea-suggest"
250
- }, autosizable ? _react.default.createElement(_reactTextareaAutosize.default, _extends({}, props, {
251
- ref: this.initialize,
252
- onChange: this.onChange,
253
- value: this.state.text || value
254
- })) : _react.default.createElement("textarea", _extends({}, props, {
255
- ref: this.initialize,
256
- onChange: this.onChange,
257
- value: this.state.text || value
258
- })), searchResults);
259
- }
260
- }]);
261
-
262
- return TextareaSuggest;
263
- }(_react.default.Component), _class.propTypes = {
264
- autosizable: _propTypes.default.bool,
265
- className: _propTypes.default.string.isRequired,
266
- onChange: _propTypes.default.func.isRequired,
267
- onSearch: _propTypes.default.func.isRequired,
268
- onSuggestItemRender: _propTypes.default.func,
269
- searchMarker: _propTypes.default.string,
270
- searchRegexp: _propTypes.default.any,
271
- suggestList: _propTypes.default.array,
272
- value: _propTypes.default.string
273
- }, _temp);
1
+ Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("react-textarea-autosize");function a(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n=a(e),r=a(t),i=function(){return i=Object.assign||function(e){for(var t,a=1,n=arguments.length;a<n;a++)for(var r in t=arguments[a])Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e},i.apply(this,arguments)};function o(e,t){var a={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(a[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var r=0;for(n=Object.getOwnPropertySymbols(e);r<n.length;r++)t.indexOf(n[r])<0&&Object.prototype.propertyIsEnumerable.call(e,n[r])&&(a[n[r]]=e[n[r]])}return a}function c(t){var a=e.useRef();return e.useEffect((function(){a.current=t}),[t]),a.current}var l=e.forwardRef((function(e,t){return n.default.createElement("textarea",i({},e,{ref:t}))}));exports.default=function(t){var a=t.autosizable,s=void 0!==a&&a,u=t.value,d=void 0===u?"":u,m=t.searchMarker,f=void 0===m?"@":m,p=t.searchRegexp,g=t.suggestList,v=void 0===g?[]:g,b=t.onSearch,h=t.onChange,w=t.customSuggestItemRenderer,k=o(t,["autosizable","value","searchMarker","searchRegexp","suggestList","onSearch","onChange","customSuggestItemRenderer"]),y=e.useState(d),x=y[0],O=y[1],E=e.useState(null==d?void 0:d.includes(f)),z=E[0],j=E[1],R=c(x),_=c(d),S=e.useRef(null),M=s?r.default:l,q=e.useMemo((function(){return p?new RegExp(p):new RegExp("".concat(f,"([a-z0-9-_.]+[a-z0-9])"),"gim")}),[p]);e.useEffect((function(){if(f.length>1)throw new TypeError("Max length of searchMarker is 1 symbol. Please change your searchMarker to char")}),[]),e.useEffect((function(){R!==d&&_!==d&&O(d)}),[x,d,R,_]);var I=function(e){var t,a,n,r,i,o,c=null===(t=S.current)||void 0===t?void 0:t.selectionEnd,l=x.slice(0,c).lastIndexOf(f),s=x.slice(l);if(-1!==l){var u=(s.includes(" ")?s.indexOf(" "):x.length)+l,d=void 0;if(s.lastIndexOf(f)>0&&(u=s.lastIndexOf(f)+l),(!u||u<l)&&(u=x.length),d=x.slice(0,l||0)+x.slice(l).replace(x.slice(l,u),"".concat(f).concat(e," ")),S.current&&(S.current.value=d,S.current.focus()),o=!1,i=navigator.userAgent||navigator.vendor||"opera"in window&&window.opera,(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(i)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw-(n|u)|c55\/|capi|ccwa|cdm-|cell|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do(c|p)o|ds(12|-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(-|_)|g1 u|g560|gene|gf-5|g-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd-(m|p|t)|hei-|hi(pt|ta)|hp( i|ip)|hs-c|ht(c(-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac( |-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h-|oo|p-)|sdk\/|se(c(-|0|1)|47|mc|nd|ri)|sgh-|shar|sie(-|m)|sk-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel(i|m)|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-|your|zeto|zte-/i.test(i.substr(0,4)))&&(o=!0),o){var m=d.slice(l).indexOf(" ")+l+1;null===(a=S.current)||void 0===a||a.setSelectionRange(m,m)}var p=new Event("onchange",{bubbles:!0,cancelable:!1});null===(r=null===(n=S.current)||void 0===n?void 0:n.onchange)||void 0===r||r.call(n,p),j(!1),O(d)}},C=e.useCallback((function(e){var t=function(){return I(e)};return w?w(e,t):n.default.createElement("div",{className:"textarea-suggest-item",onClick:t},n.default.createElement("div",{className:"textarea-suggest-item__info"},n.default.createElement("div",null,e)))}),[I,w]),P=e.useMemo((function(){var t;if(z&&v&&v.length&&S.current){var a=null===(t=S.current)||void 0===t?void 0:t.getBoundingClientRect(),r=a.width,i=a.left;return n.default.createElement("div",{className:"textarea-suggest__results ".concat(k.className,"__results"),style:{position:"absolute",width:r,left:i}},v.map((function(t,a){return n.default.createElement(e.Fragment,{key:t&&"object"==typeof t&&"id"in t?t.id:a},C(t))})))}return null}),[z,v,S]);return n.default.createElement("div",{className:"textarea-suggest"},n.default.createElement(M,i({},k,{ref:S,onChange:function(e){var t,a=o(e,[]),n=a.currentTarget,r=void 0===n?{}:n,c=a.isTrusted,l=void 0===c||c,s=r.value,u=void 0===s?x:s,d=null===(t=S.current)||void 0===t?void 0:t.selectionEnd,m=d?u.slice(d-1,d):u.slice(-1);if(O(u),m===f&&j(!0),u.includes(f)&&![" ","\n","\r"].includes(m)||!z||j(!1),m!==f&&z){var p=u.slice(0,d),g=p.slice(p.lastIndexOf(f)).match(q),v=g?g[0].slice(1):m;b(v)}return l?null==h?void 0:h(a):null==h?void 0:h(i(i({},a),{currentTarget:S.current,target:S.current}))},value:x||d})),P)};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
package/lib/styles.css ADDED
@@ -0,0 +1,39 @@
1
+ .textarea-suggest {
2
+ resize: none;
3
+ }
4
+ .textarea-suggest__results {
5
+ position: absolute;
6
+ z-index: 150;
7
+ min-width: 220px;
8
+ margin: 0 16px;
9
+ animation: ascent 0.2s forwards;
10
+ border-radius: 9px;
11
+ background-color: #fff;
12
+ box-shadow: 0 3px 12px #c1c1c1;
13
+ }
14
+ .textarea-suggest__info {
15
+ position: absolute;
16
+ bottom: 8px;
17
+ right: 8px;
18
+ }
19
+ .textarea-suggest__info-item {
20
+ line-height: 20px;
21
+ margin: 16px 0;
22
+ }
23
+ .textarea-suggest-item {
24
+ display: flex;
25
+ padding: 4px 8px 0;
26
+ }
27
+ .textarea-suggest-item:first-child {
28
+ padding-top: 8px;
29
+ }
30
+ .textarea-suggest-item:last-child {
31
+ padding-bottom: 8px;
32
+ }
33
+ .textarea-suggest-item:hover {
34
+ background-color: #f2f3f9;
35
+ }
36
+ .textarea-suggest-item--info {
37
+ margin-left: 8px;
38
+ }
39
+
package/lib/utils.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export type Nullable<T> = T | null;
2
+ export declare function usePrevious<T>(value: T): T | undefined;
3
+ export declare function isMobileAndTabletCheck(): boolean;
package/package.json CHANGED
@@ -1,18 +1,23 @@
1
1
  {
2
2
  "name": "react-textarea-with-suggest",
3
- "version": "1.1.2",
3
+ "version": "2.0.0",
4
4
  "description": "Textarea with suggest for React app",
5
5
  "main": "lib/index.js",
6
+ "types": "lib/index.d.ts",
6
7
  "dependencies": {
7
- "lodash.once": "^4.1.1",
8
- "prop-types": "^15.7.2",
9
- "react": "^16.8.6",
10
- "react-dom": "^16.8.6",
11
- "react-scripts": "3.0.1",
12
- "react-textarea-autosize": "^7.1.0"
8
+ "react-scripts": "^5.0.1",
9
+ "react-textarea-autosize": "^8.4.0"
13
10
  },
11
+ "files": [
12
+ "lib",
13
+ "example"
14
+ ],
14
15
  "scripts": {
15
- "build": "babel src -d lib"
16
+ "prettier": "prettier --write .",
17
+ "build:debug": "npm install && npm run build && rm -rf node_modules",
18
+ "build": "rollup -c",
19
+ "start": "rollup -c -w",
20
+ "build:old": "npm run prettier && babel --extensions .tsx ./src -d ./lib --source-maps && cp ./src/index.d.ts ./lib"
16
21
  },
17
22
  "license": "MIT",
18
23
  "eslintConfig": {
@@ -29,7 +34,7 @@
29
34
  "react",
30
35
  "react-component"
31
36
  ],
32
- "author": "Maria Lobareva",
37
+ "author": "Mariia Lobareva",
33
38
  "bugs": {
34
39
  "url": "https://github.com/marylorian/react-textarea-with-suggest/issues"
35
40
  },
@@ -49,7 +54,8 @@
49
54
  "babel": {
50
55
  "presets": [
51
56
  "@babel/preset-env",
52
- "@babel/preset-react"
57
+ "@babel/preset-react",
58
+ "@babel/preset-typescript"
53
59
  ],
54
60
  "plugins": [
55
61
  [
@@ -60,18 +66,33 @@
60
66
  ]
61
67
  ]
62
68
  },
69
+ "peerDependencies": {
70
+ "react": "^17.0.0 || ^18.2.0",
71
+ "react-dom": "^17.0.0 || ^18.2.0"
72
+ },
63
73
  "devDependencies": {
64
74
  "@babel/cli": "^7.5.5",
65
75
  "@babel/core": "^7.0.0-0",
66
76
  "@babel/plugin-proposal-class-properties": "^7.5.5",
67
77
  "@babel/preset-env": "^7.5.5",
68
78
  "@babel/preset-react": "^7.0.0",
79
+ "@babel/preset-typescript": "^7.18.6",
80
+ "@rollup/plugin-babel": "^6.0.3",
81
+ "@rollup/plugin-terser": "^0.2.1",
82
+ "@rollup/plugin-typescript": "^10.0.1",
83
+ "@types/lodash.once": "^4.1.7",
84
+ "@types/react": "^18.0.26",
85
+ "babel-core": "^6.26.3",
69
86
  "babel-loader": "^8.0.6",
70
- "css-loader": "^3.1.0",
71
- "uglifyjs-webpack-plugin": "^2.2.0",
72
- "webpack": "^4.39.1",
73
- "webpack-cli": "^3.3.6",
74
- "webpack-dev-server": "^3.7.2",
87
+ "css-loader": "^6.7.3",
88
+ "prettier": "2.7.1",
89
+ "rollup": "^2.79.1",
90
+ "rollup-plugin-css-only": "^4.3.0",
91
+ "terser": "^5.16.1",
92
+ "typescript": "^4.9.4",
93
+ "webpack": "^5.75.0",
94
+ "webpack-cli": "^5.0.1",
95
+ "webpack-dev-server": "^4.11.1",
75
96
  "webpack-merge": "^4.2.1"
76
97
  }
77
98
  }
package/src/index.js DELETED
@@ -1,213 +0,0 @@
1
- /** React textarea with suggest v1.0.0
2
- *
3
- *
4
- * Copyright (c) 2019-present,
5
- * by Maria Lobareva (marialobareva97@gmail.com).
6
- *
7
- * LICENSE MIT.
8
- */
9
- import React from 'react';
10
- import PropTypes from 'prop-types';
11
- import once from "lodash.once";
12
- import TextareaAutosize from "react-textarea-autosize";
13
- import "../styles.css";
14
-
15
- module.exports = class TextareaSuggest extends React.Component {
16
- _textarea = null;
17
- _element = null;
18
-
19
- state = {
20
- needStartSearch: this.props.value && this.props.value.includes(this.props.searchMarker),
21
- text: this.props.value || ""
22
- };
23
-
24
- static propTypes = {
25
- autosizable: PropTypes.bool,
26
- className: PropTypes.string.isRequired,
27
- onChange: PropTypes.func.isRequired,
28
- onSearch: PropTypes.func.isRequired,
29
- onSuggestItemRender: PropTypes.func,
30
- searchMarker: PropTypes.string,
31
- searchRegexp: PropTypes.any,
32
- suggestList: PropTypes.array,
33
- value: PropTypes.string
34
- };
35
-
36
- defaultProps = {
37
- autosizable: false,
38
- searchMarker: "@",
39
- searchRegexp: /@([a-z0\d\-.]+[a-z\d])/gim,
40
- suggestList: []
41
- };
42
-
43
- componentDidMount() {
44
- this.initialize = once(el => {
45
- const {className} = this.props;
46
- const elem = document.getElementsByClassName(className)[0];
47
- this._textarea = elem;
48
- this._element = el;
49
- });
50
-
51
- if (this.props.searchMarker.length > 1) {
52
- throw new TypeError("Max length of searchMarker is 1 symbol. Please change your searchMarker to char");
53
- }
54
- }
55
-
56
- componentDidUpdate(prevProps, prevState, snapshot) {
57
- if (
58
- prevState.text !== this.props.value &&
59
- prevProps.value !== this.props.value
60
- ) {
61
- this.setState({ text: this.props.value });
62
- }
63
- }
64
-
65
- _mobileAndTabletCheck = () => {
66
- let check = false;
67
- (function (a) {
68
- if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw-(n|u)|c55\/|capi|ccwa|cdm-|cell|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do(c|p)o|ds(12|-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(-|_)|g1 u|g560|gene|gf-5|g-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd-(m|p|t)|hei-|hi(pt|ta)|hp( i|ip)|hs-c|ht(c(-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac( |-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h-|oo|p-)|sdk\/|se(c(-|0|1)|47|mc|nd|ri)|sgh-|shar|sie(-|m)|sk-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel(i|m)|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-|your|zeto|zte-/i.test(a.substr(0, 4))) check = true;
69
- })(navigator.userAgent || navigator.vendor || window.opera);
70
- return check;
71
- };
72
-
73
- onChange = ({...args}) => {
74
- const {searchMarker, searchRegexp} = this.props;
75
- const {needStartSearch} = this.state;
76
- const {currentTarget = {}, isTrusted = true} = args;
77
- const {value = this.state.text} = currentTarget;
78
- let selectionEnd = this._textarea.selectionEnd;
79
- let last = selectionEnd
80
- ? value.slice(selectionEnd - 1, selectionEnd)
81
- : value.slice(-1);
82
-
83
- this.setState({text: value});
84
-
85
- if (last === searchMarker) {
86
- this.setState({needStartSearch: true});
87
- //TODO: clear suggestList here
88
- }
89
-
90
- if (!value.includes(searchMarker) && needStartSearch) {
91
- this.setState({needStartSearch: false});
92
- }
93
-
94
- if (last !== searchMarker && needStartSearch) {
95
- let textWithResults = value.slice(0, selectionEnd);
96
- let results = textWithResults
97
- .slice(textWithResults.lastIndexOf(searchMarker)).match(new RegExp(searchRegexp));
98
- let result = results ? results[0].slice(1) : last;
99
-
100
- this.props.onSearch(result);
101
- }
102
-
103
- if (isTrusted) return this.props.onChange(args);
104
- return this.props.onChange({
105
- ...args,
106
- currentTarget: this._textarea,
107
- target: this._textarea
108
- });
109
- };
110
-
111
- setResult = (result) => {
112
- const {searchMarker} = this.props;
113
- const {text: currentText} = this.state;
114
- let selectionEnd = this._textarea.selectionEnd;
115
- let position = currentText.slice(0, selectionEnd).lastIndexOf(searchMarker);
116
- let textWithResult = currentText.slice(position);
117
-
118
- if (position !== -1) {
119
- let endPosition =
120
- (textWithResult.includes(" ")
121
- ? textWithResult.indexOf(" ")
122
- : currentText.length) + position;
123
- let newValue;
124
-
125
- if (textWithResult.lastIndexOf(searchMarker) > 0) {
126
- endPosition = textWithResult.lastIndexOf(searchMarker) + position;
127
- }
128
- if (!endPosition || endPosition < position) {
129
- endPosition = currentText.length;
130
- }
131
-
132
- newValue =
133
- currentText.slice(0, position || 0) +
134
- currentText
135
- .slice(position)
136
- .replace(currentText.slice(position, endPosition), `${searchMarker}${result} `);
137
-
138
- this._textarea.value = newValue;
139
- this._textarea.focus();
140
-
141
- if (this._mobileAndTabletCheck()) {
142
- let endCaretPosition =
143
- newValue.slice(position).indexOf(" ") + position + 1;
144
- this._textarea.setSelectionRange(endCaretPosition, endCaretPosition);
145
- }
146
-
147
- let event = new Event("onchange", {
148
- bubbles: true,
149
- cancelable: false
150
- });
151
- this._element._onChange(event);
152
-
153
- this.setState({needStartSearch: false, text: newValue});
154
- }
155
- };
156
-
157
- renderSuggestItem = (item, index) => {
158
- if (this.props.onSuggestItemRender) return this.props.onSuggestItemRender(item);
159
- return (
160
- <div
161
- key={index}
162
- className="textarea-suggest-item"
163
- onClick={() => this.setResult(item)}
164
- >
165
- <div className="textarea-suggest-item--info">
166
- <div>{item}</div>
167
- </div>
168
- </div>
169
- );
170
- };
171
-
172
- renderSearchResults = () => {
173
- const {suggestList} = this.props;
174
-
175
- if (this.state.needStartSearch && suggestList && suggestList.length && this._textare) {
176
- let curHeight = this._textarea.getBoundingClientRect().height;
177
-
178
- return (
179
- <div className="textarea-suggest--results" style={{top: curHeight}}>
180
- {suggestList.map((item, index) => {
181
- return this.renderSuggestItem(item, index);
182
- })}
183
- </div>
184
- );
185
- }
186
- return null;
187
- };
188
-
189
- render() {
190
- const {autosizable, value, ...props} = this.props;
191
- const searchResults = this.renderSearchResults();
192
-
193
- return (
194
- <div className="textarea-suggest">
195
- {autosizable
196
- ? (<TextareaAutosize
197
- {...props}
198
- ref={this.initialize}
199
- onChange={this.onChange}
200
- value={this.state.text || value}
201
- />)
202
- : (<textarea
203
- {...props}
204
- ref={this.initialize}
205
- onChange={this.onChange}
206
- value={this.state.text || value}
207
- />)
208
- }
209
- {searchResults}
210
- </div>
211
- );
212
- }
213
- };
package/styles.css DELETED
@@ -1,29 +0,0 @@
1
- .textarea-suggest {
2
- resize: none; }
3
- .textarea-suggest--results {
4
- position: absolute;
5
- z-index: 150;
6
- min-width: 220px;
7
- margin: 0 16px;
8
- animation: ascent .2s forwards;
9
- border-radius: 9px;
10
- background-color: #fff;
11
- box-shadow: 0 3px 12px #c1c1c1; }
12
- .textarea-suggest--info {
13
- position: absolute;
14
- bottom: 8px;
15
- right: 8px; }
16
- .textarea-suggest--info-item {
17
- line-height: 20px;
18
- margin: 16px 0; }
19
- .textarea-suggest-item {
20
- display: flex;
21
- padding: 4px 8px 0; }
22
- .textarea-suggest-item:first-child {
23
- padding-top: 8px; }
24
- .textarea-suggest-item:last-child {
25
- padding-bottom: 8px; }
26
- .textarea-suggest-item:hover {
27
- background-color: #f2f3f9; }
28
- .textarea-suggest-item--info {
29
- margin-left: 8px; }