or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

components.mdindex.mdlayouts.mdpanels.mdspecialized.mdwidget-foundation.md

specialized.mddocs/

0

# Specialized Features

1

2

Advanced features for focus management, context menus, and other specialized functionality that enhance the user experience with sophisticated behaviors and interactions.

3

4

## Capabilities

5

6

### FocusTracker

7

8

A utility for tracking focus state within a collection of widgets, providing centralized focus management.

9

10

```typescript { .api }

11

/**

12

* A utility for tracking focus state within a collection of widgets.

13

* Monitors focus changes and maintains current/active widget state.

14

*/

15

class FocusTracker<T> implements IDisposable {

16

/**

17

* Construct a new focus tracker.

18

*/

19

constructor();

20

21

/** The currently focused widget, or null if no widget has focus */

22

readonly currentWidget: T | null;

23

24

/** The most recently active widget, or null if no widget has been active */

25

readonly activeWidget: T | null;

26

27

/** The widgets being tracked by the focus tracker (read-only) */

28

readonly widgets: ReadonlyArray<T>;

29

30

/** Whether the focus tracker has been disposed (read-only) */

31

readonly isDisposed: boolean;

32

33

/** A signal emitted when the current widget changes */

34

readonly currentChanged: ISignal<this, FocusTracker.ICurrentChangedArgs<T>>;

35

36

/** A signal emitted when the active widget changes */

37

readonly activeChanged: ISignal<this, FocusTracker.IActiveChangedArgs<T>>;

38

39

/** Dispose of the focus tracker and its resources */

40

dispose(): void;

41

42

/**

43

* Add a widget to the focus tracker.

44

* @param widget - The widget to add to the tracker

45

*/

46

add(widget: T): void;

47

48

/**

49

* Remove a widget from the focus tracker.

50

* @param widget - The widget to remove from the tracker

51

*/

52

remove(widget: T): void;

53

54

/**

55

* Test whether the focus tracker contains a specific widget.

56

* @param widget - The widget to test

57

* @returns Whether the widget is being tracked

58

*/

59

has(widget: T): boolean;

60

61

/**

62

* Get the focus number for a widget.

63

* @param widget - The widget of interest

64

* @returns The focus number for the widget

65

*/

66

focusNumber(widget: T): number;

67

68

/**

69

* Handle DOM events for the focus tracker.

70

* @param event - The DOM event to handle

71

*/

72

handleEvent(event: Event): void;

73

}

74

75

namespace FocusTracker {

76

/**

77

* The arguments object for the current changed signal.

78

*/

79

interface ICurrentChangedArgs<T> {

80

/** The old value for the current widget */

81

oldValue: T | null;

82

83

/** The new value for the current widget */

84

newValue: T | null;

85

}

86

87

/**

88

* The arguments object for the active changed signal.

89

*/

90

interface IActiveChangedArgs<T> {

91

/** The old value for the active widget */

92

oldValue: T | null;

93

94

/** The new value for the active widget */

95

newValue: T | null;

96

}

97

}

98

```

99

100

**Usage Examples:**

101

102

```typescript

103

import { Widget, FocusTracker } from "@lumino/widgets";

104

105

// Create focus tracker

106

const focusTracker = new FocusTracker<Widget>();

107

108

// Create widgets to track

109

const widget1 = new Widget();

110

const widget2 = new Widget();

111

const widget3 = new Widget();

112

113

// Add widgets to tracker

114

focusTracker.add(widget1);

115

focusTracker.add(widget2);

116

focusTracker.add(widget3);

117

118

// Listen for focus changes

119

focusTracker.currentChanged.connect((sender, args) => {

120

console.log('Current widget changed:', {

121

old: args.oldValue?.title.label,

122

new: args.newValue?.title.label

123

});

124

});

125

126

focusTracker.activeChanged.connect((sender, args) => {

127

console.log('Active widget changed:', {

128

old: args.oldValue?.title.label,

129

new: args.newValue?.title.label

130

});

131

});

132

133

// Check current state

134

console.log('Current widget:', focusTracker.currentWidget?.title.label);

135

console.log('Active widget:', focusTracker.activeWidget?.title.label);

136

137

// Clean up when done

138

focusTracker.dispose();

139

```

