Blocks: Another Way to Adjust Settings

As I’ve mentioned a few times, one of the ways you can adjust settings on a block in Gutenberg is via the sidebar. In fact, this is the default way most people will interact with block settings.

If you make a paragraph today, you can see it like this:

This is the default paragraph sidebar from Gutenberg. No customizations.

But. I don’t actually like it very much. I appreciate that I have it, and I love that I can get it out of the way. But sometimes I like settings to be a little more contextual.

It’s Easy to Add Sidebar Settings

One of the reasons we all use sidebar settings is that, well, they’re easy. When I built out my listicles plugin, I could use the inspector controls and automagically I have my own settings.

This:

<InspectorControls>
	<PanelBody title={ 'Listicle Settings' }>
		<RangeControl
			label={ 'Items' }
			value={ items }
			onChange={ ( value ) => setAttributes( { items: value } ) }
			min={ 1 }
			max={ MAX_ITEMS }
		/>
		<ToggleControl
			label={ 'Reversed' }
			help={ ( checked ) => checked ? 'Reversed order (10 - 1)' : 'Numerical order (1 - 10)' }
			checked={ props.attributes.reversed }
			onChange={ () => props.setAttributes( { reversed: ! props.attributes.reversed } ) }
		/>
	</PanelBody>
</InspectorControls>

Looks like this:

A screenshot of the listicle settings, which are a slider for the items and a toggle to reverse the order display.

But like I said, I don’t like it very much. It’s clunky, it’s touchy, if you delete the number and type in a new one it’ll wipe all your data. And worst of all, my partner in crime, Tracy, hates it. If your work partners hate a tool, then it’s serious problem. I’ll put up with annoyances to me, but I’ll learn new code for the team.

Think About What’s Easier

Before I get into the code I used to solve the issue, I want to take a moment to talk about theory and understanding usage.

One of the critiques about Gutenberg is that it’s changing too much too quickly, and it’s not listening to users. The problem with that complaint is it lacks context. I’m big on context because I believe that only with understanding the usage and context can we as a whole make the correct decisions going forward. What changes, when, and why depends entirely on what’s being used, for what, and why.

It’s much more direct to understand this when I look at my little listicles block. You see, we use it for one thing: to make lists with a specific format. And we have few requirements.

  • Add and remove items
  • Add content of myriad types to each item
  • Be able to reverse the item count (1 to 10 or 10 to 1)

That’s really it. Except now I’m adding one more thing:

  • An easier, inline, way to add/remove/toggle items.

So I sat and I thought about what would be the easiest to use, and I came up with a simple solution. Three buttons, one to add an item, one to remove, and one to toggle the order. Have those show perpetually at the bottom of the list, and you could easily add and remove as needed.

It’s Actually Easy To Add Buttons

Once I knew what I wanted, I took a page from some work Yoast is doing and sketched my idea to look like this:

Three buttons: Add item, remove item, and toggle order

In order to do this, I needed to add some code to the bottom of my <dl> code:

<div className='listicles-buttons'>
	<IconButton
		icon='insert'
		onClick={ () => setAttributes( { items: parseInt(`${ items }`)+1 } ) }
		className='editor-inserter__toggle'
	>Add Item</IconButton>

	<IconButton
		icon='dismiss'
		onClick={ () => setAttributes( { items: parseInt(`${ items }`)-1 } ) }
		className='editor-inserter__toggle'
	>Remove Item</IconButton>

	<IconButton
		icon='controls-repeat'
		onClick={ () => setAttributes( { reversed: ! reversed } ) }
		className='editor-inserter__toggle'
	>Toggle Order</IconButton>
</div>

This sits inside the <dl> and just below my <InnerBlocks...> insert. It generates the buttons, which change when you hover by default.

Now it’s not perfect. If you deleted all the items and pressed delete again, it would sure try to delete. I didn’t put in checks to make sure we didn’t go below 0 or above 18 (which is my current limits). But this is the start to make sure we can keep improving and iterating.

%d