Draft 旨在解决直接丰富的文本界面(如评论和聊天消息)的问题,但它也提供更丰富的编辑器体验,如Facebook Notes。
用户可以在其Notes中嵌入图像,从现有的Facebook照片加载或从桌面上传新图像。 为此,草案框架支持块级别的自定义呈现,以呈现像富媒体这样的内容来代替纯文本。
Draft 存储库中的TeX编辑器提供了自定义块渲染的实例,TeX语法通过 KaTeX 库转换为可编辑的嵌入式公式呈现。
还提供了一个媒体示例,展示了音频,图像和视频的自定义块渲染。
通过使用自定义块渲染器,可以在编辑器的框架中引入复杂的丰富的交互。
Custom Block Components在Editor组件中,可以指定blockRendererFn prop。 此支持功能允许更高级别的组件根据块类型,文本或其他条件为ContentBlock对象定义React呈现。
例如,我们可能希望使用自定义MediaComponent渲染“atomic”类型的ContentBlock对象。
function myBlockRenderer(contentBlock) {
const type = contentBlock.getType();
if (type === 'atomic') {
return {
component: MediaComponent,
editable: false,
props: {
foo: 'bar',
},
};
}
}
// Then...
import {Editor} from 'draft-js';
class EditorWithMedia extends React.Component {
...
render() {
return <Editor ... blockRendererFn={myBlockRenderer} />;
}
}
如果没有自定义渲染器对象由blockRendererFn函数返回,Editor将渲染默认的DraftEditorBlock文本块组件。
component属性定义要使用的组件,而可选的props对象包含通过props.blockProps子属性对象传递给呈现的自定义组件的道具。 此外,可选的可编辑属性确定自定义组件是否为contentEditable。
强烈建议您使用editable:如果您的自定义组件不包含文本,则为false。
如果您的组件包含ContentState提供的文本,您的自定义组件应构成一个DraftEditorBlock组件。 这将允许Draft框架在您的内容中适当地保持游标行为。
通过在更高级别组件的上下文中定义此函数,此自定义组件的道具可能绑定到该组件,允许自定义组件道具的实例方法。
定义 custom block components在MediaComponent中,最有可能的用例是您将要检索实体元数据以呈现自定义块。您可以在EditorState管理期间将实体密钥应用于“atomic”块中的文本,然后在自定义组件render()代码中检索该密钥的元数据。
class MediaComponent extends React.Component {
render() {
const {block, contentState} = this.props;
const {foo} = this.props.blockProps;
const data = contentState.getEntity(block.getEntityAt(0)).getData();
// Return a <figure> or some other content using this data.
}
}
ContentBlock对象和ContentState记录在自定义组件中可用,以及顶层定义的道具。 通过从ContentBlock和Entity map中提取实体信息,您可以获取呈现自定义组件所需的元数据。
从块中检索实体确实是一个尴尬的API,值得重新审视。
建议和其他说明如果您的自定义块渲染器需要鼠标交互,则在此交互期间临时将编辑器设置为readOnly = {true}通常是明智之举。 以这种方式,用户在与自定义块进行交互时不会在编辑器内触发任何选择更改。 这不应该是编辑器行为的问题,因为与您的自定义块组件交互最有可能与编辑器中的文本更改相互排斥。
上述建议对于涉及文本输入的自定义块渲染器尤其重要,如TeX编辑器示例。
还值得注意的是,在Facebook Notes编辑器中,我们没有尝试在嵌入式媒体上执行任何特殊的SelectionState渲染或管理,
例如在选择嵌入式照片时渲染突出显示。 这部分是因为媒体本身提供的丰富的互动,调整大小的句柄和暴露于鼠标行为的其他控件。
由于使用 Draft 的工程师充分意识到编辑器的选择状态和对Native Selection API的完全控制,所以如果需要,可以在静态嵌入式介质上构建选择行为。 到目前为止,我们还没有在Facebook上解决这个问题,所以我们目前还没有将这个用例的解决方案打包到“Draft”草案中。