djs-builder 0.7.4 → 0.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1051 -0
- package/function/dash.js +218 -146
- package/function/function.js +326 -4
- package/handler/helper.js +15 -30
- package/handler/starter.js +4 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -392,6 +392,1057 @@ console.log(
|
|
|
392
392
|
|
|
393
393
|
---
|
|
394
394
|
|
|
395
|
+
<details>
|
|
396
|
+
<summary>CreateModal 🔳</summary>
|
|
397
|
+
|
|
398
|
+
**🔳 CreateModal – Easily create Discord Modals with Text Inputs, Menus, Files, and Labels ✨**
|
|
399
|
+
|
|
400
|
+
`CreateModal` is a powerful utility to build Discord **Modals**. It supports:
|
|
401
|
+
|
|
402
|
+
- **Text Inputs** 📝
|
|
403
|
+
- **Select Menus** 🎯 (`string`, `role`, `user`, `channel`)
|
|
404
|
+
- **File Uploads** 📎
|
|
405
|
+
- **Text Displays** 🏷️
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
### 📌 Example Usage:
|
|
410
|
+
|
|
411
|
+
```js
|
|
412
|
+
const { CreateModal } = require("djs-builder");
|
|
413
|
+
|
|
414
|
+
const modal = CreateModal({
|
|
415
|
+
id: "myModal",
|
|
416
|
+
title: "User Information",
|
|
417
|
+
components: [
|
|
418
|
+
{
|
|
419
|
+
type: "textInput",
|
|
420
|
+
components: [
|
|
421
|
+
{
|
|
422
|
+
label: "Your Name",
|
|
423
|
+
id: "name",
|
|
424
|
+
style: 1, // 1: Short, 2: Paragraph
|
|
425
|
+
placeholder: "Enter your name",
|
|
426
|
+
required: true,
|
|
427
|
+
minLength: 2,
|
|
428
|
+
maxLength: 50,
|
|
429
|
+
},
|
|
430
|
+
],
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
type: "menu",
|
|
434
|
+
components: {
|
|
435
|
+
type: "string",
|
|
436
|
+
options: {
|
|
437
|
+
id: "favoriteColor",
|
|
438
|
+
placeholder: "Choose your favorite color",
|
|
439
|
+
min: 1,
|
|
440
|
+
max: 1,
|
|
441
|
+
data: [
|
|
442
|
+
{
|
|
443
|
+
label: "Red",
|
|
444
|
+
value: "red",
|
|
445
|
+
description: "A bold color",
|
|
446
|
+
emoji: "🔴",
|
|
447
|
+
default: false,
|
|
448
|
+
},
|
|
449
|
+
{
|
|
450
|
+
label: "Blue",
|
|
451
|
+
value: "blue",
|
|
452
|
+
description: "A calm color",
|
|
453
|
+
emoji: "🔵",
|
|
454
|
+
},
|
|
455
|
+
],
|
|
456
|
+
label: "label",
|
|
457
|
+
value: "value",
|
|
458
|
+
description: "description",
|
|
459
|
+
emoji: "emoji",
|
|
460
|
+
disabled: false,
|
|
461
|
+
},
|
|
462
|
+
},
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
type: "file",
|
|
466
|
+
components: {
|
|
467
|
+
id: "avatar",
|
|
468
|
+
label: "Upload Avatar",
|
|
469
|
+
description: "Optional avatar image",
|
|
470
|
+
},
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
type: "label",
|
|
474
|
+
components: {
|
|
475
|
+
label: "Thank you for your input!",
|
|
476
|
+
},
|
|
477
|
+
},
|
|
478
|
+
],
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
// Show the modal
|
|
482
|
+
await interaction.showModal(modal);
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
---
|
|
486
|
+
|
|
487
|
+
### 📔 Examples for Each Component Type:
|
|
488
|
+
|
|
489
|
+
#### 🔹 Text Input Example:
|
|
490
|
+
|
|
491
|
+
```js
|
|
492
|
+
{
|
|
493
|
+
type: "textInput",
|
|
494
|
+
components: [
|
|
495
|
+
{
|
|
496
|
+
label: "Your Age",
|
|
497
|
+
id: "age",
|
|
498
|
+
style: 1, // Short input
|
|
499
|
+
placeholder: "Enter your age",
|
|
500
|
+
required: true,
|
|
501
|
+
minLength: 1,
|
|
502
|
+
maxLength: 3,
|
|
503
|
+
value: "18", // Pre-filled
|
|
504
|
+
},
|
|
505
|
+
],
|
|
506
|
+
},
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
#### 🔹 Menu Example:
|
|
510
|
+
|
|
511
|
+
```js
|
|
512
|
+
{
|
|
513
|
+
type: "menu",
|
|
514
|
+
components: {
|
|
515
|
+
type: "string",
|
|
516
|
+
options: {
|
|
517
|
+
id: "country",
|
|
518
|
+
placeholder: "Select your country",
|
|
519
|
+
min: 1,
|
|
520
|
+
max: 1,
|
|
521
|
+
data: [
|
|
522
|
+
{
|
|
523
|
+
name: "USA",
|
|
524
|
+
id: "usa",
|
|
525
|
+
desc: "United States",
|
|
526
|
+
icon: "🇺🇸",
|
|
527
|
+
default: true, // This option is pre-selected
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
name: "Canada",
|
|
531
|
+
id: "canada",
|
|
532
|
+
desc: "Canada",
|
|
533
|
+
icon: "🇨🇦",
|
|
534
|
+
},
|
|
535
|
+
],
|
|
536
|
+
label: "name", // Maps to 'name' field in data
|
|
537
|
+
value: "id", // Maps to 'id' field in data
|
|
538
|
+
description: "desc", // Maps to 'desc' field
|
|
539
|
+
emoji: "icon", // Maps to 'icon' field
|
|
540
|
+
disabled: false,
|
|
541
|
+
},
|
|
542
|
+
},
|
|
543
|
+
},
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
#### 🔹 File Example:
|
|
547
|
+
|
|
548
|
+
```js
|
|
549
|
+
{
|
|
550
|
+
type: "file",
|
|
551
|
+
components: {
|
|
552
|
+
id: "document",
|
|
553
|
+
label: "Upload Document",
|
|
554
|
+
description: "Upload a PDF or image",
|
|
555
|
+
},
|
|
556
|
+
},
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
#### 🔹 Label Example:
|
|
560
|
+
|
|
561
|
+
```js
|
|
562
|
+
{
|
|
563
|
+
type: "label",
|
|
564
|
+
components: {
|
|
565
|
+
label: "Please fill out the form above.",
|
|
566
|
+
},
|
|
567
|
+
},
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
---
|
|
571
|
+
|
|
572
|
+
### �📖 Explanation
|
|
573
|
+
|
|
574
|
+
#### 🔹 Text Input
|
|
575
|
+
|
|
576
|
+
- `label` → Label for the input field
|
|
577
|
+
- `id` → customId for the input
|
|
578
|
+
- `style` → 1: Short, 2: Paragraph
|
|
579
|
+
- `placeholder` → Placeholder text
|
|
580
|
+
- `required` → true/false
|
|
581
|
+
- `minLength` / `maxLength` → Min/Max characters
|
|
582
|
+
- `value` → Pre-filled value
|
|
583
|
+
|
|
584
|
+
#### 🔹 Menu
|
|
585
|
+
|
|
586
|
+
Same as CreateRow select menus.
|
|
587
|
+
|
|
588
|
+
- `type` → `"string" | "user" | "role" | "channel"`
|
|
589
|
+
- `id` → customId for menu
|
|
590
|
+
- `placeholder` → Text shown before selection
|
|
591
|
+
- `min` / `max` → Min/Max selectable values
|
|
592
|
+
- `data` → Options array (for string select only)
|
|
593
|
+
|
|
594
|
+
- `label` → Visible text (maps to the field specified in `label` key)
|
|
595
|
+
- `value` → Internal value (maps to the field specified in `value` key)
|
|
596
|
+
- `description` → Short description (maps to the field specified in `description` key)
|
|
597
|
+
- `emoji` → Option emoji (maps to the field specified in `emoji` key)
|
|
598
|
+
- `default` → Pre-selected option (true/false in data array)
|
|
599
|
+
|
|
600
|
+
- `label` → Key in data to use as label (e.g., "name")
|
|
601
|
+
- `value` → Key in data to use as value (e.g., "id")
|
|
602
|
+
- `description` → Key in data to use as description (e.g., "desc")
|
|
603
|
+
- `emoji` → Key in data to use as emoji (e.g., "icon")
|
|
604
|
+
- `disabled` → Disable menu completely
|
|
605
|
+
- `defaultValues` → Pre-selected user/role/channel options (for non-string menus)
|
|
606
|
+
- `channelTypes` → Restrict selectable channel types (for channel menu)
|
|
607
|
+
|
|
608
|
+
#### 🔹 File
|
|
609
|
+
|
|
610
|
+
- `id` → customId for the file upload
|
|
611
|
+
- `label` → Label
|
|
612
|
+
- `description` → Description
|
|
613
|
+
|
|
614
|
+
#### 🔹 Label
|
|
615
|
+
|
|
616
|
+
- `label` → Text to display
|
|
617
|
+
|
|
618
|
+
---
|
|
619
|
+
|
|
620
|
+
### 🔹 Notes
|
|
621
|
+
|
|
622
|
+
- Supports multiple components in one modal
|
|
623
|
+
- Fully customizable with Discord.js ModalBuilder
|
|
624
|
+
|
|
625
|
+
</details>
|
|
626
|
+
|
|
627
|
+
---
|
|
628
|
+
|
|
629
|
+
<details>
|
|
630
|
+
<summary>CreateComponents 🧩</summary>
|
|
631
|
+
|
|
632
|
+
**🧩 CreateComponents – Build Advanced Discord UI Components with Containers, Sections & Media ✨**
|
|
633
|
+
|
|
634
|
+
`CreateComponents` is a powerful utility to build Discord's **new UI components**. It supports:
|
|
635
|
+
|
|
636
|
+
- **Text Displays** 📝
|
|
637
|
+
- **Separators** ➖
|
|
638
|
+
- **Media Galleries** 🖼️
|
|
639
|
+
- **File Attachments** 📎
|
|
640
|
+
- **Buttons** 🔘
|
|
641
|
+
- **Select Menus** 🎯 (`string`, `role`, `user`, `channel`)
|
|
642
|
+
- **Sections with Accessories** 📦 (Thumbnails & Buttons)
|
|
643
|
+
- **Containers** 📦 (Group all components together)
|
|
644
|
+
|
|
645
|
+
---
|
|
646
|
+
|
|
647
|
+
### 📌 Example Usage (Array Mode):
|
|
648
|
+
|
|
649
|
+
```js
|
|
650
|
+
const { CreateComponents } = require("djs-builder");
|
|
651
|
+
|
|
652
|
+
const components = await CreateComponents("array", [
|
|
653
|
+
{
|
|
654
|
+
type: "text",
|
|
655
|
+
content: "Welcome to our server! 🎉",
|
|
656
|
+
},
|
|
657
|
+
{
|
|
658
|
+
type: "separator",
|
|
659
|
+
divider: true,
|
|
660
|
+
spacing: 1, // 1: Small, 2: Large
|
|
661
|
+
},
|
|
662
|
+
{
|
|
663
|
+
type: "media",
|
|
664
|
+
links: [
|
|
665
|
+
"https://example.com/image1.png",
|
|
666
|
+
{
|
|
667
|
+
url: "https://example.com/image2.png",
|
|
668
|
+
description: "A cool image",
|
|
669
|
+
spoiler: true,
|
|
670
|
+
},
|
|
671
|
+
],
|
|
672
|
+
},
|
|
673
|
+
{
|
|
674
|
+
type: "button",
|
|
675
|
+
components: [
|
|
676
|
+
{
|
|
677
|
+
id: "btn_1",
|
|
678
|
+
style: 1, // 1: Primary, 2: Secondary, 3: Success, 4: Danger, 5: Link
|
|
679
|
+
label: "Click Me!",
|
|
680
|
+
emoji: "🚀",
|
|
681
|
+
},
|
|
682
|
+
{
|
|
683
|
+
id: "btn_2",
|
|
684
|
+
style: 3,
|
|
685
|
+
label: "Confirm",
|
|
686
|
+
},
|
|
687
|
+
],
|
|
688
|
+
},
|
|
689
|
+
]);
|
|
690
|
+
|
|
691
|
+
// Send the components
|
|
692
|
+
await channel.send({ components });
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
---
|
|
696
|
+
|
|
697
|
+
### 📌 Example Usage (Container Mode):
|
|
698
|
+
|
|
699
|
+
```js
|
|
700
|
+
const { CreateComponents } = require("djs-builder");
|
|
701
|
+
|
|
702
|
+
const components = await CreateComponents("container", [
|
|
703
|
+
{
|
|
704
|
+
type: "text",
|
|
705
|
+
content: "# 📢 Server Announcement\nWelcome everyone!",
|
|
706
|
+
},
|
|
707
|
+
{
|
|
708
|
+
type: "separator",
|
|
709
|
+
divider: true,
|
|
710
|
+
},
|
|
711
|
+
{
|
|
712
|
+
type: "section",
|
|
713
|
+
content: "Check out our latest updates and news!",
|
|
714
|
+
accessory: {
|
|
715
|
+
type: "thumbnail",
|
|
716
|
+
url: "https://example.com/thumbnail.png",
|
|
717
|
+
description: "News Image",
|
|
718
|
+
},
|
|
719
|
+
},
|
|
720
|
+
{
|
|
721
|
+
type: "section",
|
|
722
|
+
content: "**Click below to get your roles!**",
|
|
723
|
+
accessory: {
|
|
724
|
+
type: "button",
|
|
725
|
+
id: "get_roles",
|
|
726
|
+
style: 1,
|
|
727
|
+
label: "Get Roles",
|
|
728
|
+
emoji: "🎭",
|
|
729
|
+
},
|
|
730
|
+
},
|
|
731
|
+
{
|
|
732
|
+
type: "media",
|
|
733
|
+
links: ["https://example.com/banner.png"],
|
|
734
|
+
},
|
|
735
|
+
{
|
|
736
|
+
type: "button",
|
|
737
|
+
components: [
|
|
738
|
+
{ id: "rules", style: 2, label: "📜 Rules", emoji: "📜" },
|
|
739
|
+
{ id: "help", style: 2, label: "❓ Help", emoji: "❓" },
|
|
740
|
+
{ style: 5, label: "🌐 Website", url: "https://example.com" },
|
|
741
|
+
],
|
|
742
|
+
},
|
|
743
|
+
]);
|
|
744
|
+
|
|
745
|
+
// Send with container
|
|
746
|
+
await channel.send({ components, flags: 32768 }); // flags for components v2
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
---
|
|
750
|
+
|
|
751
|
+
### 📜 Examples for Each Component Type:
|
|
752
|
+
|
|
753
|
+
---
|
|
754
|
+
|
|
755
|
+
<details>
|
|
756
|
+
<summary>🔹 Text Component Examples</summary>
|
|
757
|
+
|
|
758
|
+
#### 📌 Simple Text:
|
|
759
|
+
|
|
760
|
+
```js
|
|
761
|
+
{
|
|
762
|
+
type: "text",
|
|
763
|
+
content: "Hello World! 👋",
|
|
764
|
+
}
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
#### 📌 Text with Markdown:
|
|
768
|
+
|
|
769
|
+
```js
|
|
770
|
+
{
|
|
771
|
+
type: "text",
|
|
772
|
+
content: "# 📢 Announcement\n**Important:** Server maintenance tonight!",
|
|
773
|
+
}
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
#### 📌 Text with Multiple Lines:
|
|
777
|
+
|
|
778
|
+
```js
|
|
779
|
+
{
|
|
780
|
+
type: "text",
|
|
781
|
+
content: `## 🎮 Game Stats
|
|
782
|
+
|
|
783
|
+
**Player:** Ahmed
|
|
784
|
+
**Level:** 50
|
|
785
|
+
**XP:** 12,500 / 15,000
|
|
786
|
+
**Rank:** Diamond 💎`,
|
|
787
|
+
}
|
|
788
|
+
```
|
|
789
|
+
|
|
790
|
+
#### 📌 Text with Emojis & Formatting:
|
|
791
|
+
|
|
792
|
+
```js
|
|
793
|
+
{
|
|
794
|
+
type: "text",
|
|
795
|
+
content: ">>> 💡 **Tip:** Use `/help` to see all commands!\n\n*This message will auto-delete in 30 seconds*",
|
|
796
|
+
}
|
|
797
|
+
```
|
|
798
|
+
|
|
799
|
+
</details>
|
|
800
|
+
|
|
801
|
+
---
|
|
802
|
+
|
|
803
|
+
<details>
|
|
804
|
+
<summary>➖ Separator Component Examples</summary>
|
|
805
|
+
|
|
806
|
+
**➖ Separator – Add spacing and dividers between components**
|
|
807
|
+
|
|
808
|
+
The separator component allows you to add visual breaks between other components with customizable spacing and divider lines.
|
|
809
|
+
|
|
810
|
+
---
|
|
811
|
+
|
|
812
|
+
### 📖 Separator Options
|
|
813
|
+
|
|
814
|
+
| Option | Type | Default | Description |
|
|
815
|
+
| --------- | --------- | ------- | -------------------------------------------------- |
|
|
816
|
+
| `type` | `string` | — | Must be `"separator"` |
|
|
817
|
+
| `divider` | `boolean` | `false` | Show a horizontal dividing line |
|
|
818
|
+
| `spacing` | `number` | `1` | Spacing size: `1` (Small) or `2` (Large) |
|
|
819
|
+
|
|
820
|
+
---
|
|
821
|
+
|
|
822
|
+
#### 📌 Simple Divider Line:
|
|
823
|
+
|
|
824
|
+
```js
|
|
825
|
+
{
|
|
826
|
+
type: "separator",
|
|
827
|
+
divider: true,
|
|
828
|
+
}
|
|
829
|
+
```
|
|
830
|
+
**Result:** A thin horizontal line appears between components.
|
|
831
|
+
|
|
832
|
+
---
|
|
833
|
+
|
|
834
|
+
#### 📌 Separator without Line (Spacing Only):
|
|
835
|
+
|
|
836
|
+
```js
|
|
837
|
+
{
|
|
838
|
+
type: "separator",
|
|
839
|
+
divider: false,
|
|
840
|
+
spacing: 2, // Large spacing
|
|
841
|
+
}
|
|
842
|
+
```
|
|
843
|
+
**Result:** Empty space without any visible line - useful for visual grouping.
|
|
844
|
+
|
|
845
|
+
---
|
|
846
|
+
|
|
847
|
+
#### 📌 Small Spacing with Divider:
|
|
848
|
+
|
|
849
|
+
```js
|
|
850
|
+
{
|
|
851
|
+
type: "separator",
|
|
852
|
+
divider: true,
|
|
853
|
+
spacing: 1, // Small spacing (default)
|
|
854
|
+
}
|
|
855
|
+
```
|
|
856
|
+
**Result:** A divider line with minimal padding above and below.
|
|
857
|
+
|
|
858
|
+
---
|
|
859
|
+
|
|
860
|
+
#### 📌 Large Spacing with Divider:
|
|
861
|
+
|
|
862
|
+
```js
|
|
863
|
+
{
|
|
864
|
+
type: "separator",
|
|
865
|
+
divider: true,
|
|
866
|
+
spacing: 2, // Large spacing
|
|
867
|
+
}
|
|
868
|
+
```
|
|
869
|
+
**Result:** A divider line with more padding - creates stronger visual separation.
|
|
870
|
+
|
|
871
|
+
---
|
|
872
|
+
|
|
873
|
+
### 💡 When to Use Each Option:
|
|
874
|
+
|
|
875
|
+
| Scenario | `divider` | `spacing` |
|
|
876
|
+
| ------------------------------------- | --------- | --------- |
|
|
877
|
+
| Separate major sections | `true` | `2` |
|
|
878
|
+
| Separate sub-sections | `true` | `1` |
|
|
879
|
+
| Group related items visually | `false` | `1` |
|
|
880
|
+
| Create breathing room between content | `false` | `2` |
|
|
881
|
+
| Minimal separation | `false` | `1` |
|
|
882
|
+
|
|
883
|
+
</details>
|
|
884
|
+
|
|
885
|
+
---
|
|
886
|
+
|
|
887
|
+
<details>
|
|
888
|
+
<summary>🖼️ Media Gallery Examples</summary>
|
|
889
|
+
|
|
890
|
+
**🖼️ Media Gallery – Display images in a beautiful gallery format**
|
|
891
|
+
|
|
892
|
+
The media component creates an image gallery that can display one or multiple images. Each image can be a simple URL string or a detailed object with additional options.
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
---
|
|
896
|
+
|
|
897
|
+
### 📌 Format 1: Simple String URLs
|
|
898
|
+
|
|
899
|
+
The simplest way - just pass image URLs as strings:
|
|
900
|
+
|
|
901
|
+
```js
|
|
902
|
+
{
|
|
903
|
+
type: "media",
|
|
904
|
+
links: ["https://example.com/image.png"],
|
|
905
|
+
}
|
|
906
|
+
```
|
|
907
|
+
|
|
908
|
+
---
|
|
909
|
+
|
|
910
|
+
### 📌 Format 2: Object with Full Options
|
|
911
|
+
|
|
912
|
+
For more control, use objects with url, description, and spoiler:
|
|
913
|
+
|
|
914
|
+
```js
|
|
915
|
+
{
|
|
916
|
+
type: "media",
|
|
917
|
+
links: [
|
|
918
|
+
{
|
|
919
|
+
url: "https://example.com/image.png",
|
|
920
|
+
description: "A beautiful sunset",
|
|
921
|
+
spoiler: false,
|
|
922
|
+
},
|
|
923
|
+
],
|
|
924
|
+
}
|
|
925
|
+
```
|
|
926
|
+
|
|
927
|
+
---
|
|
928
|
+
|
|
929
|
+
### 📌 Single Image with Spoiler:
|
|
930
|
+
|
|
931
|
+
```js
|
|
932
|
+
{
|
|
933
|
+
type: "media",
|
|
934
|
+
links: [
|
|
935
|
+
{
|
|
936
|
+
url: "https://example.com/spoiler.png",
|
|
937
|
+
description: "⚠️ Spoiler Alert!",
|
|
938
|
+
spoiler: true,
|
|
939
|
+
},
|
|
940
|
+
],
|
|
941
|
+
}
|
|
942
|
+
```
|
|
943
|
+
|
|
944
|
+
---
|
|
945
|
+
|
|
946
|
+
### 📌 Multiple Images (Simple Strings):
|
|
947
|
+
|
|
948
|
+
```js
|
|
949
|
+
{
|
|
950
|
+
type: "media",
|
|
951
|
+
links: [
|
|
952
|
+
"https://example.com/image1.png",
|
|
953
|
+
"https://example.com/image2.png",
|
|
954
|
+
"https://example.com/image3.png",
|
|
955
|
+
"https://example.com/image4.png",
|
|
956
|
+
],
|
|
957
|
+
}
|
|
958
|
+
```
|
|
959
|
+
**Result:** A 2x2 gallery grid of images.
|
|
960
|
+
|
|
961
|
+
---
|
|
962
|
+
|
|
963
|
+
### 📌 Mixed Format (Strings + Objects):
|
|
964
|
+
|
|
965
|
+
You can mix simple strings with detailed objects in the same array:
|
|
966
|
+
|
|
967
|
+
```js
|
|
968
|
+
{
|
|
969
|
+
type: "media",
|
|
970
|
+
links: [
|
|
971
|
+
// Simple string - just the URL
|
|
972
|
+
"https://example.com/public-image.png",
|
|
973
|
+
|
|
974
|
+
// Object with description
|
|
975
|
+
{
|
|
976
|
+
url: "https://example.com/special-image.png",
|
|
977
|
+
description: "Limited Edition Art",
|
|
978
|
+
},
|
|
979
|
+
|
|
980
|
+
// Object with spoiler
|
|
981
|
+
{
|
|
982
|
+
url: "https://example.com/secret-image.png",
|
|
983
|
+
description: "Secret Content",
|
|
984
|
+
spoiler: true,
|
|
985
|
+
},
|
|
986
|
+
|
|
987
|
+
// Another simple string
|
|
988
|
+
"https://example.com/another-image.png",
|
|
989
|
+
],
|
|
990
|
+
}
|
|
991
|
+
```
|
|
992
|
+
|
|
993
|
+
---
|
|
994
|
+
|
|
995
|
+
### 📌 Meme/Artwork Gallery with Spoilers:
|
|
996
|
+
|
|
997
|
+
```js
|
|
998
|
+
{
|
|
999
|
+
type: "media",
|
|
1000
|
+
links: [
|
|
1001
|
+
{
|
|
1002
|
+
url: "https://example.com/meme1.png",
|
|
1003
|
+
description: "Funny meme #1",
|
|
1004
|
+
spoiler: false,
|
|
1005
|
+
},
|
|
1006
|
+
{
|
|
1007
|
+
url: "https://example.com/meme2.png",
|
|
1008
|
+
description: "Funny meme #2",
|
|
1009
|
+
spoiler: false,
|
|
1010
|
+
},
|
|
1011
|
+
{
|
|
1012
|
+
url: "https://example.com/nsfw-meme.png",
|
|
1013
|
+
description: "⚠️ Slightly inappropriate",
|
|
1014
|
+
spoiler: true, // Hidden behind blur
|
|
1015
|
+
},
|
|
1016
|
+
],
|
|
1017
|
+
}
|
|
1018
|
+
```
|
|
1019
|
+
|
|
1020
|
+
---
|
|
1021
|
+
|
|
1022
|
+
### 💡 Tips for Media Galleries:
|
|
1023
|
+
|
|
1024
|
+
| Images Count | Display Layout |
|
|
1025
|
+
| ------------ | ---------------------- |
|
|
1026
|
+
| 1 image | Full width single image |
|
|
1027
|
+
| 2 images | Side by side |
|
|
1028
|
+
| 3 images | 1 large + 2 small |
|
|
1029
|
+
| 4+ images | Grid layout |
|
|
1030
|
+
|
|
1031
|
+
- Use `description` for accessibility and context
|
|
1032
|
+
- Use `spoiler: true` for sensitive/spoiler content
|
|
1033
|
+
- Mix formats freely - strings for quick images, objects for detailed ones
|
|
1034
|
+
- Images are displayed in the order provided
|
|
1035
|
+
|
|
1036
|
+
</details>
|
|
1037
|
+
|
|
1038
|
+
---
|
|
1039
|
+
|
|
1040
|
+
<details>
|
|
1041
|
+
<summary>📎 File Component Examples</summary>
|
|
1042
|
+
|
|
1043
|
+
#### 📌 Simple File Attachment:
|
|
1044
|
+
|
|
1045
|
+
```js
|
|
1046
|
+
{
|
|
1047
|
+
type: "file",
|
|
1048
|
+
url: "attachment://document.pdf",
|
|
1049
|
+
}
|
|
1050
|
+
```
|
|
1051
|
+
|
|
1052
|
+
|
|
1053
|
+
|
|
1054
|
+
#### 📌 Full Example with File:
|
|
1055
|
+
|
|
1056
|
+
```js
|
|
1057
|
+
const { CreateComponents } = require("djs-builder");
|
|
1058
|
+
const { AttachmentBuilder } = require("discord.js");
|
|
1059
|
+
|
|
1060
|
+
const file = new AttachmentBuilder("./myfile.txt", { name: "myfile.txt" });
|
|
1061
|
+
|
|
1062
|
+
const components = await CreateComponents("container", [
|
|
1063
|
+
{
|
|
1064
|
+
type: "text",
|
|
1065
|
+
content: "📄 **Here is your requested file:**",
|
|
1066
|
+
},
|
|
1067
|
+
{
|
|
1068
|
+
type: "file",
|
|
1069
|
+
url: "attachment://myfile.txt",
|
|
1070
|
+
},
|
|
1071
|
+
]);
|
|
1072
|
+
|
|
1073
|
+
await channel.send({ components, files: [file], flags: 32768 });
|
|
1074
|
+
```
|
|
1075
|
+
|
|
1076
|
+
</details>
|
|
1077
|
+
|
|
1078
|
+
---
|
|
1079
|
+
|
|
1080
|
+
<details>
|
|
1081
|
+
<summary>🔘 Button Component Examples</summary>
|
|
1082
|
+
|
|
1083
|
+
#### 📌 Button with Emoji:
|
|
1084
|
+
|
|
1085
|
+
```js
|
|
1086
|
+
{
|
|
1087
|
+
type: "button",
|
|
1088
|
+
components: [
|
|
1089
|
+
{
|
|
1090
|
+
id: "like_btn",
|
|
1091
|
+
style: 3, // Success (Green)
|
|
1092
|
+
label: "Like",
|
|
1093
|
+
emoji: "👍",
|
|
1094
|
+
},
|
|
1095
|
+
],
|
|
1096
|
+
}
|
|
1097
|
+
```
|
|
1098
|
+
|
|
1099
|
+
#### 📌 Multiple Buttons in Row:
|
|
1100
|
+
|
|
1101
|
+
```js
|
|
1102
|
+
{
|
|
1103
|
+
type: "button",
|
|
1104
|
+
components: [
|
|
1105
|
+
{ id: "btn_yes", style: 3, label: "Yes", emoji: "✅" },
|
|
1106
|
+
{ id: "btn_no", style: 4, label: "No", emoji: "❌" },
|
|
1107
|
+
{ id: "btn_maybe", style: 2, label: "Maybe", emoji: "🤔" },
|
|
1108
|
+
],
|
|
1109
|
+
}
|
|
1110
|
+
```
|
|
1111
|
+
|
|
1112
|
+
#### 📌 All Button Styles:
|
|
1113
|
+
|
|
1114
|
+
```js
|
|
1115
|
+
{
|
|
1116
|
+
type: "button",
|
|
1117
|
+
components: [
|
|
1118
|
+
{ id: "primary", style: 1, label: "Primary", emoji: "🔵" }, // Blue
|
|
1119
|
+
{ id: "secondary", style: 2, label: "Secondary", emoji: "⚪" }, // Gray
|
|
1120
|
+
{ id: "success", style: 3, label: "Success", emoji: "🟢" }, // Green
|
|
1121
|
+
{ id: "danger", style: 4, label: "Danger", emoji: "🔴" }, // Red
|
|
1122
|
+
{ style: 5, label: "Link", emoji: "🔗", url: "https://discord.com" }, // Link
|
|
1123
|
+
],
|
|
1124
|
+
}
|
|
1125
|
+
```
|
|
1126
|
+
|
|
1127
|
+
|
|
1128
|
+
</details>
|
|
1129
|
+
|
|
1130
|
+
---
|
|
1131
|
+
|
|
1132
|
+
<details>
|
|
1133
|
+
<summary>🎯 Menu Component Examples</summary>
|
|
1134
|
+
|
|
1135
|
+
#### 📌 String Select Menu (Basic):
|
|
1136
|
+
|
|
1137
|
+
```js
|
|
1138
|
+
{
|
|
1139
|
+
type: "menu",
|
|
1140
|
+
components: {
|
|
1141
|
+
type: "string",
|
|
1142
|
+
options: {
|
|
1143
|
+
id: "color_select",
|
|
1144
|
+
placeholder: "🎨 Choose a color",
|
|
1145
|
+
data: [
|
|
1146
|
+
{ name: "Red", id: "red", icon: "🔴" },
|
|
1147
|
+
{ name: "Blue", id: "blue", icon: "🔵" },
|
|
1148
|
+
{ name: "Green", id: "green", icon: "🟢" },
|
|
1149
|
+
],
|
|
1150
|
+
label: "name",
|
|
1151
|
+
value: "id",
|
|
1152
|
+
emoji: "icon",
|
|
1153
|
+
},
|
|
1154
|
+
},
|
|
1155
|
+
}
|
|
1156
|
+
```
|
|
1157
|
+
|
|
1158
|
+
#### 📌 String Select with Description:
|
|
1159
|
+
|
|
1160
|
+
```js
|
|
1161
|
+
{
|
|
1162
|
+
type: "menu",
|
|
1163
|
+
components: {
|
|
1164
|
+
type: "string",
|
|
1165
|
+
options: {
|
|
1166
|
+
id: "role_select",
|
|
1167
|
+
placeholder: "🎭 Select your role",
|
|
1168
|
+
data: [
|
|
1169
|
+
{ name: "Gamer", id: "gamer", desc: "For gaming enthusiasts", icon: "🎮" },
|
|
1170
|
+
{ name: "Artist", id: "artist", desc: "For creative people", icon: "🎨" },
|
|
1171
|
+
{ name: "Developer", id: "dev", desc: "For coders & programmers", icon: "💻" },
|
|
1172
|
+
{ name: "Music Lover", id: "music", desc: "For music fans", icon: "🎵" },
|
|
1173
|
+
],
|
|
1174
|
+
label: "name",
|
|
1175
|
+
value: "id",
|
|
1176
|
+
description: "desc",
|
|
1177
|
+
emoji: "icon",
|
|
1178
|
+
},
|
|
1179
|
+
},
|
|
1180
|
+
}
|
|
1181
|
+
```
|
|
1182
|
+
|
|
1183
|
+
#### 📌 String Select with Min/Max:
|
|
1184
|
+
|
|
1185
|
+
```js
|
|
1186
|
+
{
|
|
1187
|
+
type: "menu",
|
|
1188
|
+
components: {
|
|
1189
|
+
type: "string",
|
|
1190
|
+
options: {
|
|
1191
|
+
id: "games_select",
|
|
1192
|
+
placeholder: "🎮 Select your favorite games (2-4)",
|
|
1193
|
+
min: 2,
|
|
1194
|
+
max: 4,
|
|
1195
|
+
data: [
|
|
1196
|
+
{ name: "Minecraft", id: "mc", icon: "⛏️" },
|
|
1197
|
+
{ name: "Fortnite", id: "fn", icon: "🔫" },
|
|
1198
|
+
{ name: "Valorant", id: "val", icon: "🎯" },
|
|
1199
|
+
{ name: "League of Legends", id: "lol", icon: "⚔️" },
|
|
1200
|
+
{ name: "Rocket League", id: "rl", icon: "🚗" },
|
|
1201
|
+
],
|
|
1202
|
+
label: "name",
|
|
1203
|
+
value: "id",
|
|
1204
|
+
emoji: "icon",
|
|
1205
|
+
},
|
|
1206
|
+
},
|
|
1207
|
+
}
|
|
1208
|
+
```
|
|
1209
|
+
|
|
1210
|
+
|
|
1211
|
+
#### 📌 User Select (Multiple):
|
|
1212
|
+
|
|
1213
|
+
```js
|
|
1214
|
+
{
|
|
1215
|
+
type: "menu",
|
|
1216
|
+
components: {
|
|
1217
|
+
type: "user",
|
|
1218
|
+
options: {
|
|
1219
|
+
id: "users_select",
|
|
1220
|
+
placeholder: "👥 Select users to invite (1-5)",
|
|
1221
|
+
min: 1,
|
|
1222
|
+
max: 5,
|
|
1223
|
+
},
|
|
1224
|
+
},
|
|
1225
|
+
}
|
|
1226
|
+
```
|
|
1227
|
+
|
|
1228
|
+
#### 📌 Role Select Menu:
|
|
1229
|
+
|
|
1230
|
+
```js
|
|
1231
|
+
{
|
|
1232
|
+
type: "menu",
|
|
1233
|
+
components: {
|
|
1234
|
+
type: "role",
|
|
1235
|
+
options: {
|
|
1236
|
+
id: "role_select",
|
|
1237
|
+
placeholder: "🎭 Select a role",
|
|
1238
|
+
min: 1,
|
|
1239
|
+
max: 1,
|
|
1240
|
+
},
|
|
1241
|
+
},
|
|
1242
|
+
}
|
|
1243
|
+
```
|
|
1244
|
+
|
|
1245
|
+
|
|
1246
|
+
#### 📌 Channel Select Menu:
|
|
1247
|
+
|
|
1248
|
+
```js
|
|
1249
|
+
{
|
|
1250
|
+
type: "menu",
|
|
1251
|
+
components: {
|
|
1252
|
+
type: "channel",
|
|
1253
|
+
options: {
|
|
1254
|
+
id: "channel_select",
|
|
1255
|
+
placeholder: "📢 Select a channel",
|
|
1256
|
+
min: 1,
|
|
1257
|
+
max: 1,
|
|
1258
|
+
},
|
|
1259
|
+
},
|
|
1260
|
+
}
|
|
1261
|
+
```
|
|
1262
|
+
|
|
1263
|
+
#### 📌 Channel Select with Type Filter:
|
|
1264
|
+
|
|
1265
|
+
```js
|
|
1266
|
+
const { ChannelType } = require("discord.js");
|
|
1267
|
+
|
|
1268
|
+
{
|
|
1269
|
+
type: "menu",
|
|
1270
|
+
components: {
|
|
1271
|
+
type: "channel",
|
|
1272
|
+
options: {
|
|
1273
|
+
id: "text_channel_select",
|
|
1274
|
+
placeholder: "💬 Select a text channel",
|
|
1275
|
+
channelTypes: [ChannelType.GuildText, ChannelType.GuildAnnouncement],
|
|
1276
|
+
},
|
|
1277
|
+
},
|
|
1278
|
+
}
|
|
1279
|
+
```
|
|
1280
|
+
|
|
1281
|
+
#### 📌 Menu with Default Values (User/Role/Channel):
|
|
1282
|
+
|
|
1283
|
+
```js
|
|
1284
|
+
{
|
|
1285
|
+
type: "menu",
|
|
1286
|
+
components: {
|
|
1287
|
+
type: "user",
|
|
1288
|
+
options: {
|
|
1289
|
+
id: "user_select_default",
|
|
1290
|
+
placeholder: "👤 Select users",
|
|
1291
|
+
min: 1,
|
|
1292
|
+
max: 3,
|
|
1293
|
+
defaultValues: [
|
|
1294
|
+
{ id: "123456789012345678", type: "user" },
|
|
1295
|
+
{ id: "987654321098765432", type: "user" },
|
|
1296
|
+
],
|
|
1297
|
+
},
|
|
1298
|
+
},
|
|
1299
|
+
}
|
|
1300
|
+
```
|
|
1301
|
+
|
|
1302
|
+
</details>
|
|
1303
|
+
|
|
1304
|
+
---
|
|
1305
|
+
|
|
1306
|
+
<details>
|
|
1307
|
+
<summary>📦 Section Component Examples</summary>
|
|
1308
|
+
|
|
1309
|
+
|
|
1310
|
+
#### 📌 Section with Thumbnail (Product):
|
|
1311
|
+
|
|
1312
|
+
```js
|
|
1313
|
+
{
|
|
1314
|
+
type: "section",
|
|
1315
|
+
content: "🛒 **iPhone 15 Pro**\n💰 Price: $999\n⭐ Rating: 4.8/5\n📦 In Stock: Yes",
|
|
1316
|
+
accessory: {
|
|
1317
|
+
type: "thumbnail",
|
|
1318
|
+
url: "https://example.com/iphone.png",
|
|
1319
|
+
description: "iPhone 15 Pro Image",
|
|
1320
|
+
},
|
|
1321
|
+
}
|
|
1322
|
+
```
|
|
1323
|
+
|
|
1324
|
+
#### 📌 Section with Button :
|
|
1325
|
+
|
|
1326
|
+
```js
|
|
1327
|
+
{
|
|
1328
|
+
type: "section",
|
|
1329
|
+
content: "🎁 **Daily Reward**\nClick to claim your daily reward!\n💎 **+100 Coins**",
|
|
1330
|
+
accessory: {
|
|
1331
|
+
type: "button",
|
|
1332
|
+
id: "claim_daily",
|
|
1333
|
+
style: 3,
|
|
1334
|
+
label: "Claim",
|
|
1335
|
+
emoji: "🎁",
|
|
1336
|
+
},
|
|
1337
|
+
}
|
|
1338
|
+
```
|
|
1339
|
+
|
|
1340
|
+
|
|
1341
|
+
|
|
1342
|
+
|
|
1343
|
+
</details>
|
|
1344
|
+
|
|
1345
|
+
---
|
|
1346
|
+
|
|
1347
|
+
|
|
1348
|
+
### 📖 Component Types Explanation
|
|
1349
|
+
|
|
1350
|
+
#### 🔹 Text
|
|
1351
|
+
|
|
1352
|
+
- `type` → `"text"`
|
|
1353
|
+
- `content` → The text content to display (supports Markdown)
|
|
1354
|
+
|
|
1355
|
+
#### 🔹 Separator
|
|
1356
|
+
|
|
1357
|
+
- `type` → `"separator"`
|
|
1358
|
+
- `divider` → Show a dividing line (true/false)
|
|
1359
|
+
- `spacing` → Spacing size (1: Small, 2: Large)
|
|
1360
|
+
|
|
1361
|
+
#### 🔹 Media Gallery
|
|
1362
|
+
|
|
1363
|
+
- `type` → `"media"`
|
|
1364
|
+
- `links` → Array of image URLs or objects with:
|
|
1365
|
+
- `url` → Image URL
|
|
1366
|
+
- `description` → Alt text for the image
|
|
1367
|
+
- `spoiler` → Hide behind spoiler (true/false)
|
|
1368
|
+
|
|
1369
|
+
#### 🔹 File
|
|
1370
|
+
|
|
1371
|
+
- `type` → `"file"`
|
|
1372
|
+
- `url` → File URL or attachment reference
|
|
1373
|
+
- `spoiler` → Hide behind spoiler (true/false)
|
|
1374
|
+
|
|
1375
|
+
#### 🔹 Button
|
|
1376
|
+
|
|
1377
|
+
- `type` → `"button"`
|
|
1378
|
+
- `components` → Array of button objects:
|
|
1379
|
+
- `id` → customId (required for non-link buttons)
|
|
1380
|
+
- `style` → 1: Primary, 2: Secondary, 3: Success, 4: Danger, 5: Link
|
|
1381
|
+
- `label` → Button text
|
|
1382
|
+
- `emoji` → Button emoji
|
|
1383
|
+
- `disabled` → Disable button (true/false)
|
|
1384
|
+
- `url` → URL for link buttons (style: 5)
|
|
1385
|
+
|
|
1386
|
+
#### 🔹 Menu
|
|
1387
|
+
|
|
1388
|
+
- `type` → `"menu"`
|
|
1389
|
+
- `components` → Object containing:
|
|
1390
|
+
- `type` → `"string" | "user" | "role" | "channel"`
|
|
1391
|
+
- `options` → Menu configuration:
|
|
1392
|
+
- `id` → customId
|
|
1393
|
+
- `placeholder` → Placeholder text
|
|
1394
|
+
- `min` / `max` → Min/Max selectable values
|
|
1395
|
+
- `data` → Options array (for string select)
|
|
1396
|
+
- `label` → Key in data for label
|
|
1397
|
+
- `value` → Key in data for value
|
|
1398
|
+
- `emoji` → Key in data for emoji
|
|
1399
|
+
- `description` → Key in data for description
|
|
1400
|
+
- `channelTypes` → Channel types filter (for channel menu)
|
|
1401
|
+
- `defaultValues` → Pre-selected values
|
|
1402
|
+
|
|
1403
|
+
#### 🔹 Section
|
|
1404
|
+
|
|
1405
|
+
- `type` → `"section"`
|
|
1406
|
+
- `content` → Text content for the section
|
|
1407
|
+
- `accessory` → Side component:
|
|
1408
|
+
- **Button Accessory:**
|
|
1409
|
+
- `type` → `"button"`
|
|
1410
|
+
- `id` → customId
|
|
1411
|
+
- `style` → Button style
|
|
1412
|
+
- `label` → Button text
|
|
1413
|
+
- `emoji` → Button emoji
|
|
1414
|
+
- `url` → URL (for link buttons)
|
|
1415
|
+
- **Thumbnail Accessory:**
|
|
1416
|
+
- `type` → `"thumbnail"`
|
|
1417
|
+
- `url` → Image URL
|
|
1418
|
+
- `description` → Image description
|
|
1419
|
+
|
|
1420
|
+
---
|
|
1421
|
+
|
|
1422
|
+
### 🔹 Mode Differences
|
|
1423
|
+
|
|
1424
|
+
| Feature | `"array"` Mode | `"container"` Mode |
|
|
1425
|
+
| ---------------- | ----------------------- | ------------------------- |
|
|
1426
|
+
| Return Type | Array of components | Single ContainerBuilder |
|
|
1427
|
+
| Usage | Standard messages | Components V2 messages |
|
|
1428
|
+
| Sections Support | ✅ | ✅ |
|
|
1429
|
+
| Grouping | Individual components | All grouped in container |
|
|
1430
|
+
| Flags Required | ❌ | ✅ (flags: 32768) |
|
|
1431
|
+
|
|
1432
|
+
---
|
|
1433
|
+
|
|
1434
|
+
### 🔹 Notes
|
|
1435
|
+
|
|
1436
|
+
- Use `"container"` mode for Discord's **Components V2** (newer UI)
|
|
1437
|
+
- Use `"array"` mode for standard component arrays
|
|
1438
|
+
- Sections can have either a **button** or **thumbnail** as accessory, not both
|
|
1439
|
+
- Media galleries support multiple images in a single component
|
|
1440
|
+
- All components are fully customizable 🎨
|
|
1441
|
+
|
|
1442
|
+
</details>
|
|
1443
|
+
|
|
1444
|
+
---
|
|
1445
|
+
|
|
395
1446
|
<details>
|
|
396
1447
|
<summary>Wait ⏰</summary>
|
|
397
1448
|
|