feat(ui): support embed fields, footer icon, and timestamp (#9442)

This commit is contained in:
Almeida
2023-04-25 18:05:14 +01:00
committed by GitHub
parent 1b4d34cebf
commit 2e09cb4c1f
5 changed files with 82 additions and 4 deletions

View File

@@ -58,7 +58,11 @@ export const Default = {
avatar: '/assets/discordjs.png',
username: 'Guide Bot',
}}
footer={{ content: 'Sometimes, titles just have to be.' }}
footer={{
content: 'Sometimes, titles just have to be.',
icon: '/assets/discordjs.png',
timestamp: 'Today at 21:02',
}}
title={{ title: 'An amazing title' }}
>
This is a description. You can put a description here. It must be descriptive!
@@ -73,6 +77,35 @@ export const Default = {
>
Multiple embeds!
</DiscordMessageEmbed>
<DiscordMessageEmbed
author={{
avatar: '/assets/discordjs.png',
username: 'Guide Bot',
}}
fields={[
{
name: 'First field',
value: 'Some value',
},
{
name: 'Another field',
value: 'Another value',
inline: true,
},
{
name: 'A third field',
value: 'That is inline',
inline: true,
},
{
name: 'At last',
value: 'This is the last field',
inline: true,
},
]}
footer={{ timestamp: 'Today at 21:02' }}
title={{ title: 'Fields are also supported!' }}
/>
</>
</DiscordMessage>
<DiscordMessage

View File

@@ -1,13 +1,17 @@
import type { PropsWithChildren, ReactNode } from 'react';
import { DiscordMessageEmbedAuthor, type IDiscordMessageEmbedAuthor } from './MessageEmbedAuthor.jsx';
import type { IDiscordMessageEmbedField } from './MessageEmbedField.jsx';
import { DiscordMessageEmbedFields } from './MessageEmbedFields.jsx';
import { DiscordMessageEmbedFooter, type IDiscordMessageEmbedFooter } from './MessageEmbedFooter.jsx';
import { DiscordMessageEmbedTitle, type IDiscordMessageEmbedTitle } from './MessageEmbedTitle.jsx';
export interface IDiscordMessageEmbed {
author?: IDiscordMessageEmbedAuthor | undefined;
authorNode?: ReactNode | undefined;
fields?: IDiscordMessageEmbedField[];
footer?: IDiscordMessageEmbedFooter | undefined;
footerNode?: ReactNode | undefined;
timestamp?: string;
title?: IDiscordMessageEmbedTitle | undefined;
titleNode?: ReactNode | undefined;
}
@@ -15,6 +19,7 @@ export interface IDiscordMessageEmbed {
export function DiscordMessageEmbed({
author,
authorNode,
fields,
title,
titleNode,
children,
@@ -29,6 +34,7 @@ export function DiscordMessageEmbed({
{author ? <DiscordMessageEmbedAuthor {...author} /> : authorNode ?? null}
{title ? <DiscordMessageEmbedTitle {...title} /> : titleNode ?? null}
{children ? <div className="mt-2 text-sm">{children}</div> : null}
{fields ? <DiscordMessageEmbedFields fields={fields} /> : null}
{footer ? <DiscordMessageEmbedFooter {...footer} /> : footerNode ?? null}
</div>
</div>

View File

@@ -0,0 +1,14 @@
export interface IDiscordMessageEmbedField {
inline?: boolean;
name: string;
value: string;
}
export function DiscordMessageEmbedField({ name, value, inline }: IDiscordMessageEmbedField) {
return (
<div className={`${inline ? 'sm:col-span-4' : 'sm:col-span-12'} flex flex-col`}>
<span className="font-medium">{name}</span>
<span className="text-gray-300">{value}</span>
</div>
);
}

View File

@@ -0,0 +1,15 @@
import { DiscordMessageEmbedField, type IDiscordMessageEmbedField } from './MessageEmbedField.js';
export interface IDiscordMessageEmbedFields {
fields: IDiscordMessageEmbedField[];
}
export function DiscordMessageEmbedFields({ fields }: IDiscordMessageEmbedFields) {
return (
<div className="grid grid-cols-1 mt-2 gap-2 sm:grid-cols-12">
{fields.map((field, idx) => (
<DiscordMessageEmbedField key={idx} {...field} />
))}
</div>
);
}

View File

@@ -1,7 +1,17 @@
export interface IDiscordMessageEmbedFooter {
content: string;
content?: string;
icon?: string;
timestamp?: string;
}
export function DiscordMessageEmbedFooter({ content }: IDiscordMessageEmbedFooter) {
return <div className="mt-2 text-xs">{content}</div>;
export function DiscordMessageEmbedFooter({ content, icon, timestamp }: IDiscordMessageEmbedFooter) {
return (
<div className="mt-2 flex items-center text-xs">
{icon ? <img className="mr-2 rounded-full" height="20" src={icon} width="20" /> : null}
{content}
{content && timestamp ? <span className="mx-1 font-medium"></span> : null}
{timestamp}
</div>
);
}