or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-quill

A modern, powerful rich text editor built for compatibility and extensibility

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/quill@2.0.x

To install, run

npx @tessl/cli install tessl/npm-quill@2.0.0

0

# Quill

1

2

Quill is a modern, powerful rich text editor built for compatibility and extensibility. It provides a comprehensive WYSIWYG editing experience with support for operational transformation, custom formatting, modular architecture, and extensive theming capabilities. The library offers both programmatic API access and user-friendly toolbar interfaces, supports multiple output formats including Delta (its native format), HTML, and plain text, and includes built-in modules for clipboard handling, keyboard shortcuts, history/undo-redo functionality, and toolbar management.

3

4

## Package Information

5

6

- **Package Name**: quill

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install quill`

10

11

## Core Imports

12

13

```typescript

14

import Quill from "quill";

15

```

16

17

For CommonJS:

18

19

```javascript

20

const Quill = require("quill");

21

```

22

23

## Basic Usage

24

25

```typescript

26

import Quill from "quill";

27

28

// Initialize Quill editor

29

const quill = new Quill('#editor', {

30

theme: 'snow',

31

modules: {

32

toolbar: [

33

['bold', 'italic', 'underline'],

34

['link', 'image'],

35

[{ 'header': [1, 2, 3, false] }],

36

[{ 'list': 'ordered'}, { 'list': 'bullet' }]

37

]

38

}

39

});

40

41

// Get/set content

42

const content = quill.getContents();

43

quill.setContents(content);

44

45

// Listen for changes

46

quill.on('text-change', (delta, oldDelta, source) => {

47

console.log('Text changed:', delta);

48

});

49

```

50

51

## Architecture

52

53

Quill is built around several key components:

54

55

- **Delta System**: Operational transform-based document representation using Delta format for change tracking

56

- **Blot System**: Parchment-based document model where content is represented as structured blots (blocks, inlines, embeds)

57

- **Module Architecture**: Extensible plugin system with core modules (History, Keyboard, Clipboard, Toolbar)

58

- **Theme System**: UI layer providing Snow (toolbar above) and Bubble (floating toolbar) themes

59

- **Event System**: Comprehensive event emission for text changes, selection changes, and editor interactions

60

- **Format Registry**: Dynamic registration system for custom formats, blots, modules, and themes

61

62

## Capabilities

63

64

### Editor Core

65

66

Core editor functionality for creating and managing rich text editor instances. The main Quill class provides all essential editing operations.

67

68

```typescript { .api }

69