140

141

### ContextMenu

142

143

A context menu widget for displaying contextual actions based on the target element.

144

145

```typescript { .api }

146

/**

147

* A context menu widget for displaying contextual actions.

148

* Provides right-click menus with command integration and target-specific items.

149

*/

150

class ContextMenu {

151

/**

152

* Construct a new context menu.

153

* @param options - The options for initializing the context menu

154

*/

155

constructor(options: ContextMenu.IOptions);

156

157

/** The menu for the context menu (read-only) */

158

readonly menu: Menu;

159

160

/** The renderer for the context menu (read-only) */

161

readonly renderer: ContextMenu.IRenderer;

162

163

164

/**

165

* Add an item to the context menu.

166

* @param options - The options for creating the item

167

* @returns The context menu item that was added

168

*/

169

addItem(options: ContextMenu.IItemOptions): ContextMenu.IItem;

170

171

/**

172

* Remove an item from the context menu.

173

* @param item - The item to remove

174

*/

175

removeItem(item: ContextMenu.IItem): void;

176

177

/** Remove all items from the context menu */

178

clearItems(): void;

179

180

/**

181

* Open the context menu at the current mouse position.

182

* @param event - The mouse or keyboard event that triggered the menu

183

* @returns Whether the menu was opened successfully

184

*/

185

open(event: MouseEvent | KeyboardEvent): boolean;

186

}

187

188

namespace ContextMenu {

189

/**

190

* Options for initializing a context menu.

191

*/

192

interface IOptions {

193

/** The command registry to use for the context menu */

194

commands: CommandRegistry;

195

196

/** The renderer for creating context menu elements */

197

renderer?: IRenderer;

198

}

199

200

/**

201

* An object which represents an item in a context menu.

202

*/

203

interface IItem {

204

/** The rank for the item (lower ranks appear first) */

205

rank: number;

206

207

/** The CSS selector for matching target elements */

208

selector: string;

209

210

/** The command identifier for the item */

211

command: string;

212

213

/** The arguments for the command */

214

args?: any;

215

}

216

217

/**

218

* Options for creating a context menu item.

219

*/

220

interface IItemOptions {

221

/** The command identifier for the item */

222

command: string;

223

224

/** The CSS selector for matching target elements (default: '*') */

225

selector?: string;

226

227

/** The rank for the item (default: Infinity) */

228

rank?: number;

229

230

/** The arguments for the command (optional) */

231

args?: any;

232

}

233

234

/**

235

* An object which renders a context menu.

236

*/

237

interface IRenderer {

238

/** The renderer for the underlying menu */

239

readonly menu: Menu.IRenderer;

240

}

241

242

/**

243

* Default context menu renderer implementation.

244

*/

245

class Renderer implements IRenderer {

246

/** The menu renderer for the context menu */

247

readonly menu: Menu.IRenderer;

248

}

249

}

250

```

251

252

**Usage Examples:**

253

254

```typescript

255

import { ContextMenu } from "@lumino/widgets";

256

import { CommandRegistry } from "@lumino/commands";

257

258

// Create command registry

259

const commands = new CommandRegistry();

260

261

// Add commands

262

commands.addCommand('edit:cut', {

263

label: 'Cut',

264

iconClass: 'fa fa-cut',

265

execute: () => console.log('Cut executed')

266

});

267

268

commands.addCommand('edit:copy', {

269

label: 'Copy',

270

iconClass: 'fa fa-copy',

271

execute: () => console.log('Copy executed')

272

});

273

274

commands.addCommand('edit:paste', {

275

label: 'Paste',

276

iconClass: 'fa fa-paste',

277

execute: () => console.log('Paste executed')

278

});

279

280

// Create context menu

281

const contextMenu = new ContextMenu({ commands });

282

283

// Add items for text inputs

284

contextMenu.addItem({

285

command: 'edit:cut',

286

selector: 'input[type="text"], textarea',

287

rank: 1

288

});

289

290

contextMenu.addItem({

291

command: 'edit:copy',

292

selector: 'input[type="text"], textarea',

293

rank: 2

294

});

295

296

contextMenu.addItem({

297

command: 'edit:paste',

298

selector: 'input[type="text"], textarea',

299

rank: 3

300

});

301

302

// Add global items

303

contextMenu.addItem({

304

command: 'edit:copy',

305

selector: '*',

306

rank: 100

307

});

308

309

// Listen for context menu events

310

document.addEventListener('contextmenu', (event) => {

311

event.preventDefault();

312

contextMenu.open(event);

313

});

314

```

