Skip to content

Commit b42e499

Browse files
imnaiyaralmeidx
andauthored
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>
1 parent 374a678 commit b42e499

File tree

4 files changed

+154
-3
lines changed

4 files changed

+154
-3
lines changed

packages/discord.js/src/structures/ModalSubmitFields.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,37 @@ class ModalSubmitFields {
227227
getUploadedFiles(customId, required = false) {
228228
return this._getTypedComponent(customId, [ComponentType.FileUpload], ['attachments'], required).attachments ?? null;
229229
}
230+
231+
/**
232+
* Get radio group component
233+
*
234+
* @param {string} customId The custom id of the component
235+
* @param {boolean} [required=false] Whether to throw an error if the component value is not found or empty
236+
* @returns {?string} The selected radio group option value, or null if none were selected and not required
237+
*/
238+
getRadioGroup(customId, required = false) {
239+
return this._getTypedComponent(customId, [ComponentType.RadioGroup], ['value'], required).value;
240+
}
241+
242+
/**
243+
* Get checkbox group component
244+
*
245+
* @param {string} customId The custom id of the component
246+
* @returns {string[]} The selected checkbox group option values
247+
*/
248+
getCheckboxGroup(customId) {
249+
return this._getTypedComponent(customId, [ComponentType.CheckboxGroup]).values;
250+
}
251+
252+
/**
253+
* Get checkbox component
254+
*
255+
* @param {string} customId The custom id of the component
256+
* @returns {boolean} Whether this checkbox was selected
257+
*/
258+
getCheckbox(customId) {
259+
return this._getTypedComponent(customId, [ComponentType.Checkbox]).value;
260+
}
230261
}
231262

232263
module.exports = ModalSubmitFields;

packages/discord.js/src/structures/ModalSubmitInteraction.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,24 @@ const getAttachment = lazy(() => require('./Attachment'));
2424
* @property {Collection<Snowflake, Attachment>} [attachments] The resolved attachments
2525
*/
2626

27+
/**
28+
* @typedef {BaseModalData} RadioGroupModalData
29+
* @property {string} customId The custom id of the radio group
30+
* @property {?string} value The value selected for the radio group
31+
*/
32+
33+
/**
34+
* @typedef {BaseModalData} CheckboxGroupModalData
35+
* @property {string} customId The custom id of the checkbox group
36+
* @property {string[]} values The values selected for the checkbox group
37+
*/
38+
39+
/**
40+
* @typedef {BaseModalData} CheckboxModalData
41+
* @property {string} customId The custom id of the checkbox
42+
* @property {boolean} value Whether this checkbox was selected
43+
*/
44+
2745
/**
2846
* @typedef {BaseModalData} TextInputModalData
2947
* @property {string} customId The custom id of the field
@@ -45,7 +63,8 @@ const getAttachment = lazy(() => require('./Attachment'));
4563
*/
4664

4765
/**
48-
* @typedef {SelectMenuModalData|TextInputModalData|FileUploadModalData} ModalData
66+
* @typedef {SelectMenuModalData|TextInputModalData|FileUploadModalData|RadioGroupModalData|
67+
* CheckboxGroupModalData|CheckboxModalData} ModalData
4968
*/
5069

5170
/**

packages/discord.js/src/util/Components.js

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ const { ComponentType } = require('discord-api-types/v10');
2424
/**
2525
* @typedef {StringSelectMenuComponentData|TextInputComponentData|UserSelectMenuComponentData|
2626
* RoleSelectMenuComponentData|MentionableSelectMenuComponentData|ChannelSelectMenuComponentData|
27-
* FileUploadComponentData} ComponentInLabelData
27+
* FileUploadComponentData|RadioGroupComponentData|CheckboxGroupComponentData|
28+
* CheckboxComponentData} ComponentInLabelData
2829
*/
2930

3031
/**
@@ -52,6 +53,44 @@ const { ComponentType } = require('discord-api-types/v10');
5253
* @property {boolean} [required] Whether this component is required in modals
5354
*/
5455

