Closed jam-fran closed 1 week ago
Hey, I'm glad you've been enjoying the project!
For your UserDeleted
component, is that exported as a default
or named export? I think that may be what its complaining about.
edit: just kidding i misread the error. let me dig in a bit.
Awesome thanks. And yeah, I've tried both default and named exports for each component.
In case it helps, here's one of the Email components that's being imported:
import { Column, Img, Link, Row, Section, Text } from '@react-email/components'
import { Constants } from '~/utils/constants'
import { AdminFooter } from './components/Footer'
import { Headline } from './components/Headline'
import { Layout } from './components/Layout'
type Props = {
id: number
fullName: string | null
usageTimePeriod: string
apps: {
id: number
name: string
logoUrl: string | null
lastAccessed: string
}[]
}
const UserDeleted = ({ id, fullName, usageTimePeriod, apps }: Props) => {
return (
<Layout previewText="A user has been deactivated from your Hapstack account. Here's a report of the apps they were using.">
<Section>
<Headline>
{fullName || 'An unnamed user'} was deactivated from your Hapstack
account.
</Headline>
<Text>
Here's a list of all the apps in your stack they've used over the past{' '}
{usageTimePeriod}. You can view the full list on{' '}
<Link href={`${Constants.webAppUrl}/team/${id}`}>
their activity page
</Link>{' '}
in your Hapstack account.
</Text>
</Section>
<Section className="mt-4 text-sm">
<Row className="font-medium">
<Column className="w-3/5">App</Column>
<Column className="w-2/5">Last Accessed</Column>
</Row>
{apps.map((app) => (
<Row
key={app.id}
className="border-b border-gray-200 py-3 last:border-b-0"
>
<Column className="inline-flex w-3/5 items-center">
<div className="inline-flex leading-4">
{app.logoUrl ? (
<Img
src={app.logoUrl}
alt={app.name}
className="mr-2 h-4 w-4 rounded-full"
/>
) : null}
<span className="w-32 truncate">{app.name}</span>
</div>
</Column>
<Column className="w-2/5">{app.lastAccessed}</Column>
</Row>
))}
</Section>
<AdminFooter />
</Layout>
)
}
UserDeleted.PreviewProps = {
id: 1,
fullName: 'Michael Scott',
usageTimePeriod: '30 days',
apps: [
{
id: 1,
name: 'Slack',
lastAccessed: '3 days ago',
logoUrl: 'https://picsum.photos/200',
},
{
id: 2,
name: 'Notion',
lastAccessed: 'about a week ago',
logoUrl: 'https://picsum.photos/200',
},
],
}
export { UserDeleted }
Thanks for sending over the component, was actually just about to ask. Do both of the components have a PreviewProps
set? In my own setup if I remove it from one of the email templates it will complain similar to the way yours is complaining. I may be able to fix that in the remix-mailer
type.
for example this is what i have for one of my templates locally, which is very very similar to yours.
import {
Body,
Head,
Heading,
Hr,
Html,
Link,
Preview,
Text,
} from "@react-email/components";
interface WelcomeProps {
name?: string;
}
export const Welcome = ({ name }: WelcomeProps) => {
const firstName = typeof name === "string" ? name.split(" ")[0] : "stranger";
return (
<Html>
<Head />
<Preview>Welcome to rvsn</Preview>
<Body style={mainStyle}>
<div style={headerStyle}>
<div style={headerInnerStyle}>rvsn</div>
</div>
<div style={centeredStyle}>
<Heading style={headingStyle}>Hiya {firstName}!</Heading>
<Text style={paragraphStyle}>
Welcome to rvsn! We're happy you're here and look forward to seeing
you around. Feel free to reach out if you need anything ;)
</Text>
</div>
<Hr style={hrStyle} />
<div style={{ ...centeredStyle, padding: "12px 20px 0" }}>
<Link href="https://rvsn.xyz" style={footerStyle}>
rvsn
</Link>
</div>
</Body>
</Html>
);
};
Welcome.PreviewProps = {
name: "Jack Dangler",
};
export default Welcome;
const mainStyle = {
margin: "0",
backgroundColor: "#f6f6f4",
maxWidth: "100%",
fontFamily:
'-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif',
};
const headerInnerStyle = {
maxWidth: "400px",
margin: "auto",
fontFamily:
"ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace",
};
const centeredStyle = {
maxWidth: "400px",
margin: "auto",
padding: "0 20px",
};
const headerStyle = {
backgroundColor: "#09090b",
color: "#fff",
fontSize: "14px",
fontWeight: "600",
padding: "14px 20px",
};
const headingStyle = {
paddingTop: "20px",
fontSize: "16px",
};
const paragraphStyle = {
paddingTop: "6px",
};
const hrStyle = {
borderColor: "#d8d8d5",
margin: "80px 0 0",
};
const footerStyle = {
fontSize: "12px",
lineHeight: "1.5",
color: "#ababab",
};
Yeah, if I remove PreviewProps from the component I still get a similar error:
Type '({ id, fullName, usageTimePeriod, apps }: Props) => JSX.Element' is not assignable to type 'ComponentType<{}>'.
Type '({ id, fullName, usageTimePeriod, apps }: Props) => JSX.Element' is not assignable to type 'FunctionComponent<{}>'.
Types of parameters '__0' and 'props' are incompatible.
Type '{}' is missing the following properties from type 'Props': id, fullName, usageTimePeriod, apps ts(2322)
I'm having a bit of trouble reproducing on my end. Can you create a repo that reproduces the issue? Also, what version of react, remix, and typescript are you using?
Sure - here's a minimal reproduction: https://github.com/jam-fran/test-remix-mailer
I'm using the latest versions - remix 2.5.1, typescript 5.3.3, and react 18.2.0
Ok so I forked that and added some remix-mailer previews. I cant seem to get the same error on my end.
I will say that with that remix template, when I run npm run typecheck
I was getting errors from vite
which is imported as a optional peer dep from remix dev and certain modules imported by @react-email
.
To fix that I added "skipLibCheck": true
to the tsconfig.json
and things cleared up. While that fixes the issue, it also prevents tsc from typechecking other .d.ts
files which is not ideal. More on how it works here:
https://www.typescriptlang.org/tsconfig#skipLibCheck
FWIW Though, it looks like that was just enabled for the vite template in remix.
https://github.com/remix-run/remix/pull/8447
If you pull this repo down and install are you still seeing an issue?
https://github.com/gregermendle/test-remix-mailer.git
For me that works and doesn't give me any type errors. The only other thing I can think of at this moment is, if you are using vscode you can switch between which typescript version you are using. I am using the workspace version in my env. I've had that give me issues in the past with other projects when it is set to the VSCode version.
First of all - sorry for sharing a completely empty remix starter repo 🤦...must of forgotten a commit there
I don't get any type errors in your repo. I tried switching to the workspace version of typescript in my VS code with no luck, and have verified that skipLibCheck is true in my config. Totally stumped here!
The only other variable that's in play is that this is a package within a monorepo, but I can't imagine how that might be related to this issue given what I know.
Anyway, thanks so much for your help here. I'll reply back if I ever figure it out.
Hey! I didnt forget about this and went back today to test some things out and can now reproduce the issue you are seeing. So its a bit tricky and I'm going to try to get a type fix out for it soon. What seems to cause it on my end is if I have props in my Email components that are required.
interface WelcomeProps {
name?: string;
}
becomes
interface WelcomeProps {
name: string;
}
And causes a bunch of errors. For now the way I'm fixing it on my end is just making those props all optional. I do want to fix the errors though and will try to get something out soon.
Interestingly enough it looks like react-email in their preview system just casts those as React.FC
and pulls the Preview Props out into their own variable: https://github.com/resend/react-email/blob/fb25c3d696e834ec9b1ac16b5b6102134418c923/packages/react-email/src/actions/render-email-by-slug.tsx#L35
Also sorry for not responding back to your previous comment, interviewing has basically sucked up all of my time lately.
Very interesting, thank for the update. Obviously this isn't urgent but I appreciate you continuing to look into it. Keep me posted!
Hi there,
Thanks for creating this package - I love it.
I've set up my preview route just link the docs lay out, however I'm getting type errors on the object with component/route definitions and the Compent.PreviewProps in the render function. Here's my route:
Here's the type error for the component/route definitions:
And here's the type error on Component.PreviewProps:
I've confirmed that have
"moduleResolution: Bundler"
in my tsconfig.js. Any ideas?