Components

Modals

Modals

Modals in Seyfert allow you to request structured user input through a popup interface. Seyfert extends the traditional Discord modal system by supporting new component types and a more flexible builder structure.

A modal can contain multiple types of interactive components:

  • TextInput
  • StringSelectMenu
  • RoleSelectMenu
  • ChannelSelectMenu
  • UserSelectMenu
  • MentionableSelectMenu
  • FileUpload
  • TextDisplay (static text)

All interactive components are placed in a modal by wrapping them inside a Label.


Creating a Modal

A modal is created with the Modal class:

const modal = new Modal()
    .setTitle('My modal')
    .setCustomId('myfirstmodal')
    .setComponents([ /* labels here */ ])

Each component must be wrapped in a Label:

const label = new Label()
    .setLabel('Some field')
    .setComponent(myComponent);

1. Text Input Modals

This is the traditional Discord-style modal.

Example

const textInput = new TextInput()
    .setCustomId('text')
    .setStyle(TextInputStyle.Short)
    .setLength({
        max: 200,
        min: 10
    });
 
const label = new Label()
    .setLabel('Write something')
    .setComponent(textInput);
 
const modal = new Modal()
    .setTitle('My modal')
    .setCustomId('myfirstmodal')
    .setComponents([ label ]);

Sending the modal

interaction.modal(modal);

2. Static Text Modal (TextDisplay)

TextDisplay allows you to show static text inside a modal.

Example

const text = new TextDisplay()
    .setId(1)
    .setContent('hello world!');
 
const modal = new Modal()
    .setTitle('My modal')
    .setCustomId('myfirstmodal')
    .setComponents([ text ]);

3. String Select Menu Modal

A select menu with predefined string options.

Example

const stringSelectMenu = new StringSelectMenu()
    .setCustomId('strings')
    .setOptions([
        new StringSelectOption()
            .setLabel('Option 1')
            .setValue('option1'),
        new StringSelectOption()
            .setLabel('Option 2')
            .setValue('option2')
    ]);
 
const label = new Label()
    .setLabel('Choose an option')
    .setComponent(stringSelectMenu);
 
const modal = new Modal()
    .setTitle('My modal')
    .setCustomId('myfirstmodal')
    .setComponents([ label ]);

4. Role Select Menu Modal

Example

const roleSelectMenu = new RoleSelectMenu()
    .setCustomId('role');
 
const label = new Label()
    .setLabel('Choose a role')
    .setComponent(roleSelectMenu);
 
const modal = new Modal()
    .setTitle('My modal')
    .setCustomId('myfirstmodal')
    .setComponents([ label ]);

5. Channel Select Menu Modal

Example

const channelSelectMenu = new ChannelSelectMenu()
    .setCustomId('channel');
 
const label = new Label()
    .setLabel('Choose a channel')
    .setComponent(channelSelectMenu);
 
const modal = new Modal()
    .setTitle('My modal')
    .setCustomId('myfirstmodal')
    .setComponents([ label ]);

6. User Select Menu Modal

Example

const userSelectMenu = new UserSelectMenu()
    .setCustomId('user');
 
const label = new Label()
    .setLabel('Choose a user')
    .setComponent(userSelectMenu);
 
const modal = new Modal()
    .setTitle('My modal')
    .setCustomId('myfirstmodal')
    .setComponents([ label ]);

7. Mentionable Select Menu Modal

Example

const mentionableSelectMenu = new MentionableSelectMenu()
    .setCustomId('member');
 
const label = new Label()
    .setLabel('Choose a mentionable')
    .setComponent(mentionableSelectMenu);
 
const modal = new Modal()
    .setTitle('My modal')
    .setCustomId('myfirstmodal')
    .setComponents([ label ]);

8. File Upload Modal

Example

const fileUpload = new FileUpload()
    .setCustomId('fileupload');
 
const label = new Label()
    .setLabel('Choose a file')
    .setComponent(fileUpload);
 
const modal = new Modal()
    .setTitle('My modal')
    .setCustomId('myfirstmodal')
    .setComponents([ label ]);

Handling Modals

Modals are handled using the ModalCommand class.

Example

import { ModalCommand, type ModalContext } from 'seyfert';
 
export default class MyModal extends ModalCommand {
    filter(context: ModalContext) {
        return context.customId === 'myfirstmodal';
    }
 
    async run(context: ModalContext) {
        const interaction = context.interaction;
 
        const text = interaction.getInputValue('text', true);
 
        return context.write({
            content: `Your input was: ${text}`
        });
    }
}

Triggering Modals From Component Collectors

const collector = message.createComponentCollector();
 
collector.run('modal', (interaction) => {
    interaction.modal(modal);
});

This method works for all modal types.