mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-17 20:13:30 +01:00
feat: Add Modals and Text Inputs (#7023)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com> Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com> Co-authored-by: Ryan Munro <monbrey@gmail.com> Co-authored-by: Vitor <milagre.vitor@gmail.com>
This commit is contained in:
16
packages/builders/src/interactions/modals/Assertions.ts
Normal file
16
packages/builders/src/interactions/modals/Assertions.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { z } from 'zod';
|
||||
import { ActionRow, type ModalActionRowComponent } from '../..';
|
||||
import { customIdValidator } from '../../components/Assertions';
|
||||
|
||||
export const titleValidator = z.string().min(1).max(45);
|
||||
export const componentsValidator = z.array(z.instanceof(ActionRow)).min(1);
|
||||
|
||||
export function validateRequiredParameters(
|
||||
customId?: string,
|
||||
title?: string,
|
||||
components?: ActionRow<ModalActionRowComponent>[],
|
||||
) {
|
||||
customIdValidator.parse(customId);
|
||||
titleValidator.parse(title);
|
||||
componentsValidator.parse(components);
|
||||
}
|
||||
19
packages/builders/src/interactions/modals/Modal.ts
Normal file
19
packages/builders/src/interactions/modals/Modal.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { APIModalInteractionResponseCallbackData } from 'discord-api-types/v9';
|
||||
import { customIdValidator } from '../../components/Assertions';
|
||||
import { titleValidator, validateRequiredParameters } from './Assertions';
|
||||
import { UnsafeModal } from './UnsafeModal';
|
||||
|
||||
export class Modal extends UnsafeModal {
|
||||
public override setCustomId(customId: string): this {
|
||||
return super.setCustomId(customIdValidator.parse(customId));
|
||||
}
|
||||
|
||||
public override setTitle(title: string) {
|
||||
return super.setTitle(titleValidator.parse(title));
|
||||
}
|
||||
|
||||
public override toJSON(): APIModalInteractionResponseCallbackData {
|
||||
validateRequiredParameters(this.data.custom_id, this.data.title, this.components);
|
||||
return super.toJSON();
|
||||
}
|
||||
}
|
||||
80
packages/builders/src/interactions/modals/UnsafeModal.ts
Normal file
80
packages/builders/src/interactions/modals/UnsafeModal.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import type {
|
||||
APIActionRowComponent,
|
||||
APIModalActionRowComponent,
|
||||
APIModalInteractionResponseCallbackData,
|
||||
} from 'discord-api-types/v9';
|
||||
import { ActionRow, createComponent, JSONEncodable, ModalActionRowComponent } from '../../index';
|
||||
|
||||
export class UnsafeModal implements JSONEncodable<APIModalInteractionResponseCallbackData> {
|
||||
protected readonly data: Partial<Omit<APIModalInteractionResponseCallbackData, 'components'>>;
|
||||
public readonly components: ActionRow<ModalActionRowComponent>[] = [];
|
||||
|
||||
public constructor({ components, ...data }: Partial<APIModalInteractionResponseCallbackData> = {}) {
|
||||
this.data = { ...data };
|
||||
this.components = (components?.map((c) => createComponent(c)) ?? []) as ActionRow<ModalActionRowComponent>[];
|
||||
}
|
||||
|
||||
/**
|
||||
* The custom id of this modal
|
||||
*/
|
||||
public get customId() {
|
||||
return this.data.custom_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The title of this modal
|
||||
*/
|
||||
public get title() {
|
||||
return this.data.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the title of the modal
|
||||
* @param title The title of the modal
|
||||
*/
|
||||
public setTitle(title: string) {
|
||||
this.data.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the custom id of the modal
|
||||
* @param customId The custom id of this modal
|
||||
*/
|
||||
public setCustomId(customId: string) {
|
||||
this.data.custom_id = customId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds components to this modal
|
||||
* @param components The components to add to this modal
|
||||
*/
|
||||
public addComponents(
|
||||
...components: (ActionRow<ModalActionRowComponent> | APIActionRowComponent<APIModalActionRowComponent>)[]
|
||||
) {
|
||||
this.components.push(
|
||||
...components.map((component) =>
|
||||
component instanceof ActionRow ? component : new ActionRow<ModalActionRowComponent>(component),
|
||||
),
|
||||
);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the components in this modal
|
||||
* @param components The components to set this modal to
|
||||
*/
|
||||
public setComponents(...components: ActionRow<ModalActionRowComponent>[]) {
|
||||
this.components.splice(0, this.components.length, ...components);
|
||||
return this;
|
||||
}
|
||||
|
||||
public toJSON(): APIModalInteractionResponseCallbackData {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
return {
|
||||
...this.data,
|
||||
components: this.components.map((component) => component.toJSON()),
|
||||
} as APIModalInteractionResponseCallbackData;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user