Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Custom Toolbox Categories Limited to 3 in Blockly v11

82 views
Skip to first unread message

Samuel Álvarez Pérez

unread,
Apr 14, 2025, 11:37:39 AMApr 14
to Blockly
Description

When using Blockly v11, I've encountered a limitation where having more than 3 categories with kind="custom_category" causes the toolbox to fail completely. With exactly 3 custom categories, everything works perfectly. As soon as a 4th custom category is added, the toolbox no longer functions.

Steps to Reproduce

1. Create a toolbox with 3 categories that have kind="custom_category":
<xml id="toolbox">
<category name="Category1" colour="#ff0000" kind="custom_category" iconClass="fa-solid fa-image"></category>
<category name="Category2" colour="#00ff00" kind="custom_category" iconClass="fa-solid fa-image"></category>
<category name="Category3" colour="#0000ff" kind="custom_category" iconClass="fa-solid fa-image"></category>
</xml>

Result: Toolbox works as expected.

2. Add a 4th category with kind="custom_category":
<xml id="toolbox">
<category name="Category1" colour="#ff0000" kind="custom_category" iconClass="fa-solid fa-image"></category>
<category name="Category2" colour="#00ff00" kind="custom_category" iconClass="fa-solid fa-image"></category>
<category name="Category3" colour="#0000ff" kind="custom_category" iconClass="fa-solid fa-image"></category>
<category name="Category4" colour="#ffff00" kind="custom_category" iconClass="fa-solid fa-image"></category>
</xml>

Result: Toolbox completely fails to render or function.

Environment
  • Blockly version: 11.0.0
  • Browser: Chrome 123.0.6312.86 (also reproduced in Firefox and Safari)
  • OS: macOS 14.4.1
Custom Category Implementation
I've implemented a custom category class that adds icons to category buttons:

class CustomToolboxCategory extends Blockly.ToolboxCategory {
private iconClass_: string;

constructor(categoryDef: any, toolbox: Blockly.Toolbox, opt_parent?: any) {
super(categoryDef, toolbox, opt_parent);

if (categoryDef['xml'] && categoryDef['xml'].getAttribute) {
this.iconClass_ = categoryDef['xml'].getAttribute('iconClass') || '';
} else if (categoryDef['iconClass']) {
this.iconClass_ = categoryDef['iconClass'];
}
}

public override createDom_(): HTMLDivElement {
const categoryDom = super.createDom_();
const labelElement = categoryDom.querySelector('.blocklyTreeLabel') as HTMLElement;
if (labelElement && this.iconClass_) {
const iconElement = document.createElement('i');
iconElement.className = this.iconClass_;
iconElement.style.marginRight = '8px';
labelElement.insertBefore(iconElement, labelElement.firstChild);
}

return categoryDom as HTMLDivElement;
}
}

// Registration
Blockly.registry.register(
Blockly.registry.Type.TOOLBOX_ITEM,
'custom_category',
CustomToolboxCategory,
true
);

Expected Behavior

All 4 categories should display and function normally with their custom icons and behaviors.

Actual Behavior

When using 4 or more custom categories, the toolbox fails to render at all. Removing just one custom category (changing to regular category) immediately fixes the issue.

I have the following error:

free-world.page.ts:89 ERROR TypeError: Cannot read properties of null (reading 'getSelectedItem')
    at ContinuousFlyout.show (ContinuousFlyout.js:227:34)
    at init$$module$build$src$core$inject (blockly_compressed.js:430:277)
    at inject$$module$build$src$core$inject (blockly_compressed.js:423:278)
    at ************.renderBlockly (ngx-blockly.component.ts:119:28)
    at ************.ngOnChanges (ngx-blockly.component.ts:85:10)
    at ************.rememberChangeHistoryAndInvokeOnChangesHook (core.mjs:3139:14)
    at callHookInternal (core.mjs:4207:14)
    at callHook (core.mjs:4238:9)
    at callHooks (core.mjs:4188:17)
    at executeInitAndCheckHooks (core.mjs:4138:9)

This appears to be a regression in Blockly v11, as the same code works with more than 3 custom categories in earlier versions.

Would greatly appreciate any insights on workarounds or if this is a known limitation that should be documented.

Ben Henning

unread,
Apr 16, 2025, 8:23:57 PMApr 16
to Blockly
Hi,

I've tried to reproduce this issue, but didn't have any success (though I did notice other problems, but that well could be due to my setup). I updated a local checkout of the latest Blockly v11 and updated its playground.html like so: https://gist.github.com/BenHenning/5f03095263d9ad97a8ec96e31d4d96cf. This was meant to mimic what you're doing as closely as possible, and I see no issues with adding more than 3 custom categories. I did notice that having only custom categories resulted in nothing showing up (which is part of the 'noticed other problems').

One consideration I had: per https://blocklycodelabs.dev/codelabs/custom-toolbox/index.html?index=..%2F..index#0 it's generally recommended to style categories based on CSS before going the route of implementing a custom category class. Is it possible for you revise your implementation using only CSS? That may bypass the problem presented here altogether. It seems like it might be possible from looking at your code, but it's possible that your snippet isn't a complete representation of what's happening.

In the event you do still need the custom class, it seems that the error that you provided is specifically tied to the ContinuousFlyout plugin. For some reason, the parent toolbox is uninitialized when it's time to show the flyout. The toolbox is created pretty early in the workspace lifecycle (during DOM creation) so in most cases it should always be present unless 'hasCategories' is false in the options object used when initializing Blockly. You can see that in options.ts 'hasCategories' is true when the provided toolbox info has categories defined. One option you might have is to step through this code or add console statements to a locally linked copy of Blockly to better understand where there's an issue happening. It's not yet clear if this is a problem with the configuration or with interpreting the configuration, so better understanding whether the categories are being interpreted correctly seems like a good next step.

I'll be happy to share additional thoughts based on how the next bits of the investigation go.

Ben

Samuel Álvarez Pérez

unread,
Apr 29, 2025, 11:26:38 AMApr 29
to Blockly
Thanks for the reply, Ben. Your comment was crucial for me to realize that the problem was not related to a specific limit of categories (3 to 4), but to the fact that all categories were custom. After multiple tests, I confirmed that Blockly v11 does indeed have a regression when all categories in the toolbox are marked with kind="custom_category".

For now, the only workaround I have been able to implement, since I need to use exclusively custom categories, is to add an additional “fake” category that I completely hide using CSS (title, icon and content), so that it does not interfere visually or functionally with the rest of the toolbox. This allows the toolbox to work correctly.

I hope this problem can be fixed in future updates. Thanks again for the help and clarification.

Samuel Álvarez Pérez

unread,
Apr 29, 2025, 11:26:38 AMApr 29
to Blockly
Thanks for the reply, Ben. Your comment was crucial for me to realize that the problem was not related to a specific limit of categories (3 to 4), but to the fact that all categories were custom. After multiple tests, I confirmed that Blockly v11 does indeed have a regression when all categories in the toolbox are marked with kind="custom_category".

For now, the only workaround I have been able to implement, since I need to use exclusively custom categories, is to add an additional “fake” category that I completely hide using CSS (title, icon and content), so that it does not interfere visually or functionally with the rest of the toolbox. This allows the toolbox to work correctly.

I hope this problem can be fixed in future updates. Thanks again for the help and clarification.

Reply all
Reply to author
Forward
0 new messages