Resumen de tipos de campo
Los modales de Spraxium admiten 11 tipos de campo, cada uno declarado mediante un decorator a nivel de propiedad en tu clase @ModalComponent. Las entradas de texto y los selects son los más comunes, pero el sistema también incluye grupos de radio, casillas de verificación, cargas de archivos y displays de texto de solo lectura. Cada decorator de campo acepta un objeto de configuración con propiedades específicas del tipo de campo, además de propiedades compartidas como label y required.
El orden de los campos en el modal renderizado coincide con el orden de declaración de las propiedades decoradas en la clase. Los modales de Discord tienen un máximo de 5 filas de acción, y cada campo ocupa una fila. Este límite significa que un modal solo puede contener hasta 5 campos, aunque los campos dinámicos y condicionales pueden cambiar lo que aparece para cada persona usuaria.
| Decorator | Tipo de campo | Acepta opciones | Notas |
|---|---|---|---|
| @ModalInput | Entrada de texto | No | Estilo corto o párrafo. Soporta minLength, maxLength, placeholder. |
| @ModalSelect | String select | Sí | Desplegable con opciones estáticas o dinámicas. Soporta minValues, maxValues. |
| @ModalUserSelect | User select | No | Selector de miembros del servidor. Admite valores predeterminados. |
| @ModalRoleSelect | Role select | No | Selector de roles del servidor. Admite valores predeterminados. |
| @ModalMentionableSelect | Mentionable select | No | Permite elegir usuarios o roles. Combina ambos tipos de entidad en un solo desplegable. |
| @ModalChannelSelect | Channel select | No | Selector de canales. Filtra por el arreglo channelTypes. |
| @ModalRadioGroup | Grupo de radio | Sí | Botones de selección única. Debe seleccionarse exactamente una opción. |
| @ModalCheckboxGroup | Grupo de checkboxes | Sí | Checkboxes de selección múltiple. Soporta minValues, maxValues. |
| @ModalCheckbox | Checkbox único | No | Toggle booleano. Devuelve |
| @ModalFileUpload | Carga de archivo | No | Campo de adjunto. Accede al archivo subido a través de la interacción. |
| @ModalTextDisplay | Texto de solo lectura | No | Texto estático mostrado en el modal. No se envía como valor. |
Entradas de texto
El decorator @ModalInput crea un campo de entrada de texto. La propiedad style controla si el campo se renderiza como entrada de una línea (short) o de varias líneas (paragraph). Los campos cortos son ideales para nombres, asuntos y valores breves. Los campos tipo párrafo encajan mejor para descripciones, mensajes y contenido más largo.
import { ModalComponent, ModalInput } from '@spraxium/components';
@ModalComponent({ id: 'report-modal', title: 'Submit Report' })
export class ReportModal {
@ModalInput({
label: 'Title',
placeholder: 'A short title for the report',
required: true,
minLength: 5,
maxLength: 100,
style: 'short',
})
title!: string;
@ModalInput({
label: 'Description',
placeholder: 'Describe the issue in detail...',
required: true,
minLength: 20,
maxLength: 4000,
style: 'paragraph',
})
description!: string;
@ModalInput({
label: 'Reproduction Steps',
placeholder: 'Optional steps to reproduce',
required: false,
style: 'paragraph',
value: "1. \n2. \n3. ",
})
steps!: string;
}String selects con opciones
El decorator @ModalSelect crea un menú select desplegable dentro del modal. Define las opciones disponibles usando el decorator apilable @ModalChoice en la misma propiedad. Cada opción tiene label (mostrado a la persona usuaria), value (enviado al confirmar) y description opcional.
import { ModalComponent, ModalSelect, ModalChoice } from '@spraxium/components';
@ModalComponent({ id: 'ticket-modal', title: 'Create Ticket' })
export class TicketModal {
@ModalSelect({
label: 'Category',
placeholder: 'Select a ticket category',
required: true,
})
@ModalChoice({
label: 'Bug Report',
value: 'bug',
description: 'Something is broken',
})
@ModalChoice({
label: 'Feature Request',
value: 'feature',
description: 'Suggest an improvement',
})
@ModalChoice({
label: 'General Question',
value: 'question',
description: 'Ask a question',
})
category!: string;
@ModalInput({
label: 'Details',
style: 'paragraph',
required: true,
})
details!: string;
}Selects de entidades
Los decorators de selección de entidades permiten elegir miembros del servidor, roles, canales o entidades mentionable directamente en el modal. Estos campos usan los selectores nativos de Discord, por lo que muestran avatares, colores de roles e íconos de canal. No necesitas decorators @ModalChoice porque las opciones se cargan desde el servidor.
import { ModalComponent, ModalUserSelect } from '@spraxium/components';
@ModalComponent({ id: 'assign-modal', title: 'Assign User' })
export class AssignModal {
@ModalUserSelect({
label: 'Assignee',
placeholder: 'Pick a team member',
required: true,
})
assignee!: string;
}Grupos de radio y checkboxes
Los grupos de radio presentan opciones mutuamente excluyentes donde debe elegirse exactamente una. Los grupos de checkboxes permiten selecciones múltiples. Un solo @ModalCheckbox se renderiza como toggle booleano. Todos los campos basados en opciones usan @ModalOption (alias de @ModalChoice) para definir sus opciones.
import { ModalComponent, ModalRadioGroup, ModalOption } from '@spraxium/components';
@ModalComponent({ id: 'priority-modal', title: 'Set Priority' })
export class PriorityModal {
@ModalRadioGroup({ label: 'Priority Level' })
@ModalOption({ label: 'Low', value: 'low' })
@ModalOption({ label: 'Medium', value: 'medium' })
@ModalOption({ label: 'High', value: 'high' })
@ModalOption({ label: 'Critical', value: 'critical' })
priority!: string;
}Carga de archivos y displays de texto
El decorator @ModalFileUpload agrega un campo de adjunto al modal. El decorator @ModalTextDisplay agrega texto estático de solo lectura que no se envía como valor de campo. Los displays de texto son útiles para mostrar instrucciones, advertencias o información de contexto dentro del formulario modal.
import {
ModalComponent,
ModalTextDisplay,
ModalFileUpload,
ModalInput,
} from '@spraxium/components';
@ModalTextDisplay({
content:
'Please upload a screenshot or log file as evidence. Accepted formats: PNG, JPG, TXT.',
})
@ModalComponent({ id: 'evidence-modal', title: 'Upload Evidence' })
export class UploadEvidenceModal {
@ModalFileUpload({
label: 'Evidence File',
required: true,
})
file!: string;
@ModalInput({
label: 'Additional Notes',
style: 'paragraph',
required: false,
placeholder: 'Any extra context about the evidence...',
})
notes!: string;
}Helpers del namespace Modal
El namespace Modal ofrece funciones factory para crear definiciones de campo de forma programática en lugar de usar decorators. Esto se usa principalmente con campos dinámicos (cubiertos en la página de dinámicas), pero también puede ser útil al construir esquemas de modal en funciones utilitarias o librerías compartidas.
| Helper | Devuelve | Decorator equivalente |
|---|---|---|
| Modal.field.text(config) | Definición de campo de texto | @ModalInput |
| Modal.field.stringSelect(config) | Definición de campo string select | @ModalSelect |
| Modal.field.userSelect(config) | Definición de campo user select | @ModalUserSelect |
| Modal.field.roleSelect(config) | Definición de campo role select | @ModalRoleSelect |
| Modal.field.mentionableSelect(config) | Definición de campo mentionable select | @ModalMentionableSelect |
| Modal.field.channelSelect(config) | Definición de campo channel select | @ModalChannelSelect |
| Modal.field.radioGroup(config) | Definición de campo radio group | @ModalRadioGroup |
| Modal.field.checkboxGroup(config) | Definición de campo checkbox group | @ModalCheckboxGroup |
| Modal.field.checkbox(config) | Definición de checkbox único | @ModalCheckbox |
| Modal.field.fileUpload(config) | Definición de campo de carga de archivo | @ModalFileUpload |
| Modal.field.textDisplay(config) | Definición de campo de display de texto | @ModalTextDisplay |
| Modal.choice(config) | Definición de opción | @ModalChoice / @ModalOption |
| Modal.when(predicate) | Wrapper condicional | @ModalWhen |
import { Modal } from '@spraxium/components';
export function createReasonField(required = true) {
return Modal.field.text({
id: 'reason',
label: 'Reason',
placeholder: 'Provide a reason...',
style: 'paragraph',
required,
minLength: 10,
});
}
export function createPriorityChoices() {
return [
Modal.choice({ label: 'Low', value: 'low' }),
Modal.choice({ label: 'Medium', value: 'medium' }),
Modal.choice({ label: 'High', value: 'high' }),
];
}