or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdeditor-core.mdindex.mdmode-management.mdpreview-mode.mdschema-validation.mdtext-operations.mdtransform-operations.mdtree-operations.md
tile.json

tree-operations.mddocs/

0

# Tree Operations

1

2

Interactive tree editing capabilities including node manipulation, selection management, expansion control, and visual operations for tree, view, and form modes.

3

4

## Capabilities

5

6

### Expand All Nodes

7

8

Expand all collapsible nodes in the tree to show the complete data structure.

9

10

```javascript { .api }

11

/**

12

* Expand all fields in the tree

13

* Only applicable for tree, view, and form modes

14

*/

15

expandAll(): void;

16

```

17

18

**Usage Example:**

19

20

```javascript

21

// Expand all nodes to show full structure

22

editor.expandAll();

23

```

24

25

### Collapse All Nodes

26

27

Collapse all expanded nodes to show only the top-level structure.

28

29

```javascript { .api }

30

/**

31

* Collapse all fields in the tree

32

* Only applicable for tree, view, and form modes

33

*/

34

collapseAll(): void;

35

```

36

37

**Usage Example:**

38

39

```javascript

40

// Collapse all nodes for compact view

41

editor.collapseAll();

42

```

43

44

### Expand Specific Node

45

46

Expand or collapse a specific node at a given path with optional recursion.

47

48

```javascript { .api }

49

/**

50

* Expand or collapse a specific JSON node

51

* @param options - Expansion configuration

52

*/

53

expand(options: ExpandOptions): void;

54

55

interface ExpandOptions {

56

/** Path to the node to expand/collapse */

57

path: (string | number)[];

58

59

/** True to expand, false to collapse */

60

isExpand: boolean;

61

62

/** Apply to child nodes recursively (optional) */

63

recursive?: boolean;

64

65

/** Also expand/collapse all nodes in the path (optional) */

66

withPath?: boolean;

67

}

68

```

69

70

**Usage Example:**

71

72

```javascript

73

// Expand a specific node

74

editor.expand({

75

path: ['users', 0, 'address'],

76

isExpand: true

77

});

78

79

// Collapse a node and all its children

80

editor.expand({

81

path: ['data'],

82

isExpand: false,

83

recursive: true

84

});

85

86

// Expand a node and ensure its path is visible

87

editor.expand({

88

path: ['config', 'database', 'settings'],

89

isExpand: true,

90

withPath: true

91

});

92

```

93

94

### Set Node Selection

95

96

Set selection for a range of nodes in the tree, supporting both single and multi-node selection.

97

98

```javascript { .api }

99

/**

100

* Set selection for a range of nodes

101

* @param start - Path to start node (optional)

102

* @param end - Path to end node (optional)

103

*/

104

setSelection(start?: (string | number)[], end?: (string | number)[]): void;

105

```

106

107

**Usage Example:**

108

109

```javascript

110

// Select a single node

111

editor.setSelection(['users', 0, 'name']);

112

113

// Select a range of nodes

114

editor.setSelection(['users', 0], ['users', 2]);

115

116

// Clear selection

117

editor.setSelection();

118

```

119

120

### Get Current Selection

121

122

Retrieve the currently selected nodes in the tree.

123

124

```javascript { .api }

125

/**

126

* Get the current selected nodes

127

* @returns Object with start and end selection points

128

*/

129

getSelection(): { start: SerializableNode; end: SerializableNode };

130

131

interface SerializableNode {

132

/** Value of the selected node */

133

value: any;

134

135

/** Path to the selected node */

136

path: (string | number)[];

137

}

138

```

139

140

**Usage Example:**

141

142

```javascript

143

const selection = editor.getSelection();

144

145

if (selection.start) {

146

console.log('Selection start:', selection.start.path);

147

console.log('Start value:', selection.start.value);

148

}

149

150

if (selection.end && selection.end.path !== selection.start?.path) {

151

console.log('Multi-node selection to:', selection.end.path);

152

}

153

```

154

155

### Get Nodes by Range

156

157

Get all nodes within a specified range, useful for batch operations on selected content.

158

159

