@ctrl-ui/react 0.8.4 → 0.8.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audio-visualizer.js +1 -1
- package/dist/chat-composer-editor/extensions/mention.js +4 -0
- package/dist/chat-layout.d.ts +5 -0
- package/dist/chat-layout.js +61 -20
- package/dist/chat-message.d.ts +5 -0
- package/dist/chat-message.js +19 -2
- package/dist/context.js +0 -2
- package/dist/email/email-brand.d.ts +60 -0
- package/dist/email/email-brand.js +101 -0
- package/dist/email/email-code.d.ts +18 -0
- package/dist/email/email-code.js +172 -0
- package/dist/email/email-footer.d.ts +63 -0
- package/dist/email/email-footer.js +98 -0
- package/dist/email/email.d.ts +60 -11
- package/dist/email/email.js +155 -24
- package/dist/email/templates.d.ts +54 -9
- package/dist/email/templates.js +314 -116
- package/dist/email/theme.d.ts +13 -5
- package/dist/email/theme.js +30 -8
- package/dist/hooks/use-chat-message.d.ts +1 -0
- package/dist/hooks/use-chat-message.js +1 -0
- package/dist/hooks/use-chat-thread-scroll.d.ts +8 -0
- package/dist/hooks/use-chat-thread-scroll.js +66 -0
- package/dist/hooks/use-user-ask.d.ts +6 -4
- package/dist/hooks/use-user-ask.js +56 -17
- package/dist/inline-attachment.js +1 -1
- package/dist/knob-contracts/action-bar-knobs.d.ts +1 -1
- package/dist/knob-contracts/action-bar-knobs.js +1 -1
- package/dist/knob-contracts/activity-knobs.d.ts +1 -1
- package/dist/knob-contracts/activity-knobs.js +2 -1
- package/dist/knob-contracts/audio-visualizer-knobs.d.ts +1 -1
- package/dist/knob-contracts/audio-visualizer-knobs.js +1 -0
- package/dist/knob-contracts/chat-composer-attachment-knobs.d.ts +1 -1
- package/dist/knob-contracts/chat-composer-attachment-knobs.js +2 -0
- package/dist/knob-contracts/chat-composer-knobs.d.ts +1 -1
- package/dist/knob-contracts/chat-composer-knobs.js +1 -0
- package/dist/knob-contracts/chat-layout-knobs.d.ts +1 -1
- package/dist/knob-contracts/chat-layout-knobs.js +2 -1
- package/dist/knob-contracts/chat-message-knobs.d.ts +1 -1
- package/dist/knob-contracts/chat-message-knobs.js +3 -1
- package/dist/knob-contracts/context-knobs.d.ts +1 -1
- package/dist/knob-contracts/context-knobs.js +3 -0
- package/dist/knob-contracts/inline-attachment-knobs.d.ts +1 -1
- package/dist/knob-contracts/inline-attachment-knobs.js +4 -0
- package/dist/knob-contracts/inline-citation-knobs.d.ts +1 -1
- package/dist/knob-contracts/inline-citation-knobs.js +3 -1
- package/dist/knob-contracts/page-layout-knobs.d.ts +4 -0
- package/dist/knob-contracts/page-layout-knobs.js +16 -0
- package/dist/knob-contracts/table-of-contents-knobs.d.ts +1 -1
- package/dist/knob-contracts/table-of-contents-knobs.js +3 -3
- package/dist/knob-contracts/task-list-knobs.d.ts +1 -1
- package/dist/knob-contracts/task-list-knobs.js +4 -0
- package/dist/knob-contracts/user-ask-knobs.d.ts +1 -1
- package/dist/knob-contracts/user-ask-knobs.js +4 -0
- package/dist/lib/phone-input-format.js +1 -1
- package/dist/markdown-block.js +1 -1
- package/dist/styles/index.css +2 -1
- package/dist/styles/recipes/action-bar.css +37 -5
- package/dist/styles/recipes/activity.css +36 -3
- package/dist/styles/recipes/alert.css +2 -0
- package/dist/styles/recipes/audio-visualizer.css +8 -1
- package/dist/styles/recipes/button-group.css +8 -0
- package/dist/styles/recipes/button.css +15 -0
- package/dist/styles/recipes/calendar.css +21 -0
- package/dist/styles/recipes/card.css +2 -0
- package/dist/styles/recipes/chat-composer-attachment.css +33 -2
- package/dist/styles/recipes/chat-composer.css +16 -2
- package/dist/styles/recipes/chat-layout.css +25 -1
- package/dist/styles/recipes/chat-message.css +69 -2
- package/dist/styles/recipes/choice.css +12 -0
- package/dist/styles/recipes/code-diff.css +1 -0
- package/dist/styles/recipes/code.css +25 -0
- package/dist/styles/recipes/context.css +30 -18
- package/dist/styles/recipes/dynamic-notification-input.css +6 -0
- package/dist/styles/recipes/dynamic-notification.css +1 -0
- package/dist/styles/recipes/environment-variables.css +1 -0
- package/dist/styles/recipes/field-parts.css +2 -0
- package/dist/styles/recipes/field.css +6 -0
- package/dist/styles/recipes/gradient-editor.css +17 -0
- package/dist/styles/recipes/inline-attachment.css +57 -14
- package/dist/styles/recipes/inline-citation.css +44 -6
- package/dist/styles/recipes/item.css +3 -1
- package/dist/styles/recipes/markdown-block.css +1 -0
- package/dist/styles/recipes/markdown.css +7 -0
- package/dist/styles/recipes/page-layout.css +219 -0
- package/dist/styles/recipes/pagination.css +16 -0
- package/dist/styles/recipes/popup-drawer.css +3 -1
- package/dist/styles/recipes/popup-toast.css +2 -0
- package/dist/styles/recipes/popup.css +8 -12
- package/dist/styles/recipes/range.css +24 -2
- package/dist/styles/recipes/rich-tooltip.css +1 -0
- package/dist/styles/recipes/source-badge.css +20 -0
- package/dist/styles/recipes/table-of-contents.css +10 -10
- package/dist/styles/recipes/tabs.css +16 -0
- package/dist/styles/recipes/task-list.css +61 -8
- package/dist/styles/recipes/thread-rail.css +19 -13
- package/dist/styles/recipes/toolbar.css +21 -0
- package/dist/styles/recipes/transcript-divider.css +1 -0
- package/dist/styles/recipes/user-ask.css +59 -16
- package/dist/styles/theme.css +34 -0
- package/dist/thread-rail.js +1 -1
- package/dist/ui/alert-dialog.js +2 -2
- package/dist/ui/autocomplete.js +1 -1
- package/dist/ui/color-picker.js +3 -3
- package/dist/ui/combobox.js +1 -1
- package/dist/ui/command.d.ts +5 -3
- package/dist/ui/command.js +27 -3
- package/dist/ui/context-menu.js +2 -2
- package/dist/ui/dialog.js +2 -2
- package/dist/ui/drawer.js +2 -2
- package/dist/ui/dropdown-menu.js +1 -1
- package/dist/ui/dropzone.js +4 -1
- package/dist/ui/gradient-editor.js +2 -2
- package/dist/ui/hover-card.js +1 -1
- package/dist/ui/infinite-canvas.js +1 -0
- package/dist/ui/menubar.js +2 -2
- package/dist/ui/navigation-menu.js +1 -1
- package/dist/ui/number-field.js +1 -1
- package/dist/ui/page-layout.d.ts +44 -0
- package/dist/ui/page-layout.js +108 -0
- package/dist/ui/phone-input.js +4 -4
- package/dist/ui/popover.js +1 -1
- package/dist/ui/resizable.js +1 -1
- package/dist/ui/rich-tooltip.js +1 -1
- package/dist/ui/select.js +1 -1
- package/dist/ui/sheet.js +2 -2
- package/dist/ui/sidebar-resize-rail.js +1 -1
- package/dist/ui/slider.js +1 -1
- package/dist/ui/toast.js +2 -2
- package/dist/ui/tooltip.js +1 -1
- package/dist/ui/trigger-menu.js +1 -1
- package/dist/user-ask.d.ts +5 -3
- package/dist/user-ask.js +38 -13
- package/package.json +3 -2
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { EmailCaption, EmailDivider, EmailMutedLink } from "./email.js";
|
|
2
|
+
import { Fragment } from "react";
|
|
3
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { Img, Section } from "react-email";
|
|
5
|
+
//#region src/email/email-footer.tsx
|
|
6
|
+
const emailSocialPlatformNames = {
|
|
7
|
+
x: "X",
|
|
8
|
+
bluesky: "Bluesky",
|
|
9
|
+
threads: "Threads",
|
|
10
|
+
instagram: "Instagram",
|
|
11
|
+
facebook: "Facebook",
|
|
12
|
+
linkedin: "LinkedIn",
|
|
13
|
+
youtube: "YouTube",
|
|
14
|
+
tiktok: "TikTok",
|
|
15
|
+
github: "GitHub",
|
|
16
|
+
discord: "Discord",
|
|
17
|
+
slack: "Slack",
|
|
18
|
+
mastodon: "Mastodon"
|
|
19
|
+
};
|
|
20
|
+
function separatedLinks(links) {
|
|
21
|
+
return links.map((link, index) => /* @__PURE__ */ jsxs(Fragment, { children: [index > 0 ? " · " : null, /* @__PURE__ */ jsx(EmailMutedLink, {
|
|
22
|
+
href: link.href,
|
|
23
|
+
children: link.label
|
|
24
|
+
})] }, link.href));
|
|
25
|
+
}
|
|
26
|
+
function EmailFooter({ children, align = "start", placement = "inside" }) {
|
|
27
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [placement === "inside" ? /* @__PURE__ */ jsx(EmailDivider, {}) : null, /* @__PURE__ */ jsx(Section, {
|
|
28
|
+
className: `${placement === "inside" ? "" : "pt-6"} ${align === "center" ? "text-center" : "text-left"}`,
|
|
29
|
+
children
|
|
30
|
+
})] });
|
|
31
|
+
}
|
|
32
|
+
function EmailFooterLegal({ children, className = "" }) {
|
|
33
|
+
return /* @__PURE__ */ jsx(Section, {
|
|
34
|
+
className: `mt-6 ${className}`,
|
|
35
|
+
children
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function resolveSocialLink(link, iconBaseUrl) {
|
|
39
|
+
const label = link.platform ? link.label ?? emailSocialPlatformNames[link.platform] : link.label;
|
|
40
|
+
const base = iconBaseUrl?.replace(/\/$/, "");
|
|
41
|
+
return {
|
|
42
|
+
label,
|
|
43
|
+
iconUrl: link.iconUrl ?? (link.platform && base ? `${base}/${link.platform}.png` : void 0),
|
|
44
|
+
alt: link.iconAlt ?? label
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function EmailSocialLinks({ links, iconBaseUrl, iconSize = 24 }) {
|
|
48
|
+
if (links.length === 0) return null;
|
|
49
|
+
return /* @__PURE__ */ jsx(Section, {
|
|
50
|
+
className: "mb-4",
|
|
51
|
+
children: links.map((link, index) => {
|
|
52
|
+
const { label, iconUrl, alt } = resolveSocialLink(link, iconBaseUrl);
|
|
53
|
+
const spacing = index < links.length - 1 ? "mr-3" : "";
|
|
54
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [index > 0 ? " " : null, /* @__PURE__ */ jsx(EmailMutedLink, {
|
|
55
|
+
href: link.href,
|
|
56
|
+
className: `${iconUrl ? "no-underline" : "underline"} ${spacing}`,
|
|
57
|
+
children: iconUrl ? /* @__PURE__ */ jsx(Img, {
|
|
58
|
+
src: iconUrl,
|
|
59
|
+
alt,
|
|
60
|
+
width: iconSize,
|
|
61
|
+
height: iconSize,
|
|
62
|
+
className: "inline-block align-middle"
|
|
63
|
+
}) : label
|
|
64
|
+
})] }, link.href);
|
|
65
|
+
})
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function EmailFooterLinks({ links }) {
|
|
69
|
+
if (links.length === 0) return null;
|
|
70
|
+
return /* @__PURE__ */ jsx(EmailCaption, {
|
|
71
|
+
className: "mb-2",
|
|
72
|
+
children: separatedLinks(links)
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function EmailAddress({ company, lines }) {
|
|
76
|
+
return /* @__PURE__ */ jsxs(EmailCaption, {
|
|
77
|
+
className: "mb-2",
|
|
78
|
+
children: [/* @__PURE__ */ jsx("strong", {
|
|
79
|
+
className: "font-semibold",
|
|
80
|
+
children: company
|
|
81
|
+
}), lines.map((line) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("br", {}), line] }, line))]
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function EmailUnsubscribe({ unsubscribeUrl, preferencesUrl, unsubscribeLabel = "Unsubscribe", preferencesLabel = "Manage preferences" }) {
|
|
85
|
+
const unsubscribe = {
|
|
86
|
+
label: unsubscribeLabel,
|
|
87
|
+
href: unsubscribeUrl
|
|
88
|
+
};
|
|
89
|
+
return /* @__PURE__ */ jsx(EmailCaption, {
|
|
90
|
+
className: "mb-2",
|
|
91
|
+
children: separatedLinks(preferencesUrl ? [unsubscribe, {
|
|
92
|
+
label: preferencesLabel,
|
|
93
|
+
href: preferencesUrl
|
|
94
|
+
}] : [unsubscribe])
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
//#endregion
|
|
98
|
+
export { EmailAddress, EmailFooter, EmailFooterLegal, EmailFooterLinks, EmailSocialLinks, EmailUnsubscribe, emailSocialPlatformNames };
|
package/dist/email/email.d.ts
CHANGED
|
@@ -1,27 +1,76 @@
|
|
|
1
1
|
import { EmailTheme } from "./theme.js";
|
|
2
2
|
import { ReactNode } from "react";
|
|
3
|
-
import { ButtonProps, HeadingProps, LinkProps, TextProps } from "react-email";
|
|
3
|
+
import { ButtonProps, HeadingProps, HrProps, LinkProps, SectionProps, TextProps } from "react-email";
|
|
4
4
|
//#region src/email/email.d.ts
|
|
5
|
-
export
|
|
5
|
+
export type EmailVariant = "contained" | "plain";
|
|
6
|
+
export type EmailFooterPlacement = "inside" | "outside";
|
|
7
|
+
export declare function surfaceColors(theme: EmailTheme, variant: EmailVariant): Record<"background" | "border" | "card" | "card-foreground" | "foreground" | "muted" | "muted-foreground" | "primary" | "primary-foreground" | "primary-text", string>;
|
|
8
|
+
export declare function EmailLayout({ theme, preview, children, footer, footerPlacement, head, lang, dir, variant }: {
|
|
6
9
|
theme: EmailTheme;
|
|
7
10
|
preview: string;
|
|
8
11
|
children: ReactNode;
|
|
12
|
+
footer?: ReactNode;
|
|
13
|
+
footerPlacement?: EmailFooterPlacement;
|
|
9
14
|
head?: ReactNode;
|
|
10
15
|
lang?: string;
|
|
11
16
|
dir?: "ltr" | "rtl";
|
|
17
|
+
variant?: EmailVariant;
|
|
12
18
|
}): import("react").JSX.Element;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
export type EmailAlign = "left" | "center" | "right";
|
|
20
|
+
declare const headingSizeClasses: {
|
|
21
|
+
display: string;
|
|
22
|
+
"heading-1": string;
|
|
23
|
+
"heading-2": string;
|
|
24
|
+
"heading-3": string;
|
|
25
|
+
"heading-4": string;
|
|
18
26
|
};
|
|
19
|
-
|
|
20
|
-
|
|
27
|
+
type EmailHeadingSize = keyof typeof headingSizeClasses;
|
|
28
|
+
declare const headingSizeForTag: {
|
|
29
|
+
readonly h1: "heading-1";
|
|
30
|
+
readonly h2: "heading-2";
|
|
31
|
+
readonly h3: "heading-3";
|
|
32
|
+
readonly h4: "heading-4";
|
|
33
|
+
};
|
|
34
|
+
export declare function EmailHeading({ as, size, align, className, ...props }: Omit<HeadingProps, "as"> & {
|
|
35
|
+
as?: keyof typeof headingSizeForTag;
|
|
36
|
+
size?: EmailHeadingSize;
|
|
37
|
+
align?: EmailAlign;
|
|
38
|
+
}): import("react").JSX.Element;
|
|
39
|
+
export declare function EmailSection({ align, className, ...props }: SectionProps & {
|
|
40
|
+
align?: EmailAlign;
|
|
21
41
|
}): import("react").JSX.Element;
|
|
22
|
-
export declare function EmailText({ tone, className, style, ...props }: TextProps & {
|
|
42
|
+
export declare function EmailText({ tone, align, className, style, ...props }: TextProps & {
|
|
23
43
|
tone?: "default" | "muted";
|
|
44
|
+
align?: EmailAlign;
|
|
45
|
+
}): import("react").JSX.Element;
|
|
46
|
+
export declare function EmailButton({ width, className, ...props }: ButtonProps & {
|
|
47
|
+
width?: "auto" | "full";
|
|
24
48
|
}): import("react").JSX.Element;
|
|
25
|
-
export declare function EmailButton({ className, ...props }: ButtonProps): import("react").JSX.Element;
|
|
26
49
|
export declare function EmailLink({ className, ...props }: LinkProps): import("react").JSX.Element;
|
|
50
|
+
export declare function EmailCaption({ className, ...props }: TextProps & {
|
|
51
|
+
align?: EmailAlign;
|
|
52
|
+
}): import("react").JSX.Element;
|
|
53
|
+
export declare function EmailMutedLink({ className, ...props }: LinkProps): import("react").JSX.Element;
|
|
54
|
+
export declare function EmailDivider({ className, ...props }: HrProps): import("react").JSX.Element;
|
|
55
|
+
export declare function EmailPanel({ className, ...props }: SectionProps): import("react").JSX.Element;
|
|
56
|
+
export declare function EmailOneTimeCode({ children, className }: {
|
|
57
|
+
children: ReactNode;
|
|
58
|
+
className?: string;
|
|
59
|
+
}): import("react").JSX.Element;
|
|
60
|
+
export declare function EmailBulletList({ items, className }: {
|
|
61
|
+
items: ReactNode[];
|
|
62
|
+
className?: string;
|
|
63
|
+
}): import("react").JSX.Element | null;
|
|
64
|
+
export declare function EmailColumns({ children, widths, gap, verticalAlign, className }: {
|
|
65
|
+
children: ReactNode[];
|
|
66
|
+
widths?: string[];
|
|
67
|
+
gap?: number;
|
|
68
|
+
verticalAlign?: "top" | "middle" | "bottom";
|
|
69
|
+
className?: string;
|
|
70
|
+
}): import("react").JSX.Element | null;
|
|
71
|
+
export declare function EmailDetailRow({ label, value, emphasis }: {
|
|
72
|
+
label: ReactNode;
|
|
73
|
+
value: ReactNode;
|
|
74
|
+
emphasis?: boolean;
|
|
75
|
+
}): import("react").JSX.Element;
|
|
27
76
|
//#endregion
|
package/dist/email/email.js
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Body, Button, Container, Head, Heading, Html, Link, Preview, Tailwind, Text, pixelBasedPreset } from "react-email";
|
|
2
|
+
import { Body, Button, Column, Container, Head, Heading, Hr, Html, Link, Preview, Row, Section, Tailwind, Text, pixelBasedPreset } from "react-email";
|
|
3
3
|
//#region src/email/email.tsx
|
|
4
|
-
function
|
|
4
|
+
function surfaceColors(theme, variant) {
|
|
5
|
+
if (variant === "contained") return theme.colors;
|
|
6
|
+
return {
|
|
7
|
+
...theme.colors,
|
|
8
|
+
card: theme.colors.background,
|
|
9
|
+
"card-foreground": theme.colors.foreground
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function tailwindTheme(theme, variant) {
|
|
5
13
|
return {
|
|
6
14
|
presets: [pixelBasedPreset],
|
|
7
15
|
theme: { extend: {
|
|
8
|
-
colors: theme
|
|
16
|
+
colors: surfaceColors(theme, variant),
|
|
9
17
|
borderRadius: theme.radii,
|
|
10
18
|
minHeight: { control: theme.button.height },
|
|
11
19
|
padding: {
|
|
@@ -14,7 +22,8 @@ function tailwindTheme(theme) {
|
|
|
14
22
|
},
|
|
15
23
|
fontFamily: {
|
|
16
24
|
body: theme.fonts.body,
|
|
17
|
-
display: theme.fonts.display
|
|
25
|
+
display: theme.fonts.display,
|
|
26
|
+
mono: theme.fonts.mono
|
|
18
27
|
},
|
|
19
28
|
fontSize: {
|
|
20
29
|
...Object.fromEntries(Object.entries(theme.text).map(([name, { fontSize, ...options }]) => [name, [fontSize, options]])),
|
|
@@ -23,36 +32,78 @@ function tailwindTheme(theme) {
|
|
|
23
32
|
} }
|
|
24
33
|
};
|
|
25
34
|
}
|
|
26
|
-
function EmailLayout({ theme, preview, children, head, lang = "en", dir = "ltr" }) {
|
|
35
|
+
function EmailLayout({ theme, preview, children, footer, footerPlacement = "inside", head, lang = "en", dir = "ltr", variant = "contained" }) {
|
|
36
|
+
const contained = variant === "contained";
|
|
37
|
+
const outside = contained && footerPlacement === "outside";
|
|
38
|
+
const backdrop = theme.colorScheme === "light" ? "bg-muted" : "bg-background";
|
|
27
39
|
return /* @__PURE__ */ jsx(Html, {
|
|
28
40
|
lang,
|
|
29
41
|
dir,
|
|
30
42
|
children: /* @__PURE__ */ jsxs(Tailwind, {
|
|
31
|
-
config: tailwindTheme(theme),
|
|
32
|
-
children: [/* @__PURE__ */
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
43
|
+
config: tailwindTheme(theme, variant),
|
|
44
|
+
children: [/* @__PURE__ */ jsxs(Head, { children: [
|
|
45
|
+
/* @__PURE__ */ jsx("meta", {
|
|
46
|
+
name: "color-scheme",
|
|
47
|
+
content: theme.colorScheme
|
|
48
|
+
}),
|
|
49
|
+
/* @__PURE__ */ jsx("meta", {
|
|
50
|
+
name: "supported-color-schemes",
|
|
51
|
+
content: theme.colorScheme
|
|
52
|
+
}),
|
|
53
|
+
head
|
|
54
|
+
] }), /* @__PURE__ */ jsxs(Body, {
|
|
55
|
+
className: `m-0 font-body text-body text-foreground ${contained ? `${backdrop} px-4 py-8` : "bg-background p-0"}`,
|
|
56
|
+
children: [
|
|
57
|
+
/* @__PURE__ */ jsx(Preview, { children: preview }),
|
|
58
|
+
/* @__PURE__ */ jsxs(Container, {
|
|
59
|
+
className: `mx-auto w-full max-w-[600px] bg-card text-card-foreground ${contained ? "rounded-panel border border-border border-solid p-6" : "px-6 py-8"}`,
|
|
60
|
+
children: [children, outside ? null : footer]
|
|
61
|
+
}),
|
|
62
|
+
outside ? /* @__PURE__ */ jsx(Container, {
|
|
63
|
+
className: "mx-auto w-full max-w-[600px] px-6",
|
|
64
|
+
children: footer
|
|
65
|
+
}) : null
|
|
66
|
+
]
|
|
38
67
|
})]
|
|
39
68
|
})
|
|
40
69
|
});
|
|
41
70
|
}
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
71
|
+
const alignClasses = {
|
|
72
|
+
left: "text-left",
|
|
73
|
+
center: "text-center",
|
|
74
|
+
right: "text-right"
|
|
75
|
+
};
|
|
76
|
+
function alignClass(align) {
|
|
77
|
+
return align ? alignClasses[align] : "";
|
|
78
|
+
}
|
|
79
|
+
const headingSizeClasses = {
|
|
80
|
+
display: "text-display",
|
|
81
|
+
"heading-1": "text-heading-1",
|
|
82
|
+
"heading-2": "text-heading-2",
|
|
83
|
+
"heading-3": "text-heading-3",
|
|
84
|
+
"heading-4": "text-heading-4"
|
|
85
|
+
};
|
|
86
|
+
const headingSizeForTag = {
|
|
87
|
+
h1: "heading-1",
|
|
88
|
+
h2: "heading-2",
|
|
89
|
+
h3: "heading-3",
|
|
90
|
+
h4: "heading-4"
|
|
47
91
|
};
|
|
48
|
-
function EmailHeading({ as = "h1", className = "", ...props }) {
|
|
92
|
+
function EmailHeading({ as = "h1", size, align, className = "", ...props }) {
|
|
93
|
+
const sizeClass = headingSizeClasses[size ?? headingSizeForTag[as]];
|
|
49
94
|
return /* @__PURE__ */ jsx(Heading, {
|
|
50
95
|
...props,
|
|
51
96
|
as,
|
|
52
|
-
className: `mb-4 mt-0 font-display text-card-foreground ${
|
|
97
|
+
className: `mb-4 mt-0 font-display text-card-foreground ${sizeClass} ${alignClass(align)} ${className}`
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
function EmailSection({ align, className = "", ...props }) {
|
|
101
|
+
return /* @__PURE__ */ jsx(Section, {
|
|
102
|
+
...props,
|
|
103
|
+
className: `${alignClass(align)} ${className}`
|
|
53
104
|
});
|
|
54
105
|
}
|
|
55
|
-
function EmailText({ tone = "default", className = "", style, ...props }) {
|
|
106
|
+
function EmailText({ tone = "default", align, className = "", style, ...props }) {
|
|
56
107
|
const textColor = tone === "muted" ? "text-muted-foreground" : "text-card-foreground";
|
|
57
108
|
return /* @__PURE__ */ jsx(Text, {
|
|
58
109
|
...props,
|
|
@@ -60,13 +111,14 @@ function EmailText({ tone = "default", className = "", style, ...props }) {
|
|
|
60
111
|
overflowWrap: "break-word",
|
|
61
112
|
...style
|
|
62
113
|
},
|
|
63
|
-
className: `mb-4 mt-0 font-body text-body ${textColor} ${className}`
|
|
114
|
+
className: `mb-4 mt-0 font-body text-body ${textColor} ${alignClass(align)} ${className}`
|
|
64
115
|
});
|
|
65
116
|
}
|
|
66
|
-
function EmailButton({ className = "", ...props }) {
|
|
117
|
+
function EmailButton({ width = "auto", className = "", ...props }) {
|
|
118
|
+
const widthClass = width === "full" ? "block w-full" : "inline-block";
|
|
67
119
|
return /* @__PURE__ */ jsx(Button, {
|
|
68
120
|
...props,
|
|
69
|
-
className: `box-border min-h-control rounded-control bg-primary px-control-x py-control-y text-center font-body text-control font-medium text-primary-foreground no-underline ${className}`
|
|
121
|
+
className: `box-border min-h-control rounded-control bg-primary px-control-x py-control-y text-center font-body text-control font-medium text-primary-foreground no-underline ${widthClass} ${className}`
|
|
70
122
|
});
|
|
71
123
|
}
|
|
72
124
|
function EmailLink({ className = "", ...props }) {
|
|
@@ -75,5 +127,84 @@ function EmailLink({ className = "", ...props }) {
|
|
|
75
127
|
className: `font-body text-primary-text underline ${className}`
|
|
76
128
|
});
|
|
77
129
|
}
|
|
130
|
+
function EmailCaption({ className = "", ...props }) {
|
|
131
|
+
return /* @__PURE__ */ jsx(EmailText, {
|
|
132
|
+
tone: "muted",
|
|
133
|
+
...props,
|
|
134
|
+
className: `text-caption ${className}`
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
function EmailMutedLink({ className = "", ...props }) {
|
|
138
|
+
return /* @__PURE__ */ jsx(EmailLink, {
|
|
139
|
+
...props,
|
|
140
|
+
className: `text-caption text-muted-foreground ${className}`
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
function EmailDivider({ className = "", ...props }) {
|
|
144
|
+
return /* @__PURE__ */ jsx(Hr, {
|
|
145
|
+
...props,
|
|
146
|
+
className: `my-6 border-0 border-t border-solid border-t-border ${className}`
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
function EmailPanel({ className = "", ...props }) {
|
|
150
|
+
return /* @__PURE__ */ jsx(Section, {
|
|
151
|
+
...props,
|
|
152
|
+
className: `my-6 rounded-panel bg-muted p-5 ${className}`
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
function EmailOneTimeCode({ children, className = "" }) {
|
|
156
|
+
return /* @__PURE__ */ jsx(EmailPanel, {
|
|
157
|
+
className: `text-center ${className}`,
|
|
158
|
+
children: /* @__PURE__ */ jsx(EmailText, {
|
|
159
|
+
className: "mb-0 text-center font-mono text-heading-2 font-semibold tracking-[0.25em]",
|
|
160
|
+
children
|
|
161
|
+
})
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
function EmailBulletList({ items, className = "" }) {
|
|
165
|
+
if (items.length === 0) return null;
|
|
166
|
+
return /* @__PURE__ */ jsx("ul", {
|
|
167
|
+
className: `mb-4 mt-0 list-disc pl-5 font-body text-body text-card-foreground ${className}`,
|
|
168
|
+
children: items.map((item, index) => /* @__PURE__ */ jsx("li", {
|
|
169
|
+
className: "mb-1 font-body text-body text-card-foreground",
|
|
170
|
+
children: item
|
|
171
|
+
}, index))
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
function EmailColumns({ children, widths, gap = 20, verticalAlign = "top", className = "" }) {
|
|
175
|
+
if (children.length === 0) return null;
|
|
176
|
+
const evenWidth = `${(100 / children.length).toFixed(4)}%`;
|
|
177
|
+
return /* @__PURE__ */ jsx(Row, {
|
|
178
|
+
className: `mb-6 table-fixed ${className}`,
|
|
179
|
+
children: children.map((child, index) => /* @__PURE__ */ jsx(Column, {
|
|
180
|
+
width: widths?.[index] ?? evenWidth,
|
|
181
|
+
className: `max-[480px]:block max-[480px]:w-full max-[480px]:pl-0 ${index === 0 ? "" : `max-[480px]:pt-[${gap}px]`}`,
|
|
182
|
+
style: {
|
|
183
|
+
verticalAlign,
|
|
184
|
+
paddingLeft: index === 0 ? 0 : gap
|
|
185
|
+
},
|
|
186
|
+
children: child
|
|
187
|
+
}, index))
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
function EmailDetailRow({ label, value, emphasis = false }) {
|
|
191
|
+
return /* @__PURE__ */ jsxs(Row, {
|
|
192
|
+
className: "table-fixed",
|
|
193
|
+
children: [/* @__PURE__ */ jsx(Column, {
|
|
194
|
+
className: "align-top",
|
|
195
|
+
children: /* @__PURE__ */ jsx(EmailText, {
|
|
196
|
+
className: "mb-2",
|
|
197
|
+
children: label
|
|
198
|
+
})
|
|
199
|
+
}), /* @__PURE__ */ jsx(Column, {
|
|
200
|
+
align: "right",
|
|
201
|
+
className: "align-top",
|
|
202
|
+
children: /* @__PURE__ */ jsx(EmailText, {
|
|
203
|
+
className: `mb-2 ${emphasis ? "font-semibold" : ""}`,
|
|
204
|
+
children: value
|
|
205
|
+
})
|
|
206
|
+
})]
|
|
207
|
+
});
|
|
208
|
+
}
|
|
78
209
|
//#endregion
|
|
79
|
-
export { EmailButton, EmailHeading, EmailLayout, EmailLink, EmailText };
|
|
210
|
+
export { EmailBulletList, EmailButton, EmailCaption, EmailColumns, EmailDetailRow, EmailDivider, EmailHeading, EmailLayout, EmailLink, EmailMutedLink, EmailOneTimeCode, EmailPanel, EmailSection, EmailText, surfaceColors };
|
|
@@ -1,23 +1,37 @@
|
|
|
1
1
|
import { EmailTheme } from "./theme.js";
|
|
2
|
+
import { EmailVariant } from "./email.js";
|
|
3
|
+
import { EmailBrand, EmailFooterContent } from "./email-brand.js";
|
|
4
|
+
import { ReactNode } from "react";
|
|
5
|
+
import { PrismLanguage } from "react-email";
|
|
2
6
|
//#region src/email/templates.d.ts
|
|
3
|
-
type
|
|
7
|
+
type EmailMessageProps = {
|
|
4
8
|
theme: EmailTheme;
|
|
5
|
-
brand:
|
|
6
|
-
footer:
|
|
9
|
+
brand: EmailBrand;
|
|
10
|
+
footer: EmailFooterContent;
|
|
11
|
+
variant?: EmailVariant;
|
|
12
|
+
head?: ReactNode;
|
|
7
13
|
};
|
|
8
|
-
|
|
14
|
+
type EmailBrandProps = EmailMessageProps & {
|
|
15
|
+
browserUrl?: string;
|
|
16
|
+
};
|
|
17
|
+
export type EmailHighlight = {
|
|
18
|
+
title: string;
|
|
19
|
+
description: string;
|
|
20
|
+
};
|
|
21
|
+
export declare function InvitationEmail({ theme, variant, head, brand, browserUrl, footer, inviter, workspace, inviteUrl }: EmailBrandProps & {
|
|
9
22
|
inviter: string;
|
|
10
23
|
workspace: string;
|
|
11
24
|
inviteUrl: string;
|
|
12
25
|
}): import("react").JSX.Element;
|
|
13
|
-
export declare function ProductEmail({ theme, brand, footer, title, description, imageUrl, imageAlt, actionUrl }: EmailBrandProps & {
|
|
26
|
+
export declare function ProductEmail({ theme, variant, head, brand, browserUrl, footer, title, description, imageUrl, imageAlt, highlights, actionUrl }: EmailBrandProps & {
|
|
14
27
|
title: string;
|
|
15
28
|
description: string;
|
|
16
29
|
imageUrl: string;
|
|
17
30
|
imageAlt: string;
|
|
31
|
+
highlights?: EmailHighlight[];
|
|
18
32
|
actionUrl: string;
|
|
19
33
|
}): import("react").JSX.Element;
|
|
20
|
-
export declare function EditorialEmail({ theme, brand, footer, title, description, imageUrl, imageAlt, articleUrl }: EmailBrandProps & {
|
|
34
|
+
export declare function EditorialEmail({ theme, variant, head, brand, browserUrl, footer, title, description, imageUrl, imageAlt, articleUrl }: EmailBrandProps & {
|
|
21
35
|
title: string;
|
|
22
36
|
description: string;
|
|
23
37
|
imageUrl: string;
|
|
@@ -31,11 +45,10 @@ export type EmailArticle = {
|
|
|
31
45
|
imageUrl: string;
|
|
32
46
|
imageAlt: string;
|
|
33
47
|
};
|
|
34
|
-
export declare function NewsletterEmail({ theme, brand, footer, articles
|
|
48
|
+
export declare function NewsletterEmail({ theme, variant, head, brand, browserUrl, footer, articles }: EmailBrandProps & {
|
|
35
49
|
articles: EmailArticle[];
|
|
36
|
-
unsubscribeUrl: string;
|
|
37
50
|
}): import("react").JSX.Element;
|
|
38
|
-
export declare function SummaryEmail({ theme, brand, footer, period, metrics, details, dashboardUrl }: EmailBrandProps & {
|
|
51
|
+
export declare function SummaryEmail({ theme, variant, head, brand, browserUrl, footer, period, metrics, details, dashboardUrl }: EmailBrandProps & {
|
|
39
52
|
period: string;
|
|
40
53
|
metrics: {
|
|
41
54
|
label: string;
|
|
@@ -47,4 +60,36 @@ export declare function SummaryEmail({ theme, brand, footer, period, metrics, de
|
|
|
47
60
|
}[];
|
|
48
61
|
dashboardUrl: string;
|
|
49
62
|
}): import("react").JSX.Element;
|
|
63
|
+
export declare function VerificationEmail({ theme, variant, head, brand, footer, code, expiresInMinutes, supportUrl }: EmailMessageProps & {
|
|
64
|
+
code: string;
|
|
65
|
+
expiresInMinutes: number;
|
|
66
|
+
supportUrl: string;
|
|
67
|
+
}): import("react").JSX.Element;
|
|
68
|
+
export type EmailReceiptLine = {
|
|
69
|
+
label: string;
|
|
70
|
+
value: string;
|
|
71
|
+
};
|
|
72
|
+
export declare function ReceiptEmail({ theme, variant, head, brand, footer, orderNumber, orderDate, lines, total, paymentMethod, invoiceUrl }: EmailMessageProps & {
|
|
73
|
+
orderNumber: string;
|
|
74
|
+
orderDate: string;
|
|
75
|
+
lines: EmailReceiptLine[];
|
|
76
|
+
total: string;
|
|
77
|
+
paymentMethod: string;
|
|
78
|
+
invoiceUrl: string;
|
|
79
|
+
}): import("react").JSX.Element;
|
|
80
|
+
export type EmailReleaseSection = {
|
|
81
|
+
title: string;
|
|
82
|
+
changes: string[];
|
|
83
|
+
};
|
|
84
|
+
export declare function ReleaseNotesEmail({ theme, variant, head, brand, browserUrl, footer, version, summary, sections, migration, changelogUrl }: EmailBrandProps & {
|
|
85
|
+
version: string;
|
|
86
|
+
summary: string;
|
|
87
|
+
sections: EmailReleaseSection[];
|
|
88
|
+
migration?: {
|
|
89
|
+
notes: string;
|
|
90
|
+
language: PrismLanguage;
|
|
91
|
+
code: string;
|
|
92
|
+
};
|
|
93
|
+
changelogUrl: string;
|
|
94
|
+
}): import("react").JSX.Element;
|
|
50
95
|
//#endregion
|