Skip to main content

Accordion and pagination

Combine collapsible detail with a page of content and navigation. Your application owns the page state and rebuilds the payload when a navigation callback arrives.

Output

Local preview of the selected language’s tested example. Slack client appearance may differ; controls here do not send requests.

Details
Ready
Result one
Serialized output
{
"channel": "C1",
"mrkdwn": true,
"blocks": [
{
"type": "container",
"block_id": "<generated-block-id>",
"title": {
"type": "plain_text",
"text": "Details"
},
"child_blocks": [
{
"type": "section",
"block_id": "<generated-block-id>",
"text": {
"type": "mrkdwn",
"text": "Ready"
}
}
],
"width": "standard",
"is_collapsible": true,
"default_collapsed": false,
"has_header_divider": false
},
{
"type": "section",
"block_id": "<generated-block-id>",
"text": {
"type": "mrkdwn",
"text": "Result one"
}
},
{
"type": "actions",
"block_id": "<generated-block-id>",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Next"
},
"action_id": "items.next",
"value": "2"
}
]
}
],
"text": "Items"
}

Code​

Python has no named Accordion/Paginator helper. Compose native blocks and keep paging state in the application. Your callback handler reads the destination page and rebuilds the message.

from slackblocks import ActionsBlock, Button, ContainerBlock, Message, SectionBlock

items = ["Result one", "Result two"]
page, page_size = 1, 1
visible = items[(page - 1) * page_size:page * page_size]
blocks = [ContainerBlock(title="Details", is_collapsible=True, child_blocks=[SectionBlock("Ready")])]
blocks.extend(SectionBlock(item) for item in visible)
if page * page_size < len(items):
blocks.append(ActionsBlock(elements=[Button(text="Next", action_id="items.next", value=str(page + 1))]))
print(Message(channel="C1", text="Items", blocks=blocks).json())