Hi,
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!
TSX:
import React from 'react';
// Types for variants and checkbox states
type Variant = 'warning' | 'error' | 'info';
type CheckboxState = 'checked' | 'unchecked';
// Icon.tsx component that changes based on data-variant
const Icon: React.FC<{ variant: Variant }> = ({ variant }) => {
return (
<span data-variant={variant} className="icon">
{variant === 'warning' && '⚠️'}
{variant === 'error' && '❌'}
{variant === 'info' && 'ℹ️'}
</span>
);
};
// Title.tsx component
const Title: React.FC<{ title: string }> = ({ title }) => (
<span className="title">{title}</span>
);
// Header component that contains Icon and Title
const Header: React.FC<{ variant: Variant; title: string }> = ({ variant, title }) => (
<div className="header">
<Icon variant={variant} />
<Title title={title} />
</div>
);
// Content.tsx component
const Content: React.FC = ({ children }) => (
<div className="content">
{children}
</div>
);
// Checkbox.tsx component with data-state attribute
const Checkbox: React.FC<{ label: string; state: CheckboxState; onChange: () => void }> = ({ label, state, onChange }) => (
<label data-state={state} className="checkbox">
<input type="checkbox" checked={state === 'checked'} onChange={onChange} />
{label}
</label>
);
// AcceptButton.tsx component
const AcceptButton: React.FC<{ onClick: () => void }> = ({ onClick }) => (
<button onClick={onClick} className="accept-button">
Accept
</button>
);
// Announcement.tsx component with data-variant attribute
const Announcement: React.FC<{ variant: Variant; title: string; content: string }> = ({ variant, title, content }) => {
const [checkbox1State, setCheckbox1State] = React.useState<CheckboxState>('unchecked');
const [checkbox2State, setCheckbox2State] = React.useState<CheckboxState>('unchecked');
return (
<div className={`announcement ${variant}`} data-variant={variant}>
<Header variant={variant} title={title} />
<Content>{content}</Content>
<Checkbox
label="I agree to the terms"
state={checkbox1State}
onChange={() => setCheckbox1State(checkbox1State === 'checked' ? 'unchecked' : 'checked')}
/>
<Checkbox
label="I agree to the privacy policy"
state={checkbox2State}
onChange={() => setCheckbox2State(checkbox2State === 'checked' ? 'unchecked' : 'checked')}
/>
<AcceptButton onClick={() => alert('Accepted')} />
</div>
);
};
CSS:
.announcement[data-variant="warning"] {
background-color: yellow;
color: black;
}
.announcement[data-variant="error"] {
background-color: red;
color: white;
}
.announcement[data-variant="info"] {
background-color: blue;
color: white;
}
.icon[data-variant="warning"] {
color: orange;
}
.icon[data-variant="error"] {
color: red;
}
.icon[data-variant="info"] {
color: blue;
}
.checkbox[data-state="checked"] {
font-weight: bold;
}