Skip to content

Commit 306a93b

Browse files
authored
feat: support autoSize(#17746) (#27)
* ✨ replace textarea with rc-textarea to support autoSize * 🐛 fix setTextAreaRef null
1 parent 6a2191b commit 306a93b

4 files changed

Lines changed: 27 additions & 37 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ React.render(<Demo />, container);
8282
| onFocus | Trigger when mentions get focus | React.FocusEventHandler<HTMLTextAreaElement> | - |
8383
| onBlur | Trigger when mentions lose focus | React.FocusEventHandler<HTMLTextAreaElement> | - |
8484
| getPopupContainer | DOM Container for suggestions | () => HTMLElement | - |
85+
| autoSize | Textarea height autosize feature, can be set to `true\|false` or an object `{ minRows: 2, maxRows: 6 }` | boolean \| object | - |
86+
| onPressEnter | The callback function that is triggered when Enter key is pressed | function(e) | - |
87+
| onResize | The callback function that is triggered when textarea resize | function({ width, height }) | - |
8588

8689
### Methods
8790

examples/textarea.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ export default () => (
2121
<Option value="cat">Cat</Option>
2222
</Mentions>
2323

24+
<div style={{ paddingTop: 100 }}>
25+
<Mentions placeholder="Support AutoSize" autoSize transitionName="motion-zoom">
26+
<Option value="light">Light</Option>
27+
<Option value="bamboo">Bamboo</Option>
28+
<Option value="cat">Cat</Option>
29+
</Mentions>
30+
</div>
31+
2432
<div style={{ paddingTop: 100 }}>
2533
<Mentions placeholder="placement: top" placement="top" transitionName="motion-zoom">
2634
<Option value="light">Light</Option>

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
"@babel/runtime": "^7.10.1",
5959
"classnames": "^2.2.6",
6060
"rc-menu": "^8.0.1",
61+
"rc-textarea": "^0.2.0",
6162
"rc-trigger": "^4.3.0",
6263
"rc-util": "^5.0.1"
6364
}

src/Mentions.tsx

Lines changed: 15 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import classNames from 'classnames';
22
import toArray from 'rc-util/lib/Children/toArray';
33
import KeyCode from 'rc-util/lib/KeyCode';
44
import * as React from 'react';
5+
import TextArea, { TextAreaProps } from 'rc-textarea';
56
import KeywordTrigger from './KeywordTrigger';
67
import { MentionsContextProvider } from './MentionsContext';
78
import Option, { OptionProps } from './Option';
@@ -16,10 +17,7 @@ import {
1617
validateSearch as defaultValidateSearch,
1718
} from './util';
1819

19-
type BaseTextareaAttrs = Omit<
20-
React.TextareaHTMLAttributes<HTMLTextAreaElement>,
21-
'prefix' | 'onChange' | 'onSelect'
22-
>;
20+
type BaseTextareaAttrs = Omit<TextAreaProps, 'prefix' | 'onChange' | 'onSelect'>;
2321

2422
export type Placement = 'top' | 'bottom';
2523
export type Direction = 'ltr' | 'rtl';
@@ -74,10 +72,7 @@ class Mentions extends React.Component<MentionsProps, MentionsState> {
7472
rows: 1,
7573
};
7674

77-
public static getDerivedStateFromProps(
78-
props: MentionsProps,
79-
prevState: MentionsState,
80-
) {
75+
public static getDerivedStateFromProps(props: MentionsProps, prevState: MentionsState) {
8176
const newState: Partial<MentionsState> = {};
8277

8378
if ('value' in props && props.value !== prevState.value) {
@@ -120,9 +115,7 @@ class Mentions extends React.Component<MentionsProps, MentionsState> {
120115
}
121116
};
122117

123-
public onChange: React.ChangeEventHandler<HTMLTextAreaElement> = ({
124-
target: { value },
125-
}) => {
118+
public onChange: React.ChangeEventHandler<HTMLTextAreaElement> = ({ target: { value } }) => {
126119
this.triggerChange(value);
127120
};
128121

@@ -173,23 +166,18 @@ class Mentions extends React.Component<MentionsProps, MentionsState> {
173166
const { prefix = '', onSearch, validateSearch } = this.props;
174167
const target = event.target as HTMLTextAreaElement;
175168
const selectionStartText = getBeforeSelectionText(target);
176-
const {
177-
location: measureIndex,
178-
prefix: measurePrefix,
179-
} = getLastMeasureIndex(selectionStartText, prefix);
169+
const { location: measureIndex, prefix: measurePrefix } = getLastMeasureIndex(
170+
selectionStartText,
171+
prefix,
172+
);
180173

181174
// Skip if match the white key list
182-
if (
183-
[KeyCode.ESC, KeyCode.UP, KeyCode.DOWN, KeyCode.ENTER].indexOf(which) !==
184-
-1
185-
) {
175+
if ([KeyCode.ESC, KeyCode.UP, KeyCode.DOWN, KeyCode.ENTER].indexOf(which) !== -1) {
186176
return;
187177
}
188178

189179
if (measureIndex !== -1) {
190-
const measureText = selectionStartText.slice(
191-
measureIndex + measurePrefix.length,
192-
);
180+
const measureText = selectionStartText.slice(measureIndex + measurePrefix.length);
193181
const validateMeasure: boolean = validateSearch(measureText, this.props);
194182
const matchOption = !!this.getOptions(measureText).length;
195183

@@ -284,8 +272,8 @@ class Mentions extends React.Component<MentionsProps, MentionsState> {
284272
});
285273
};
286274

287-
public setTextAreaRef = (element: HTMLTextAreaElement) => {
288-
this.textarea = element;
275+
public setTextAreaRef = (element: TextArea) => {
276+
this.textarea = element?.resizableTextArea?.textArea;
289277
};
290278

291279
public setMeasureRef = (element: HTMLDivElement) => {
@@ -307,11 +295,7 @@ class Mentions extends React.Component<MentionsProps, MentionsState> {
307295
return list;
308296
};
309297

310-
public startMeasure(
311-
measureText: string,
312-
measurePrefix: string,
313-
measureLocation: number,
314-
) {
298+
public startMeasure(measureText: string, measurePrefix: string, measureLocation: number) {
315299
this.setState({
316300
measuring: true,
317301
measureText,
@@ -341,13 +325,7 @@ class Mentions extends React.Component<MentionsProps, MentionsState> {
341325
}
342326

343327
public render() {
344-
const {
345-
value,
346-
measureLocation,
347-
measurePrefix,
348-
measuring,
349-
activeIndex,
350-
} = this.state;
328+
const { value, measureLocation, measurePrefix, measuring, activeIndex } = this.state;
351329
const {
352330
prefixCls,
353331
placement,
@@ -378,7 +356,7 @@ class Mentions extends React.Component<MentionsProps, MentionsState> {
378356

379357
return (
380358
<div className={classNames(prefixCls, className)} style={style}>
381-
<textarea
359+
<TextArea
382360
autoFocus={autoFocus}
383361
ref={this.setTextAreaRef}
384362
value={value}

0 commit comments

Comments
 (0)