Skip to content

Commit 550769f

Browse files
GlassBricksPerryvw
andauthored
Improve JSX documentation (#65)
* Improve JSX documentation * Update docs/jsx.md Co-authored-by: Perry van Wesel <Perryvw@users.noreply.github.com> * Update docs/jsx.md Co-authored-by: Perry van Wesel <Perryvw@users.noreply.github.com> * Update docs/jsx.md Co-authored-by: Perry van Wesel <Perryvw@users.noreply.github.com> * Changes for PR. Co-authored-by: Benjamin Ye <24237065+enjoydambience@users.noreply.github.com> Co-authored-by: Perry van Wesel <Perryvw@users.noreply.github.com>
1 parent 3b4b7e6 commit 550769f

File tree

3 files changed

+134
-114
lines changed

3 files changed

+134
-114
lines changed

docs/jsx.md

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
---
2+
title: JSX
3+
---
4+
5+
As of version `0.42.0`, TypeScriptToLua supports the use of JSX. To enable it, add `"jsx": "react"` to your tsconfig - other values are not supported.
6+
7+
```json title=tsconfig.json
8+
{
9+
"compilerOptions": {
10+
...
11+
"jsx": "react",
12+
...
13+
},
14+
}
15+
```
16+
17+
JSX will be translated to lua as Typescript would translate it to JS:
18+
19+
```tsx
20+
const element = <div a={b}>Inner text!</div>;
21+
```
22+
23+
Will become:
24+
25+
```lua
26+
local element = React.createElement("div", { a = b }, "Inner text!");
27+
```
28+
29+
## Custom factory functions
30+
31+
It is possible to supply custom factory functions using the `jsxFactory` tsconfig setting, or on a per-file basis using the `/** @jsx */` annotation.
32+
33+
### Examples
34+
35+
With compiler option:
36+
37+
```json title=tsconfig.json
38+
{
39+
"compilerOptions": {
40+
...
41+
"jsx": "react",
42+
"jsxFactory": "MyNamespace.myCreate"
43+
...
44+
},
45+
}
46+
```
47+
48+
or with jsx annotation:
49+
50+
Note: the annotation MUST be at the top of the file!
51+
52+
```tsx
53+
/** @jsx MyNamespace.myCreate */
54+
```
55+
56+
```tsx
57+
const element = <div a={b}>Inner text!</div>;
58+
```
59+
60+
Will translate to:
61+
62+
```lua
63+
local element = MyNamespace.myCreate("div", { a = b }, "Inner text!");
64+
```
65+
66+
For more info on creating your own factory function, see [Creating your own JSX](#creating-your-own-jsx).
67+
68+
## jsxFragmentFactory
69+
70+
JSX fragments are translated as special components.
71+
72+
You can provide a custom fragment component using the `jsxFragmentFactory` tsconfig setting or with the `/** @jsxFrag */` annotation.
73+
74+
### Example
75+
76+
With compiler option:
77+
78+
```json title=tsconfig.json
79+
{
80+
"compilerOptions": {
81+
...
82+
"jsx": "react",
83+
"jsxFactory": "MyNamespace.myCreate",
84+
"jsxFragmentFactory": "MyNamespace.MyFragment"
85+
...
86+
},
87+
}
88+
```
89+
90+
or with `@jsxFrag` annotation:
91+
92+
```tsx
93+
/** @jsx MyNamespace.myCreate */
94+
/** @jsxFrag MyNamespace.MyFragment */
95+
```
96+
97+
```tsx
98+
const element = <></>;
99+
```
100+
101+
Will translate to:
102+
103+
```lua
104+
local element = MyNamespace.myCreate(MyNamespace.MyFragment);
105+
```
106+
107+
## Creating your own JSX
108+
109+
### JSX typings
110+
111+
The types on the jsx factory function itself do _not_ affect how typescript checks JSX types, and no type checking against the jsx factory function is done during transformation.
112+
113+
Instead, typescript looks for types for jsx on the special `JSX` namespace. You can read more creating JSX types [here](https://www.typescriptlang.org/docs/handbook/jsx.html#type-checking).
114+
115+
### JSX factory function
116+
117+
Typescript expects the jsx factory function to be similar to the following:
118+
119+
```ts
120+
/** @noSelf */
121+
function createElement(type: string | Function | Class, props?: object, ...children: any[]): any;
122+
```
123+
124+
- The function should have a `@noSelf` annotation or have a `this: void` parameter. See [here](the-self-parameter.md) for more info.
125+
- `type` will be a string for intrinsic properties (tag name starts with a lowercase letter), or a function/class component.
126+
- `props` will be the tag properties as an object/table, or `undefined`/`null`/`nil` if no properties are specified.
127+
- The remaining parameters form the `children`, and should be collected with a rest parameter (`...`), and not as one array parameter. The type of the children will be strings for inner text, and values passed directly for JSX expressions and nested elements.
128+
- No transformations are done on the children parameters, meaning they may have any type (including arrays) that you may need to handle.
129+
- Using a jsx children spread syntax `<>{...children}</>` does _not_ affect how the children are passed to the createElement function -- it is equivalent to `<>{children}</>`
130+
131+
The function may process in any way and return any value that you wish.
132+
133+
It is recommended that the jsx factory function is in a namespace that is the default export of a module, or that the function itself is the default export of a module, and that the namespace/function name matches the `jsxFactory` compiler option. This is for better integration with tooling (import suggestions). This applies similarly for custom fragment components and the `jsxFragmentFactory` compiler option.

docs/tsx.md

-113
This file was deleted.

sidebars.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"advanced/writing-declarations",
1111
"advanced/compiler-annotations",
1212
"advanced/language-extensions",
13-
"tsx",
13+
"jsx",
1414
{
1515
"type": "category",
1616
"label": "API",

0 commit comments

Comments
 (0)