or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

component-api.mdfunctional-api.mdindex.mdmenu-bar.mdthemes.md
tile.json

functional-api.mddocs/

0

# Functional API

1

2

The functional API provides programmatic control over context menus through global methods. This approach is ideal for dynamic menus, event-driven scenarios, and situations where you need full control over menu display and configuration.

3

4

## Capabilities

5

6

### Show Context Menu

7

8

Display a context menu at specified coordinates with configurable options and menu items.

9

10

```typescript { .api }

11

/**

12

* Show a context menu programmatically

13

* @param options - Menu configuration including position, items, and display options

14

* @param customSlots - Optional custom rendering slots for menu components

15

* @returns ContextMenuInstance for controlling the displayed menu

16

*/

17

function showContextMenu(

18

options: MenuOptions,

19

customSlots?: Record<string, Slot>

20

): ContextMenuInstance;

21

```

22

23

**Usage Examples:**

24

25

```typescript

26

import ContextMenu from '@imengyu/vue3-context-menu';

27

28

// Basic context menu

29

function showBasicMenu(e: MouseEvent) {

30

e.preventDefault();

31

32

ContextMenu.showContextMenu({

33

x: e.x,

34

y: e.y,

35

items: [

36

{ label: "Open", onClick: () => console.log("Open clicked") },

37

{ label: "Save", onClick: () => console.log("Save clicked") },

38

{ divided: true, label: "Exit", onClick: () => console.log("Exit clicked") }

39

]

40

});

41

}

42

43

// Advanced menu with theming and configuration

44

function showAdvancedMenu(e: MouseEvent) {

45

e.preventDefault();

46

47

const menuInstance = ContextMenu.showContextMenu({

48

x: e.x,

49

y: e.y,

50

theme: 'win10 dark',

51

minWidth: 200,

52

maxHeight: 400,

53

keyboardControl: true,

54

adjustPosition: true,

55

items: [

56

{

57

label: "File Operations",

58

icon: "folder-icon",

59

children: [

60

{ label: "New File", shortcut: "Ctrl+N", onClick: createFile },

61

{ label: "Open File", shortcut: "Ctrl+O", onClick: openFile },

62

{ divided: true, label: "Recent Files", children: getRecentFiles() }

63

]

64

},

65

{ label: "Edit", disabled: !canEdit, onClick: editHandler }

66

],

67

onClose: (lastItem) => {

68

if (lastItem) {

69

console.log(`Menu closed after clicking: ${lastItem.label}`);

70

}

71

}

72

});

73

74

// You can control the menu instance

75

setTimeout(() => {

76

if (!menuInstance.isClosed()) {

77

menuInstance.closeMenu();

78

}

79

}, 5000);

80

}

81

82

// Menu with custom rendering slots

83

function showCustomMenu(e: MouseEvent) {

84

ContextMenu.showContextMenu({

85

x: e.x,

86

y: e.y,

87

items: [{ label: "Custom Item", icon: "star" }]

88

}, {

89

// Custom item renderer

90

itemRender: ({ label, icon, onClick, onMouseEnter, disabled }) => [

91

h('div', {

92

class: `my-custom-item ${disabled ? 'disabled' : ''}`,

93

onClick: onClick,

94

onMouseenter: onMouseEnter

95

}, [

96

icon ? h('img', { src: icon, class: 'custom-icon' }) : null,

97

h('span', { class: 'custom-label' }, label)

98

])

99

]

100

});

101

}

102

```

103

104

### Close Context Menu

105

106

Close the currently open context menu programmatically.

107

108

```typescript { .api }

109

/**

110

* Close the currently open context menu

111

*/

112

function closeContextMenu(): void;

113

```

114

115

**Usage:**

116

117

```typescript

118

import ContextMenu from '@imengyu/vue3-context-menu';

119

120

// Close menu after some action

121

function handleAction() {

122

performAction();

123

ContextMenu.closeContextMenu();

124

}

125

126

// Close menu on escape key

127

document.addEventListener('keydown', (e) => {

128

if (e.key === 'Escape' && ContextMenu.isAnyContextMenuOpen()) {

129

ContextMenu.closeContextMenu();

130

}

131

});

132

```

133

134

### Check Menu Status

135

136

Check if any context menu is currently open.

137

138

