# `Noizu.Slack.Blocks`
[🔗](https://github.com/noizu-labs-sdks/elixir-slack/blob/v0.1.0/lib/noizu/slack/blocks.ex#L1)

Block Kit builders and limit validation. Builders return plain maps (atom keys)
ready for `Noizu.Slack.Chat.post_message/4`'s `:blocks`.

    alias Noizu.Slack.Blocks

    blocks = [
      Blocks.header("Deploy finished"),
      Blocks.section("*api* rolled out", fields: ["*Env*\nprod", "*SHA*\n`abc123`"]),
      Blocks.divider(),
      Blocks.context(["triggered by <@U123>"]),
      Blocks.actions([Blocks.button("Open", "open_run", url: "https://example.com")])
    ]

    {:ok, blocks} = Blocks.validate(blocks)

## Limits enforced by `validate/1`

  * at most 50 blocks per message — exceeding is an error;
  * section `text` ≤ 3000 chars, each section field ≤ 2000 chars, header text ≤ 150
    chars — overlong text is **truncated** with a `…(truncated)` marker;
  * at most 10 fields per section — exceeding is an error.

# `block`

```elixir
@type block() :: map()
```

# `text_object`

```elixir
@type text_object() :: %{type: String.t(), text: String.t()}
```

# `actions`

```elixir
@spec actions([map()]) :: block()
```

An actions block of interactive elements.

# `button`

```elixir
@spec button(String.t(), String.t(), keyword()) :: map()
```

A button element. Options: `:value`, `:url`, `:style` (`"primary"` / `"danger"`).

# `context`

```elixir
@spec context([String.t() | map()]) :: block()
```

A context block; strings become mrkdwn elements, maps pass through.

# `divider`

```elixir
@spec divider() :: block()
```

A divider block.

# `fields`

```elixir
@spec fields([String.t() | map()]) :: [map()]
```

A list of mrkdwn text objects for a section's `:fields`.

# `header`

```elixir
@spec header(String.t()) :: block()
```

A header block (plain text).

# `image`

```elixir
@spec image(String.t(), String.t()) :: block()
```

An image block.

# `max_blocks`

Block limit per message (50).

# `max_section_text`

Section text limit (3000 chars).

# `mrkdwn`

```elixir
@spec mrkdwn(String.t()) :: text_object()
```

A `mrkdwn` text object.

# `plain_text`

```elixir
@spec plain_text(String.t()) :: map()
```

A `plain_text` text object (emoji enabled).

# `section`

```elixir
@spec section(String.t() | map(), keyword()) :: block()
```

A section block. `text` may be a string (mrkdwn) or a text object. Options:
`:fields` (strings or text objects), `:accessory` (an element, e.g. `button/3`),
`:block_id`.

# `truncate`

```elixir
@spec truncate(String.t(), pos_integer()) :: String.t()
```

Truncates `text` to `max` characters (graphemes), ending with the marker when cut.

# `truncation_marker`

Truncation marker appended to overlong text.

# `validate`

```elixir
@spec validate([block()]) :: {:ok, [block()]} | {:error, Noizu.Slack.Error.t()}
```

Validates (and normalizes) a block list against Slack's limits. Overlong text is
truncated with the marker; structural violations return
`{:error, %Error{tag: :blocks}}`. Works on atom- or string-keyed blocks.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
