I trying to create a component for Typography purposes.
In pure React it’s will look like a:
// more props
const Typography = ({ tag: Tag = 'div', children}) => {
// some logic and props
return <Tag>{children}</Tag>
}
export default function App() {
return (
<div className="App">
<Typography tag="h1">Hello, React</Typography>
<Typography tag="h2">Start editing to see some magic happen!</Typography>
</div>
);
}
A simple approach might use something like this, where you declare each of the valid container tags:
module Typography = {
type tag = [#div | #h1 | #h2]
@react.component
let make = (~tag: tag, ~children: React.element) => {
switch tag {
| #div => <div> {children} </div>
| #h1 => <h1> {children} </h1>
| #h2 => <h2> {children} </h2>
}
}
}
let _ = <Typography tag=#h1> {"Hello, React"->React.string} </Typography>
A more dynamic approach that could allow invalid tags might look something like this:
module Typography = {
@react.component
let make = (~tag: string, ~children: React.element) => {
React.createElementVariadic(
ReactDOM.stringToComponent(tag),
ReactDOM.domProps(), // No props for the tag
[children],
)
}
}
let _ = <Typography tag="h1"> {"Hello, React"->React.string} </Typography>
Or perhaps a combination of the above two:
module Typography = {
type tag = [#div | #h1 | #h2]
@react.component
let make = (~tag: tag, ~children: React.element) => {
React.createElementVariadic(
ReactDOM.stringToComponent((tag :> string)),
ReactDOM.domProps(),
[children],
)
}
}
let _ = <Typography tag=#h1> {"Hello, React"->React.string} </Typography>
I’m not an expert on those last two approaches, so someone else might be able to offer an improvement.
4 Likes