@@ -8,11 +8,18 @@ import {
88 ButtonBuilder ,
99 ButtonStyle ,
1010 type AnyComponentBuilder ,
11- type RestOrArray
11+ type RestOrArray ,
12+ StringSelectMenuBuilder ,
13+ UserSelectMenuBuilder ,
14+ ChannelSelectMenuBuilder ,
15+ RoleSelectMenuBuilder ,
16+ StringSelectMenuOptionBuilder ,
17+ MentionableSelectMenuBuilder
1218} from 'discord.js'
1319import type { Stream } from 'node:stream'
1420import type {
1521 ButtonOptions ,
22+ ChannelSelectMenuOptions ,
1623 CommandConfig ,
1724 CommandExecute ,
1825 ContextMenuCallback ,
@@ -32,10 +39,16 @@ import type {
3239 HarmonixContextMenu ,
3340 HarmonixEvent ,
3441 HarmonixEvents ,
42+ MentionableSelectMenuOptions ,
3543 ModalOptions ,
3644 OptionsDef ,
37- PreconditionCallback
45+ PreconditionCallback ,
46+ RoleSelectMenuOptions ,
47+ SelectMenuOptions ,
48+ StringSelectMenuOptions ,
49+ UserSelectMenuOptions
3850} from './types'
51+ import { createError } from './harmonix'
3952
4053export const defineHarmonixConfig = ( config : HarmonixConfig ) => {
4154 return config
@@ -221,3 +234,134 @@ export const defineButton = (options: ButtonOptions) => {
221234
222235 return builder
223236}
237+
238+ export const defineSelectMenu = ( options : SelectMenuOptions ) => {
239+ const { id, placeholder, type, disabled, minValues, maxValues } = options
240+
241+ switch ( type ) {
242+ case 'String' : {
243+ const stringOptions = options as StringSelectMenuOptions
244+ const selectMenu = new StringSelectMenuBuilder ( )
245+ . setCustomId ( id )
246+ . setPlaceholder ( placeholder )
247+
248+ if ( disabled ) {
249+ selectMenu . setDisabled ( disabled )
250+ }
251+ if ( minValues ) {
252+ selectMenu . setMinValues ( minValues )
253+ }
254+ if ( maxValues ) {
255+ selectMenu . setMaxValues ( maxValues )
256+ }
257+ stringOptions . options . forEach ( ( option ) => {
258+ const optionBuilder = new StringSelectMenuOptionBuilder ( )
259+ . setLabel ( option . label )
260+ . setValue ( option . value )
261+
262+ if ( option . description ) {
263+ optionBuilder . setDescription ( option . description )
264+ }
265+ if ( option . emoji ) {
266+ optionBuilder . setEmoji ( option . emoji )
267+ }
268+ if ( option . default ) {
269+ optionBuilder . setDefault ( true )
270+ }
271+
272+ selectMenu . addOptions ( optionBuilder )
273+ } )
274+
275+ return selectMenu
276+ }
277+ case 'User' : {
278+ const userOptions = options as UserSelectMenuOptions
279+ const selectMenu = new UserSelectMenuBuilder ( )
280+ . setCustomId ( id )
281+ . setPlaceholder ( placeholder )
282+
283+ if ( disabled ) {
284+ selectMenu . setDisabled ( disabled )
285+ }
286+ if ( minValues ) {
287+ selectMenu . setMinValues ( minValues )
288+ }
289+ if ( maxValues ) {
290+ selectMenu . setMaxValues ( maxValues )
291+ }
292+ if ( userOptions . defaultUsers ) {
293+ selectMenu . setDefaultUsers ( userOptions . defaultUsers )
294+ }
295+
296+ return selectMenu
297+ }
298+ case 'Channel' : {
299+ const channelOptions = options as ChannelSelectMenuOptions
300+ const selectMenu = new ChannelSelectMenuBuilder ( )
301+ . setCustomId ( id )
302+ . setPlaceholder ( placeholder )
303+
304+ if ( disabled ) {
305+ selectMenu . setDisabled ( disabled )
306+ }
307+ if ( minValues ) {
308+ selectMenu . setMinValues ( minValues )
309+ }
310+ if ( maxValues ) {
311+ selectMenu . setMaxValues ( maxValues )
312+ }
313+ if ( channelOptions . channelTypes ) {
314+ selectMenu . addChannelTypes ( ...channelOptions . channelTypes )
315+ }
316+ if ( channelOptions . defaultChannels ) {
317+ selectMenu . setDefaultChannels ( channelOptions . defaultChannels )
318+ }
319+
320+ return selectMenu
321+ }
322+ case 'Role' : {
323+ const roleOptions = options as RoleSelectMenuOptions
324+ const selectMenu = new RoleSelectMenuBuilder ( )
325+ . setCustomId ( id )
326+ . setPlaceholder ( placeholder )
327+
328+ if ( disabled ) {
329+ selectMenu . setDisabled ( disabled )
330+ }
331+ if ( minValues ) {
332+ selectMenu . setMinValues ( minValues )
333+ }
334+ if ( maxValues ) {
335+ selectMenu . setMaxValues ( maxValues )
336+ }
337+ if ( roleOptions . defaultRoles ) {
338+ selectMenu . setDefaultRoles ( roleOptions . defaultRoles )
339+ }
340+
341+ return selectMenu
342+ }
343+ case 'Mentionable' : {
344+ const mentionableOptions = options as MentionableSelectMenuOptions
345+ const selectMenu = new MentionableSelectMenuBuilder ( )
346+ . setCustomId ( id )
347+ . setPlaceholder ( placeholder )
348+
349+ if ( disabled ) {
350+ selectMenu . setDisabled ( disabled )
351+ }
352+ if ( minValues ) {
353+ selectMenu . setMinValues ( minValues )
354+ }
355+ if ( maxValues ) {
356+ selectMenu . setMaxValues ( maxValues )
357+ }
358+ if ( mentionableOptions . defaultValues ) {
359+ selectMenu . setDefaultValues ( mentionableOptions . defaultValues )
360+ }
361+
362+ return selectMenu
363+ }
364+ default :
365+ throw createError ( 'Invalid select menu type' )
366+ }
367+ }
0 commit comments