315

316

### Menu

317

318

A widget that displays menu items for user selection with full keyboard and mouse support.

319

320

```typescript { .api }

321

/**

322

* A widget that displays menu items for user selection.

323

* Provides hierarchical menus with keyboard navigation, mnemonics, and submenus.

324

*/

325

class Menu extends Widget {

326

/**

327

* Construct a new menu.

328

* @param options - The options for initializing the menu

329

*/

330

constructor(options: Menu.IOptions);

331

332

/** The command registry for the menu (read-only) */

333

readonly commands: CommandRegistry;

334

335

/** The renderer for the menu (read-only) */

336

readonly renderer: Menu.IRenderer;

337

338

/** The child menu for this menu (read-only) */

339

readonly childMenu: Menu | null;

340

341

/** The parent menu for this menu (read-only) */

342

readonly parentMenu: Menu | null;

343

344

/** The root menu for this menu (read-only) */

345

readonly rootMenu: Menu;

346

347

/** The leaf menu for this menu (read-only) */

348

readonly leafMenu: Menu;

349

350

/** The menu items (read-only) */

351

readonly items: ReadonlyArray<Menu.IItem>;

352

353

/** The active menu item, or null if no item is active */

354

activeItem: Menu.IItem | null;

355

356

/** The index of the active menu item, or -1 if no item is active */

357

activeIndex: number;

358

359

/** The content node for the menu (read-only) */

360

readonly contentNode: HTMLUListElement;

361

362

/** A signal emitted when the menu is about to close */

363

readonly aboutToClose: ISignal<this, void>;

364

365

/** A signal emitted when a menu is requested */

366

readonly menuRequested: ISignal<this, 'next' | 'previous'>;

367

368

/** Dispose of the menu and its resources */

369

dispose(): void;

370

371

/**

372

* Add an item to the end of the menu.

373

* @param options - The options for creating the item

374

* @returns The menu item that was added

375

*/

376

addItem(options: Menu.IItemOptions): Menu.IItem;

377

378

/**

379

* Insert an item at the specified index.

380

* @param index - The index at which to insert the item

381

* @param options - The options for creating the item

382

* @returns The menu item that was inserted

383

*/

384

insertItem(index: number, options: Menu.IItemOptions): Menu.IItem;

385

386

/**

387

* Remove an item from the menu.

388

* @param item - The item to remove

389

*/

390

removeItem(item: Menu.IItem): void;

391

392

/**

393

* Remove the item at the specified index.

394

* @param index - The index of the item to remove

395

*/

396

removeItemAt(index: number): void;

397

398

/** Remove all items from the menu */

399

clearItems(): void;

400

401

/**

402

* Open the menu at the specified location.

403

* @param x - The client X coordinate for the menu

404

* @param y - The client Y coordinate for the menu

405

* @param options - Additional options for opening the menu

406

* @returns Whether the menu was successfully opened

407

*/

408

open(x: number, y: number, options?: Menu.IOpenOptions): boolean;

409

410

/**

411

* Show the menu as a popup at the specified location.

412

* @param x - The client X coordinate for the menu

413

* @param y - The client Y coordinate for the menu

414

*/

415

popup(x: number, y: number): void;

416

417

/** Handle DOM events for the menu */

418

handleEvent(event: Event): void;

419

420

/** Activate the next menu item */

421

activateNextItem(): void;

422

423

/** Activate the previous menu item */

424

activatePreviousItem(): void;

425

426

/** Trigger the active menu item */

427

triggerActiveItem(): void;

428

}

429

430

namespace Menu {

431

/**

432

* Options for initializing a menu.

433

*/

434

interface IOptions extends Widget.IOptions {

435

/** The command registry to use for the menu */

436

commands: CommandRegistry;

437

438

/** The renderer for creating menu elements */

439

renderer?: IRenderer;

440

}

441

442

/**

443

* An object which represents an item in a menu.

444

*/

445

interface IItem {

446

/** The command identifier for the item */

447

readonly command: string;

448

449

/** The arguments for the command */

450

readonly args: any;

451

452

/** The submenu for the item, or null if no submenu */

453

readonly submenu: Menu | null;

454

455

/** The type of the menu item */

456

readonly type: ItemType;

457

458

/** The display label for the item */

459

readonly label: string;

460

461

/** The mnemonic index for the label */

462

readonly mnemonic: number;

463

464

/** The icon renderer for the item */

465

readonly icon: VirtualElement.IRenderer | undefined;

466

467

/** The icon class name for the item */

468

readonly iconClass: string;

469

470

/** The icon label for the item */

471

readonly iconLabel: string;

472

473

/** The caption for the item */

474

readonly caption: string;

475

476

/** The extra class name for the item */

477

readonly className: string;

478

479

/** The dataset for the item */

480

readonly dataset: { readonly [key: string]: string };

481

482

/** Whether the item is enabled */

483

readonly isEnabled: boolean;

484

485

/** Whether the item is toggled */

486

readonly isToggled: boolean;

487

488

/** Whether the item is visible */

489

readonly isVisible: boolean;

490

491

/** The key binding for the item, or null if no key binding */

492

readonly keyBinding: CommandRegistry.IKeyBinding | null;

493

}

494

495

/**

496

* Options for creating a menu item.

497

*/

498

interface IItemOptions {

499

/** The command identifier for the item (required for command items) */

500

command?: string;

501

502

/** The arguments for the command (optional) */

503

args?: any;

504

505

/** The submenu for the item (required for submenu items) */

506

submenu?: Menu;

507

508

/** The type of the menu item (default: 'command') */

509

type?: ItemType;

510

}

511

512

/**

513

* The available item types for menu items.

514

*/

515

type ItemType = 'command' | 'submenu' | 'separator';

516

517

/**

518

* Options for opening a menu.

519

*/

520

interface IOpenOptions {

521

/** Whether to force the X coordinate */

522

forceX?: boolean;

523

524

/** Whether to force the Y coordinate */

525

forceY?: boolean;

526

}

527

528

/**

529

* An object which renders the visual parts of a menu.

530

*/

531

interface IRenderer {

532

/**

533

* Create an item node for a menu item.

534

* @param data - The render data for the item

535

* @returns The item node for the menu item

536

*/

537

createItemNode(data: IRenderData): HTMLLIElement;

538

539

/**

540

* Update an existing item node to reflect current state.

541

* @param node - The item node to update

542

* @param data - The render data for the item

543

*/

544

updateItemNode(node: HTMLLIElement, data: IRenderData): void;

545

546

/**

547

* Create an icon node for a menu item.

548

* @param data - The render data for the item

549

* @returns The icon node for the menu item

550

*/

551

createIconNode(data: IRenderData): HTMLSpanElement;

552

553

/**

554

* Update an existing icon node to reflect current state.

555

* @param node - The icon node to update

556

* @param data - The render data for the item

557

*/

558

updateIconNode(node: HTMLSpanElement, data: IRenderData): void;

559

560

/**

561

* Create a label node for a menu item.

562

* @param data - The render data for the item

563

* @returns The label node for the menu item

564

*/

565

createLabelNode(data: IRenderData): HTMLSpanElement;

566

567

/**

568

* Update an existing label node to reflect current state.

569

* @param node - The label node to update

570

* @param data - The render data for the item

571

*/

572

updateLabelNode(node: HTMLSpanElement, data: IRenderData): void;

573

574

/**

575

* Create a submenu icon node for a menu item.

576

* @param data - The render data for the item

577

* @returns The submenu icon node for the menu item

578

*/

579

createSubmenuIconNode(data: IRenderData): HTMLSpanElement;

580

581

/**

582

* Update an existing submenu icon node to reflect current state.

583

* @param node - The submenu icon node to update

584

* @param data - The render data for the item

585

*/

586

updateSubmenuIconNode(node: HTMLSpanElement, data: IRenderData): void;

587

588

/**

589

* Create a shortcut node for a menu item.

590

* @param data - The render data for the item

591

* @returns The shortcut node for the menu item

592

*/

593

createShortcutNode(data: IRenderData): HTMLSpanElement;

594

595

/**

596

* Update an existing shortcut node to reflect current state.

597

* @param node - The shortcut node to update

598

* @param data - The render data for the item

599

*/

600

updateShortcutNode(node: HTMLSpanElement, data: IRenderData): void;

601

}

602

603

/**

604

* The render data for a menu item.

605

*/

606

interface IRenderData {

607

/** The menu item being rendered */

608

item: IItem;

609

610

/** Whether the item is active */

611

active: boolean;

612

613

/** Whether the item is collapsed (for submenus) */

614

collapsed: boolean;

615

}

616

617

/**

618

* Default menu renderer implementation.

619

*/

620

class Renderer implements IRenderer {

621

createItemNode(data: IRenderData): HTMLLIElement;

622

updateItemNode(node: HTMLLIElement, data: IRenderData): void;

623

createIconNode(data: IRenderData): HTMLSpanElement;

624

updateIconNode(node: HTMLSpanElement, data: IRenderData): void;

625

createLabelNode(data: IRenderData): HTMLSpanElement;

626

updateLabelNode(node: HTMLSpanElement, data: IRenderData): void;

627

createSubmenuIconNode(data: IRenderData): HTMLSpanElement;

628

updateSubmenuIconNode(node: HTMLSpanElement, data: IRenderData): void;

629

createShortcutNode(data: IRenderData): HTMLSpanElement;

630

updateShortcutNode(node: HTMLSpanElement, data: IRenderData): void;

631

}

632

}

633

```

