non-interactive buttons
This commit is contained in:
67
src/button.tsx
Normal file
67
src/button.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
import type {
|
||||
BaseMessageComponentOptions,
|
||||
EmojiResolvable,
|
||||
MessageActionRowOptions,
|
||||
MessageButtonStyle,
|
||||
MessageOptions,
|
||||
} from "discord.js"
|
||||
import { nanoid } from "nanoid"
|
||||
import React from "react"
|
||||
import { ContainerInstance } from "./container-instance.js"
|
||||
import { last } from "./helpers/last.js"
|
||||
import { pick } from "./helpers/pick.js"
|
||||
import { toUpper } from "./helpers/to-upper.js"
|
||||
|
||||
export type ButtonStyle = Exclude<Lowercase<MessageButtonStyle>, "link">
|
||||
|
||||
export type ButtonProps = {
|
||||
style?: ButtonStyle
|
||||
emoji?: EmojiResolvable
|
||||
disabled?: boolean
|
||||
children?: React.ReactNode
|
||||
}
|
||||
|
||||
export function Button(props: ButtonProps) {
|
||||
return (
|
||||
<reacord-element createInstance={() => new ButtonInstance(props)}>
|
||||
{props.children}
|
||||
</reacord-element>
|
||||
)
|
||||
}
|
||||
|
||||
class ButtonInstance extends ContainerInstance {
|
||||
readonly name = "Button"
|
||||
|
||||
constructor(private readonly props: ButtonProps) {
|
||||
super({ warnOnNonTextChildren: true })
|
||||
}
|
||||
|
||||
override renderToMessage(options: MessageOptions) {
|
||||
options.components ??= []
|
||||
|
||||
// i hate this
|
||||
let actionRow:
|
||||
| (Required<BaseMessageComponentOptions> & MessageActionRowOptions)
|
||||
| undefined = last(options.components)
|
||||
|
||||
if (
|
||||
!actionRow ||
|
||||
actionRow.components[0]?.type === "SELECT_MENU" ||
|
||||
actionRow.components.length >= 5
|
||||
) {
|
||||
actionRow = {
|
||||
type: "ACTION_ROW",
|
||||
components: [],
|
||||
}
|
||||
options.components.push(actionRow)
|
||||
}
|
||||
|
||||
actionRow.components.push({
|
||||
...pick(this.props, "emoji", "disabled"),
|
||||
type: "BUTTON",
|
||||
style: this.props.style ? toUpper(this.props.style) : "SECONDARY",
|
||||
label: this.getChildrenText(),
|
||||
customId: nanoid(),
|
||||
})
|
||||
}
|
||||
}
|
||||
3
src/helpers/last.ts
Normal file
3
src/helpers/last.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export function last<T>(array: T[]): T | undefined {
|
||||
return array[array.length - 1]
|
||||
}
|
||||
4
src/helpers/to-upper.ts
Normal file
4
src/helpers/to-upper.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
/** A typesafe version of toUpperCase */
|
||||
export function toUpper<S extends string>(string: S) {
|
||||
return string.toUpperCase() as Uppercase<S>
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from "./button"
|
||||
export * from "./embed"
|
||||
export * from "./embed-field"
|
||||
export * from "./root"
|
||||
|
||||
Reference in New Issue
Block a user