THIS PACKAGE IS NOT FINISHED! DO NOT USE IT FOR PRODUCTION
discord.js-better-buttons
About
discord.js-better-components is a package that makes message components easier (and fun) to use.
Installation
Node.js 16.9.0 or newer is required.
npm i discord.js discord.js-better-components
Fundamentals
With discord.js-better-components, five main "elements" are used:
- Button: Your standard message button
- Menu: Your standard select menu
- Menu Option: An option for a select menu
- Button Bundle: A container for buttons (minimum of 1 button and maximum of 5)
- Package: A container for button bundles and select menus (minimum of 1 element and maximum of 5)
When a button is clicked, it emits a "click" event with the MessageComponentInteraction
passed as an argument.
When a select menu option is clicked, it emits a "click" event and passes the MessageComponentInteraction
as well.
Example Usage
const { Button, ButtonStyles, ButtonBundle, Menu, MenuOption, Package } = require('discord.js-better-components');
const button = new Button({ label: 'My button', style: ButtonStyles.primary });
const bundle = new ButtonBundle([ button ]);
const option1 = new MenuOption({ label: 'Apples are better than oranges', description: 'If you say so...' });
const option2 = new MenuOption({ label: 'Oranges are better than apples', description: 'If you say so...' });
const menu = new Menu({ placeholder: 'Nothing selected', options: [ option1, option2 ]});
const package = new Package([ bundle, menu ], interaction.client);
button.on('click', i => console.log('My button was clicked!'));
option1.on('click', i => console.log(`${i.user.username} thinks that apples are better than oranges!`));
option2.on('click', i => console.log(`${i.user.username} thinks that oranges are better than apples!`));
await interaction.reply({ content: 'Here\'s a button!', components: package.format() });
Alternatively, if you're a masochist, here's how you do that exact same thing with discord.js:
const row = new Discord.MessageActionRow()
.addComponents(
new Discord.MessageButton()
.setLabel('My button')
.setCustomId('mybutton')
.setStyle('PRIMARY'),
);
const row2 = new MessageActionRow()
.addComponents(
new MessageSelectMenu()
.setCustomId('select')
.setPlaceholder('Nothing selected')
.addOptions([
{
label: 'Apples are better than oranges',
description: 'If you say so...',
value: 'apple_option',
},
{
label: 'Oranges are better than apples',
description: 'If you say so...',
value: 'orange_option',
},
]),
);
await interaction.reply({ content: 'Here\'s a button!', components: [row, row2] });
const filter = i => i.user.id == interaction.user.id;
const collector = interaction.channel.createMessageComponentCollector({ filter, time: 15000 });
collector.on('collect', i => {
if (i.customId == 'mybutton') {
console.log('My button was clicked!');
}
else if (i.customId == 'select') {
const optionPicked = i.values[0];
if (optionPicked == 'apple_option') {
console.log(`${i.user.username} thinks that apples are better than oranges!`);
}
else if (optionPicked == 'orange_option') {
console.log(`${i.user.username} thinks that oranges are better than apples!`);
}
}
});
Yeah, it's not pretty. Having to handle custom ID's, the huge constructors for action rows and components... it makes me shiver just thinking about it.