Skip to content
This repository was archived by the owner on Jun 15, 2023. It is now read-only.

Commit 5dedb5b

Browse files
mununkicristianoc
andauthored
JSX V4 (#547)
* react ppx v4 and parsing spread props * change the empty record to "_" for jsx upper case * change empty record to {key: None} for jsx upper case * polishing the loc of react ppx * implicit option type of @obj record update * add match vbs for optional arg with default value * add @optional record declarations * fix missing pattern * clean up codes and comments * support React.forwardRef * replace filterMap with std lib * Add JSX V4 spec. * typo * JSX spec: move createElement to application. Following https://forum.rescript-lang.org/t/jsx-v4-next-rescript-react-0-10-x/3431/10 * spec: comment on name * spec: clean up file * external * Be consistent with interface only show how to transform the arrow function. * Update JSXV4.md * restore React.createElement in application site * spec: react fragment * spec: tweak fragment. * make react component name capitalized * test: add test files * fix ppx for forwardRef * remove ref from props except forwardRef * add test for forwardRef * format * remove uneccessary adding @optional attr from extracting props type * indent by relocating every fn from jsxMapper * remove unused jsxVersion * jsx version check is conducted in compiler config side * add new line * update jsx ppx comment * rename v3 -> v4, restore v3, add cli args * add tests for v3 and v4 respectively Co-authored-by: Cristiano Calcagno <cristianoc@users.noreply.github.com>
1 parent fed1a27 commit 5dedb5b

29 files changed

+1815
-10
lines changed

cli/JSXV4.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
**Abbreviation**
2+
3+
The placement of `@react.component` is an abbreviation as described below.
4+
5+
**Normal Case**
6+
7+
```rescript
8+
@react.component
9+
let make = (~x, ~y, ~z) => body
10+
11+
// is an abbreviation for
12+
13+
let make = @react.component (~x, ~y, ~z) => body
14+
```
15+
16+
**Forward Ref**
17+
18+
```rescript
19+
@react.component
20+
let make = React.forwardRef((~x, ~y, ref) => body)
21+
22+
// is an abbreviation for
23+
24+
let make = React.forwardRef({
25+
let fn =
26+
@react.component (~x, ~y, ~ref=?) => {
27+
let ref = ref->Js.Nullable.fromOption
28+
body
29+
}
30+
(props, ref) => fn({...props, ref: {ref->Js.Nullable.toOption}})
31+
})
32+
```
33+
34+
**Conversion**
35+
36+
Conversion applies to an arrow function definition where all the arguments are labelled.
37+
It produces a type definition and a new function.
38+
39+
**Definition**
40+
41+
```rescript
42+
@react.component (~x, ~y=3+x, ?z) => body
43+
44+
// is converted to
45+
46+
type props<'x, 'y, 'z> = {x: 'x, @optional y: 'y, @optional z: 'z, @optional key: string}
47+
48+
({x, y, z}: props<_>) => {
49+
let y = switch props.y {
50+
| None => 3 + x
51+
| Some(y) => y
52+
}
53+
body
54+
}
55+
```
56+
57+
**Application**
58+
59+
```rescript
60+
<Comp x>
61+
// is converted to
62+
React.createElement(Comp.make, {x})
63+
64+
<Comp x y=7 ?z>
65+
// is converted to
66+
React.createElement(Comp.make, {x, y:7, @optional z})
67+
68+
<Comp x key="7">
69+
// is converted to
70+
React.createElement(Comp.make, {x, key: "7"})
71+
```
72+
73+
**Interface And External**
74+
75+
```rescript
76+
@react.component (~x: int, ~y: int=?, ~z: int=?) => React.element
77+
78+
// is converted to
79+
80+
type props<'x, 'y, 'z> = {x: 'x, @optional y: 'y, @optional z: 'z}
81+
82+
props<int, int, int> => React.element
83+
```
84+
85+
Since an external is a function declaration, it follows the same rule.
86+
87+
**Component Name**
88+
89+
Use the V3 convention for names, and make sure the generated
90+
function has the name of the enclosing module/file.
91+
92+
**Fragment**
93+
94+
```rescript
95+
<> comp1 comp2 comp3 </>
96+
97+
// is converted to
98+
99+
ReactDOMRe.createElement(ReasonReact.fragment, [comp1, comp2, comp3])
100+
```

0 commit comments

Comments
 (0)