-
Notifications
You must be signed in to change notification settings - Fork 672
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Docs: update JSX pragma guide with automatic runtime section #1718
Docs: update JSX pragma guide with automatic runtime section #1718
Conversation
- add link to JSX pragma guide from "How it works" guide
This pull request is being automatically deployed with Vercel (learn more). 🔍 Inspect: https://vercel.com/systemui/theme-ui/4qzuzXah4UqVeaGT57bd9smhaJCD |
### Using TypeScript | ||
|
||
If you use TypeScript to transpile your source code with `tsc` (or only | ||
typecheck), or for instance to run tests with `ts-jest` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry mate, I was under impression we already merged this PR.
Could we write something like "If you use TypeScript to transpile your JSX"?
A lot of people are using TypeScript together with Babel, and they don't need to configure jsxImportSource globally twice (you only need it in Babel config if you're using Babel)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You still need it for instance for eslint and other tools like ts-jest
that do not use Babel, even if you use @babel/preset-typescript
to build, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I assumed people would use babel-jest
, but typescript-eslint
will probably need it in the tsconfig when it's doing typechecking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we still be more explicit here then? I don't mind 🤷
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's okay now. @lachlanjc could you take a look at this PR when you have a moment?
NOTE: this requires | ||
[TypeScript >= 4.1](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-1.html#react-17-jsx-factories) | ||
|
||
NOTE: in order to typecheck `sx` using automatic runtime, you will also need to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this also the case when "jsxImportSource": "theme-ui"
is configured in TypeScript config?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huuuh, I think this is above my TS understanding to be honest, but I can re-try in a project 😁
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was under impression that TS correctly found types from configured importSource, but I'll have to double-check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like you're right actually, good catch :)
I will remove it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hasparus just figured out why I thought this was still necessary:
If you apply sx
to a non theme-ui component without manually providing sx
types, then it does not typecheck even with jsxImportSource: "theme-ui"
inside tsconfig.json (even though sx gets correctly compiled)
// StyledForm.tsx
import { Button, Flex, Input, Label } from 'theme-ui';
// Some interface not explicitly typing "sx"
export interface StyledFormProps {
onChange(data: Record<string, unknown>): void;
}
const StyledForm: React.FC<StyledFormProps> = ({
onChange,
...props
}) => (
<form {...props}> // spreading props, including sx --> Emotion correctly compiles it to a className
<Flex sx={{ flexFlow: 'column', p: 's' }}>
<Label htmlFor="input.test">Test</Label>
<Input
id="input.test"
type="text"
onChange={
(event) => onChange({
test: event.target.value
})
}
/>
</Flex>
</form>
);
export default StyledForm;
TS error when forwarding sx
// App.tsx
const App = () => (
<StyledForm
onChange={console.log}
sx={{
// Type '{ /* ... */ sx: { ...; }; }' is not assignable to type 'IntrinsicAttributes & StyledFormProps & { children?: ReactNode; }'.
// Property 'sx' does not exist on type 'IntrinsicAttributes & StyledFormProps & { children?: ReactNode; }'.
'px': 'm'
}}
/>
);
This can be easily fixed by adding sx?: ThemeUIStyleObject
to StyledFormProps
in that case, just slightly sad that we get a TS error even though the className works fine IMHO, but I don't mind adding the types wherever it is needed
Could/Should the automatic sx
typings be added to all JSX components instead of only theme-ui ones, or is that anti-pattern? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @flo-sch 👋 @hasparus doesn't have access to his computer, and he asked me to write this 😄
Theme UI types add sx
prop only to components which props already accept className
, as sx
transpiles to className
.
The code responsible for this is at packages/core/src/jsx-namespace.ts#L3.
Here's a CodeSandbox, so you can try it out: https://codesandbox.io/s/frosty-https-wpp7f?file=/src/index.tsx
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @beerose, nice to meet you and thanks for relaying the answer 😁
(not sure if the sandbox link was the correct one though, seems more about GraphQL in there?)
That make sense in term of typings I guess, I did reproduce it (even without automatic runtime):
https://codesandbox.io/s/sx-props-typings-automatic-runtime-dte1v?file=/src/App.tsx
My only claim was that, since Emotion successfully compiles it anyway, it felt like a "false-negative" from TS to complain on missing sx
types in that case (in that App.tsx, there is a TS complain on the first <Form sx={{ }} />
since it does not add types for className or sx)
But I guess this is another discussion here, not related to automatic runtime in itself
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey! I'm not sure how it happened but yes, the link was wrong 🤦♀️
Here's the valid one: https://codesandbox.io/s/affectionate-architecture-utrwm?file=/src/index.tsx
Sorry!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My only claim was that, since Emotion successfully compiles it anyway, it felt like a "false-negative" from TS to complain on missing sx types in that case (in that App.tsx, there is a TS complain on the first <Form sx={{ }} /> since it does not add types for className or sx)
IMHO this isn't a false negative — sx
is compiled to className
which is not handled so we see almost the same error as if we passed a className
, meaning "this component cannot be styled from the outside".
Co-authored-by: Piotr Monwid-Olechnowicz <[email protected]>
🚀 PR was released in |
Fixes #1335