```typescript { .api }

139

/**

140

* Check if any context menu is currently open

141

* @returns true if a context menu is open, false otherwise

142

*/

143

function isAnyContextMenuOpen(): boolean;

144

```

145

146

**Usage:**

147

148

```typescript

149

import ContextMenu from '@imengyu/vue3-context-menu';

150

151

// Conditional logic based on menu state

152

function handleGlobalClick() {

153

if (ContextMenu.isAnyContextMenuOpen()) {

154

// Don't perform action if menu is open

155

return;

156

}

157

158

performGlobalAction();

159

}

160

161

// Prevent multiple menus

162

function showMenuIfNoneOpen(e: MouseEvent) {

163

if (!ContextMenu.isAnyContextMenuOpen()) {

164

ContextMenu.showContextMenu({

165

x: e.x,

166

y: e.y,

167

items: getMenuItems()

168

});

169

}

170

}

171

```

172

173

### Transform Menu Position

174

175

Transform menu display position for scaled containers or special positioning needs.

176

177

```typescript { .api }

178

/**

179

* Transform menu position for scaled containers

180

* @param element - Target element for position calculation

181

* @param x - X coordinate relative to element

182

* @param y - Y coordinate relative to element

183

* @param container - Optional container element for position calculation

184

* @returns Transformed coordinates for menu display

185

*/

186

function transformMenuPosition(

187

element: HTMLElement,

188

x: number,

189

y: number,

190

container?: HTMLElement

191

): { x: number, y: number };

192

```

193

194

**Usage:**

195

196

```typescript

197

import ContextMenu from '@imengyu/vue3-context-menu';

198

199

// Handle scaled containers

200

function onContextMenuInScaledContainer(e: MouseEvent) {

201

e.preventDefault();

202

203

const target = e.target as HTMLElement;

204

const scaledContainer = document.getElementById('scaled-container');

205

206

// Transform position to account for scaling

207

const position = ContextMenu.transformMenuPosition(

208

target,

209

e.offsetX,

210

e.offsetY,

211

scaledContainer

212

);

213

214

ContextMenu.showContextMenu({

215

x: position.x,

216

y: position.y,

217

items: getMenuItems(),

218

getContainer: () => scaledContainer

219

});

220

}

221

```

222

223

## Configuration Options

224

225

### MenuOptions Interface

226

227

Complete configuration interface for context menu display and behavior.

228

229

```typescript { .api }

230

interface MenuOptions {

231

/** Array of menu items to display */

232

items?: MenuItem[];

233

/** X coordinate for menu display */

234

x: number;

235

/** Y coordinate for menu display */

236

y: number;

237

/** X-coordinate offset between submenu and parent */

238

xOffset?: number;

239

/** Y-coordinate offset between submenu and parent */

240

yOffset?: number;

241

/** Menu popup direction relative to coordinates */

242

direction?: MenuPopDirection;

243

/** Z-index for menu display */

244

zIndex?: number;

245

/** Zoom level for menu display */

246

zoom?: number;

247

/** Custom CSS class for menu styling */

248

customClass?: string;

249

/** Enable mouse scroll in menu area */

250

mouseScroll?: boolean;

251

/** Reserve space for up/down scroll buttons */

252

updownButtonSpaceholder?: boolean;

253

/** Theme name for menu styling */

254

theme?: string;

255

/** Class name to ignore click events */

256

ignoreClickClassName?: string;

257

/** Close menu when clicking outside */

258

clickCloseOnOutside?: boolean;

259

/** Class name that closes menu when clicked */

260

clickCloseClassName?: string;

261

/** Custom icon font class name */

262

iconFontClass?: string;

263

/** Vue transition properties for menu animations */

264

menuTransitionProps?: TransitionProps;

265

/** Reserve icon width for items without icons */

266

preserveIconWidth?: boolean;

267

/** Enable keyboard navigation control */

268

keyboardControl?: boolean;

269

/** Maximum menu width in pixels */

270

maxWidth?: number;

271

/** Maximum menu height in pixels */

272

maxHeight?: number;

273

/** Minimum menu width in pixels */

274

minWidth?: number;

275

/** Close menu when user scrolls */

276

closeWhenScroll?: boolean;

277

/** Padding for submenu position adjustment */

278

adjustPadding?: { x: number, y: number } | number;

279

/** Automatically adjust menu position to prevent overflow */

280

adjustPosition?: boolean;

281

/** Custom container element for menu mounting */

282

getContainer?: HTMLElement | (() => HTMLElement);

283

/** Callback when menu is closing */

284

onClose?: (lastClickItem: MenuItem | undefined) => void;

285

/** Callback when user clicks outside (when clickCloseOnOutside is false) */

286

onClickOnOutside?: (e: MouseEvent) => void;

287

/** Callback for left keyboard focus movement (MenuBar use) */

288

onKeyFocusMoveLeft?: () => void;

289

/** Callback for right keyboard focus movement (MenuBar use) */

290

onKeyFocusMoveRight?: () => void;

291

}

292

```

