Skip to content

feat(blocks): add Card, Carousel, and Alert block types#1865

Open
srtaalej wants to merge 3 commits intomainfrom
ale-new-block-kit-elements
Open

feat(blocks): add Card, Carousel, and Alert block types#1865
srtaalej wants to merge 3 commits intomainfrom
ale-new-block-kit-elements

Conversation

@srtaalej
Copy link
Copy Markdown
Contributor

@srtaalej srtaalej commented Apr 29, 2026

Summary

  • Adds CardBlock — a rich display block for presenting structured content (hero image, icon, title, subtitle, body, actions)
  • Adds CarouselBlock — a horizontally scrollable collection of card blocks (1–10 cards)
  • Adds AlertBlock — a prominent notice block for warnings, status updates, or important information with severity levels (default, info, warning, error, success)

All three blocks include deserialization support via Block.parse(), exports in __init__.py, and round-trip tests.

Note: The AlertBlock is only supported in modal views (views_open / views_update). It is not supported in chat_postMessage or other message surfaces.

Test plan

Test app.py (sends carousel + cards via chat_postMessage on startup)
import os
import logging

from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler

from listeners import register_listeners

logging.basicConfig(level=logging.DEBUG)

# Initialization
app = App(token=os.environ.get("SLACK_BOT_TOKEN"))

# Register Listeners
register_listeners(app)

# Start Bolt app
if __name__ == "__main__":
    app.client.chat_postMessage(
        channel="#test-blockkit-new-types",
        blocks=[
            {
                "type": "carousel",
                "elements": [
                    {
                        "type": "card",
                        "hero_image": {"type": "image", "image_url": "https://picsum.photos/seed/a/400/200", "alt_text": "Card 1 hero"},
                        "title": {"type": "mrkdwn", "text": "Card Block"},
                        "subtitle": {"type": "mrkdwn", "text": "Rich structured content"},
                        "body": {"type": "mrkdwn", "text": "Recommendations, results, or work items."},
                        "actions": [{"type": "button", "text": {"type": "plain_text", "text": "Learn more"}, "action_id": "card_1_btn"}],
                    },
                    {
                        "type": "card",
                        "hero_image": {"type": "image", "image_url": "https://picsum.photos/seed/b/400/200", "alt_text": "Card 2 hero"},
                        "title": {"type": "mrkdwn", "text": "Alert Block"},
                        "subtitle": {"type": "mrkdwn", "text": "Prominent notices"},
                        "body": {"type": "mrkdwn", "text": "Warnings, status updates, and more."},
                        "actions": [{"type": "button", "text": {"type": "plain_text", "text": "Learn more"}, "action_id": "card_2_btn"}],
                    },
                    {
                        "type": "card",
                        "hero_image": {"type": "image", "image_url": "https://picsum.photos/seed/c/400/200", "alt_text": "Card 3 hero"},
                        "title": {"type": "mrkdwn", "text": "Carousel Block"},
                        "subtitle": {"type": "mrkdwn", "text": "Scrollable card collections"},
                        "body": {"type": "mrkdwn", "text": "Up to 10 cards, side by side."},
                        "actions": [{"type": "button", "text": {"type": "plain_text", "text": "Learn more"}, "action_id": "card_3_btn"}],
                    },
                ],
            },
        ],
        text="New Block Kit types demo",
    )
    SocketModeHandler(app, os.environ.get("SLACK_APP_TOKEN")).start()
Test shortcut handler (opens modal with alert blocks via global shortcut)
def sample_shortcut_callback(body: dict, ack: Ack, client: WebClient, logger: Logger):
    try:
        ack()
        client.views_open(
            trigger_id=body["trigger_id"],
            view={
                "type": "modal",
                "callback_id": "sample_view_id",
                "title": {"type": "plain_text", "text": "Alert Block Demo"},
                "blocks": [
                    {
                        "type": "alert",
                        "text": {"type": "mrkdwn", "text": "This is a *default* alert block"},
                    },
                    {
                        "type": "alert",
                        "text": {"type": "mrkdwn", "text": "This is an *info* alert block"},
                        "level": "info",
                    },
                    {
                        "type": "alert",
                        "text": {"type": "mrkdwn", "text": "This is a *warning* alert block"},
                        "level": "warning",
                    },
                    {
                        "type": "alert",
                        "text": {"type": "mrkdwn", "text": "This is an *error* alert block"},
                        "level": "error",
                    },
                    {
                        "type": "alert",
                        "text": {"type": "mrkdwn", "text": "This is a *success* alert block"},
                        "level": "success",
                    },
                ],
                "submit": {"type": "plain_text", "text": "Submit"},
            },
        )
    except Exception as e:
        logger.error(e)
  • Round-trip serialization tests for all three block types
  • Block.parse() deserialization tests
  • Validation tests (required fields, length constraints, enum values)
  • Integration test: send a message with CardBlock to Slack
  • Integration test: send a message with CarouselBlock to Slack
  • Integration test: open a modal with AlertBlock in Slack (alert blocks are only supported in modal views)

🤖 Generated with Claude Code

@srtaalej srtaalej self-assigned this Apr 29, 2026
@srtaalej srtaalej added enhancement M-T: A feature request for new functionality semver:minor server-side-issue labels Apr 29, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 29, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.09%. Comparing base (69163d6) to head (6fddb54).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1865      +/-   ##
==========================================
+ Coverage   84.00%   84.09%   +0.08%     
==========================================
  Files         117      117              
  Lines       13257    13325      +68     
==========================================
+ Hits        11137    11205      +68     
  Misses       2120     2120              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@srtaalej srtaalej marked this pull request as ready for review April 30, 2026 20:00
@srtaalej srtaalej requested a review from a team as a code owner April 30, 2026 20:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement M-T: A feature request for new functionality semver:minor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant