JSPM

djs-components-helper

1.0.3
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 5
  • Score
    100M100P100Q22806F
  • License MIT

A developer-friendly abstraction layer for Discord.js Components V2

Package Exports

  • djs-components-helper
  • djs-components-helper/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (djs-components-helper) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Discord.js Components V2 Helper

A developer-friendly abstraction layer for Discord.js Components V2 that makes working with the new component system intuitive and enjoyable.

Features

  • 🚀 Full V2 Support: Every feature of Discord's Components V2 including buttons, select menus, layouts, embeds-style cards, media galleries, containers, etc.
  • 🎨 Color Utilities: Built-in utilities for handling hex-to-Discord's internal color formats
  • 🔧 Developer-friendly: Clean, ergonomic APIs that drastically reduce boilerplate while staying flexible
  • 📦 TypeScript-ready: First-class type definitions for great DX in both JavaScript and TypeScript
  • 🔄 Migration Tools: Helpers to easily migrate from classic embeds and Components V1 into V2 equivalents
  • 📚 Comprehensive Documentation: Clear, example-driven docs with migration guides

Installation

npm install djs-components-helper

Quick Start

import { MessageBuilder, ColorUtils } from 'djs-components-helper';
import { MessageFlags } from 'discord.js';

// Create a message with components
const message = new MessageBuilder()
  .addText('Hello, Discord!')
  .addSeparator()
  .addContainer({
    accentColor: ColorUtils.hexToInt('#0099FF'),
    children: [
      { type: 'text', content: 'This is inside a container!' },
      { type: 'button', customId: 'my-button', label: 'Click me!', style: 'primary' }
    ]
  });

// Send the message
await channel.send({
  components: message.build(),
  flags: MessageFlags.IsComponentsV2
});

Core Concepts

MessageBuilder

The main class for building complex messages with components:

import { MessageBuilder } from 'djs-components-helper';

const message = new MessageBuilder()
  .addText('Welcome to our server!')
  .addSeparator()
  .addSection({
    text: 'Choose your role:',
    accessory: {
      type: 'button',
      customId: 'role-select',
      label: 'Select Role',
      style: 'primary'
    }
  });

Color Utilities

Convert hex colors to Discord's internal format:

import { ColorUtils } from 'djs-components-helper';

// Convert hex to Discord color
const color = ColorUtils.hexToInt('#FF0000'); // Red
const blue = ColorUtils.hexToInt('#0099FF');   // Discord Blue
const green = ColorUtils.hexToInt('#57F287');  // Discord Green

Component Types

Text Display

message.addText('Simple text content');
message.addText('**Bold text** with *markdown*');

Sections

message.addSection({
  text: 'Section with button accessory',
  accessory: {
    type: 'button',
    customId: 'section-button',
    label: 'Click me!',
    style: 'primary'
  }
});

Containers

message.addContainer({
  accentColor: ColorUtils.hexToInt('#FF0000'),
  children: [
    { type: 'text', content: 'Container content' },
    { type: 'button', customId: 'container-btn', label: 'Button', style: 'secondary' }
  ]
});

Media Galleries

message.addMediaGallery([
  { url: 'attachment://image1.png', description: 'First image' },
  { url: 'https://example.com/image2.jpg', description: 'Second image', spoiler: true }
]);

Select Menus

message.addSelectMenu({
  customId: 'user-select',
  placeholder: 'Select users',
  type: 'user',
  minValues: 1,
  maxValues: 5
});

Migration from V1

From Embeds to Containers

Before (V1):

const embed = new EmbedBuilder()
  .setTitle('My Embed')
  .setDescription('Description')
  .setColor('#FF0000');

await channel.send({ embeds: [embed] });

After (V2):

const message = new MessageBuilder()
  .addContainer({
    accentColor: ColorUtils.hexToInt('#FF0000'),
    children: [
      { type: 'text', content: '**My Embed**' },
      { type: 'text', content: 'Description' }
    ]
  });