class Quill {

70

constructor(container: HTMLElement | string, options?: QuillOptions);

71

72

// Content operations

73

getContents(index?: number, length?: number): Delta;

74

setContents(delta: Delta | Op[], source?: EmitterSource): Delta;

75

updateContents(delta: Delta | Op[], source?: EmitterSource): Delta;

76

getText(index?: number, length?: number): string;

77

setText(text: string, source?: EmitterSource): Delta;

78

getSemanticHTML(range: Range): string;

79

getSemanticHTML(index?: number, length?: number): string;

80

81

// Selection operations

82

getSelection(focus?: boolean): Range | null;

83

setSelection(range: Range | null, source?: EmitterSource): void;

84

setSelection(index: number, length?: number, source?: EmitterSource): void;

85

getBounds(index: number | Range, length?: number): Bounds | null;

86

87

// Formatting operations

88

format(name: string, value: unknown, source?: EmitterSource): Delta;

89

formatText(index: number, length: number, formats: Record<string, unknown>, source?: EmitterSource): Delta;

90

formatLine(index: number, length: number, formats: Record<string, unknown>, source?: EmitterSource): Delta;

91

removeFormat(index: number, length: number, source?: EmitterSource): Delta;

92

getFormat(index?: number, length?: number): { [format: string]: unknown };

93

94

// Text operations

95

insertText(index: number, text: string, formats?: Record<string, unknown>, source?: EmitterSource): Delta;

96

insertEmbed(index: number, embed: string, value: unknown, source?: EmitterSource): Delta;

97

deleteText(index: number, length: number, source?: EmitterSource): Delta;

98

99

// Editor state

100

focus(options?: { preventScroll?: boolean }): void;

101

blur(): void;

102

enable(enabled?: boolean): void;

103

disable(): void;

104

isEnabled(): boolean;

105

hasFocus(): boolean;

106

107

// Event handling

108

on(event: string, handler: (...args: any[]) => void): Emitter;

109

off(event: string, handler?: (...args: any[]) => void): Emitter;

110

once(event: string, handler: (...args: any[]) => void): Emitter;

111

112

// Additional content methods

113

getIndex(blot: Parchment.Blot): number;

114

getLeaf(index: number): [Parchment.Leaf | null, number];

115

getLine(index: number): [Parchment.Block | Parchment.BlockEmbed | null, number];

116

getLines(index?: number, length?: number): (Parchment.Block | Parchment.BlockEmbed)[];

117

getLines(range: Range): (Parchment.Block | Parchment.BlockEmbed)[];

118

119

// Container management

120

addContainer(container: string, refNode?: Node | null): HTMLDivElement;

121

addContainer(container: HTMLElement, refNode?: Node | null): HTMLElement;

122

123

// Advanced editing

124

editReadOnly<T>(modifier: () => T): T;

125

scrollRectIntoView(rect: { top: number; left: number; right: number; bottom: number }): void;

126

127

// Deprecated methods

128

scrollIntoView(): void; // @deprecated Use scrollSelectionIntoView()

129

130

// Utility methods

131

getLength(): number;

132

getModule(name: string): Module;

133

scrollSelectionIntoView(): void;

134

update(source?: EmitterSource): Delta | undefined;

135

// Static methods

136

static debug(level: DebugLevel | boolean): void;

137

static find(node: Node, bubble?: boolean): Parchment.Blot | null;

138

static import(name: string): unknown;

139

static register(path: string, target: any, overwrite?: boolean): void;

140

static register(target: Record<string, any>, overwrite?: boolean): void;

141

static register(target: Parchment.RegistryDefinition, overwrite?: boolean): void;

142

143

// Static properties

144

static DEFAULTS: Partial<QuillOptions>;

145

static events: typeof Emitter.events;

146

static sources: typeof Emitter.sources;

147

static version: string;

148

}

149

150

interface QuillOptions {

151

theme?: string;

152

debug?: DebugLevel | boolean;

153

registry?: Parchment.Registry;

154

readOnly?: boolean;

155

placeholder?: string;

156

bounds?: HTMLElement | string | null;

157

modules?: Record<string, unknown>;

158

formats?: string[] | null;

159

}

160

161

interface Range {

162

index: number;

163

length: number;

164

}

165

166

interface Bounds {

167

bottom: number;

168

height: number;

169

left: number;

170

right: number;

171

top: number;

172

width: number;

173

}

174

175

type EmitterSource = 'api' | 'user' | 'silent';

176

type DebugLevel = 'error' | 'warn' | 'log' | 'info';

177

178

interface Emitter {

179

on(event: string, handler: (...args: any[]) => void): Emitter;

180

off(event: string, handler?: (...args: any[]) => void): Emitter;

181

once(event: string, handler: (...args: any[]) => void): Emitter;

182

emit(event: string, ...args: any[]): void;

183

}

184

185

namespace Emitter {

186

const events = {

187

TEXT_CHANGE: 'text-change',

188

SELECTION_CHANGE: 'selection-change',

189

EDITOR_CHANGE: 'editor-change'

190

};

191

const sources = {

192

API: 'api' as EmitterSource,

193

USER: 'user' as EmitterSource,

194

SILENT: 'silent' as EmitterSource

195

};

196

}

197

```

198

199

[Editor Core](./editor-core.md)

200

201

### Delta Operations

202

203

Delta-based document representation and operational transform system for tracking and applying changes to rich text content.

204

205

```typescript { .api }

206

