From 3659c59ce7b3ee8c0281bf28499e733e1bc0752b Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Fri, 29 Aug 2025 14:16:14 +0400 Subject: [PATCH] feat: Support select in modals (#1321) --- .../payloads/v10/_interactions/modalSubmit.ts | 25 ++++++-- deno/payloads/v10/_interactions/responses.ts | 10 +++- deno/payloads/v10/channel.ts | 57 ++++++++++++++++--- deno/payloads/v9/_interactions/modalSubmit.ts | 25 ++++++-- deno/payloads/v9/_interactions/responses.ts | 10 +++- deno/payloads/v9/channel.ts | 57 ++++++++++++++++--- payloads/v10/_interactions/modalSubmit.ts | 25 ++++++-- payloads/v10/_interactions/responses.ts | 10 +++- payloads/v10/channel.ts | 57 ++++++++++++++++--- payloads/v9/_interactions/modalSubmit.ts | 25 ++++++-- payloads/v9/_interactions/responses.ts | 10 +++- payloads/v9/channel.ts | 57 ++++++++++++++++--- 12 files changed, 306 insertions(+), 62 deletions(-) diff --git a/deno/payloads/v10/_interactions/modalSubmit.ts b/deno/payloads/v10/_interactions/modalSubmit.ts index 3a431255..80d95c43 100644 --- a/deno/payloads/v10/_interactions/modalSubmit.ts +++ b/deno/payloads/v10/_interactions/modalSubmit.ts @@ -7,16 +7,31 @@ import type { InteractionType, } from '../mod.ts'; -export interface ModalSubmitComponent { - type: ComponentType; +export interface APIBaseModalSubmitComponent extends APIBaseComponent { + type: T; custom_id: string; +} + +export interface APIModalSubmitTextInputComponent extends APIBaseModalSubmitComponent { value: string; } -export interface ModalSubmitActionRowComponent extends APIBaseComponent { - components: ModalSubmitComponent[]; +export interface APIModalSubmitStringSelectComponent extends APIBaseModalSubmitComponent { + values: string[]; } +export type ModalSubmitComponent = APIModalSubmitStringSelectComponent | APIModalSubmitTextInputComponent; + +export interface ModalSubmitActionRowComponent extends APIBaseComponent { + components: APIModalSubmitTextInputComponent[]; +} + +export interface ModalSubmitLabelComponent extends APIBaseComponent { + component: ModalSubmitComponent; +} + +export type APIModalSubmissionComponent = ModalSubmitActionRowComponent | ModalSubmitLabelComponent; + /** * @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-modal-submit-data-structure} */ @@ -28,7 +43,7 @@ export interface APIModalSubmission { /** * A list of child components */ - components: ModalSubmitActionRowComponent[]; + components: APIModalSubmissionComponent[]; } /** diff --git a/deno/payloads/v10/_interactions/responses.ts b/deno/payloads/v10/_interactions/responses.ts index a56736ce..5068bf08 100644 --- a/deno/payloads/v10/_interactions/responses.ts +++ b/deno/payloads/v10/_interactions/responses.ts @@ -1,5 +1,5 @@ import type { RESTPostAPIWebhookWithTokenJSONBody } from '../../../v10.ts'; -import type { APIActionRowComponent, APIComponentInModalActionRow } from '../channel.ts'; +import type { APIActionRowComponent, APIComponentInModalActionRow, APILabelComponent } from '../channel.ts'; import type { APIApplicationCommandOptionChoice } from './applicationCommands.ts'; /** @@ -126,6 +126,10 @@ export interface APICommandAutocompleteInteractionResponseCallbackData { choices?: APIApplicationCommandOptionChoice[]; } +export type APIModalInteractionResponseCallbackComponent = + | APIActionRowComponent + | APILabelComponent; + /** * @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-modal} */ @@ -140,6 +144,8 @@ export interface APIModalInteractionResponseCallbackData { title: string; /** * Between 1 and 5 (inclusive) components that make up the modal + * + * @remarks Using action rows inside modals is deprecated. */ - components: APIActionRowComponent[]; + components: APIModalInteractionResponseCallbackComponent[]; } diff --git a/deno/payloads/v10/channel.ts b/deno/payloads/v10/channel.ts index 75e66996..ca337f0b 100644 --- a/deno/payloads/v10/channel.ts +++ b/deno/payloads/v10/channel.ts @@ -1705,7 +1705,10 @@ export enum ComponentType { * Container that visually groups a set of components */ Container, - + /** + * Container associating a label and description with a component + */ + Label, // EVERYTHING BELOW THIS LINE SHOULD BE OLD NAMES FOR RENAMED ENUM MEMBERS // /** @@ -1717,7 +1720,7 @@ export enum ComponentType { } /** - * An Action Row is a top-level layout component used in messages and modals. + * An Action Row is a top-level layout component used in messages. Use in modals is deprecated. * * @see {@link https://discord.com/developers/docs/components/reference#action-row} */ @@ -1919,7 +1922,7 @@ export interface APIBaseAutoPopulatedSelectMenuComponent< * * String Selects can be configured for both single-select and multi-select behavior. When a user finishes making their choice(s) your app receives an interaction. * - * String Selects must be placed inside an Action Row and are only available in messages. An Action Row can contain only one select menu and cannot contain buttons if it has a select menu. + * An Action Row can contain only one select menu and cannot contain buttons if it has a select menu. * * @see {@link https://discord.com/developers/docs/components/reference#string-select} */ @@ -1928,6 +1931,10 @@ export interface APIStringSelectComponent extends APIBaseSelectMenuComponent { + /** + * The label text; max 45 characters + */ + label: string; + /** + * An optional description text for the label; max 100 characters + */ + description?: string; + /** + * The component within the label + */ + component: APIComponentInLabel; +} + /** * @see {@link https://discord.com/developers/docs/resources/channel#message-snapshot-object} */ @@ -2403,7 +2432,11 @@ export type APIMessageTopLevelComponent = /** * @see {@link https://discord.com/developers/docs/components/reference} */ -export type APIModalComponent = APIActionRowComponent | APIComponentInModalActionRow; +export type APIModalComponent = + | APIActionRowComponent + | APIComponentInLabel + | APIComponentInModalActionRow + | APILabelComponent; /** * @see {@link https://discord.com/developers/docs/components/reference#action-row} @@ -2417,9 +2450,15 @@ export type APIComponentInMessageActionRow = APIButtonComponent | APISelectMenuC /** * @see {@link https://discord.com/developers/docs/components/reference#action-row} + * @deprecated */ export type APIComponentInModalActionRow = APITextInputComponent; +/** + * @see {@link https://discord.com/developers/docs/components/reference#label-label-child-components} + */ +export type APIComponentInLabel = APIStringSelectComponent | APITextInputComponent; + /** * @see {@link https://discord.com/developers/docs/components/reference#section} */ diff --git a/deno/payloads/v9/_interactions/modalSubmit.ts b/deno/payloads/v9/_interactions/modalSubmit.ts index 3a431255..80d95c43 100644 --- a/deno/payloads/v9/_interactions/modalSubmit.ts +++ b/deno/payloads/v9/_interactions/modalSubmit.ts @@ -7,16 +7,31 @@ import type { InteractionType, } from '../mod.ts'; -export interface ModalSubmitComponent { - type: ComponentType; +export interface APIBaseModalSubmitComponent extends APIBaseComponent { + type: T; custom_id: string; +} + +export interface APIModalSubmitTextInputComponent extends APIBaseModalSubmitComponent { value: string; } -export interface ModalSubmitActionRowComponent extends APIBaseComponent { - components: ModalSubmitComponent[]; +export interface APIModalSubmitStringSelectComponent extends APIBaseModalSubmitComponent { + values: string[]; } +export type ModalSubmitComponent = APIModalSubmitStringSelectComponent | APIModalSubmitTextInputComponent; + +export interface ModalSubmitActionRowComponent extends APIBaseComponent { + components: APIModalSubmitTextInputComponent[]; +} + +export interface ModalSubmitLabelComponent extends APIBaseComponent { + component: ModalSubmitComponent; +} + +export type APIModalSubmissionComponent = ModalSubmitActionRowComponent | ModalSubmitLabelComponent; + /** * @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-modal-submit-data-structure} */ @@ -28,7 +43,7 @@ export interface APIModalSubmission { /** * A list of child components */ - components: ModalSubmitActionRowComponent[]; + components: APIModalSubmissionComponent[]; } /** diff --git a/deno/payloads/v9/_interactions/responses.ts b/deno/payloads/v9/_interactions/responses.ts index 136e3fd5..570fecfe 100644 --- a/deno/payloads/v9/_interactions/responses.ts +++ b/deno/payloads/v9/_interactions/responses.ts @@ -1,5 +1,5 @@ import type { RESTPostAPIWebhookWithTokenJSONBody } from '../../../v9.ts'; -import type { APIActionRowComponent, APIComponentInModalActionRow } from '../channel.ts'; +import type { APIActionRowComponent, APIComponentInModalActionRow, APILabelComponent } from '../channel.ts'; import type { APIApplicationCommandOptionChoice } from './applicationCommands.ts'; /** @@ -126,6 +126,10 @@ export interface APICommandAutocompleteInteractionResponseCallbackData { choices?: APIApplicationCommandOptionChoice[]; } +export type APIModalInteractionResponseCallbackComponent = + | APIActionRowComponent + | APILabelComponent; + /** * @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-modal} */ @@ -140,6 +144,8 @@ export interface APIModalInteractionResponseCallbackData { title: string; /** * Between 1 and 5 (inclusive) components that make up the modal + * + * @remarks Using action rows inside modals is deprecated. */ - components: APIActionRowComponent[]; + components: APIModalInteractionResponseCallbackComponent[]; } diff --git a/deno/payloads/v9/channel.ts b/deno/payloads/v9/channel.ts index 54efa51e..23b4c78a 100644 --- a/deno/payloads/v9/channel.ts +++ b/deno/payloads/v9/channel.ts @@ -1704,7 +1704,10 @@ export enum ComponentType { * Container that visually groups a set of components */ Container, - + /** + * Container associating a label and description with a component + */ + Label, // EVERYTHING BELOW THIS LINE SHOULD BE OLD NAMES FOR RENAMED ENUM MEMBERS // /** @@ -1716,6 +1719,8 @@ export enum ComponentType { } /** + * An Action Row is a top-level layout component used in messages. Use in modals is deprecated. + * * @see {@link https://discord.com/developers/docs/components/reference#action-row} */ export interface APIActionRowComponent @@ -1916,7 +1921,7 @@ export interface APIBaseAutoPopulatedSelectMenuComponent< * * String Selects can be configured for both single-select and multi-select behavior. When a user finishes making their choice(s) your app receives an interaction. * - * String Selects must be placed inside an Action Row and are only available in messages. An Action Row can contain only one select menu and cannot contain buttons if it has a select menu. + * An Action Row can contain only one select menu and cannot contain buttons if it has a select menu. * * @see {@link https://discord.com/developers/docs/components/reference#string-select} */ @@ -1925,6 +1930,10 @@ export interface APIStringSelectComponent extends APIBaseSelectMenuComponent { + /** + * The label text; max 45 characters + */ + label: string; + /** + * An optional description text for the label; max 100 characters + */ + description?: string; + /** + * The component within the label + */ + component: APIComponentInLabel; +} + /** * @see {@link https://discord.com/developers/docs/resources/channel#message-snapshot-object} */ @@ -2400,7 +2431,11 @@ export type APIMessageTopLevelComponent = /** * @see {@link https://discord.com/developers/docs/components/reference} */ -export type APIModalComponent = APIActionRowComponent | APIComponentInModalActionRow; +export type APIModalComponent = + | APIActionRowComponent + | APIComponentInLabel + | APIComponentInModalActionRow + | APILabelComponent; /** * @see {@link https://discord.com/developers/docs/components/reference#action-row} @@ -2414,9 +2449,15 @@ export type APIComponentInMessageActionRow = APIButtonComponent | APISelectMenuC /** * @see {@link https://discord.com/developers/docs/components/reference#action-row} + * @deprecated */ export type APIComponentInModalActionRow = APITextInputComponent; +/** + * @see {@link https://discord.com/developers/docs/components/reference#label-label-child-components} + */ +export type APIComponentInLabel = APIStringSelectComponent | APITextInputComponent; + /** * @see {@link https://discord.com/developers/docs/components/reference#section} */ diff --git a/payloads/v10/_interactions/modalSubmit.ts b/payloads/v10/_interactions/modalSubmit.ts index fbb9d3c3..97c8c4d7 100644 --- a/payloads/v10/_interactions/modalSubmit.ts +++ b/payloads/v10/_interactions/modalSubmit.ts @@ -7,16 +7,31 @@ import type { InteractionType, } from '../index'; -export interface ModalSubmitComponent { - type: ComponentType; +export interface APIBaseModalSubmitComponent extends APIBaseComponent { + type: T; custom_id: string; +} + +export interface APIModalSubmitTextInputComponent extends APIBaseModalSubmitComponent { value: string; } -export interface ModalSubmitActionRowComponent extends APIBaseComponent { - components: ModalSubmitComponent[]; +export interface APIModalSubmitStringSelectComponent extends APIBaseModalSubmitComponent { + values: string[]; } +export type ModalSubmitComponent = APIModalSubmitStringSelectComponent | APIModalSubmitTextInputComponent; + +export interface ModalSubmitActionRowComponent extends APIBaseComponent { + components: APIModalSubmitTextInputComponent[]; +} + +export interface ModalSubmitLabelComponent extends APIBaseComponent { + component: ModalSubmitComponent; +} + +export type APIModalSubmissionComponent = ModalSubmitActionRowComponent | ModalSubmitLabelComponent; + /** * @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-modal-submit-data-structure} */ @@ -28,7 +43,7 @@ export interface APIModalSubmission { /** * A list of child components */ - components: ModalSubmitActionRowComponent[]; + components: APIModalSubmissionComponent[]; } /** diff --git a/payloads/v10/_interactions/responses.ts b/payloads/v10/_interactions/responses.ts index d5775bde..2b40daba 100644 --- a/payloads/v10/_interactions/responses.ts +++ b/payloads/v10/_interactions/responses.ts @@ -1,5 +1,5 @@ import type { RESTPostAPIWebhookWithTokenJSONBody } from '../../../v10'; -import type { APIActionRowComponent, APIComponentInModalActionRow } from '../channel'; +import type { APIActionRowComponent, APIComponentInModalActionRow, APILabelComponent } from '../channel'; import type { APIApplicationCommandOptionChoice } from './applicationCommands'; /** @@ -126,6 +126,10 @@ export interface APICommandAutocompleteInteractionResponseCallbackData { choices?: APIApplicationCommandOptionChoice[]; } +export type APIModalInteractionResponseCallbackComponent = + | APIActionRowComponent + | APILabelComponent; + /** * @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-modal} */ @@ -140,6 +144,8 @@ export interface APIModalInteractionResponseCallbackData { title: string; /** * Between 1 and 5 (inclusive) components that make up the modal + * + * @remarks Using action rows inside modals is deprecated. */ - components: APIActionRowComponent[]; + components: APIModalInteractionResponseCallbackComponent[]; } diff --git a/payloads/v10/channel.ts b/payloads/v10/channel.ts index cafe25e3..9705cdbf 100644 --- a/payloads/v10/channel.ts +++ b/payloads/v10/channel.ts @@ -1705,7 +1705,10 @@ export enum ComponentType { * Container that visually groups a set of components */ Container, - + /** + * Container associating a label and description with a component + */ + Label, // EVERYTHING BELOW THIS LINE SHOULD BE OLD NAMES FOR RENAMED ENUM MEMBERS // /** @@ -1717,7 +1720,7 @@ export enum ComponentType { } /** - * An Action Row is a top-level layout component used in messages and modals. + * An Action Row is a top-level layout component used in messages. Use in modals is deprecated. * * @see {@link https://discord.com/developers/docs/components/reference#action-row} */ @@ -1919,7 +1922,7 @@ export interface APIBaseAutoPopulatedSelectMenuComponent< * * String Selects can be configured for both single-select and multi-select behavior. When a user finishes making their choice(s) your app receives an interaction. * - * String Selects must be placed inside an Action Row and are only available in messages. An Action Row can contain only one select menu and cannot contain buttons if it has a select menu. + * An Action Row can contain only one select menu and cannot contain buttons if it has a select menu. * * @see {@link https://discord.com/developers/docs/components/reference#string-select} */ @@ -1928,6 +1931,10 @@ export interface APIStringSelectComponent extends APIBaseSelectMenuComponent { + /** + * The label text; max 45 characters + */ + label: string; + /** + * An optional description text for the label; max 100 characters + */ + description?: string; + /** + * The component within the label + */ + component: APIComponentInLabel; +} + /** * @see {@link https://discord.com/developers/docs/resources/channel#message-snapshot-object} */ @@ -2403,7 +2432,11 @@ export type APIMessageTopLevelComponent = /** * @see {@link https://discord.com/developers/docs/components/reference} */ -export type APIModalComponent = APIActionRowComponent | APIComponentInModalActionRow; +export type APIModalComponent = + | APIActionRowComponent + | APIComponentInLabel + | APIComponentInModalActionRow + | APILabelComponent; /** * @see {@link https://discord.com/developers/docs/components/reference#action-row} @@ -2417,9 +2450,15 @@ export type APIComponentInMessageActionRow = APIButtonComponent | APISelectMenuC /** * @see {@link https://discord.com/developers/docs/components/reference#action-row} + * @deprecated */ export type APIComponentInModalActionRow = APITextInputComponent; +/** + * @see {@link https://discord.com/developers/docs/components/reference#label-label-child-components} + */ +export type APIComponentInLabel = APIStringSelectComponent | APITextInputComponent; + /** * @see {@link https://discord.com/developers/docs/components/reference#section} */ diff --git a/payloads/v9/_interactions/modalSubmit.ts b/payloads/v9/_interactions/modalSubmit.ts index fbb9d3c3..97c8c4d7 100644 --- a/payloads/v9/_interactions/modalSubmit.ts +++ b/payloads/v9/_interactions/modalSubmit.ts @@ -7,16 +7,31 @@ import type { InteractionType, } from '../index'; -export interface ModalSubmitComponent { - type: ComponentType; +export interface APIBaseModalSubmitComponent extends APIBaseComponent { + type: T; custom_id: string; +} + +export interface APIModalSubmitTextInputComponent extends APIBaseModalSubmitComponent { value: string; } -export interface ModalSubmitActionRowComponent extends APIBaseComponent { - components: ModalSubmitComponent[]; +export interface APIModalSubmitStringSelectComponent extends APIBaseModalSubmitComponent { + values: string[]; } +export type ModalSubmitComponent = APIModalSubmitStringSelectComponent | APIModalSubmitTextInputComponent; + +export interface ModalSubmitActionRowComponent extends APIBaseComponent { + components: APIModalSubmitTextInputComponent[]; +} + +export interface ModalSubmitLabelComponent extends APIBaseComponent { + component: ModalSubmitComponent; +} + +export type APIModalSubmissionComponent = ModalSubmitActionRowComponent | ModalSubmitLabelComponent; + /** * @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-modal-submit-data-structure} */ @@ -28,7 +43,7 @@ export interface APIModalSubmission { /** * A list of child components */ - components: ModalSubmitActionRowComponent[]; + components: APIModalSubmissionComponent[]; } /** diff --git a/payloads/v9/_interactions/responses.ts b/payloads/v9/_interactions/responses.ts index 2a4c9463..7f59f32e 100644 --- a/payloads/v9/_interactions/responses.ts +++ b/payloads/v9/_interactions/responses.ts @@ -1,5 +1,5 @@ import type { RESTPostAPIWebhookWithTokenJSONBody } from '../../../v9'; -import type { APIActionRowComponent, APIComponentInModalActionRow } from '../channel'; +import type { APIActionRowComponent, APIComponentInModalActionRow, APILabelComponent } from '../channel'; import type { APIApplicationCommandOptionChoice } from './applicationCommands'; /** @@ -126,6 +126,10 @@ export interface APICommandAutocompleteInteractionResponseCallbackData { choices?: APIApplicationCommandOptionChoice[]; } +export type APIModalInteractionResponseCallbackComponent = + | APIActionRowComponent + | APILabelComponent; + /** * @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-modal} */ @@ -140,6 +144,8 @@ export interface APIModalInteractionResponseCallbackData { title: string; /** * Between 1 and 5 (inclusive) components that make up the modal + * + * @remarks Using action rows inside modals is deprecated. */ - components: APIActionRowComponent[]; + components: APIModalInteractionResponseCallbackComponent[]; } diff --git a/payloads/v9/channel.ts b/payloads/v9/channel.ts index a1af2444..50dd9336 100644 --- a/payloads/v9/channel.ts +++ b/payloads/v9/channel.ts @@ -1704,7 +1704,10 @@ export enum ComponentType { * Container that visually groups a set of components */ Container, - + /** + * Container associating a label and description with a component + */ + Label, // EVERYTHING BELOW THIS LINE SHOULD BE OLD NAMES FOR RENAMED ENUM MEMBERS // /** @@ -1716,6 +1719,8 @@ export enum ComponentType { } /** + * An Action Row is a top-level layout component used in messages. Use in modals is deprecated. + * * @see {@link https://discord.com/developers/docs/components/reference#action-row} */ export interface APIActionRowComponent @@ -1916,7 +1921,7 @@ export interface APIBaseAutoPopulatedSelectMenuComponent< * * String Selects can be configured for both single-select and multi-select behavior. When a user finishes making their choice(s) your app receives an interaction. * - * String Selects must be placed inside an Action Row and are only available in messages. An Action Row can contain only one select menu and cannot contain buttons if it has a select menu. + * An Action Row can contain only one select menu and cannot contain buttons if it has a select menu. * * @see {@link https://discord.com/developers/docs/components/reference#string-select} */ @@ -1925,6 +1930,10 @@ export interface APIStringSelectComponent extends APIBaseSelectMenuComponent { + /** + * The label text; max 45 characters + */ + label: string; + /** + * An optional description text for the label; max 100 characters + */ + description?: string; + /** + * The component within the label + */ + component: APIComponentInLabel; +} + /** * @see {@link https://discord.com/developers/docs/resources/channel#message-snapshot-object} */ @@ -2400,7 +2431,11 @@ export type APIMessageTopLevelComponent = /** * @see {@link https://discord.com/developers/docs/components/reference} */ -export type APIModalComponent = APIActionRowComponent | APIComponentInModalActionRow; +export type APIModalComponent = + | APIActionRowComponent + | APIComponentInLabel + | APIComponentInModalActionRow + | APILabelComponent; /** * @see {@link https://discord.com/developers/docs/components/reference#action-row} @@ -2414,9 +2449,15 @@ export type APIComponentInMessageActionRow = APIButtonComponent | APISelectMenuC /** * @see {@link https://discord.com/developers/docs/components/reference#action-row} + * @deprecated */ export type APIComponentInModalActionRow = APITextInputComponent; +/** + * @see {@link https://discord.com/developers/docs/components/reference#label-label-child-components} + */ +export type APIComponentInLabel = APIStringSelectComponent | APITextInputComponent; + /** * @see {@link https://discord.com/developers/docs/components/reference#section} */