{"id":13535649,"url":"https://github.com/reedsy/quill-cursors","last_synced_at":"2025-04-02T02:31:03.880Z","repository":{"id":19869808,"uuid":"87843293","full_name":"reedsy/quill-cursors","owner":"reedsy","description":"A multi cursor module for Quill text editor.","archived":false,"fork":false,"pushed_at":"2024-01-18T12:10:57.000Z","size":892,"stargazers_count":243,"open_issues_count":6,"forks_count":54,"subscribers_count":14,"default_branch":"main","last_synced_at":"2024-05-28T14:51:32.166Z","etag":null,"topics":["collaborative-editing","cursors","module","quill"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/reedsy.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-MIT.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-04-10T18:19:31.000Z","updated_at":"2024-05-31T09:47:01.254Z","dependencies_parsed_at":"2024-05-31T09:46:52.884Z","dependency_job_id":"01d52bdd-2ed3-448f-a67e-9290fbadb87b","html_url":"https://github.com/reedsy/quill-cursors","commit_stats":{"total_commits":136,"total_committers":9,"mean_commits":15.11111111111111,"dds":0.6176470588235294,"last_synced_commit":"dc0ea8ea0cae572788baccffe529dd6f1af78566"},"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reedsy%2Fquill-cursors","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reedsy%2Fquill-cursors/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reedsy%2Fquill-cursors/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reedsy%2Fquill-cursors/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/reedsy","download_url":"https://codeload.github.com/reedsy/quill-cursors/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246743545,"owners_count":20826551,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["collaborative-editing","cursors","module","quill"],"created_at":"2024-08-01T09:00:20.134Z","updated_at":"2025-04-02T02:31:03.513Z","avatar_url":"https://github.com/reedsy.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","Uncategorized"],"sub_categories":["Uncategorized"],"readme":"[![NPM Version](https://img.shields.io/npm/v/quill-cursors.svg)](https://npmjs.org/package/quill-cursors)\n[![Test](https://github.com/reedsy/quill-cursors/actions/workflows/test.yml/badge.svg)](https://github.com/reedsy/quill-cursors/actions/workflows/test.yml)\n\n# quill-cursors\n\nA collaborative editing module for the [Quill](https://github.com/quilljs/quill) text editor used by the\n[Reedsy](https://reedsy.com) team.\n\n![Quill cursors](assets/demo.gif)\n\n## Install\n\n```bash\nnpm install quill-cursors --save\n```\n\n## Usage\n\n`quill-cursors` is a Quill module that exposes a number of methods to help display other users' cursors for\ncollaborative editing.\n\nFirst, [set up a Quill editor](https://quilljs.com/docs/quickstart/).\n\nNext, load `quill-cursors` through any of the options presented by [UMD](https://github.com/umdjs/umd).\n\nLoad script in HTML:\n\n```html\n\u003cscript src=\"quill-cursors.js\"\u003e\u003c/script\u003e\n```\n\nUsing [ES6-style `import`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import):\n\n```javascript\nimport QuillCursors from 'quill-cursors';\n```\n\nUsing CommonJS-style `require`:\n\n```javascript\nconst QuillCursors = require('quill-cursors');\n```\n\nThen, register the `quill-cursors` module:\n\n```javascript\nQuill.register('modules/cursors', QuillCursors);\n\nconst quill = new Quill('#editor', {\n  modules: {\n    cursors: true,\n  }\n});\n```\n\nFinally, use the exposed `quill-cursors` methods to update the cursors (see below). For an example setup, see the\n[example code](example), which can be run with:\n\n```bash\nnpm start\n```\n\n## API\n\n### Configuration\n\nThe `quill-cursors` module has the following optional configuration:\n\n  - `template` _string_: override the default HTML template used for a cursor\n  - `containerClass` _string_ (default: `ql-cursors`): the CSS class to add to the cursors container\n  - `hideDelayMs` _number_ (default: `3000`): number of milliseconds to show the username flag before hiding it\n  - `hideSpeedMs` _number_ (default: `400`): the duration of the flag hiding animation in milliseconds\n  - `selectionChangeSource` _string_ | _null_ (default: `api`): the event source to use when emitting `selection-change`\n  - `transformOnTextChange` _boolean_ (default: `false`): attempt to locally infer cursor positions whenever the editor\n    contents change, without receiving an update from the other client. This can be useful for smoother performance on\n    high-latency connections.\n  - `boundsContainer` _HTMLElement_ (default: Quill's bounds container): the element container used to determine flag positioning\n  - `positionFlag` _`(flag: HTMLElement, caretRectangle: ClientRect, container: ClientRect) =\u003e void`_ (default: flip horizontally): an optional function for positioning the caret flag according to its position relative to the bounds container. By default, the flag will flip horizontally when it reaches the right-hand edge of the bounds\n\nProvide these options when setting up the Quill editor:\n\n```javascript\nconst editor = new Quill('#editor', {\n  modules: {\n    cursors: {\n      template: '\u003cdiv class=\"custom-cursor\"\u003e...\u003c/div\u003e',\n      hideDelayMs: 5000,\n      hideSpeedMs: 0,\n      selectionChangeSource: null,\n      transformOnTextChange: true,\n    },\n  },\n});\n```\n\n#### `template`\n\nFor the custom template to work correctly with the module, it should closely follow the classes in the\n[original template](src/quill-cursors/template.ts).\n\n#### `selectionChangeSource`\n\nBy default, QuillJS will [suppress `selection-change` events when typing](https://quilljs.com/docs/api/#selection-change)\nto avoid noise.\n\nHowever, you will probably want to update the `quill-cursors` selection on both `selection-change` and `text-change`.\nIn order to aid this, `quill-cursors` will automatically emit a `selection-change` event on `text-change`.\n\nYou can differentiate between user input and the `quill-cursors` module by checking the `source` argument for the\n`selection-change` event. By default, `quill-cursors` will have `source = 'api'`, but if you need to differentiate\nbetween calls from `quill-cursors` and other events, then you can change this `source` using the `selectionChangeSource`\noption.\n\nIf emitting an event is undesirable (eg you want `selection-change` to act like the Quill default), then the\n`selectionChangeSource` can be set to `null`, and an event will not be emitted. Note that in this case, you will need to\nseparately handle the `text-change` event and update the cursor position.\n\n### Methods\n\nThe module instance can be retrieved through Quill's [`getModule`](https://quilljs.com/docs/api/#getmodule):\n\n```javascript\nconst cursors = editor.getModule('cursors');\n```\n\n#### `createCursor`\n\n```typescript\ncreateCursor(id: string, name: string, color: string): Cursor;\n```\n\nCreates a `Cursor` instance with the given `id`. If a cursor with this `id` already exists, a new one is not created.\n\n- `id` _string_: the unique ID for the cursor\n- `name` _string_: the name to display on the cursor\n- `color` _string_: the [CSS color](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value) to use for the cursor\n\nReturns a `Cursor` object:\n\n```typescript\n{\n  id: string;\n  name: string;\n  color: string;\n  range: Range; // See https://quilljs.com/docs/api/#selection-change\n}\n```\n\n#### `moveCursor`\n\n```typescript\nmoveCursor(id: string, range: QuillRange): void;\n```\n\nSets the selection range of the cursor with the given `id`.\n\n- `id` _string_: the ID of the cursor to move\n- `range` [_Range_](https://quilljs.com/docs/api/#selection-change): the selection range\n\n#### `removeCursor`\n\n```typescript\nremoveCursor(id: string): void;\n```\n\nRemoves the cursor with the given `id` from the DOM.\n\n- `id` _string_: the ID of the cursor to remove\n\n#### `update`\n\n```typescript\nupdate(): void;\n```\n\nRedraws all of the cursors in the DOM.\n\n#### `clearCursors`\n\n```typescript\nclearCursors(): void;\n```\n\nRemoves all the cursors from the DOM.\n\n#### `toggleFlag`\n\n```typescript\ntoggleFlag(id: string, shouldShow?: boolean): void;\n```\n\nToggles display of the flag for the cursor with the given `id`.\n\n- `id` _string_: the ID of the cursor whose flag should be toggled\n- `shouldShow` _boolean_ (optional): if set to `true`, will display the flag. If set to `false`, will hide it. If omitted, the flag's display state will be toggled.\n\n#### `cursors`\n\n```typescript\ncursors(): Cursor[];\n```\n\nReturns an array of all the `Cursor` objects in the DOM in no particular order.\n\n## License\n\nThis code is available under the [MIT license](LICENSE-MIT.txt).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freedsy%2Fquill-cursors","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freedsy%2Fquill-cursors","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freedsy%2Fquill-cursors/lists"}