class Delta {

207

constructor(ops?: Op[] | Delta);

208

209

// Core operations

210

insert(text: string, attributes?: AttributeMap): Delta;

211

insert(embed: object, attributes?: AttributeMap): Delta;

212

delete(length: number): Delta;

213

retain(length: number, attributes?: AttributeMap): Delta;

214

215

// Delta manipulation

216

compose(other: Delta): Delta;

217

transform(other: Delta, priority?: boolean): Delta;

218

transformPosition(index: number, priority?: boolean): number;

219

diff(other: Delta, cursor?: number): Delta;

220

221

// Utility methods

222

length(): number;

223

slice(start?: number, end?: number): Delta;

224

partition(predicate: (op: Op) => boolean): [Delta, Delta];

225

filter(predicate: (op: Op, index: number) => boolean): Op[];

226

forEach(predicate: (op: Op, index: number) => void): void;

227

map<T>(predicate: (op: Op, index: number) => T): T[];

228

reduce<T>(predicate: (acc: T, curr: Op, index: number) => T, initialValue: T): T;

229

}

230

231

interface Op {

232

insert?: string | object;

233

delete?: number;

234

retain?: number;

235

attributes?: AttributeMap;

236

}

237

238

interface AttributeMap {

239

[key: string]: unknown;

240

}

241

```

242

243

[Delta Operations](./delta-operations.md)

244

245

### Formatting System

246

247

Comprehensive formatting system supporting inline formats (bold, italic, links), block formats (headers, lists, blockquotes), and custom attributors.

248

249

```typescript { .api }

250

// Built-in inline formats

251

class Bold extends Inline {

252

static blotName: 'bold';

253

static tagName: ['STRONG', 'B'];

254

}

255

256

class Italic extends Inline {

257

static blotName: 'italic';

258

static tagName: ['EM', 'I'];

259

}

260

261

class Link extends Inline {

262

static blotName: 'link';

263

static tagName: 'A';

264

static create(value: string): HTMLAnchorElement;

265

static formats(domNode: HTMLAnchorElement): string;

266

static sanitize(url: string): string;

267

}

268

269

// Built-in block formats

270

class Header extends Block {

271

static blotName: 'header';

272

static tagName: ['H1', 'H2', 'H3', 'H4', 'H5', 'H6'];

273

static formats(domNode: HTMLElement): number;

274

}

275

276

class List extends Block {

277

static blotName: 'list';

278

static tagName: 'LI';

279

static create(value: 'ordered' | 'bullet'): HTMLLIElement;

280

static formats(domNode: HTMLLIElement): string;

281

}

282

283

// Embed formats

284

class Image extends EmbedBlot {

285

static blotName: 'image';

286

static tagName: 'IMG';

287

static create(value: string): HTMLImageElement;

288

static formats(domNode: HTMLImageElement): Record<string, string>;

289

static value(domNode: HTMLImageElement): string;

290

}

291

```

292

293

[Formatting System](./formatting-system.md)

294

295

### Module System

296

297

Extensible module architecture with core modules for history, keyboard, clipboard, toolbar, and upload functionality.

298

299

```typescript { .api }

300

abstract class Module {

301

static DEFAULTS: Record<string, unknown>;

302

constructor(quill: Quill, options?: Record<string, unknown>);

303

}

304

305

class History extends Module {

306

static DEFAULTS: {

307

delay: number;

308

maxStack: number;

309

userOnly: boolean;

310

};

311

312

clear(): void;

313

cutoff(): void;

314

undo(): void;

315

redo(): void;

316

}

317

318

class Toolbar extends Module {

319

static DEFAULTS: {

320

container?: string | HTMLElement | (string | Record<string, unknown>)[];

321

handlers?: Record<string, ToolbarHandler>;

322

};

323

324

addHandler(format: string, handler: ToolbarHandler): void;

325

attach(input: HTMLElement): void;

326

update(range: Range | null): void;

327

}

328

329

class Clipboard extends Module {

330

addMatcher(selector: string, matcher: ClipboardMatcher): void;

331

dangerouslyPasteHTML(html: string, source?: EmitterSource): void;

332

convert(clipboard: { html?: string; text?: string }): Delta;

333

}

334

335

type ToolbarHandler = (value: unknown) => void;

336