56+
/**
57+
* @typedef {Object} RadioGroupOption
58+
* @property {string} value The value of the radio group option
59+
* @property {string} label The label to use
60+
* @property {string} [description] The optional description for the radio group option
61+
* @property {boolean} [default] Whether this option is default selected
62+
*/
63+
64+
/**
65+
* @typedef {BaseComponentData} RadioGroupComponentData
66+
* @property {string} customId The custom id of the radio group
67+
* @property {RadioGroupOption[]} options The options in this radio group (2-10)
68+
* @property {boolean} [required] Whether this component is required in modals
69+
*/
70+
71+
/**
72+
* @typedef {Object} CheckboxGroupOption
73+
* @property {string} value The value of the checkbox group option
74+
* @property {string} label The label to use
75+
* @property {string} [description] The optional description for the checkbox group option
76+
* @property {boolean} [default] Whether this option is default selected
77+
*/
78+
79+
/**
80+
* @typedef {BaseComponentData} CheckboxGroupComponentData
81+
* @property {string} customId The custom id of the checkbox group
82+
* @property {CheckboxGroupOption[]} options The options in this checkbox group
83+
* @property {number} [minValues] The minimum number of options that must be selected (0-10)
84+
* @property {number} [maxValues] The maximum number of options that can be selected (defaults to options length)
85+
* @property {boolean} [required] Whether this component is required in modals
86+
*/
87+
88+
/**
89+
* @typedef {BaseComponentData} CheckboxComponentData
90+
* @property {string} customId The custom id of the checkbox
91+
* @property {boolean} [default] Whether this component is default selected in modals
92+
*/
93+
5594
/**
5695
* @typedef {BaseComponentData} BaseSelectMenuComponentData
5796
* @property {string} customId The custom id of the select menu

packages/discord.js/typings/index.d.ts

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,9 @@ export class ActionRowBuilder<
363363
}
364364

365365
export type ComponentInLabelData =
366+
| CheckboxComponentData
367+
| CheckboxGroupComponentData
368+
| RadioGroupComponentData
366369
| StringSelectMenuComponentData
367370
| TextInputComponentData
368371
| UserSelectMenuComponentData
@@ -2828,7 +2831,28 @@ export interface FileUploadModalData extends BaseModalData<ComponentType.FileUpl
28282831
attachments: ReadonlyCollection<Snowflake, Attachment>;
28292832
}
28302833

2831-
export type ModalData = FileUploadModalData | SelectMenuModalData | TextInputModalData;
2834+
export interface RadioGroupModalData extends BaseModalData<ComponentType.RadioGroup> {
2835+
customId: string;
2836+
value: string | null;
2837+
}
2838+
2839+
export interface CheckboxGroupModalData extends BaseModalData<ComponentType.CheckboxGroup> {
2840+
customId: string;
2841+
values: readonly string[];
2842+
}
2843+
2844+
export interface CheckboxModalData extends BaseModalData<ComponentType.Checkbox> {
2845+
customId: string;
2846+
value: boolean;
2847+
}
2848+
2849+
export type ModalData =
2850+
| CheckboxGroupModalData
2851+
| CheckboxModalData
2852+
| FileUploadModalData
2853+
| RadioGroupModalData
2854+
| SelectMenuModalData
2855+
| TextInputModalData;
28322856

28332857
export interface LabelModalData extends BaseModalData<ComponentType.Label> {
28342858
component: ModalData;
@@ -2907,6 +2931,10 @@ export class ModalSubmitFields<Cached extends CacheType = CacheType> {
29072931
public getSelectedMentionables(customId: string, required?: boolean): ModalSelectedMentionables<Cached> | null;
29082932
public getUploadedFiles(customId: string, required: true): ReadonlyCollection<Snowflake, Attachment>;
29092933
public getUploadedFiles(customId: string, required?: boolean): ReadonlyCollection<Snowflake, Attachment> | null;
2934+
public getRadioGroup(customId: string, required: true): string;
2935+
public getRadioGroup(customId: string, required?: boolean): string | null;
2936+
public getCheckboxGroup(customId: string): readonly string[];
2937+
public getCheckbox(customId: string): boolean;
29102938
}
29112939

29122940
export interface ModalMessageModalSubmitInteraction<
@@ -7469,6 +7497,40 @@ export interface FileUploadComponentData extends BaseComponentData {
74697497
type: ComponentType.FileUpload;
74707498
}
74717499

7500+
export interface RadioGroupOption {
7501+
default?: boolean;
7502+
description?: string;
7503+
label: string;
7504+
value: string;
7505+
}
7506+
export interface RadioGroupComponentData extends BaseComponentData {
7507+
customId: string;
7508+
options: readonly RadioGroupOption[];
7509+
required?: boolean;
7510+
type: ComponentType.RadioGroup;
7511+
}
7512+
7513+
export interface CheckboxGroupOption {
7514+
default?: boolean;
7515+
description?: string;
7516+
label: string;
7517+
value: string;
7518+
}
7519+
export interface CheckboxGroupComponentData extends BaseComponentData {
7520+
customId: string;
7521+
maxValues?: number;
7522+
minValues?: number;
7523+
options: readonly CheckboxGroupOption[];
7524+
required?: boolean;
7525+
type: ComponentType.CheckboxGroup;
7526+
}
7527+
7528+
export interface CheckboxComponentData extends BaseComponentData {
7529+
customId: string;
7530+
default?: boolean;
7531+
type: ComponentType.Checkbox;
7532+
}
7533+
74727534
export type MessageTarget =
74737535
| Interaction
74747536
| InteractionWebhook

0 commit comments

Comments
 (0)