or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

command-management.mdcommand-metadata.mdindex.mdkey-binding-system.md

command-metadata.mddocs/

0

# Command Metadata

1

2

Rich metadata system for command presentation in user interfaces, including labels, icons, state management, and contextual information. The metadata system enables commands to provide dynamic visual representation and state-dependent behavior.

3

4

## Capabilities

5

6

### Command Description

7

8

Get comprehensive description and schema information for commands.

9

10

```typescript { .api }

11

/**

12

* Get the description for a specific command.

13

* @param id - The id of the command of interest

14

* @param args - The arguments for the command

15

* @returns The description for the command

16

*/

17

describedBy(id: string, args?: ReadonlyPartialJSONObject): Promise<CommandRegistry.Description>;

18

19

type Description = { args: ReadonlyJSONObject | null };

20

```

21

22

### Text Metadata

23

24

Get textual information about commands for UI display.

25

26

```typescript { .api }

27

/**

28

* Get the display label for a specific command.

29

* @param id - The id of the command of interest

30

* @param args - The arguments for the command

31

* @returns The display label for the command, or an empty string if the command is not registered

32

*/

33

label(id: string, args?: ReadonlyPartialJSONObject): string;

34

35

/**

36

* Get the mnemonic index for a specific command.

37

* @param id - The id of the command of interest

38

* @param args - The arguments for the command

39

* @returns The mnemonic index for the command, or -1 if the command is not registered

40

*/

41

mnemonic(id: string, args?: ReadonlyPartialJSONObject): number;

42

43

/**

44

* Get the short form caption for a specific command.

45

* @param id - The id of the command of interest

46

* @param args - The arguments for the command

47

* @returns The caption for the command, or an empty string if the command is not registered

48

*/

49

caption(id: string, args?: ReadonlyPartialJSONObject): string;

50

51

/**

52

* Get the usage help text for a specific command.

53

* @param id - The id of the command of interest

54

* @param args - The arguments for the command

55

* @returns The usage text for the command, or an empty string if the command is not registered

56

*/

57

usage(id: string, args?: ReadonlyPartialJSONObject): string;

58

```

59

60

### Visual Metadata

61

62

Get visual representation information for commands including icons and styling.

63

64

```typescript { .api }

65

/**

66

* Get the icon renderer for a specific command.

67

* @param id - The id of the command of interest

68

* @param args - The arguments for the command

69

* @returns The icon renderer for the command or undefined

70

*/

71

icon(id: string, args?: ReadonlyPartialJSONObject): VirtualElement.IRenderer | undefined;

72

73

/**

74

* Get the icon class for a specific command.

75

* @param id - The id of the command of interest

76

* @param args - The arguments for the command

77

* @returns The icon class for the command, or an empty string if the command is not registered

78

*/

79

iconClass(id: string, args?: ReadonlyPartialJSONObject): string;

80

81

/**

82

* Get the icon label for a specific command.

83

* @param id - The id of the command of interest

84

* @param args - The arguments for the command

85

* @returns The icon label for the command, or an empty string if the command is not registered

86

*/

87

iconLabel(id: string, args?: ReadonlyPartialJSONObject): string;

88

89

/**

90

* Get the extra class name for a specific command.

91

* @param id - The id of the command of interest

92

* @param args - The arguments for the command

93

* @returns The class name for the command, or an empty string if the command is not registered

94

*/

95

className(id: string, args?: ReadonlyPartialJSONObject): string;

96

97

/**

98

* Get the dataset for a specific command.

99

* @param id - The id of the command of interest

100

* @param args - The arguments for the command

101

* @returns The dataset for the command, or an empty dataset if the command is not registered

102

*/

103

dataset(id: string, args?: ReadonlyPartialJSONObject): CommandRegistry.Dataset;

104

```

105

106

### Command State

107

108

Check the current state of commands for UI state management.

109

110

```typescript { .api }

111

/**

112

* Test whether a specific command is enabled.

113

* @param id - The id of the command of interest

114

* @param args - The arguments for the command

115

* @returns A boolean indicating whether the command is enabled, or false if the command is not registered

116

*/

117

isEnabled(id: string, args?: ReadonlyPartialJSONObject): boolean;

118

119

/**

120

* Test whether a specific command is toggled.

121

* @param id - The id of the command of interest

122

* @param args - The arguments for the command

123

* @returns A boolean indicating whether the command is toggled, or false if the command is not registered

124

*/

125

isToggled(id: string, args?: ReadonlyPartialJSONObject): boolean;

126

127

/**

128

* Test whether a specific command is toggleable.

129

* @param id - The id of the command of interest

130

* @param args - The arguments for the command

131

* @returns A boolean indicating whether the command is toggleable, or false if the command is not registered

132

*/

133

isToggleable(id: string, args?: ReadonlyJSONObject): boolean;

134

135

/**

136

* Test whether a specific command is visible.

137

* @param id - The id of the command of interest

138

* @param args - The arguments for the command

139

* @returns A boolean indicating whether the command is visible, or false if the command is not registered

140

*/

141

isVisible(id: string, args?: ReadonlyPartialJSONObject): boolean;

142

```

