当前位置: 首页 > 工具软件 > Draft.js > 使用案例 >

draft.js_如何使用快捷方式在Draft.js中创建有序列表和无序列表

石思淼
2023-12-01

draft.js

by Andrey Semin

通过安德烈·塞米(Andrey Semin)

如何使用快捷方式在Draft.js中创建有序列表和无序列表 (How to create ordered and unordered lists in Draft.js with a shortcut)

We at Propeller have encountered many differences between Draft.js and popular text editors. We also found some issues like controlling list depth and multiline items in lists. The biggest difference is the inability to use shortcuts to start a list by default. Surprisingly enough you need to implement this logic yourself.

Propeller的我们在Draft.js和流行的文本编辑器之间遇到了许多差异。 我们还发现了一些问题,例如控制列表深度和列表中的多行项目。 最大的区别是默认情况下无法使用快捷方式启动列表。 令人惊讶的是,您需要自己实现此逻辑。

As always, there is a plugin available to add support for the shortcuts you use. I also want to refer to draft-js-autolist-plugin as a source of inspiration. For some reason, this plugin didn’t work when we tried it. So we’ve come up with our own solution which is now presented in this post.

与往常一样,有一个插件可用于添加对您所使用快捷方式的支持。 我也想参考draft-js-autolist-plugin作为灵感来源。 出于某种原因,当我们尝试该插件时无法使用。 因此,我们提出了自己的解决方案,该解决方案现在将在本文中介绍。

问题 (The problem)

Open Google Docs, Word365, or whatever editor you use. Try to type * and then type space. Boom! You’ve started an unordered list. Nice feature to have, right?

打开Goog​​le文档,Word365或您使用的任何编辑器。 尝试键入* ,然后键入space 。 繁荣! 您已经开始了无序列表。 不错的功能,对不对?

If we try the exact same trick with the default Draft.js configuration, we will get nothing but plain text.

如果我们使用默认的Draft.js配置尝试完全相同的技巧,则只会得到纯文本。

Let’s change it!

让我们改变它!

(Solution)

To implement this feature, we need to keep track of the last three pressed buttons. Why three? Well, that’s because the longest character combination we need to support is 1. + space which is exactly three presses.

要实现此功能,我们需要跟踪最后按下的三个按钮。 为什么是三个? 好吧,这是因为我们需要支持的最长字符组合是1. + space ,正好是三按。

To start, let’s implement the logic to store these presses. Here we would use a simple array named history. This array will store the value of the key that was pressed. We definitely don’t want to process any key presses with modifiers like shift, alt and so on. We can use Draft.js built-inKeyBindingUtil.hasCommandModifier function to perform the check for any modifier.

首先,让我们实现存储这些印刷机的逻辑。 在这里,我们将使用一个名为history的简单数组。 该数组将存储所按下键的值。 我们绝对不希望使用shiftalt等修饰符来处理任何按键。 我们可以使用Draft.js内置的KeyBindingUtil.hasCommandModifier函数执行对任何修饰符的检查。

Draft.js exposes a keyDown event for us in the keyBindingFn prop function. We are going to check if we need to start a list here. If so, we need to return a so calledDraftEditorCommand, which is a string. Also, to benefit from OS-level commands we need to add a getDefaultKeyBinding function call as a fall-through case.

Draft.js在keyBindingFn prop函数中为我们公开了一个keyDown事件。 我们将检查是否需要在此处开始列表。 如果是这样,我们需要返回一个所谓的DraftEditorCommand ,它是一个字符串。 另外,要从操作系统级别的命令中受益,我们需要添加getDefaultKeyBinding函数调用作为getDefaultKeyBinding案例。

We need to check if the currently pressed key is a space. If so we would run our checks against the history array. We check if we have a suitable set of previously pressed keys — * for an unordered list and 1. for an ordered one. If we find a match, we return a command(string) to be processed later.

我们需要检查当前按下的键是否为space 。 如果是这样,我们将对history数组进行检查。 我们检查是否有一组合适的先前按下的键- *表示无序列表, 1. .表示有序键。 如果找到匹配项,则返回一个命令(字符串),以便稍后处理。

