From 76bd0b0b98de18ebfa76cbb07d8a153d0beb4105 Mon Sep 17 00:00:00 2001 From: MapleLeaf <19603573+itsMapleLeaf@users.noreply.github.com> Date: Sun, 9 Jan 2022 20:31:31 -0600 Subject: [PATCH] add doc comments --- .../reacord/library/core/component-event.ts | 30 +++++++++++++ .../core/components/button-shared-props.ts | 22 ++++++++++ .../library/core/components/button.tsx | 15 +++++-- .../reacord/library/core/components/embed.tsx | 2 + .../reacord/library/core/components/link.tsx | 10 ++--- .../library/core/components/option.tsx | 19 +++++++- .../library/core/components/select.tsx | 44 +++++++++++++++++++ packages/reacord/library/core/instance.ts | 11 ++++- .../library/core/reacord-discord-js.ts | 12 +++-- packages/reacord/library/main.ts | 1 + packages/reacord/playground/counter.tsx | 1 + 11 files changed, 152 insertions(+), 15 deletions(-) create mode 100644 packages/reacord/library/core/components/button-shared-props.ts diff --git a/packages/reacord/library/core/component-event.ts b/packages/reacord/library/core/component-event.ts index 57dbefa..713f659 100644 --- a/packages/reacord/library/core/component-event.ts +++ b/packages/reacord/library/core/component-event.ts @@ -5,11 +5,41 @@ import type { ReacordInstance } from "./instance" * @category Component Event */ export type ComponentEvent = { + /** + * The message associated with this event. + * For example: with a button click, + * this is the message that the button is on. + * @see https://discord.com/developers/docs/resources/channel#message-object + */ message: MessageInfo + + /** + * The channel that this event occurred in. + * @see https://discord.com/developers/docs/resources/channel#channel-object + */ channel: ChannelInfo + + /** + * The user that triggered this event. + * @see https://discord.com/developers/docs/resources/user#user-object + */ user: UserInfo + + /** + * The guild that this event occurred in. + * @see https://discord.com/developers/docs/resources/guild#guild-object + */ guild?: GuildInfo + + /** + * Create a new reply to this event. + */ reply(content?: ReactNode): ReacordInstance + + /** + * Create an ephemeral reply to this event, + * shown only to the user who triggered it. + */ ephemeralReply(content?: ReactNode): ReacordInstance } diff --git a/packages/reacord/library/core/components/button-shared-props.ts b/packages/reacord/library/core/components/button-shared-props.ts new file mode 100644 index 0000000..3cef1a7 --- /dev/null +++ b/packages/reacord/library/core/components/button-shared-props.ts @@ -0,0 +1,22 @@ +/** + * Common props between button-like components + * @category Button + */ +export type ButtonSharedProps = { + /** The text on the button. Rich formatting (markdown) is not supported here. */ + label?: string + + /** When true, the button will be slightly faded, and cannot be clicked. */ + disabled?: boolean + + /** + * Renders an emoji to the left of the text. + * Has to be a literal emoji character (e.g. 🍍), + * or an emoji code, like `<:plus_one:778531744860602388>`. + * + * To get an emoji code, type your emoji in Discord chat + * with a backslash `\` in front. + * The bot has to be in the emoji's guild to use it. + */ + emoji?: string +} diff --git a/packages/reacord/library/core/components/button.tsx b/packages/reacord/library/core/components/button.tsx index cb9da88..02bf400 100644 --- a/packages/reacord/library/core/components/button.tsx +++ b/packages/reacord/library/core/components/button.tsx @@ -6,17 +6,24 @@ import type { MessageOptions } from "../../internal/message" import { getNextActionRow } from "../../internal/message" import { Node } from "../../internal/node.js" import type { ComponentEvent } from "../component-event" +import type { ButtonSharedProps } from "./button-shared-props" /** * @category Button */ -export type ButtonProps = { - label?: string +export type ButtonProps = ButtonSharedProps & { + /** + * The style determines the color of the button and signals intent. + * @see https://discord.com/developers/docs/interactions/message-components#button-object-button-styles + */ style?: "primary" | "secondary" | "success" | "danger" - disabled?: boolean - emoji?: string + + /** + * Happens when a user clicks the button. + */ onClick: (event: ButtonClickEvent) => void } + /** * @category Button */ diff --git a/packages/reacord/library/core/components/embed.tsx b/packages/reacord/library/core/components/embed.tsx index 473675c..cc78aab 100644 --- a/packages/reacord/library/core/components/embed.tsx +++ b/packages/reacord/library/core/components/embed.tsx @@ -10,6 +10,7 @@ import type { EmbedOptions } from "./embed-options" /** * @category Embed + * @see https://discord.com/developers/docs/resources/channel#embed-object */ export type EmbedProps = { title?: string @@ -28,6 +29,7 @@ export type EmbedProps = { /** * @category Embed + * @see https://discord.com/developers/docs/resources/channel#embed-object */ export function Embed(props: EmbedProps) { return ( diff --git a/packages/reacord/library/core/components/link.tsx b/packages/reacord/library/core/components/link.tsx index b43a680..d3315be 100644 --- a/packages/reacord/library/core/components/link.tsx +++ b/packages/reacord/library/core/components/link.tsx @@ -3,16 +3,16 @@ import { ReacordElement } from "../../internal/element.js" import type { MessageOptions } from "../../internal/message" import { getNextActionRow } from "../../internal/message" import { Node } from "../../internal/node.js" +import type { ButtonSharedProps } from "./button-shared-props" /** * @category Link */ -export type LinkProps = { - label?: string - children?: string - emoji?: string - disabled?: boolean +export type LinkProps = ButtonSharedProps & { + /** The URL the link should lead to */ url: string + /** The link text */ + children?: string } /** diff --git a/packages/reacord/library/core/components/option.tsx b/packages/reacord/library/core/components/option.tsx index 579cd52..e27088b 100644 --- a/packages/reacord/library/core/components/option.tsx +++ b/packages/reacord/library/core/components/option.tsx @@ -6,10 +6,25 @@ import { OptionNode } from "./option-node" * @category Select */ export type OptionProps = { - label?: string - children?: string + /** The internal value of this option */ value: string + /** The text shown to the user. This takes priority over `children` */ + label?: string + /** The text shown to the user */ + children?: string + /** Description for the option, shown to the user */ description?: string + + /** + * Renders an emoji to the left of the text. + * + * Has to be a literal emoji character (e.g. 🍍), + * or an emoji code, like `<:plus_one:778531744860602388>`. + * + * To get an emoji code, type your emoji in Discord chat + * with a backslash `\` in front. + * The bot has to be in the emoji's guild to use it. + */ emoji?: string } diff --git a/packages/reacord/library/core/components/select.tsx b/packages/reacord/library/core/components/select.tsx index 41ad14c..3519091 100644 --- a/packages/reacord/library/core/components/select.tsx +++ b/packages/reacord/library/core/components/select.tsx @@ -14,15 +14,54 @@ import { OptionNode } from "./option-node" */ export type SelectProps = { children?: ReactNode + /** Sets the currently selected value */ value?: string + + /** Sets the currently selected values, for use with `multiple` */ values?: string[] + + /** The text shown when no value is selected */ placeholder?: string + + /** Set to true to allow multiple selected values */ multiple?: boolean + + /** + * With `multiple`, the minimum number of values that can be selected. + * When `multiple` is false or not defined, this is always 1. + * + * This only limits the number of values that can be received by the user. + * This does not limit the number of values that can be displayed by you. + */ minValues?: number + + /** + * With `multiple`, the maximum number of values that can be selected. + * When `multiple` is false or not defined, this is always 1. + * + * This only limits the number of values that can be received by the user. + * This does not limit the number of values that can be displayed by you. + */ maxValues?: number + + /** When true, the select will be slightly faded, and cannot be interacted with. */ disabled?: boolean + + /** + * Called when the user inputs a selection. + * Receives the entire select change event, + * which can be used to create new replies, etc. + */ onChange?: (event: SelectChangeEvent) => void + + /** + * Convenience shorthand for `onChange`, which receives the first selected value. + */ onChangeValue?: (value: string, event: SelectChangeEvent) => void + + /** + * Convenience shorthand for `onChange`, which receives all selected values. + */ onChangeMultiple?: (values: string[], event: SelectChangeEvent) => void } @@ -34,6 +73,7 @@ export type SelectChangeEvent = ComponentEvent & { } /** + * See [the select menu guide](/guides/select-menu) for a usage example. * @category Select */ export function Select(props: SelectProps) { @@ -73,6 +113,10 @@ class SelectNode extends Node { type: "select", customId: this.customId, options, + // I'm not counting on people using value and values at the same time, + // but maybe we should resolve this differently anyhow? e.g. one should override the other + // or just warn if there are both + // or... try some other alternative design entirely values: [...(values || []), ...(value ? [value] : [])], minValues: multiple ? minValues : undefined, maxValues: multiple ? Math.max(minValues, maxValues) : undefined, diff --git a/packages/reacord/library/core/instance.ts b/packages/reacord/library/core/instance.ts index 4f30d50..d0aa740 100644 --- a/packages/reacord/library/core/instance.ts +++ b/packages/reacord/library/core/instance.ts @@ -1,10 +1,19 @@ import type { ReactNode } from "react" /** + * Represents an interactive message, which can later be replaced or deleted. * @category Core */ export type ReacordInstance = { + /** Render some JSX to this instance (edits the message) */ render: (content: ReactNode) => void - deactivate: () => void + + /** Remove this message */ destroy: () => void + + /** + * Same as destroy, but keeps the message and disables the components on it. + * This prevents it from listening to user interactions. + */ + deactivate: () => void } diff --git a/packages/reacord/library/core/reacord-discord-js.ts b/packages/reacord/library/core/reacord-discord-js.ts index 3d67ea1..ee1d6dd 100644 --- a/packages/reacord/library/core/reacord-discord-js.ts +++ b/packages/reacord/library/core/reacord-discord-js.ts @@ -40,9 +40,7 @@ export class ReacordDiscordJs extends Reacord { /** * Sends a message to a channel. - * @param channelId The ID of the channel to create a message in. - * @param initialContent The initial content of the message. - * @returns A Record instance. + * @see https://reacord.fly.dev/guides/sending-messages */ override send( channelId: string, @@ -54,6 +52,10 @@ export class ReacordDiscordJs extends Reacord { ) } + /** + * Sends a message as a reply to a command interaction. + * @see https://reacord.fly.dev/guides/sending-messages + */ override reply( interaction: Discord.CommandInteraction, initialContent?: React.ReactNode, @@ -64,6 +66,10 @@ export class ReacordDiscordJs extends Reacord { ) } + /** + * Sends an ephemeral message as a reply to a command interaction. + * @see https://reacord.fly.dev/guides/sending-messages + */ override ephemeralReply( interaction: Discord.CommandInteraction, initialContent?: React.ReactNode, diff --git a/packages/reacord/library/main.ts b/packages/reacord/library/main.ts index 6b48c94..0db269d 100644 --- a/packages/reacord/library/main.ts +++ b/packages/reacord/library/main.ts @@ -1,6 +1,7 @@ export * from "./core/component-event" export * from "./core/components/action-row" export * from "./core/components/button" +export * from "./core/components/button-shared-props" export * from "./core/components/embed" export * from "./core/components/embed-author" export * from "./core/components/embed-field" diff --git a/packages/reacord/playground/counter.tsx b/packages/reacord/playground/counter.tsx index 875c82a..562df12 100644 --- a/packages/reacord/playground/counter.tsx +++ b/packages/reacord/playground/counter.tsx @@ -23,6 +23,7 @@ export function Counter(props: { onDeactivate: () => void }) { )}