634

635

**Usage Examples:**

636

637

```typescript

638

import { Menu } from "@lumino/widgets";

639

import { CommandRegistry } from "@lumino/commands";

640

641

// Create command registry and commands

642

const commands = new CommandRegistry();

643

644

commands.addCommand('file:new', {

645

label: 'New File',

646

iconClass: 'fa fa-file',

647

execute: () => console.log('Creating new file')

648

});

649

650

commands.addCommand('file:open', {

651

label: 'Open File...',

652

iconClass: 'fa fa-folder-open',

653

execute: () => console.log('Opening file dialog')

654

});

655

656

commands.addCommand('edit:undo', {

657

label: 'Undo',

658

iconClass: 'fa fa-undo',

659

execute: () => console.log('Undoing last action')

660

});

661

662

// Create main menu

663

const fileMenu = new Menu({ commands });

664

665

// Add menu items

666

fileMenu.addItem({ command: 'file:new' });

667

fileMenu.addItem({ command: 'file:open' });

668

fileMenu.addItem({ type: 'separator' });

669

670

// Create submenu

671

const recentMenu = new Menu({ commands });

672

recentMenu.addItem({ command: 'file:open', args: { path: '/path/to/file1.txt' } });

673

recentMenu.addItem({ command: 'file:open', args: { path: '/path/to/file2.txt' } });

674

675

// Add submenu to main menu

676

fileMenu.addItem({

677

type: 'submenu',

678

submenu: recentMenu

679

});

680

recentMenu.title.label = 'Open Recent';

681

682

// Open menu at specific coordinates

683

fileMenu.open(100, 200);

684

685

// Or show as popup (centers on screen)

686

fileMenu.popup(event.clientX, event.clientY);

687

```