```javascript { .api }

160

/**

161

* Get a list of all nodes within a specified range

162

* @param start - Path to the first node in range

163

* @param end - Path to the last node in range

164

* @returns Array of all nodes in the range

165

*/

166

getNodesByRange(start: (string | number)[], end: (string | number)[]): SerializableNode[];

167

```

168

169

### Search Tree Content

170

171

Search for text within all nodes in the tree and return matching results.

172

173

```javascript { .api }

174

/**

175

* Search for text in all nodes of the tree

176

* @param text - Text to search for

177

* @returns Array of search result objects with node information

178

*/

179

search(text: string): SearchResult[];

180

181

interface SearchResult {

182

/** Path to the node containing the match */

183

path: (string | number)[];

184

185

/** Field name where the match was found */

186

field: string;

187

188

/** Value containing the match */

189

value: any;

190

191

/** Node object reference */

192

node: any;

193

}

194

```

195

196

**Usage Example:**

197

198

```javascript

199

// Search for text in all nodes

200

const results = editor.search("example");

201

202

results.forEach(result => {

203

console.log(`Found "${result.field}" at path: ${result.path.join('.')}`);

204

console.log(`Value: ${result.value}`);

205

});

206

207

// Search for partial matches

208

const partialResults = editor.search("mail"); // Finds "email", "mailbox", etc.

209

210

// Navigate to first search result

211

if (results.length > 0) {

212

editor.setSelection(results[0].path);

213

214

// Expand path to make result visible

215

editor.expand({

216

path: results[0].path,

217

isExpand: true,

218

withPath: true

219

});

220

}

221

```

222

223

**Usage Example:**

224

225

```javascript

226

// Get all nodes in a range

227

const nodes = editor.getNodesByRange(['users', 0], ['users', 5]);

228

229

nodes.forEach(node => {

230

console.log(`Node at ${node.path.join('.')}: ${node.value}`);

231

});

232

233

// Process nodes in selection range

234

const selection = editor.getSelection();

235

if (selection.start && selection.end) {

236

const selectedNodes = editor.getNodesByRange(

237

selection.start.path,

238

selection.end.path

239

);

240

241

// Perform batch operation

242

selectedNodes.forEach(node => {

243

// Process each selected node

244

});

245

}

246

```

247

248

### Selection Change Events

249

250

Handle selection changes with event callbacks to respond to user interactions.

251

252

```javascript { .api }

253

/**

254

* Selection change callback in editor options

255

*/

256

interface SelectionCallbacks {

257

onSelectionChange?: (start?: SerializableNode, end?: SerializableNode) => void;

258

}

259

```

260

261

**Usage Example:**

262

263

```javascript

264

const options = {

265

mode: "tree",

266

onSelectionChange: (start, end) => {

267

if (!start) {

268

console.log("Selection cleared");

269

return;

270

}

271

272

const pathStr = start.path.join('.');

273

console.log(`Selected: ${pathStr} = ${JSON.stringify(start.value)}`);

274

275

if (end && end.path !== start.path) {

276

const endPathStr = end.path.join('.');

277

console.log(`Multi-selection to: ${endPathStr}`);

278

}

279

280

// Update UI based on selection

281

updateSelectionUI(start, end);

282

}

283

};

284

285

const editor = new JSONEditor(container, options);

286

```

287

288

### Node Expansion Events

289

290

Handle node expansion and collapse events to track tree state changes.

291

292

```javascript { .api }

293

/**

294

* Expansion event callback in editor options

295

*/

296

interface ExpansionCallbacks {

297

onExpand?: (event: {

298

path: (string | number)[];

299

isExpand: boolean;

300

recursive: boolean;

301

}) => void;

302

}

303

```

304

305

**Usage Example:**

306

307

```javascript

308

const options = {

309

mode: "tree",

310

onExpand: ({ path, isExpand, recursive }) => {

311

const pathStr = path.join('.');

312

const action = isExpand ? "expanded" : "collapsed";

313

const scope = recursive ? " (recursive)" : "";

314

315

console.log(`Node ${pathStr} ${action}${scope}`);

316

317

// Save expansion state

318

saveExpansionState(path, isExpand);

319

}

320

};

321

```

322

323

## Advanced Tree Operations

324

