Closed davesnx closed 2 years ago
Hey @dodomorandi, saw your PR adding polyvariants to rescript-react and your comments on the jsx ppx v4 from Ricky. This PR allows us to have fine granted type-safety for all elements and the next changes will include moving away from strings
and introducing polyvariants or variants for many attributes.
Would you like to participate and have a chat with me about this topic? I would love to know your opinions on the questions I ask on this PR. Let me know if you want to chat here or in discord, both work great for me :D
Hope this cc isn't to intrusive!
Description
This PR brings a layer of safety to writing React components that render HTML elements or SVG elements. The idea behind this isn't new, libraries like https://github.com/ocsigen/tyxml from OCaml, or https://github.com/kotlin/kotlinx.html from Kotlin Web, or https://github.com/nicojs/typed-html from TypeScript.
Since this library/ppx focuses on React, it includes the divergences from HTML standard: https://reactjs.org/docs/dom-elements.html.
Plan of action
tyxml
validate attributes: https://github.com/ocsigen/tyxml/blob/master/lib/html_types.mliTried to use tyxml to easily integrate with our codebase, but found that their implementation to derivate a bit from our needs. The approach they took was more functional. Ensuring to provide a huge list of functions where those type-check against some nested open polyvars.
Our goal was to have a list of attributes and store this as metadata in order to generate the type-checks from the ppx. Using the types from types/react was easier to parse. I expect React's static types from TypeScript to be tested intensively and ensure we provide those React pieces that other HTML implementations will lack. That was the approach I took.
Todo
HTMLAttributes
htmlElements
htmlNames
commonDOMAttributes
abstractView
touch
touchList
errorInfo
Transform lists to be Hash tables? any other structure that fits best?Any other pattern that might benefit us from the HTML metadata encoded?Any way to battle-test it?(Migrating real-world-example might make the trick)Flag those that are experimental, or deprecated. Any way to run it automatically?(Will be done in further PRs)Improve error messaging(Will be done in further PRs)→ ~/C/g/r/jsoo-react on Type-safe-html-tags ✗ make
File "test.ml", lines 109-111, characters 2-10: 109 | ..((div ~cols:1 ~href:(("https://example.com") 110 | [@reason.raw_literal "https://example.com"]) ~children:[foo] ()) 111 | [@JSX ]) Error: prop 'cols' isn't a valid prop for a 'div'
( They should look like )
File "test.ml", lines 109-111, characters 2-10: 109 | ..((div ~cols:1 ~href:(("https://example.com") 110 | [@reason.raw_literal "https://example.com"]) ~children:[foo] ()) 111 | [@JSX ]) Error: 'div' contains an invalid prop: 'cols'. It only accepts 'Global attributes' defined in https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes