Components

Components

Discord components are interactive elements such as buttons, drop-down menus and text fields that developers can integrate into messages sent by bots.

They allow users to interact directly with bots in a more intuitive and dynamic way, improving the user experience by making interactions more engaging and responsive.

Buttons

Buttons in Discord are used to allow users to interact with the interface and perform actions. For example, a button might be used to send a message, join a voice channel, or initiate a game.

You can read the entire documentation about buttons here.

Guidelines

  • 34 characters max with icon or emoji.
  • 38 characters max without icon or emoji.
  • Keep text concise and to the point.
  • Use clear and easily understandable language. Avoid jargon or overly technical terms.
  • Use verbs that indicate the outcome of the action.
  • Maintain consistency in language and tone across buttons.
  • Anticipate the need for translation, test for expansion or contraction in different languages.

Types

  • action : which allow you to create an interaction
  • link : which allow you to open a url
  • premium : which allow you to buy a premium subscription

Builders

Action buttons are buttons that allow you to interact with the bot.

You should define label or emoji property.

PropertyDescriptionRequired
labelThe text displayed on the button.No
emojiThe emoji displayed on the button.No
disabledWhether the button is disabled.No

Primary button

Used for the main actions that the user needs to perform, often visually highlighted.

final primary = ButtonBuilder.primary('primary')
..setLabel('Click me')
..setEmoji(PartialEmoji.fromUnicode('👍'))
..setDisabled(true);

Secondary button

Used for secondary actions, less important than those of primary buttons.

final secondary = ButtonBuilder.secondary('secondary')
..setLabel('Click me')
..setEmoji(PartialEmoji.fromUnicode('🚀'))
..setDisabled(true);

Success button

Used to indicate a successful or positive action, often associated with confirmations.

final success = ButtonBuilder.success('success')
..setLabel('Click me')
..setEmoji(PartialEmoji.fromUnicode('✅'))
..setDisabled(true);

Danger button

Used for critical or destructive actions, such as deleting data.

final danger = ButtonBuilder.danger('danger')
..setLabel('Click me')
..setEmoji(PartialEmoji.fromUnicode('❌'))
..setDisabled(true);

Used to redirect the user to an external URL without triggering an internal action.

You should define url property.

final link = ButtonBuilder.link()
..setLabel('Click me')
..setUrl('https://google.com');

Premium button

Used to allow users to buy a premium subscription.

final premium = ButtonBuilder.premium('sku_id');

Sending buttons

No more than 5 components can be registered in a single RowBuilder.

await channel.send(
content: 'Hello World !',
components: [
RowBuilder()
..addComponent(primary)
..addComponent(secondary)
..addComponent(success)
..addComponent(danger)
..addComponent(link)
]);

Dialogs

Modals in Discord are interactive pop-up windows that allow users to input information or make specific choices.

They are used for more complex interactions, such as filling out forms or confirming important actions, enhancing the user experience by providing a richer and more intuitive interface.

The customId property is mandatory for dialogs.

Text input

Field customId property is mandatory for text.

final text = DialogTextInput('customId')
..setLabel('Hello')
..setPlaceholder('World')
..setConstraint(
minLength: 1,
maxLength: 255,
required: true
);

Paragraph input

Field customId property is mandatory for paragraph.

final paragraph = DialogParagraphInput('customId')
..setLabel('Hello')
..setPlaceholder('World')
..setConstraint(
minLength: 1,
maxLength: 255,
required: true
);

Dialog builder

final dialog = DialogBuilder('customId')
..setTitle('Hello Mineral')
..text(
customId: 'title',
title: 'Title',
defaultValue: post.title)
..paragraph(
customId: 'content',
title: 'Content',
constraint: DialogFieldConstraint(
minLength: 1,
maxLength: 255,
required: true
));

Sending dialogs

Dialogs in Discord can only be used in response to a user interaction.

This means they must be triggered by a specific user action, such as clicking a button or using a command.

This restriction ensures that dialogs are always relevant and contextual, thereby enhancing the user experience by providing information or choices at the appropriate time.

final dialog = DialogBuilder('customId')
..setTitle('Hello')
..text('hello', (input) {
input
..setLabel('Hello')
..setPlaceholder('World')
..setConstraint(
minLength: 1,
maxLength: 255,
required: true
);
});
await ctx.interaction.dialog(dialog);

Handing dialogs

Basiquement, vous pouvez écouter l'évènement de deux manières différentes. Par défaut, l'évènement catch l'ensemble des interactions de type ServerDialogSubmitEvent.

final class MyDialogEvent extends ServerDialogSubmitEvent {
FutureOr<void> handle(ctx, options) {
// Handle dialog submit
}
}

However, it is possible to choose just one component to listen to, using its customId.

final class MyDialogEvent implements ServerDialogSubmitEvent {
@override
String? get customId => 'customId';
@override
FutureOr<void> handle(ctx, options) {
// Handle dialog submit when customId is 'customId'
}
}

Select menus

Selection menus in Discord are interactive elements that allow users to choose from a list of predefined options.

They are used for more complex interactions where multiple choices are possible, enhancing the user experience by providing a richer, more intuitive interface.

Execution context

The action resulting from the user's choice is carried out in a certain interaction context which influences the information available to the user.

There are currently 2 types of interaction context:

  • ServerSelectContext : Interaction context for servers.
  • PrivateSelectContext : Interaction context for private messages.

Text menu

final helloEmoji = PartialEmoji.fromUnicode('👋');
final worldEmoji = PartialEmoji.fromUnicode('🌍');
final select = SelectMenuBuilder.text('customId')
..setPlaceholder('World')
..addOption(label: 'Hello', value: 'hello', emoji: helloEmoji)
..addOption(label: 'World', value: 'world', emoji: worldEmoji);

Channel menu

final select = SelectMenuBuilder.channel('customId')
..setPlaceholder('World')
..setChannelTypes([ChannelType.guildCategory]);