Components

Role Select Menus

Learn how to create and use role select menu components with djs-core.

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 dynamically show all roles available in the server. Users can select from roles they have permission to see, making it perfect for role assignment features.

Creating a Role Select Menu

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.

Role select menus are ideal for features like self-assignable roles, permission management, or any functionality that requires users to choose from server roles.

Basic Role Select Menu

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}`);
        }
    });

Multiple Role Selection

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(", ")}`);
    });

Accessing Selected Roles

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}`);
    });

Role Information

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}`,
        });
    });

Using Role Select Menus in Commands

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 Menu Data

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.

Component Definition (without data)

src/components/selects/role/assign.ts
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}`,
        );
    });

Using Select Menu with Data

src/interactions/commands/assign-roles.ts
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],
        });
    });

Min and Max Values

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(", ")}`);
    });

Disabled Role Select Menu

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");
    });