Interactive Input
解决了什么问题?
- 通过 onChage 时时更新当前 input 框中的状态,包括内容,和光标位置,使用方法就像 controlled form,只不过信息更全
- 在光标出现的位置弹出指定的组件,通过 onSelect Prop 获取组件操作的结果,最终可以实现像 Weibo 那样的@人的功能
使用方法
npm install italent-interactive-input
import React, { Component } from "react";
import InteractiveInput from "../../src/";
import Notify from "./notify";
import styled from "styled-components";
const H2 = styled.h2`
font-size: 12px;
font-weight: normal;
font: 14px/24px "Helvetica Neue", Tahoma, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
STHeitiSC, sans-serif;
`;
export default class extends Component {
constructor() {
super(...arguments);
this.state = {
notify: false,
value: "",
caret: null
};
}
handleChange = (value, caret) => {
this.setState({
value,
caret
});
};
render() {
return (
<div
style={{
position: "absolute",
left: "200px",
top: "100px"
}}
>
<H2>在文本框当中输入@就可以出现选人弹层,上下键选择,回车确定</H2>
<InteractiveInput
Notify={Notify}
onChange={this.handleChange}
value={this.state.value}
caret={this.state.caret}
height={100}
width={600}
/>
</div>
);
}
}
InteractiveInput 接受的 Props
onChange [function] 文本框内容发生变化时的回调,包括文本的变化和光标的变化,这样外层组件就可以时时知道 input 的内部状态
参数: value 当前 文本框当中的内容
参数: caret 当前文本框当中光标的位置
value [string] 传递进来的 value 会 直接覆盖当前文本框当中的内容,可以通过修改这个值结合 caret 位置在当前文本框中插入你想要的值
caret [number] 传递进来的光标位置
Nofity 当在 框里输入@字符时弹出的组件
height [number] 文本框的高
width [number] 文本框的宽
className [string] 给文本框设计一个 class
Nofify 组件的实现 示例请看项目当中的 example
*onSelect [function] 在 Nofity 当中会自动传入 onSelect 方法,在 Nofity 组件当中调用 this.props.onSelect(value), 就可以把你传出来的 value 插入到@字符后面, 可以通过调用这个方法方便的实现
search [string] 当在 notify 状态时,用户在@后面输入的字符可以在 Nofity 组件当可以通过 this.props.search 获取到。这样 nofity 组件就可以根据这个值进行搜索,更新 Notify 组件的展示内容。
关于键盘事件 当进入 notify 状态时,interactive-input 不会影响任何键盘事件,如果需要改变键盘事件的默认状态,需要在 Nofity 组件当中去实现,
componentDidMount() {
document.addEventListener("keydown", this.handleKeyPress);
if (typeof this.state.current !== "number") {
this.setState({
current: 0
});
}
}
componentWillUnmount() {
document.removeEventListener("keydown", this.handleKeyPress);
}
handleKeyPress = e => {
if (arrowKeyCodes.includes(e.keyCode)) {
e.preventDefault();
let { current, data } = this.state;
if (e.keyCode === 13) {
this.props.onSelect((data[current] && data[current].email) || " ");
}
if (e.keyCode === 38) {
this.setState({
current: current <= 0 ? data.length : current - 1
});
}
if (e.keyCode === 40) {
this.setState({
current: current >= data.length ? 0 : current + 1
});
}
}
};
TODO
- 文本框高度自适应
- 自定义弹层和关键符号
- input框支持