From b7a1b830324edbe5be0281cc1d1fb4e6b312a893 Mon Sep 17 00:00:00 2001 From: Ale Mercado Date: Thu, 27 Aug 2026 16:00:18 -0400 Subject: [PATCH 1/2] feat: add card block example --- block-kit/src/main/java/blocks/Card.java | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 block-kit/src/main/java/blocks/Card.java diff --git a/block-kit/src/main/java/blocks/Card.java b/block-kit/src/main/java/blocks/Card.java new file mode 100644 index 0000000..5e1bc92 --- /dev/null +++ b/block-kit/src/main/java/blocks/Card.java @@ -0,0 +1,30 @@ +package blocks; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.CardBlock; +import com.slack.api.model.block.composition.BlockCompositions; +import com.slack.api.model.block.element.BlockElements; +import java.util.List; + +/** + * Displays a card layout with optional icon, title, body, and actions. + * {@link https://docs.slack.dev/reference/block-kit/blocks/card-block/} + */ +public class Card { + /** + * A card with icon, title, subtitle, hero image, body, and an action button. + */ + public static CardBlock example01() { + CardBlock block = Blocks.card(c -> c.icon(BlockElements.imageElement( + i -> i.imageUrl("https://picsum.photos/36/36").altText("Icon"))) + .title(BlockCompositions.markdownText("Lumon Industries")) + .subtitle(BlockCompositions.markdownText("Committed to work-life balance")) + .heroImage(BlockElements.imageElement( + i -> i.imageUrl("https://picsum.photos/400/300").altText("Sample hero image"))) + .body(BlockCompositions.markdownText("Please enjoy each card equally.")) + .actions(List.of(BlockElements.button(b -> b.text(BlockCompositions.plainText( + pt -> pt.text("Action Button").emoji(false))) + .actionId("button_action"))))); + return block; + } +} From 93ce431ee333716d0e501be021f05484466c656d Mon Sep 17 00:00:00 2001 From: Ale Mercado Date: Fri, 28 Aug 2026 10:28:15 -0400 Subject: [PATCH 2/2] test: add card block test, update readme and docstring --- block-kit/README.md | 1 + block-kit/src/main/java/blocks/Card.java | 2 +- block-kit/src/test/java/blocks/CardTest.java | 55 ++++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 block-kit/src/test/java/blocks/CardTest.java diff --git a/block-kit/README.md b/block-kit/README.md index 3cd3768..45da9a0 100644 --- a/block-kit/README.md +++ b/block-kit/README.md @@ -9,6 +9,7 @@ Read the [docs](https://docs.slack.dev/block-kit/) to learn concepts behind thes ### Blocks - **[Actions](https://docs.slack.dev/reference/block-kit/blocks/actions-block)**: Holds multiple interactive elements. [Implementation](./src/main/java/blocks/Actions.java). +- **[Card](https://docs.slack.dev/reference/block-kit/blocks/card-block)**: Displays content in a card. [Implementation](./src/main/java/blocks/Card.java). - **[Context](https://docs.slack.dev/reference/block-kit/blocks/context-block)**: Provides contextual info, which can include both images and text. [Implementation](./src/main/java/blocks/Context.java). - **[Divider](https://docs.slack.dev/reference/block-kit/blocks/divider-block)**: Visually separates pieces of info inside of a message. [Implementation](./src/main/java/blocks/Divider.java). - **[File](https://docs.slack.dev/reference/block-kit/blocks/file-block)**: Displays info about remote files. [Implementation](./src/main/java/blocks/File.java). diff --git a/block-kit/src/main/java/blocks/Card.java b/block-kit/src/main/java/blocks/Card.java index 5e1bc92..e1e6870 100644 --- a/block-kit/src/main/java/blocks/Card.java +++ b/block-kit/src/main/java/blocks/Card.java @@ -7,7 +7,7 @@ import java.util.List; /** - * Displays a card layout with optional icon, title, body, and actions. + * Displays content in a card. * {@link https://docs.slack.dev/reference/block-kit/blocks/card-block/} */ public class Card { diff --git a/block-kit/src/test/java/blocks/CardTest.java b/block-kit/src/test/java/blocks/CardTest.java new file mode 100644 index 0000000..59c61d9 --- /dev/null +++ b/block-kit/src/test/java/blocks/CardTest.java @@ -0,0 +1,55 @@ +package blocks; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.CardBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class CardTest { + @Test + public void testExample01() { + CardBlock block = Card.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "card", + "icon": { + "type": "image", + "image_url": "https://picsum.photos/36/36", + "alt_text": "Icon" + }, + "title": { + "type": "mrkdwn", + "text": "Lumon Industries" + }, + "subtitle": { + "type": "mrkdwn", + "text": "Committed to work-life balance" + }, + "hero_image": { + "type": "image", + "image_url": "https://picsum.photos/400/300", + "alt_text": "Sample hero image" + }, + "body": { + "type": "mrkdwn", + "text": "Please enjoy each card equally." + }, + "actions": [ + { + "type": "button", + "text": { + "type": "plain_text", + "text": "Action Button", + "emoji": false + }, + "action_id": "button_action" + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +}