diff --git a/packages/discord.js/src/structures/ModalComponentResolver.js b/packages/discord.js/src/structures/ModalComponentResolver.js index 5ad4ca731..e1fdfeb0b 100644 --- a/packages/discord.js/src/structures/ModalComponentResolver.js +++ b/packages/discord.js/src/structures/ModalComponentResolver.js @@ -233,6 +233,37 @@ class ModalComponentResolver { 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; + } } exports.ModalComponentResolver = ModalComponentResolver; diff --git a/packages/discord.js/src/structures/ModalSubmitInteraction.js b/packages/discord.js/src/structures/ModalSubmitInteraction.js index 9235a67c0..6562409f7 100644 --- a/packages/discord.js/src/structures/ModalSubmitInteraction.js +++ b/packages/discord.js/src/structures/ModalSubmitInteraction.js @@ -34,6 +34,24 @@ const getAttachment = lazy(() => require('./Attachment.js').Attachment); * @property {Collection} [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 component @@ -45,7 +63,7 @@ const getAttachment = lazy(() => require('./Attachment.js').Attachment); */ /** - * @typedef {SelectMenuModalData|TextInputModalData|FileUploadModalData} ModalData + * @typedef {SelectMenuModalData|TextInputModalData|FileUploadModalData|RadioGroupModalData|CheckboxGroupModalData|CheckboxModalData} ModalData */ /** diff --git a/packages/discord.js/src/util/Components.js b/packages/discord.js/src/util/Components.js index 5a1278659..52c453ed6 100644 --- a/packages/discord.js/src/util/Components.js +++ b/packages/discord.js/src/util/Components.js @@ -52,7 +52,8 @@ const getUserSelectMenuComponent = lazy( /** * @typedef {StringSelectMenuComponentData|TextInputComponentData|UserSelectMenuComponentData| - * RoleSelectMenuComponentData|MentionableSelectMenuComponentData|ChannelSelectMenuComponentData|FileUploadComponentData} ComponentInLabelData + * RoleSelectMenuComponentData|MentionableSelectMenuComponentData|ChannelSelectMenuComponentData|FileUploadComponentData| + * RadioGroupComponentData|CheckboxGroupComponentData|CheckboxComponentData} ComponentInLabelData */ /** @@ -80,6 +81,44 @@ const getUserSelectMenuComponent = lazy( * @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 diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index bc8bba0e8..47cc38b04 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -274,8 +274,11 @@ export interface ActionRowData< export type ComponentInLabelData = | ChannelSelectMenuComponentData + | CheckboxComponentData + | CheckboxGroupComponentData | FileUploadComponentData | MentionableSelectMenuComponentData + | RadioGroupComponentData | RoleSelectMenuComponentData | StringSelectMenuComponentData | TextInputComponentData @@ -2583,7 +2586,28 @@ export interface FileUploadModalData extends BaseModalData { + customId: string; + value: string | null; +} + +export interface CheckboxGroupModalData extends BaseModalData { + customId: string; + values: readonly string[]; +} + +export interface CheckboxModalData extends BaseModalData { + customId: string; + value: boolean; +} + +export type ModalData = + | CheckboxGroupModalData + | CheckboxModalData + | FileUploadModalData + | RadioGroupModalData + | SelectMenuModalData + | TextInputModalData; export interface LabelModalData extends BaseModalData { component: ModalData; @@ -2658,6 +2682,10 @@ export class ModalComponentResolver { public getSelectedMentionables(customId: string, required?: boolean): ModalSelectedMentionables | null; public getUploadedFiles(customId: string, required: true): ReadonlyCollection; public getUploadedFiles(customId: string, required?: boolean): ReadonlyCollection | 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< @@ -6864,6 +6892,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 = | ChannelManager | Interaction