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 new file mode 100644 index 0000000..e1e6870 --- /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 content in a card. + * {@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; + } +} 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)); + } +}