293

294

### MenuItem Interface

295

296

Configuration for individual menu items including appearance, behavior, and submenu support.

297

298

```typescript { .api }

299

interface MenuItem {

300

/** Menu item label text or custom render function */

301

label?: string | VNode | ((label: string) => VNode);

302

/** Menu item icon (CSS class, image path, or VNode) */

303

icon?: string | VNode | ((icon: string) => VNode);

304

/** Custom icon font class name */

305

iconFontClass?: string;

306

/** Reserve icon width for this item */

307

preserveIconWidth?: boolean;

308

/** SVG symbol icon reference */

309

svgIcon?: string;

310

/** SVG element properties */

311

svgProps?: SVGAttributes;

312

/** Disable menu item */

313

disabled?: boolean | ComputedRef<boolean>;

314

/** Hide menu item */

315

hidden?: boolean | ComputedRef<boolean>;

316

/** Show check mark on menu item */

317

checked?: boolean | ComputedRef<boolean>;

318

/** Shortcut key text display */

319

shortcut?: string;

320

/** Submenu popup direction */

321

direction?: MenuPopDirection;

322

/** Auto-adjust submenu position */

323

adjustSubMenuPosition?: boolean;

324

/** Allow click event when item has children */

325

clickableWhenHasChildren?: boolean;

326

/** Close menu when this item is clicked */

327

clickClose?: boolean;

328

/** Separator configuration */

329

divided?: boolean | 'up' | 'down' | 'self';

330

/** Custom CSS class for item */

331

customClass?: string;

332

/** Maximum height for submenu */

333

maxHeight?: number;

334

/** Maximum width for submenu */

335

maxWidth?: number | string;

336

/** Minimum width for submenu */

337

minWidth?: number | string;

338

/** Click event handler */

339

onClick?: (e?: MouseEvent | KeyboardEvent) => void;

340

/** Submenu close event handler */

341

onSubMenuClose?: (itemInstance?: MenuItemContext) => void;

342

/** Submenu open event handler */

343

onSubMenuOpen?: (itemInstance?: MenuItemContext) => void;

344

/** Custom render function for item */

345

customRender?: VNode | ((item: MenuItem) => VNode);

346

/** Child menu items for submenu */

347

children?: MenuItem[];

348

}

349

```

350

351

## Context Menu Instance

352

353

The returned instance from `showContextMenu` provides methods to control the displayed menu.

354

355

```typescript { .api }

356

interface ContextMenuInstance {

357

/** Close the menu programmatically */

358

closeMenu(fromItem?: MenuItem | undefined): void;

359

/** Check if the menu is currently closed */

360

isClosed(): boolean;

361

/** Get the root menu instance for advanced control */

362

getMenuRef(): ContextSubMenuInstance | undefined;

363

/** Get menu dimensions in pixels */

364

getMenuDimensions(): { width: number, height: number };

365

}

366

367

interface ContextSubMenuInstance {

368

/** Get root element of submenu */

369

getSubmenuRoot(): HTMLElement | undefined;

370

/** Get inner container element */

371

getMenu(): HTMLElement | undefined;

372

/** Get child menu item by index */

373

getChildItem(index: number): MenuItemContext | undefined;

374

/** Get submenu dimensions */

375

getMenuDimensions(): { width: number, height: number };

376

/** Get/set scroll position */

377

getScrollValue(): number;

378

setScrollValue(v: number): void;

379

/** Get maximum scroll height */

380

getScrollHeight(): number;

381

/** Force position adjustment */

382

adjustPosition(): void;

383

/** Get maximum submenu height */

384

getMaxHeight(): number;

385

/** Get/set submenu position */

386

getPosition(): { x: number, y: number };

387

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

388

}

389

```