await channel.send({
  components: message.build(),
  flags: MessageFlags.IsComponentsV2
});

From Action Rows to Inline Components

Before (V1):

const row = new ActionRowBuilder()
  .addComponents(
    new ButtonBuilder()
      .setCustomId('button1')
      .setLabel('Button 1')
      .setStyle(ButtonStyle.Primary)
  );

await channel.send({ components: [row] });

After (V2):

const message = new MessageBuilder()
  .addText('Message with inline button:')
  .addButton({
    customId: 'button1',
    label: 'Button 1',
    style: 'primary'
  });

await channel.send({
  components: message.build(),
  flags: MessageFlags.IsComponentsV2
});

API Reference

MessageBuilder

Methods

  • addText(content: string, options?: TextOptions): MessageBuilder
  • addSection(options: SectionOptions): MessageBuilder
  • addContainer(options: ContainerOptions): MessageBuilder
  • addSeparator(options?: SeparatorOptions): MessageBuilder
  • addMediaGallery(items: MediaItem[]): MessageBuilder
  • addFile(options: FileOptions): MessageBuilder
  • addButton(options: ButtonOptions): MessageBuilder
  • addSelectMenu(options: SelectMenuOptions): MessageBuilder
  • build(): Component[]

ColorUtils

Methods

  • hexToInt(hex: string): number - Convert hex color to Discord integer
  • intToHex(int: number): string - Convert Discord integer to hex
  • isValidHex(hex: string): boolean - Validate hex color format

Component Options

TextOptions

interface TextOptions {
  id?: number;
  allowedMentions?: AllowedMentions;
}

SectionOptions

interface SectionOptions {
  text: string | string[];
  accessory?: ButtonOptions | ThumbnailOptions;
  id?: number;
}

ContainerOptions

interface ContainerOptions {
  accentColor?: number;
  children: ComponentConfig[];
  spoiler?: boolean;
  id?: number;
}

Examples

Complex Message with Multiple Components

const message = new MessageBuilder()
  .addText('**Welcome to our Community!**')
  .addSeparator()
  .addContainer({
    accentColor: ColorUtils.hexToInt('#57F287'),
    children: [
      { type: 'text', content: '**Getting Started**' },
      { type: 'text', content: 'Choose your role and explore our channels!' }
    ]
  })
  .addSection({
    text: 'Select your role:',
    accessory: {
      type: 'button',
      customId: 'role-select',
      label: 'Choose Role',
      style: 'primary'
    }
  })
  .addMediaGallery([
    { url: 'attachment://welcome.png', description: 'Welcome banner' }
  ]);

await channel.send({
  components: message.build(),
  files: [new AttachmentBuilder('./assets/welcome.png')],
  flags: MessageFlags.IsComponentsV2
});

Interactive Dashboard

const dashboard = new MessageBuilder()
  .addText('**Server Dashboard**')
  .addSeparator()
  .addContainer({
    accentColor: ColorUtils.hexToInt('#0099FF'),
    children: [
      { type: 'text', content: '**Statistics**' },
      { type: 'text', content: 'Members: 1,234' },
      { type: 'text', content: 'Online: 567' }
    ]
  })
  .addSection({
    text: 'Quick Actions:',
    accessory: {
      type: 'button',
      customId: 'refresh-stats',
      label: '🔄 Refresh',
      style: 'secondary'
    }
  })
  .addSelectMenu({
    customId: 'admin-actions',
    placeholder: 'Admin actions...',
    type: 'string',
    options: [
      { label: 'Ban User', value: 'ban', description: 'Ban a user from the server' },
      { label: 'Kick User', value: 'kick', description: 'Kick a user from the server' },
      { label: 'Mute User', value: 'mute', description: 'Mute a user temporarily' }
    ]
  });

await channel.send({
  components: dashboard.build(),
  flags: MessageFlags.IsComponentsV2
});

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support