or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

buffers-graphics.mdcolors-styling.mddocument-model.mdindex.mdinteractive-input.mdterminal-control.md

document-model.mddocs/

0

# Document Model

1

2

The Document Model provides a high-level declarative UI framework for building complex terminal applications with components, layouts, and event handling. It offers a DOM-like structure for terminal interfaces.

3

4

## Core Architecture

5

6

### Base Classes

7

8

```javascript { .api }

9

const Element: typeof import('./document/Element');

10

const Container: typeof import('./document/Container');

11

const Document: typeof import('./document/Document');

12

```

13

14

The document model is built on three foundational classes:

15

16

- **Element**: Base class for all UI components

17

- **Container**: Elements that can contain child elements

18

- **Document**: Root container managing the entire UI

19

20

### Document Creation

21

22

```javascript { .api }

23

new Document(options: DocumentOptions): Document;

24

```

25

26

Create a new document instance to manage your UI.

27

28

```javascript { .api }

29

interface DocumentOptions {

30

outputDst?: Terminal;

31

eventSource?: Terminal;

32

x?: number;

33

y?: number;

34

width?: number;

35

height?: number;

36

}

37

```

38

39

```javascript

40

const term = require('terminal-kit').terminal;

41

const termkit = require('terminal-kit');

42

43

const document = new termkit.Document({

44

outputDst: term,

45

eventSource: term

46

});

47

48

// Enable event handling

49

term.grabInput({ mouse: 'button' });

50

```

51

52

## Text Components

53

54

### Static Text

55

56

```javascript { .api }

57

new termkit.Text(options: TextOptions): Text;

58

```

59

60

Display static text content.

61

62

```javascript { .api }

63

interface TextOptions {

64

parent?: Container;

65

content?: string;

66

markup?: boolean;

67

x?: number;

68

y?: number;

69

width?: number;

70

height?: number;

71

style?: object;

72

}

73

```

74

75

```javascript

76

const text = new termkit.Text({

77

parent: document,

78

content: 'Hello, World!',

79

x: 2,

80

y: 2,

81

style: { color: 'brightCyan' }

82

});

83

```

84

85

### Animated Text

86

87

```javascript { .api }

88

new termkit.AnimatedText(options: AnimatedTextOptions): AnimatedText;

89

```

90

91

Text with animation effects.

92

93

```javascript { .api }

94

interface AnimatedTextOptions extends TextOptions {

95

animation?: string;

96

animationDelay?: number;

97

}

98

```

99

100

```javascript

101

const animatedText = new termkit.AnimatedText({

102

parent: document,

103

content: 'Loading...',

104

x: 5,

105

y: 5,

106

animation: 'typewriter'

107

});

108

```

109

110

## Text Display and Input

111

112

### Text Box

113

114

```javascript { .api }

115

new termkit.TextBox(options: TextBoxOptions): TextBox;

116

```

117

118

Multi-line text display with scrolling support.

119

120

```javascript { .api }

121

interface TextBoxOptions {

122

parent?: Container;

123

content?: string;

124

markup?: boolean;

125

x?: number;

126

y?: number;

127

width?: number;

128

height?: number;

129

wrap?: boolean;

130

scrollable?: boolean;

131

vScrollBar?: boolean;

132

hScrollBar?: boolean;

133

style?: object;

134

scrollBarStyle?: object;

135

}

136

```

137

138

```javascript

139

const textBox = new termkit.TextBox({

140

parent: document,

141

content: 'This is a multi-line text box.\nIt supports scrolling and wrapping.',

142

x: 2,

143

y: 4,

144

width: 40,

145

height: 8,

146

scrollable: true,

147

vScrollBar: true

148

});

149

```

150

151

### Editable Text Box

152

153

```javascript { .api }

154

new termkit.EditableTextBox(options: EditableTextBoxOptions): EditableTextBox;

155

```

156

157

Multi-line editable text area.

158

159

```javascript { .api }

160

interface EditableTextBoxOptions extends TextBoxOptions {

161

keyBindings?: object;

162

readOnly?: boolean;

163

}

164

```

165

166

```javascript

167

const editableTextBox = new termkit.EditableTextBox({

168

parent: document,

169

content: 'Edit this text...',

170

x: 2,

171

y: 2,

172

width: 50,

173

height: 10,

174

scrollable: true

175

});

176

177

editableTextBox.on('submit', (content) => {

178

term.green('Text submitted: %s\n', content);

179

});

180

```

181

182

## Interactive Components

183

184

### Button

185

186

```javascript { .api }

187

new termkit.Button(options: ButtonOptions): Button;

188

```

189

190

Clickable button component.

191

192

```javascript { .api }

193

interface ButtonOptions {

194

parent?: Container;

195

content?: string;

196

value?: any;

197

x?: number;

198

y?: number;

199

width?: number;

200

height?: number;

201

style?: object;

202

focusStyle?: object;

203

disabledStyle?: object;

204

keyBindings?: object;

205

}

206

```

