diff --git a/CHANGELOG.md b/CHANGELOG.md
index 83b16d39..67b9dc4c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,18 @@
 
 > Documentation: [draftail.org/docs/next/getting-started](https://www.draftail.org/docs/next/getting-started)
 
+### Added
+
+- Make it possible to hide buttons with default labels by setting their `label` to `null`. [#442](https://github.com/springload/draftail/pull/442)
+
+### Changed
+
+- Improve the editor props’ JSDoc annotations. [#441](https://github.com/springload/draftail/pull/441)
+
+### Fixed
+
+- Fix empty buttons appearing when providing custom formats without a defined label or icon. [#442](https://github.com/springload/draftail/pull/442)
+
 ## [[v1.3.0]](https://github.com/springload/draftail/releases/tag/v1.3.0)
 
 > Documentation: [draftail.org/docs/getting-started](https://www.draftail.org/docs/getting-started)
diff --git a/examples/components/BlockPicker.js b/examples/components/BlockPicker.js
new file mode 100644
index 00000000..10a9e833
--- /dev/null
+++ b/examples/components/BlockPicker.js
@@ -0,0 +1,44 @@
+// @flow
+import React from "react";
+import { EditorState, RichUtils } from "draft-js";
+
+import { BLOCK_TYPE } from "../../lib";
+
+type Props = {|
+  getEditorState: () => EditorState,
+  onChange: (EditorState) => void,
+|};
+
+/**
+ * A traditional text style picker.
+ */
+const BlockPicker = ({ getEditorState, onChange }: Props) => {
+  const editorState = getEditorState();
+
+  return (
+    <select
+      onChange={(e) => {
+        const selection = editorState.getSelection();
+        let nextState = editorState;
+        nextState = RichUtils.toggleBlockType(nextState, e.target.value);
+        nextState = EditorState.forceSelection(nextState, selection);
+        onChange(nextState);
+      }}
+      style={{ maxWidth: "3rem" }}
+    >
+      {[
+        [BLOCK_TYPE.HEADER_TWO, "H2"],
+        [BLOCK_TYPE.HEADER_THREE, "H3"],
+        [BLOCK_TYPE.HEADER_FOUR, "H4"],
+        ["tiny-text", "ₜᵢₙᵧ"],
+        [BLOCK_TYPE.UNSTYLED, "¶"],
+      ].map(([type, label]) => (
+        <option key={type} value={type}>
+          {label}
+        </option>
+      ))}
+    </select>
+  );
+};
+
+export default BlockPicker;
diff --git a/examples/components/ColorPicker.scss b/examples/components/ColorPicker.scss
index 91d91297..f608ce62 100644
--- a/examples/components/ColorPicker.scss
+++ b/examples/components/ColorPicker.scss
@@ -4,7 +4,3 @@
   padding-block-start: 1rem;
   padding-block-end: 1rem;
 }
-
-.Draftail-ToolbarButton[name^="COLOR_"] {
-  display: none;
-}
diff --git a/examples/docs.story.js b/examples/docs.story.js
index a2025450..782d6ac7 100644
--- a/examples/docs.story.js
+++ b/examples/docs.story.js
@@ -20,6 +20,7 @@ import {
 import EditorWrapper from "./components/EditorWrapper";
 import PrismDecorator from "./components/PrismDecorator";
 import ReadingTime from "./components/ReadingTime";
+import BlockPicker from "./components/BlockPicker";
 
 storiesOf("Docs", module)
   // Add a decorator rendering story as a component for hooks support.
@@ -204,7 +205,17 @@ storiesOf("Docs", module)
         entityMap: {},
       }}
       stripPastedStyles={false}
-      controls={[ReadingTime]}
+      blockTypes={[
+        { type: BLOCK_TYPE.HEADER_TWO, label: null },
+        { type: BLOCK_TYPE.HEADER_THREE, label: null },
+        { type: BLOCK_TYPE.HEADER_FOUR, label: null },
+        BLOCK_CONTROL.CODE,
+        {
+          type: "tiny-text",
+          element: "blockquote",
+        },
+      ]}
+      controls={[BlockPicker, ReadingTime]}
     />
   ))
   .add("UI theming", () => (
diff --git a/examples/plugins/sectionBreakPlugin.scss b/examples/plugins/sectionBreakPlugin.scss
index 34970428..8c7e1785 100644
--- a/examples/plugins/sectionBreakPlugin.scss
+++ b/examples/plugins/sectionBreakPlugin.scss
@@ -1,7 +1,3 @@
-[name="section-break"] {
-  display: none;
-}
-
 .SectionBreak {
   border-bottom: 1px solid #aaa;
   text-align: center;
diff --git a/lib/components/DraftailEditor.js b/lib/components/DraftailEditor.js
index 8f110690..51282cbd 100644
--- a/lib/components/DraftailEditor.js
+++ b/lib/components/DraftailEditor.js
@@ -38,7 +38,7 @@ import DividerBlock from "../blocks/DividerBlock";
 
 type ControlProp = {|
   /** Describes the control in the editor UI, concisely. */
-  label?: string,
+  label?: ?string,
   /** Describes the control in the editor UI. */
   description?: string,
   /** Represents the control in the editor UI. */
diff --git a/lib/components/ToolbarDefaults.js b/lib/components/ToolbarDefaults.js
index ab61ec2a..bb9847e8 100644
--- a/lib/components/ToolbarDefaults.js
+++ b/lib/components/ToolbarDefaults.js
@@ -17,7 +17,7 @@ import type { IconProp } from "./Icon";
 
 type ControlProp = {
   // Describes the control in the editor UI, concisely.
-  label?: string,
+  label?: ?string,
   // Describes the control in the editor UI.
   description?: string,
   // Represents the control in the editor UI.
@@ -27,7 +27,7 @@ type ControlProp = {
 const getButtonLabel = (type: string, config: boolean | ControlProp) => {
   const icon = typeof config === "boolean" ? undefined : config.icon;
 
-  if (typeof config.label === "string") {
+  if (typeof config.label === "string" || config.label === null) {
     return config.label;
   }
 
@@ -38,6 +38,9 @@ const getButtonLabel = (type: string, config: boolean | ControlProp) => {
   return LABELS[type];
 };
 
+const showButton = (config: ControlProp & { type: string }) =>
+  Boolean(config.icon) || Boolean(getButtonLabel(config.type, config));
+
 const getButtonTitle = (type: string, config: boolean | ControlProp) => {
   const description =
     typeof config === "boolean" || typeof config.description === "undefined"
@@ -104,7 +107,7 @@ class ToolbarDefaults extends PureComponent<ToolbarDefaultProps> {
     } = this.props;
     return [
       <ToolbarGroup key="styles">
-        {inlineStyles.map((t) => (
+        {inlineStyles.filter(showButton).map((t) => (
           <ToolbarButton
             key={t.type}
             name={t.type}
@@ -118,7 +121,7 @@ class ToolbarDefaults extends PureComponent<ToolbarDefaultProps> {
       </ToolbarGroup>,
 
       <ToolbarGroup key="blocks">
-        {blockTypes.map((t) => (
+        {blockTypes.filter(showButton).map((t) => (
           <ToolbarButton
             key={t.type}
             name={t.type}
@@ -166,7 +169,7 @@ class ToolbarDefaults extends PureComponent<ToolbarDefaultProps> {
       </ToolbarGroup>,
 
       <ToolbarGroup key="entities">
-        {entityTypes.map((t) => (
+        {entityTypes.filter(showButton).map((t) => (
           <ToolbarButton
             key={t.type}
             name={t.type}
diff --git a/lib/components/ToolbarDefaults.test.js b/lib/components/ToolbarDefaults.test.js
index d5330f31..8603668c 100644
--- a/lib/components/ToolbarDefaults.test.js
+++ b/lib/components/ToolbarDefaults.test.js
@@ -196,6 +196,87 @@ describe("ToolbarDefaults", () => {
     expect(wrapper.find("ToolbarButton").prop("label")).toBe("Format as bold");
   });
 
+  it("custom button without label nor icon", () => {
+    const wrapper = mount(
+      <ToolbarDefaults
+        {...mockProps}
+        blockTypes={[
+          {
+            type: "emphasize",
+          },
+        ]}
+        inlineStyles={[
+          {
+            type: "EMPHASIZE",
+          },
+        ]}
+        entityTypes={[
+          {
+            type: "CUSTOM_LINK",
+            source: () => {},
+          },
+        ]}
+      />,
+    );
+    expect(wrapper.find("ToolbarButton").exists()).toBe(false);
+  });
+
+  it("built-in button with empty label", () => {
+    const wrapper = mount(
+      <ToolbarDefaults
+        {...mockProps}
+        blockTypes={[
+          {
+            type: "blockquote",
+            label: "",
+          },
+        ]}
+        inlineStyles={[
+          {
+            type: "BOLD",
+            label: "",
+          },
+        ]}
+        entityTypes={[
+          {
+            type: "LINK",
+            label: "",
+            source: () => {},
+          },
+        ]}
+      />,
+    );
+    expect(wrapper.find("ToolbarButton").exists()).toBe(false);
+  });
+
+  it("built-in button with null label", () => {
+    const wrapper = mount(
+      <ToolbarDefaults
+        {...mockProps}
+        blockTypes={[
+          {
+            type: "blockquote",
+            label: null,
+          },
+        ]}
+        inlineStyles={[
+          {
+            type: "BOLD",
+            label: null,
+          },
+        ]}
+        entityTypes={[
+          {
+            type: "LINK",
+            label: null,
+            source: () => {},
+          },
+        ]}
+      />,
+    );
+    expect(wrapper.find("ToolbarButton").exists()).toBe(false);
+  });
+
   it("button titles with shortcut", () => {
     expect(
       mount(
