From 7da27d6c40339036a12aac3517e4b68b60323ddd Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Thu, 27 Aug 2026 22:41:25 -0700 Subject: [PATCH 01/10] feat(block-kit): add block element examples Add dedicated block-element examples under the block-kit project, mirroring the reference payloads on the docs.slack.dev block-elements reference pages, with tests asserting the complete serialized JSON. Elements: button, select menu (5 variants), multi-select menu (5 variants), radio buttons, date picker, time picker, datetime picker, email input, URL input, number input, file input, overflow menu, plain-text input, image (3 variants), workflow button. Co-Authored-By: Claude --- block-kit/README.md | 18 ++ .../src/main/java/blockelements/Button.java | 62 +++++++ .../main/java/blockelements/DatePicker.java | 26 +++ .../java/blockelements/DatetimePicker.java | 24 +++ .../main/java/blockelements/EmailInput.java | 24 +++ .../main/java/blockelements/FileInput.java | 26 +++ .../src/main/java/blockelements/Image.java | 51 ++++++ .../java/blockelements/MultiSelectMenu.java | 85 ++++++++++ .../main/java/blockelements/NumberInput.java | 23 +++ .../main/java/blockelements/OverflowMenu.java | 47 ++++++ .../java/blockelements/PlainTextInput.java | 23 +++ .../main/java/blockelements/RadioButtons.java | 37 ++++ .../main/java/blockelements/SelectMenu.java | 85 ++++++++++ .../main/java/blockelements/TimePicker.java | 27 +++ .../src/main/java/blockelements/UrlInput.java | 23 +++ .../java/blockelements/WorkflowButton.java | 41 +++++ .../test/java/blockelements/ButtonTest.java | 116 +++++++++++++ .../java/blockelements/DatePickerTest.java | 36 ++++ .../blockelements/DatetimePickerTest.java | 37 ++++ .../java/blockelements/EmailInputTest.java | 36 ++++ .../java/blockelements/FileInputTest.java | 34 ++++ .../test/java/blockelements/ImageTest.java | 80 +++++++++ .../blockelements/MultiSelectMenuTest.java | 159 ++++++++++++++++++ .../java/blockelements/NumberInputTest.java | 33 ++++ .../java/blockelements/OverflowMenuTest.java | 68 ++++++++ .../blockelements/PlainTextInputTest.java | 33 ++++ .../java/blockelements/RadioButtonsTest.java | 53 ++++++ .../java/blockelements/SelectMenuTest.java | 159 ++++++++++++++++++ .../java/blockelements/TimePickerTest.java | 37 ++++ .../test/java/blockelements/UrlInputTest.java | 32 ++++ .../blockelements/WorkflowButtonTest.java | 49 ++++++ 31 files changed, 1584 insertions(+) create mode 100644 block-kit/src/main/java/blockelements/Button.java create mode 100644 block-kit/src/main/java/blockelements/DatePicker.java create mode 100644 block-kit/src/main/java/blockelements/DatetimePicker.java create mode 100644 block-kit/src/main/java/blockelements/EmailInput.java create mode 100644 block-kit/src/main/java/blockelements/FileInput.java create mode 100644 block-kit/src/main/java/blockelements/Image.java create mode 100644 block-kit/src/main/java/blockelements/MultiSelectMenu.java create mode 100644 block-kit/src/main/java/blockelements/NumberInput.java create mode 100644 block-kit/src/main/java/blockelements/OverflowMenu.java create mode 100644 block-kit/src/main/java/blockelements/PlainTextInput.java create mode 100644 block-kit/src/main/java/blockelements/RadioButtons.java create mode 100644 block-kit/src/main/java/blockelements/SelectMenu.java create mode 100644 block-kit/src/main/java/blockelements/TimePicker.java create mode 100644 block-kit/src/main/java/blockelements/UrlInput.java create mode 100644 block-kit/src/main/java/blockelements/WorkflowButton.java create mode 100644 block-kit/src/test/java/blockelements/ButtonTest.java create mode 100644 block-kit/src/test/java/blockelements/DatePickerTest.java create mode 100644 block-kit/src/test/java/blockelements/DatetimePickerTest.java create mode 100644 block-kit/src/test/java/blockelements/EmailInputTest.java create mode 100644 block-kit/src/test/java/blockelements/FileInputTest.java create mode 100644 block-kit/src/test/java/blockelements/ImageTest.java create mode 100644 block-kit/src/test/java/blockelements/MultiSelectMenuTest.java create mode 100644 block-kit/src/test/java/blockelements/NumberInputTest.java create mode 100644 block-kit/src/test/java/blockelements/OverflowMenuTest.java create mode 100644 block-kit/src/test/java/blockelements/PlainTextInputTest.java create mode 100644 block-kit/src/test/java/blockelements/RadioButtonsTest.java create mode 100644 block-kit/src/test/java/blockelements/SelectMenuTest.java create mode 100644 block-kit/src/test/java/blockelements/TimePickerTest.java create mode 100644 block-kit/src/test/java/blockelements/UrlInputTest.java create mode 100644 block-kit/src/test/java/blockelements/WorkflowButtonTest.java diff --git a/block-kit/README.md b/block-kit/README.md index 3cd3768..c1e3658 100644 --- a/block-kit/README.md +++ b/block-kit/README.md @@ -20,3 +20,21 @@ Read the [docs](https://docs.slack.dev/block-kit/) to learn concepts behind thes - **[Section](https://docs.slack.dev/reference/block-kit/blocks/section-block)**: Displays text, possibly alongside elements. [Implementation](./src/main/java/blocks/Section.java). - **[Video](https://docs.slack.dev/reference/block-kit/blocks/video-block)**: Displays an embedded video player. [Implementation](./src/main/java/blocks/Video.java). +### Block elements + +- **[Button](https://docs.slack.dev/reference/block-kit/block-elements/button-element)**: Allows users a direct path to performing basic actions. [Implementation](./src/main/java/blockelements/Button.java). +- **[Date picker](https://docs.slack.dev/reference/block-kit/block-elements/date-picker-element)**: Allows users to select a date from a calendar style UI. [Implementation](./src/main/java/blockelements/DatePicker.java). +- **[Datetime picker](https://docs.slack.dev/reference/block-kit/block-elements/datetime-picker-element)**: Allows users to select both a date and a time of day. [Implementation](./src/main/java/blockelements/DatetimePicker.java). +- **[Email input](https://docs.slack.dev/reference/block-kit/block-elements/email-input-element)**: Allows user to enter an email into a single-line field. [Implementation](./src/main/java/blockelements/EmailInput.java). +- **[File input](https://docs.slack.dev/reference/block-kit/block-elements/file-input-element)**: Allows user to upload files. [Implementation](./src/main/java/blockelements/FileInput.java). +- **[Image](https://docs.slack.dev/reference/block-kit/block-elements/image-element)**: Displays an image as part of a larger block of content. [Implementation](./src/main/java/blockelements/Image.java). +- **[Multi-select menu](https://docs.slack.dev/reference/block-kit/block-elements/multi-select-menu-element)**: Allows users to select multiple items from a list of options. [Implementation](./src/main/java/blockelements/MultiSelectMenu.java). +- **[Number input](https://docs.slack.dev/reference/block-kit/block-elements/number-input-element)**: Allows user to enter a number into a single-line field. [Implementation](./src/main/java/blockelements/NumberInput.java). +- **[Overflow menu](https://docs.slack.dev/reference/block-kit/block-elements/overflow-menu-element)**: Allows users to press a button to view a list of options. [Implementation](./src/main/java/blockelements/OverflowMenu.java). +- **[Plain-text input](https://docs.slack.dev/reference/block-kit/block-elements/plain-text-input-element)**: Allows users to enter freeform text data into a single-line or multi-line field. [Implementation](./src/main/java/blockelements/PlainTextInput.java). +- **[Radio button group](https://docs.slack.dev/reference/block-kit/block-elements/radio-button-group-element)**: Allows users to choose one item from a list of possible options. [Implementation](./src/main/java/blockelements/RadioButtons.java). +- **[Select menu](https://docs.slack.dev/reference/block-kit/block-elements/select-menu-element)**: Allows users to choose an option from a drop down menu. [Implementation](./src/main/java/blockelements/SelectMenu.java). +- **[Time picker](https://docs.slack.dev/reference/block-kit/block-elements/time-picker-element)**: A time picker element; on desktop a dropdown with free-text entry, on mobile the native time picker UI. [Implementation](./src/main/java/blockelements/TimePicker.java). +- **[URL input](https://docs.slack.dev/reference/block-kit/block-elements/url-input-element)**: Allows user to enter a URL into a single-line field. [Implementation](./src/main/java/blockelements/UrlInput.java). +- **[Workflow button](https://docs.slack.dev/reference/block-kit/block-elements/workflow-button-element)**: Allows users to run a link trigger with customizable inputs. [Implementation](./src/main/java/blockelements/WorkflowButton.java). + diff --git a/block-kit/src/main/java/blockelements/Button.java b/block-kit/src/main/java/blockelements/Button.java new file mode 100644 index 0000000..6255873 --- /dev/null +++ b/block-kit/src/main/java/blockelements/Button.java @@ -0,0 +1,62 @@ +package blockelements; + +import static com.slack.api.model.block.composition.BlockCompositions.markdownText; +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.LayoutBlock; +import com.slack.api.model.block.element.BlockElements; +import com.slack.api.model.block.element.ButtonElement; +import java.util.List; + +/** + * Allows users a direct path to performing basic actions. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/button-element/} + */ +public class Button { + /** + * A regular button. + */ + public static ButtonElement example01() { + ButtonElement element = BlockElements.button( + b -> b.text(plainText("Click Me")).value("click_me_123").actionId("button")); + return element; + } + + /** + * A button using the primary style. + */ + public static ButtonElement example02() { + ButtonElement element = BlockElements.button(b -> + b.text(plainText("Save")).style("primary").value("click_me_123").actionId("button")); + return element; + } + + /** + * A button that opens a link. + */ + public static ButtonElement example03() { + ButtonElement element = + BlockElements.button(b -> b.text(plainText("Link Button")).url("https://docs.slack.dev/block-kit")); + return element; + } + + /** + * Buttons hosted in a section accessory and an actions block. + */ + public static List example04() { + List blocks = List.of( + Blocks.section(s -> s.text(markdownText("This is a section block with a button.")) + .accessory(BlockElements.button(b -> b.text(plainText("Click Me")) + .value("click_me_123") + .actionId("button")))), + Blocks.actions(a -> a.blockId("actionblock789") + .elements(List.of( + BlockElements.button(b -> b.text(plainText("Primary Button")) + .style("primary") + .value("click_me_456")), + BlockElements.button(b -> + b.text(plainText("Link Button")).url("https://api.slack.com/block-kit")))))); + return blocks; + } +} diff --git a/block-kit/src/main/java/blockelements/DatePicker.java b/block-kit/src/main/java/blockelements/DatePicker.java new file mode 100644 index 0000000..4fbd6c3 --- /dev/null +++ b/block-kit/src/main/java/blockelements/DatePicker.java @@ -0,0 +1,26 @@ +package blockelements; + +import static com.slack.api.model.block.composition.BlockCompositions.markdownText; +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.model.block.element.BlockElements; + +/** + * Allows users to select a date from a calendar style UI. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/date-picker-element/} + */ +public class DatePicker { + /** + * A section block with a date picker accessory. + */ + public static SectionBlock example01() { + SectionBlock block = Blocks.section(s -> s.blockId("section1234") + .text(markdownText("Pick a date for the deadline.")) + .accessory(BlockElements.datePicker(d -> d.actionId("datepicker123") + .initialDate("1990-04-28") + .placeholder(plainText("Select a date"))))); + return block; + } +} diff --git a/block-kit/src/main/java/blockelements/DatetimePicker.java b/block-kit/src/main/java/blockelements/DatetimePicker.java new file mode 100644 index 0000000..7a65b61 --- /dev/null +++ b/block-kit/src/main/java/blockelements/DatetimePicker.java @@ -0,0 +1,24 @@ +package blockelements; + +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.InputBlock; +import com.slack.api.model.block.element.BlockElements; + +/** + * Allows users to select both a date and a time of day. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/datetime-picker-element/} + */ +public class DatetimePicker { + /** + * An input block with a datetime picker element. + */ + public static InputBlock example01() { + InputBlock block = + Blocks.input(i -> i.element(BlockElements.datetimePicker(d -> d.actionId("datetimepicker-action"))) + .hint(plainText(pt -> pt.text("This is some hint text").emoji(true))) + .label(plainText(pt -> pt.text("Start date").emoji(true)))); + return block; + } +} diff --git a/block-kit/src/main/java/blockelements/EmailInput.java b/block-kit/src/main/java/blockelements/EmailInput.java new file mode 100644 index 0000000..d99d588 --- /dev/null +++ b/block-kit/src/main/java/blockelements/EmailInput.java @@ -0,0 +1,24 @@ +package blockelements; + +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.InputBlock; +import com.slack.api.model.block.element.BlockElements; + +/** + * Allows user to enter an email into a single-line field. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/email-input-element/} + */ +public class EmailInput { + /** + * An input block with an email input element. + */ + public static InputBlock example01() { + InputBlock block = Blocks.input(i -> i.blockId("input123") + .label(plainText("Email Address")) + .element(BlockElements.emailTextInput( + e -> e.actionId("email_text_input-action").placeholder(plainText("Enter an email"))))); + return block; + } +} diff --git a/block-kit/src/main/java/blockelements/FileInput.java b/block-kit/src/main/java/blockelements/FileInput.java new file mode 100644 index 0000000..261ed46 --- /dev/null +++ b/block-kit/src/main/java/blockelements/FileInput.java @@ -0,0 +1,26 @@ +package blockelements; + +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.InputBlock; +import com.slack.api.model.block.element.BlockElements; +import java.util.List; + +/** + * Allows user to upload files. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/file-input-element/} + */ +public class FileInput { + /** + * An input block with a file input element. + */ + public static InputBlock example01() { + InputBlock block = Blocks.input(i -> i.blockId("input_block_id") + .label(plainText("Upload Files")) + .element(BlockElements.fileInput(f -> f.actionId("file_input_action_id_1") + .filetypes(List.of("jpg", "png")) + .maxFiles(5)))); + return block; + } +} diff --git a/block-kit/src/main/java/blockelements/Image.java b/block-kit/src/main/java/blockelements/Image.java new file mode 100644 index 0000000..08db8dd --- /dev/null +++ b/block-kit/src/main/java/blockelements/Image.java @@ -0,0 +1,51 @@ +package blockelements; + +import static com.slack.api.model.block.composition.BlockCompositions.markdownText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.model.block.composition.SlackFileObject; +import com.slack.api.model.block.element.BlockElements; + +/** + * Displays an image as part of a larger block of content. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/image-element/} + */ +public class Image { + /** + * A section block with an image accessory using image_url. + */ + public static SectionBlock example01() { + SectionBlock block = Blocks.section(s -> s.blockId("section567") + .text(markdownText("This is a section block with an accessory image.")) + .accessory(BlockElements.image( + i -> i.imageUrl("https://pbs.twimg.com/profile_images/625633822235693056/lNGUneLX_400x400.jpg") + .altText("cute cat")))); + return block; + } + + /** + * A section block with an image accessory using a slack_file url. + */ + public static SectionBlock example02() { + SectionBlock block = Blocks.section(s -> s.blockId("section567") + .text(markdownText("This is a section block with an accessory image.")) + .accessory(BlockElements.image(i -> i.slackFile(SlackFileObject.builder() + .url("https://files.slack.com/files-pri/T0123456-F0123456/xyz.png") + .build()) + .altText("Slack file object.")))); + return block; + } + + /** + * A section block with an image accessory using a slack_file id. + */ + public static SectionBlock example03() { + SectionBlock block = Blocks.section(s -> s.blockId("section567") + .text(markdownText("This is a section block with an accessory image.")) + .accessory(BlockElements.image(i -> i.slackFile( + SlackFileObject.builder().id("F01234567").build()) + .altText("Slack file object.")))); + return block; + } +} diff --git a/block-kit/src/main/java/blockelements/MultiSelectMenu.java b/block-kit/src/main/java/blockelements/MultiSelectMenu.java new file mode 100644 index 0000000..f2f4eb1 --- /dev/null +++ b/block-kit/src/main/java/blockelements/MultiSelectMenu.java @@ -0,0 +1,85 @@ +package blockelements; + +import static com.slack.api.model.block.composition.BlockCompositions.markdownText; +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.model.block.composition.OptionObject; +import com.slack.api.model.block.element.BlockElements; +import java.util.List; + +/** + * Allows users to select multiple items from a list of options. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/multi-select-menu-element/} + */ +public class MultiSelectMenu { + /** + * A section block with a multi-select menu of static options. + */ + public static SectionBlock example01() { + SectionBlock block = Blocks.section(s -> s.blockId("section678") + .text(markdownText("Pick items from the list")) + .accessory(BlockElements.multiStaticSelect(m -> m.actionId("text1234") + .placeholder(plainText("Select items")) + .options(List.of( + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-0") + .build(), + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-1") + .build(), + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-2") + .build()))))); + return block; + } + + /** + * A section block with a multi-select menu of options loaded from an external source. + */ + public static SectionBlock example02() { + SectionBlock block = Blocks.section(s -> s.blockId("section678") + .text(markdownText("Pick items from the list")) + .accessory(BlockElements.multiExternalSelect(m -> m.actionId("text1234") + .placeholder(plainText("Select items")) + .minQueryLength(3)))); + return block; + } + + /** + * A section block with a multi-select menu of users. + */ + public static SectionBlock example03() { + SectionBlock block = Blocks.section(s -> s.blockId("section678") + .text(markdownText("Pick users from the list")) + .accessory(BlockElements.multiUsersSelect( + m -> m.actionId("text1234").placeholder(plainText("Select users"))))); + return block; + } + + /** + * A section block with a multi-select menu of conversations. + */ + public static SectionBlock example04() { + SectionBlock block = Blocks.section(s -> s.blockId("section678") + .text(markdownText("Pick conversations from the list")) + .accessory(BlockElements.multiConversationsSelect( + m -> m.actionId("text1234").placeholder(plainText("Select conversations"))))); + return block; + } + + /** + * A section block with a multi-select menu of channels. + */ + public static SectionBlock example05() { + SectionBlock block = Blocks.section(s -> s.blockId("section678") + .text(markdownText("Pick channels from the list")) + .accessory(BlockElements.multiChannelsSelect( + m -> m.actionId("text1234").placeholder(plainText("Select channels"))))); + return block; + } +} diff --git a/block-kit/src/main/java/blockelements/NumberInput.java b/block-kit/src/main/java/blockelements/NumberInput.java new file mode 100644 index 0000000..656533b --- /dev/null +++ b/block-kit/src/main/java/blockelements/NumberInput.java @@ -0,0 +1,23 @@ +package blockelements; + +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.InputBlock; +import com.slack.api.model.block.element.BlockElements; + +/** + * Allows user to enter a number into a single-line field. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/number-input-element/} + */ +public class NumberInput { + /** + * An input block with a number input element. + */ + public static InputBlock example01() { + InputBlock block = Blocks.input(i -> i.element( + BlockElements.numberInput(n -> n.decimalAllowed(false).actionId("number_input-action"))) + .label(plainText(pt -> pt.text("Label").emoji(true)))); + return block; + } +} diff --git a/block-kit/src/main/java/blockelements/OverflowMenu.java b/block-kit/src/main/java/blockelements/OverflowMenu.java new file mode 100644 index 0000000..d86e993 --- /dev/null +++ b/block-kit/src/main/java/blockelements/OverflowMenu.java @@ -0,0 +1,47 @@ +package blockelements; + +import static com.slack.api.model.block.composition.BlockCompositions.markdownText; +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.model.block.composition.OptionObject; +import com.slack.api.model.block.element.BlockElements; +import java.util.List; + +/** + * Allows users to press a button to view a list of options. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/overflow-menu-element/} + */ +public class OverflowMenu { + /** + * A section block with an overflow menu accessory. + */ + public static SectionBlock example01() { + SectionBlock block = Blocks.section(s -> s.blockId("section 890") + .text(markdownText("This is a section block with an overflow menu.")) + .accessory(BlockElements.overflowMenu(o -> o.actionId("overflow") + .options(List.of( + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-0") + .build(), + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-1") + .build(), + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-2") + .build(), + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-3") + .build(), + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-4") + .build()))))); + return block; + } +} diff --git a/block-kit/src/main/java/blockelements/PlainTextInput.java b/block-kit/src/main/java/blockelements/PlainTextInput.java new file mode 100644 index 0000000..7fa1787 --- /dev/null +++ b/block-kit/src/main/java/blockelements/PlainTextInput.java @@ -0,0 +1,23 @@ +package blockelements; + +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.InputBlock; +import com.slack.api.model.block.element.BlockElements; + +/** + * Allows users to enter freeform text data into a single-line or multi-line field. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/plain-text-input-element/} + */ +public class PlainTextInput { + /** + * An input block with a plain-text input element. + */ + public static InputBlock example01() { + InputBlock block = + Blocks.input(i -> i.element(BlockElements.plainTextInput(pt -> pt.actionId("plain_text_input-action"))) + .label(plainText(l -> l.text("Label").emoji(true)))); + return block; + } +} diff --git a/block-kit/src/main/java/blockelements/RadioButtons.java b/block-kit/src/main/java/blockelements/RadioButtons.java new file mode 100644 index 0000000..bab9957 --- /dev/null +++ b/block-kit/src/main/java/blockelements/RadioButtons.java @@ -0,0 +1,37 @@ +package blockelements; + +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.model.block.composition.OptionObject; +import com.slack.api.model.block.element.BlockElements; +import java.util.List; + +/** + * Allows users to choose one item from a list of possible options. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/radio-button-group-element/} + */ +public class RadioButtons { + /** + * A section block with a radio button group accessory. + */ + public static SectionBlock example01() { + SectionBlock block = Blocks.section(s -> s.text(plainText("Check out these rad radio buttons")) + .accessory(BlockElements.radioButtons(r -> r.actionId("this_is_an_action_id") + .initialOption(OptionObject.builder() + .value("A1") + .text(plainText("Radio 1")) + .build()) + .options(List.of( + OptionObject.builder() + .value("A1") + .text(plainText("Radio 1")) + .build(), + OptionObject.builder() + .value("A2") + .text(plainText("Radio 2")) + .build()))))); + return block; + } +} diff --git a/block-kit/src/main/java/blockelements/SelectMenu.java b/block-kit/src/main/java/blockelements/SelectMenu.java new file mode 100644 index 0000000..0688b5e --- /dev/null +++ b/block-kit/src/main/java/blockelements/SelectMenu.java @@ -0,0 +1,85 @@ +package blockelements; + +import static com.slack.api.model.block.composition.BlockCompositions.markdownText; +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.model.block.composition.OptionObject; +import com.slack.api.model.block.element.BlockElements; +import java.util.List; + +/** + * Allows users to choose an option from a drop down menu. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/select-menu-element/} + */ +public class SelectMenu { + /** + * A section block with a select menu of static options. + */ + public static SectionBlock example01() { + SectionBlock block = Blocks.section(s -> s.blockId("section678") + .text(markdownText("Pick an item from the dropdown list")) + .accessory(BlockElements.staticSelect(m -> m.actionId("text1234") + .placeholder(plainText("Select an item")) + .options(List.of( + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-0") + .build(), + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-1") + .build(), + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-2") + .build()))))); + return block; + } + + /** + * A section block with a select menu of options loaded from an external source. + */ + public static SectionBlock example02() { + SectionBlock block = Blocks.section(s -> s.blockId("section678") + .text(markdownText("Pick an item from the dropdown list")) + .accessory(BlockElements.externalSelect(m -> m.actionId("text1234") + .placeholder(plainText("Select an item")) + .minQueryLength(3)))); + return block; + } + + /** + * A section block with a select menu of users. + */ + public static SectionBlock example03() { + SectionBlock block = Blocks.section(s -> s.blockId("section678") + .text(markdownText("Pick a user from the dropdown list")) + .accessory(BlockElements.usersSelect( + m -> m.actionId("text1234").placeholder(plainText("Select an item"))))); + return block; + } + + /** + * A section block with a select menu of conversations. + */ + public static SectionBlock example04() { + SectionBlock block = Blocks.section(s -> s.blockId("section678") + .text(markdownText("Pick a conversation from the dropdown list")) + .accessory(BlockElements.conversationsSelect( + m -> m.actionId("text1234").placeholder(plainText("Select an item"))))); + return block; + } + + /** + * A section block with a select menu of channels. + */ + public static SectionBlock example05() { + SectionBlock block = Blocks.section(s -> s.blockId("section678") + .text(markdownText("Pick a channel from the dropdown list")) + .accessory(BlockElements.channelsSelect( + m -> m.actionId("text1234").placeholder(plainText("Select an item"))))); + return block; + } +} diff --git a/block-kit/src/main/java/blockelements/TimePicker.java b/block-kit/src/main/java/blockelements/TimePicker.java new file mode 100644 index 0000000..5ec12d3 --- /dev/null +++ b/block-kit/src/main/java/blockelements/TimePicker.java @@ -0,0 +1,27 @@ +package blockelements; + +import static com.slack.api.model.block.composition.BlockCompositions.markdownText; +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.model.block.element.BlockElements; + +/** + * A time picker element; on desktop a dropdown with free-text entry, on mobile the native time picker UI. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/time-picker-element/} + */ +public class TimePicker { + /** + * A section block with a time picker accessory. + */ + public static SectionBlock example01() { + SectionBlock block = Blocks.section(s -> s.blockId("section1234") + .text(markdownText("Pick a date for the deadline.")) + .accessory(BlockElements.timePicker(t -> t.timezone("America/Los_Angeles") + .actionId("timepicker123") + .initialTime("11:40") + .placeholder(plainText("Select a time"))))); + return block; + } +} diff --git a/block-kit/src/main/java/blockelements/UrlInput.java b/block-kit/src/main/java/blockelements/UrlInput.java new file mode 100644 index 0000000..d9e853c --- /dev/null +++ b/block-kit/src/main/java/blockelements/UrlInput.java @@ -0,0 +1,23 @@ +package blockelements; + +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.InputBlock; +import com.slack.api.model.block.element.BlockElements; + +/** + * Allows user to enter a URL into a single-line field. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/url-input-element/} + */ +public class UrlInput { + /** + * An input block with a URL input element. + */ + public static InputBlock example01() { + InputBlock block = + Blocks.input(i -> i.element(BlockElements.urlTextInput(u -> u.actionId("url_text_input-action"))) + .label(plainText(pt -> pt.text("Label").emoji(true)))); + return block; + } +} diff --git a/block-kit/src/main/java/blockelements/WorkflowButton.java b/block-kit/src/main/java/blockelements/WorkflowButton.java new file mode 100644 index 0000000..3c8adf8 --- /dev/null +++ b/block-kit/src/main/java/blockelements/WorkflowButton.java @@ -0,0 +1,41 @@ +package blockelements; + +import static com.slack.api.model.block.composition.BlockCompositions.markdownText; +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.model.block.composition.WorkflowObject; +import com.slack.api.model.block.element.BlockElements; +import java.util.List; + +/** + * Allows users to run a link trigger with customizable inputs. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/workflow-button-element/} + */ +public class WorkflowButton { + /** + * A section block with a workflow button accessory. + */ + public static SectionBlock example01() { + SectionBlock block = + Blocks.section(s -> s.text(markdownText("A message *with some bold text* and _some italicized text_.")) + .accessory(BlockElements.workflowButton(w -> w.text(plainText("Run Workflow")) + .actionId("workflowbutton123") + .workflow(WorkflowObject.builder() + .trigger(WorkflowObject.Trigger.builder() + .url("https://slack.com/shortcuts/Ft0123ABC456/xyz...zyx") + .customizableInputParameters(List.of( + WorkflowObject.Trigger.InputParameter.builder() + .name("input_parameter_a") + .value("Value for input param A") + .build(), + WorkflowObject.Trigger.InputParameter.builder() + .name("input_parameter_b") + .value("Value for input param B") + .build())) + .build()) + .build())))); + return block; + } +} diff --git a/block-kit/src/test/java/blockelements/ButtonTest.java b/block-kit/src/test/java/blockelements/ButtonTest.java new file mode 100644 index 0000000..4d2ad65 --- /dev/null +++ b/block-kit/src/test/java/blockelements/ButtonTest.java @@ -0,0 +1,116 @@ +package blockelements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.LayoutBlock; +import com.slack.api.model.block.element.ButtonElement; +import com.slack.api.util.json.GsonFactory; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class ButtonTest { + @Test + public void testExample01() { + ButtonElement element = Button.example01(); + String actual = GsonFactory.createSnakeCase().toJson(element); + String expected = """ + { + "type": "button", + "text": { + "type": "plain_text", + "text": "Click Me" + }, + "value": "click_me_123", + "action_id": "button" + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample02() { + ButtonElement element = Button.example02(); + String actual = GsonFactory.createSnakeCase().toJson(element); + String expected = """ + { + "type": "button", + "text": { + "type": "plain_text", + "text": "Save" + }, + "style": "primary", + "value": "click_me_123", + "action_id": "button" + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample03() { + ButtonElement element = Button.example03(); + String actual = GsonFactory.createSnakeCase().toJson(element); + String expected = """ + { + "type": "button", + "text": { + "type": "plain_text", + "text": "Link Button" + }, + "url": "https://docs.slack.dev/block-kit" + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample04() { + List blocks = Button.example04(); + String actual = GsonFactory.createSnakeCase().toJson(blocks); + String expected = """ + [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "This is a section block with a button." + }, + "accessory": { + "type": "button", + "text": { + "type": "plain_text", + "text": "Click Me" + }, + "value": "click_me_123", + "action_id": "button" + } + }, + { + "type": "actions", + "block_id": "actionblock789", + "elements": [ + { + "type": "button", + "text": { + "type": "plain_text", + "text": "Primary Button" + }, + "style": "primary", + "value": "click_me_456" + }, + { + "type": "button", + "text": { + "type": "plain_text", + "text": "Link Button" + }, + "url": "https://api.slack.com/block-kit" + } + ] + } + ] + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/blockelements/DatePickerTest.java b/block-kit/src/test/java/blockelements/DatePickerTest.java new file mode 100644 index 0000000..655b588 --- /dev/null +++ b/block-kit/src/test/java/blockelements/DatePickerTest.java @@ -0,0 +1,36 @@ +package blockelements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class DatePickerTest { + @Test + public void testExample01() { + SectionBlock block = DatePicker.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section1234", + "text": { + "type": "mrkdwn", + "text": "Pick a date for the deadline." + }, + "accessory": { + "type": "datepicker", + "action_id": "datepicker123", + "initial_date": "1990-04-28", + "placeholder": { + "type": "plain_text", + "text": "Select a date" + } + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/blockelements/DatetimePickerTest.java b/block-kit/src/test/java/blockelements/DatetimePickerTest.java new file mode 100644 index 0000000..7267009 --- /dev/null +++ b/block-kit/src/test/java/blockelements/DatetimePickerTest.java @@ -0,0 +1,37 @@ +package blockelements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.InputBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class DatetimePickerTest { + @Test + public void testExample01() { + InputBlock block = DatetimePicker.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "input", + "element": { + "type": "datetimepicker", + "action_id": "datetimepicker-action" + }, + "hint": { + "type": "plain_text", + "text": "This is some hint text", + "emoji": true + }, + "label": { + "type": "plain_text", + "text": "Start date", + "emoji": true + }, + "optional": false + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/blockelements/EmailInputTest.java b/block-kit/src/test/java/blockelements/EmailInputTest.java new file mode 100644 index 0000000..28b0ffd --- /dev/null +++ b/block-kit/src/test/java/blockelements/EmailInputTest.java @@ -0,0 +1,36 @@ +package blockelements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.InputBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class EmailInputTest { + @Test + public void testExample01() { + InputBlock block = EmailInput.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "input", + "block_id": "input123", + "label": { + "type": "plain_text", + "text": "Email Address" + }, + "element": { + "type": "email_text_input", + "action_id": "email_text_input-action", + "placeholder": { + "type": "plain_text", + "text": "Enter an email" + } + }, + "optional": false + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/blockelements/FileInputTest.java b/block-kit/src/test/java/blockelements/FileInputTest.java new file mode 100644 index 0000000..51ed593 --- /dev/null +++ b/block-kit/src/test/java/blockelements/FileInputTest.java @@ -0,0 +1,34 @@ +package blockelements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.InputBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class FileInputTest { + @Test + public void testExample01() { + InputBlock block = FileInput.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "input", + "block_id": "input_block_id", + "label": { + "type": "plain_text", + "text": "Upload Files" + }, + "element": { + "type": "file_input", + "action_id": "file_input_action_id_1", + "filetypes": ["jpg", "png"], + "max_files": 5 + }, + "optional": false + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/blockelements/ImageTest.java b/block-kit/src/test/java/blockelements/ImageTest.java new file mode 100644 index 0000000..8e4fd75 --- /dev/null +++ b/block-kit/src/test/java/blockelements/ImageTest.java @@ -0,0 +1,80 @@ +package blockelements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class ImageTest { + @Test + public void testExample01() { + SectionBlock block = Image.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section567", + "text": { + "type": "mrkdwn", + "text": "This is a section block with an accessory image." + }, + "accessory": { + "type": "image", + "image_url": "https://pbs.twimg.com/profile_images/625633822235693056/lNGUneLX_400x400.jpg", + "alt_text": "cute cat" + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample02() { + SectionBlock block = Image.example02(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section567", + "text": { + "type": "mrkdwn", + "text": "This is a section block with an accessory image." + }, + "accessory": { + "type": "image", + "slack_file": { + "url": "https://files.slack.com/files-pri/T0123456-F0123456/xyz.png" + }, + "alt_text": "Slack file object." + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample03() { + SectionBlock block = Image.example03(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section567", + "text": { + "type": "mrkdwn", + "text": "This is a section block with an accessory image." + }, + "accessory": { + "type": "image", + "slack_file": { + "id": "F01234567" + }, + "alt_text": "Slack file object." + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/blockelements/MultiSelectMenuTest.java b/block-kit/src/test/java/blockelements/MultiSelectMenuTest.java new file mode 100644 index 0000000..cd79151 --- /dev/null +++ b/block-kit/src/test/java/blockelements/MultiSelectMenuTest.java @@ -0,0 +1,159 @@ +package blockelements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class MultiSelectMenuTest { + @Test + public void testExample01() { + SectionBlock block = MultiSelectMenu.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section678", + "text": { + "type": "mrkdwn", + "text": "Pick items from the list" + }, + "accessory": { + "action_id": "text1234", + "type": "multi_static_select", + "placeholder": { + "type": "plain_text", + "text": "Select items" + }, + "options": [ + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-0" + }, + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-1" + }, + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-2" + } + ] + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample02() { + SectionBlock block = MultiSelectMenu.example02(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section678", + "text": { + "type": "mrkdwn", + "text": "Pick items from the list" + }, + "accessory": { + "action_id": "text1234", + "type": "multi_external_select", + "placeholder": { + "type": "plain_text", + "text": "Select items" + }, + "min_query_length": 3 + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample03() { + SectionBlock block = MultiSelectMenu.example03(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section678", + "text": { + "type": "mrkdwn", + "text": "Pick users from the list" + }, + "accessory": { + "action_id": "text1234", + "type": "multi_users_select", + "placeholder": { + "type": "plain_text", + "text": "Select users" + } + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample04() { + SectionBlock block = MultiSelectMenu.example04(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section678", + "text": { + "type": "mrkdwn", + "text": "Pick conversations from the list" + }, + "accessory": { + "action_id": "text1234", + "type": "multi_conversations_select", + "placeholder": { + "type": "plain_text", + "text": "Select conversations" + } + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample05() { + SectionBlock block = MultiSelectMenu.example05(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section678", + "text": { + "type": "mrkdwn", + "text": "Pick channels from the list" + }, + "accessory": { + "action_id": "text1234", + "type": "multi_channels_select", + "placeholder": { + "type": "plain_text", + "text": "Select channels" + } + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/blockelements/NumberInputTest.java b/block-kit/src/test/java/blockelements/NumberInputTest.java new file mode 100644 index 0000000..bf877cf --- /dev/null +++ b/block-kit/src/test/java/blockelements/NumberInputTest.java @@ -0,0 +1,33 @@ +package blockelements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.InputBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class NumberInputTest { + @Test + public void testExample01() { + InputBlock block = NumberInput.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "input", + "element": { + "type": "number_input", + "is_decimal_allowed": false, + "action_id": "number_input-action" + }, + "label": { + "type": "plain_text", + "text": "Label", + "emoji": true + }, + "optional": false + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/blockelements/OverflowMenuTest.java b/block-kit/src/test/java/blockelements/OverflowMenuTest.java new file mode 100644 index 0000000..f652d44 --- /dev/null +++ b/block-kit/src/test/java/blockelements/OverflowMenuTest.java @@ -0,0 +1,68 @@ +package blockelements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class OverflowMenuTest { + @Test + public void testExample01() { + SectionBlock block = OverflowMenu.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section 890", + "text": { + "type": "mrkdwn", + "text": "This is a section block with an overflow menu." + }, + "accessory": { + "type": "overflow", + "action_id": "overflow", + "options": [ + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-0" + }, + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-1" + }, + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-2" + }, + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-3" + }, + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-4" + } + ] + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/blockelements/PlainTextInputTest.java b/block-kit/src/test/java/blockelements/PlainTextInputTest.java new file mode 100644 index 0000000..27bb4c1 --- /dev/null +++ b/block-kit/src/test/java/blockelements/PlainTextInputTest.java @@ -0,0 +1,33 @@ +package blockelements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.InputBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class PlainTextInputTest { + @Test + public void testExample01() { + InputBlock block = PlainTextInput.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "input", + "element": { + "type": "plain_text_input", + "action_id": "plain_text_input-action", + "multiline": false + }, + "label": { + "type": "plain_text", + "text": "Label", + "emoji": true + }, + "optional": false + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/blockelements/RadioButtonsTest.java b/block-kit/src/test/java/blockelements/RadioButtonsTest.java new file mode 100644 index 0000000..bf45e3f --- /dev/null +++ b/block-kit/src/test/java/blockelements/RadioButtonsTest.java @@ -0,0 +1,53 @@ +package blockelements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class RadioButtonsTest { + @Test + public void testExample01() { + SectionBlock block = RadioButtons.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "text": { + "type": "plain_text", + "text": "Check out these rad radio buttons" + }, + "accessory": { + "type": "radio_buttons", + "action_id": "this_is_an_action_id", + "initial_option": { + "value": "A1", + "text": { + "type": "plain_text", + "text": "Radio 1" + } + }, + "options": [ + { + "value": "A1", + "text": { + "type": "plain_text", + "text": "Radio 1" + } + }, + { + "value": "A2", + "text": { + "type": "plain_text", + "text": "Radio 2" + } + } + ] + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/blockelements/SelectMenuTest.java b/block-kit/src/test/java/blockelements/SelectMenuTest.java new file mode 100644 index 0000000..aba093b --- /dev/null +++ b/block-kit/src/test/java/blockelements/SelectMenuTest.java @@ -0,0 +1,159 @@ +package blockelements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class SelectMenuTest { + @Test + public void testExample01() { + SectionBlock block = SelectMenu.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section678", + "text": { + "type": "mrkdwn", + "text": "Pick an item from the dropdown list" + }, + "accessory": { + "action_id": "text1234", + "type": "static_select", + "placeholder": { + "type": "plain_text", + "text": "Select an item" + }, + "options": [ + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-0" + }, + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-1" + }, + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-2" + } + ] + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample02() { + SectionBlock block = SelectMenu.example02(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section678", + "text": { + "type": "mrkdwn", + "text": "Pick an item from the dropdown list" + }, + "accessory": { + "action_id": "text1234", + "type": "external_select", + "placeholder": { + "type": "plain_text", + "text": "Select an item" + }, + "min_query_length": 3 + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample03() { + SectionBlock block = SelectMenu.example03(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section678", + "text": { + "type": "mrkdwn", + "text": "Pick a user from the dropdown list" + }, + "accessory": { + "action_id": "text1234", + "type": "users_select", + "placeholder": { + "type": "plain_text", + "text": "Select an item" + } + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample04() { + SectionBlock block = SelectMenu.example04(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section678", + "text": { + "type": "mrkdwn", + "text": "Pick a conversation from the dropdown list" + }, + "accessory": { + "action_id": "text1234", + "type": "conversations_select", + "placeholder": { + "type": "plain_text", + "text": "Select an item" + } + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample05() { + SectionBlock block = SelectMenu.example05(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section678", + "text": { + "type": "mrkdwn", + "text": "Pick a channel from the dropdown list" + }, + "accessory": { + "action_id": "text1234", + "type": "channels_select", + "placeholder": { + "type": "plain_text", + "text": "Select an item" + } + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/blockelements/TimePickerTest.java b/block-kit/src/test/java/blockelements/TimePickerTest.java new file mode 100644 index 0000000..4d80900 --- /dev/null +++ b/block-kit/src/test/java/blockelements/TimePickerTest.java @@ -0,0 +1,37 @@ +package blockelements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class TimePickerTest { + @Test + public void testExample01() { + SectionBlock block = TimePicker.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section1234", + "text": { + "type": "mrkdwn", + "text": "Pick a date for the deadline." + }, + "accessory": { + "type": "timepicker", + "timezone": "America/Los_Angeles", + "action_id": "timepicker123", + "initial_time": "11:40", + "placeholder": { + "type": "plain_text", + "text": "Select a time" + } + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/blockelements/UrlInputTest.java b/block-kit/src/test/java/blockelements/UrlInputTest.java new file mode 100644 index 0000000..bde3c03 --- /dev/null +++ b/block-kit/src/test/java/blockelements/UrlInputTest.java @@ -0,0 +1,32 @@ +package blockelements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.InputBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class UrlInputTest { + @Test + public void testExample01() { + InputBlock block = UrlInput.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "input", + "element": { + "type": "url_text_input", + "action_id": "url_text_input-action" + }, + "label": { + "type": "plain_text", + "text": "Label", + "emoji": true + }, + "optional": false + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/blockelements/WorkflowButtonTest.java b/block-kit/src/test/java/blockelements/WorkflowButtonTest.java new file mode 100644 index 0000000..01c0635 --- /dev/null +++ b/block-kit/src/test/java/blockelements/WorkflowButtonTest.java @@ -0,0 +1,49 @@ +package blockelements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class WorkflowButtonTest { + @Test + public void testExample01() { + SectionBlock block = WorkflowButton.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "text": { + "text": "A message *with some bold text* and _some italicized text_.", + "type": "mrkdwn" + }, + "accessory": { + "type": "workflow_button", + "text": { + "type": "plain_text", + "text": "Run Workflow" + }, + "action_id": "workflowbutton123", + "workflow": { + "trigger": { + "url": "https://slack.com/shortcuts/Ft0123ABC456/xyz...zyx", + "customizable_input_parameters": [ + { + "name": "input_parameter_a", + "value": "Value for input param A" + }, + { + "name": "input_parameter_b", + "value": "Value for input param B" + } + ] + } + } + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} From 9e9aea0ffb1e880911e96ea8f774c3853531afa7 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Thu, 27 Aug 2026 23:29:07 -0700 Subject: [PATCH 02/10] feat(block-kit): add feedback buttons, icon button, rich text input, and team elements Adds the remaining documented block elements that the Java SDK models and serializes to the exact reference payload: - feedback_buttons and icon_button, each inside a context_actions block - rich_text_input, inside an input block - the team rich text element, added to the existing rich text block example Each example ships a test asserting the complete reference JSON, and every new element is listed in the README with its docs.slack.dev reference and tagline. Deferred: url_source is not modeled by the Java SDK (no url source object or task card block), so it is omitted rather than approximated. Co-Authored-By: Claude --- block-kit/README.md | 3 ++ .../java/blockelements/FeedbackButtons.java | 34 ++++++++++++++ .../main/java/blockelements/IconButton.java | 25 +++++++++++ .../java/blockelements/RichTextInput.java | 31 +++++++++++++ block-kit/src/main/java/blocks/RichText.java | 12 +++++ .../blockelements/FeedbackButtonsTest.java | 44 +++++++++++++++++++ .../java/blockelements/IconButtonTest.java | 34 ++++++++++++++ .../java/blockelements/RichTextInputTest.java | 42 ++++++++++++++++++ .../src/test/java/blocks/RichTextTest.java | 23 ++++++++++ 9 files changed, 248 insertions(+) create mode 100644 block-kit/src/main/java/blockelements/FeedbackButtons.java create mode 100644 block-kit/src/main/java/blockelements/IconButton.java create mode 100644 block-kit/src/main/java/blockelements/RichTextInput.java create mode 100644 block-kit/src/test/java/blockelements/FeedbackButtonsTest.java create mode 100644 block-kit/src/test/java/blockelements/IconButtonTest.java create mode 100644 block-kit/src/test/java/blockelements/RichTextInputTest.java diff --git a/block-kit/README.md b/block-kit/README.md index c1e3658..7f29d5e 100644 --- a/block-kit/README.md +++ b/block-kit/README.md @@ -26,13 +26,16 @@ Read the [docs](https://docs.slack.dev/block-kit/) to learn concepts behind thes - **[Date picker](https://docs.slack.dev/reference/block-kit/block-elements/date-picker-element)**: Allows users to select a date from a calendar style UI. [Implementation](./src/main/java/blockelements/DatePicker.java). - **[Datetime picker](https://docs.slack.dev/reference/block-kit/block-elements/datetime-picker-element)**: Allows users to select both a date and a time of day. [Implementation](./src/main/java/blockelements/DatetimePicker.java). - **[Email input](https://docs.slack.dev/reference/block-kit/block-elements/email-input-element)**: Allows user to enter an email into a single-line field. [Implementation](./src/main/java/blockelements/EmailInput.java). +- **[Feedback buttons](https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element)**: Buttons to indicate positive or negative feedback. [Implementation](./src/main/java/blockelements/FeedbackButtons.java). - **[File input](https://docs.slack.dev/reference/block-kit/block-elements/file-input-element)**: Allows user to upload files. [Implementation](./src/main/java/blockelements/FileInput.java). +- **[Icon button](https://docs.slack.dev/reference/block-kit/block-elements/icon-button-element)**: An icon button to perform actions. [Implementation](./src/main/java/blockelements/IconButton.java). - **[Image](https://docs.slack.dev/reference/block-kit/block-elements/image-element)**: Displays an image as part of a larger block of content. [Implementation](./src/main/java/blockelements/Image.java). - **[Multi-select menu](https://docs.slack.dev/reference/block-kit/block-elements/multi-select-menu-element)**: Allows users to select multiple items from a list of options. [Implementation](./src/main/java/blockelements/MultiSelectMenu.java). - **[Number input](https://docs.slack.dev/reference/block-kit/block-elements/number-input-element)**: Allows user to enter a number into a single-line field. [Implementation](./src/main/java/blockelements/NumberInput.java). - **[Overflow menu](https://docs.slack.dev/reference/block-kit/block-elements/overflow-menu-element)**: Allows users to press a button to view a list of options. [Implementation](./src/main/java/blockelements/OverflowMenu.java). - **[Plain-text input](https://docs.slack.dev/reference/block-kit/block-elements/plain-text-input-element)**: Allows users to enter freeform text data into a single-line or multi-line field. [Implementation](./src/main/java/blockelements/PlainTextInput.java). - **[Radio button group](https://docs.slack.dev/reference/block-kit/block-elements/radio-button-group-element)**: Allows users to choose one item from a list of possible options. [Implementation](./src/main/java/blockelements/RadioButtons.java). +- **[Rich text input](https://docs.slack.dev/reference/block-kit/block-elements/rich-text-input-element)**: Allows users to enter formatted text in a WYSIWYG composer, offering the same messaging writing experience as in Slack. [Implementation](./src/main/java/blockelements/RichTextInput.java). - **[Select menu](https://docs.slack.dev/reference/block-kit/block-elements/select-menu-element)**: Allows users to choose an option from a drop down menu. [Implementation](./src/main/java/blockelements/SelectMenu.java). - **[Time picker](https://docs.slack.dev/reference/block-kit/block-elements/time-picker-element)**: A time picker element; on desktop a dropdown with free-text entry, on mobile the native time picker UI. [Implementation](./src/main/java/blockelements/TimePicker.java). - **[URL input](https://docs.slack.dev/reference/block-kit/block-elements/url-input-element)**: Allows user to enter a URL into a single-line field. [Implementation](./src/main/java/blockelements/UrlInput.java). diff --git a/block-kit/src/main/java/blockelements/FeedbackButtons.java b/block-kit/src/main/java/blockelements/FeedbackButtons.java new file mode 100644 index 0000000..6b65ea7 --- /dev/null +++ b/block-kit/src/main/java/blockelements/FeedbackButtons.java @@ -0,0 +1,34 @@ +package blockelements; + +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.ContextActionsBlock; +import com.slack.api.model.block.composition.FeedbackButtonObject; +import com.slack.api.model.block.element.BlockElements; +import java.util.List; + +/** + * Buttons to indicate positive or negative feedback. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element/} + */ +public class FeedbackButtons { + /** + * A context actions block with a feedback buttons element. + */ + public static ContextActionsBlock example01() { + ContextActionsBlock block = + Blocks.contextActions(List.of(BlockElements.feedbackButtons(fb -> fb.actionId("feedback_buttons_1") + .positiveButton(FeedbackButtonObject.builder() + .text(plainText("Good")) + .value("positive_feedback") + .accessibilityLabel("Mark this response as good") + .build()) + .negativeButton(FeedbackButtonObject.builder() + .text(plainText("Bad")) + .value("negative_feedback") + .accessibilityLabel("Mark this response as bad") + .build())))); + return block; + } +} diff --git a/block-kit/src/main/java/blockelements/IconButton.java b/block-kit/src/main/java/blockelements/IconButton.java new file mode 100644 index 0000000..10e264d --- /dev/null +++ b/block-kit/src/main/java/blockelements/IconButton.java @@ -0,0 +1,25 @@ +package blockelements; + +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.ContextActionsBlock; +import com.slack.api.model.block.element.BlockElements; +import java.util.List; + +/** + * An icon button to perform actions. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/icon-button-element/} + */ +public class IconButton { + /** + * A context actions block with an icon button element. + */ + public static ContextActionsBlock example01() { + ContextActionsBlock block = Blocks.contextActions(List.of(BlockElements.iconButton(ib -> ib.icon("trash") + .text(plainText("Delete")) + .actionId("delete_button") + .value("delete_item")))); + return block; + } +} diff --git a/block-kit/src/main/java/blockelements/RichTextInput.java b/block-kit/src/main/java/blockelements/RichTextInput.java new file mode 100644 index 0000000..7034ebe --- /dev/null +++ b/block-kit/src/main/java/blockelements/RichTextInput.java @@ -0,0 +1,31 @@ +package blockelements; + +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.InputBlock; +import com.slack.api.model.block.composition.DispatchActionConfig; +import com.slack.api.model.block.element.BlockElements; +import java.util.List; + +/** + * Allows users to enter formatted text in a WYSIWYG composer, offering the same messaging writing experience as in + * Slack. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/rich-text-input-element/} + */ +public class RichTextInput { + /** + * An input block with a rich text input element. + */ + public static InputBlock example01() { + InputBlock block = + Blocks.input(i -> i.element(BlockElements.richTextInput(rt -> rt.actionId("rich_text_input-action") + .dispatchActionConfig(DispatchActionConfig.builder() + .triggerActionsOn(List.of("on_character_entered")) + .build()) + .focusOnLoad(true) + .placeholder(plainText("Enter text")))) + .label(plainText(l -> l.text("Label").emoji(true)))); + return block; + } +} diff --git a/block-kit/src/main/java/blocks/RichText.java b/block-kit/src/main/java/blocks/RichText.java index 63e9944..d400121 100644 --- a/block-kit/src/main/java/blocks/RichText.java +++ b/block-kit/src/main/java/blocks/RichText.java @@ -281,4 +281,16 @@ public static RichTextBlock example13() { .build()))); return block; } + + /** + * A rich text block with a team mention element. + */ + public static RichTextBlock example14() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Team.builder() + .teamId("T123ABC456") + .build())) + .build()))); + return block; + } } diff --git a/block-kit/src/test/java/blockelements/FeedbackButtonsTest.java b/block-kit/src/test/java/blockelements/FeedbackButtonsTest.java new file mode 100644 index 0000000..c3a736e --- /dev/null +++ b/block-kit/src/test/java/blockelements/FeedbackButtonsTest.java @@ -0,0 +1,44 @@ +package blockelements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.ContextActionsBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class FeedbackButtonsTest { + @Test + public void testExample01() { + ContextActionsBlock block = FeedbackButtons.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "context_actions", + "elements": [ + { + "type": "feedback_buttons", + "action_id": "feedback_buttons_1", + "positive_button": { + "text": { + "type": "plain_text", + "text": "Good" + }, + "value": "positive_feedback", + "accessibility_label": "Mark this response as good" + }, + "negative_button": { + "text": { + "type": "plain_text", + "text": "Bad" + }, + "value": "negative_feedback", + "accessibility_label": "Mark this response as bad" + } + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/blockelements/IconButtonTest.java b/block-kit/src/test/java/blockelements/IconButtonTest.java new file mode 100644 index 0000000..2ff3e51 --- /dev/null +++ b/block-kit/src/test/java/blockelements/IconButtonTest.java @@ -0,0 +1,34 @@ +package blockelements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.ContextActionsBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class IconButtonTest { + @Test + public void testExample01() { + ContextActionsBlock block = IconButton.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "context_actions", + "elements": [ + { + "type": "icon_button", + "icon": "trash", + "text": { + "type": "plain_text", + "text": "Delete" + }, + "action_id": "delete_button", + "value": "delete_item" + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/blockelements/RichTextInputTest.java b/block-kit/src/test/java/blockelements/RichTextInputTest.java new file mode 100644 index 0000000..1280151 --- /dev/null +++ b/block-kit/src/test/java/blockelements/RichTextInputTest.java @@ -0,0 +1,42 @@ +package blockelements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.InputBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class RichTextInputTest { + @Test + public void testExample01() { + InputBlock block = RichTextInput.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "input", + "element": { + "type": "rich_text_input", + "action_id": "rich_text_input-action", + "dispatch_action_config": { + "trigger_actions_on": [ + "on_character_entered" + ] + }, + "focus_on_load": true, + "placeholder": { + "type": "plain_text", + "text": "Enter text" + } + }, + "label": { + "type": "plain_text", + "text": "Label", + "emoji": true + }, + "optional": false + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/blocks/RichTextTest.java b/block-kit/src/test/java/blocks/RichTextTest.java index c67af51..3d023bf 100644 --- a/block-kit/src/test/java/blocks/RichTextTest.java +++ b/block-kit/src/test/java/blocks/RichTextTest.java @@ -522,4 +522,27 @@ public void testExample13() { """; assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); } + + @Test + public void testExample14() { + RichTextBlock block = RichText.example14(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "team", + "team_id": "T123ABC456" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } } From 257cd538a73733197eac2d7d160c6ab03c5cfffc Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Sun, 30 Aug 2026 14:22:07 -0700 Subject: [PATCH 03/10] refactor(block-kit): rename blockelements package to elements Renames the package (and its src/test directories) from blockelements to elements so the example layout reads blocks/ + elements/, matching the docs.slack.dev path structure where Blocks and Block elements are siblings under Block Kit, and aligning with the JS and Python example repos. Package declarations and README implementation links follow; the docs URL slug (block-elements, hyphenated) is unchanged, and the SDK's own com.slack.api.model.block.element.BlockElements import is untouched. --- block-kit/README.md | 36 +++++++++---------- .../{blockelements => elements}/Button.java | 2 +- .../DatePicker.java | 2 +- .../DatetimePicker.java | 2 +- .../EmailInput.java | 2 +- .../FeedbackButtons.java | 2 +- .../FileInput.java | 2 +- .../IconButton.java | 2 +- .../{blockelements => elements}/Image.java | 2 +- .../MultiSelectMenu.java | 2 +- .../NumberInput.java | 2 +- .../OverflowMenu.java | 2 +- .../PlainTextInput.java | 2 +- .../RadioButtons.java | 2 +- .../RichTextInput.java | 2 +- .../SelectMenu.java | 2 +- .../TimePicker.java | 2 +- .../{blockelements => elements}/UrlInput.java | 2 +- .../WorkflowButton.java | 2 +- .../ButtonTest.java | 2 +- .../DatePickerTest.java | 2 +- .../DatetimePickerTest.java | 2 +- .../EmailInputTest.java | 2 +- .../FeedbackButtonsTest.java | 2 +- .../FileInputTest.java | 2 +- .../IconButtonTest.java | 2 +- .../ImageTest.java | 2 +- .../MultiSelectMenuTest.java | 2 +- .../NumberInputTest.java | 2 +- .../OverflowMenuTest.java | 2 +- .../PlainTextInputTest.java | 2 +- .../RadioButtonsTest.java | 2 +- .../RichTextInputTest.java | 2 +- .../SelectMenuTest.java | 2 +- .../TimePickerTest.java | 2 +- .../UrlInputTest.java | 2 +- .../WorkflowButtonTest.java | 2 +- 37 files changed, 54 insertions(+), 54 deletions(-) rename block-kit/src/main/java/{blockelements => elements}/Button.java (99%) rename block-kit/src/main/java/{blockelements => elements}/DatePicker.java (97%) rename block-kit/src/main/java/{blockelements => elements}/DatetimePicker.java (97%) rename block-kit/src/main/java/{blockelements => elements}/EmailInput.java (97%) rename block-kit/src/main/java/{blockelements => elements}/FeedbackButtons.java (98%) rename block-kit/src/main/java/{blockelements => elements}/FileInput.java (97%) rename block-kit/src/main/java/{blockelements => elements}/IconButton.java (97%) rename block-kit/src/main/java/{blockelements => elements}/Image.java (98%) rename block-kit/src/main/java/{blockelements => elements}/MultiSelectMenu.java (99%) rename block-kit/src/main/java/{blockelements => elements}/NumberInput.java (97%) rename block-kit/src/main/java/{blockelements => elements}/OverflowMenu.java (98%) rename block-kit/src/main/java/{blockelements => elements}/PlainTextInput.java (97%) rename block-kit/src/main/java/{blockelements => elements}/RadioButtons.java (98%) rename block-kit/src/main/java/{blockelements => elements}/RichTextInput.java (98%) rename block-kit/src/main/java/{blockelements => elements}/SelectMenu.java (99%) rename block-kit/src/main/java/{blockelements => elements}/TimePicker.java (97%) rename block-kit/src/main/java/{blockelements => elements}/UrlInput.java (97%) rename block-kit/src/main/java/{blockelements => elements}/WorkflowButton.java (98%) rename block-kit/src/test/java/{blockelements => elements}/ButtonTest.java (99%) rename block-kit/src/test/java/{blockelements => elements}/DatePickerTest.java (97%) rename block-kit/src/test/java/{blockelements => elements}/DatetimePickerTest.java (97%) rename block-kit/src/test/java/{blockelements => elements}/EmailInputTest.java (97%) rename block-kit/src/test/java/{blockelements => elements}/FeedbackButtonsTest.java (98%) rename block-kit/src/test/java/{blockelements => elements}/FileInputTest.java (97%) rename block-kit/src/test/java/{blockelements => elements}/IconButtonTest.java (97%) rename block-kit/src/test/java/{blockelements => elements}/ImageTest.java (99%) rename block-kit/src/test/java/{blockelements => elements}/MultiSelectMenuTest.java (99%) rename block-kit/src/test/java/{blockelements => elements}/NumberInputTest.java (97%) rename block-kit/src/test/java/{blockelements => elements}/OverflowMenuTest.java (98%) rename block-kit/src/test/java/{blockelements => elements}/PlainTextInputTest.java (97%) rename block-kit/src/test/java/{blockelements => elements}/RadioButtonsTest.java (98%) rename block-kit/src/test/java/{blockelements => elements}/RichTextInputTest.java (98%) rename block-kit/src/test/java/{blockelements => elements}/SelectMenuTest.java (99%) rename block-kit/src/test/java/{blockelements => elements}/TimePickerTest.java (98%) rename block-kit/src/test/java/{blockelements => elements}/UrlInputTest.java (97%) rename block-kit/src/test/java/{blockelements => elements}/WorkflowButtonTest.java (98%) diff --git a/block-kit/README.md b/block-kit/README.md index 7f29d5e..fb922e1 100644 --- a/block-kit/README.md +++ b/block-kit/README.md @@ -22,22 +22,22 @@ Read the [docs](https://docs.slack.dev/block-kit/) to learn concepts behind thes ### Block elements -- **[Button](https://docs.slack.dev/reference/block-kit/block-elements/button-element)**: Allows users a direct path to performing basic actions. [Implementation](./src/main/java/blockelements/Button.java). -- **[Date picker](https://docs.slack.dev/reference/block-kit/block-elements/date-picker-element)**: Allows users to select a date from a calendar style UI. [Implementation](./src/main/java/blockelements/DatePicker.java). -- **[Datetime picker](https://docs.slack.dev/reference/block-kit/block-elements/datetime-picker-element)**: Allows users to select both a date and a time of day. [Implementation](./src/main/java/blockelements/DatetimePicker.java). -- **[Email input](https://docs.slack.dev/reference/block-kit/block-elements/email-input-element)**: Allows user to enter an email into a single-line field. [Implementation](./src/main/java/blockelements/EmailInput.java). -- **[Feedback buttons](https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element)**: Buttons to indicate positive or negative feedback. [Implementation](./src/main/java/blockelements/FeedbackButtons.java). -- **[File input](https://docs.slack.dev/reference/block-kit/block-elements/file-input-element)**: Allows user to upload files. [Implementation](./src/main/java/blockelements/FileInput.java). -- **[Icon button](https://docs.slack.dev/reference/block-kit/block-elements/icon-button-element)**: An icon button to perform actions. [Implementation](./src/main/java/blockelements/IconButton.java). -- **[Image](https://docs.slack.dev/reference/block-kit/block-elements/image-element)**: Displays an image as part of a larger block of content. [Implementation](./src/main/java/blockelements/Image.java). -- **[Multi-select menu](https://docs.slack.dev/reference/block-kit/block-elements/multi-select-menu-element)**: Allows users to select multiple items from a list of options. [Implementation](./src/main/java/blockelements/MultiSelectMenu.java). -- **[Number input](https://docs.slack.dev/reference/block-kit/block-elements/number-input-element)**: Allows user to enter a number into a single-line field. [Implementation](./src/main/java/blockelements/NumberInput.java). -- **[Overflow menu](https://docs.slack.dev/reference/block-kit/block-elements/overflow-menu-element)**: Allows users to press a button to view a list of options. [Implementation](./src/main/java/blockelements/OverflowMenu.java). -- **[Plain-text input](https://docs.slack.dev/reference/block-kit/block-elements/plain-text-input-element)**: Allows users to enter freeform text data into a single-line or multi-line field. [Implementation](./src/main/java/blockelements/PlainTextInput.java). -- **[Radio button group](https://docs.slack.dev/reference/block-kit/block-elements/radio-button-group-element)**: Allows users to choose one item from a list of possible options. [Implementation](./src/main/java/blockelements/RadioButtons.java). -- **[Rich text input](https://docs.slack.dev/reference/block-kit/block-elements/rich-text-input-element)**: Allows users to enter formatted text in a WYSIWYG composer, offering the same messaging writing experience as in Slack. [Implementation](./src/main/java/blockelements/RichTextInput.java). -- **[Select menu](https://docs.slack.dev/reference/block-kit/block-elements/select-menu-element)**: Allows users to choose an option from a drop down menu. [Implementation](./src/main/java/blockelements/SelectMenu.java). -- **[Time picker](https://docs.slack.dev/reference/block-kit/block-elements/time-picker-element)**: A time picker element; on desktop a dropdown with free-text entry, on mobile the native time picker UI. [Implementation](./src/main/java/blockelements/TimePicker.java). -- **[URL input](https://docs.slack.dev/reference/block-kit/block-elements/url-input-element)**: Allows user to enter a URL into a single-line field. [Implementation](./src/main/java/blockelements/UrlInput.java). -- **[Workflow button](https://docs.slack.dev/reference/block-kit/block-elements/workflow-button-element)**: Allows users to run a link trigger with customizable inputs. [Implementation](./src/main/java/blockelements/WorkflowButton.java). +- **[Button](https://docs.slack.dev/reference/block-kit/block-elements/button-element)**: Allows users a direct path to performing basic actions. [Implementation](./src/main/java/elements/Button.java). +- **[Date picker](https://docs.slack.dev/reference/block-kit/block-elements/date-picker-element)**: Allows users to select a date from a calendar style UI. [Implementation](./src/main/java/elements/DatePicker.java). +- **[Datetime picker](https://docs.slack.dev/reference/block-kit/block-elements/datetime-picker-element)**: Allows users to select both a date and a time of day. [Implementation](./src/main/java/elements/DatetimePicker.java). +- **[Email input](https://docs.slack.dev/reference/block-kit/block-elements/email-input-element)**: Allows user to enter an email into a single-line field. [Implementation](./src/main/java/elements/EmailInput.java). +- **[Feedback buttons](https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element)**: Buttons to indicate positive or negative feedback. [Implementation](./src/main/java/elements/FeedbackButtons.java). +- **[File input](https://docs.slack.dev/reference/block-kit/block-elements/file-input-element)**: Allows user to upload files. [Implementation](./src/main/java/elements/FileInput.java). +- **[Icon button](https://docs.slack.dev/reference/block-kit/block-elements/icon-button-element)**: An icon button to perform actions. [Implementation](./src/main/java/elements/IconButton.java). +- **[Image](https://docs.slack.dev/reference/block-kit/block-elements/image-element)**: Displays an image as part of a larger block of content. [Implementation](./src/main/java/elements/Image.java). +- **[Multi-select menu](https://docs.slack.dev/reference/block-kit/block-elements/multi-select-menu-element)**: Allows users to select multiple items from a list of options. [Implementation](./src/main/java/elements/MultiSelectMenu.java). +- **[Number input](https://docs.slack.dev/reference/block-kit/block-elements/number-input-element)**: Allows user to enter a number into a single-line field. [Implementation](./src/main/java/elements/NumberInput.java). +- **[Overflow menu](https://docs.slack.dev/reference/block-kit/block-elements/overflow-menu-element)**: Allows users to press a button to view a list of options. [Implementation](./src/main/java/elements/OverflowMenu.java). +- **[Plain-text input](https://docs.slack.dev/reference/block-kit/block-elements/plain-text-input-element)**: Allows users to enter freeform text data into a single-line or multi-line field. [Implementation](./src/main/java/elements/PlainTextInput.java). +- **[Radio button group](https://docs.slack.dev/reference/block-kit/block-elements/radio-button-group-element)**: Allows users to choose one item from a list of possible options. [Implementation](./src/main/java/elements/RadioButtons.java). +- **[Rich text input](https://docs.slack.dev/reference/block-kit/block-elements/rich-text-input-element)**: Allows users to enter formatted text in a WYSIWYG composer, offering the same messaging writing experience as in Slack. [Implementation](./src/main/java/elements/RichTextInput.java). +- **[Select menu](https://docs.slack.dev/reference/block-kit/block-elements/select-menu-element)**: Allows users to choose an option from a drop down menu. [Implementation](./src/main/java/elements/SelectMenu.java). +- **[Time picker](https://docs.slack.dev/reference/block-kit/block-elements/time-picker-element)**: A time picker element; on desktop a dropdown with free-text entry, on mobile the native time picker UI. [Implementation](./src/main/java/elements/TimePicker.java). +- **[URL input](https://docs.slack.dev/reference/block-kit/block-elements/url-input-element)**: Allows user to enter a URL into a single-line field. [Implementation](./src/main/java/elements/UrlInput.java). +- **[Workflow button](https://docs.slack.dev/reference/block-kit/block-elements/workflow-button-element)**: Allows users to run a link trigger with customizable inputs. [Implementation](./src/main/java/elements/WorkflowButton.java). diff --git a/block-kit/src/main/java/blockelements/Button.java b/block-kit/src/main/java/elements/Button.java similarity index 99% rename from block-kit/src/main/java/blockelements/Button.java rename to block-kit/src/main/java/elements/Button.java index 6255873..b5f1600 100644 --- a/block-kit/src/main/java/blockelements/Button.java +++ b/block-kit/src/main/java/elements/Button.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static com.slack.api.model.block.composition.BlockCompositions.markdownText; import static com.slack.api.model.block.composition.BlockCompositions.plainText; diff --git a/block-kit/src/main/java/blockelements/DatePicker.java b/block-kit/src/main/java/elements/DatePicker.java similarity index 97% rename from block-kit/src/main/java/blockelements/DatePicker.java rename to block-kit/src/main/java/elements/DatePicker.java index 4fbd6c3..be415d6 100644 --- a/block-kit/src/main/java/blockelements/DatePicker.java +++ b/block-kit/src/main/java/elements/DatePicker.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static com.slack.api.model.block.composition.BlockCompositions.markdownText; import static com.slack.api.model.block.composition.BlockCompositions.plainText; diff --git a/block-kit/src/main/java/blockelements/DatetimePicker.java b/block-kit/src/main/java/elements/DatetimePicker.java similarity index 97% rename from block-kit/src/main/java/blockelements/DatetimePicker.java rename to block-kit/src/main/java/elements/DatetimePicker.java index 7a65b61..6019075 100644 --- a/block-kit/src/main/java/blockelements/DatetimePicker.java +++ b/block-kit/src/main/java/elements/DatetimePicker.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static com.slack.api.model.block.composition.BlockCompositions.plainText; diff --git a/block-kit/src/main/java/blockelements/EmailInput.java b/block-kit/src/main/java/elements/EmailInput.java similarity index 97% rename from block-kit/src/main/java/blockelements/EmailInput.java rename to block-kit/src/main/java/elements/EmailInput.java index d99d588..0b1ae85 100644 --- a/block-kit/src/main/java/blockelements/EmailInput.java +++ b/block-kit/src/main/java/elements/EmailInput.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static com.slack.api.model.block.composition.BlockCompositions.plainText; diff --git a/block-kit/src/main/java/blockelements/FeedbackButtons.java b/block-kit/src/main/java/elements/FeedbackButtons.java similarity index 98% rename from block-kit/src/main/java/blockelements/FeedbackButtons.java rename to block-kit/src/main/java/elements/FeedbackButtons.java index 6b65ea7..d81025f 100644 --- a/block-kit/src/main/java/blockelements/FeedbackButtons.java +++ b/block-kit/src/main/java/elements/FeedbackButtons.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static com.slack.api.model.block.composition.BlockCompositions.plainText; diff --git a/block-kit/src/main/java/blockelements/FileInput.java b/block-kit/src/main/java/elements/FileInput.java similarity index 97% rename from block-kit/src/main/java/blockelements/FileInput.java rename to block-kit/src/main/java/elements/FileInput.java index 261ed46..6e3f6f8 100644 --- a/block-kit/src/main/java/blockelements/FileInput.java +++ b/block-kit/src/main/java/elements/FileInput.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static com.slack.api.model.block.composition.BlockCompositions.plainText; diff --git a/block-kit/src/main/java/blockelements/IconButton.java b/block-kit/src/main/java/elements/IconButton.java similarity index 97% rename from block-kit/src/main/java/blockelements/IconButton.java rename to block-kit/src/main/java/elements/IconButton.java index 10e264d..2cec20a 100644 --- a/block-kit/src/main/java/blockelements/IconButton.java +++ b/block-kit/src/main/java/elements/IconButton.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static com.slack.api.model.block.composition.BlockCompositions.plainText; diff --git a/block-kit/src/main/java/blockelements/Image.java b/block-kit/src/main/java/elements/Image.java similarity index 98% rename from block-kit/src/main/java/blockelements/Image.java rename to block-kit/src/main/java/elements/Image.java index 08db8dd..32990b2 100644 --- a/block-kit/src/main/java/blockelements/Image.java +++ b/block-kit/src/main/java/elements/Image.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static com.slack.api.model.block.composition.BlockCompositions.markdownText; diff --git a/block-kit/src/main/java/blockelements/MultiSelectMenu.java b/block-kit/src/main/java/elements/MultiSelectMenu.java similarity index 99% rename from block-kit/src/main/java/blockelements/MultiSelectMenu.java rename to block-kit/src/main/java/elements/MultiSelectMenu.java index f2f4eb1..bdcb933 100644 --- a/block-kit/src/main/java/blockelements/MultiSelectMenu.java +++ b/block-kit/src/main/java/elements/MultiSelectMenu.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static com.slack.api.model.block.composition.BlockCompositions.markdownText; import static com.slack.api.model.block.composition.BlockCompositions.plainText; diff --git a/block-kit/src/main/java/blockelements/NumberInput.java b/block-kit/src/main/java/elements/NumberInput.java similarity index 97% rename from block-kit/src/main/java/blockelements/NumberInput.java rename to block-kit/src/main/java/elements/NumberInput.java index 656533b..6beda5e 100644 --- a/block-kit/src/main/java/blockelements/NumberInput.java +++ b/block-kit/src/main/java/elements/NumberInput.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static com.slack.api.model.block.composition.BlockCompositions.plainText; diff --git a/block-kit/src/main/java/blockelements/OverflowMenu.java b/block-kit/src/main/java/elements/OverflowMenu.java similarity index 98% rename from block-kit/src/main/java/blockelements/OverflowMenu.java rename to block-kit/src/main/java/elements/OverflowMenu.java index d86e993..82edc31 100644 --- a/block-kit/src/main/java/blockelements/OverflowMenu.java +++ b/block-kit/src/main/java/elements/OverflowMenu.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static com.slack.api.model.block.composition.BlockCompositions.markdownText; import static com.slack.api.model.block.composition.BlockCompositions.plainText; diff --git a/block-kit/src/main/java/blockelements/PlainTextInput.java b/block-kit/src/main/java/elements/PlainTextInput.java similarity index 97% rename from block-kit/src/main/java/blockelements/PlainTextInput.java rename to block-kit/src/main/java/elements/PlainTextInput.java index 7fa1787..ffe0fba 100644 --- a/block-kit/src/main/java/blockelements/PlainTextInput.java +++ b/block-kit/src/main/java/elements/PlainTextInput.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static com.slack.api.model.block.composition.BlockCompositions.plainText; diff --git a/block-kit/src/main/java/blockelements/RadioButtons.java b/block-kit/src/main/java/elements/RadioButtons.java similarity index 98% rename from block-kit/src/main/java/blockelements/RadioButtons.java rename to block-kit/src/main/java/elements/RadioButtons.java index bab9957..f83e2f4 100644 --- a/block-kit/src/main/java/blockelements/RadioButtons.java +++ b/block-kit/src/main/java/elements/RadioButtons.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static com.slack.api.model.block.composition.BlockCompositions.plainText; diff --git a/block-kit/src/main/java/blockelements/RichTextInput.java b/block-kit/src/main/java/elements/RichTextInput.java similarity index 98% rename from block-kit/src/main/java/blockelements/RichTextInput.java rename to block-kit/src/main/java/elements/RichTextInput.java index 7034ebe..7503735 100644 --- a/block-kit/src/main/java/blockelements/RichTextInput.java +++ b/block-kit/src/main/java/elements/RichTextInput.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static com.slack.api.model.block.composition.BlockCompositions.plainText; diff --git a/block-kit/src/main/java/blockelements/SelectMenu.java b/block-kit/src/main/java/elements/SelectMenu.java similarity index 99% rename from block-kit/src/main/java/blockelements/SelectMenu.java rename to block-kit/src/main/java/elements/SelectMenu.java index 0688b5e..2c80686 100644 --- a/block-kit/src/main/java/blockelements/SelectMenu.java +++ b/block-kit/src/main/java/elements/SelectMenu.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static com.slack.api.model.block.composition.BlockCompositions.markdownText; import static com.slack.api.model.block.composition.BlockCompositions.plainText; diff --git a/block-kit/src/main/java/blockelements/TimePicker.java b/block-kit/src/main/java/elements/TimePicker.java similarity index 97% rename from block-kit/src/main/java/blockelements/TimePicker.java rename to block-kit/src/main/java/elements/TimePicker.java index 5ec12d3..807c37a 100644 --- a/block-kit/src/main/java/blockelements/TimePicker.java +++ b/block-kit/src/main/java/elements/TimePicker.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static com.slack.api.model.block.composition.BlockCompositions.markdownText; import static com.slack.api.model.block.composition.BlockCompositions.plainText; diff --git a/block-kit/src/main/java/blockelements/UrlInput.java b/block-kit/src/main/java/elements/UrlInput.java similarity index 97% rename from block-kit/src/main/java/blockelements/UrlInput.java rename to block-kit/src/main/java/elements/UrlInput.java index d9e853c..cbdeef4 100644 --- a/block-kit/src/main/java/blockelements/UrlInput.java +++ b/block-kit/src/main/java/elements/UrlInput.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static com.slack.api.model.block.composition.BlockCompositions.plainText; diff --git a/block-kit/src/main/java/blockelements/WorkflowButton.java b/block-kit/src/main/java/elements/WorkflowButton.java similarity index 98% rename from block-kit/src/main/java/blockelements/WorkflowButton.java rename to block-kit/src/main/java/elements/WorkflowButton.java index 3c8adf8..862a13a 100644 --- a/block-kit/src/main/java/blockelements/WorkflowButton.java +++ b/block-kit/src/main/java/elements/WorkflowButton.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static com.slack.api.model.block.composition.BlockCompositions.markdownText; import static com.slack.api.model.block.composition.BlockCompositions.plainText; diff --git a/block-kit/src/test/java/blockelements/ButtonTest.java b/block-kit/src/test/java/elements/ButtonTest.java similarity index 99% rename from block-kit/src/test/java/blockelements/ButtonTest.java rename to block-kit/src/test/java/elements/ButtonTest.java index 4d2ad65..ca7d342 100644 --- a/block-kit/src/test/java/blockelements/ButtonTest.java +++ b/block-kit/src/test/java/elements/ButtonTest.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/block-kit/src/test/java/blockelements/DatePickerTest.java b/block-kit/src/test/java/elements/DatePickerTest.java similarity index 97% rename from block-kit/src/test/java/blockelements/DatePickerTest.java rename to block-kit/src/test/java/elements/DatePickerTest.java index 655b588..60750ca 100644 --- a/block-kit/src/test/java/blockelements/DatePickerTest.java +++ b/block-kit/src/test/java/elements/DatePickerTest.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/block-kit/src/test/java/blockelements/DatetimePickerTest.java b/block-kit/src/test/java/elements/DatetimePickerTest.java similarity index 97% rename from block-kit/src/test/java/blockelements/DatetimePickerTest.java rename to block-kit/src/test/java/elements/DatetimePickerTest.java index 7267009..f29581d 100644 --- a/block-kit/src/test/java/blockelements/DatetimePickerTest.java +++ b/block-kit/src/test/java/elements/DatetimePickerTest.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/block-kit/src/test/java/blockelements/EmailInputTest.java b/block-kit/src/test/java/elements/EmailInputTest.java similarity index 97% rename from block-kit/src/test/java/blockelements/EmailInputTest.java rename to block-kit/src/test/java/elements/EmailInputTest.java index 28b0ffd..ecdaf09 100644 --- a/block-kit/src/test/java/blockelements/EmailInputTest.java +++ b/block-kit/src/test/java/elements/EmailInputTest.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/block-kit/src/test/java/blockelements/FeedbackButtonsTest.java b/block-kit/src/test/java/elements/FeedbackButtonsTest.java similarity index 98% rename from block-kit/src/test/java/blockelements/FeedbackButtonsTest.java rename to block-kit/src/test/java/elements/FeedbackButtonsTest.java index c3a736e..c9482fe 100644 --- a/block-kit/src/test/java/blockelements/FeedbackButtonsTest.java +++ b/block-kit/src/test/java/elements/FeedbackButtonsTest.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/block-kit/src/test/java/blockelements/FileInputTest.java b/block-kit/src/test/java/elements/FileInputTest.java similarity index 97% rename from block-kit/src/test/java/blockelements/FileInputTest.java rename to block-kit/src/test/java/elements/FileInputTest.java index 51ed593..ab48eea 100644 --- a/block-kit/src/test/java/blockelements/FileInputTest.java +++ b/block-kit/src/test/java/elements/FileInputTest.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/block-kit/src/test/java/blockelements/IconButtonTest.java b/block-kit/src/test/java/elements/IconButtonTest.java similarity index 97% rename from block-kit/src/test/java/blockelements/IconButtonTest.java rename to block-kit/src/test/java/elements/IconButtonTest.java index 2ff3e51..396ba71 100644 --- a/block-kit/src/test/java/blockelements/IconButtonTest.java +++ b/block-kit/src/test/java/elements/IconButtonTest.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/block-kit/src/test/java/blockelements/ImageTest.java b/block-kit/src/test/java/elements/ImageTest.java similarity index 99% rename from block-kit/src/test/java/blockelements/ImageTest.java rename to block-kit/src/test/java/elements/ImageTest.java index 8e4fd75..6d388f0 100644 --- a/block-kit/src/test/java/blockelements/ImageTest.java +++ b/block-kit/src/test/java/elements/ImageTest.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/block-kit/src/test/java/blockelements/MultiSelectMenuTest.java b/block-kit/src/test/java/elements/MultiSelectMenuTest.java similarity index 99% rename from block-kit/src/test/java/blockelements/MultiSelectMenuTest.java rename to block-kit/src/test/java/elements/MultiSelectMenuTest.java index cd79151..9dc3657 100644 --- a/block-kit/src/test/java/blockelements/MultiSelectMenuTest.java +++ b/block-kit/src/test/java/elements/MultiSelectMenuTest.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/block-kit/src/test/java/blockelements/NumberInputTest.java b/block-kit/src/test/java/elements/NumberInputTest.java similarity index 97% rename from block-kit/src/test/java/blockelements/NumberInputTest.java rename to block-kit/src/test/java/elements/NumberInputTest.java index bf877cf..601d8e6 100644 --- a/block-kit/src/test/java/blockelements/NumberInputTest.java +++ b/block-kit/src/test/java/elements/NumberInputTest.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/block-kit/src/test/java/blockelements/OverflowMenuTest.java b/block-kit/src/test/java/elements/OverflowMenuTest.java similarity index 98% rename from block-kit/src/test/java/blockelements/OverflowMenuTest.java rename to block-kit/src/test/java/elements/OverflowMenuTest.java index f652d44..4ab253d 100644 --- a/block-kit/src/test/java/blockelements/OverflowMenuTest.java +++ b/block-kit/src/test/java/elements/OverflowMenuTest.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/block-kit/src/test/java/blockelements/PlainTextInputTest.java b/block-kit/src/test/java/elements/PlainTextInputTest.java similarity index 97% rename from block-kit/src/test/java/blockelements/PlainTextInputTest.java rename to block-kit/src/test/java/elements/PlainTextInputTest.java index 27bb4c1..008916f 100644 --- a/block-kit/src/test/java/blockelements/PlainTextInputTest.java +++ b/block-kit/src/test/java/elements/PlainTextInputTest.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/block-kit/src/test/java/blockelements/RadioButtonsTest.java b/block-kit/src/test/java/elements/RadioButtonsTest.java similarity index 98% rename from block-kit/src/test/java/blockelements/RadioButtonsTest.java rename to block-kit/src/test/java/elements/RadioButtonsTest.java index bf45e3f..959419e 100644 --- a/block-kit/src/test/java/blockelements/RadioButtonsTest.java +++ b/block-kit/src/test/java/elements/RadioButtonsTest.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/block-kit/src/test/java/blockelements/RichTextInputTest.java b/block-kit/src/test/java/elements/RichTextInputTest.java similarity index 98% rename from block-kit/src/test/java/blockelements/RichTextInputTest.java rename to block-kit/src/test/java/elements/RichTextInputTest.java index 1280151..5b1e340 100644 --- a/block-kit/src/test/java/blockelements/RichTextInputTest.java +++ b/block-kit/src/test/java/elements/RichTextInputTest.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/block-kit/src/test/java/blockelements/SelectMenuTest.java b/block-kit/src/test/java/elements/SelectMenuTest.java similarity index 99% rename from block-kit/src/test/java/blockelements/SelectMenuTest.java rename to block-kit/src/test/java/elements/SelectMenuTest.java index aba093b..e0fa0d6 100644 --- a/block-kit/src/test/java/blockelements/SelectMenuTest.java +++ b/block-kit/src/test/java/elements/SelectMenuTest.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/block-kit/src/test/java/blockelements/TimePickerTest.java b/block-kit/src/test/java/elements/TimePickerTest.java similarity index 98% rename from block-kit/src/test/java/blockelements/TimePickerTest.java rename to block-kit/src/test/java/elements/TimePickerTest.java index 4d80900..4e4df73 100644 --- a/block-kit/src/test/java/blockelements/TimePickerTest.java +++ b/block-kit/src/test/java/elements/TimePickerTest.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/block-kit/src/test/java/blockelements/UrlInputTest.java b/block-kit/src/test/java/elements/UrlInputTest.java similarity index 97% rename from block-kit/src/test/java/blockelements/UrlInputTest.java rename to block-kit/src/test/java/elements/UrlInputTest.java index bde3c03..74ef73a 100644 --- a/block-kit/src/test/java/blockelements/UrlInputTest.java +++ b/block-kit/src/test/java/elements/UrlInputTest.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/block-kit/src/test/java/blockelements/WorkflowButtonTest.java b/block-kit/src/test/java/elements/WorkflowButtonTest.java similarity index 98% rename from block-kit/src/test/java/blockelements/WorkflowButtonTest.java rename to block-kit/src/test/java/elements/WorkflowButtonTest.java index 01c0635..519351a 100644 --- a/block-kit/src/test/java/blockelements/WorkflowButtonTest.java +++ b/block-kit/src/test/java/elements/WorkflowButtonTest.java @@ -1,4 +1,4 @@ -package blockelements; +package elements; import static org.junit.jupiter.api.Assertions.assertEquals; From 6c590be328a4dc8a5a2bace41ddd074841bf4a85 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Mon, 31 Aug 2026 19:54:52 -0700 Subject: [PATCH 04/10] docs(block-kit): align example descriptions with the reviewed JS wording Match the per-example descriptive Javadoc lines to the reviewed wording established in the JS examples (bolt-js-examples), keeping the three language sample sets consistent. Element-level (first) Javadoc lines and docs links are unchanged. Co-Authored-By: Claude --- block-kit/src/main/java/elements/Button.java | 8 ++++---- block-kit/src/main/java/elements/FeedbackButtons.java | 2 +- block-kit/src/main/java/elements/IconButton.java | 2 +- block-kit/src/main/java/elements/Image.java | 4 ++-- block-kit/src/main/java/elements/MultiSelectMenu.java | 10 +++++----- block-kit/src/main/java/elements/RadioButtons.java | 2 +- block-kit/src/main/java/elements/SelectMenu.java | 10 +++++----- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/block-kit/src/main/java/elements/Button.java b/block-kit/src/main/java/elements/Button.java index b5f1600..48a03cc 100644 --- a/block-kit/src/main/java/elements/Button.java +++ b/block-kit/src/main/java/elements/Button.java @@ -15,7 +15,7 @@ */ public class Button { /** - * A regular button. + * A regular interactive button. */ public static ButtonElement example01() { ButtonElement element = BlockElements.button( @@ -24,7 +24,7 @@ public static ButtonElement example01() { } /** - * A button using the primary style. + * A button with a primary style attribute. */ public static ButtonElement example02() { ButtonElement element = BlockElements.button(b -> @@ -33,7 +33,7 @@ public static ButtonElement example02() { } /** - * A button that opens a link. + * A link button. */ public static ButtonElement example03() { ButtonElement element = @@ -42,7 +42,7 @@ public static ButtonElement example03() { } /** - * Buttons hosted in a section accessory and an actions block. + * The button element used inside either the section or actions block. */ public static List example04() { List blocks = List.of( diff --git a/block-kit/src/main/java/elements/FeedbackButtons.java b/block-kit/src/main/java/elements/FeedbackButtons.java index d81025f..d071533 100644 --- a/block-kit/src/main/java/elements/FeedbackButtons.java +++ b/block-kit/src/main/java/elements/FeedbackButtons.java @@ -14,7 +14,7 @@ */ public class FeedbackButtons { /** - * A context actions block with a feedback buttons element. + * A context actions block with feedback buttons. */ public static ContextActionsBlock example01() { ContextActionsBlock block = diff --git a/block-kit/src/main/java/elements/IconButton.java b/block-kit/src/main/java/elements/IconButton.java index 2cec20a..055f8bb 100644 --- a/block-kit/src/main/java/elements/IconButton.java +++ b/block-kit/src/main/java/elements/IconButton.java @@ -13,7 +13,7 @@ */ public class IconButton { /** - * A context actions block with an icon button element. + * A context actions block with an icon button. */ public static ContextActionsBlock example01() { ContextActionsBlock block = Blocks.contextActions(List.of(BlockElements.iconButton(ib -> ib.icon("trash") diff --git a/block-kit/src/main/java/elements/Image.java b/block-kit/src/main/java/elements/Image.java index 32990b2..723f1e3 100644 --- a/block-kit/src/main/java/elements/Image.java +++ b/block-kit/src/main/java/elements/Image.java @@ -25,7 +25,7 @@ public static SectionBlock example01() { } /** - * A section block with an image accessory using a slack_file url. + * An image block using slack_file with a url. */ public static SectionBlock example02() { SectionBlock block = Blocks.section(s -> s.blockId("section567") @@ -38,7 +38,7 @@ public static SectionBlock example02() { } /** - * A section block with an image accessory using a slack_file id. + * An image block using slack_file with a id. */ public static SectionBlock example03() { SectionBlock block = Blocks.section(s -> s.blockId("section567") diff --git a/block-kit/src/main/java/elements/MultiSelectMenu.java b/block-kit/src/main/java/elements/MultiSelectMenu.java index bdcb933..048d570 100644 --- a/block-kit/src/main/java/elements/MultiSelectMenu.java +++ b/block-kit/src/main/java/elements/MultiSelectMenu.java @@ -15,7 +15,7 @@ */ public class MultiSelectMenu { /** - * A section block with a multi-select menu of static options. + * A section block containing a static multi-select menu. */ public static SectionBlock example01() { SectionBlock block = Blocks.section(s -> s.blockId("section678") @@ -39,7 +39,7 @@ public static SectionBlock example01() { } /** - * A section block with a multi-select menu of options loaded from an external source. + * A multi-select menu in a section block with an external data source. */ public static SectionBlock example02() { SectionBlock block = Blocks.section(s -> s.blockId("section678") @@ -51,7 +51,7 @@ public static SectionBlock example02() { } /** - * A section block with a multi-select menu of users. + * A multi-select menu in a section block showing a list of users. */ public static SectionBlock example03() { SectionBlock block = Blocks.section(s -> s.blockId("section678") @@ -62,7 +62,7 @@ public static SectionBlock example03() { } /** - * A section block with a multi-select menu of conversations. + * A multi-select menu in a section block showing a list of conversations. */ public static SectionBlock example04() { SectionBlock block = Blocks.section(s -> s.blockId("section678") @@ -73,7 +73,7 @@ public static SectionBlock example04() { } /** - * A section block with a multi-select menu of channels. + * A multi-select menu in a section block showing a list of channels. */ public static SectionBlock example05() { SectionBlock block = Blocks.section(s -> s.blockId("section678") diff --git a/block-kit/src/main/java/elements/RadioButtons.java b/block-kit/src/main/java/elements/RadioButtons.java index f83e2f4..7737774 100644 --- a/block-kit/src/main/java/elements/RadioButtons.java +++ b/block-kit/src/main/java/elements/RadioButtons.java @@ -14,7 +14,7 @@ */ public class RadioButtons { /** - * A section block with a radio button group accessory. + * A section block with a radio buttons accessory. */ public static SectionBlock example01() { SectionBlock block = Blocks.section(s -> s.text(plainText("Check out these rad radio buttons")) diff --git a/block-kit/src/main/java/elements/SelectMenu.java b/block-kit/src/main/java/elements/SelectMenu.java index 2c80686..cae91e4 100644 --- a/block-kit/src/main/java/elements/SelectMenu.java +++ b/block-kit/src/main/java/elements/SelectMenu.java @@ -15,7 +15,7 @@ */ public class SelectMenu { /** - * A section block with a select menu of static options. + * A section block with a static select menu accessory. */ public static SectionBlock example01() { SectionBlock block = Blocks.section(s -> s.blockId("section678") @@ -39,7 +39,7 @@ public static SectionBlock example01() { } /** - * A section block with a select menu of options loaded from an external source. + * A section block with an external select menu accessory. */ public static SectionBlock example02() { SectionBlock block = Blocks.section(s -> s.blockId("section678") @@ -51,7 +51,7 @@ public static SectionBlock example02() { } /** - * A section block with a select menu of users. + * A section block with a users select menu accessory. */ public static SectionBlock example03() { SectionBlock block = Blocks.section(s -> s.blockId("section678") @@ -62,7 +62,7 @@ public static SectionBlock example03() { } /** - * A section block with a select menu of conversations. + * A section block with a conversations select menu accessory. */ public static SectionBlock example04() { SectionBlock block = Blocks.section(s -> s.blockId("section678") @@ -73,7 +73,7 @@ public static SectionBlock example04() { } /** - * A section block with a select menu of channels. + * A section block with a channels select menu accessory. */ public static SectionBlock example05() { SectionBlock block = Blocks.section(s -> s.blockId("section678") From 34ab9016c42b2f8a0cd37ff39199333f9709942e Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Mon, 31 Aug 2026 19:54:58 -0700 Subject: [PATCH 05/10] fix(block-kit): wrap file_input and rich_text_input examples in their docs view The docs.slack.dev reference pages show the file input element inside a modal view and the rich text input element inside a home view. Return those full View payloads (instead of a bare input block) so each example matches its reference JSON field-for-field, and update the tests to assert the full view payload. Descriptive Javadoc lines match the reviewed JS wording. Co-Authored-By: Claude --- .../src/main/java/elements/FileInput.java | 24 +++++---- .../src/main/java/elements/RichTextInput.java | 15 +++--- .../src/test/java/elements/FileInputTest.java | 46 ++++++++++++----- .../test/java/elements/RichTextInputTest.java | 51 ++++++++++--------- 4 files changed, 84 insertions(+), 52 deletions(-) diff --git a/block-kit/src/main/java/elements/FileInput.java b/block-kit/src/main/java/elements/FileInput.java index 6e3f6f8..e4e9ff6 100644 --- a/block-kit/src/main/java/elements/FileInput.java +++ b/block-kit/src/main/java/elements/FileInput.java @@ -3,8 +3,9 @@ import static com.slack.api.model.block.composition.BlockCompositions.plainText; import com.slack.api.model.block.Blocks; -import com.slack.api.model.block.InputBlock; import com.slack.api.model.block.element.BlockElements; +import com.slack.api.model.view.View; +import com.slack.api.model.view.Views; import java.util.List; /** @@ -13,14 +14,19 @@ */ public class FileInput { /** - * An input block with a file input element. + * A modal view with a file input element hosted in an input block. */ - public static InputBlock example01() { - InputBlock block = Blocks.input(i -> i.blockId("input_block_id") - .label(plainText("Upload Files")) - .element(BlockElements.fileInput(f -> f.actionId("file_input_action_id_1") - .filetypes(List.of("jpg", "png")) - .maxFiles(5)))); - return block; + public static View example01() { + View view = Views.view(v -> v.type("modal") + .title(Views.viewTitle(t -> t.type("plain_text").text("My App").emoji(true))) + .submit(Views.viewSubmit( + s -> s.type("plain_text").text("Submit").emoji(true))) + .close(Views.viewClose(c -> c.type("plain_text").text("Cancel").emoji(true))) + .blocks(List.of(Blocks.input(i -> i.blockId("input_block_id") + .label(plainText("Upload Files")) + .element(BlockElements.fileInput(f -> f.actionId("file_input_action_id_1") + .filetypes(List.of("jpg", "png")) + .maxFiles(5))))))); + return view; } } diff --git a/block-kit/src/main/java/elements/RichTextInput.java b/block-kit/src/main/java/elements/RichTextInput.java index 7503735..557164c 100644 --- a/block-kit/src/main/java/elements/RichTextInput.java +++ b/block-kit/src/main/java/elements/RichTextInput.java @@ -3,9 +3,10 @@ import static com.slack.api.model.block.composition.BlockCompositions.plainText; import com.slack.api.model.block.Blocks; -import com.slack.api.model.block.InputBlock; import com.slack.api.model.block.composition.DispatchActionConfig; import com.slack.api.model.block.element.BlockElements; +import com.slack.api.model.view.View; +import com.slack.api.model.view.Views; import java.util.List; /** @@ -15,17 +16,17 @@ */ public class RichTextInput { /** - * An input block with a rich text input element. + * A home view with an input block containing a rich text input element. */ - public static InputBlock example01() { - InputBlock block = - Blocks.input(i -> i.element(BlockElements.richTextInput(rt -> rt.actionId("rich_text_input-action") + public static View example01() { + View view = Views.view(v -> v.type("home").blocks(List.of(Blocks.input(i -> i.element( + BlockElements.richTextInput(rt -> rt.actionId("rich_text_input-action") .dispatchActionConfig(DispatchActionConfig.builder() .triggerActionsOn(List.of("on_character_entered")) .build()) .focusOnLoad(true) .placeholder(plainText("Enter text")))) - .label(plainText(l -> l.text("Label").emoji(true)))); - return block; + .label(plainText(l -> l.text("Label").emoji(true))))))); + return view; } } diff --git a/block-kit/src/test/java/elements/FileInputTest.java b/block-kit/src/test/java/elements/FileInputTest.java index ab48eea..22db5b1 100644 --- a/block-kit/src/test/java/elements/FileInputTest.java +++ b/block-kit/src/test/java/elements/FileInputTest.java @@ -3,30 +3,50 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import com.google.gson.JsonParser; -import com.slack.api.model.block.InputBlock; +import com.slack.api.model.view.View; import com.slack.api.util.json.GsonFactory; import org.junit.jupiter.api.Test; public class FileInputTest { @Test public void testExample01() { - InputBlock block = FileInput.example01(); - String actual = GsonFactory.createSnakeCase().toJson(block); + View view = FileInput.example01(); + String actual = GsonFactory.createSnakeCase().toJson(view); String expected = """ { - "type": "input", - "block_id": "input_block_id", - "label": { + "type": "modal", + "title": { "type": "plain_text", - "text": "Upload Files" + "text": "My App", + "emoji": true }, - "element": { - "type": "file_input", - "action_id": "file_input_action_id_1", - "filetypes": ["jpg", "png"], - "max_files": 5 + "submit": { + "type": "plain_text", + "text": "Submit", + "emoji": true + }, + "close": { + "type": "plain_text", + "text": "Cancel", + "emoji": true }, - "optional": false + "blocks": [ + { + "type": "input", + "block_id": "input_block_id", + "label": { + "type": "plain_text", + "text": "Upload Files" + }, + "element": { + "type": "file_input", + "action_id": "file_input_action_id_1", + "filetypes": ["jpg", "png"], + "max_files": 5 + }, + "optional": false + } + ] } """; assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); diff --git a/block-kit/src/test/java/elements/RichTextInputTest.java b/block-kit/src/test/java/elements/RichTextInputTest.java index 5b1e340..d32c94d 100644 --- a/block-kit/src/test/java/elements/RichTextInputTest.java +++ b/block-kit/src/test/java/elements/RichTextInputTest.java @@ -3,38 +3,43 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import com.google.gson.JsonParser; -import com.slack.api.model.block.InputBlock; +import com.slack.api.model.view.View; import com.slack.api.util.json.GsonFactory; import org.junit.jupiter.api.Test; public class RichTextInputTest { @Test public void testExample01() { - InputBlock block = RichTextInput.example01(); - String actual = GsonFactory.createSnakeCase().toJson(block); + View view = RichTextInput.example01(); + String actual = GsonFactory.createSnakeCase().toJson(view); String expected = """ { - "type": "input", - "element": { - "type": "rich_text_input", - "action_id": "rich_text_input-action", - "dispatch_action_config": { - "trigger_actions_on": [ - "on_character_entered" - ] - }, - "focus_on_load": true, - "placeholder": { - "type": "plain_text", - "text": "Enter text" + "type": "home", + "blocks": [ + { + "type": "input", + "element": { + "type": "rich_text_input", + "action_id": "rich_text_input-action", + "dispatch_action_config": { + "trigger_actions_on": [ + "on_character_entered" + ] + }, + "focus_on_load": true, + "placeholder": { + "type": "plain_text", + "text": "Enter text" + } + }, + "label": { + "type": "plain_text", + "text": "Label", + "emoji": true + }, + "optional": false } - }, - "label": { - "type": "plain_text", - "text": "Label", - "emoji": true - }, - "optional": false + ] } """; assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); From 46e68d6ac191ac1ad91e6834f569c633d93992c8 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Mon, 31 Aug 2026 21:25:06 -0700 Subject: [PATCH 06/10] docs(block-kit): match time_picker description to JS/Python (buggy docs summary) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Java previously used the correct body prose for the time-picker description; JS and Python now mirror the upstream docs description: frontmatter, which carries the number-input text by mistake (docs repo content/reference/block-kit/block-elements/time-picker-element.md:2). Align Java's class Javadoc + README the same way so all three example langs are identical, and the correction sweeps Java too when the docs fix lands. Traceability probe — do not pre-correct. Co-Authored-By: Claude --- block-kit/README.md | 2 +- block-kit/src/main/java/elements/TimePicker.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/block-kit/README.md b/block-kit/README.md index fb922e1..b2a3b1f 100644 --- a/block-kit/README.md +++ b/block-kit/README.md @@ -37,7 +37,7 @@ Read the [docs](https://docs.slack.dev/block-kit/) to learn concepts behind thes - **[Radio button group](https://docs.slack.dev/reference/block-kit/block-elements/radio-button-group-element)**: Allows users to choose one item from a list of possible options. [Implementation](./src/main/java/elements/RadioButtons.java). - **[Rich text input](https://docs.slack.dev/reference/block-kit/block-elements/rich-text-input-element)**: Allows users to enter formatted text in a WYSIWYG composer, offering the same messaging writing experience as in Slack. [Implementation](./src/main/java/elements/RichTextInput.java). - **[Select menu](https://docs.slack.dev/reference/block-kit/block-elements/select-menu-element)**: Allows users to choose an option from a drop down menu. [Implementation](./src/main/java/elements/SelectMenu.java). -- **[Time picker](https://docs.slack.dev/reference/block-kit/block-elements/time-picker-element)**: A time picker element; on desktop a dropdown with free-text entry, on mobile the native time picker UI. [Implementation](./src/main/java/elements/TimePicker.java). +- **[Time picker](https://docs.slack.dev/reference/block-kit/block-elements/time-picker-element)**: Allows users to enter numerical data into a single-line field. [Implementation](./src/main/java/elements/TimePicker.java). - **[URL input](https://docs.slack.dev/reference/block-kit/block-elements/url-input-element)**: Allows user to enter a URL into a single-line field. [Implementation](./src/main/java/elements/UrlInput.java). - **[Workflow button](https://docs.slack.dev/reference/block-kit/block-elements/workflow-button-element)**: Allows users to run a link trigger with customizable inputs. [Implementation](./src/main/java/elements/WorkflowButton.java). diff --git a/block-kit/src/main/java/elements/TimePicker.java b/block-kit/src/main/java/elements/TimePicker.java index 807c37a..be058c7 100644 --- a/block-kit/src/main/java/elements/TimePicker.java +++ b/block-kit/src/main/java/elements/TimePicker.java @@ -8,7 +8,7 @@ import com.slack.api.model.block.element.BlockElements; /** - * A time picker element; on desktop a dropdown with free-text entry, on mobile the native time picker UI. + * Allows users to enter numerical data into a single-line field. * {@link https://docs.slack.dev/reference/block-kit/block-elements/time-picker-element/} */ public class TimePicker { From 7ce26b8f835a54508bb426645eda4029d71f4a41 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Mon, 31 Aug 2026 21:42:34 -0700 Subject: [PATCH 07/10] feat(block-kit): add standalone rich-text sub-element examples to match JS/Python Node and Python model each rich-text sub-element as its own elements/ file; Java only demonstrated them nested inside blocks/RichText.java. Add standalone elements/ examples (+ test + README line each) for all 14 to converge the file layout across the three example repos: Broadcast, Channel, Color, Date, Emoji, Link, Team, Text, User, UserGroup, RichTextList, RichTextPreformatted, RichTextQuote, RichTextSection. The nested blocks/RichText.java example01-example14 are left intact (composition-within-a-block demo); the new files demonstrate each element in isolation, matching the JS/Python structure. Tests assert the complete Gson snake-case payload; spotless clean; 75 tests pass. Co-Authored-By: Claude --- block-kit/README.md | 14 ++ .../src/main/java/elements/Broadcast.java | 24 +++ block-kit/src/main/java/elements/Channel.java | 24 +++ block-kit/src/main/java/elements/Color.java | 23 +++ block-kit/src/main/java/elements/Date.java | 26 +++ block-kit/src/main/java/elements/Emoji.java | 33 ++++ block-kit/src/main/java/elements/Link.java | 24 +++ .../src/main/java/elements/RichTextList.java | 99 +++++++++++ .../java/elements/RichTextPreformatted.java | 27 +++ .../src/main/java/elements/RichTextQuote.java | 32 ++++ .../main/java/elements/RichTextSection.java | 56 +++++++ block-kit/src/main/java/elements/Team.java | 24 +++ block-kit/src/main/java/elements/Text.java | 30 ++++ block-kit/src/main/java/elements/User.java | 24 +++ .../src/main/java/elements/UserGroup.java | 24 +++ .../src/test/java/elements/BroadcastTest.java | 33 ++++ .../src/test/java/elements/ChannelTest.java | 33 ++++ .../src/test/java/elements/ColorTest.java | 33 ++++ .../src/test/java/elements/DateTest.java | 35 ++++ .../src/test/java/elements/EmojiTest.java | 49 ++++++ .../src/test/java/elements/LinkTest.java | 33 ++++ .../test/java/elements/RichTextListTest.java | 157 ++++++++++++++++++ .../elements/RichTextPreformattedTest.java | 34 ++++ .../test/java/elements/RichTextQuoteTest.java | 43 +++++ .../java/elements/RichTextSectionTest.java | 120 +++++++++++++ .../src/test/java/elements/TeamTest.java | 33 ++++ .../src/test/java/elements/TextTest.java | 47 ++++++ .../src/test/java/elements/UserGroupTest.java | 33 ++++ .../src/test/java/elements/UserTest.java | 33 ++++ 29 files changed, 1200 insertions(+) create mode 100644 block-kit/src/main/java/elements/Broadcast.java create mode 100644 block-kit/src/main/java/elements/Channel.java create mode 100644 block-kit/src/main/java/elements/Color.java create mode 100644 block-kit/src/main/java/elements/Date.java create mode 100644 block-kit/src/main/java/elements/Emoji.java create mode 100644 block-kit/src/main/java/elements/Link.java create mode 100644 block-kit/src/main/java/elements/RichTextList.java create mode 100644 block-kit/src/main/java/elements/RichTextPreformatted.java create mode 100644 block-kit/src/main/java/elements/RichTextQuote.java create mode 100644 block-kit/src/main/java/elements/RichTextSection.java create mode 100644 block-kit/src/main/java/elements/Team.java create mode 100644 block-kit/src/main/java/elements/Text.java create mode 100644 block-kit/src/main/java/elements/User.java create mode 100644 block-kit/src/main/java/elements/UserGroup.java create mode 100644 block-kit/src/test/java/elements/BroadcastTest.java create mode 100644 block-kit/src/test/java/elements/ChannelTest.java create mode 100644 block-kit/src/test/java/elements/ColorTest.java create mode 100644 block-kit/src/test/java/elements/DateTest.java create mode 100644 block-kit/src/test/java/elements/EmojiTest.java create mode 100644 block-kit/src/test/java/elements/LinkTest.java create mode 100644 block-kit/src/test/java/elements/RichTextListTest.java create mode 100644 block-kit/src/test/java/elements/RichTextPreformattedTest.java create mode 100644 block-kit/src/test/java/elements/RichTextQuoteTest.java create mode 100644 block-kit/src/test/java/elements/RichTextSectionTest.java create mode 100644 block-kit/src/test/java/elements/TeamTest.java create mode 100644 block-kit/src/test/java/elements/TextTest.java create mode 100644 block-kit/src/test/java/elements/UserGroupTest.java create mode 100644 block-kit/src/test/java/elements/UserTest.java diff --git a/block-kit/README.md b/block-kit/README.md index b2a3b1f..08c29bd 100644 --- a/block-kit/README.md +++ b/block-kit/README.md @@ -22,22 +22,36 @@ Read the [docs](https://docs.slack.dev/block-kit/) to learn concepts behind thes ### Block elements +- **[Broadcast](https://docs.slack.dev/reference/block-kit/block-elements/broadcast-element)**: Displays a broadcast mention such as here, channel, or everyone. [Implementation](./src/main/java/elements/Broadcast.java). - **[Button](https://docs.slack.dev/reference/block-kit/block-elements/button-element)**: Allows users a direct path to performing basic actions. [Implementation](./src/main/java/elements/Button.java). +- **[Channel](https://docs.slack.dev/reference/block-kit/block-elements/channel-element)**: Renders as a mention of a channel. [Implementation](./src/main/java/elements/Channel.java). +- **[Color](https://docs.slack.dev/reference/block-kit/block-elements/color-element)**: Displays a color swatch from a hex value. [Implementation](./src/main/java/elements/Color.java). +- **[Date](https://docs.slack.dev/reference/block-kit/block-elements/date-element)**: Displays a formatted, localized date. [Implementation](./src/main/java/elements/Date.java). - **[Date picker](https://docs.slack.dev/reference/block-kit/block-elements/date-picker-element)**: Allows users to select a date from a calendar style UI. [Implementation](./src/main/java/elements/DatePicker.java). - **[Datetime picker](https://docs.slack.dev/reference/block-kit/block-elements/datetime-picker-element)**: Allows users to select both a date and a time of day. [Implementation](./src/main/java/elements/DatetimePicker.java). - **[Email input](https://docs.slack.dev/reference/block-kit/block-elements/email-input-element)**: Allows user to enter an email into a single-line field. [Implementation](./src/main/java/elements/EmailInput.java). +- **[Emoji](https://docs.slack.dev/reference/block-kit/block-elements/emoji-element)**: Displays an emoji. [Implementation](./src/main/java/elements/Emoji.java). - **[Feedback buttons](https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element)**: Buttons to indicate positive or negative feedback. [Implementation](./src/main/java/elements/FeedbackButtons.java). - **[File input](https://docs.slack.dev/reference/block-kit/block-elements/file-input-element)**: Allows user to upload files. [Implementation](./src/main/java/elements/FileInput.java). - **[Icon button](https://docs.slack.dev/reference/block-kit/block-elements/icon-button-element)**: An icon button to perform actions. [Implementation](./src/main/java/elements/IconButton.java). - **[Image](https://docs.slack.dev/reference/block-kit/block-elements/image-element)**: Displays an image as part of a larger block of content. [Implementation](./src/main/java/elements/Image.java). +- **[Link](https://docs.slack.dev/reference/block-kit/block-elements/link-element)**: Displays a hyperlink. [Implementation](./src/main/java/elements/Link.java). - **[Multi-select menu](https://docs.slack.dev/reference/block-kit/block-elements/multi-select-menu-element)**: Allows users to select multiple items from a list of options. [Implementation](./src/main/java/elements/MultiSelectMenu.java). - **[Number input](https://docs.slack.dev/reference/block-kit/block-elements/number-input-element)**: Allows user to enter a number into a single-line field. [Implementation](./src/main/java/elements/NumberInput.java). - **[Overflow menu](https://docs.slack.dev/reference/block-kit/block-elements/overflow-menu-element)**: Allows users to press a button to view a list of options. [Implementation](./src/main/java/elements/OverflowMenu.java). - **[Plain-text input](https://docs.slack.dev/reference/block-kit/block-elements/plain-text-input-element)**: Allows users to enter freeform text data into a single-line or multi-line field. [Implementation](./src/main/java/elements/PlainTextInput.java). - **[Radio button group](https://docs.slack.dev/reference/block-kit/block-elements/radio-button-group-element)**: Allows users to choose one item from a list of possible options. [Implementation](./src/main/java/elements/RadioButtons.java). - **[Rich text input](https://docs.slack.dev/reference/block-kit/block-elements/rich-text-input-element)**: Allows users to enter formatted text in a WYSIWYG composer, offering the same messaging writing experience as in Slack. [Implementation](./src/main/java/elements/RichTextInput.java). +- **[Rich text list](https://docs.slack.dev/reference/block-kit/block-elements/rich-text-list-element)**: Displays a list of rich text items. [Implementation](./src/main/java/elements/RichTextList.java). +- **[Rich text preformatted](https://docs.slack.dev/reference/block-kit/block-elements/rich-text-preformatted-element)**: Displays a preformatted rich text element. [Implementation](./src/main/java/elements/RichTextPreformatted.java). +- **[Rich text quote](https://docs.slack.dev/reference/block-kit/block-elements/rich-text-quote-element)**: Displays a rich text quote block. [Implementation](./src/main/java/elements/RichTextQuote.java). +- **[Rich text section](https://docs.slack.dev/reference/block-kit/block-elements/rich-text-section-element)**: A section element that holds rich text elements. [Implementation](./src/main/java/elements/RichTextSection.java). - **[Select menu](https://docs.slack.dev/reference/block-kit/block-elements/select-menu-element)**: Allows users to choose an option from a drop down menu. [Implementation](./src/main/java/elements/SelectMenu.java). +- **[Team](https://docs.slack.dev/reference/block-kit/block-elements/team-element)**: Renders as a mention of a workspace or team. [Implementation](./src/main/java/elements/Team.java). +- **[Text](https://docs.slack.dev/reference/block-kit/block-elements/text-element)**: Displays text, optionally with styling. [Implementation](./src/main/java/elements/Text.java). - **[Time picker](https://docs.slack.dev/reference/block-kit/block-elements/time-picker-element)**: Allows users to enter numerical data into a single-line field. [Implementation](./src/main/java/elements/TimePicker.java). - **[URL input](https://docs.slack.dev/reference/block-kit/block-elements/url-input-element)**: Allows user to enter a URL into a single-line field. [Implementation](./src/main/java/elements/UrlInput.java). +- **[User](https://docs.slack.dev/reference/block-kit/block-elements/user-element)**: Renders as a mention of a user. [Implementation](./src/main/java/elements/User.java). +- **[Usergroup](https://docs.slack.dev/reference/block-kit/block-elements/usergroup-element)**: Renders as a mention of a user group. [Implementation](./src/main/java/elements/UserGroup.java). - **[Workflow button](https://docs.slack.dev/reference/block-kit/block-elements/workflow-button-element)**: Allows users to run a link trigger with customizable inputs. [Implementation](./src/main/java/elements/WorkflowButton.java). diff --git a/block-kit/src/main/java/elements/Broadcast.java b/block-kit/src/main/java/elements/Broadcast.java new file mode 100644 index 0000000..ad57011 --- /dev/null +++ b/block-kit/src/main/java/elements/Broadcast.java @@ -0,0 +1,24 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Displays a broadcast mention such as here, channel, or everyone. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/broadcast-element/} + */ +public class Broadcast { + /** + * A rich text block with a broadcast mention in a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Broadcast.builder() + .range("everyone") + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/Channel.java b/block-kit/src/main/java/elements/Channel.java new file mode 100644 index 0000000..d91e74f --- /dev/null +++ b/block-kit/src/main/java/elements/Channel.java @@ -0,0 +1,24 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Renders as a mention of a channel. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/channel-element/} + */ +public class Channel { + /** + * A rich text block with a channel mention in a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Channel.builder() + .channelId("C123ABC456") + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/Color.java b/block-kit/src/main/java/elements/Color.java new file mode 100644 index 0000000..1bb5a23 --- /dev/null +++ b/block-kit/src/main/java/elements/Color.java @@ -0,0 +1,23 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Displays a color swatch from a hex value. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/color-element/} + */ +public class Color { + /** + * A rich text block with a color element in a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of( + RichTextSectionElement.Color.builder().value("#F405B3").build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/Date.java b/block-kit/src/main/java/elements/Date.java new file mode 100644 index 0000000..7c3c9f5 --- /dev/null +++ b/block-kit/src/main/java/elements/Date.java @@ -0,0 +1,26 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Displays a formatted, localized date. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/date-element/} + */ +public class Date { + /** + * A rich text block with a date element in a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Date.builder() + .timestamp(1720710212) + .format("{date_num} at {time}") + .fallback("timey") + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/Emoji.java b/block-kit/src/main/java/elements/Emoji.java new file mode 100644 index 0000000..2ce758b --- /dev/null +++ b/block-kit/src/main/java/elements/Emoji.java @@ -0,0 +1,33 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Displays an emoji. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/emoji-element/} + */ +public class Emoji { + /** + * A rich text block with emoji elements in a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of( + RichTextSectionElement.Emoji.builder() + .name("basketball") + .build(), + RichTextSectionElement.Text.builder().text(" ").build(), + RichTextSectionElement.Emoji.builder() + .name("snowboarder") + .build(), + RichTextSectionElement.Text.builder().text(" ").build(), + RichTextSectionElement.Emoji.builder() + .name("checkered_flag") + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/Link.java b/block-kit/src/main/java/elements/Link.java new file mode 100644 index 0000000..7c1f0e2 --- /dev/null +++ b/block-kit/src/main/java/elements/Link.java @@ -0,0 +1,24 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Displays a hyperlink. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/link-element/} + */ +public class Link { + /** + * A rich text block with a link element in a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Link.builder() + .url("https://docs.slack.dev") + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/RichTextList.java b/block-kit/src/main/java/elements/RichTextList.java new file mode 100644 index 0000000..d9f16d1 --- /dev/null +++ b/block-kit/src/main/java/elements/RichTextList.java @@ -0,0 +1,99 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextListElement; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Displays a list of rich text items. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/rich-text-list-element/} + */ +public class RichTextList { + /** + * A rich text block with a bulleted list. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.blockId("block1") + .elements(List.of( + RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("My favorite Slack features (in no particular order):") + .build())) + .build(), + RichTextListElement.builder() + .style("bullet") + .indent(0) + .border(1) + .elements(List.of( + RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Huddles") + .build())) + .build(), + RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Canvas") + .build())) + .build(), + RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Developing with Block Kit") + .build())) + .build())) + .build()))); + return block; + } + + /** + * A rich text block with nested bulleted lists using indent. + */ + public static RichTextBlock example02() { + RichTextBlock block = Blocks.richText(rt -> rt.blockId("block1") + .elements(List.of( + RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Breakfast foods I enjoy:") + .build())) + .build(), + RichTextListElement.builder() + .style("bullet") + .elements(List.of( + RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Hashbrowns") + .build())) + .build(), + RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Eggs") + .build())) + .build())) + .build(), + RichTextListElement.builder() + .style("bullet") + .indent(1) + .elements(List.of( + RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Scrambled") + .build())) + .build(), + RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Over easy") + .build())) + .build())) + .build(), + RichTextListElement.builder() + .style("bullet") + .elements(List.of(RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Pancakes, extra syrup") + .build())) + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/RichTextPreformatted.java b/block-kit/src/main/java/elements/RichTextPreformatted.java new file mode 100644 index 0000000..0699403 --- /dev/null +++ b/block-kit/src/main/java/elements/RichTextPreformatted.java @@ -0,0 +1,27 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextPreformattedElement; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Displays a preformatted rich text element. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/rich-text-preformatted-element/} + */ +public class RichTextPreformatted { + /** + * A rich text block with a preformatted code section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextPreformattedElement.builder() + .border(0) + .elements(List.of(RichTextSectionElement.Text.builder() + .text( + "{\n \"object\": {\n \"description\": \"this is an example of a json object\"\n }\n}") + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/RichTextQuote.java b/block-kit/src/main/java/elements/RichTextQuote.java new file mode 100644 index 0000000..7d7492d --- /dev/null +++ b/block-kit/src/main/java/elements/RichTextQuote.java @@ -0,0 +1,32 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextQuoteElement; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Displays a rich text quote block. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/rich-text-quote-element/} + */ +public class RichTextQuote { + /** + * A rich text block with a quote followed by a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.blockId("Vrzsu") + .elements(List.of( + RichTextQuoteElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("What we need is good examples in our documentation.") + .build())) + .build(), + RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Yes - I completely agree, Luke!") + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/RichTextSection.java b/block-kit/src/main/java/elements/RichTextSection.java new file mode 100644 index 0000000..91f91e2 --- /dev/null +++ b/block-kit/src/main/java/elements/RichTextSection.java @@ -0,0 +1,56 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import com.slack.api.model.block.element.RichTextSectionElement.TextStyle; +import java.util.List; + +/** + * A section element that holds rich text elements. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/rich-text-section-element/} + */ +public class RichTextSection { + /** + * Rich text blocks showing basic, bold, italic, and strikethrough text sections. + */ + public static List example01() { + List blocks = List.of( + Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Hello there, I am a basic rich text block!") + .build())) + .build()))), + Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of( + RichTextSectionElement.Text.builder() + .text("Hello there, ") + .build(), + RichTextSectionElement.Text.builder() + .text("I am a bold rich text block!") + .style(TextStyle.builder().bold(true).build()) + .build())) + .build()))), + Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of( + RichTextSectionElement.Text.builder() + .text("Hello there, ") + .build(), + RichTextSectionElement.Text.builder() + .text("I am an italic rich text block!") + .style(TextStyle.builder().italic(true).build()) + .build())) + .build()))), + Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of( + RichTextSectionElement.Text.builder() + .text("Hello there, ") + .build(), + RichTextSectionElement.Text.builder() + .text("I am a strikethrough rich text block!") + .style(TextStyle.builder().strike(true).build()) + .build())) + .build())))); + return blocks; + } +} diff --git a/block-kit/src/main/java/elements/Team.java b/block-kit/src/main/java/elements/Team.java new file mode 100644 index 0000000..e14d090 --- /dev/null +++ b/block-kit/src/main/java/elements/Team.java @@ -0,0 +1,24 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Renders as a mention of a workspace or team. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/team-element/} + */ +public class Team { + /** + * A rich text block with a team mention in a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Team.builder() + .teamId("T123ABC456") + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/Text.java b/block-kit/src/main/java/elements/Text.java new file mode 100644 index 0000000..851e0eb --- /dev/null +++ b/block-kit/src/main/java/elements/Text.java @@ -0,0 +1,30 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import com.slack.api.model.block.element.RichTextSectionElement.TextStyle; +import java.util.List; + +/** + * Displays text, optionally with styling. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/text-element/} + */ +public class Text { + /** + * A rich text block with plain and bold text elements in a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of( + RichTextSectionElement.Text.builder() + .text("Hello there, ") + .build(), + RichTextSectionElement.Text.builder() + .text("I am a bold rich text block!") + .style(TextStyle.builder().bold(true).build()) + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/User.java b/block-kit/src/main/java/elements/User.java new file mode 100644 index 0000000..690e0ca --- /dev/null +++ b/block-kit/src/main/java/elements/User.java @@ -0,0 +1,24 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Renders as a mention of a user. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/user-element/} + */ +public class User { + /** + * A rich text block with a user mention in a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.User.builder() + .userId("U123ABC456") + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/UserGroup.java b/block-kit/src/main/java/elements/UserGroup.java new file mode 100644 index 0000000..d5dcd51 --- /dev/null +++ b/block-kit/src/main/java/elements/UserGroup.java @@ -0,0 +1,24 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Renders as a mention of a user group. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/usergroup-element/} + */ +public class UserGroup { + /** + * A rich text block with a user group mention in a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.UserGroup.builder() + .usergroupId("G123ABC456") + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/test/java/elements/BroadcastTest.java b/block-kit/src/test/java/elements/BroadcastTest.java new file mode 100644 index 0000000..e1567ed --- /dev/null +++ b/block-kit/src/test/java/elements/BroadcastTest.java @@ -0,0 +1,33 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class BroadcastTest { + @Test + public void testExample01() { + RichTextBlock block = Broadcast.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "broadcast", + "range": "everyone" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/ChannelTest.java b/block-kit/src/test/java/elements/ChannelTest.java new file mode 100644 index 0000000..0f9baae --- /dev/null +++ b/block-kit/src/test/java/elements/ChannelTest.java @@ -0,0 +1,33 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class ChannelTest { + @Test + public void testExample01() { + RichTextBlock block = Channel.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "channel", + "channel_id": "C123ABC456" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/ColorTest.java b/block-kit/src/test/java/elements/ColorTest.java new file mode 100644 index 0000000..c96731e --- /dev/null +++ b/block-kit/src/test/java/elements/ColorTest.java @@ -0,0 +1,33 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class ColorTest { + @Test + public void testExample01() { + RichTextBlock block = Color.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "color", + "value": "#F405B3" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/DateTest.java b/block-kit/src/test/java/elements/DateTest.java new file mode 100644 index 0000000..7cbeab7 --- /dev/null +++ b/block-kit/src/test/java/elements/DateTest.java @@ -0,0 +1,35 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class DateTest { + @Test + public void testExample01() { + RichTextBlock block = Date.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "date", + "timestamp": 1720710212, + "format": "{date_num} at {time}", + "fallback": "timey" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/EmojiTest.java b/block-kit/src/test/java/elements/EmojiTest.java new file mode 100644 index 0000000..8bf0e13 --- /dev/null +++ b/block-kit/src/test/java/elements/EmojiTest.java @@ -0,0 +1,49 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class EmojiTest { + @Test + public void testExample01() { + RichTextBlock block = Emoji.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "emoji", + "name": "basketball" + }, + { + "type": "text", + "text": " " + }, + { + "type": "emoji", + "name": "snowboarder" + }, + { + "type": "text", + "text": " " + }, + { + "type": "emoji", + "name": "checkered_flag" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/LinkTest.java b/block-kit/src/test/java/elements/LinkTest.java new file mode 100644 index 0000000..c6b84c3 --- /dev/null +++ b/block-kit/src/test/java/elements/LinkTest.java @@ -0,0 +1,33 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class LinkTest { + @Test + public void testExample01() { + RichTextBlock block = Link.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "link", + "url": "https://docs.slack.dev" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/RichTextListTest.java b/block-kit/src/test/java/elements/RichTextListTest.java new file mode 100644 index 0000000..6fddb86 --- /dev/null +++ b/block-kit/src/test/java/elements/RichTextListTest.java @@ -0,0 +1,157 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class RichTextListTest { + @Test + public void testExample01() { + RichTextBlock block = RichTextList.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "block_id": "block1", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "My favorite Slack features (in no particular order):" + } + ] + }, + { + "type": "rich_text_list", + "style": "bullet", + "indent": 0, + "border": 1, + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Huddles" + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Canvas" + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Developing with Block Kit" + } + ] + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample02() { + RichTextBlock block = RichTextList.example02(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "block_id": "block1", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Breakfast foods I enjoy:" + } + ] + }, + { + "type": "rich_text_list", + "style": "bullet", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Hashbrowns" + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Eggs" + } + ] + } + ] + }, + { + "type": "rich_text_list", + "style": "bullet", + "indent": 1, + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Scrambled" + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Over easy" + } + ] + } + ] + }, + { + "type": "rich_text_list", + "style": "bullet", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Pancakes, extra syrup" + } + ] + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/RichTextPreformattedTest.java b/block-kit/src/test/java/elements/RichTextPreformattedTest.java new file mode 100644 index 0000000..4ae915c --- /dev/null +++ b/block-kit/src/test/java/elements/RichTextPreformattedTest.java @@ -0,0 +1,34 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class RichTextPreformattedTest { + @Test + public void testExample01() { + RichTextBlock block = RichTextPreformatted.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_preformatted", + "border": 0, + "elements": [ + { + "type": "text", + "text": "{\\n \\"object\\": {\\n \\"description\\": \\"this is an example of a json object\\"\\n }\\n}" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/RichTextQuoteTest.java b/block-kit/src/test/java/elements/RichTextQuoteTest.java new file mode 100644 index 0000000..aa0264d --- /dev/null +++ b/block-kit/src/test/java/elements/RichTextQuoteTest.java @@ -0,0 +1,43 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class RichTextQuoteTest { + @Test + public void testExample01() { + RichTextBlock block = RichTextQuote.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "block_id": "Vrzsu", + "elements": [ + { + "type": "rich_text_quote", + "elements": [ + { + "type": "text", + "text": "What we need is good examples in our documentation." + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Yes - I completely agree, Luke!" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/RichTextSectionTest.java b/block-kit/src/test/java/elements/RichTextSectionTest.java new file mode 100644 index 0000000..91b7afe --- /dev/null +++ b/block-kit/src/test/java/elements/RichTextSectionTest.java @@ -0,0 +1,120 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class RichTextSectionTest { + @Test + public void testExample01() { + List blocks = RichTextSection.example01(); + String actual = GsonFactory.createSnakeCase().toJson(blocks); + String expected = """ + [ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Hello there, I am a basic rich text block!" + } + ] + } + ] + }, + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Hello there, " + }, + { + "type": "text", + "text": "I am a bold rich text block!", + "style": { + "bold": true, + "italic": false, + "strike": false, + "highlight": false, + "client_highlight": false, + "underline": false, + "unlink": false, + "code": false + } + } + ] + } + ] + }, + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Hello there, " + }, + { + "type": "text", + "text": "I am an italic rich text block!", + "style": { + "bold": false, + "italic": true, + "strike": false, + "highlight": false, + "client_highlight": false, + "underline": false, + "unlink": false, + "code": false + } + } + ] + } + ] + }, + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Hello there, " + }, + { + "type": "text", + "text": "I am a strikethrough rich text block!", + "style": { + "bold": false, + "italic": false, + "strike": true, + "highlight": false, + "client_highlight": false, + "underline": false, + "unlink": false, + "code": false + } + } + ] + } + ] + } + ] + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/TeamTest.java b/block-kit/src/test/java/elements/TeamTest.java new file mode 100644 index 0000000..fc3cc50 --- /dev/null +++ b/block-kit/src/test/java/elements/TeamTest.java @@ -0,0 +1,33 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class TeamTest { + @Test + public void testExample01() { + RichTextBlock block = Team.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "team", + "team_id": "T123ABC456" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/TextTest.java b/block-kit/src/test/java/elements/TextTest.java new file mode 100644 index 0000000..e6e00b5 --- /dev/null +++ b/block-kit/src/test/java/elements/TextTest.java @@ -0,0 +1,47 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class TextTest { + @Test + public void testExample01() { + RichTextBlock block = Text.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Hello there, " + }, + { + "type": "text", + "text": "I am a bold rich text block!", + "style": { + "bold": true, + "italic": false, + "strike": false, + "highlight": false, + "client_highlight": false, + "underline": false, + "unlink": false, + "code": false + } + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/UserGroupTest.java b/block-kit/src/test/java/elements/UserGroupTest.java new file mode 100644 index 0000000..17c055e --- /dev/null +++ b/block-kit/src/test/java/elements/UserGroupTest.java @@ -0,0 +1,33 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class UserGroupTest { + @Test + public void testExample01() { + RichTextBlock block = UserGroup.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "usergroup", + "usergroup_id": "G123ABC456" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/UserTest.java b/block-kit/src/test/java/elements/UserTest.java new file mode 100644 index 0000000..b6be589 --- /dev/null +++ b/block-kit/src/test/java/elements/UserTest.java @@ -0,0 +1,33 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class UserTest { + @Test + public void testExample01() { + RichTextBlock block = User.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "user", + "user_id": "U123ABC456" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} From 8ca6ab58fe77dee4ff6b26d25af00e8d4d188987 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Mon, 31 Aug 2026 21:49:32 -0700 Subject: [PATCH 08/10] revert(block-kit): drop Team from blocks/RichText.java, keep only elements/Team.java example14 (Team) was added to blocks/RichText.java by an earlier commit on this branch; now that Team has its own standalone elements/Team.java matching JS/Python, the nested duplicate is removed so blocks/RichText.java is byte-identical to main again (example01-example13). Also drops the matching RichTextTest.testExample14. Team is demonstrated once, in elements/Team.java. 74 tests pass. Co-Authored-By: Claude --- block-kit/src/main/java/blocks/RichText.java | 12 ---------- .../src/test/java/blocks/RichTextTest.java | 23 ------------------- 2 files changed, 35 deletions(-) diff --git a/block-kit/src/main/java/blocks/RichText.java b/block-kit/src/main/java/blocks/RichText.java index d400121..63e9944 100644 --- a/block-kit/src/main/java/blocks/RichText.java +++ b/block-kit/src/main/java/blocks/RichText.java @@ -281,16 +281,4 @@ public static RichTextBlock example13() { .build()))); return block; } - - /** - * A rich text block with a team mention element. - */ - public static RichTextBlock example14() { - RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() - .elements(List.of(RichTextSectionElement.Team.builder() - .teamId("T123ABC456") - .build())) - .build()))); - return block; - } } diff --git a/block-kit/src/test/java/blocks/RichTextTest.java b/block-kit/src/test/java/blocks/RichTextTest.java index 3d023bf..c67af51 100644 --- a/block-kit/src/test/java/blocks/RichTextTest.java +++ b/block-kit/src/test/java/blocks/RichTextTest.java @@ -522,27 +522,4 @@ public void testExample13() { """; assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); } - - @Test - public void testExample14() { - RichTextBlock block = RichText.example14(); - String actual = GsonFactory.createSnakeCase().toJson(block); - String expected = """ - { - "type": "rich_text", - "elements": [ - { - "type": "rich_text_section", - "elements": [ - { - "type": "team", - "team_id": "T123ABC456" - } - ] - } - ] - } - """; - assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); - } } From e7cba09313175e99fe1c4438ae8f32609d56e7d7 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Mon, 31 Aug 2026 22:00:57 -0700 Subject: [PATCH 09/10] refactor(block-kit): rename Button section/actions example example04 -> example05 Aligns Java's Button numbering with bolt-js-examples and bolt-python-examples, which both skip 04 and use example05 for the section/actions block example (the one that returns a list of blocks rather than a bare ButtonElement). example01-03 already matched (regular / primary / link button). Co-Authored-By: Claude --- block-kit/src/main/java/elements/Button.java | 2 +- block-kit/src/test/java/elements/ButtonTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/block-kit/src/main/java/elements/Button.java b/block-kit/src/main/java/elements/Button.java index 48a03cc..563d91d 100644 --- a/block-kit/src/main/java/elements/Button.java +++ b/block-kit/src/main/java/elements/Button.java @@ -44,7 +44,7 @@ public static ButtonElement example03() { /** * The button element used inside either the section or actions block. */ - public static List example04() { + public static List example05() { List blocks = List.of( Blocks.section(s -> s.text(markdownText("This is a section block with a button.")) .accessory(BlockElements.button(b -> b.text(plainText("Click Me")) diff --git a/block-kit/src/test/java/elements/ButtonTest.java b/block-kit/src/test/java/elements/ButtonTest.java index ca7d342..cbae6c6 100644 --- a/block-kit/src/test/java/elements/ButtonTest.java +++ b/block-kit/src/test/java/elements/ButtonTest.java @@ -65,8 +65,8 @@ public void testExample03() { } @Test - public void testExample04() { - List blocks = Button.example04(); + public void testExample05() { + List blocks = Button.example05(); String actual = GsonFactory.createSnakeCase().toJson(blocks); String expected = """ [ From 55c337efa482b623bedc7eb71bcc6a9bc018d7a8 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Mon, 31 Aug 2026 23:01:18 -0700 Subject: [PATCH 10/10] docs(block-kit): align workflow button description with docs wording MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The docs.slack.dev workflow-button-element page describes this example as "a section block containing a workflow button element" — match that prose (was "a section block with a workflow button accessory") and keep it identical to bolt-python-examples. Co-Authored-By: Claude --- block-kit/src/main/java/elements/WorkflowButton.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block-kit/src/main/java/elements/WorkflowButton.java b/block-kit/src/main/java/elements/WorkflowButton.java index 862a13a..6a3c192 100644 --- a/block-kit/src/main/java/elements/WorkflowButton.java +++ b/block-kit/src/main/java/elements/WorkflowButton.java @@ -15,7 +15,7 @@ */ public class WorkflowButton { /** - * A section block with a workflow button accessory. + * A section block containing a workflow button element. */ public static SectionBlock example01() { SectionBlock block =