Skip to content

Commit 0ac6264

Browse files
authored
Merge pull request #171 from ghostdevv/buttons
2 parents 09324a0 + 4843e8f commit 0ac6264

File tree

17 files changed

+430
-3
lines changed

17 files changed

+430
-3
lines changed

.changeset/nice-pears-attack.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'jellycommands': minor
3+
---
4+
5+
support buttons

dev/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "dev",
33
"type": "module",
4-
"main": "index.js",
4+
"main": "src/index.js",
55
"version": "0.0.1-next.1",
66
"private": true,
77
"scripts": {

dev/src/buttons/test.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { button } from 'jellycommands';
2+
3+
export default button({
4+
id: 'test',
5+
6+
async run({ interaction }) {
7+
interaction.reply({
8+
content: 'Hello World',
9+
});
10+
},
11+
});
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { ButtonBuilder, ActionRowBuilder, ButtonStyle } from 'discord.js';
2+
import { command } from 'jellycommands';
3+
4+
export default command({
5+
name: 'testbutton',
6+
description: 'Test the buttons',
7+
8+
global: true,
9+
defer: true,
10+
11+
async run({ interaction }) {
12+
const row = new ActionRowBuilder().addComponents(
13+
new ButtonBuilder().setCustomId('test').setLabel('test').setStyle(ButtonStyle.Primary),
14+
);
15+
16+
interaction.followUp({
17+
content: 'Test Buttons',
18+
components: [
19+
// @ts-ignore
20+
row,
21+
],
22+
});
23+
},
24+
});

dev/src/index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ if (typeof testGuild !== 'string') {
1212

1313
const client = new JellyCommands({
1414
// For testing loading commands by importing we have a file-loaded dir for each
15-
commands: [pog, 'commands/file-loaded'],
16-
events: [ready, 'events/file-loaded'],
15+
commands: [pog, 'src/commands/file-loaded'],
16+
events: [ready, 'src/events/file-loaded'],
17+
buttons: 'src/buttons',
1718

1819
clientOptions: {
1920
intents: [IntentsBitField.Flags.Guilds, IntentsBitField.Flags.GuildMessages],

docs/.vitepress/config.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ export default defineConfig({
5858
text: 'Events',
5959
link: '/api/events',
6060
},
61+
{
62+
text: 'Buttons',
63+
link: '/api/buttons',
64+
},
6165
{
6266
text: 'App Types',
6367
link: '/api/types',
@@ -135,6 +139,19 @@ export default defineConfig({
135139
},
136140
],
137141
},
142+
{
143+
text: 'Buttons',
144+
items: [
145+
{
146+
text: 'Loading Buttons',
147+
link: '/guide/buttons/loading',
148+
},
149+
{
150+
text: 'Creating Buttons',
151+
link: '/guide/buttons/files',
152+
},
153+
],
154+
},
138155
{
139156
text: 'Migrate',
140157
items: [

docs/api/buttons.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Buttons
2+
3+
## Loading
4+
5+
- API: [/api/client#buttons](/api/client#buttons)
6+
- Guide: [/guide/buttons](/guide/buttons/loading)
7+
8+
## Button File
9+
10+
A button file uses the `button` helper function and exports it on the default export. For example:
11+
12+
```js
13+
import { button } from 'jellycommands';
14+
15+
export default button({
16+
id: 'hello',
17+
18+
run: async ({ interaction }) => {
19+
await interaction.reply({
20+
content: 'Hello there!'
21+
})
22+
}
23+
})
24+
```
25+
26+
## Options
27+
28+
### id
29+
30+
- Type: `string | RegExp | Awaitable<() => boolean>`
31+
32+
The `customId` of the button, or a regex/function to match the id to.
33+
34+
### run
35+
36+
- Type: `Function`
37+
- Guide: [/guide/buttons/files#run-function](/guide/buttons/files#run-function)
38+
- Required
39+
40+
The main handler for the button
41+
42+
### defer
43+
44+
- Type: `boolean | InteractionDeferReplyOptions`
45+
46+
Should the interaction be defered
47+
48+
### disabled
49+
50+
- Type: `boolean`
51+
52+
When true JellyCommands will ignore this button.
53+
54+
:::tip NOTE
55+
When using file-loaded commands, you can get the same behavior by adding an `_` in front of the file.
56+
:::

docs/api/client.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ Passing a string will automatically load commands from that directory, otherwise
3535

3636
Passing a `string` will automatically load events from that directory. Otherwise, you can manually import your events and pass them in as an `array`. Files prefixed with `_` are ignored.
3737

38+
### buttons
39+
40+
- Type: `string | Array<string | Button>`
41+
- Guide: [/guide/buttons](/guide/buttons/loading)
42+
43+
Passing a `string` will automatically load buttons from that directory. Otherwise, you can manually import your events and pass them in as an `array`. Files prefixed with `_` are ignored.
44+
3845
### clientOptions
3946

4047
- Type: [`ClientOptions`](https://discord.js.org/#/docs/discord.js/main/typedef/ClientOptions)

docs/guide/buttons/files.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Creating Buttons
2+
3+
`Button` files contain a **button handler**. They aren't responsible for adding buttons to messages but are a way of running code when the buttons you made are pressed.
4+
5+
```js
6+
import { button } from 'jellycommands';
7+
8+
export default button({
9+
id: 'test',
10+
11+
run: () => {
12+
// Do something with button click
13+
}
14+
})
15+
```
16+
17+
[You can view a list of all the button options here](/api/buttons#options)
18+
19+
:::tip TIP
20+
If you are unsure how to add buttons to messages, checkout the [Discord.js Guide](https://discordjs.guide/interactions/buttons.html)
21+
:::
22+
23+
## Button `id`
24+
25+
The `id` field on the button is important, it can be a `string`, `regexp`, or a function. The `id` field corresponds to the `customId` feild you set when you create a button.
26+
27+
### Simple ids
28+
29+
The simplest form is a plain string, for example you could have an id of `hello`. This might be a button that does the same thing each time.
30+
31+
```js
32+
import { button } from 'jellycommands';
33+
34+
export default button({
35+
id: 'hello',
36+
37+
run: async ({ interaction }) => {
38+
await interaction.reply({
39+
content: 'Hello there!'
40+
})
41+
}
42+
})
43+
```
44+
45+
### Regex & Function ids
46+
47+
If the id is not the same each time. As an example, say you have a button that should respond with a fruit name. Your id might look like `fruit_[FRUIT NAME]`, we can impliment this with regex or a function. The function should always return `true` or `false`
48+
49+
```js
50+
import { button } from 'jellycommands';
51+
52+
export default button({
53+
// a regex id
54+
id: /fruit_([\w])+/,
55+
56+
// a function id
57+
id: (id) => {
58+
return id.startsWith('fruit_');
59+
},
60+
61+
run: async ({ interaction }) => {
62+
const fruit = interaction.customId.replace('fruit_', '');
63+
64+
await interaction.reply({
65+
content: `Your fruit is ${fruit}`
66+
})
67+
}
68+
})
69+
```
70+
71+
## Button `run` handler
72+
73+
When an `event` is invoked, the event's `run` function is called. This is where your custom event logic lives.
74+
75+
When a button is clicked, the `run` function is called. This is where your custom logic for the button lives.
76+
77+
You are provided with [`context`](/guide/buttons/files.html#context), which allows you to get things such as the `interaction`.
78+
79+
### Context
80+
81+
The context object has the following properties:
82+
83+
### interaction [`ButtonInteraction`](https://discord.js.org/#/docs/discord.js/main/class/ButtonInteraction)
84+
85+
The button interaction from discord.js
86+
87+
#### client [`JellyCommands`](/api/client)
88+
89+
The client used by the command.
90+
91+
#### props [`Props`](/api/props)
92+
93+
Your project's props.

docs/guide/buttons/loading.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Loading Buttons
2+
3+
JellyCommands can load `buttons` both automatically and manually. Usually we recommend loading them automatically for the best Developer Expierence.
4+
5+
## Automatic Loading
6+
7+
To automatically load `buttons` from your file system, you can specify the path to your `buttons` folder with the [buttons option](/api/client#buttons).
8+
9+
```js
10+
const client = new JellyCommands({
11+
buttons: 'src/buttons' // Loads all buttons in src/buttons
12+
})
13+
```
14+
15+
Multiple directories can be specified with an array.
16+
17+
```js
18+
const client = new JellyCommands({
19+
buttons: ['src/buttons', 'src/otherbuttons']
20+
})
21+
```
22+
23+
:::tip NOTE
24+
`JellyCommands` loads directories recursively, so you only need to specify the top-level directory.
25+
26+
For example, if your `buttons` folder is set to `src/buttons`, files in `src/buttons/something/` will also be loaded.
27+
:::
28+
29+
## Manual Loading
30+
31+
If you prefer to import your `buttons` manually, you can pass them in directly to the [buttons option](/api/client#buttons).
32+
33+
```js
34+
import SomeButton from '.'
35+
36+
const client = new JellyCommands({
37+
buttons: [
38+
SomeButton
39+
]
40+
})
41+
```
42+
43+
## Combined
44+
45+
Automatic and manual loading can be combined freely.
46+
47+
```js
48+
import SomeButton from '.'
49+
50+
const client = new JellyCommands({
51+
commands: [
52+
SomeButton,
53+
'src/buttons'
54+
]
55+
})
56+
```

0 commit comments

Comments
 (0)