Unfortunately, I’ve tried several different ways to port this to a React component written in Rescript, and unfortunately, each time the compiler has a problem with declared data-attributes.
Without this functionality, I won’t be able to use Rescript at work, and I care a lot about it.
Is there a special syntax for using data-attributes in JSX in Rescript that I don’t know?
The upcoming ReScript version 11.1.0 is for you! It will ship both with a generic JSX transform which includes among other things the possibility to extend the attributes of lowercase JSX tags and also finally allows hyphens in tag names. Although that already worked before with a special escape syntax:
let component = () => <div \"data-custom-state"=true />
I created a small example to show how it is now possible to extend JSX attributes:
module MyOverrides = {
module Elements = {
// Extend the available lowercase JSX props here.
type props = {
...JsxDOM.domProps,
\"data-custom-state": bool,
}
@module("react")
external jsx: (string, props) => Jsx.element = "jsx"
}
}
@@jsxConfig({module_: "MyOverrides"})
let component = () => <div \"data-custom-state"=true />
What is put in the jsxConfig annotation here is usually done in rescript.json where you can add the name of a special file/module like the MyOverrides one above to make it available in your whole codebase. It’s incomplete though, since I don’t know myself what is missing to make it fully work with React for instance, but maybe the creator of that feature (@zth) can explain further?
One thing to add is that you don’t need to use hyphens to make that work, you can use @as:
type props = {
...JsxDOM.domProps,
@as("data-custom-state") dataCustomState: bool,
}
But other than that, @fham covers it very well. You can of course configure the JSX module at the rescript.json level too so you don’t need to do the file level config. And don’t be afraid of copy pasting and vendoring things, including making modifications to them, from other libs like RescriptReact. It’s a great way to tailor things the way you need for your specific use case.
Should be in the next couple of days. We are preparing the next main release currently. But do not hesitate to install one of the release candidates and try it now.
Btw.: When you use npm create rescript-app it suggests experimental versions.
I want to propose Rescript in the company, starting with small individual components.
The project I am working on uses libraries that rely heavily on data-attributes. In our own components we also use data-attributes to store state information, control CSS styles, etc.
I’m new to Rescript and don’t really understand the solution you’ve showed, ie. from my point of view each component should have data-attributes defined only for it, and in the code example you propose you create MyOverrides module that overwrites the whole Elements module giving all components "data-custom-state’': bool (at least I understand it that way)
Doesn’t Rescript really allow you to work with legitimate HTML tags like data-attributes in a more “normal” way?
Below I have prepared an example of a component in JSX/TypeScript that uses various data-attributes.
Could you use it and convert it to Rescript/JSX to demonstrate how to work with Rescript in practice in applications with a strong emphasis on data-attributes? Thank you for your help!
So you’re saying all your elements don’t expect the same data attributes? How would you do it in a type-safe way in typescript?
My advice would be to override the element attributes with all the data attributes you expect to use, then wrap those lowercase components inside uppercase components that only expect the right data attributes for the given lowercase component.
This way you’d have good DX and type-safety with a minimal runtime overhead.
Don’t hesitate to reply if this doesn’t solve your problem.
You can find bellow a working version in ReScript of your code, don’t forget to enable auto-run if you want to test it live.
You can notice how close to the typescript version it is, it’s almost identical, you basically need to remove the type annotations and the return keyword.
Thank you for the link to playground with the code example.
Now I understand where I was making a mistake. Thank You a lot!
I’ll admit that this overwriting of modules, adding external is a bit confusing.
Do future versions of Rescript have plans to simplify this?
Many of the UI libraries in the React ecosystem use data-attributes, it would be nice if they could be declared without all this boilerplate (in the commercial project I work in, we have about 1200 components in the project - our own and from UI libraries that rely heavily on data-attributes to store meta-data and control CSS styles).
I’m having a hard time imagining arguments to convince the rest of the team that having to define these props override declarations in each component file to add data-attributes is, as you pointed out, “close to a version of typescript”