Role select menus allow users to select one or more Discord roles from the server. They're commonly used for role assignment, permissions management, or role-based features.
Role select menus in djs-core are created using the RoleSelectMenu class. Each select menu component file in src/components/selects/role/ is automatically registered.
import { RoleSelectMenu } from "@djs-core/runtime";
export default new RoleSelectMenu()
.setPlaceholder("Select a role")
.run(async (interaction) => {
const selectedRole = interaction.roles.first();
if (selectedRole) {
await interaction.reply(`You selected: ${selectedRole.name}`);
}
});
Role select menus can allow users to select multiple roles:
import { RoleSelectMenu } from "@djs-core/runtime";
export default new RoleSelectMenu()
.setPlaceholder("Select roles")
.setMinValues(1)
.setMaxValues(3)
.run(async (interaction) => {
const selectedRoles = interaction.roles.map((role) => role.name);
await interaction.reply(`Selected roles: ${selectedRoles.join(", ")}`);
});
The interaction.roles collection contains all selected roles:
import { RoleSelectMenu } from "@djs-core/runtime";
export default new RoleSelectMenu()
.setPlaceholder("Select roles to assign")
.run(async (interaction) => {
const roleMentions = interaction.roles.map((role) => role.toString()).join(" ");
await interaction.reply(`Selected roles: ${roleMentions}`);
});
You can access detailed information about selected roles:
import { RoleSelectMenu } from "@djs-core/runtime";
export default new RoleSelectMenu()
.setPlaceholder("Select a role to view info")
.run(async (interaction) => {
const role = interaction.roles.first();
if (!role) return;
await interaction.reply({
content: `Role Info:
**Name:** ${role.name}
**ID:** ${role.id}
**Color:** ${role.hexColor}
**Members:** ${role.members.size}
**Mentionable:** ${role.mentionable}
**Hoisted:** ${role.hoist}`,
});
});
Role select menus are typically sent as part of a command response:
import { Command, RoleSelectMenu } from "@djs-core/runtime";
import { ActionRowBuilder } from "discord.js";
import roleSelect from "../../components/selects/role/assign";
export default new Command()
.setDescription("Assign roles")
.run(async (interaction) => {
const row = new ActionRowBuilder<RoleSelectMenu>().addComponents(roleSelect);
await interaction.reply({
content: "Select roles to assign:",
components: [row],
});
});
Role select menus can receive custom data. Important: The data is set when you use the select menu from a command or another component, not in the component definition.
import { RoleSelectMenu } from "@djs-core/runtime";
export default new RoleSelectMenu<{ userId: string }>()
.setPlaceholder("Select roles to assign")
.run(async (interaction, data) => {
const roles = interaction.roles.map((r) => r.name);
await interaction.reply(
`Assigning roles ${roles.join(", ")} to user ${data.userId}`,
);
});
import { Command, RoleSelectMenu } from "@djs-core/runtime";
import { ActionRowBuilder } from "discord.js";
import assignRoleSelect from "../../components/selects/role/assign";
export default new Command()
.setDescription("Assign roles to a user")
.addUserOption((option) =>
option
.setName("user")
.setDescription("The user to assign roles to")
.setRequired(true),
)
.run(async (interaction) => {
const userId = interaction.options.getUser("user")?.id;
const row = new ActionRowBuilder<RoleSelectMenu>().addComponents(
assignRoleSelect.setData({ userId: userId! }),
);
await interaction.reply({
content: "Select roles to assign:",
components: [row],
});
});
Control how many roles can be selected:
import { RoleSelectMenu } from "@djs-core/runtime";
export default new RoleSelectMenu()
.setPlaceholder("Select 1-3 roles")
.setMinValues(1)
.setMaxValues(3)
.run(async (interaction) => {
const roles = interaction.roles.map((r) => r.name);
await interaction.reply(`Selected ${roles.length} role(s): ${roles.join(", ")}`);
});
Role select menus can be disabled:
import { RoleSelectMenu } from "@djs-core/runtime";
export default new RoleSelectMenu()
.setPlaceholder("This menu is disabled")
.setDisabled(true)
.run(async (interaction) => {
await interaction.reply("Menu is disabled");
});