Carbon

Modals

Modals are popup forms that can be used to collect user input.

Modals are popup forms that can be used to collect user input. They are created by extending the Modal class, and adding a title and components property. The components must be Label classes that each contain a single TextInput or StringSelectMenu component.

Modals are automatically registered when they are shown to a user. The registration happens when you call showModal on an interaction.

src/commands/modal.ts
import { 
	Command, 
	type CommandInteraction, 
	type ComponentData, 
	Label,
	type Modal, 
	type ModalInteraction, 
	TextInput, 
	TextInputStyle
} from "@buape/carbon"

export default class ModalCommand extends Command {
	name = "modal"
	description = "A command that shows a modal"

	async run(interaction: CommandInteraction) {
		await interaction.showModal(new TestModal())
	}
}

class TestModal extends Modal {
	title = "Test Modal"
	customId = "test-modal:action=submit"

	components = [
		new NameLabel(),
		new AgeLabel()
	]

	async run(interaction: ModalInteraction, data: ComponentData) {
		const name = interaction.fields.getText("name")
		const age = interaction.fields.getText("age")
		await interaction.reply(
			`Hi ${name}, you are ${age} years old!`
		)
	}
}

class NameLabel extends Label {
	label = "What is your name?"
	description = "Enter your full name"
	
	constructor() {
		super(new TextInputName())
	}
}

class AgeLabel extends Label {
	label = "How old are you?"
	description = "Enter your age in years"
	
	constructor() {
		super(new TextInputAge())
	}
}

class TextInputName extends TextInput {
	customId = "name"
	style = TextInputStyle.Short
	placeholder = "Enter your name"
}

class TextInputAge extends TextInput {
	customId = "age"
	style = TextInputStyle.Short
	placeholder = "Enter your age"
}

Custom ID System

Modals use the same custom ID system as components, allowing you to pass data along with the modal. The format is:

key:arg1=value1;arg2=value2

For example, if you have a modal that needs to know which user to edit, you could do:

class EditUserModal extends Modal {
	title = "Edit User"
	customId = "edit-user:userId=123456789"

	components = [
		new UserNameLabel()
	]

	async run(interaction: ModalInteraction) {
		const { userId } = interaction.customIdParser(interaction.customId).data
		const name = interaction.fields.getText("name")
		// Edit user with ID userId to have name name
	}
}

class UserNameLabel extends Label {
	label = "User Name"
	description = "Enter the new name for this user"
	
	constructor() {
		super(new TextInputName())
	}
}

The custom ID parser will automatically convert:

  • true and false to booleans
  • Numbers to numbers
  • Everything else to strings

You can also override the customIdParser method if you want to use a different format for your custom IDs.

Edit on GitHub

Last updated on

On this page