143

144

## Usage Examples

145

146

### Dynamic Labels

147

148

```typescript

149

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

150

151

const registry = new CommandRegistry();

152

153

// Command with dynamic label based on context

154

registry.addCommand("open-file", {

155

execute: (args) => {

156

console.log(`Opening ${args.filename}`);

157

},

158

label: (args) => {

159

return args.filename ? `Open ${args.filename}` : "Open File";

160

},

161

caption: (args) => {

162

return args.filename ? `Open the file: ${args.filename}` : "Open a file";

163

}

164

});

165

166

// Get labels with different arguments

167

console.log(registry.label("open-file")); // "Open File"

168

console.log(registry.label("open-file", { filename: "document.txt" })); // "Open document.txt"

169

console.log(registry.caption("open-file", { filename: "document.txt" })); // "Open the file: document.txt"

170

```

171

172

### Icon Management

173

174

```typescript

175

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

176

177

const registry = new CommandRegistry();

178

179

// Icon renderer object

180

const saveIconRenderer = {

181

render: (host: HTMLElement) => {

182

const icon = document.createElement("i");

183

icon.className = "fa fa-save";

184

host.appendChild(icon);

185

}

186

};

187

188

registry.addCommand("save", {

189

execute: () => console.log("Saving..."),

190

label: "Save",

191

icon: saveIconRenderer,

192

iconClass: "save-icon",

193

iconLabel: "💾" // Emoji fallback

194

});

195

196

// Get icon information

197

const iconRenderer = registry.icon("save");

198

const iconClass = registry.iconClass("save"); // "save-icon"

199

const iconLabel = registry.iconLabel("save"); // "💾"

200

```

201

202

### State-Dependent Styling

203

204

```typescript

205

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

206

207

const registry = new CommandRegistry();

208

let isPlaying = false;

209

210

registry.addCommand("play-pause", {

211

execute: () => {

212

isPlaying = !isPlaying;

213

registry.notifyCommandChanged("play-pause");

214

},

215

label: () => isPlaying ? "Pause" : "Play",

216

iconClass: () => isPlaying ? "fa fa-pause" : "fa fa-play",

217

className: () => isPlaying ? "active playing" : "inactive",

218

isToggled: () => isPlaying,

219

isToggleable: true

220

});

221

222

// Check current state

223

console.log(registry.label("play-pause")); // "Play"

224

console.log(registry.iconClass("play-pause")); // "fa fa-play"

225

console.log(registry.isToggled("play-pause")); // false

226

console.log(registry.isToggleable("play-pause")); // true

227

228

// Execute to change state

229

await registry.execute("play-pause");

230

231

console.log(registry.label("play-pause")); // "Pause"

232

console.log(registry.iconClass("play-pause")); // "fa fa-pause"

233

console.log(registry.isToggled("play-pause")); // true

234

```

235

236

### Context-Sensitive Metadata

237

238

```typescript

239

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

240

241

const registry = new CommandRegistry();

242

243

registry.addCommand("format-text", {

244

execute: (args) => {

245

console.log(`Formatting as ${args.format}`);

246

},

247

label: (args) => {

248

const format = args.format || "default";

249

return `Format as ${format.toUpperCase()}`;

250

},

251

iconClass: (args) => {

252

switch (args.format) {

253

case "bold": return "fa fa-bold";

254

case "italic": return "fa fa-italic";

255

case "underline": return "fa fa-underline";

256

default: return "fa fa-font";

257

}

258

},

259

isEnabled: (args) => Boolean(args.selectedText),

260

dataset: (args) => ({

261

"format-type": args.format || "default",

262

"has-selection": args.selectedText ? "true" : "false"

263

})

264

});

265

266

// Get metadata with different contexts

267

const boldContext = { format: "bold", selectedText: "Hello World" };

268

console.log(registry.label("format-text", boldContext)); // "Format as BOLD"

269

console.log(registry.iconClass("format-text", boldContext)); // "fa fa-bold"

270

console.log(registry.isEnabled("format-text", boldContext)); // true

271

console.log(registry.dataset("format-text", boldContext)); // { "format-type": "bold", "has-selection": "true" }

272

273

const noSelectionContext = { format: "bold" };

274

console.log(registry.isEnabled("format-text", noSelectionContext)); // false

275

```