207

208

```javascript

209

const button = new termkit.Button({

210

parent: document,

211

content: 'Click Me',

212

x: 10,

213

y: 5,

214

width: 15,

215

height: 3

216

});

217

218

button.on('submit', () => {

219

term.green('Button clicked!\n');

220

});

221

```

222

223

### Toggle Button

224

225

```javascript { .api }

226

new termkit.ToggleButton(options: ToggleButtonOptions): ToggleButton;

227

```

228

229

Button that toggles between states.

230

231

```javascript { .api }

232

interface ToggleButtonOptions extends ButtonOptions {

233

turnedOnContent?: string;

234

turnedOffContent?: string;

235

turnedOn?: boolean;

236

turnedOnStyle?: object;

237

turnedOffStyle?: object;

238

}

239

```

240

241

```javascript

242

const toggleButton = new termkit.ToggleButton({

243

parent: document,

244

turnedOffContent: 'OFF',

245

turnedOnContent: 'ON',

246

x: 5,

247

y: 8,

248

width: 10,

249

turnedOn: false

250

});

251

252

toggleButton.on('toggle', (state) => {

253

term('Toggle state: %s\n', state ? 'ON' : 'OFF');

254

});

255

```

256

257

### Slider

258

259

```javascript { .api }

260

new termkit.Slider(options: SliderOptions): Slider;

261

```

262

263

Horizontal slider control.

264

265

```javascript { .api }

266

interface SliderOptions {

267

parent?: Container;

268

x?: number;

269

y?: number;

270

width?: number;

271

min?: number;

272

max?: number;

273

value?: number;

274

step?: number;

275

style?: object;

276

barStyle?: object;

277

buttonStyle?: object;

278

keyBindings?: object;

279

}

280

```

281

282

```javascript

283

const slider = new termkit.Slider({

284

parent: document,

285

x: 5,

286

y: 10,

287

width: 30,

288

min: 0,

289

max: 100,

290

value: 50,

291

step: 5

292

});

293

294

slider.on('slide', (value) => {

295

term.moveTo(1, 15)('Slider value: %d', value);

296

});

297

```

298

299

## Input Components

300

301

### Labeled Input

302

303

```javascript { .api }

304

new termkit.LabeledInput(options: LabeledInputOptions): LabeledInput;

305

```

306

307

Input field with an associated label.

308

309

```javascript { .api }

310

interface LabeledInputOptions {

311

parent?: Container;

312

label?: string;

313

x?: number;

314

y?: number;

315

width?: number;

316

height?: number;

317

labelStyle?: object;

318

inputStyle?: object;

319

keyBindings?: object;

320

}

321

```

322

323

```javascript

324

const labeledInput = new termkit.LabeledInput({

325

parent: document,

326

label: 'Name: ',

327

x: 5,

328

y: 12,

329

width: 30

330

});

331

332

labeledInput.on('submit', (value) => {

333

term.green('Entered name: %s\n', value);

334

});

335

```

336

337

### Inline Input

338

339

```javascript { .api }

340

new termkit.InlineInput(options: InlineInputOptions): InlineInput;

341

```

342

343

Compact inline input field.

344

345

```javascript { .api }

346

interface InlineInputOptions {

347

parent?: Container;

348

x?: number;

349

y?: number;

350

width?: number;

351

placeholder?: string;

352

default?: string;

353

style?: object;

354

focusStyle?: object;

355

}

356

```

357

358

### Inline File Input

359

360

```javascript { .api }

361

new termkit.InlineFileInput(options: InlineFileInputOptions): InlineFileInput;

362

```

363

364

File selection input with auto-completion.

365

366

```javascript { .api }

367

interface InlineFileInputOptions extends InlineInputOptions {

368

baseDir?: string;

369

allowedExtensions?: string[];

370

}

371

```

372

373

## Menu Components

374

375

### Inline Menu

376

377

```javascript { .api }

378

new termkit.InlineMenu(options: InlineMenuOptions): InlineMenu;

379

```

380

381

Horizontal inline menu.

382

383

```javascript { .api }

384

interface InlineMenuOptions {

385

parent?: Container;

386

items?: MenuItem[];

387

x?: number;

388

y?: number;

389

keyBindings?: object;

390

style?: object;

391

focusStyle?: object;

392

selectedStyle?: object;

393

}

394

395

interface MenuItem {

396

content: string;

397

value?: any;

398

disabled?: boolean;

399

}

400

```

401

402

### Row Menu

403

404

```javascript { .api }

405

new termkit.RowMenu(options: RowMenuOptions): RowMenu;

406

```

407

408

Horizontal row-based menu.

409

410

