From 0328701527967c925b928d5c41620807c230c212 Mon Sep 17 00:00:00 2001 From: scientihark Date: Fri, 16 Aug 2019 13:54:34 +0800 Subject: [PATCH 1/2] support click on mention to open dropdown --- examples/click.js | 43 ++++++++++++++++++++++++ src/Mentions.tsx | 84 +++++++++++++++++++++++++++-------------------- 2 files changed, 92 insertions(+), 35 deletions(-) create mode 100644 examples/click.js diff --git a/examples/click.js b/examples/click.js new file mode 100644 index 0000000..07f129e --- /dev/null +++ b/examples/click.js @@ -0,0 +1,43 @@ +/* eslint no-console: 0 */ + +import React from 'react'; +import Mentions from '../src'; +import '../assets/index.less'; + +const { Option } = Mentions; + +class Demo extends React.Component { + onSelect = (option, prefix) => { + console.log('Select:', prefix, '-', option.value); + }; + + onFocus = () => { + console.log('onFocus'); + }; + + onBlur = () => { + console.log('onBlur'); + }; + + render() { + return ( +
+ + + + + +
+ ); + } +} + +export default Demo; diff --git a/src/Mentions.tsx b/src/Mentions.tsx index 2c2b54c..51bec58 100644 --- a/src/Mentions.tsx +++ b/src/Mentions.tsx @@ -26,6 +26,7 @@ export type Placement = 'top' | 'bottom'; export interface MentionsProps extends BaseTextareaAttrs { autoFocus?: boolean; + enableClick?: boolean; className?: string; defaultValue?: string; notFoundContent?: React.ReactNode; @@ -149,20 +150,64 @@ class Mentions extends React.Component { } }; + public onKeyUp: React.KeyboardEventHandler = event => { + this.handleMeasure(event); + }; + + public onMouseSelect: React.MouseEventHandler = event => { + const { enableClick } = this.props; + if (enableClick) { + this.handleMeasure(event); + } + }; + + public onInputFocus: React.FocusEventHandler = event => { + this.onFocus(event); + }; + + public onInputBlur: React.FocusEventHandler = event => { + this.onBlur(event); + }; + + public onDropdownFocus = () => { + this.onFocus(); + }; + + public onFocus = (event?: React.FocusEvent) => { + window.clearTimeout(this.focusId); + const { isFocus } = this.state; + const { onFocus } = this.props; + if (!isFocus && event && onFocus) { + onFocus(event); + } + this.setState({ isFocus: true }); + }; + + public onBlur = (event: React.FocusEvent) => { + this.focusId = window.setTimeout(() => { + const { onBlur } = this.props; + this.setState({ isFocus: false }); + this.stopMeasure(); + if (onBlur) { + onBlur(event); + } + }, 0); + }; + /** * When to start measure: * 1. When user press `prefix` * 2. When measureText !== prevMeasureText * - If measure hit * - If measuring + * 3. When user click on mentions * * When to stop measure: * 1. Selection is out of range * 2. Contains `space` * 3. ESC or select one */ - public onKeyUp: React.KeyboardEventHandler = event => { - const { key, which } = event; + public handleMeasure = event => { const { measureText: prevMeasureText, measuring } = this.state; const { prefix = '', onSearch, validateSearch } = this.props; const target = event.target as HTMLTextAreaElement; @@ -171,6 +216,7 @@ class Mentions extends React.Component { selectionStartText, prefix, ); + const { key = measurePrefix, which } = event; // Skip if match the white key list if ([KeyCode.ESC, KeyCode.UP, KeyCode.DOWN, KeyCode.ENTER].indexOf(which) !== -1) { @@ -207,39 +253,6 @@ class Mentions extends React.Component { } }; - public onInputFocus: React.FocusEventHandler = event => { - this.onFocus(event); - }; - - public onInputBlur: React.FocusEventHandler = event => { - this.onBlur(event); - }; - - public onDropdownFocus = () => { - this.onFocus(); - }; - - public onFocus = (event?: React.FocusEvent) => { - window.clearTimeout(this.focusId); - const { isFocus } = this.state; - const { onFocus } = this.props; - if (!isFocus && event && onFocus) { - onFocus(event); - } - this.setState({ isFocus: true }); - }; - - public onBlur = (event: React.FocusEvent) => { - this.focusId = window.setTimeout(() => { - const { onBlur } = this.props; - this.setState({ isFocus: false }); - this.stopMeasure(); - if (onBlur) { - onBlur(event); - } - }, 0); - }; - public selectOption = (option: OptionProps) => { const { value, measureLocation, measurePrefix } = this.state; const { split, onSelect } = this.props; @@ -362,6 +375,7 @@ class Mentions extends React.Component { onKeyUp={this.onKeyUp} onFocus={this.onInputFocus} onBlur={this.onInputBlur} + onMouseUp={this.onMouseSelect} /> {measuring && (
From 155ee39976d55a00681d9f48a7a5bfdeb735d2c5 Mon Sep 17 00:00:00 2001 From: scientihark Date: Fri, 16 Aug 2019 14:09:08 +0800 Subject: [PATCH 2/2] add ReadMe entry for enableClick prop --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index dca154b..476a1a1 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ React.render(, container); | name | description | type | default | |----------|----------------|----------|--------------| | autoFocus | Auto get focus when component mounted | boolean | `false` | +| enableClick | Enable click on mention to open dropdown | boolean | `false` | | defaultValue | Default value | string | - | | filterOption | Customize filter option logic | false \| (input: string, option: OptionProps) => boolean | - | | notFoundContent | Set mentions content when not match | ReactNode | 'Not Found' |