block-types > Toggle Block

Toggle Block

The Toggle block is used to create collapsible content. It's an interactive element where hidden content expands or collapses when the user clicks on the toggle.

Data Structure

The Notion API data structure for a Toggle block is as follows:

{
  "type": "toggle",
  "toggle": {
    "rich_text": [
      {
        "type": "text",
        "text": {
          "content": "Click to toggle",
          "link": null
        },
        "annotations": {
          "bold": false,
          "italic": false,
          "strikethrough": false,
          "underline": false,
          "code": false,
          "color": "default"
        },
        "plain_text": "Click to toggle",
        "href": null
      }
    ],
    "color": "default",
    "children": [
      // Nested blocks...
    ]
  }
}
  • rich_text: An array containing the display text and style information of the toggle.
  • color: Specifies the color of the toggle text.
  • children: An array of nested blocks that will be displayed when the toggle is expanded.

React Component

The component that renders the Toggle block in Notionpresso is as follows:

import React, { useState, useCallback } from "react";
import type { ToggleArgs } from "../types";
import { getColorCss } from "../utils";
import RichText from "./internal/rich-text";


type ToggleProps = {
children?: React.ReactNode;
} & ToggleArgs;




const Toggle: React.FC<ToggleProps> = ({ children, ...props }) => {
const {
toggle: { color, rich_text: texts },
} = props;




const [open, setOpen] = useState(false);




const toggleOpen = useCallback(() => setOpen((prevOpen) => !prevOpen), []);




return (
<div
className={notion-block notion-toggle ${getColorCss(color)} ${         open ? "notion-toggle-open" : ""       }}
aria-expanded={open}
>
<div className="notion-toggle-content">
<button onClick={toggleOpen} className="notion-toggle-button">
<div
className={notion-toggle-button-arrow ${               open ? "notion-toggle-button-arrow-opened" : ""             }}
/>
</button>
<p>
<RichText props={texts} />
</p>
</div>



  {open &#x26;&#x26; children}
&#x3C;/div>




);
};




export default Toggle;

export default Toggle;

Usage Example

Here's an example of how to use the Toggle block:

import { Notion } from "@notionpresso/react";


function MyNotionPage({ blocks }) {
return (
<Notion>
<Notion.Blocks blocks={blocks} />
</Notion>
);
}

function MyNotionPage({ blocks }) { return ( <Notion> <Notion.Blocks blocks={blocks} /> </Notion> ); }

Here, blocks is an array of block data received from the Notion API.

State Management

The Toggle block internally uses the useState hook to manage its open/closed state. The open state variable represents the current state of the toggle, and the toggleOpen function switches this state.

Styling

The style of the Toggle block can be customized through the following CSS classes:

  • .notion-block: Basic style applied to all Notion blocks
  • .notion-toggle: Specific style for Toggle blocks
  • .notion-toggle-open: Style for when the toggle is in the open state
  • .notion-toggle-content: Style for the toggle content
  • .notion-toggle-button: Style for the toggle button
  • .notion-toggle-button-arrow: Style for the toggle arrow

If additional styling is needed, you can write CSS targeting these classes. For example:

.notion-toggle {
  margin-bottom: 8px;
}


.notion-toggle-button {
cursor: pointer;
background: none;
border: none;
padding: 0;
margin-right: 4px;
}




.notion-toggle-button-arrow {
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 5px solid #333;
transition: transform 0.3s ease;
}




.notion-toggle-button-arrow-opened {
transform: rotate(180deg);
}

.notion-toggle-button-arrow-opened { transform: rotate(180deg); }

Nesting Support

Toggle blocks can contain other blocks. This is handled through the children prop. The children are only rendered when the toggle is in the open state.

Accessibility Considerations

  • The aria-expanded attribute is used to inform screen readers of the toggle's current state.
  • It's good to add tabIndex={0} to the toggle button to support keyboard navigation.
  • Providing an appropriate aria-label to the toggle button is recommended to clearly describe its function.

Notes

  • Including too much content inside a toggle can degrade the user experience, so it's best to include only an appropriate amount of content.
  • The open/closed state of toggles is not stored on the server, so all toggles will return to their default state (closed) when the page is refreshed.
  • Deeply nested toggles can confuse users, so it's best to limit the nesting levels as much as possible.