【发布时间】:2019-02-22 11:07:56
【问题描述】:
我不得不说我这周开始使用 Javascript 和 React,所以我还不是很熟悉它或前端的任何东西。
我在工具栏旁边有一个链接按钮。我希望能够单击它,打开一个文本框,我可以在其中编写链接,然后将文本与它一起超文本。只想说任何提示都值得赞赏。
类似于以下图片。
我已经对工具栏进行了编码,并且正在使用编辑器的 slate-react 模块(使用的文本编辑器)。我正在尝试遵循 GitHub 示例中所做的操作,这并不完全相同。
因此,本质上,它是工具栏内的链接组件,它位于“工具提示”组件(包含水平工具栏和另一个垂直栏)内,位于编辑器内。
我的问题是:如何使用 react 和 slate 编辑器将工具栏中的链接绑定在一起? Link 组件是否需要 state 和 onChange 函数?如何在工具栏(按钮组)中包含链接组件,以及“const Marks”中的其他按钮?
我知道这些问题可能很基础,但我是初学者,希望得到解释。
我创建的 Link 组件可以包装和解开链接。点击后,
onClickLink = event => {
event.preventDefault()
const { value } = this.state
const hasLinks = this.hasLinks()
const change = value.change()
if (hasLinks) {
change.call(this.unwrapLink)
}
else
{
const href = window.prompt('Enter the URL of the link:')
change.call(this.wrapLink, href)
}
this.onChange(change)
}
wrap、unwrap 和 hasLinks 布尔值
class Links extends React.Component {
onChange = ({ value }) => {
this.setState({ value })
}
wrapLink(change, href) {
change.wrapInline({
type: 'link',
data: { href },
})
change.moveToEnd() }
unwrapLink(change) {
change.unwrapInline('link') }
hasLinks = () => {
const { value } = this.state
return value.inlines.some(inline => inline.type == 'link')
}
在编辑器中渲染它。
const renderNode = ({ children, node, attributes }) => {
switch (node.type) {
case 'link': {
const { data } = node
const href = data.get('href')
return (
<a {...attributes} href={href}>
{children}
</a>
)
}
“工具提示”组件,包含 MarkSelect(如图中的水平工具栏)和另一个称为 NodeSelector 的垂直栏。
function Tooltip({ onChange, value }: Props) {
return (
<Fragment>
<SelectionPlacement
value={value}
render={({ placement: { left, top, isActive } }) => (
<div
id=...
{
isActive,
},
)}
style={{ left, top }}
>
<NodeSelector onChange={onChange} value={value} />
<MarkSelector onChange={onChange} value={value} />
</div>
)}
/>
按钮组中的 MarkSelector 和其他标记(按钮)。
const MarkSelector = function MarkSelector({ onChange, value }: Props) {
return (
<ButtonGroup className=...>
{Marks.map(({ tooltip, text, type }) => {
const isActive = value.activeMarks.some(mark => mark.type === type);
return (
<Tooltip key={type} title={tooltip}>
<Button
className={classNames({ 'secondary-color': isActive })}
onMouseDown={event => {
event.preventDefault();
const change = value.change().toggleMark(type);
onChange(change);
}}
size=...
style=...
}}
>
{text}
</Button>
</Tooltip>
);
})}
</ButtonGroup>
);
};
const Marks = [
{
type: BOLD,
text: <strong>B</strong>,
tooltip: (
<strong>
Bold
<div className=...</div>
</strong>
),
},
{
type: ITALIC,
text:...
带有工具提示的编辑器。
render() {
const { onChangeHandler, onKeyDown, value, readOnly } = this.props;
return (
<div
className=...
id=...
style=..
>
{!readOnly && (
<EditorTooltip value={value} onChange={onChangeHandler} />
)}
<SlateEditor
ref=...
className=...
placeholder=...
value={value}
plugins={plugins}
onChange={onChangeHandler}
onKeyDown={onKeyDown}
renderNode={renderNode}
renderMark={renderMark}
readOnly={readOnly}
/>
{!readOnly && <ClickablePadding onClick={this.focusAtEnd} grow />}
</div>
);
}
【问题讨论】:
标签: javascript node.js reactjs