type ClipboardMatcher = (node: Node, delta: Delta) => Delta;

337

```

338

339

[Module System](./module-system.md)

340

341

### Theme System

342

343

Theme system providing Snow and Bubble themes with customizable UI components and toolbar layouts.

344

345

```typescript { .api }

346

abstract class Theme {

347

static DEFAULTS: Record<string, unknown>;

348

constructor(quill: Quill, options: Record<string, unknown>);

349

350

init(): void;

351

addModule(name: string): Module;

352

}

353

354

class SnowTheme extends Theme {

355

// Snow theme with toolbar above editor

356

}

357

358

class BubbleTheme extends Theme {

359

// Bubble theme with floating toolbar

360

}

361

```

362

363

[Theme System](./theme-system.md)

364

365

### Registry System

366

367

Dynamic registration system for formats, modules, themes, and blots enabling extensibility and customization.

368

369

```typescript { .api }

370

class Quill {

371

static register(path: string, target: any, overwrite?: boolean): void;

372

static register(target: Record<string, any>, overwrite?: boolean): void;

373

static register(target: RegistryDefinition, overwrite?: boolean): void;

374

375

static import(name: string): unknown;

376

static find(node: Node, bubble?: boolean): Blot | null;

377

static debug(level: DebugLevel | boolean): void;

378

}

379

380

// Registration paths

381

// 'formats/bold' - Register Bold format

382

// 'modules/toolbar' - Register Toolbar module

383

// 'themes/snow' - Register Snow theme

384

// 'blots/block' - Register Block blot

385

// 'attributors/style/color' - Register style-based color attributor

386

```

387

388

[Registry System](./registry-system.md)

389

390

## Types

391

392

```typescript { .api }

393

// Re-exported from quill-delta

394

interface Delta {

395

ops: Op[];

396

}

397

398

interface Op {

399

insert?: string | object;

400

delete?: number;

401

retain?: number;

402

attributes?: AttributeMap;

403

}

404

405

interface AttributeMap {

406

[key: string]: unknown;

407

}

408

409

class OpIterator {

410

constructor(ops: Op[]);

411

hasNext(): boolean;

412

next(length?: number): Op;

413

peek(): Op;

414

peekLength(): number;

415

peekType(): 'insert' | 'delete' | 'retain';

416

rest(): Op[];

417

}

418

419

// Re-exported from parchment

420

namespace Parchment {

421

abstract class Blot {

422

static blotName: string;

423

static className?: string;

424

static tagName?: string | string[];

425

static scope: Scope;

426

427

domNode: Node;

428

parent: Blot | null;

429

prev: Blot | null;

430

next: Blot | null;

431

432

constructor(scroll: ScrollBlot, domNode?: Node);

433

434

attach(): void;

435

clone(): Blot;

436

detach(): void;

437

deleteAt(index: number, length: number): void;

438

formatAt(index: number, length: number, name: string, value: any): void;

439

insertAt(index: number, value: string, def?: any): void;

440

isolate(index: number, length: number): Blot;

441

length(): number;

442

offset(root?: Blot): number;

443

optimize(context: any): void;

444

remove(): void;

445

replaceWith(name: string | Blot, value?: any): Blot;

446

split(index: number, force?: boolean): Blot | null;

447

update(mutations: MutationRecord[], context: any): void;

448

wrap(name: string | Blot, value?: any): Blot;

449

}

450

451

enum Scope {

452

TYPE = 3,

453

LEVEL = 12,

454

ATTRIBUTE = 13,

455

BLOT = 14,

456

INLINE = 7,

457

BLOCK = 11,

458

BLOCK_BLOT = 10,

459

INLINE_BLOT = 6,

460

LEAF = 4,

461

PARENT = 8,

462

ANY = 15

463

}

464

465

class Registry {

466

create(scroll: ScrollBlot, input: Node | string | Scope, value?: any): Blot;

467

find(domNode: Node, bubble?: boolean): Blot | null;

468

query(query: string | Node | Scope, scope?: Scope): BlotConstructor | null;

469

register(...definitions: RegistryDefinition[]): void;

470

}

471

}

472

```