defmodule BlockBox.LayoutBlocks do
@moduledoc """
Defines generator functions for all [layout blocks](https://api.slack.com/reference/block-kit/blocks).
"""
alias BlockBox.CompositionObjects, as: CO
alias BlockBox.Utils, as: Utils
@doc """
Creates a [section block](https://api.slack.com/reference/block-kit/blocks#section).
## Options
Options are not included by default.
* `:block_id` - string
* `:fields` - list of `t:BlockBox.CompositionObjects.text_object/0`s
* `:accessory` - any element from `BlockBox.BlockElements`
"""
@spec section(String.t() | CO.text_object(), keyword()) :: map()
def section(text, opts \\ [])
def section(text, opts) when is_binary(text) do
CO.text_object(text, :mrkdwn)
|> section(opts)
end
def section(text_object, opts) do
%{
type: "section",
text: text_object
}
|> Map.merge(Enum.into(opts, %{}))
end
@doc """
Creates a [divider block](https://api.slack.com/reference/block-kit/blocks#divider).
## Options
Options are not included by default.
* `:block_id` - String
"""
@spec divider(keyword()) :: map()
def divider(opts \\ []) do
%{type: "divider"}
|> Map.merge(Enum.into(opts, %{}))
end
@doc """
Creates an [image block](https://api.slack.com/reference/block-kit/blocks#image).
## Options
Options are not included by default.
* `:title` - `t:BlockBox.CompositionObjects.plain_text_object/0` or String
* `:block_id` - String
"""
@spec image_block(String.t(), String.t(), keyword()) :: map()
def image_block(image_url, alt_text, opts \\ []) do
opts = Utils.convert_text_opts(opts, [:title])
%{
type: "image",
image_url: image_url,
alt_text: alt_text
}
|> Map.merge(Enum.into(opts, %{}))
end
@doc """
Creates an [actions block](https://api.slack.com/reference/block-kit/blocks#actions).
## Options
Options are not included by default.
* `:block_id` - String
"""
@spec actions_block(list(), keyword()) :: map()
def actions_block(elements, opts \\ []) when is_list(elements) do
%{
type: "actions",
elements: elements
}
|> Map.merge(Enum.into(opts, %{}))
end
@doc """
Creates a [context block](https://api.slack.com/reference/block-kit/blocks#context).
## Options
Options are not included by default.
* `:block_id` - String
"""
@spec context_block(list(), keyword()) :: map()
def context_block(elements, opts \\ []) when is_list(elements) do
%{
type: "context",
elements: elements
}
|> Map.merge(Enum.into(opts, %{}))
end
@doc """
Creates an [input block](https://api.slack.com/reference/block-kit/blocks#input).
## Options
Options are not included by default.
* `:block_id` - String
* `:hint` - `t:BlockBox.CompositionObjects.plain_text_object/0` or String
* `:optional` - boolean
"""
@spec input(String.t() | CO.plain_text_object(), map(), keyword()) :: map()
def input(label, element, opts \\ [])
def input(label, element, opts) when is_binary(label) do
CO.text_object(label)
|> input(element, opts)
end
def input(label, element, opts) do
opts = Utils.convert_text_opts(opts, [:hint])
%{
type: "input",
element: element,
label: label
}
|> Map.merge(Enum.into(opts, %{}))
end
@doc """
Creates a [file block](https://api.slack.com/reference/block-kit/blocks#file).
## Options
Options are not included by default.
* `:block_id` - String
"""
def file_block(external_id, source \\ "remote", opts \\ []) do
%{
type: "file",
external_id: external_id,
source: source
}
|> Map.merge(Enum.into(opts, %{}))
end
end