Overview
Component types define the structure of interactive elements like buttons, select menus, and other UI components.
ComponentJson
Base type for all component objects.
type ComponentJson = {
type: number
[key: string]: JsonValue
}
All components must have a type field corresponding to Discord’s component types.
ComponentLike
Union type accepting either a builder or a plain JSON object.
type ComponentLike = ComponentBuilder | ComponentJson
Used in methods that accept components in either format.
ComponentBuilder
Interface for component builders.
type ComponentBuilder = {
toJSON: () => ComponentJson
}
All builder classes implement this interface, allowing them to be converted to JSON.
ComponentType
Enum of Discord component type constants.
const ComponentType = {
ActionRow: 1,
Button: 2,
StringSelect: 3,
InputText: 4,
UserSelect: 5,
RoleSelect: 6,
MentionableSelect: 7,
ChannelSelect: 8,
Section: 9,
TextDisplay: 10,
Thumbnail: 11,
MediaGallery: 12,
File: 13,
Separator: 14,
Container: 17,
Label: 18,
FileUpload: 19
} as const
Example
const buttonJson: ComponentJson = {
type: ComponentType.Button,
style: 1,
label: 'Click me',
custom_id: 'my_button'
}
Enum of button style constants.
const ButtonStyle = {
Primary: 1, // Blue (blurple)
Secondary: 2, // Gray
Success: 3, // Green
Danger: 4 // Red
} as const
type ButtonStyle = 1 | 2 | 3 | 4
Example
import { ButtonStyles } from 'flora'
const btn = button()
.setStyle(ButtonStyles.Primary)
.setLabel('Confirm')
.toJSON()
InputTextStyle
Enum of text input style constants.
const InputTextStyle = {
Short: 1, // Single line
Paragraph: 2 // Multi-line
} as const
type InputTextStyle = 1 | 2
Example
import { InputTextStyles } from 'flora'
const input = inputText('feedback')
.setStyle(InputTextStyles.Paragraph)
.setPlaceholder('Enter your feedback...')
.toJSON()
SelectOption
Option for string select menus.
type SelectOption = {
label: string
value: string
description?: string
emoji?: JsonValue
default?: boolean
}
Properties
The value sent when selected (not shown to users)
Additional description text
Emoji to display (string for unicode, object for custom)
Whether this option is selected by default
Example
const options: SelectOption[] = [
{
label: 'Red Team',
value: 'team_red',
description: 'Join the red team',
emoji: '❤️',
default: false
},
{
label: 'Blue Team',
value: 'team_blue',
description: 'Join the blue team',
emoji: '💙'
}
]
const select = stringSelect('team_select')
.setOptions(options)
.toJSON()
SelectDefaultValue
Default value for auto-populated selects.
type SelectDefaultValue = {
id: string
type: 'user' | 'role' | 'channel'
}
Properties
Snowflake ID of the default entity
type
'user' | 'role' | 'channel'
required
Type of entity being selected
Example
const userSelectMenu = userSelect('choose_user')
.setDefaultValues([
{ id: '123456789', type: 'user' },
{ id: '987654321', type: 'user' }
])
.toJSON()
MediaItemEntry
Entry for media gallery items.
type MediaItemEntry = {
media: { url: string }
description?: string
spoiler?: boolean
}
Properties
Media object containing the image/video URL
Whether to mark as spoiler
Example
const items: MediaItemEntry[] = [
{
media: { url: 'https://example.com/image1.png' },
description: 'First image'
},
{
media: { url: 'https://example.com/image2.png' },
spoiler: true
}
]
const gallery = mediaGallery()
.setItems(items)
.toJSON()
MessageReplyOptions
Options for replying to messages or interactions.
type MessageReplyOptions = {
content?: string
embeds?: RawEmbed[]
attachments?: RawAttachment[]
components?: JsonValue[]
tts?: boolean
allowedMentions?: RawAllowedMentions
replyTo?: string | null
ephemeral?: boolean
flags?: number
}
Properties
Interactive components (buttons, select menus)
Whether to use text-to-speech
Control which mentions are allowed
Message ID to reply to (null to not reply)
Only for interactions: make the response visible only to the user
Example
await ctx.reply({
content: 'Choose an option:',
embeds: [myEmbed],
components: [actionRow],
ephemeral: true
})
MessageEditOptions
Options for editing messages.
type MessageEditOptions = {
content?: string
embeds?: RawEmbed[]
components?: JsonValue[]
allowedMentions?: RawAllowedMentions
flags?: number
}
Similar to MessageReplyOptions but without reply-specific fields.
Example
await ctx.edit({
content: 'Updated message',
embeds: [updatedEmbed],
components: []
})
Builder Classes
All builder classes follow a common pattern:
- Chainable setter methods (return
this)
toJSON() method to convert to ComponentJson
- Type-safe parameters
Example Builder Pattern
const component = builder()
.setProperty1(value1) // Returns this
.setProperty2(value2) // Returns this
.setProperty3(value3) // Returns this
.toJSON() // Returns ComponentJson
Notes
- Always call
.toJSON() on builders before passing to messages
- Component types are Discord-defined numeric constants
- Maximum 5 action rows per message
- Maximum 5 buttons or 1 select menu per action row
- Use
ComponentType constants instead of magic numbers
- Builders provide type safety and validation