mirror of
https://gitee.com/baidu/amis.git
synced 2024-12-02 03:58:07 +08:00
feat: Textarea/Editor/DiffEditor动作事件扩充
This commit is contained in:
parent
97c624ae48
commit
1d46d6a4c7
@ -11,6 +11,7 @@ export default {
|
||||
},
|
||||
{
|
||||
type: 'form',
|
||||
name: 'text-form',
|
||||
debug: true,
|
||||
api: '/api/mock2/form/saveForm',
|
||||
body: [
|
||||
@ -30,6 +31,11 @@ export default {
|
||||
actionType: 'clear',
|
||||
componentId: 'clear-receiver',
|
||||
description: '点击清空指定输入框的内容'
|
||||
},
|
||||
{
|
||||
actionType: 'toast',
|
||||
msgType: 'info',
|
||||
msg: '派发clear事件'
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -39,6 +45,7 @@ export default {
|
||||
name: 'clear-receiver',
|
||||
id: 'clear-receiver',
|
||||
type: 'input-text',
|
||||
clearable: true,
|
||||
label: 'clear动作测试',
|
||||
mode: 'row',
|
||||
value: 'chunk of text ready to be cleared.'
|
||||
@ -61,6 +68,11 @@ export default {
|
||||
actionType: 'focus',
|
||||
componentId: 'focus-receiver',
|
||||
description: '点击使指定输入框聚焦'
|
||||
},
|
||||
{
|
||||
actionType: 'toast',
|
||||
msgType: 'info',
|
||||
msg: '派发focus事件'
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -76,6 +88,191 @@ export default {
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'divider'
|
||||
},
|
||||
{
|
||||
type: 'tpl',
|
||||
tpl: 'Textarea 多行文本输入框',
|
||||
inline: false,
|
||||
wrapperComponent: 'h2'
|
||||
},
|
||||
{
|
||||
type: 'form',
|
||||
name: 'textarea-form',
|
||||
debug: true,
|
||||
api: '/api/mock2/form/saveForm',
|
||||
body: [
|
||||
{
|
||||
type: 'group',
|
||||
body: [
|
||||
{
|
||||
name: 'textarea-trigger1',
|
||||
id: 'textarea-trigger1',
|
||||
type: 'action',
|
||||
label: 'clear触发器',
|
||||
level: 'primary',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'clear',
|
||||
componentId: 'textarea-clear-receiver',
|
||||
description: '点击清空指定输入框的内容'
|
||||
},
|
||||
{
|
||||
actionType: 'toast',
|
||||
msgType: 'info',
|
||||
msg: '派发clear事件'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'textarea-clear-receiver',
|
||||
id: 'textarea-clear-receiver',
|
||||
type: 'textarea',
|
||||
clearable: true,
|
||||
label: 'clear动作测试',
|
||||
mode: 'row',
|
||||
value: 'chunk of text ready to be cleared.'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'group',
|
||||
body: [
|
||||
{
|
||||
name: 'textarea-trigger2',
|
||||
id: 'textarea-trigger2',
|
||||
type: 'action',
|
||||
label: 'focus触发器',
|
||||
level: 'primary',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'focus',
|
||||
componentId: 'textarea-focus-receiver',
|
||||
description: '点击使指定输入框聚焦'
|
||||
},
|
||||
{
|
||||
actionType: 'toast',
|
||||
msgType: 'info',
|
||||
msg: '派发focus事件'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'textarea-focus-receiver',
|
||||
id: 'textarea-focus-receiver',
|
||||
type: 'textarea',
|
||||
label: 'focus动作测试',
|
||||
mode: 'row'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'divider'
|
||||
},
|
||||
{
|
||||
type: 'tpl',
|
||||
tpl: 'Editor 编辑器',
|
||||
inline: false,
|
||||
wrapperComponent: 'h2'
|
||||
},
|
||||
{
|
||||
type: 'form',
|
||||
name: 'editor-form',
|
||||
debug: true,
|
||||
api: '/api/mock2/form/saveForm',
|
||||
body: [
|
||||
{
|
||||
type: 'group',
|
||||
mode: 'inline',
|
||||
body: [
|
||||
{
|
||||
name: 'editor-trigger2',
|
||||
id: 'editor-trigger2',
|
||||
type: 'action',
|
||||
label: '编辑器focus触发器',
|
||||
level: 'primary',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'focus',
|
||||
componentId: 'editor-focus-receiver',
|
||||
description: '点击使指定输入框聚焦'
|
||||
},
|
||||
{
|
||||
actionType: 'toast',
|
||||
msgType: 'info',
|
||||
msg: '派发focus事件'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'editor-focus-receiver',
|
||||
id: 'editor-focus-receiver',
|
||||
type: 'editor',
|
||||
language: 'javascript',
|
||||
label: '编辑器focus动作测试',
|
||||
value:
|
||||
"function HelloWorld() {\n console.log('Hello World');\n}",
|
||||
mode: 'row'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'group',
|
||||
mode: 'inline',
|
||||
body: [
|
||||
{
|
||||
name: 'diffeditor-trigger2',
|
||||
id: 'diffeditor-trigger2',
|
||||
type: 'action',
|
||||
label: '对比编辑器focus触发器',
|
||||
level: 'primary',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'focus',
|
||||
componentId: 'diffeditor-focus-receiver',
|
||||
description: '点击使指定输入框聚焦'
|
||||
},
|
||||
{
|
||||
actionType: 'toast',
|
||||
msgType: 'info',
|
||||
msg: '派发focus事件'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'diffeditor-focus-receiver',
|
||||
id: 'diffeditor-focus-receiver',
|
||||
type: 'diff-editor',
|
||||
label: '对比编辑器focus动作测试',
|
||||
diffValue:
|
||||
"function HelloWorld() {\n console.log('Hello World');\n}",
|
||||
value:
|
||||
"function HelloWorld() {\n console.log('Hello World!');\n}",
|
||||
mode: 'row'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
86
src/actions/Decorators.ts
Normal file
86
src/actions/Decorators.ts
Normal file
@ -0,0 +1,86 @@
|
||||
import {createObject} from '../utils/helper';
|
||||
|
||||
import type {ListenerAction} from './Action';
|
||||
import type {OptionsControlProps} from '../renderers/Form/Options';
|
||||
import type {FormControlProps} from '../renderers/Form/Item';
|
||||
import type {RendererEvent} from '../utils/renderer-event';
|
||||
|
||||
/**
|
||||
* 渲染器事件派发
|
||||
*
|
||||
* @param props 组件props
|
||||
* @param e 事件类型
|
||||
* @param ctx 上下文数据
|
||||
*/
|
||||
export async function rendererEventDispatcher<
|
||||
T extends FormControlProps,
|
||||
E = any
|
||||
>(
|
||||
props: T,
|
||||
e: E,
|
||||
ctx: Record<string, any> = {}
|
||||
): Promise<RendererEvent<any> | undefined> {
|
||||
const {dispatchEvent, data} = props;
|
||||
|
||||
return dispatchEvent(e, createObject(data, ctx));
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染器事件方法装饰器
|
||||
*
|
||||
* @param event 事件类型
|
||||
* @param ctx 上下文数据
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function bindRendererEvent<T extends FormControlProps, E = any>(
|
||||
event: E,
|
||||
ctx: Record<string, any> = {}
|
||||
) {
|
||||
return function (
|
||||
target: any,
|
||||
propertyKey: string,
|
||||
descriptor: TypedPropertyDescriptor<any>
|
||||
) {
|
||||
let fn =
|
||||
descriptor.value && typeof descriptor.value === 'function'
|
||||
? descriptor.value
|
||||
: typeof descriptor?.get === 'function'
|
||||
? descriptor.get()
|
||||
: null;
|
||||
|
||||
if (!fn || typeof fn !== 'function') {
|
||||
throw new Error(
|
||||
`decorator can only be applied to methods not: ${typeof fn}`
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
...descriptor,
|
||||
|
||||
value: async function boundFn(...params: any[]) {
|
||||
const triggerProps = (this as TypedPropertyDescriptor<any> & {props: T})
|
||||
?.props;
|
||||
let value = triggerProps?.value;
|
||||
|
||||
// clear清除内容事件
|
||||
if (typeof event === 'string' && event === 'clear') {
|
||||
value = triggerProps?.resetValue;
|
||||
}
|
||||
|
||||
const dispatcher = await rendererEventDispatcher<T>(
|
||||
triggerProps,
|
||||
event,
|
||||
{
|
||||
value
|
||||
}
|
||||
);
|
||||
|
||||
if (dispatcher?.prevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
return fn.apply(this, [...params]);
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
@ -17,5 +17,6 @@ import './DrawerAction';
|
||||
import './EmailAction';
|
||||
import './LinkAction';
|
||||
import './ToastAction';
|
||||
import './Decorators';
|
||||
|
||||
export * from './Action';
|
||||
|
@ -8,6 +8,10 @@ import {
|
||||
} from '../../utils/tpl-builtin';
|
||||
import {SchemaTokenizeableString} from '../../Schema';
|
||||
import {autobind} from '../../utils/helper';
|
||||
import {bindRendererEvent} from '../../actions/Decorators';
|
||||
|
||||
import type {Position} from 'monaco-editor';
|
||||
import type {ListenerAction} from '../../actions/Action';
|
||||
|
||||
/**
|
||||
* Diff 编辑器
|
||||
@ -35,6 +39,8 @@ export interface DiffControlSchema extends FormBaseControl {
|
||||
options?: any;
|
||||
}
|
||||
|
||||
export type DiffEditorRendererEvent = 'blur' | 'focus';
|
||||
|
||||
function loadComponent(): Promise<any> {
|
||||
return import('../../components/Editor').then(item => item.default);
|
||||
}
|
||||
@ -106,12 +112,31 @@ export class DiffEditor extends React.Component<DiffEditorProps, any> {
|
||||
this.toDispose.forEach(fn => fn());
|
||||
}
|
||||
|
||||
doAction(action: ListenerAction, args: any) {
|
||||
const actionType = action?.actionType as string;
|
||||
|
||||
if (actionType === 'focus') {
|
||||
this.focus();
|
||||
}
|
||||
}
|
||||
|
||||
focus() {
|
||||
this.editor.focus();
|
||||
this.setState({focused: true});
|
||||
|
||||
// 最近一次光标位置
|
||||
const position: Position | null = this.editor?.getPosition();
|
||||
this.editor?.setPosition(position);
|
||||
}
|
||||
|
||||
@bindRendererEvent<DiffEditorProps, DiffEditorRendererEvent>('focus')
|
||||
handleFocus() {
|
||||
this.setState({
|
||||
focused: true
|
||||
});
|
||||
}
|
||||
|
||||
@bindRendererEvent<DiffEditorProps, DiffEditorRendererEvent>('blur')
|
||||
handleBlur() {
|
||||
this.setState({
|
||||
focused: false
|
||||
|
@ -8,6 +8,10 @@ import {
|
||||
isPureVariable,
|
||||
resolveVariableAndFilter
|
||||
} from '../../utils/tpl-builtin';
|
||||
import {bindRendererEvent} from '../../actions/Decorators';
|
||||
|
||||
import type {Position} from 'monaco-editor';
|
||||
import type {ListenerAction} from '../../actions/Action';
|
||||
|
||||
/**
|
||||
* Editor 代码编辑器
|
||||
@ -110,6 +114,8 @@ export interface EditorControlSchema extends Omit<FormBaseControl, 'size'> {
|
||||
allowFullscreen?: boolean;
|
||||
}
|
||||
|
||||
export type EditorRendererEvent = 'blur' | 'focus';
|
||||
|
||||
export interface EditorProps extends FormControlProps {
|
||||
options?: object;
|
||||
}
|
||||
@ -148,12 +154,31 @@ export default class EditorControl extends React.Component<EditorProps, any> {
|
||||
this.toDispose.forEach(fn => fn());
|
||||
}
|
||||
|
||||
doAction(action: ListenerAction, args: any) {
|
||||
const actionType = action?.actionType as string;
|
||||
|
||||
if (actionType === 'focus') {
|
||||
this.focus();
|
||||
}
|
||||
}
|
||||
|
||||
focus() {
|
||||
this.editor.focus();
|
||||
this.setState({focused: true});
|
||||
|
||||
// 最近一次光标位置
|
||||
const position: Position | null = this.editor?.getPosition();
|
||||
this.editor?.setPosition(position);
|
||||
}
|
||||
|
||||
@bindRendererEvent<EditorProps, EditorRendererEvent>('focus')
|
||||
handleFocus() {
|
||||
this.setState({
|
||||
focused: true
|
||||
});
|
||||
}
|
||||
|
||||
@bindRendererEvent<EditorProps, EditorRendererEvent>('blur')
|
||||
handleBlur() {
|
||||
this.setState({
|
||||
focused: false
|
||||
|
@ -20,10 +20,12 @@ import {FormBaseControl} from './Item';
|
||||
import {ActionSchema} from '../Action';
|
||||
import {SchemaApi} from '../../Schema';
|
||||
import {generateIcon} from '../../utils/icon';
|
||||
import {
|
||||
rendererEventDispatcher,
|
||||
bindRendererEvent
|
||||
} from '../../actions/Decorators';
|
||||
|
||||
import type {Option} from '../../components/Select';
|
||||
import type {RendererEvent} from '../../utils/renderer-event';
|
||||
import type {IScopedContext} from '../../Scoped';
|
||||
import type {ListenerAction} from '../../actions/Action';
|
||||
|
||||
// declare function matchSorter(items:Array<any>, input:any, options:any): Array<any>;
|
||||
@ -86,6 +88,14 @@ export interface TextControlSchema extends FormOptionsControl {
|
||||
suffix?: string;
|
||||
}
|
||||
|
||||
export type InputTextRendererEvent =
|
||||
| 'blur'
|
||||
| 'focus'
|
||||
| 'click'
|
||||
| 'change'
|
||||
| 'clear'
|
||||
| 'enter';
|
||||
|
||||
export interface TextProps extends OptionsControlProps {
|
||||
placeholder?: string;
|
||||
addOn?: Action & {
|
||||
@ -112,71 +122,6 @@ export interface TextState {
|
||||
isFocused?: boolean;
|
||||
}
|
||||
|
||||
export type InputTextRendererEvent =
|
||||
| 'blur'
|
||||
| 'focus'
|
||||
| 'click'
|
||||
| 'change'
|
||||
| 'clear'
|
||||
| 'enter';
|
||||
|
||||
/**
|
||||
* 渲染器事件派发
|
||||
*/
|
||||
async function rendererEventDispatcher<T extends OptionsControlProps>(
|
||||
props: T,
|
||||
e: InputTextRendererEvent,
|
||||
ctx: Record<string, any> = {}
|
||||
): Promise<RendererEvent<any> | undefined> {
|
||||
const {dispatchEvent, data} = props;
|
||||
|
||||
return dispatchEvent(e, createObject(data, ctx));
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染器事件装饰器
|
||||
*
|
||||
* @param {InputTextRendererEvent} e 事件类型
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function bindRendererEvent<T extends OptionsControlProps, P = any>(
|
||||
e: InputTextRendererEvent,
|
||||
ctx: Record<string, any> = {}
|
||||
) {
|
||||
return function (
|
||||
target: any,
|
||||
propertyKey: string,
|
||||
descriptor: TypedPropertyDescriptor<any>
|
||||
) {
|
||||
let fn = descriptor.value;
|
||||
|
||||
if (!fn || typeof fn !== 'function') {
|
||||
throw new Error(
|
||||
`decorator can only be applied to methods not: ${typeof fn}`
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
...descriptor,
|
||||
|
||||
value: async function boundFn(...params: any[]) {
|
||||
const context = (this as TypedPropertyDescriptor<any> & {props: T})
|
||||
?.props;
|
||||
let value = e === 'clear' ? context?.resetValue : context?.value;
|
||||
const dispatcher = await rendererEventDispatcher<T>(context, e, {
|
||||
value
|
||||
});
|
||||
|
||||
if (dispatcher?.prevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
return fn.apply(this, [...params]);
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export default class TextControl extends React.PureComponent<
|
||||
TextProps,
|
||||
TextState
|
||||
@ -272,9 +217,6 @@ export default class TextControl extends React.PureComponent<
|
||||
this.input = ref;
|
||||
}
|
||||
|
||||
/**
|
||||
* 动作处理
|
||||
*/
|
||||
doAction(action: ListenerAction, args: any) {
|
||||
const actionType = action?.actionType as string;
|
||||
|
||||
@ -297,7 +239,7 @@ export default class TextControl extends React.PureComponent<
|
||||
len && this.input.setSelectionRange(len, len);
|
||||
}
|
||||
|
||||
@bindRendererEvent<TextProps>('clear')
|
||||
@bindRendererEvent<TextProps, InputTextRendererEvent>('clear')
|
||||
clearValue() {
|
||||
const {onChange, resetValue} = this.props;
|
||||
|
||||
@ -322,7 +264,7 @@ export default class TextControl extends React.PureComponent<
|
||||
onChange(this.normalizeValue(newValue));
|
||||
}
|
||||
|
||||
@bindRendererEvent<TextProps>('click')
|
||||
@bindRendererEvent<TextProps, InputTextRendererEvent>('click')
|
||||
handleClick() {
|
||||
this.focus();
|
||||
this.setState({
|
||||
@ -330,7 +272,7 @@ export default class TextControl extends React.PureComponent<
|
||||
});
|
||||
}
|
||||
|
||||
@bindRendererEvent<TextProps>('focus')
|
||||
@bindRendererEvent<TextProps, InputTextRendererEvent>('focus')
|
||||
handleFocus(e: any) {
|
||||
this.setState({
|
||||
isOpen: true,
|
||||
@ -340,7 +282,7 @@ export default class TextControl extends React.PureComponent<
|
||||
this.props.onFocus && this.props.onFocus(e);
|
||||
}
|
||||
|
||||
@bindRendererEvent<TextProps>('blur')
|
||||
@bindRendererEvent<TextProps, InputTextRendererEvent>('blur')
|
||||
handleBlur(e: any) {
|
||||
const {onBlur, trimContents, value, onChange} = this.props;
|
||||
|
||||
@ -415,11 +357,10 @@ export default class TextControl extends React.PureComponent<
|
||||
value = this.normalizeValue(newValue).concat();
|
||||
}
|
||||
|
||||
const dispatcher = await rendererEventDispatcher<TextProps>(
|
||||
this.props,
|
||||
'enter',
|
||||
{value}
|
||||
);
|
||||
const dispatcher = await rendererEventDispatcher<
|
||||
TextProps,
|
||||
InputTextRendererEvent
|
||||
>(this.props, 'enter', {value});
|
||||
|
||||
if (dispatcher?.prevented) {
|
||||
return;
|
||||
@ -513,11 +454,10 @@ export default class TextControl extends React.PureComponent<
|
||||
async handleNormalInputChange(e: React.ChangeEvent<HTMLInputElement>) {
|
||||
const {onChange} = this.props;
|
||||
let value = e.currentTarget.value;
|
||||
const dispatcher = await rendererEventDispatcher<TextProps>(
|
||||
this.props,
|
||||
'change',
|
||||
{value: this.transformValue(value)}
|
||||
);
|
||||
const dispatcher = await rendererEventDispatcher<
|
||||
TextProps,
|
||||
InputTextRendererEvent
|
||||
>(this.props, 'change', {value: this.transformValue(value)});
|
||||
|
||||
if (dispatcher?.prevented) {
|
||||
return;
|
||||
|
@ -5,6 +5,10 @@ import Textarea from '../../components/Textarea';
|
||||
import {Icon} from '../../components/icons';
|
||||
import {findDOMNode} from 'react-dom';
|
||||
import {autobind, ucFirst} from '../../utils/helper';
|
||||
|
||||
import {bindRendererEvent} from '../../actions/Decorators';
|
||||
import type {ListenerAction} from '../../actions/Action';
|
||||
|
||||
/**
|
||||
* TextArea 多行文本输入框。
|
||||
* 文档:https://baidu.gitee.io/amis/docs/components/form/textarea
|
||||
@ -56,6 +60,8 @@ export interface TextareaControlSchema extends FormBaseControl {
|
||||
resetValue?: string;
|
||||
}
|
||||
|
||||
export type TextAreaRendererEvent = 'blur' | 'focus' | 'clear';
|
||||
|
||||
export interface TextAreaProps extends FormControlProps {
|
||||
placeholder?: string;
|
||||
minRows?: number;
|
||||
@ -64,9 +70,13 @@ export interface TextAreaProps extends FormControlProps {
|
||||
resetValue?: string;
|
||||
}
|
||||
|
||||
export interface TextAreaState {
|
||||
focused: boolean;
|
||||
}
|
||||
|
||||
export default class TextAreaControl extends React.Component<
|
||||
TextAreaProps,
|
||||
{focused: boolean}
|
||||
TextAreaState
|
||||
> {
|
||||
static defaultProps: Partial<TextAreaProps> = {
|
||||
minRows: 3,
|
||||
@ -83,6 +93,16 @@ export default class TextAreaControl extends React.Component<
|
||||
input?: HTMLInputElement;
|
||||
inputRef = (ref: any) => (this.input = findDOMNode(ref) as HTMLInputElement);
|
||||
|
||||
doAction(action: ListenerAction, args: any) {
|
||||
const actionType = action?.actionType as string;
|
||||
|
||||
if (!!~['clear', 'reset'].indexOf(actionType)) {
|
||||
this.handleClear();
|
||||
} else if (actionType === 'focus') {
|
||||
this.focus();
|
||||
}
|
||||
}
|
||||
|
||||
valueToString(value: any) {
|
||||
return typeof value === 'undefined' || value === null
|
||||
? ''
|
||||
@ -115,15 +135,15 @@ export default class TextAreaControl extends React.Component<
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleChange(e: React.ChangeEvent<any>) {
|
||||
handleChange(e: React.ChangeEvent<HTMLTextAreaElement>) {
|
||||
const {onChange} = this.props;
|
||||
|
||||
let value = e.currentTarget.value;
|
||||
|
||||
onChange(value);
|
||||
onChange?.(value);
|
||||
}
|
||||
|
||||
@autobind
|
||||
@bindRendererEvent<TextAreaProps, TextAreaRendererEvent>('focus')
|
||||
handleFocus(e: React.FocusEvent<HTMLTextAreaElement>) {
|
||||
const {onFocus} = this.props;
|
||||
|
||||
@ -138,6 +158,7 @@ export default class TextAreaControl extends React.Component<
|
||||
}
|
||||
|
||||
@autobind
|
||||
@bindRendererEvent<TextAreaProps, TextAreaRendererEvent>('blur')
|
||||
handleBlur(e: React.FocusEvent<HTMLTextAreaElement>) {
|
||||
const {onBlur, trimContents, value, onChange} = this.props;
|
||||
|
||||
@ -156,7 +177,8 @@ export default class TextAreaControl extends React.Component<
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleClear() {
|
||||
@bindRendererEvent<TextAreaProps, TextAreaRendererEvent>('clear')
|
||||
async handleClear() {
|
||||
const {onChange, resetValue} = this.props;
|
||||
|
||||
onChange?.(resetValue);
|
||||
|
Loading…
Reference in New Issue
Block a user