<!-- ![alt example block creation](https://raw.githubusercontent.com/azohra/BlockBox/master/images/shit_bricks.png) -->
<p align="center">
<img src="images/stroke_shit_bricks.png" width="600" alt="logo">
</p>
# BlockBox
A tool used to generate slack UI blocks using elixir defined functions.
## Motivation
* Slack blocks are large
- As seen in the example below, the json payload is about 2 times larger than the functional definition.
* Usability
- There's no longer a need to memorize Slack block-kit syntax. Get off the ground faster when building your blocks.
* Reusability
- Repetition of blocks is reduced across code, the same functions are used and can be changed in a single place.
* Readability
- It's easier to read functions with parameters instead of large scoped blocks.
## Installation
```elixir
def deps do
[
{:blockbox, "~> 1.1.2"}
]
end
```
## Usage
use BlockBox to get access to all the components visible in our [hex docs](https://hex.pm/packages/blockbox).
```
use BlockBox
```
## Example
The following Slack UI view
<!-- ![alt example block creation](https://raw.githubusercontent.com/azohra/BlockBox/master/images/demo.png) -->
<img src="images/demo.png" width="600" alt="example view">
has the elixir structure shown below (it is assumed that atoms will be converted to strings using whatever JSON encoding library you're using)
```elixir
[
%{type: "divider"},
%{
block_id: "summary",
element: %{action_id: "sum_input", type: "plain_text_input"},
label: %{text: "Summary", type: :plain_text},
type: "input"
},
%{elements: [%{text: "Summarize ...", type: :mrkdwn}], type: "context"},
%{
block_id: "description",
element: %{
action_id: "desc_input",
multiline: true,
placeholder: %{text: "Write something", type: :plain_text},
type: "plain_text_input"
},
label: %{text: "Description", type: :plain_text},
type: "input"
},
%{elements: [%{text: "Describe ...", type: :mrkdwn}], type: "context"},
%{
block_id: "priority",
element: %{
action_id: "priority_input",
options: [
%{text: %{text: "P1", type: :plain_text}, value: "6"},
%{text: %{text: "P2", type: :plain_text}, value: "7"},
%{text: %{text: "P3", type: :plain_text}, value: "8"},
%{text: %{text: "P4", type: :plain_text}, value: "9"}
],
placeholder: %{text: "Select items", type: :plain_text},
type: :static_select
},
label: %{text: "Priority", type: :plain_text},
type: "input"
},
%{
block_id: "labels",
element: %{
action_id: "label_input",
multiline: true,
placeholder: %{text: "thing1, thing2, ...", type: :plain_text},
type: "plain_text_input"
},
label: %{text: "Labels", type: :plain_text},
type: "input"
}
]
```
using BlockBox the structure can be simplified to
```elixir
[
divider(),
input("Summary", plain_text_input("sum_input"), block_id: "summary"),
context_block([text_object("Summarize ...", :mrkdwn)]),
input(
"Description",
plain_text_input("desc_input", multiline: true, placeholder: "Write something"),
block_id: "description"
),
context_block([text_object("Describe ...", :mrkdwn)]),
input(
"Priority",
select_menu("Select items", :static_select, "priority_input",
options: Enum.map(1..4, fn x -> option_object("P#{x}", "#{x + 5}") end)
),
block_id: "priority"
),
input(
"Labels",
plain_text_input("label_input", multiline: true, placeholder: "thing1, thing2, ..."),
block_id: "labels"
)
]
```