Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions pages/docs/api/js.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Note: Under the hood, Loro combines a Fugue-based CRDT core with Eg-walker-inspi
- **Create rich text**: [`getText`](#LoroDoc.getText) - Initialize a collaborative text container
- **Edit text**: [`insert`](#LoroText.insert), [`delete`](#LoroText.delete), [`applyDelta`](#LoroText.applyDelta)
- **Apply formatting**: [`mark`](#LoroText.mark) - Add bold, italic, links, custom styles
- **Copy styled snippets**: [`sliceDelta`](#LoroText.sliceDelta) - Get a Delta for a range (UTF-16; use `sliceDeltaUtf8` for byte offsets)
- **Track cursor positions**: [`getCursor`](#LoroText.getCursor) + [`getCursorPos`](#LoroDoc.getCursorPos) - Stable positions across edits
- **Configure styles**: [`configTextStyle`](#LoroDoc.configTextStyle) - Define expand behavior for marks

Expand Down Expand Up @@ -2195,6 +2196,71 @@ const delta = text.toDelta();
```
</Indent>

<Method id="LoroText.sliceDelta">
```typescript no_run
sliceDelta(start: number, end: number): Delta<string>[]
```
</Method>
<Indent>
Returns a Quill-style Delta for a subsection of the text, using UTF-16 indices. Useful for copying a styled span. Use `sliceDeltaUtf8` if you need UTF-8 byte offsets instead.

**Parameters:**
- `start` - Start UTF-16 code unit index (inclusive)
- `end` - End UTF-16 code unit index (exclusive)

**Example:**
```ts threeslash
import { LoroDoc } from "loro-crdt";
import { expect } from "expect";
const doc = new LoroDoc();
doc.configTextStyle({
bold: { expand: "after" },
comment: { expand: "none" },
});
const text = doc.getText("text");

text.insert(0, "Hello World!");
text.mark({ start: 0, end: 5 }, "bold", true);
text.mark({ start: 6, end: 11 }, "comment", "greeting");

const snippet = text.sliceDelta(1, 8);
expect(snippet).toStrictEqual([
{ insert: "ello", attributes: { bold: true } },
{ insert: " " },
{ insert: "Wo", attributes: { comment: "greeting" } },
]);
```
</Indent>

<Method id="LoroText.sliceDeltaUtf8">
```typescript no_run
sliceDeltaUtf8(start: number, end: number): Delta<string>[]
```
</Method>
<Indent>
Returns a Quill-style Delta for a subsection of the text using **UTF-8 byte offsets**. Choose this when your offsets come from UTF-8 encoded buffers.

**Parameters:**
- `start` - Start byte offset (inclusive)
- `end` - End byte offset (exclusive)

**Example:**
```ts threeslash
import { LoroDoc } from "loro-crdt";
import { expect } from "expect";
const doc = new LoroDoc();
const text = doc.getText("text");
text.insert(0, "Hi 👋");

const enc = new TextEncoder();
const start = enc.encode("Hi ").length; // 3 bytes
const end = enc.encode("Hi 👋").length; // 7 bytes

const delta = text.sliceDeltaUtf8(start, end);
expect(delta).toStrictEqual([{ insert: "👋" }]);
```
</Indent>

<Method id="LoroText.applyDelta">
```typescript no_run
applyDelta(delta: Delta<string>[]): void
Expand Down
36 changes: 36 additions & 0 deletions pages/docs/tutorial/text.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,15 @@ Delete text at the given range.

Get a string slice.

### `sliceDelta(start: number, end: number): Delta<string>[]`

Get a Quill-style Delta slice for the given UTF-16 range. Use
`sliceDeltaUtf8` to slice by UTF-8 byte offsets instead.

### `sliceDeltaUtf8(start: number, end: number): Delta<string>[]`

Get a Quill-style Delta slice for the given UTF-8 byte range.

### `toString(): string`

Get the plain text value.
Expand Down Expand Up @@ -352,6 +361,33 @@ console.log(text.toDelta());
// ]
```

### Slice a Delta snippet

Use `sliceDelta(start, end)` when you only need a portion of the Delta (for example, to copy a styled snippet). It uses UTF-16 indices just like other text APIs; use `sliceDeltaUtf8` if you need to slice by UTF-8 byte offsets instead.

```ts twoslash
import { LoroDoc } from "loro-crdt";
import { expect } from "expect";
// ---cut---
const doc = new LoroDoc();
doc.configTextStyle({
bold: { expand: "after" },
comment: { expand: "none" },
});
const text = doc.getText("text");

text.insert(0, "Hello World!");
text.mark({ start: 0, end: 5 }, "bold", true);
text.mark({ start: 6, end: 11 }, "comment", "greeting");

const snippet = text.sliceDelta(1, 8);
expect(snippet).toStrictEqual([
{ insert: "ello", attributes: { bold: true } },
{ insert: " " },
{ insert: "Wo", attributes: { comment: "greeting" } },
]);
```

### `mark(range: {start: number, end: number}, key: string, value: any): void`

Mark the given range with a key-value pair.
Expand Down