Visão geral dos tipos de campo
Os modais do Spraxium oferecem 11 tipos de campo, cada um declarado por meio de um decorator no nível de propriedade na sua classe @ModalComponent. Inputs de texto e selects são os mais comuns, mas o sistema também inclui grupos de rádio, checkboxes, uploads de arquivo e exibições de texto somente leitura. Cada decorator de campo aceita um objeto de configuração com propriedades específicas do tipo de campo, além de propriedades compartilhadas como label e required.
A ordem dos campos no modal renderizado segue a ordem de declaração das propriedades decoradas na classe. Modais do Discord têm no máximo 5 action rows, e cada campo ocupa uma linha. Esse limite significa que um único modal pode conter no máximo 5 campos, embora campos dinâmicos e condicionais possam alterar o que aparece para cada usuário.
| Decorator | Tipo de campo | Aceita escolhas | Observações |
|---|---|---|---|
| @ModalInput | Input de texto | Não | Estilo curto ou parágrafo. Suporta minLength, maxLength e placeholder. |
| @ModalSelect | Select de string | Sim | Dropdown com opções estáticas ou dinâmicas. Suporta minValues e maxValues. |
| @ModalUserSelect | Select de usuário | Não | Seletor de membros do servidor. Suporta valores padrão. |
| @ModalRoleSelect | Select de cargo | Não | Seletor de cargos do servidor. Suporta valores padrão. |
| @ModalMentionableSelect | Select de mentionable | Não | Permite escolher usuários ou cargos. Combina os dois tipos de entidade no mesmo dropdown. |
| @ModalChannelSelect | Select de canal | Não | Seletor de canais. Filtre pelo array channelTypes. |
| @ModalRadioGroup | Grupo de rádio | Sim | Botões de rádio com seleção única. Exatamente uma opção deve ser escolhida. |
| @ModalCheckboxGroup | Grupo de checkboxes | Sim | Checkboxes com múltipla seleção. Suporta minValues e maxValues. |
| @ModalCheckbox | Checkbox único | Não | Alternância booleana. Retorna true ou false como string. |
| @ModalFileUpload | Upload de arquivo | Não | Campo de anexo. Acesse o arquivo enviado por meio da interação. |
| @ModalTextDisplay | Texto somente leitura | Não | Texto estático exibido no modal. Não é enviado como valor. |
Inputs de texto
O decorator @ModalInput cria um campo de input de texto. A propriedade style controla se o campo será renderizado como um input de linha única (short) ou de múltiplas linhas (paragraph). Campos curtos são ideais para nomes, assuntos e valores breves. Campos do tipo parágrafo funcionam melhor para descrições, mensagens e conteúdos mais longos.
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;
}Selects de string com escolhas
O decorator @ModalSelect cria um menu de seleção dropdown dentro do modal. Defina as opções disponíveis usando o decorator empilhável @ModalChoice na mesma propriedade. Cada escolha tem um label (exibido para o usuário), um value (enviado na submissão) e um 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 entidade
Decorators de select de entidade permitem que os usuários escolham membros do servidor, cargos, canais ou entidades mentionable diretamente no modal. Esses campos usam os seletores nativos de entidade do Discord, então exibem avatares, cores de cargo e ícones de canal. Nenhum decorator @ModalChoice é necessário, porque as opções são preenchidas a partir do 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 rádio e checkboxes
Grupos de rádio apresentam opções mutuamente exclusivas em que o usuário deve escolher exatamente uma. Grupos de checkboxes permitem múltiplas seleções. Um único @ModalCheckbox é renderizado como uma alternância booleana. Todos os campos baseados em escolhas usam @ModalOption (um alias de @ModalChoice) para definir suas opções.
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;
}Uploads de arquivo e textos de exibição
O decorator @ModalFileUpload adiciona um campo de anexo ao modal. O decorator @ModalTextDisplay adiciona texto estático somente leitura, que não é enviado como valor de campo. Textos de exibição são úteis para mostrar instruções, avisos ou informações de contexto dentro do próprio formulário do 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 do namespace Modal
O namespace Modal fornece funções factory para criar definições de campo programaticamente em vez de usar decorators. Isso é usado principalmente com campos dinâmicos, abordados na página de dinâmicos, mas também pode ser útil ao montar schemas de modal em funções utilitárias ou bibliotecas compartilhadas.
| Helper | Retorna | Decorator equivalente |
|---|---|---|
| Modal.field.text(config) | Definição de campo de input de texto | @ModalInput |
| Modal.field.stringSelect(config) | Definição de campo de select de string | @ModalSelect |
| Modal.field.userSelect(config) | Definição de campo de select de usuário | @ModalUserSelect |
| Modal.field.roleSelect(config) | Definição de campo de select de cargo | @ModalRoleSelect |
| Modal.field.mentionableSelect(config) | Definição de campo de select de mentionable | @ModalMentionableSelect |
| Modal.field.channelSelect(config) | Definição de campo de select de canal | @ModalChannelSelect |
| Modal.field.radioGroup(config) | Definição de campo de grupo de rádio | @ModalRadioGroup |
| Modal.field.checkboxGroup(config) | Definição de campo de grupo de checkboxes | @ModalCheckboxGroup |
| Modal.field.checkbox(config) | Definição de campo de checkbox único | @ModalCheckbox |
| Modal.field.fileUpload(config) | Definição de campo de upload de arquivo | @ModalFileUpload |
| Modal.field.textDisplay(config) | Definição de campo de texto de exibição | @ModalTextDisplay |
| Modal.choice(config) | Definição de escolha | @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' }),
];
}