```javascript { .api }

411

interface RowMenuOptions {

412

parent?: Container;

413

items?: MenuItem[];

414

x?: number;

415

y?: number;

416

width?: number;

417

keyBindings?: object;

418

style?: object;

419

focusStyle?: object;

420

selectedStyle?: object;

421

}

422

```

423

424

### Column Menu

425

426

```javascript { .api }

427

new termkit.ColumnMenu(options: ColumnMenuOptions): ColumnMenu;

428

```

429

430

Vertical column menu.

431

432

```javascript { .api }

433

interface ColumnMenuOptions {

434

parent?: Container;

435

items?: MenuItem[];

436

x?: number;

437

y?: number;

438

width?: number;

439

height?: number;

440

keyBindings?: object;

441

style?: object;

442

focusStyle?: object;

443

selectedStyle?: object;

444

}

445

```

446

447

### Column Menu Multi

448

449

```javascript { .api }

450

new termkit.ColumnMenuMulti(options: ColumnMenuMultiOptions): ColumnMenuMulti;

451

```

452

453

Multi-select column menu.

454

455

```javascript { .api }

456

interface ColumnMenuMultiOptions extends ColumnMenuOptions {

457

multiSelect?: boolean;

458

checkedContent?: string;

459

uncheckedContent?: string;

460

}

461

```

462

463

### Column Menu Mixed

464

465

```javascript { .api }

466

new termkit.ColumnMenuMixed(options: ColumnMenuMixedOptions): ColumnMenuMixed;

467

```

468

469

Mixed-type column menu combining regular menu items with toggleable items.

470

471

```javascript { .api }

472

interface ColumnMenuMixedOptions extends ColumnMenuOptions {

473

// Items can be regular menu items or toggle items with states

474

toggledStyle?: object;

475

untoggledStyle?: object;

476

}

477

```

478

479

### Select List

480

481

```javascript { .api }

482

new termkit.SelectList(options: SelectListOptions): SelectList;

483

```

484

485

Scrollable selection list.

486

487

```javascript { .api }

488

interface SelectListOptions {

489

parent?: Container;

490

items?: MenuItem[];

491

x?: number;

492

y?: number;

493

width?: number;

494

height?: number;

495

scrollable?: boolean;

496

master?: object;

497

keyBindings?: object;

498

}

499

```

500

501

### Select List Multi

502

503

```javascript { .api }

504

new termkit.SelectListMulti(options: SelectListMultiOptions): SelectListMulti;

505

```

506

507

Multi-select scrollable selection list.

508

509

```javascript { .api }

510

interface SelectListMultiOptions extends SelectListOptions {

511

multiSelect?: boolean;

512

checkedContent?: string;

513

uncheckedContent?: string;

514

}

515

```

516

517

### Drop Down Menu

518

519

```javascript { .api }

520

new termkit.DropDownMenu(options: DropDownMenuOptions): DropDownMenu;

521

```

522

523

Expandable dropdown menu.

524

525

```javascript { .api }

526

interface DropDownMenuOptions {

527

parent?: Container;

528

items?: MenuItem[];

529

x?: number;

530

y?: number;

531

width?: number;

532

button?: object;

533

keyBindings?: object;

534

}

535

```

536

537

## Layout and Structure

538

539

### Layout Container

540

541

```javascript { .api }

542

new termkit.Layout(options: LayoutOptions): Layout;

543

```

544

545

Container for organizing child elements.

546

547

```javascript { .api }

548

interface LayoutOptions {

549

parent?: Container;

550

x?: number;

551

y?: number;

552

width?: number;

553

height?: number;

554

boxChars?: string;

555

style?: object;

556

}

557

```

558

559

### Border

560

561

```javascript { .api }

562

new termkit.Border(options: BorderOptions): Border;

563

```

564

565

Decorative border around content.

566

567

```javascript { .api }

568

interface BorderOptions {

569

parent?: Container;

570

x?: number;

571

y?: number;

572

width?: number;

573

height?: number;

574

boxChars?: string;

575

style?: object;

576

}

577

```

578

579

### Window

580

581

```javascript { .api }

582

new termkit.Window(options: WindowOptions): Window;

583

```

584

585

Window container with title bar and borders.

586

587

```javascript { .api }

588

interface WindowOptions {

589

parent?: Container;

590

title?: string;

591

x?: number;

592

y?: number;

593

width?: number;

594

height?: number;

595

movable?: boolean;

596

resizable?: boolean;

597

style?: object;

598

titleStyle?: object;

599

}

600

```

601

602

## Advanced Components

603

604

### Form

605

606

```javascript { .api }

607

new termkit.Form(options: FormOptions): Form;

608

```

609

610

Container for form elements with validation.

611

612

```javascript { .api }

613

interface FormOptions {

614

parent?: Container;

615

x?: number;

616

y?: number;

617

width?: number;

618

height?: number;

619

keyBindings?: object;

620

}

621

```

