Great question, and you are almost there. The issue is that Blockly has two incompatible save formats, and each requires different hooks. You are using XML, but your hooks (saveExtraState/loadExtraState) are for JSON. So either use JSON as your save format, or use the XML hooks (mutationToDom/domToMutation).
If you want to use XML, then a good block to look at is math_number_property. It is an interesting block because the second input appears or disappears depending on whether the dropdown is set to "divisible by" or not. At least that's what the user sees. In practice the existence of this input is due to a mutation.
If you load this XML:
Then you get this block:
But if you load this XML:
You get this block:
The code for this is here:
So what you need to do is add a pair of 'mutationToDom' and a 'domToMutation' functions to your block. If it's just a binary flag that needs to be stored ("no options" vs "more options") then it's really simple:
mutationToDom: function() {
const container = xmlUtils.createElement('mutation');
const moreOptions = YOUR CODE TO DETERMINE IF 'MORE OPTIONS' IS ENABLED;
container.setAttribute('more_options', Boolean(moreOptions));
return container;
},
domToMutation: function(xmlElement) {
const moreOptions = (xmlElement.getAttribute('moreOptions') === 'true');
YOUR CODE TO CREATE MORE OPTIONS IF moreOptions IS TRUE.
},
Using mutationToDom, you can encode any data you want on the XML mutation container. Any format, doesn't matter. But then it's your responsibility to be able to parse and read your data back in domToMutation.