move stuff around
This commit is contained in:
62
library/core/components/button.tsx
Normal file
62
library/core/components/button.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import { nanoid } from "nanoid"
|
||||
import React from "react"
|
||||
import { last } from "../../../helpers/last.js"
|
||||
import { ReacordElement } from "../../internal/element.js"
|
||||
import type { ComponentInteraction } from "../../internal/interaction"
|
||||
import type { MessageOptions } from "../../internal/message"
|
||||
import { Node } from "../../internal/node.js"
|
||||
|
||||
export type ButtonProps = {
|
||||
label?: string
|
||||
style?: "primary" | "secondary" | "success" | "danger"
|
||||
disabled?: boolean
|
||||
emoji?: string
|
||||
onClick: (event: ButtonClickEvent) => void
|
||||
}
|
||||
|
||||
export type ButtonClickEvent = {}
|
||||
|
||||
export function Button(props: ButtonProps) {
|
||||
return (
|
||||
<ReacordElement props={props} createNode={() => new ButtonNode(props)} />
|
||||
)
|
||||
}
|
||||
|
||||
class ButtonNode extends Node<ButtonProps> {
|
||||
private customId = nanoid()
|
||||
|
||||
override modifyMessageOptions(options: MessageOptions): void {
|
||||
options.actionRows ??= []
|
||||
|
||||
let actionRow = last(options.actionRows)
|
||||
|
||||
if (
|
||||
actionRow == undefined ||
|
||||
actionRow.length >= 5 ||
|
||||
actionRow[0]?.type === "select"
|
||||
) {
|
||||
actionRow = []
|
||||
options.actionRows.push(actionRow)
|
||||
}
|
||||
|
||||
actionRow.push({
|
||||
type: "button",
|
||||
customId: this.customId,
|
||||
style: this.props.style ?? "secondary",
|
||||
disabled: this.props.disabled,
|
||||
emoji: this.props.emoji,
|
||||
label: this.props.label,
|
||||
})
|
||||
}
|
||||
|
||||
override handleComponentInteraction(interaction: ComponentInteraction) {
|
||||
if (
|
||||
interaction.type === "button" &&
|
||||
interaction.customId === this.customId
|
||||
) {
|
||||
this.props.onClick(interaction)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
30
library/core/components/embed-author.tsx
Normal file
30
library/core/components/embed-author.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import React from "react"
|
||||
import { ReacordElement } from "../../internal/element.js"
|
||||
import { EmbedChildNode } from "./embed-child.js"
|
||||
import type { EmbedOptions } from "./embed-options"
|
||||
|
||||
export type EmbedAuthorProps = {
|
||||
name?: string
|
||||
children?: string
|
||||
url?: string
|
||||
iconUrl?: string
|
||||
}
|
||||
|
||||
export function EmbedAuthor(props: EmbedAuthorProps) {
|
||||
return (
|
||||
<ReacordElement
|
||||
props={props}
|
||||
createNode={() => new EmbedAuthorNode(props)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
class EmbedAuthorNode extends EmbedChildNode<EmbedAuthorProps> {
|
||||
override modifyEmbedOptions(options: EmbedOptions): void {
|
||||
options.author = {
|
||||
name: this.props.name ?? this.props.children ?? "",
|
||||
url: this.props.url,
|
||||
icon_url: this.props.iconUrl,
|
||||
}
|
||||
}
|
||||
}
|
||||
6
library/core/components/embed-child.ts
Normal file
6
library/core/components/embed-child.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { Node } from "../../internal/node.js"
|
||||
import type { EmbedOptions } from "./embed-options"
|
||||
|
||||
export abstract class EmbedChildNode<Props> extends Node<Props> {
|
||||
abstract modifyEmbedOptions(options: EmbedOptions): void
|
||||
}
|
||||
31
library/core/components/embed-field.tsx
Normal file
31
library/core/components/embed-field.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import React from "react"
|
||||
import { ReacordElement } from "../../internal/element.js"
|
||||
import { EmbedChildNode } from "./embed-child.js"
|
||||
import type { EmbedOptions } from "./embed-options"
|
||||
|
||||
export type EmbedFieldProps = {
|
||||
name: string
|
||||
value?: string
|
||||
inline?: boolean
|
||||
children?: string
|
||||
}
|
||||
|
||||
export function EmbedField(props: EmbedFieldProps) {
|
||||
return (
|
||||
<ReacordElement
|
||||
props={props}
|
||||
createNode={() => new EmbedFieldNode(props)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
class EmbedFieldNode extends EmbedChildNode<EmbedFieldProps> {
|
||||
override modifyEmbedOptions(options: EmbedOptions): void {
|
||||
options.fields ??= []
|
||||
options.fields.push({
|
||||
name: this.props.name,
|
||||
value: this.props.value ?? this.props.children ?? "",
|
||||
inline: this.props.inline,
|
||||
})
|
||||
}
|
||||
}
|
||||
32
library/core/components/embed-footer.tsx
Normal file
32
library/core/components/embed-footer.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import React from "react"
|
||||
import { ReacordElement } from "../../internal/element.js"
|
||||
import { EmbedChildNode } from "./embed-child.js"
|
||||
import type { EmbedOptions } from "./embed-options"
|
||||
|
||||
export type EmbedFooterProps = {
|
||||
text?: string
|
||||
children?: string
|
||||
iconUrl?: string
|
||||
timestamp?: string | number | Date
|
||||
}
|
||||
|
||||
export function EmbedFooter(props: EmbedFooterProps) {
|
||||
return (
|
||||
<ReacordElement
|
||||
props={props}
|
||||
createNode={() => new EmbedFooterNode(props)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
class EmbedFooterNode extends EmbedChildNode<EmbedFooterProps> {
|
||||
override modifyEmbedOptions(options: EmbedOptions): void {
|
||||
options.footer = {
|
||||
text: this.props.text ?? this.props.children ?? "",
|
||||
icon_url: this.props.iconUrl,
|
||||
}
|
||||
options.timestamp = this.props.timestamp
|
||||
? new Date(this.props.timestamp).toISOString()
|
||||
: undefined
|
||||
}
|
||||
}
|
||||
23
library/core/components/embed-image.tsx
Normal file
23
library/core/components/embed-image.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import React from "react"
|
||||
import { ReacordElement } from "../../internal/element.js"
|
||||
import { EmbedChildNode } from "./embed-child.js"
|
||||
import type { EmbedOptions } from "./embed-options"
|
||||
|
||||
export type EmbedImageProps = {
|
||||
url: string
|
||||
}
|
||||
|
||||
export function EmbedImage(props: EmbedImageProps) {
|
||||
return (
|
||||
<ReacordElement
|
||||
props={props}
|
||||
createNode={() => new EmbedImageNode(props)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
class EmbedImageNode extends EmbedChildNode<EmbedImageProps> {
|
||||
override modifyEmbedOptions(options: EmbedOptions): void {
|
||||
options.image = { url: this.props.url }
|
||||
}
|
||||
}
|
||||
8
library/core/components/embed-options.ts
Normal file
8
library/core/components/embed-options.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import type { Except, SnakeCasedPropertiesDeep } from "type-fest"
|
||||
import type { EmbedProps } from "./embed"
|
||||
|
||||
export type EmbedOptions = SnakeCasedPropertiesDeep<
|
||||
Except<EmbedProps, "timestamp" | "children"> & {
|
||||
timestamp?: string
|
||||
}
|
||||
>
|
||||
23
library/core/components/embed-thumbnail.tsx
Normal file
23
library/core/components/embed-thumbnail.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import React from "react"
|
||||
import { ReacordElement } from "../../internal/element.js"
|
||||
import { EmbedChildNode } from "./embed-child.js"
|
||||
import type { EmbedOptions } from "./embed-options"
|
||||
|
||||
export type EmbedThumbnailProps = {
|
||||
url: string
|
||||
}
|
||||
|
||||
export function EmbedThumbnail(props: EmbedThumbnailProps) {
|
||||
return (
|
||||
<ReacordElement
|
||||
props={props}
|
||||
createNode={() => new EmbedThumbnailNode(props)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
class EmbedThumbnailNode extends EmbedChildNode<EmbedThumbnailProps> {
|
||||
override modifyEmbedOptions(options: EmbedOptions): void {
|
||||
options.thumbnail = { url: this.props.url }
|
||||
}
|
||||
}
|
||||
25
library/core/components/embed-title.tsx
Normal file
25
library/core/components/embed-title.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import React from "react"
|
||||
import { ReacordElement } from "../../internal/element.js"
|
||||
import { EmbedChildNode } from "./embed-child.js"
|
||||
import type { EmbedOptions } from "./embed-options"
|
||||
|
||||
export type EmbedTitleProps = {
|
||||
children: string
|
||||
url?: string
|
||||
}
|
||||
|
||||
export function EmbedTitle(props: EmbedTitleProps) {
|
||||
return (
|
||||
<ReacordElement
|
||||
props={props}
|
||||
createNode={() => new EmbedTitleNode(props)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
class EmbedTitleNode extends EmbedChildNode<EmbedTitleProps> {
|
||||
override modifyEmbedOptions(options: EmbedOptions): void {
|
||||
options.title = this.props.children
|
||||
options.url = this.props.url
|
||||
}
|
||||
}
|
||||
50
library/core/components/embed.tsx
Normal file
50
library/core/components/embed.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
import React from "react"
|
||||
import { snakeCaseDeep } from "../../../helpers/convert-object-property-case"
|
||||
import { omit } from "../../../helpers/omit"
|
||||
import { ReacordElement } from "../../internal/element.js"
|
||||
import type { MessageOptions } from "../../internal/message"
|
||||
import { Node } from "../../internal/node.js"
|
||||
import { EmbedChildNode } from "./embed-child.js"
|
||||
import type { EmbedOptions } from "./embed-options"
|
||||
|
||||
export type EmbedProps = {
|
||||
title?: string
|
||||
description?: string
|
||||
url?: string
|
||||
color?: number
|
||||
fields?: Array<{ name: string; value: string; inline?: boolean }>
|
||||
author?: { name: string; url?: string; iconUrl?: string }
|
||||
thumbnail?: { url: string }
|
||||
image?: { url: string }
|
||||
video?: { url: string }
|
||||
footer?: { text: string; iconUrl?: string }
|
||||
timestamp?: string | number | Date
|
||||
children?: React.ReactNode
|
||||
}
|
||||
|
||||
export function Embed(props: EmbedProps) {
|
||||
return (
|
||||
<ReacordElement props={props} createNode={() => new EmbedNode(props)}>
|
||||
{props.children}
|
||||
</ReacordElement>
|
||||
)
|
||||
}
|
||||
|
||||
class EmbedNode extends Node<EmbedProps> {
|
||||
override modifyMessageOptions(options: MessageOptions): void {
|
||||
const embed: EmbedOptions = {
|
||||
...snakeCaseDeep(omit(this.props, ["children", "timestamp"])),
|
||||
timestamp: this.props.timestamp
|
||||
? new Date(this.props.timestamp).toISOString()
|
||||
: undefined,
|
||||
}
|
||||
|
||||
for (const child of this.children) {
|
||||
if (child instanceof EmbedChildNode) {
|
||||
child.modifyEmbedOptions(embed)
|
||||
}
|
||||
}
|
||||
|
||||
options.embeds.push(embed)
|
||||
}
|
||||
}
|
||||
40
library/core/components/link.tsx
Normal file
40
library/core/components/link.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import React from "react"
|
||||
import { last } from "../../../helpers/last.js"
|
||||
import { ReacordElement } from "../../internal/element.js"
|
||||
import type { MessageOptions } from "../../internal/message"
|
||||
import { Node } from "../../internal/node.js"
|
||||
|
||||
export type LinkProps = {
|
||||
label?: string
|
||||
children?: string
|
||||
emoji?: string
|
||||
disabled?: boolean
|
||||
url: string
|
||||
}
|
||||
|
||||
export function Link(props: LinkProps) {
|
||||
return <ReacordElement props={props} createNode={() => new LinkNode(props)} />
|
||||
}
|
||||
|
||||
class LinkNode extends Node<LinkProps> {
|
||||
override modifyMessageOptions(options: MessageOptions): void {
|
||||
let actionRow = last(options.actionRows)
|
||||
|
||||
if (
|
||||
actionRow == undefined ||
|
||||
actionRow.length >= 5 ||
|
||||
actionRow[0]?.type === "select"
|
||||
) {
|
||||
actionRow = []
|
||||
options.actionRows.push(actionRow)
|
||||
}
|
||||
|
||||
actionRow.push({
|
||||
type: "link",
|
||||
disabled: this.props.disabled,
|
||||
emoji: this.props.emoji,
|
||||
label: this.props.label || this.props.children,
|
||||
url: this.props.url,
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user