325

### Navigate to Node

326

327

Navigate to and reveal a specific node in the tree by expanding its path.

328

329

```javascript

330

function navigateToNode(editor, targetPath) {

331

// Expand all parent nodes to make target visible

332

for (let i = 1; i < targetPath.length; i++) {

333

const parentPath = targetPath.slice(0, i);

334

editor.expand({

335

path: parentPath,

336

isExpand: true

337

});

338

}

339

340

// Select the target node

341

editor.setSelection(targetPath);

342

}

343

344

// Usage

345

navigateToNode(editor, ['config', 'database', 'host']);

346

```

347

348

### Batch Node Operations

349

350

Perform operations on multiple selected nodes.

351

352

```javascript

353

function processSelectedNodes(editor, processor) {

354

const selection = editor.getSelection();

355

356

if (selection.start && selection.end) {

357

const nodes = editor.getNodesByRange(

358

selection.start.path,

359

selection.end.path

360

);

361

362

const currentData = editor.get();

363

let modified = false;

364

365

nodes.forEach(node => {

366

const result = processor(node.value, node.path);

367

if (result !== node.value) {

368

// Update the data

369

setValueAtPath(currentData, node.path, result);

370

modified = true;

371

}

372

});

373

374

if (modified) {

375

editor.set(currentData);

376

}

377

}

378

}

379

380

// Usage: Convert all selected strings to uppercase

381

processSelectedNodes(editor, (value, path) => {

382

return typeof value === 'string' ? value.toUpperCase() : value;

383

});

384

```

385

386

### Tree State Management

387

388

Save and restore tree expansion and selection state.

389

390

```javascript

391

function saveTreeState(editor) {

392

return {

393

selection: editor.getSelection(),

394

// Note: Expansion state requires walking the tree

395

// This is a simplified example

396

mode: editor.getMode()

397

};

398

}

399

400

function restoreTreeState(editor, state) {

401

if (state.selection && state.selection.start) {

402

editor.setSelection(state.selection.start.path, state.selection.end?.path);

403

}

404

405

if (state.mode && state.mode !== editor.getMode()) {

406

editor.setMode(state.mode);

407

}

408

}

409

410

// Usage

411

const state = saveTreeState(editor);

412

// ... make changes ...

413

restoreTreeState(editor, state);

414

```

415

416

## Tree Configuration Options

417

418

### Visual Behavior

419

420

```javascript

421

const treeOptions = {

422

mode: "tree",

423

424

// Limit visible children before "show more" appears

425

maxVisibleChilds: 100,

426

427

// Restrict dragging to same parent

428

limitDragging: true,

429

430

// Sort object keys alphabetically

431

sortObjectKeys: false,

432

433

// Enable search functionality

434

search: true,

435

436

// Enable undo/redo

437

history: true

438

};

439

```

440

441

### Node Customization

442

443

```javascript

444

const customTreeOptions = {

445

mode: "tree",

446

447

// Customize node appearance

448

onClassName: ({ path, field, value }) => {

449

if (field === 'id') return 'id-field';

450

if (typeof value === 'number' && value < 0) return 'negative';

451

if (path.includes('deprecated')) return 'deprecated';

452

},

453

454

// Customize object/array node names

455

onNodeName: ({ type, size, value }) => {

456

if (type === 'array' && value.length === 0) return '[empty]';

457

if (type === 'object' && size === 0) return '{empty}';

458

return type === 'array' ? `[${size}]` : `{${size}}`;

459

},

460

461

// Control editability

462

onEditable: ({ path, field, value }) => {

463

// Make 'id' fields read-only

464

if (field === 'id') return { field: false, value: false };

465

466

// Make system fields read-only

467

if (field.startsWith('_')) return false;

468

469

return true; // Allow editing

470

}

471

};

472

```

473

474

## Tree Mode Limitations

475

476

- **Data Size**: Large datasets may impact performance; consider using preview mode for very large JSON

477

- **Deep Nesting**: Extremely deep object hierarchies may affect rendering performance

478

- **Memory Usage**: Full tree rendering keeps all nodes in memory

479

- **Browser Limits**: Very wide objects (many properties) may affect horizontal scrolling