diff --git a/pages/docs/api/js.mdx b/pages/docs/api/js.mdx
index 83da9d3..60c51d0 100644
--- a/pages/docs/api/js.mdx
+++ b/pages/docs/api/js.mdx
@@ -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
@@ -2195,6 +2196,71 @@ const delta = text.toDelta();
```
+
+```typescript no_run
+sliceDelta(start: number, end: number): Delta[]
+```
+
+
+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" } },
+]);
+```
+
+
+
+```typescript no_run
+sliceDeltaUtf8(start: number, end: number): Delta[]
+```
+
+
+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: "👋" }]);
+```
+
+
```typescript no_run
applyDelta(delta: Delta[]): void
diff --git a/pages/docs/tutorial/text.mdx b/pages/docs/tutorial/text.mdx
index d027b15..087c7c8 100644
--- a/pages/docs/tutorial/text.mdx
+++ b/pages/docs/tutorial/text.mdx
@@ -224,6 +224,15 @@ Delete text at the given range.
Get a string slice.
+### `sliceDelta(start: number, end: number): Delta[]`
+
+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[]`
+
+Get a Quill-style Delta slice for the given UTF-8 byte range.
+
### `toString(): string`
Get the plain text value.
@@ -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.