@hintoric/email 0.0.0-stage → 0.1.1
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/README.md +53 -2
- package/dist/components/Avatar.d.ts +37 -0
- package/dist/components/Avatar.d.ts.map +1 -0
- package/dist/components/Button.d.ts +39 -0
- package/dist/components/Button.d.ts.map +1 -0
- package/dist/components/Card.d.ts +17 -0
- package/dist/components/Card.d.ts.map +1 -0
- package/dist/components/Chip.d.ts +34 -0
- package/dist/components/Chip.d.ts.map +1 -0
- package/dist/components/Divider.d.ts +13 -0
- package/dist/components/Divider.d.ts.map +1 -0
- package/dist/components/HintoricLogo.d.ts +6 -0
- package/dist/components/HintoricLogo.d.ts.map +1 -0
- package/dist/components/Layout.d.ts +28 -0
- package/dist/components/Layout.d.ts.map +1 -0
- package/dist/components/Link.d.ts +18 -0
- package/dist/components/Link.d.ts.map +1 -0
- package/dist/components/Typography.d.ts +19 -0
- package/dist/components/Typography.d.ts.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +801 -0
- package/dist/index.js.map +1 -0
- package/dist/render.d.ts +9 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/safeUrl.d.ts +4 -0
- package/dist/safeUrl.d.ts.map +1 -0
- package/dist/styles.d.ts +18 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/templates/SecurityActivityAlert/SecurityActivityAlertEmail.d.ts +18 -0
- package/dist/templates/SecurityActivityAlert/SecurityActivityAlertEmail.d.ts.map +1 -0
- package/dist/templates/SecurityActivityAlert/index.d.ts +5 -0
- package/dist/templates/SecurityActivityAlert/index.d.ts.map +1 -0
- package/dist/templates/SecurityActivityAlert/messages.d.ts +4 -0
- package/dist/templates/SecurityActivityAlert/messages.d.ts.map +1 -0
- package/dist/templates/SecurityActivityAlert/types.d.ts +78 -0
- package/dist/templates/SecurityActivityAlert/types.d.ts.map +1 -0
- package/dist/tokens.d.ts +50 -0
- package/dist/tokens.d.ts.map +1 -0
- package/package.json +59 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/render.ts","../src/tokens.ts","../src/safeUrl.ts","../src/styles.ts","../src/components/Layout.tsx","../src/components/Typography.tsx","../src/components/Button.tsx","../src/components/Link.tsx","../src/components/Divider.tsx","../src/components/Card.tsx","../src/components/Avatar.tsx","../src/components/Chip.tsx","../src/components/HintoricLogo.tsx","../src/templates/SecurityActivityAlert/SecurityActivityAlertEmail.tsx","../src/templates/SecurityActivityAlert/messages.tsx"],"sourcesContent":["import type * as React from 'react';\nimport { render } from '@react-email/render';\n\nexport interface RenderedEmailBody {\n html: string;\n /** The plain-text part. Multipart mails without one score worse with spam filters. */\n text: string;\n}\n\n/** Renders an email element — normally a `<Layout>` — to HTML and plain text. */\nexport async function renderEmail(element: React.ReactElement): Promise<RenderedEmailBody> {\n const [html, text] = await Promise.all([render(element), render(element, { plainText: true })]);\n return { html, text };\n}\n","/*\n * The email module's copy of theme.css, resolved to literal values.\n *\n * Email clients cannot use the component library's styling: Gmail, Outlook\n * and Apple Mail resolve neither CSS custom properties nor Tailwind classes,\n * and Gmail drops <style> blocks in some contexts. So every email component\n * paints with inline `style` values taken from here, and the dark scheme is a\n * progressive enhancement layered on top (see styles.ts).\n *\n * The raw stops are theme.css's; the per-variant mapping below is the same\n * formula theme.css spells out token by token (Joy's createLight/DarkMode\n * VariantVariables, with neutral's -700 plain/outlined override in light).\n * The parity tests in src/visual/email/*.visual.test.tsx compare every email\n * component against its web counterpart in both schemes, so a drift between\n * the two shows up as a failing computed-style assertion.\n */\n\nexport type EmailColor = 'primary' | 'neutral' | 'danger' | 'success' | 'warning';\nexport type EmailVariant = 'solid' | 'soft' | 'outlined' | 'plain';\nexport type EmailScheme = 'light' | 'dark';\n\ntype Stop = 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;\n\nexport const emailPalette: Record<EmailColor, Record<Stop, string>> = {\n neutral: { 50: '#FBFCFE', 100: '#F0F4F8', 200: '#DDE7EE', 300: '#CDD7E1', 400: '#9FA6AD', 500: '#636B74', 600: '#555E68', 700: '#32383E', 800: '#171A1C', 900: '#0B0D0E' },\n primary: { 50: '#EDF5FD', 100: '#E3EFFB', 200: '#C7DFF7', 300: '#97C3F0', 400: '#4393E4', 500: '#0B6BCB', 600: '#185EA5', 700: '#12467B', 800: '#0A2744', 900: '#051423' },\n warning: { 50: '#FEFAF6', 100: '#FDF0E1', 200: '#FCE1C2', 300: '#F3C896', 400: '#EA9A3E', 500: '#9A5B13', 600: '#72430D', 700: '#492B08', 800: '#2E1B05', 900: '#1D1002' },\n danger: { 50: '#FEF6F6', 100: '#FCE4E4', 200: '#F7C5C5', 300: '#F09898', 400: '#E47474', 500: '#C41C1C', 600: '#A51818', 700: '#7D1212', 800: '#430A0A', 900: '#240505' },\n success: { 50: '#F6FEF6', 100: '#E3FBE3', 200: '#C7F7C7', 300: '#A1E8A1', 400: '#51BC51', 500: '#1F7A1F', 600: '#136C13', 700: '#0A470A', 800: '#042F04', 900: '#021D02' },\n};\n\nexport const EMAIL_COLORS: EmailColor[] = ['primary', 'neutral', 'danger', 'success', 'warning'];\nexport const EMAIL_VARIANTS: EmailVariant[] = ['solid', 'soft', 'outlined', 'plain'];\n\n/** What one variant × colour paints. `undefined` means \"leaves it to the surroundings\". */\nexport interface EmailVariantTokens {\n color: string;\n backgroundColor?: string;\n borderColor?: string;\n}\n\nexport function variantTokens(scheme: EmailScheme, variant: EmailVariant, color: EmailColor): EmailVariantTokens {\n const c = emailPalette[color];\n const dark = scheme === 'dark';\n switch (variant) {\n case 'solid':\n return { color: '#FFFFFF', backgroundColor: c[500] };\n case 'soft':\n return dark ? { color: c[200], backgroundColor: c[800] } : { color: c[700], backgroundColor: c[100] };\n case 'outlined':\n return dark\n ? { color: c[200], borderColor: c[700] }\n : { color: color === 'neutral' ? c[700] : c[500], borderColor: c[300] };\n case 'plain':\n return { color: dark ? c[300] : color === 'neutral' ? c[700] : c[500] };\n }\n}\n\n/** `--color-*-main`: step 500 in light, 400 in dark. What Link renders. */\nexport function mainColor(scheme: EmailScheme, color: EmailColor): string {\n return emailPalette[color][scheme === 'dark' ? 400 : 500];\n}\n\nexport interface EmailSchemeTokens {\n inkPrimary: string;\n inkSecondary: string;\n inkTertiary: string;\n /** `--color-ink-icon`: the faintest ink. */\n inkIcon: string;\n /** `--color-surface`: what a Sheet / Card paints under outlined and plain. */\n surface: string;\n /** `--color-surface-1`. */\n surface1: string;\n /**\n * `--color-divider`. Kept as the rgba() theme.css uses so it composites the\n * same way over any surface; Outlook's Word engine drops rgba(), which is\n * why Divider also sets a solid `dividerFallback`.\n */\n divider: string;\n /** `divider` flattened onto `surface`. */\n dividerFallback: string;\n}\n\nexport const emailSchemes: Record<EmailScheme, EmailSchemeTokens> = {\n light: {\n inkPrimary: emailPalette.neutral[800],\n inkSecondary: emailPalette.neutral[700],\n inkTertiary: emailPalette.neutral[600],\n inkIcon: emailPalette.neutral[500],\n surface: emailPalette.neutral[50],\n surface1: emailPalette.neutral[100],\n divider: 'rgba(99, 107, 116, 0.2)',\n dividerFallback: '#DCDFE2',\n },\n dark: {\n inkPrimary: emailPalette.neutral[100],\n inkSecondary: emailPalette.neutral[300],\n inkTertiary: emailPalette.neutral[400],\n inkIcon: emailPalette.neutral[400],\n surface: emailPalette.neutral[900],\n surface1: emailPalette.neutral[800],\n divider: 'rgba(159, 166, 173, 0.16)',\n dividerFallback: '#232628',\n },\n};\n\nexport const emailFonts = {\n // `--font-body`.\n body: \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\",\n // core's `--font-heading`. Only clients with the font installed or web-font\n // support (Apple Mail) show Montserrat; the rest fall back to the body stack.\n heading: \"Montserrat, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\",\n};\n\n/** theme.css's radius scale. */\nexport const emailRadius = { xs: '2px', sm: '6px', md: '8px', lg: '12px', xl: '16px' };\n","/*\n * Every link in an email is a link someone may click without a second look —\n * a security alert's \"review this activity\" button most of all. React escapes\n * text but not the scheme of an href, so a `javascript:` or `data:` URL that\n * reached a template through data would survive rendering intact. Only these\n * schemes are let through; anything else renders as plain, unlinked text.\n */\nconst LINK_PROTOCOLS = new Set(['https:', 'http:', 'mailto:']);\n\nexport function safeHref(href: string | undefined | null): string | undefined {\n if (!href) return undefined;\n try {\n const url = new URL(href);\n return LINK_PROTOCOLS.has(url.protocol) ? url.href : undefined;\n } catch {\n // Relative URLs are meaningless in an email: there is no base to resolve\n // them against once the message leaves the server.\n return undefined;\n }\n}\n\n/** Images additionally have to be https: mail clients block or warn on http. */\nexport function safeImageSrc(src: string | undefined | null): string | undefined {\n if (!src) return undefined;\n try {\n const url = new URL(src);\n return url.protocol === 'https:' ? url.href : undefined;\n } catch {\n return undefined;\n }\n}\n","import {\n EMAIL_COLORS,\n EMAIL_VARIANTS,\n emailSchemes,\n mainColor,\n variantTokens,\n type EmailColor,\n type EmailVariant,\n} from './tokens';\n\n/*\n * Inline styles carry the light scheme, so an email always renders correctly\n * even where <style> is stripped. Dark mode is a progressive enhancement: each\n * painted element also carries a class from here, and the stylesheet below\n * overrides it — `!important` because it has to beat the inline value.\n *\n * Two triggers, deliberately:\n * - `prefers-color-scheme: dark`, which Apple Mail, iOS Mail, Outlook for\n * Mac and Thunderbird honour. Guarded by `:not([data-color-scheme=\"light\"])`\n * so a preview forced to light stays light on a dark OS.\n * - `[data-color-scheme=\"dark\"]` on any ancestor — the same switch the\n * component library uses, so an email component rendered inside the docs\n * or a visual test follows the page's scheme.\n *\n * Gmail and Outlook.com ignore both and apply their own colour inversion,\n * which is out of any template's control.\n */\nexport const emailClass = {\n variant: (variant: EmailVariant, color: EmailColor) => `hx-${variant}-${color}`,\n main: (color: EmailColor) => `hx-main-${color}`,\n inkPrimary: 'hx-ink-1',\n inkSecondary: 'hx-ink-2',\n inkTertiary: 'hx-ink-3',\n inkIcon: 'hx-ink-icon',\n surface: 'hx-surface',\n divider: 'hx-divider',\n // Layout's AuthScreen shell: page and card swap surfaces in dark.\n layoutCanvas: 'hx-layout-canvas',\n layoutCard: 'hx-layout-card',\n // The card's inner area, which carries its padding. A div of our own rather\n // than react-email's cell: Container moves its `padding` onto an inner <td>,\n // so a rule on the card itself added to it instead of replacing it.\n layoutCardBody: 'hx-layout-card-body',\n // A logo pair: the light one shows by default, the dark one only once the\n // dark rules apply — clients without <style> support keep the light logo.\n logoLight: 'hx-logo-light',\n logoDark: 'hx-logo-dark',\n} as const;\n\nfunction darkRules(scope: string): string {\n const t = emailSchemes.dark;\n const rule = (selector: string, body: string) => `${scope} .${selector}{${body}}`;\n const rules = [\n rule(emailClass.inkPrimary, `color:${t.inkPrimary}!important;`),\n rule(emailClass.inkSecondary, `color:${t.inkSecondary}!important;`),\n rule(emailClass.inkTertiary, `color:${t.inkTertiary}!important;`),\n rule(emailClass.inkIcon, `color:${t.inkIcon}!important;`),\n rule(emailClass.surface, `background-color:${t.surface}!important;`),\n rule(emailClass.divider, `background-color:${t.divider}!important;`),\n rule(emailClass.layoutCanvas, `background-color:${t.surface}!important;`),\n // react-email's Body repeats its inline style on an inner wrapper cell\n // that carries no class, so the canvas colour has to reach it too.\n rule(`${emailClass.layoutCanvas}>table>tbody>tr>td`, `background-color:${t.surface}!important;`),\n rule(emailClass.logoLight, 'display:none!important;'),\n rule(emailClass.logoDark, 'display:inline-block!important;'),\n rule(emailClass.layoutCard,`background-color:${t.surface1}!important;border-color:${variantTokens('dark', 'outlined', 'neutral').borderColor}!important;`),\n ];\n for (const color of EMAIL_COLORS) {\n rules.push(rule(emailClass.main(color), `color:${mainColor('dark', color)}!important;`));\n for (const variant of EMAIL_VARIANTS) {\n const v = variantTokens('dark', variant, color);\n rules.push(\n rule(\n emailClass.variant(variant, color),\n [\n `color:${v.color}!important;`,\n v.backgroundColor && `background-color:${v.backgroundColor}!important;`,\n v.borderColor && `border-color:${v.borderColor}!important;`,\n ]\n .filter(Boolean)\n .join(''),\n ),\n );\n }\n }\n return rules.join('');\n}\n\n/*\n * AuthScreen's phone layout: the card stops being a card. It fills the width,\n * loses border and radius, insets its content by 24px, and the page around it\n * takes the card's colour — surface in light, surface-1 in dark. Last in the\n * sheet so it wins over the dark rules at equal specificity.\n */\nfunction phoneRules(): string {\n const canvas = (scope: string) => `${scope}.${emailClass.layoutCanvas},${scope}.${emailClass.layoutCanvas}>table>tbody>tr>td`;\n const dark = (scope: string) => `${canvas(scope)}{background-color:${emailSchemes.dark.surface1}!important;}`;\n return [\n `@media only screen and (max-width:600px){`,\n `.${emailClass.layoutCard}{max-width:100%!important;border:0!important;border-radius:0!important;}`,\n `.${emailClass.layoutCardBody}{padding:32px 24px!important;}`,\n `${canvas('')}{padding:0!important;background-color:${emailSchemes.light.surface}!important;}`,\n dark('[data-color-scheme=\"dark\"] '),\n `}`,\n `@media only screen and (max-width:600px) and (prefers-color-scheme:dark){${dark(':root:not([data-color-scheme=\"light\"]) ')}}`,\n ].join('');\n}\n\nexport const emailStylesheet = [\n // iOS turns dates and addresses into blue links that ignore the text colour.\n 'a[x-apple-data-detectors]{color:inherit!important;text-decoration:none!important;}',\n `@media (prefers-color-scheme:dark){${darkRules(':root:not([data-color-scheme=\"light\"])')}}`,\n darkRules('[data-color-scheme=\"dark\"]'),\n phoneRules(),\n].join('\\n');\n","import * as React from 'react';\nimport { Body, Container, Head, Html, Preview } from 'react-email';\nimport { emailClass, emailStylesheet } from '../styles';\nimport { emailFonts, emailSchemes, variantTokens } from '../tokens';\n\nexport interface LayoutProps {\n /** The `lang` of the message — screen readers pick their voice from it. */\n lang: string;\n /**\n * The line inbox lists show after the subject. Without one, clients take the\n * first text they find, which is usually the brand name.\n */\n preview: string;\n /** Rendered under the card: why the reader got this, the sender's legal line. */\n footer?: React.ReactNode;\n /** Forces a scheme for previews. Left out, the email follows the reader's OS where the client supports that. */\n colorScheme?: 'light' | 'dark';\n children: React.ReactNode;\n}\n\n/**\n * The whole document, laid out like core's AuthScreen: a 440px outlined card\n * with a 20px radius and 48px padding on a `surface-1` page, the fine print\n * centred under it. In dark the page and card swap surfaces, as AuthScreen's do.\n */\nexport function Layout({ lang, preview, footer, colorScheme, children }: LayoutProps) {\n const t = emailSchemes.light;\n return (\n <Html lang={lang} data-color-scheme={colorScheme}>\n <Head>\n <meta name=\"color-scheme\" content=\"light dark\" />\n <meta name=\"supported-color-schemes\" content=\"light dark\" />\n <ColorSchemeStyles />\n </Head>\n <Preview>{preview}</Preview>\n <Body className={emailClass.layoutCanvas} style={{ margin: 0, padding: '40px 0', backgroundColor: t.surface1, fontFamily: emailFonts.body }}>\n <Container\n className={emailClass.layoutCard}\n style={{\n width: '100%',\n maxWidth: '440px',\n boxSizing: 'border-box',\n backgroundColor: t.surface,\n border: `1px solid ${variantTokens('light', 'outlined', 'neutral').borderColor}`,\n borderRadius: '20px',\n }}\n >\n <div className={emailClass.layoutCardBody} style={{ padding: '48px' }}>\n {children}\n </div>\n </Container>\n {footer && <Container style={{ maxWidth: '440px', padding: '24px 24px 0', textAlign: 'center' }}>{footer}</Container>}\n </Body>\n </Html>\n );\n}\n\n/**\n * The dark-mode stylesheet on its own. Layout includes it; render it\n * once yourself when email components are shown inside a normal page — a\n * preview, the docs — so they follow that page's `data-color-scheme`.\n */\nexport function ColorSchemeStyles() {\n return <style dangerouslySetInnerHTML={{ __html: emailStylesheet }} />;\n}\n","import * as React from 'react';\nimport { emailClass } from '../styles';\nimport { emailFonts, emailSchemes } from '../tokens';\n\nexport type TypographyLevel =\n | 'h1'\n | 'h2'\n | 'h3'\n | 'h4'\n | 'title-lg'\n | 'title-md'\n | 'title-sm'\n | 'body-lg'\n | 'body-md'\n | 'body-sm'\n | 'body-xs';\n\ntype Ink = 'inkPrimary' | 'inkSecondary' | 'inkTertiary' | 'inkIcon';\n\n/*\n * Typography's typographyVariants.ts, resolved: Tailwind's text-4xl…text-xs\n * in px, its font-bold/semibold/medium as numbers, `tracking-tight` as\n * -0.025em, and the same unitless line-heights (1.33334, 1.5, 1.42858), so the\n * computed line box matches the web component to the sub-pixel.\n */\nconst LEVELS: Record<TypographyLevel, { fontSize: string; fontWeight: number; lineHeight: number; letterSpacing?: string; ink: Ink }> = {\n h1: { fontSize: '36px', fontWeight: 700, lineHeight: 1.33334, letterSpacing: '-0.025em', ink: 'inkPrimary' },\n h2: { fontSize: '30px', fontWeight: 700, lineHeight: 1.33334, letterSpacing: '-0.025em', ink: 'inkPrimary' },\n h3: { fontSize: '24px', fontWeight: 600, lineHeight: 1.33334, letterSpacing: '-0.025em', ink: 'inkPrimary' },\n h4: { fontSize: '20px', fontWeight: 600, lineHeight: 1.5, letterSpacing: '-0.025em', ink: 'inkPrimary' },\n 'title-lg': { fontSize: '18px', fontWeight: 600, lineHeight: 1.33334, ink: 'inkPrimary' },\n 'title-md': { fontSize: '16px', fontWeight: 500, lineHeight: 1.5, ink: 'inkPrimary' },\n 'title-sm': { fontSize: '14px', fontWeight: 500, lineHeight: 1.42858, ink: 'inkPrimary' },\n 'body-lg': { fontSize: '18px', fontWeight: 400, lineHeight: 1.5, ink: 'inkSecondary' },\n 'body-md': { fontSize: '16px', fontWeight: 400, lineHeight: 1.5, ink: 'inkSecondary' },\n 'body-sm': { fontSize: '14px', fontWeight: 400, lineHeight: 1.5, ink: 'inkTertiary' },\n 'body-xs': { fontSize: '12px', fontWeight: 500, lineHeight: 1.5, ink: 'inkTertiary' },\n};\n\nconst DEFAULT_TAG: Record<TypographyLevel, 'h1' | 'h2' | 'h3' | 'h4' | 'p' | 'span'> = {\n h1: 'h1',\n h2: 'h2',\n h3: 'h3',\n h4: 'h4',\n 'title-lg': 'p',\n 'title-md': 'p',\n 'title-sm': 'p',\n 'body-lg': 'p',\n 'body-md': 'p',\n 'body-sm': 'p',\n 'body-xs': 'span',\n};\n\nexport interface TypographyProps {\n level?: TypographyLevel;\n /** The element to render. Defaults to the same tag the web Typography picks for the level. */\n component?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'div';\n textAlign?: 'left' | 'center' | 'right';\n /**\n * Overrides the level's ink, like Joy's `textColor=\"text.tertiary\"`.\n * `icon` is the theme's faintest ink — for fine print that should recede.\n */\n textColor?: 'primary' | 'secondary' | 'tertiary' | 'icon';\n /** Margin, spacing and the like — there is no Stack in email, so spacing lives on the text. */\n style?: React.CSSProperties;\n children?: React.ReactNode;\n}\n\nconst TEXT_COLOR: Record<NonNullable<TypographyProps['textColor']>, Ink> = {\n primary: 'inkPrimary',\n secondary: 'inkSecondary',\n tertiary: 'inkTertiary',\n icon: 'inkIcon',\n};\n\n/** Typography for email: the same levels, sizes and ink colours, as inline styles. */\nexport function Typography({ level = 'body-md', component, textAlign, textColor, style, children }: TypographyProps) {\n const spec = LEVELS[level];\n const ink = textColor ? TEXT_COLOR[textColor] : spec.ink;\n const Tag = component ?? DEFAULT_TAG[level];\n return (\n <Tag\n className={emailClass[ink]}\n style={{\n margin: 0,\n fontFamily: emailFonts.body,\n fontSize: spec.fontSize,\n fontWeight: spec.fontWeight,\n lineHeight: spec.lineHeight,\n letterSpacing: spec.letterSpacing,\n color: emailSchemes.light[ink],\n textAlign,\n ...style,\n }}\n >\n {children}\n </Tag>\n );\n}\n","import * as React from 'react';\nimport { Button as ReactEmailButton } from 'react-email';\nimport { emailClass } from '../styles';\nimport { emailFonts, emailRadius, variantTokens, type EmailColor, type EmailVariant } from '../tokens';\nimport { safeHref } from '../safeUrl';\n\n/*\n * buttonVariants.ts, resolved. The web Button gets its height from\n * `min-h-8/9/11` and centres the label with flexbox; email has neither, so the\n * same box is built from line-height plus vertical padding:\n * (min-height − line-height) / 2, less the 1px border for outlined.\n */\nconst SIZES = {\n sm: { minHeight: 32, paddingInline: 12, fontSize: 14, lineHeight: 21 },\n md: { minHeight: 36, paddingInline: 16, fontSize: 14, lineHeight: 21 },\n lg: { minHeight: 44, paddingInline: 24, fontSize: 16, lineHeight: 24 },\n} as const;\n\nexport interface ButtonProps {\n /** Rendered only for http(s) URLs; anything else renders nothing — a button nobody can follow is worse than none. */\n href: string;\n variant?: EmailVariant;\n color?: EmailColor;\n size?: keyof typeof SIZES;\n /** `rounded-full`, as on the web Button. */\n pill?: boolean;\n /** Stretches to the container — the usual call-to-action layout in a narrow email. */\n fullWidth?: boolean;\n style?: React.CSSProperties;\n children: React.ReactNode;\n}\n\n/** Button for email: a link styled as the web Button, built on react-email's Outlook-safe Button. */\nexport function Button({ href, variant = 'solid', color = 'primary', size = 'md', pill = false, fullWidth = false, style, children }: ButtonProps) {\n const safe = safeHref(href);\n if (!safe || safe.startsWith('mailto:')) return null;\n const s = SIZES[size];\n const v = variantTokens('light', variant, color);\n const border = variant === 'outlined' ? 1 : 0;\n const paddingBlock = (s.minHeight - s.lineHeight) / 2 - border;\n return (\n <ReactEmailButton\n href={safe}\n className={emailClass.variant(variant, color)}\n style={{\n display: fullWidth ? 'block' : 'inline-block',\n boxSizing: 'border-box',\n width: fullWidth ? '100%' : undefined,\n textAlign: 'center',\n paddingTop: `${paddingBlock}px`,\n paddingBottom: `${paddingBlock}px`,\n paddingLeft: `${s.paddingInline}px`,\n paddingRight: `${s.paddingInline}px`,\n fontFamily: emailFonts.body,\n fontSize: `${s.fontSize}px`,\n fontWeight: 600,\n lineHeight: `${s.lineHeight}px`,\n textDecoration: 'none',\n borderRadius: pill ? '9999px' : emailRadius.sm,\n color: v.color,\n backgroundColor: v.backgroundColor ?? 'transparent',\n border: v.borderColor ? `1px solid ${v.borderColor}` : undefined,\n ...style,\n }}\n >\n {/* react-email wraps the label in its own inline-block span at\n line-height 120%. In the modes mail is actually shown in — the\n limited-quirks mode its XHTML doctype yields, or full quirks where a\n webmail drops the doctype — the link's own line-height no longer\n props the line up, so the button shrank to 120% of the font plus\n padding: 4–5px short at every size. This span carries the full\n line-height itself, so the box no longer depends on the mode. */}\n <span style={{ display: 'inline-block', lineHeight: `${s.lineHeight}px` }}>{children}</span>\n </ReactEmailButton>\n );\n}\n","import * as React from 'react';\nimport { Link as ReactEmailLink } from 'react-email';\nimport { emailClass } from '../styles';\nimport { emailFonts, mainColor, type EmailColor } from '../tokens';\nimport { safeHref } from '../safeUrl';\n\nexport interface LinkProps {\n /** Rendered only for http(s) and mailto URLs; anything else becomes plain text. */\n href: string;\n color?: EmailColor;\n /**\n * The web Link defaults to `hover`, but there is no reliable hover in email,\n * so the default here is `always`: an inbox reader needs to see a link is\n * one without touching it.\n */\n underline?: 'none' | 'always';\n style?: React.CSSProperties;\n children: React.ReactNode;\n}\n\n/** Link for email: the web Link's `--color-*-main` colour, which steps from 500 to 400 in dark. */\nexport function Link({ href, color = 'primary', underline = 'always', style, children }: LinkProps) {\n const safe = safeHref(href);\n if (!safe) return <>{children}</>;\n return (\n <ReactEmailLink\n href={safe}\n className={emailClass.main(color)}\n style={{ fontFamily: emailFonts.body, color: mainColor('light', color), textDecoration: underline === 'always' ? 'underline' : 'none', wordBreak: 'break-word', ...style }}\n >\n {children}\n </ReactEmailLink>\n );\n}\n","import * as React from 'react';\nimport { emailClass } from '../styles';\nimport { emailSchemes } from '../tokens';\n\nexport interface DividerProps {\n /** Spacing around the line — the web Divider has none of its own either. */\n style?: React.CSSProperties;\n}\n\n/**\n * Divider for email: a 1px line in `--color-divider`. A div rather than an\n * <hr>, whose borders Outlook and Gmail each draw differently. `background`\n * carries a solid fallback that Outlook's Word engine — which drops rgba() —\n * keeps; every other client takes the rgba `background-color` after it.\n */\nexport function Divider({ style }: DividerProps) {\n const t = emailSchemes.light;\n return (\n <div\n role=\"separator\"\n className={emailClass.divider}\n style={{ height: '1px', lineHeight: '1px', fontSize: '1px', background: t.dividerFallback, backgroundColor: t.divider, border: 'none', margin: 0, ...style }}\n >\n \n </div>\n );\n}\n","import * as React from 'react';\nimport { emailClass } from '../styles';\nimport { emailFonts, emailRadius, emailSchemes, variantTokens, type EmailColor, type EmailVariant } from '../tokens';\n\nexport interface CardProps {\n variant?: EmailVariant;\n color?: EmailColor;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n}\n\n/**\n * Card for email: Sheet's variant colours plus Card's own `rounded-md p-4`,\n * defaulting to outlined / neutral like the web Card. Outlined and plain fill\n * with `surface`, as Joy's Sheet does. A one-cell table, because that is the\n * only box Outlook pads reliably; Card's `gap-2` has no email equivalent, so\n * spacing between children is theirs to set.\n */\nexport function Card({ variant = 'outlined', color = 'neutral', style, children }: CardProps) {\n const v = variantTokens('light', variant, color);\n const filled = v.backgroundColor !== undefined;\n return (\n <table\n role=\"presentation\"\n width=\"100%\"\n cellPadding={0}\n cellSpacing={0}\n border={0}\n className={[emailClass.variant(variant, color), filled ? '' : emailClass.surface].filter(Boolean).join(' ')}\n style={{\n borderCollapse: 'separate',\n borderRadius: emailRadius.md,\n backgroundColor: v.backgroundColor ?? emailSchemes.light.surface,\n color: v.color,\n border: v.borderColor ? `1px solid ${v.borderColor}` : undefined,\n fontFamily: emailFonts.body,\n ...style,\n }}\n >\n <tbody>\n <tr>\n <td style={{ padding: '16px' }}>{children}</td>\n </tr>\n </tbody>\n </table>\n );\n}\n","import * as React from 'react';\nimport { Img } from 'react-email';\nimport { emailClass } from '../styles';\nimport { emailFonts, variantTokens, type EmailColor, type EmailVariant } from '../tokens';\nimport { safeImageSrc } from '../safeUrl';\n\n/** avatarVariants.ts: 32/40/48px boxes, text-sm/base/lg, medium/medium/semibold. */\nconst SIZES = {\n sm: { box: 32, fontSize: '14px', fontWeight: 500 },\n md: { box: 40, fontSize: '16px', fontWeight: 500 },\n lg: { box: 48, fontSize: '18px', fontWeight: 600 },\n} as const;\n\nexport interface AvatarProps {\n variant?: EmailVariant;\n color?: EmailColor;\n size?: keyof typeof SIZES;\n /** An https image. Without one, `children` (usually initials) is shown. */\n src?: string;\n alt?: string;\n children?: React.ReactNode;\n}\n\n/**\n * Avatar for email, defaulting to soft / neutral like the web Avatar. Unlike\n * Card, outlined and plain stay transparent — Joy's Avatar has no surface\n * fallback. The initials are centred by a table cell, since email has no flexbox.\n */\nexport function Avatar({ variant = 'soft', color = 'neutral', size = 'md', src, alt = '', children }: AvatarProps) {\n const s = SIZES[size];\n const safe = safeImageSrc(src);\n if (safe) {\n return <Img src={safe} width={s.box} height={s.box} alt={alt} style={{ display: 'inline-block', borderRadius: '50%', objectFit: 'cover' }} />;\n }\n const v = variantTokens('light', variant, color);\n return (\n <table\n role=\"presentation\"\n cellPadding={0}\n cellSpacing={0}\n border={0}\n className={emailClass.variant(variant, color)}\n style={{\n display: 'inline-table',\n boxSizing: 'border-box',\n width: `${s.box}px`,\n height: `${s.box}px`,\n borderCollapse: 'separate',\n borderRadius: '50%',\n backgroundColor: v.backgroundColor ?? 'transparent',\n color: v.color,\n border: v.borderColor ? `1px solid ${v.borderColor}` : undefined,\n fontFamily: emailFonts.body,\n fontSize: s.fontSize,\n fontWeight: s.fontWeight,\n lineHeight: 1,\n verticalAlign: 'middle',\n }}\n >\n <tbody>\n <tr>\n <td align=\"center\" style={{ padding: 0, verticalAlign: 'middle', textAlign: 'center' }}>\n {children}\n </td>\n </tr>\n </tbody>\n </table>\n );\n}\n","import * as React from 'react';\nimport { emailClass } from '../styles';\nimport { emailFonts, emailSchemes, variantTokens, type EmailColor, type EmailVariant } from '../tokens';\n\n/**\n * chipVariants.ts: `min-h-5/6/7`, `px-1.5/2/3`, `text-xs/sm/base` at a 1.5\n * line-height. As with Button, the min-height becomes vertical padding.\n */\nconst SIZES = {\n sm: { minHeight: 20, paddingInline: 6, fontSize: 12 },\n md: { minHeight: 24, paddingInline: 8, fontSize: 14 },\n lg: { minHeight: 28, paddingInline: 12, fontSize: 16 },\n} as const;\n\nexport interface ChipProps {\n variant?: EmailVariant;\n color?: EmailColor;\n size?: keyof typeof SIZES;\n style?: React.CSSProperties;\n children: React.ReactNode;\n}\n\n/** Chip for email, defaulting to soft / neutral like the web Chip; outlined and plain fill with `surface`. */\nexport function Chip({ variant = 'soft', color = 'neutral', size = 'md', style, children }: ChipProps) {\n const s = SIZES[size];\n const v = variantTokens('light', variant, color);\n const filled = v.backgroundColor !== undefined;\n const border = v.borderColor ? 1 : 0;\n const lineHeight = s.fontSize * 1.5;\n const paddingBlock = (s.minHeight - lineHeight) / 2 - border;\n return (\n <span\n className={[emailClass.variant(variant, color), filled ? '' : emailClass.surface].filter(Boolean).join(' ')}\n style={{\n display: 'inline-block',\n boxSizing: 'border-box',\n whiteSpace: 'nowrap',\n verticalAlign: 'middle',\n padding: `${paddingBlock}px ${s.paddingInline}px`,\n borderRadius: '1.5rem',\n fontFamily: emailFonts.body,\n fontSize: `${s.fontSize}px`,\n fontWeight: 500,\n lineHeight: 1.5,\n color: v.color,\n backgroundColor: v.backgroundColor ?? emailSchemes.light.surface,\n border: v.borderColor ? `1px solid ${v.borderColor}` : undefined,\n ...style,\n }}\n >\n {children}\n </span>\n );\n}\n","import { Img } from 'react-email';\nimport { emailClass } from '../styles';\n\n/*\n * The hintoric wordmark as hosted PNGs (1336 × 410 artwork, shown at 104 × 32\n * so it stays sharp on HiDPI screens). PNG rather than SVG, which Gmail and\n * desktop Outlook don't display; linked rather than attached, so messages stay\n * small. A client that blocks remote images until asked shows the alt text.\n */\nconst LOGO = {\n light: 'https://cdn.hintoric.com/assets/logo/black.png',\n dark: 'https://cdn.hintoric.com/assets/logo/white.png',\n width: 104,\n height: 32,\n};\n\n/**\n * The email counterpart of the web HintoricLogo: the black wordmark, swapped\n * for the white one where the client applies the dark stylesheet.\n */\nexport function HintoricLogo() {\n return (\n <>\n <Img\n src={LOGO.light}\n width={LOGO.width}\n height={LOGO.height}\n alt=\"hintoric\"\n className={emailClass.logoLight}\n style={{ display: 'inline-block', margin: '0 auto' }}\n />\n <Img\n src={LOGO.dark}\n width={LOGO.width}\n height={LOGO.height}\n alt=\"hintoric\"\n className={emailClass.logoDark}\n style={{ display: 'none', margin: '0 auto' }}\n />\n </>\n );\n}\n","import { Avatar } from '../../components/Avatar';\nimport { Button } from '../../components/Button';\nimport { Divider } from '../../components/Divider';\nimport { Layout } from '../../components/Layout';\nimport { Link } from '../../components/Link';\nimport { Typography } from '../../components/Typography';\nimport { HintoricLogo } from '../../components/HintoricLogo';\nimport { renderEmail } from '../../render';\nimport { emailFonts } from '../../tokens';\nimport type { SecurityActivityAlertContext, SecurityActivityAlertProps } from './types';\n\nfunction contextOf(props: SecurityActivityAlertProps): SecurityActivityAlertContext {\n return {\n activity: props.activity,\n target: props.target,\n targetName: targetNameOf(props),\n occurredAt: props.messages.formatDateTime(props.activity.occurredAt, props.timeZone),\n };\n}\n\nfunction targetNameOf({ target }: SecurityActivityAlertProps): string {\n return target.type === 'workspace' ? target.workspaceName : target.email;\n}\n\nfunction initials(name: string): string {\n return name\n .split(/\\s+/)\n .filter(Boolean)\n .slice(0, 2)\n .map((word) => word[0]!.toUpperCase())\n .join('');\n}\n\n/**\n * For security-relevant activity: a change in a workspace (sent to its\n * admins) or to an account (sent to its owner) — see `SecurityActivityTarget`.\n * Deliberately short: what happened as the heading, what it concerns, one\n * sentence, one button, one link.\n */\nexport function SecurityActivityAlertEmail(props: SecurityActivityAlertProps) {\n const { messages } = props;\n const ctx = contextOf(props);\n return (\n <Layout\n lang={messages.lang}\n preview={messages.preview(ctx)}\n colorScheme={props.colorScheme}\n footer={\n <Typography level=\"body-xs\" component=\"p\" textAlign=\"center\" textColor=\"icon\" style={{ fontWeight: 400 }}>\n {messages.footer(ctx)}\n {props.legalNotice && (\n <>\n <br />\n {props.legalNotice}\n </>\n )}\n </Typography>\n }\n >\n <SecurityActivityAlertContent {...props} />\n </Layout>\n );\n}\n\n/** What goes inside the card, without the document — for in-app previews (render `ColorSchemeStyles` next to it). */\nexport function SecurityActivityAlertContent(props: SecurityActivityAlertProps) {\n const { messages, activityLogUrl } = props;\n const ctx = contextOf(props);\n return (\n <>\n <div style={{ textAlign: 'center' }}>\n <HintoricLogo />\n <Typography level=\"h3\" component=\"h1\" style={{ margin: '16px 0 12px', fontFamily: emailFonts.heading }}>\n {props.activity.title}\n </Typography>\n {/* primary, not the default neutral: in dark the layout card is surface-1,\n exactly the soft-neutral avatar fill, which would make it vanish. */}\n <Avatar size=\"sm\" color=\"primary\">\n {initials(ctx.targetName)}\n </Avatar>\n <Typography level=\"title-sm\" component=\"span\" style={{ marginLeft: '8px', verticalAlign: 'middle' }}>\n {ctx.targetName}\n </Typography>\n </div>\n <Divider style={{ margin: '32px 0' }} />\n <Typography level=\"body-sm\" style={{ marginBottom: '24px' }}>\n {props.activity.description?.trim() || messages.summary(ctx)} {messages.guidance(ctx)}\n </Typography>\n <Button href={props.reviewUrl} size=\"lg\" fullWidth>\n {messages.reviewButton}\n </Button>\n {activityLogUrl && (\n <Typography level=\"body-xs\" component=\"p\" textAlign=\"center\" style={{ marginTop: '24px', fontWeight: 400 }}>\n {messages.activityLogHint((label) => (\n <Link href={activityLogUrl} underline=\"none\">\n {label}\n </Link>\n ))}\n </Typography>\n )}\n </>\n );\n}\n\nexport interface RenderedEmail {\n subject: string;\n html: string;\n text: string;\n}\n\n/** Subject, HTML and plain-text body in one call — what a mail API's send() takes. */\nexport async function renderSecurityActivityAlert(props: SecurityActivityAlertProps): Promise<RenderedEmail> {\n const { html, text } = await renderEmail(<SecurityActivityAlertEmail {...props} />);\n return { subject: props.messages.subject(contextOf(props)), html, text };\n}\n","import type { SecurityActivityAlertMessages } from './types';\n\nfunction dateTimeFormatter(locale: string) {\n return (date: Date, timeZone: string) =>\n new Intl.DateTimeFormat(locale, { dateStyle: 'long', timeStyle: 'short', timeZone }).format(date);\n}\n\nexport const securityActivityAlertMessagesDe: SecurityActivityAlertMessages = {\n lang: 'de',\n subject: ({ activity, targetName }) => `${activity.title} – ${targetName}`,\n preview: ({ activity, occurredAt }) => `${activity.actorName} · ${occurredAt}`,\n summary: ({ activity, occurredAt }) => `${activity.actorName} hat am ${occurredAt} eine sicherheitsrelevante Änderung vorgenommen.`,\n guidance: () => 'Wenn du diese Änderung nicht erwartet hast, prüfe die Aktivität jetzt.',\n reviewButton: 'Aktivität prüfen',\n activityLogHint: (link) => <>Alle sicherheitsrelevanten Aktivitäten findest du im {link('Aktivitätsprotokoll')}.</>,\n footer: ({ target }) =>\n target.type === 'workspace'\n ? 'Wir haben dir diese E-Mail gesendet, um dich als Administrator über wichtige Änderungen in deinem Workspace zu informieren.'\n : 'Wir haben dir diese E-Mail gesendet, um dich über wichtige Änderungen an deinem hintoric-Konto zu informieren.',\n formatDateTime: dateTimeFormatter('de-DE'),\n};\n\nexport const securityActivityAlertMessagesEn: SecurityActivityAlertMessages = {\n lang: 'en',\n subject: ({ activity, targetName }) => `${activity.title} – ${targetName}`,\n preview: ({ activity, occurredAt }) => `${activity.actorName} · ${occurredAt}`,\n summary: ({ activity, occurredAt }) => `${activity.actorName} made a security-relevant change on ${occurredAt}.`,\n guidance: () => \"If you didn't expect this change, review the activity now.\",\n reviewButton: 'Review activity',\n activityLogHint: (link) => <>You can see all security-relevant activity in the {link('activity log')}.</>,\n footer: ({ target }) =>\n target.type === 'workspace'\n ? 'We sent you this email to let you know, as an admin, about important changes in your workspace.'\n : 'We sent you this email to let you know about important changes to your hintoric account.',\n formatDateTime: dateTimeFormatter('en-GB'),\n};\n"],"mappings":"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"}
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
export interface RenderedEmailBody {
|
|
3
|
+
html: string;
|
|
4
|
+
/** The plain-text part. Multipart mails without one score worse with spam filters. */
|
|
5
|
+
text: string;
|
|
6
|
+
}
|
|
7
|
+
/** Renders an email element — normally a `<Layout>` — to HTML and plain text. */
|
|
8
|
+
export declare function renderEmail(element: React.ReactElement): Promise<RenderedEmailBody>;
|
|
9
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAGpC,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,sFAAsF;IACtF,IAAI,EAAE,MAAM,CAAC;CACd;AAED,iFAAiF;AACjF,wBAAsB,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,YAAY,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAGzF"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function safeHref(href: string | undefined | null): string | undefined;
|
|
2
|
+
/** Images additionally have to be https: mail clients block or warn on http. */
|
|
3
|
+
export declare function safeImageSrc(src: string | undefined | null): string | undefined;
|
|
4
|
+
//# sourceMappingURL=safeUrl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safeUrl.d.ts","sourceRoot":"","sources":["../src/safeUrl.ts"],"names":[],"mappings":"AASA,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAU5E;AAED,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAQ/E"}
|
package/dist/styles.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { EmailColor, EmailVariant } from './tokens';
|
|
2
|
+
export declare const emailClass: {
|
|
3
|
+
readonly variant: (variant: EmailVariant, color: EmailColor) => string;
|
|
4
|
+
readonly main: (color: EmailColor) => string;
|
|
5
|
+
readonly inkPrimary: "hx-ink-1";
|
|
6
|
+
readonly inkSecondary: "hx-ink-2";
|
|
7
|
+
readonly inkTertiary: "hx-ink-3";
|
|
8
|
+
readonly inkIcon: "hx-ink-icon";
|
|
9
|
+
readonly surface: "hx-surface";
|
|
10
|
+
readonly divider: "hx-divider";
|
|
11
|
+
readonly layoutCanvas: "hx-layout-canvas";
|
|
12
|
+
readonly layoutCard: "hx-layout-card";
|
|
13
|
+
readonly layoutCardBody: "hx-layout-card-body";
|
|
14
|
+
readonly logoLight: "hx-logo-light";
|
|
15
|
+
readonly logoDark: "hx-logo-dark";
|
|
16
|
+
};
|
|
17
|
+
export declare const emailStylesheet: string;
|
|
18
|
+
//# sourceMappingURL=styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,UAAU,EACf,KAAK,YAAY,EAClB,MAAM,UAAU,CAAC;AAmBlB,eAAO,MAAM,UAAU;gCACF,YAAY,SAAS,UAAU;2BACpC,UAAU;;;;;;;;;;;;CAkBhB,CAAC;AA6DX,eAAO,MAAM,eAAe,QAMhB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SecurityActivityAlertProps } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* For security-relevant activity: a change in a workspace (sent to its
|
|
4
|
+
* admins) or to an account (sent to its owner) — see `SecurityActivityTarget`.
|
|
5
|
+
* Deliberately short: what happened as the heading, what it concerns, one
|
|
6
|
+
* sentence, one button, one link.
|
|
7
|
+
*/
|
|
8
|
+
export declare function SecurityActivityAlertEmail(props: SecurityActivityAlertProps): import("react").JSX.Element;
|
|
9
|
+
/** What goes inside the card, without the document — for in-app previews (render `ColorSchemeStyles` next to it). */
|
|
10
|
+
export declare function SecurityActivityAlertContent(props: SecurityActivityAlertProps): import("react").JSX.Element;
|
|
11
|
+
export interface RenderedEmail {
|
|
12
|
+
subject: string;
|
|
13
|
+
html: string;
|
|
14
|
+
text: string;
|
|
15
|
+
}
|
|
16
|
+
/** Subject, HTML and plain-text body in one call — what a mail API's send() takes. */
|
|
17
|
+
export declare function renderSecurityActivityAlert(props: SecurityActivityAlertProps): Promise<RenderedEmail>;
|
|
18
|
+
//# sourceMappingURL=SecurityActivityAlertEmail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SecurityActivityAlertEmail.d.ts","sourceRoot":"","sources":["../../../src/templates/SecurityActivityAlert/SecurityActivityAlertEmail.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAgC,0BAA0B,EAAE,MAAM,SAAS,CAAC;AAwBxF;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,0BAA0B,+BAuB3E;AAED,qHAAqH;AACrH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,0BAA0B,+BAqC7E;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,sFAAsF;AACtF,wBAAsB,2BAA2B,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,aAAa,CAAC,CAG3G"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { SecurityActivityAlertEmail, SecurityActivityAlertContent, renderSecurityActivityAlert } from './SecurityActivityAlertEmail';
|
|
2
|
+
export type { RenderedEmail } from './SecurityActivityAlertEmail';
|
|
3
|
+
export { securityActivityAlertMessagesDe, securityActivityAlertMessagesEn } from './messages';
|
|
4
|
+
export type { SecurityActivity, SecurityActivityAlertContext, SecurityActivityAlertMessages, SecurityActivityAlertProps, SecurityActivityTarget, } from './types';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/SecurityActivityAlert/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AACrI,YAAY,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,+BAA+B,EAAE,+BAA+B,EAAE,MAAM,YAAY,CAAC;AAC9F,YAAY,EACV,gBAAgB,EAChB,4BAA4B,EAC5B,6BAA6B,EAC7B,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/templates/SecurityActivityAlert/messages.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,SAAS,CAAC;AAO7D,eAAO,MAAM,+BAA+B,EAAE,6BAa7C,CAAC;AAEF,eAAO,MAAM,+BAA+B,EAAE,6BAa7C,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
export interface SecurityActivity {
|
|
3
|
+
/** What happened, short — "Bankverbindung geändert", "Passwort geändert". Becomes the heading and the subject. */
|
|
4
|
+
title: string;
|
|
5
|
+
/** Who did it. */
|
|
6
|
+
actorName: string;
|
|
7
|
+
occurredAt: Date;
|
|
8
|
+
/**
|
|
9
|
+
* Free text for this one activity — "Erika Mustermann hat die IBAN des
|
|
10
|
+
* Geschäftskontos geändert.", "Neue Anmeldung von Chrome auf Windows in
|
|
11
|
+
* Berlin." Replaces `messages.summary`; `messages.guidance` still follows
|
|
12
|
+
* it. Plain text, escaped like everything else.
|
|
13
|
+
*/
|
|
14
|
+
description?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* What the activity concerns, which also decides who gets the mail:
|
|
18
|
+
*
|
|
19
|
+
* - `workspace` — a change in a workspace (bank details, a new admin). Sent to
|
|
20
|
+
* every admin of it.
|
|
21
|
+
* - `account` — a change to one person's account (password changed, sign-in
|
|
22
|
+
* from an unknown device). Sent to that person.
|
|
23
|
+
*/
|
|
24
|
+
export type SecurityActivityTarget = {
|
|
25
|
+
type: 'workspace';
|
|
26
|
+
workspaceName: string;
|
|
27
|
+
} | {
|
|
28
|
+
type: 'account';
|
|
29
|
+
email: string;
|
|
30
|
+
};
|
|
31
|
+
/** What every message function receives. */
|
|
32
|
+
export interface SecurityActivityAlertContext {
|
|
33
|
+
activity: SecurityActivity;
|
|
34
|
+
target: SecurityActivityTarget;
|
|
35
|
+
/** The workspace name or the account's email — what is shown under the heading. */
|
|
36
|
+
targetName: string;
|
|
37
|
+
/** `occurredAt`, already formatted with `formatDateTime` in the given zone. */
|
|
38
|
+
occurredAt: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Every string the template shows. There are no built-in defaults — like the
|
|
42
|
+
* library's other blocks, the template doesn't decide what language its
|
|
43
|
+
* consumers speak. Pass `securityActivityAlertMessagesDe` /
|
|
44
|
+
* `securityActivityAlertMessagesEn`, or spread one and override what differs.
|
|
45
|
+
*/
|
|
46
|
+
export interface SecurityActivityAlertMessages {
|
|
47
|
+
/** BCP 47 tag for `<html lang>`. */
|
|
48
|
+
lang: string;
|
|
49
|
+
subject: (ctx: SecurityActivityAlertContext) => string;
|
|
50
|
+
preview: (ctx: SecurityActivityAlertContext) => string;
|
|
51
|
+
/** Who did what and when, for activities without their own `description`. */
|
|
52
|
+
summary: (ctx: SecurityActivityAlertContext) => string;
|
|
53
|
+
/** What to do if the change wasn't expected. Follows the summary or description. */
|
|
54
|
+
guidance: (ctx: SecurityActivityAlertContext) => string;
|
|
55
|
+
reviewButton: string;
|
|
56
|
+
/** The line under the button. `link` is the rendered link to the activity log, so word order stays the translation's. */
|
|
57
|
+
activityLogHint: (link: (label: string) => React.ReactNode) => React.ReactNode;
|
|
58
|
+
/** Under the card: answers "why did I get this?" — differs for workspace and account targets. */
|
|
59
|
+
footer: (ctx: SecurityActivityAlertContext) => string;
|
|
60
|
+
formatDateTime: (date: Date, timeZone: string) => string;
|
|
61
|
+
}
|
|
62
|
+
export interface SecurityActivityAlertProps {
|
|
63
|
+
activity: SecurityActivity;
|
|
64
|
+
/** The workspace or the account the activity concerns. */
|
|
65
|
+
target: SecurityActivityTarget;
|
|
66
|
+
/** Deep link to this one entry in the activity log. */
|
|
67
|
+
reviewUrl: string;
|
|
68
|
+
/** The activity log itself, shown as a link under the button. */
|
|
69
|
+
activityLogUrl?: string;
|
|
70
|
+
messages: SecurityActivityAlertMessages;
|
|
71
|
+
/** IANA zone for `occurredAt`. Servers usually run in UTC; readers don't. */
|
|
72
|
+
timeZone: string;
|
|
73
|
+
/** The sender's legal line under the footer — company, address. */
|
|
74
|
+
legalNotice?: string;
|
|
75
|
+
/** Previews only — see `Layout`. */
|
|
76
|
+
colorScheme?: 'light' | 'dark';
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/templates/SecurityActivityAlert/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,MAAM,WAAW,gBAAgB;IAC/B,kHAAkH;IAClH,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,IAAI,CAAC;IACjB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,sBAAsB,GAC9B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC,4CAA4C;AAC5C,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,MAAM,EAAE,sBAAsB,CAAC;IAC/B,mFAAmF;IACnF,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,WAAW,6BAA6B;IAC5C,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,CAAC,GAAG,EAAE,4BAA4B,KAAK,MAAM,CAAC;IACvD,OAAO,EAAE,CAAC,GAAG,EAAE,4BAA4B,KAAK,MAAM,CAAC;IACvD,6EAA6E;IAC7E,OAAO,EAAE,CAAC,GAAG,EAAE,4BAA4B,KAAK,MAAM,CAAC;IACvD,oFAAoF;IACpF,QAAQ,EAAE,CAAC,GAAG,EAAE,4BAA4B,KAAK,MAAM,CAAC;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB,yHAAyH;IACzH,eAAe,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,CAAC;IAC/E,iGAAiG;IACjG,MAAM,EAAE,CAAC,GAAG,EAAE,4BAA4B,KAAK,MAAM,CAAC;IACtD,cAAc,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;CAC1D;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,0DAA0D;IAC1D,MAAM,EAAE,sBAAsB,CAAC;IAC/B,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,6BAA6B,CAAC;IACxC,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAChC"}
|
package/dist/tokens.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export type EmailColor = 'primary' | 'neutral' | 'danger' | 'success' | 'warning';
|
|
2
|
+
export type EmailVariant = 'solid' | 'soft' | 'outlined' | 'plain';
|
|
3
|
+
export type EmailScheme = 'light' | 'dark';
|
|
4
|
+
type Stop = 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;
|
|
5
|
+
export declare const emailPalette: Record<EmailColor, Record<Stop, string>>;
|
|
6
|
+
export declare const EMAIL_COLORS: EmailColor[];
|
|
7
|
+
export declare const EMAIL_VARIANTS: EmailVariant[];
|
|
8
|
+
/** What one variant × colour paints. `undefined` means "leaves it to the surroundings". */
|
|
9
|
+
export interface EmailVariantTokens {
|
|
10
|
+
color: string;
|
|
11
|
+
backgroundColor?: string;
|
|
12
|
+
borderColor?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function variantTokens(scheme: EmailScheme, variant: EmailVariant, color: EmailColor): EmailVariantTokens;
|
|
15
|
+
/** `--color-*-main`: step 500 in light, 400 in dark. What Link renders. */
|
|
16
|
+
export declare function mainColor(scheme: EmailScheme, color: EmailColor): string;
|
|
17
|
+
export interface EmailSchemeTokens {
|
|
18
|
+
inkPrimary: string;
|
|
19
|
+
inkSecondary: string;
|
|
20
|
+
inkTertiary: string;
|
|
21
|
+
/** `--color-ink-icon`: the faintest ink. */
|
|
22
|
+
inkIcon: string;
|
|
23
|
+
/** `--color-surface`: what a Sheet / Card paints under outlined and plain. */
|
|
24
|
+
surface: string;
|
|
25
|
+
/** `--color-surface-1`. */
|
|
26
|
+
surface1: string;
|
|
27
|
+
/**
|
|
28
|
+
* `--color-divider`. Kept as the rgba() theme.css uses so it composites the
|
|
29
|
+
* same way over any surface; Outlook's Word engine drops rgba(), which is
|
|
30
|
+
* why Divider also sets a solid `dividerFallback`.
|
|
31
|
+
*/
|
|
32
|
+
divider: string;
|
|
33
|
+
/** `divider` flattened onto `surface`. */
|
|
34
|
+
dividerFallback: string;
|
|
35
|
+
}
|
|
36
|
+
export declare const emailSchemes: Record<EmailScheme, EmailSchemeTokens>;
|
|
37
|
+
export declare const emailFonts: {
|
|
38
|
+
body: string;
|
|
39
|
+
heading: string;
|
|
40
|
+
};
|
|
41
|
+
/** theme.css's radius scale. */
|
|
42
|
+
export declare const emailRadius: {
|
|
43
|
+
xs: string;
|
|
44
|
+
sm: string;
|
|
45
|
+
md: string;
|
|
46
|
+
lg: string;
|
|
47
|
+
xl: string;
|
|
48
|
+
};
|
|
49
|
+
export {};
|
|
50
|
+
//# sourceMappingURL=tokens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAiBA,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;AAClF,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC;AACnE,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3C,KAAK,IAAI,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAErE,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAMjE,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,UAAU,EAA2D,CAAC;AACjG,eAAO,MAAM,cAAc,EAAE,YAAY,EAA2C,CAAC;AAErF,2FAA2F;AAC3F,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,GAAG,kBAAkB,CAe/G;AAED,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM,CAExE;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,OAAO,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,WAAW,EAAE,iBAAiB,CAqB/D,CAAC;AAEF,eAAO,MAAM,UAAU;;;CAMtB,CAAC;AAEF,gCAAgC;AAChC,eAAO,MAAM,WAAW;;;;;;CAA8D,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,62 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hintoric/email",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Transactional email components in @hintoric/ui's look, built on react-email.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://ui.hintoric.dev/email",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/hintoric/ui.git",
|
|
11
|
+
"directory": "packages/email"
|
|
12
|
+
},
|
|
13
|
+
"bugs": "https://github.com/hintoric/ui/issues",
|
|
14
|
+
"sideEffects": false,
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"module": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": "./dist/index.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"react": "^18.3.0 || ^19.0.0",
|
|
32
|
+
"react-dom": "^18.3.0 || ^19.0.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@testing-library/jest-dom": "^7.0.1",
|
|
36
|
+
"@testing-library/react": "^16.3.3",
|
|
37
|
+
"@types/react": "^19.2.18",
|
|
38
|
+
"@types/react-dom": "^19.2.5",
|
|
39
|
+
"@typescript/typescript6": "^6.0.2",
|
|
40
|
+
"@vitejs/plugin-react": "^6.1.1",
|
|
41
|
+
"@vitest/browser-playwright": "^4.1.11",
|
|
42
|
+
"jsdom": "^30.0.1",
|
|
43
|
+
"playwright": "^1.62.1",
|
|
44
|
+
"react": "^19.2.8",
|
|
45
|
+
"react-dom": "^19.2.8",
|
|
46
|
+
"typescript": "^7.0.2",
|
|
47
|
+
"vite": "^8.2.2",
|
|
48
|
+
"vite-plugin-dts": "^5.1.0",
|
|
49
|
+
"vitest": "^4.1.11",
|
|
50
|
+
"@hintoric/ui": "0.8.0"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"@react-email/render": "^2.1.0",
|
|
54
|
+
"react-email": "^6.11.0"
|
|
55
|
+
},
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "vite build",
|
|
58
|
+
"test": "vitest run",
|
|
59
|
+
"test:visual": "vitest run --config vitest.visual.config.ts",
|
|
60
|
+
"typecheck": "tsc --noEmit"
|
|
61
|
+
}
|
|
6
62
|
}
|