Modals
The term "Modal" refers to a pop-up window within the Discord client. Modals contain a title and a number of Components.
Type | Input | Has ID |
---|---|---|
Action Row | ❌ No | |
Text Input (Line) | Single Line | ✅ Yes |
Text Input (Paragraph) | Multiple Lines | ✅ Yes |
As the ModalForm
type attempts to expose an API similar to the concept of UI forms; Modal components are referred to as Widgets, to be placed on a grid.
As of this writing, this concept hasn't yet been fully explored. We plan to expand upon the concept later.
Limitations
There are a number of limitations to keep in mind when working with Discord modals.
Discord won't tell the bot when a user closes a Modal without submitting it. The only way around this is to use a timeout, and assume that the Modal won't be submitted once it expires.
As Modals use interactions, they must be submitted within 15 minutes. The interaction will fail if the user takes too long to submit a Modal.
Modals have a very limited number of compatible Widgets. They used to support Select Menus, but this support was suddenly removed without explanation.
Modals may only be sent as the first response to an interaction. This means they must be created and sent within 5 seconds, and they cannot be sent once the interaction has been deferred, edited, or responded to.
Modal Forms
Kord Extensions represents Modals using the ModalForm
type. This type provides a container for a Modal's Widgets, settings, and data. Similarly to command arguments classes, you'll need to extend ModalForm
when creating your Modals.
The ModalForm
type exposes a number of APIs.
Widgets
Name | Description |
---|---|
| Create a text input Widget which supports a single line of text. |
| Create a text input Widget which supports multiple lines of text. |
Widget DSL API
All Widgets
The following properties are available on all Widget types.
Name | Type | Description |
---|---|---|
|
| The value provided by the user when the Modal is submitted. |
Text Widgets
The following properties are available on all text-based Widget types.
Name | Type | Description | |
---|---|---|---|
|
| Required: Key object representing a short, descriptive label that explains what the user should enter into the Widget. | |
|
| The Widget's ID, used as the component ID on Discord. Defaults to a randomly generated UUID. | |
|
| Key object representing an optional value to provide for this Widget. This will show as a pre-filled value on Discord, for the user to edit. | |
|
| The maximum number of characters that a user may provide as a value. | |
|
| The minimum number of characters that a user may provide as a value. | |
|
| Key object representing some optional placeholder text. This will show as text within the component on Discord, in a lighter font, and will be hidden when the user enters text into the component. | |
|
| Whether the user must provide a value for this Widget to submit the Modal. Defaults to | |
|
| Whether to attempt to translate the When this is set to | |
|
| The value provided by the user when the Modal is submitted. Will be |
Builders
Name | Description |
---|---|
| Convenience function to send the Modal to the current interaction, wait for its completion, and call the provided The callback block will receive a Several overrides are provided, which will fill the function's parameters using the given event or command context object. |
Functions
Name | Description |
---|---|
| Calls |
| Calls |
Properties
Name | Type | Description |
---|---|---|
|
| Modal ID, used to associate the |
|
| How long to wait before assuming that the used closed the Modal. Defaults to 15 minutes. |
|
| Required: Override this Key object to set the Modal's title, which will be shown in the Discord client. |
Implementation Strategies
There are several ways to support Modals in your bots. We've detailed the major approaches below.
Automatic
The simplest way to add a Modal to your bot is to create a ModalForm
as described above, and pass the constructor to your Application Command or Component builder functions.
This causes a Modal to be sent as the first response to that command invocation or component interaction, with the filled-in ModalForm
(or null
if timed out) provided as an argument to the action
block.
For Slash Commands, you may also combine this with an Arguments
subtype.
Semi-Automatic
Sometimes, the fully automatic approach isn't appropriate. For example, perhaps your Modal needs to be modified based on the arguments provided to the command, or needs to be pre-filled with data from your database.
For these cases, you can instantiate your ModalForm
subtype yourself, using the types provided by the Unsafe Module to delay the interaction response.
This approach should be combined with the use of the sendAndDefer
functions.
This approach is also appropriate for relevant event handlers.
Manual
For greater control than either of the above approaches, you can also retain control over how your bot responds to the Modal submission interaction.
You can do this by following the semi-automatic approach, replacing the sendAndDefer
functions with sendAndAwait
.
Without Forms
While there are very few situations where this is useful, it is possible to define and handle Modals without using Kord Extensions' abstractions. This is a relatively complex process in comparison, but it's still an approachable strategy.