276

277

### Mnemonic Handling

278

279

```typescript

280

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

281

282

const registry = new CommandRegistry();

283

284

registry.addCommand("file-menu", {

285

execute: () => console.log("Opening file menu"),

286

label: "File",

287

mnemonic: 0, // 'F' is at index 0

288

caption: "File operations menu"

289

});

290

291

registry.addCommand("edit-menu", {

292

execute: () => console.log("Opening edit menu"),

293

label: "Edit",

294

mnemonic: 0, // 'E' is at index 0

295

caption: "Edit operations menu"

296

});

297

298

// Get mnemonic indices for keyboard navigation

299

console.log(registry.mnemonic("file-menu")); // 0

300

console.log(registry.mnemonic("edit-menu")); // 0

301

302

// Dynamic mnemonic based on context

303

registry.addCommand("save-as", {

304

execute: (args) => console.log("Save as:", args.filename),

305

label: (args) => args.filename ? `Save as ${args.filename}` : "Save As...",

306

mnemonic: (args) => args.filename ? 8 : 5, // 'A' in "Save As..." or 'a' in filename

307

});

308

```

309

310

### Comprehensive Metadata Example

311

312

```typescript

313

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

314

315

const registry = new CommandRegistry();

316

317

// Complex command with rich metadata

318

registry.addCommand("document-action", {

319

execute: async (args) => {

320

console.log(`Performing ${args.action} on document ${args.docId}`);

321

return { success: true, action: args.action };

322

},

323

324

describedBy: (args) => ({

325

args: {

326

type: "object",

327

properties: {

328

action: { type: "string", enum: ["save", "export", "print"] },

329

docId: { type: "string" },

330

format: { type: "string", optional: true }

331

}

332

}

333

}),

334

335

label: (args) => {

336

const action = args.action || "action";

337

const docName = args.docName || `Document ${args.docId || ""}`.trim();

338

return `${action.charAt(0).toUpperCase() + action.slice(1)} ${docName}`;

339

},

340

341

caption: (args) => {

342

return `${args.action || "Perform action on"} the current document`;

343

},

344

345

usage: () => "document-action --action=<save|export|print> --docId=<id> [--format=<format>]",

346

347

iconClass: (args) => {

348

switch (args.action) {

349

case "save": return "fa fa-save";

350

case "export": return "fa fa-download";

351

case "print": return "fa fa-print";

352

default: return "fa fa-file";

353

}

354

},

355

356

className: (args) => {

357

const classes = ["document-action"];

358

if (args.action) classes.push(`action-${args.action}`);

359

if (args.urgent) classes.push("urgent");

360

return classes.join(" ");

361

},

362

363

dataset: (args) => ({

364

"action": args.action || "",

365

"doc-id": args.docId || "",

366

"format": args.format || "",

367

"timestamp": Date.now().toString()

368

}),

369

370

isEnabled: (args) => Boolean(args.docId && args.action),

371

isVisible: (args) => Boolean(args.hasPermission),

372

isToggled: (args) => args.action === "save" && args.autoSave,

373

isToggleable: true

374

});

375

376

// Use the comprehensive metadata

377

const context = {

378

action: "export",

379

docId: "doc123",

380

docName: "Annual Report",

381

format: "pdf",

382

hasPermission: true,

383

urgent: true

384

};

385

386

console.log(registry.label("document-action", context)); // "Export Annual Report"

387

console.log(registry.caption("document-action", context)); // "export the current document"

388

console.log(registry.iconClass("document-action", context)); // "fa fa-download"

389

console.log(registry.className("document-action", context)); // "document-action action-export urgent"

390

console.log(registry.isEnabled("document-action", context)); // true

391

console.log(registry.isVisible("document-action", context)); // true

392

393

const description = await registry.describedBy("document-action", context);

394

console.log(description); // { args: { type: "object", properties: { ... } } }

395

```

396

397

## Types

398

399

```typescript { .api }

400

type Dataset = { readonly [key: string]: string };

401

type Description = { args: ReadonlyJSONObject | null };

402

type CommandFunc<T> = (args: ReadonlyPartialJSONObject) => T;

403

```