diff --git a/biome.json b/biome.json index bc66183bb1..5d1595c84d 100644 --- a/biome.json +++ b/biome.json @@ -39,6 +39,9 @@ "noStaticOnlyClass": "off", "useOptionalChain": "off", "noUselessLabel": "off" + }, + "a11y": { + "noSvgWithoutTitle": "off" } } } diff --git a/package.json b/package.json index 2571fb9152..c7479891bc 100644 --- a/package.json +++ b/package.json @@ -140,6 +140,7 @@ }, "devDependencies": { "@biomejs/biome": "^1.9.4", + "@radix-ui/react-icons": "^1.3.1", "@types/benchmark": "^2.1.5", "@types/jest": "^29.5.12", "@types/react": "^18.3.11", @@ -153,6 +154,7 @@ "json-crdt-traces": "https://github.com/streamich/json-crdt-traces#ec825401dc05cbb74b9e0b3c4d6527399f54d54d", "json-logic-js": "^2.0.2", "nano-theme": "^1.4.3", + "nice-ui": "^1.18.0", "quill-delta": "^5.1.0", "react": "^18.3.1", "react-dom": "^18.3.1", diff --git a/src/json-crdt-extensions/peritext/editor/Editor.ts b/src/json-crdt-extensions/peritext/editor/Editor.ts index bb30c08546..a63911b76d 100644 --- a/src/json-crdt-extensions/peritext/editor/Editor.ts +++ b/src/json-crdt-extensions/peritext/editor/Editor.ts @@ -12,13 +12,13 @@ import {PersistedSlice} from '../slice/PersistedSlice'; import {ValueSyncStore} from '../../../util/events/sync-store'; import {formatType} from '../slice/util'; import {CommonSliceType, type SliceType} from '../slice'; +import {tick} from '../../../json-crdt-patch'; import type {ChunkSlice} from '../util/ChunkSlice'; import type {Peritext} from '../Peritext'; import type {Point} from '../rga/Point'; import type {Range} from '../rga/Range'; import type {CharIterator, CharPredicate, Position, TextRangeUnit} from './types'; import type {Printable} from 'tree-dump'; -import {tick} from '../../../json-crdt-patch'; /** * For inline boolean ("Overwrite") slices, both range endpoints should be @@ -105,15 +105,31 @@ export class Editor implements Printable { for (let cursor: Cursor | undefined, i = this.cursors0(); (cursor = i()); ) callback(cursor); } + /** + * @returns Returns `true` if there is at least one cursor in the document. + */ + public hasCursor(): boolean { + return !!this.cursors0()(); + } + + /** + * @returns Returns the exact number of cursors in the document. + */ public cursorCount(): number { let cnt = 0; for (const i = this.cursors0(); i(); ) cnt++; return cnt; } - /** Returns true if there is at least one cursor in the document. */ - public hasCursor(): boolean { - return !!this.cursors0()(); + /** + * Returns relative count of cursors (cardinality). + * + * @returns 0 if there are no cursors, 1 if there is exactly one cursor, 2 if + * there are more than one cursor. + */ + public cursorCard(): 0 | 1 | 2 { + const i = this.cursors0(); + return !i() ? 0 : !i() ? 1 : 2; } public delCursor(cursor: Cursor): void { diff --git a/src/json-crdt-extensions/peritext/slice/constants.ts b/src/json-crdt-extensions/peritext/slice/constants.ts index 5b29659a62..8c1ec8f98d 100644 --- a/src/json-crdt-extensions/peritext/slice/constants.ts +++ b/src/json-crdt-extensions/peritext/slice/constants.ts @@ -36,6 +36,9 @@ export enum CommonSliceType { aside = 19, //