feat: modal radio group and checkbox components for v14 (#11437)

feat: modal radio group and checkbox components

* feat: radio group and checkbox component in modal

* chore: some doc and type fixes

* chore: missing types

* chore: update component names

* docs: radio group value now returns null if not selected

* Remove empty line at the beginning of ModalSubmitInteraction.js

* Change value property to be nullable in RadioGroupModalData

* chore: review

* chore: missing "type"

* chore: suggestion



* chore: review



---------

Co-authored-by: Almeida <github@almeidx.dev>
This commit is contained in:
Naiyar
2026-03-11 14:11:29 +06:00
committed by GitHub
parent 374a6785ae
commit b42e499410
4 changed files with 154 additions and 3 deletions

View File

@@ -227,6 +227,37 @@ class ModalSubmitFields {
getUploadedFiles(customId, required = false) {
return this._getTypedComponent(customId, [ComponentType.FileUpload], ['attachments'], required).attachments ?? null;
}
/**
* Get radio group component
*
* @param {string} customId The custom id of the component
* @param {boolean} [required=false] Whether to throw an error if the component value is not found or empty
* @returns {?string} The selected radio group option value, or null if none were selected and not required
*/
getRadioGroup(customId, required = false) {
return this._getTypedComponent(customId, [ComponentType.RadioGroup], ['value'], required).value;
}
/**
* Get checkbox group component
*
* @param {string} customId The custom id of the component
* @returns {string[]} The selected checkbox group option values
*/
getCheckboxGroup(customId) {
return this._getTypedComponent(customId, [ComponentType.CheckboxGroup]).values;
}
/**
* Get checkbox component
*
* @param {string} customId The custom id of the component
* @returns {boolean} Whether this checkbox was selected
*/
getCheckbox(customId) {
return this._getTypedComponent(customId, [ComponentType.Checkbox]).value;
}
}
module.exports = ModalSubmitFields;

View File

@@ -24,6 +24,24 @@ const getAttachment = lazy(() => require('./Attachment'));
* @property {Collection<Snowflake, Attachment>} [attachments] The resolved attachments
*/
/**
* @typedef {BaseModalData} RadioGroupModalData
* @property {string} customId The custom id of the radio group
* @property {?string} value The value selected for the radio group
*/
/**
* @typedef {BaseModalData} CheckboxGroupModalData
* @property {string} customId The custom id of the checkbox group
* @property {string[]} values The values selected for the checkbox group
*/
/**
* @typedef {BaseModalData} CheckboxModalData
* @property {string} customId The custom id of the checkbox
* @property {boolean} value Whether this checkbox was selected
*/
/**
* @typedef {BaseModalData} TextInputModalData
* @property {string} customId The custom id of the field
@@ -45,7 +63,8 @@ const getAttachment = lazy(() => require('./Attachment'));
*/
/**
* @typedef {SelectMenuModalData|TextInputModalData|FileUploadModalData} ModalData
* @typedef {SelectMenuModalData|TextInputModalData|FileUploadModalData|RadioGroupModalData|
* CheckboxGroupModalData|CheckboxModalData} ModalData
*/
/**

View File

@@ -24,7 +24,8 @@ const { ComponentType } = require('discord-api-types/v10');
/**
* @typedef {StringSelectMenuComponentData|TextInputComponentData|UserSelectMenuComponentData|
* RoleSelectMenuComponentData|MentionableSelectMenuComponentData|ChannelSelectMenuComponentData|
* FileUploadComponentData} ComponentInLabelData
* FileUploadComponentData|RadioGroupComponentData|CheckboxGroupComponentData|
* CheckboxComponentData} ComponentInLabelData
*/
/**
@@ -52,6 +53,44 @@ const { ComponentType } = require('discord-api-types/v10');
* @property {boolean} [required] Whether this component is required in modals
*/
/**
* @typedef {Object} RadioGroupOption
* @property {string} value The value of the radio group option
* @property {string} label The label to use
* @property {string} [description] The optional description for the radio group option
* @property {boolean} [default] Whether this option is default selected
*/
/**
* @typedef {BaseComponentData} RadioGroupComponentData
* @property {string} customId The custom id of the radio group
* @property {RadioGroupOption[]} options The options in this radio group (2-10)
* @property {boolean} [required] Whether this component is required in modals
*/
/**
* @typedef {Object} CheckboxGroupOption
* @property {string} value The value of the checkbox group option
* @property {string} label The label to use
* @property {string} [description] The optional description for the checkbox group option
* @property {boolean} [default] Whether this option is default selected
*/
/**
* @typedef {BaseComponentData} CheckboxGroupComponentData
* @property {string} customId The custom id of the checkbox group
* @property {CheckboxGroupOption[]} options The options in this checkbox group
* @property {number} [minValues] The minimum number of options that must be selected (0-10)
* @property {number} [maxValues] The maximum number of options that can be selected (defaults to options length)
* @property {boolean} [required] Whether this component is required in modals
*/
/**
* @typedef {BaseComponentData} CheckboxComponentData
* @property {string} customId The custom id of the checkbox
* @property {boolean} [default] Whether this component is default selected in modals
*/
/**
* @typedef {BaseComponentData} BaseSelectMenuComponentData
* @property {string} customId The custom id of the select menu

View File

@@ -363,6 +363,9 @@ export class ActionRowBuilder<
}
export type ComponentInLabelData =
| CheckboxComponentData
| CheckboxGroupComponentData
| RadioGroupComponentData
| StringSelectMenuComponentData
| TextInputComponentData
| UserSelectMenuComponentData
@@ -2828,7 +2831,28 @@ export interface FileUploadModalData extends BaseModalData<ComponentType.FileUpl
attachments: ReadonlyCollection<Snowflake, Attachment>;
}
export type ModalData = FileUploadModalData | SelectMenuModalData | TextInputModalData;
export interface RadioGroupModalData extends BaseModalData<ComponentType.RadioGroup> {
customId: string;
value: string | null;
}
export interface CheckboxGroupModalData extends BaseModalData<ComponentType.CheckboxGroup> {
customId: string;
values: readonly string[];
}
export interface CheckboxModalData extends BaseModalData<ComponentType.Checkbox> {
customId: string;
value: boolean;
}
export type ModalData =
| CheckboxGroupModalData
| CheckboxModalData
| FileUploadModalData
| RadioGroupModalData
| SelectMenuModalData
| TextInputModalData;
export interface LabelModalData extends BaseModalData<ComponentType.Label> {
component: ModalData;
@@ -2907,6 +2931,10 @@ export class ModalSubmitFields<Cached extends CacheType = CacheType> {
public getSelectedMentionables(customId: string, required?: boolean): ModalSelectedMentionables<Cached> | null;
public getUploadedFiles(customId: string, required: true): ReadonlyCollection<Snowflake, Attachment>;
public getUploadedFiles(customId: string, required?: boolean): ReadonlyCollection<Snowflake, Attachment> | null;
public getRadioGroup(customId: string, required: true): string;
public getRadioGroup(customId: string, required?: boolean): string | null;
public getCheckboxGroup(customId: string): readonly string[];
public getCheckbox(customId: string): boolean;
}
export interface ModalMessageModalSubmitInteraction<
@@ -7469,6 +7497,40 @@ export interface FileUploadComponentData extends BaseComponentData {
type: ComponentType.FileUpload;
}
export interface RadioGroupOption {
default?: boolean;
description?: string;
label: string;
value: string;
}
export interface RadioGroupComponentData extends BaseComponentData {
customId: string;
options: readonly RadioGroupOption[];
required?: boolean;
type: ComponentType.RadioGroup;
}
export interface CheckboxGroupOption {
default?: boolean;
description?: string;
label: string;
value: string;
}
export interface CheckboxGroupComponentData extends BaseComponentData {
customId: string;
maxValues?: number;
minValues?: number;
options: readonly CheckboxGroupOption[];
required?: boolean;
type: ComponentType.CheckboxGroup;
}
export interface CheckboxComponentData extends BaseComponentData {
customId: string;
default?: boolean;
type: ComponentType.Checkbox;
}
export type MessageTarget =
| Interaction
| InteractionWebhook