Skip to main content

Customizing a Blockly toolbox

8. Adding a custom toolbox item

In the previous sections we modified the toolbox by extending the base category class. In this section we will make a completely new toolbox item and add it to our toolbox.

For this example, we are going to create a toolbox label.

Setup

In the same directory as index.js create a new file named toolbox_label.js. Create a class in toolbox_label.js that extends Blockly.ToolboxItem and create a function to register it.

import * as Blockly from 'blockly';

class ToolboxLabel extends Blockly.ToolboxItem {
// You'll add functions to this class soon

}

export function registerToolboxLabel() {
Blockly.registry.register(
Blockly.registry.Type.TOOLBOX_ITEM,
'toolboxlabel',
ToolboxLabel,
);
}

As with the custom category, you'll also need to import the registration function in index.js. To register the toolbox label, call the registerToolboxLabel() function in index.js, just after registering the custom category:

import { registerToolboxLabel } from './toolbox_label.js';

...

// Register the custom category
registerCustomCategory();
// Register the toolbox label
registerToolboxLabel();

By registering this toolbox item with the name "toolboxlabel" we can now use this name in our toolbox definition to add our custom item to the toolbox.

Navigate to toolbox.js, and add a toolboxlabel as the first item in the list of toolbox contents:

{
kind: 'toolboxlabel',
}

Your toolbox definition should now look something like:

export const toolbox = {
kind: 'categoryToolbox',
contents: [
{
kind: 'toolboxlabel',
},
{ kind: 'category', name: 'Logic', /* etc */ },
// ...
]
}

Initialize the toolbox item

In order to create a toolbox item we must implement one of the toolbox item interfaces.

For this example, we will be implementing the basic IToolboxItem interface. There are three different types of toolbox item interfaces: IToolboxItem, ISelectableToobloxItem and ICollapsibleToolboxItem. Since we do not need our label to be selectable or collapsible, we can implement the basic IToolboxItem interface.

First, we are going to add an init method to the ToolboxLabel class that will create the dom for our toolbox label:

/** @override */
init() {
// Create the label.
this.label = document.createElement('label');
// Set ARIA role and description, so that screenreaders can see and read the label
Blockly.utils.aria.setRole(this.label, Blockly.utils.aria.Role.TREEITEM);
Blockly.utils.aria.setState(
this.label,
Blockly.utils.aria.State.ROLEDESCRIPTION,
'Label',
);
// Set the name.
this.label.textContent = 'Label';
}

The init() function defined above includes setting the ARIA role and state for screenreader support. To learn more, see the [screenreader support doc].(/guides/configure/screen-reader/)

Next, we are going to return this element:

/** @override */
getDiv() {
return this.label;
}

If you refresh the app page you should see a label above your first category.

The toolbox with a label at the top that says "Label."

Add attributes to the toolbox definition

The above code is rather limiting since it only allows us to create a toolbox label with the text "Label". To make it possible to create different labels with different text and colour we are going to add name and colour attributes to our toolbox definition.

Open toolbox.js. Add a name and colour to your toolbox label

contents: [
{
kind: 'toolboxlabel',
name: 'Custom Toolbox',
colour: 'darkslategrey',
},
{ kind: 'category', name: 'Logic', /* etc */ },
// ...
]

These values will get passed in to our ToolboxLabel class through the toolboxItemDef. Navigate to toolbox_label.js and add the following lines to your init method:

// Set the name.
this.label.textContent = this.toolboxItemDef_['name'];
// Set the color.
this.label.style.color = this.toolboxItemDef_['colour'];

Remove the following line from your init method:

this.label.textContent = 'Label';

All attributes on our toolbox definition get added to the toolboxItemDef_. this.toolboxItemDef_ is set in the Blockly.ToolboxItem constructor.

Refresh your app in a browser to see the updated label.

The toolbox with a label that now says "Custom Toolbox".

Add some CSS

Similar to how we added colour and name above, we are going to add a custom class to our label.

Navigate to your toolbox definition in toolbox.js and add the cssconfig.

contents: [
{
kind: 'toolboxlabel',
name: 'Custom Toolbox',
colour: 'darkslategrey',
cssconfig: { label: 'customLabel' },
},
{ kind: 'category', name: 'Logic', /* etc */ },
// ...
]

This gets added to a cssconfig object stored on the toolboxItemDef.

To use this value navigate to toolbox_label.js and add the following lines to your init method.

const cssConfig = this.toolboxItemDef_['cssconfig'];
// Add the class.
if (cssConfig) {
this.label.classList.add(cssConfig['label']);
}

The above code will add the class to the label. Now, in toolbox_style.css add the below CSS to make the label bold.

.customLabel {
font-weight: bold;
}

The result

If you refresh your app you should now see a bold dark gray label at the top of your toolbox.

The toolbox with a label that is now bolded.