EDA.Modal (EDA v0.3.0)

Copy Markdown View Source

Builder for Discord Modal dialogs.

Modals are popup forms with text inputs, shown as an interaction response (type 9). Each modal contains 1–5 text inputs, a title, and a custom_id.

Features

  • Dedicated builder API — no need to construct raw maps manually
  • Validation — enforces Discord limits at build time (title length, input count, etc.)
  • text_input/3 builder with all options (min/max length, placeholder, value, required)
  • get_value/2 helper to extract submitted values from MODAL_SUBMIT interactions

Example

import EDA.Modal

modal =
  modal("feedback_form", "Send Feedback",
    text_input("subject", "Subject", :short,
      placeholder: "Brief summary",
      min_length: 1,
      max_length: 100
    ),
    text_input("body", "Details", :paragraph,
      placeholder: "Describe in detail...",
      required: false
    )
  )

# Send as interaction response
EDA.Interaction.respond_modal(interaction, modal)

Handling submissions

def handle_event({:INTERACTION_CREATE, interaction}) do
  import EDA.Interaction
  import EDA.Modal

  if interaction_type(interaction) == :modal_submit and custom_id(interaction) == "feedback_form" do
    subject = get_value(interaction, "subject")
    body = get_value(interaction, "body")
    respond(interaction, "Got it: #{subject}")
  end
end

Summary

Functions

Extracts a single value from a MODAL_SUBMIT interaction by custom_id.

Extracts all submitted values from a MODAL_SUBMIT interaction.

Creates a modal dialog from a list of text inputs.

Creates a text input component for use inside a modal.

Functions

get_value(interaction, custom_id, default \\ nil)

@spec get_value(map(), String.t(), term()) :: String.t() | nil | term()

Extracts a single value from a MODAL_SUBMIT interaction by custom_id.

Returns nil if not found, or default if provided.

Example

subject = EDA.Modal.get_value(interaction, "subject")

get_values(arg1)

@spec get_values(map()) :: %{required(String.t()) => String.t()}

Extracts all submitted values from a MODAL_SUBMIT interaction.

Returns a map of %{"custom_id" => "value"}.

Example

values = EDA.Modal.get_values(interaction)
# => %{"subject" => "Bug report", "body" => "The bot crashed..."}

modal(custom_id, title, input1, input2 \\ nil, input3 \\ nil, input4 \\ nil, input5 \\ nil)

@spec modal(
  String.t(),
  String.t(),
  map(),
  map() | nil,
  map() | nil,
  map() | nil,
  map() | nil
) :: map()

Creates a modal dialog with the given text inputs.

Parameters

  • custom_id — unique identifier for the modal (1–100 chars)
  • title — title displayed at top (max 45 chars)
  • inputs — 1–5 text input maps (from text_input/4)

Example

modal("survey", "Quick Survey",
  text_input("q1", "Favorite color?", :short),
  text_input("q2", "Why?", :paragraph, required: false)
)

text_input(custom_id, label, style, opts \\ [])

@spec text_input(String.t(), String.t(), :short | :paragraph, keyword()) :: map()

Creates a text input component for use inside a modal.

Parameters

  • custom_id — unique identifier for this field (1–100 chars)
  • label — label displayed above the input (max 45 chars)
  • style — :short (single line) or :paragraph (multi-line)

Options

  • :placeholder — hint text when empty (max 100 chars)
  • :min_length — minimum input length (0–4000)
  • :max_length — maximum input length (1–4000)
  • :required — whether the field must be filled (default true)
  • :value — pre-filled text (max 4000 chars)

Example

text_input("name", "Your Name", :short, placeholder: "John Doe")
text_input("bio", "About You", :paragraph, required: false, max_length: 1000)