Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ React.render(<Demo />, container);
| onFocus | Trigger when mentions get focus | React.FocusEventHandler<HTMLTextAreaElement> | - |
| onBlur | Trigger when mentions lose focus | React.FocusEventHandler<HTMLTextAreaElement> | - |
| getPopupContainer | DOM Container for suggestions | () => HTMLElement | - |
| autoSize | Textarea height autosize feature, can be set to `true\|false` or an object `{ minRows: 2, maxRows: 6 }` | boolean \| object | - |
| onPressEnter | The callback function that is triggered when Enter key is pressed | function(e) | - |
| onResize | The callback function that is triggered when textarea resize | function({ width, height }) | - |

### Methods

Expand Down
8 changes: 8 additions & 0 deletions examples/textarea.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ export default () => (
<Option value="cat">Cat</Option>
</Mentions>

<div style={{ paddingTop: 100 }}>
<Mentions placeholder="Support AutoSize" autoSize transitionName="motion-zoom">
<Option value="light">Light</Option>
<Option value="bamboo">Bamboo</Option>
<Option value="cat">Cat</Option>
</Mentions>
</div>

<div style={{ paddingTop: 100 }}>
<Mentions placeholder="placement: top" placement="top" transitionName="motion-zoom">
<Option value="light">Light</Option>
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.6",
"rc-menu": "^8.0.1",
"rc-textarea": "^0.2.0",
"rc-trigger": "^4.3.0",
"rc-util": "^5.0.1"
}
Expand Down
52 changes: 15 additions & 37 deletions src/Mentions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import classNames from 'classnames';
import toArray from 'rc-util/lib/Children/toArray';
import KeyCode from 'rc-util/lib/KeyCode';
import * as React from 'react';
import TextArea, { TextAreaProps } from 'rc-textarea';
import KeywordTrigger from './KeywordTrigger';
import { MentionsContextProvider } from './MentionsContext';
import Option, { OptionProps } from './Option';
Expand All @@ -16,10 +17,7 @@ import {
validateSearch as defaultValidateSearch,
} from './util';

type BaseTextareaAttrs = Omit<
React.TextareaHTMLAttributes<HTMLTextAreaElement>,
'prefix' | 'onChange' | 'onSelect'
>;
type BaseTextareaAttrs = Omit<TextAreaProps, 'prefix' | 'onChange' | 'onSelect'>;

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

public static getDerivedStateFromProps(
props: MentionsProps,
prevState: MentionsState,
) {
public static getDerivedStateFromProps(props: MentionsProps, prevState: MentionsState) {
const newState: Partial<MentionsState> = {};

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

public onChange: React.ChangeEventHandler<HTMLTextAreaElement> = ({
target: { value },
}) => {
public onChange: React.ChangeEventHandler<HTMLTextAreaElement> = ({ target: { value } }) => {
this.triggerChange(value);
};

Expand Down Expand Up @@ -173,23 +166,18 @@ class Mentions extends React.Component<MentionsProps, MentionsState> {
const { prefix = '', onSearch, validateSearch } = this.props;
const target = event.target as HTMLTextAreaElement;
const selectionStartText = getBeforeSelectionText(target);
const {
location: measureIndex,
prefix: measurePrefix,
} = getLastMeasureIndex(selectionStartText, prefix);
const { location: measureIndex, prefix: measurePrefix } = getLastMeasureIndex(
selectionStartText,
prefix,
);

// Skip if match the white key list
if (
[KeyCode.ESC, KeyCode.UP, KeyCode.DOWN, KeyCode.ENTER].indexOf(which) !==
-1
) {
if ([KeyCode.ESC, KeyCode.UP, KeyCode.DOWN, KeyCode.ENTER].indexOf(which) !== -1) {
return;
}

if (measureIndex !== -1) {
const measureText = selectionStartText.slice(
measureIndex + measurePrefix.length,
);
const measureText = selectionStartText.slice(measureIndex + measurePrefix.length);
const validateMeasure: boolean = validateSearch(measureText, this.props);
const matchOption = !!this.getOptions(measureText).length;

Expand Down Expand Up @@ -284,8 +272,8 @@ class Mentions extends React.Component<MentionsProps, MentionsState> {
});
};

public setTextAreaRef = (element: HTMLTextAreaElement) => {
this.textarea = element;
public setTextAreaRef = (element: TextArea) => {
this.textarea = element?.resizableTextArea?.textArea;
};

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

public startMeasure(
measureText: string,
measurePrefix: string,
measureLocation: number,
) {
public startMeasure(measureText: string, measurePrefix: string, measureLocation: number) {
this.setState({
measuring: true,
measureText,
Expand Down Expand Up @@ -341,13 +325,7 @@ class Mentions extends React.Component<MentionsProps, MentionsState> {
}

public render() {
const {
value,
measureLocation,
measurePrefix,
measuring,
activeIndex,
} = this.state;
const { value, measureLocation, measurePrefix, measuring, activeIndex } = this.state;
const {
prefixCls,
placement,
Expand Down Expand Up @@ -378,7 +356,7 @@ class Mentions extends React.Component<MentionsProps, MentionsState> {

return (
<div className={classNames(prefixCls, className)} style={style}>
<textarea
<TextArea
autoFocus={autoFocus}
ref={this.setTextAreaRef}
value={value}
Expand Down