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.

Note

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.

Note

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
final primary = ButtonBuilder.primary(
  'customId',
  label: 'Click me',
  emoji: PartialEmoji.fromUnicode('πŸ‘'),
  disabled: true,
);

Special buttons

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

Note

You should define url property.

final link = ButtonBuilder.link(
  'https://mineral-foundation.com',
  label: 'Click me',
);

Sending buttons

Important

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

final buttons = [
  MessageButton.primary('primary', label: 'label'),
  MessageButton.secondary('secondary', label: 'label'),
  MessageButton.danger('danger', label: 'label'),
  MessageButton.link('https://google.com', label: 'label'),
];

final builder = MessageBuilder()
  ..text('# Hello from World')
  ..buttons(buttons);

await channel.send(builder);

Modals

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.

Note

The customId property is mandatory for modals.

final modal = ModalBuilder(customId)
  ..setTitle("Modal title")
  ..text("# Some markdown compatible text")
  ..label(
    label: "A label wrapping a component",
    description: "Some optional description",
    component: ModalTextInput(
      "textInputID",
      style: ModalTextInputStyle.short,
      isRequired: false,
      minLength: 10,
      maxLength: 100,
      placeholder: "Some default value",
    ),
  )
  ..label(
    label: "Another label",
    description: "Some optional description",
    component: SelectMenu.role("selectMenuId", maxValues: 3),
  );

Sending modals

Note

Modals 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 modals are always relevant and contextual, thereby enhancing the user experience by providing information or choices at the appropriate time.

await ctx.interaction.modal(modal);

Handing modals

Basically, you can listen to the event in two different ways.
By default, the event catches all interactions of type ServerModalSubmitEvent.

final class MyModalEvent extends ServerModalSubmitEvent {
  FutureOr<void> handle(ctx, options) {
    // Handle modal submit
  }
}

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

final class MyModalEvent implements ServerModalSubmitEvent {
  @override
  String? get customId => 'customId';

  @override
  FutureOr<void> handle(ctx, options) {
    // Handle modal 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 selectMenu = SelectMenu.text('text', [
  SelectMenuOption(label: 'label 1', value: 'value 1'),
  SelectMenuOption(label: 'label 2', value: 'value 2'),
]);

final builder = MessageBuilder()
  ..text('# Hello from World')
  ..selectMenu(selectMenu);

await channel.send(builder);

Channel menu

final channelSelectMenu = SelectMenu.channel('channel',
  channelTypes: [ChannelType.guildText],
  defaultValues: [Snowflake.parse('1322554770057068636')]);

final builder = MessageBuilder()
  ..text('# Hello from World')
  ..selectMenu(channelSelectMenu));

await channel.send(builder);