622

623

### Text Table

624

625

```javascript { .api }

626

new termkit.TextTable(options: TextTableOptions): TextTable;

627

```

628

629

Table display for structured data.

630

631

```javascript { .api }

632

interface TextTableOptions {

633

parent?: Container;

634

x?: number;

635

y?: number;

636

width?: number;

637

height?: number;

638

columns?: TableColumn[];

639

rows?: any[][];

640

style?: object;

641

headerStyle?: object;

642

cellStyle?: object;

643

}

644

645

interface TableColumn {

646

title: string;

647

width?: number;

648

align?: 'left' | 'center' | 'right';

649

}

650

```

651

652

### Bar (Progress Bar)

653

654

```javascript { .api }

655

new termkit.Bar(options: BarOptions): Bar;

656

```

657

658

Visual progress or status bar.

659

660

```javascript { .api }

661

interface BarOptions {

662

parent?: Container;

663

x?: number;

664

y?: number;

665

width?: number;

666

height?: number;

667

value?: number;

668

barChar?: string;

669

style?: object;

670

barStyle?: object;

671

}

672

```

673

674

### Inspector

675

676

```javascript { .api }

677

new termkit.Inspector(options: InspectorOptions): Inspector;

678

```

679

680

Object inspector for displaying complex data structures.

681

682

```javascript { .api }

683

interface InspectorOptions {

684

parent?: Container;

685

x?: number;

686

y?: number;

687

width?: number;

688

height?: number;

689

object?: any;

690

style?: object;

691

}

692

```

693

694

## Usage Examples

695

696

### Complete Application

697

698

```javascript

699

const term = require('terminal-kit').terminal;

700

const termkit = require('terminal-kit');

701

702

// Create document

703

const document = new termkit.Document({

704

outputDst: term,

705

eventSource: term

706

});

707

708

// Enable input

709

term.grabInput({ mouse: 'button' });

710

711

// Create window

712

const window = new termkit.Window({

713

parent: document,

714

title: 'My Application',

715

x: 2,

716

y: 2,

717

width: 60,

718

height: 20,

719

movable: true

720

});

721

722

// Add form elements

723

const nameInput = new termkit.LabeledInput({

724

parent: window,

725

label: 'Name: ',

726

x: 2,

727

y: 2,

728

width: 30

729

});

730

731

const emailInput = new termkit.LabeledInput({

732

parent: window,

733

label: 'Email: ',

734

x: 2,

735

y: 4,

736

width: 30

737

});

738

739

const submitButton = new termkit.Button({

740

parent: window,

741

content: 'Submit',

742

x: 2,

743

y: 6,

744

width: 12,

745

height: 3

746

});

747

748

// Handle events

749

submitButton.on('submit', () => {

750

term.green('Form submitted!\n');

751

term.green('Name: %s\n', nameInput.getValue());

752

term.green('Email: %s\n', emailInput.getValue());

753

});

754

755

// Start the document

756

document.giveFocusTo(nameInput);

757

```

758

759

### Dashboard Layout

760

761

```javascript

762

const term = require('terminal-kit').terminal;

763

const termkit = require('terminal-kit');

764

765

const document = new termkit.Document({

766

outputDst: term,

767

eventSource: term

768

});

769

770

term.grabInput({ mouse: 'button' });

771

772

// Main layout

773

const mainLayout = new termkit.Layout({

774

parent: document,

775

x: 1,

776

y: 1,

777

width: term.width - 1,

778

height: term.height - 1

779

});

780

781

// Status bar

782

const statusBar = new termkit.Bar({

783

parent: mainLayout,

784

x: 2,

785

y: 2,

786

width: 50,

787

height: 1,

788

value: 0.7,

789

barChar: '█'

790

});

791

792

// Menu

793

const menu = new termkit.ColumnMenu({

794

parent: mainLayout,

795

items: [

796

{ content: 'Dashboard' },

797

{ content: 'Reports' },

798

{ content: 'Settings' },

799

{ content: 'Exit' }

800

],

801

x: 2,

802

y: 5,

803

width: 20,

804

height: 8

805

});

806

807

// Data table

808

const table = new termkit.TextTable({

809

parent: mainLayout,

810

x: 25,

811

y: 5,

812

width: 40,

813

height: 10,

814

columns: [

815

{ title: 'Name', width: 15 },

816

{ title: 'Status', width: 10 },

817

{ title: 'Value', width: 10, align: 'right' }

818

],

819

rows: [

820

['Item 1', 'Active', '100'],

821

['Item 2', 'Inactive', '50'],

822

['Item 3', 'Pending', '75']

823

]

824

});

825

826

menu.on('submit', (buttonValue) => {

827

term.moveTo(1, term.height)('Selected: %s', buttonValue.content);

828

});

829

```