Now we need to implement the handleKeyCommand prop function and pass it to the editor. The logic is pretty simple. If we get one of our custom commands, we check if we should start a list on the current block. So here is a skeleton of the handleKeyCommand function.

现在,我们需要实现handleKeyCommand prop函数并将其传递给编辑器。 逻辑很简单。 如果得到自定义命令之一,则检查是否应在当前块上启动列表。 因此,这是handleKeyCommand函数的框架。

To check if we are good to start a list, we check if the currently selected block satisfies all three of the following rules:

要检查是否可以很好地启动列表,请检查当前选定的块是否满足以下所有三个规则:

  • The block type is unstyled

    块类型是无unstyled

  • The block has a depth of 0

    块的depth为0

  • the block has * or 1. as a text

    该块具有*1.作为文本

Let’s wrap it up with the code:

让我们用代码包装一下:

Now we’re able to catch the exact case where Draft.js needs to start a list! Now it’s a time to implement the startList function.

现在,我们可以捕捉到Draft.js需要启动列表的确切情况! 现在是时候实现startList函数了。

First of all, we need to map our custom commands to a particular list style. This means we need to start an unordered list for the start-unoredered-list command.

首先,我们需要将自定义命令映射到特定的列表样式。 这意味着我们需要为start-unoredered-list命令启动一个无序列表。

We start an ordered list for the start-ordered-list command. Next, we need to update the styling of the block to the selected type. To do it we would use the toggleBlockType function of RichUtils module, which comes as a part of Draft.js.

我们为start-ordered-list命令启动一个有序列表。 接下来,我们需要将块的样式更新为选定的类型。 为此,我们将使用RichUtils模块的toggleBlockType函数,该函数是RichUtils的一部分。

Next we need to replace the shortcut text we’ve entered with an empty string. To do it we need to call the replaceText method of the Modifier module. This method requires a selection range to determine what should be replaced. We need to get the selection out of the block and update it to have focusOffset value equal to block length. This combination means we want to replace the whole text we’ve entered.

接下来,我们需要将输入的快捷方式文本替换为空字符串。 为此,我们需要调用Modifier模块的replaceText方法。 此方法需要一个选择范围来确定应替换的内容。 我们需要从块中取出选择并进行更新,以focusOffset值等于块长度。 这种组合意味着我们要替换输入的整个文本。

Great! Now we need to update our local editor state with the new state we get from the startList function. So let’s bring it all together!

大! 现在,我们需要使用从startList函数获得的新状态来更新本地编辑器状态。 因此,让我们将它们放在一起!

OK! We’re almost done! But there is one more moment we need to handle. In some cases when one of our custom commands fire, we should not start a list based on the output of the shouldStartList function. We need to process the insertion of the space manually.

好! 我们快完成了! 但是,我们还有另外一刻需要处理。 在某些情况下,当我们的自定义命令之一触发时,我们不应基于shouldStartList函数的输出来启动列表。 我们需要手动处理空间的插入。

For implementation details of the getSelectedBlock method, check out my previous post on this Draft.js topic!

有关getSelectedBlock方法的实现细节,请查看我以前关于此Draft.js主题的文章!

To do this we may want to use a method called insertText of the Modifier module. Obviously enough, it is used to build a new content state with the provided text inserted into it. As always, we need to provide the current content state, current selection state and the text we want to insert (a single space in our case).

为此,我们可能需要使用Modifier模块的一个名为insertText的方法。 显然,它用于通过插入所提供的文本来构建新的内容状态。 与往常一样,我们需要提供当前的内容状态,当前的选择状态和我们要插入的文本(在本例中为单个空格)。

We need to add a call to this function to our handleKeyCommand function. So here is the final version of it:

我们需要在handleKeyCommand函数中添加对此函数的调用。 所以这是它的最终版本:

If you’ve read this post all the way through, you may also want to check out my previous post about Draft.js enchantment. You may want to apply it to your project as well.

如果您已经阅读了所有文章,那么您可能还想看看我以前有关Draft.js附魔的文章。 您可能还希望将其应用于您的项目。

翻译自: https://www.freecodecamp.org/news/how-to-create-ordered-and-unordered-lists-in-draft-js-with-a-shortcut-5de34a1a570f/

draft.js

 类似资料: