From 9eade4ac460f2e4be3ddde03f12d9d77aad5e7b6 Mon Sep 17 00:00:00 2001 From: LappiLappland Date: Thu, 28 May 2026 20:26:09 +0300 Subject: [PATCH] feat: truncate long text in menu items --- packages/blockly/core/menuitem.ts | 14 ++++++++++++- .../blockly/tests/mocha/menu_item_test.js | 21 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/packages/blockly/core/menuitem.ts b/packages/blockly/core/menuitem.ts index 454e35744ef..5c92d253d42 100644 --- a/packages/blockly/core/menuitem.ts +++ b/packages/blockly/core/menuitem.ts @@ -13,11 +13,15 @@ import * as aria from './utils/aria.js'; import * as idGenerator from './utils/idgenerator.js'; +import * as tooltip from './tooltip.js'; /** * Class representing an item in a menu. */ export class MenuItem { + /** Maximum characters of text to display before adding an ellipsis. */ + maxDisplayLength = 50; + /** Is the menu item clickable, as opposed to greyed-out. */ private enabled = true; @@ -76,7 +80,15 @@ export class MenuItem { let contentDom: Node = this.content as HTMLElement; if (typeof this.content === 'string') { - contentDom = document.createTextNode(this.content); + let displayText = this.content; + if (this.content.length > this.maxDisplayLength) { + displayText = this.content.substring(0, this.maxDisplayLength - 1) + '…'; + + (element as any).tooltip = this.content; + tooltip.bindMouseEvents(element); + } + + contentDom = document.createTextNode(displayText); } content.appendChild(contentDom); element.appendChild(content); diff --git a/packages/blockly/tests/mocha/menu_item_test.js b/packages/blockly/tests/mocha/menu_item_test.js index 7690c0f187e..52d22c4a3f4 100644 --- a/packages/blockly/tests/mocha/menu_item_test.js +++ b/packages/blockly/tests/mocha/menu_item_test.js @@ -173,4 +173,25 @@ suite('Menu items', function () { this.menuItem.performAction(new Event('click')); assert.isTrue(called); }); + + test('truncates long text and binds tooltip', function () { + const longText = 'w'.repeat(300); + this.menuItem = new Blockly.MenuItem(longText); + this.menuItem.createDom(); + + const element = this.menuItem.getElement(); + assert.equal(element.textContent.length, this.menuItem.maxDisplayLength); + assert.isTrue(element.textContent.endsWith('…')); + assert.equal(element.tooltip, longText); + }); + + test('does not truncate or bind tooltip for short text', function () { + const shortText = 'Hello World'; + this.menuItem = new Blockly.MenuItem(shortText); + this.menuItem.createDom(); + + const element = this.menuItem.getElement(); + assert.equal(element.textContent, shortText); + assert.isUndefined(element.tooltip); + }); });