Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Quill Editor binding for Yjs

License

NotificationsYou must be signed in to change notification settings

yjs/y-quill

Repository files navigation

Quill Editor binding forYjs -Demo

This binding maps a Y.Text to a Quill instance. It optionally supports shared cursors viathequill-cursors module.

Example

import{QuillBinding}from'y-quill'importQuillfrom'quill'importQuillCursorsfrom'quill-cursors'..Quill.register('modules/cursors',QuillCursors)consttype=ydoc.getText('quill')vareditor=newQuill('#editor-container',{modules:{cursors:true,toolbar:[[{header:[1,2,false]}],['bold','italic','underline'],['image','code-block']]},placeholder:'Start collaborating...',theme:'snow'// or 'bubble'})// Optionally specify an Awareness instance, if supported by the Providerconstbinding=newQuillBinding(type,editor,provider.awareness)/*// Define user name and user name// Check the quill-cursors package on how to change the way cursors are renderedprovider.awareness.setLocalStateField('user', {  name: 'Typing Jimmy',  color: 'blue'})*/

Also lookhere for a working example.

Custom Embeds

The Delta format supports "custom embeds", a feature for embedding customdata using custom data models. This feature is currently not well documented, butit enables us to create good data models for tables and other complex widgets(like drawing widgets) that can't be well represented using text+formatting.

y-quill supports custom embeds. However, you need teach y-quill how to translatethe custom deltas to Yjs transformations and how to translate Yjstransformations to custom deltas.

This package already ships with a couple of custom deltas that might be useful.

Notes:

  • You need to register a "Blot" to render those embeds! This TableEmbed Blot might beavailable in a third-party package or you can build it yourself.
  • The Quill project currently doesn't talk a lot about this feature. This mightmean that it is unstable, or subject to future changes. y-quill will try tokeep track of the changes.

Custom Delta: table-embed

import{tableEmbed}from'y-quill/embeds/table-embed'importTableEmbedfrom'quill/modules/tableEmbed.js'TableEmbed.register()constembeds={'table-embed':tableEmbed}constbinding=newQuillBinding(type,editor,provider.awareness,{ embeds})

How to build custom deltas

The QuillBinding accepts aembeds option that is used as a lookup table fortransforming custom embed operations to Yjs operations and back.

Here is an example for building adelta embed that simply nests another deltain a custom embed:

importDeltafrom'quill-delta'// Register a custom `delta` embed in `quill-embed` module.Delta.registerEmbed('delta',{compose:(a,b)=>newDelta(a).compose(newDelta(b)).ops,transform:(a,b,priority)=>newDelta(a).transform(newDelta(b),priority).ops,invert:(a,b)=>newDelta(a).invert(newDelta(b)).ops})/** * This object is used to translate between quill-deltas and Yjs * transformations. */constembeds={/**   * The `delta` embed might be useful to render another editor (e.g. quill, or   * a code editor like codemirror) inside of a quill instance.   */delta:{/**     * A custom embed is always represented as a Y.XmlElement, because it is a     * very versatile shared type and the only one that can be "named" (     * `yxml.nodeName` will be the name of the custom embed). You must represent     * your data using a Y.XmlElement. However, you may embed other Yjs types       inside the Y.XmlElement.     *     * The `update` function is called whenever the quill editor changes the     * custom embed (i.e. `[ retain: { delta: op} ]`, where `op` is the second     * parameter of `update`).     *     * The `update` function is also called when the embed is created so we may     * initialize some content here if needed.     *     *@param {Y.XmlElement<{ ytext: Y.Text }>} yxml     *@param {DeltaOp} op     */update:(yxml,op)=>{if(!yxml.hasAttribute('ytext')){// The "delta" will be represented as a Y.Text, which we will maintain// on the "ytext" propertyyxml.setAttribute('ytext',newY.Text())}constytext=yxml.getAttribute('ytext')ytext?.applyDelta(op)},/**     * Translate Yjs events to a delta embed event.     * In this case, Y.Text (the child of yxml) already emits a quill-compatible     * delta event that we can simply return.     *     *@param {Y.XmlElement} yxml     *@param {Array<Y.YEvent<any>>} events     *@return {DeltaOps}     */eventsToDelta:(yxml,events)=>{constytext=yxml.getAttribute('ytext')constytextevent=events.find(event=>event.target===ytext)if(ytextevent){return/**@type {any} */(ytextevent.delta)}return[]},/**     * Translate the Y.XmlElement to a custom embed delta.     * In this case, we can simply return the delta representation of the     * Y.Text.     */typeToDelta:(yxml)=>{returnyxml.getAttribute('ytext').toDelta()}}}constbinding=newQuillBinding(type,editor,provider.awareness,{ embeds})

License

The MIT License © Kevin Jahns


[8]ページ先頭

©2009-2025 Movatter.jp