diff --git a/block-kit/README.md b/block-kit/README.md index 8f64c51..6ec391d 100644 --- a/block-kit/README.md +++ b/block-kit/README.md @@ -12,6 +12,7 @@ Read the [docs](https://docs.slack.dev/block-kit/) to learn concepts behind thes - **[Alert](https://docs.slack.dev/reference/block-kit/blocks/alert-block)**: Displays alerts, warnings, and informational messages. [Implementation](./src/blocks/alert.js). - **[Card](https://docs.slack.dev/reference/block-kit/blocks/card-block)**: Displays content in a card. [Implementation](./src/blocks/card.js). - **[Carousel](https://docs.slack.dev/reference/block-kit/blocks/carousel-block)**: Displays related card blocks in a horizontally-scrolling container. [Implementation](./src/blocks/carousel.js). +- **[Container](https://docs.slack.dev/reference/block-kit/blocks/container-block)**: Groups child blocks together in a configurable container. [Implementation](./src/blocks/container.js). - **[Context](https://docs.slack.dev/reference/block-kit/blocks/context-block)**: Provides contextual info, which can include both images and text. [Implementation](./src/blocks/context.js). - **[Context actions](https://docs.slack.dev/reference/block-kit/blocks/context-actions-block)**: Displays actions as contextual info, which can include both feedback buttons and icon buttons. [Implementation](./src/blocks/context_actions.js). - **[Divider](https://docs.slack.dev/reference/block-kit/blocks/divider-block)**: Visually separates pieces of info inside of a message. [Implementation](./src/blocks/divider.js). diff --git a/block-kit/src/blocks/container.js b/block-kit/src/blocks/container.js new file mode 100644 index 0000000..a427874 --- /dev/null +++ b/block-kit/src/blocks/container.js @@ -0,0 +1,92 @@ +/** + * A general-purpose wrapper for grouping child blocks together, with a configurable size. + * + * @see {@link https://docs.slack.dev/reference/block-kit/blocks/container-block/} + */ + +/** + * A collapsible container grouping a bulk-update summary out of section, + * divider, context, and actions child blocks. + * + * @returns {import('@slack/types').ContainerBlock} + */ +export function example01() { + /** + * @type {import('@slack/types').ContainerBlock} + */ + const block = { + type: "container", + block_id: "bkb_container_bulk_update", + title: { + type: "plain_text", + text: "Bulk update: 2 records selected", + }, + subtitle: { + type: "plain_text", + text: "Review changes before confirming", + }, + is_collapsible: true, + child_blocks: [ + { + type: "section", + block_id: "record-row-1", + text: { + type: "mrkdwn", + text: "*DCW-1024*\nStatus: Open → Closed\nAssignee: @princessdonut → @carl", + }, + }, + { + type: "divider", + block_id: "bulk-div-1", + }, + { + type: "section", + block_id: "record-row-2", + text: { + type: "mrkdwn", + text: "*DCW-1025*\nStatus: In Progress → Closed\nAssignee: @mordecai → @carl", + }, + }, + { + type: "divider", + block_id: "bulk-div-2", + }, + { + type: "context", + block_id: "bulk-status-bar", + elements: [ + { + type: "mrkdwn", + text: ":white_check_mark: 2 records will be updated • Status → Closed • Assignee → @carl", + }, + ], + }, + { + type: "actions", + block_id: "bulk-actions", + elements: [ + { + type: "button", + text: { + type: "plain_text", + text: "Confirm All", + emoji: true, + }, + style: "primary", + action_id: "bulk_confirm", + }, + { + type: "button", + text: { + type: "plain_text", + text: "Cancel", + emoji: true, + }, + action_id: "bulk_cancel", + }, + ], + }, + ], + }; + return block; +} diff --git a/block-kit/tests/blocks/container.test.js b/block-kit/tests/blocks/container.test.js new file mode 100644 index 0000000..c5d0048 --- /dev/null +++ b/block-kit/tests/blocks/container.test.js @@ -0,0 +1,84 @@ +import * as assert from "node:assert"; +import { describe, it } from "node:test"; +import { example01 } from "../../src/blocks/container.js"; + +describe("container", () => { + it("example01", () => { + const block = example01(); + const expected = { + type: "container", + block_id: "bkb_container_bulk_update", + title: { + type: "plain_text", + text: "Bulk update: 2 records selected", + }, + subtitle: { + type: "plain_text", + text: "Review changes before confirming", + }, + is_collapsible: true, + child_blocks: [ + { + type: "section", + block_id: "record-row-1", + text: { + type: "mrkdwn", + text: "*DCW-1024*\nStatus: Open → Closed\nAssignee: @princessdonut → @carl", + }, + }, + { + type: "divider", + block_id: "bulk-div-1", + }, + { + type: "section", + block_id: "record-row-2", + text: { + type: "mrkdwn", + text: "*DCW-1025*\nStatus: In Progress → Closed\nAssignee: @mordecai → @carl", + }, + }, + { + type: "divider", + block_id: "bulk-div-2", + }, + { + type: "context", + block_id: "bulk-status-bar", + elements: [ + { + type: "mrkdwn", + text: ":white_check_mark: 2 records will be updated • Status → Closed • Assignee → @carl", + }, + ], + }, + { + type: "actions", + block_id: "bulk-actions", + elements: [ + { + type: "button", + text: { + type: "plain_text", + text: "Confirm All", + emoji: true, + }, + style: "primary", + action_id: "bulk_confirm", + }, + { + type: "button", + text: { + type: "plain_text", + text: "Cancel", + emoji: true, + }, + action_id: "bulk_cancel", + }, + ], + }, + ], + }; + assert.deepStrictEqual(block, expected); + }); +});