From c68d38159ed613886d959b59193c75ef2f190c93 Mon Sep 17 00:00:00 2001 From: nojaf Date: Thu, 13 Jun 2024 14:30:24 +0200 Subject: [PATCH 1/4] Add React interopt guide --- data/sidebar_react_latest.json | 3 +- pages/docs/react/latest/interopt.mdx | 122 +++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 pages/docs/react/latest/interopt.mdx diff --git a/data/sidebar_react_latest.json b/data/sidebar_react_latest.json index 3a2d32fda..1c551af1f 100644 --- a/data/sidebar_react_latest.json +++ b/data/sidebar_react_latest.json @@ -28,6 +28,7 @@ "Guides": [ "beyond-jsx", "forwarding-refs", - "extensions-of-props" + "extensions-of-props", + "interopt" ] } \ No newline at end of file diff --git a/pages/docs/react/latest/interopt.mdx b/pages/docs/react/latest/interopt.mdx new file mode 100644 index 000000000..dcab246a0 --- /dev/null +++ b/pages/docs/react/latest/interopt.mdx @@ -0,0 +1,122 @@ +--- +title: Interopt +description: "Reusing existing React components" +canonical: "/docs/react/latest/interopt" +--- + +# Interopt + +Reusing existing React components in ReScript is straightforward. +This guide will walk you through the steps required to import and use React components within ReScript, +including defining component props and handling various import scenarios. + +## Basic Example + +To reuse a React component in ReScript, create a new module, specify the component's location, and define its props. + +```js +import Confetti from "react-confetti" + +const App = () => { + +} +``` + +```res +module Confetti = { + @module("react-confetti") + @react.component + external make : (~width:int, ~height: int) => React.element = "default" +} + +// Assuming we are in App.res +@react.component +let make = () => { + +} +``` + +## Importing from Relative Paths + +You can import components from relative file paths using the `@module` attribute. +Use "default" to indicate the default export, or specify a named export if needed. + +### Named Export Example + +```res +// Equivalent of import { Foo } from "bar" +module Foo = { + @module("bar") + @react.component + external make : () => React.element = "Foo" +} +``` + +## Defining Props Types + +You can define a separate type for your component's props within the module. + +### Props Type Example + +```res +module Confetti = { + type confettiProps = { + width: int, + height: int, + } + + @module("react-confetti") @react.component(: confettiProps) + external make: confettiProps => React.element = "default" +} + +@react.component +let make = () => { + +} +``` + +## Optional Props + +To define optional props, use the `?` symbol. + +```res +module Confetti = { + type confettiProps = { + width: int, + height: int, + initialVelocityX?: int, + initialVelocityY?: int, + } + + @module("react-confetti") @react.component(: confettiProps) + external make: confettiProps => React.element = "default" +} + +@react.component +let make = () => { + +} +``` + +## Extending Built-in DOM Nodes + +To accept existing DOM props for a component, extend the `JsxDOM.domProps` type. + +```res +module Foo = { + type fooProps = { + ...JsxDOM.domProps, + customProp: string, + } + + @module("foo") @react.component(: fooProps) + external make: fooProps => React.element = "default" +} + +@react.component +let make = () => { + +} +``` + +In this example `width` and `height` can be set because `JsxDOM.domProps` was spread into `fooProps`. From 8edb9a958b8f34482a269f6e3662c8607156df27 Mon Sep 17 00:00:00 2001 From: nojaf Date: Sun, 16 Jun 2024 10:58:53 +0200 Subject: [PATCH 2/4] Rename to interop --- data/sidebar_react_latest.json | 2 +- pages/docs/react/latest/interopt.mdx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/sidebar_react_latest.json b/data/sidebar_react_latest.json index 1c551af1f..6674659f3 100644 --- a/data/sidebar_react_latest.json +++ b/data/sidebar_react_latest.json @@ -29,6 +29,6 @@ "beyond-jsx", "forwarding-refs", "extensions-of-props", - "interopt" + "interop" ] } \ No newline at end of file diff --git a/pages/docs/react/latest/interopt.mdx b/pages/docs/react/latest/interopt.mdx index dcab246a0..30374897b 100644 --- a/pages/docs/react/latest/interopt.mdx +++ b/pages/docs/react/latest/interopt.mdx @@ -1,10 +1,10 @@ --- -title: Interopt +title: Interop description: "Reusing existing React components" -canonical: "/docs/react/latest/interopt" +canonical: "/docs/react/latest/interop" --- -# Interopt +# Interop Reusing existing React components in ReScript is straightforward. This guide will walk you through the steps required to import and use React components within ReScript, From 65c73d397aeccfef59e65f3bfcf96fd4763efd65 Mon Sep 17 00:00:00 2001 From: nojaf Date: Sun, 16 Jun 2024 11:07:16 +0200 Subject: [PATCH 3/4] Use CodeTab --- .../latest/{interopt.mdx => interop.mdx} | 93 ++++++++++++++++--- 1 file changed, 80 insertions(+), 13 deletions(-) rename pages/docs/react/latest/{interopt.mdx => interop.mdx} (60%) diff --git a/pages/docs/react/latest/interopt.mdx b/pages/docs/react/latest/interop.mdx similarity index 60% rename from pages/docs/react/latest/interopt.mdx rename to pages/docs/react/latest/interop.mdx index 30374897b..2b92b72a5 100644 --- a/pages/docs/react/latest/interopt.mdx +++ b/pages/docs/react/latest/interop.mdx @@ -14,19 +14,12 @@ including defining component props and handling various import scenarios. To reuse a React component in ReScript, create a new module, specify the component's location, and define its props. -```js -import Confetti from "react-confetti" - -const App = () => { - -} -``` + ```res module Confetti = { - @module("react-confetti") - @react.component - external make : (~width:int, ~height: int) => React.element = "default" + @module("react-confetti") @react.component + external make: (~width: int, ~height: int) => React.element = "default" } // Assuming we are in App.res @@ -36,6 +29,22 @@ let make = () => { } ``` +```js +import ReactConfetti from "react-confetti"; +import * as JsxRuntime from "react/jsx-runtime"; + +var Confetti = {}; + +function Playground(props) { + return JsxRuntime.jsx(ReactConfetti, { + width: 300, + height: 300 + }); +} +``` + + + ## Importing from Relative Paths You can import components from relative file paths using the `@module` attribute. @@ -43,21 +52,26 @@ Use "default" to indicate the default export, or specify a named export if neede ### Named Export Example + + ```res // Equivalent of import { Foo } from "bar" module Foo = { - @module("bar") - @react.component - external make : () => React.element = "Foo" + @module("bar") @react.component + external make: unit => React.element = "Foo" } ``` + + ## Defining Props Types You can define a separate type for your component's props within the module. ### Props Type Example + + ```res module Confetti = { type confettiProps = { @@ -75,10 +89,28 @@ let make = () => { } ``` +```js +import ReactConfetti from "react-confetti"; +import * as JsxRuntime from "react/jsx-runtime"; + +var Confetti = {}; + +function Playground(props) { + return JsxRuntime.jsx(ReactConfetti, { + width: 300, + height: 300 + }); +} +``` + + + ## Optional Props To define optional props, use the `?` symbol. + + ```res module Confetti = { type confettiProps = { @@ -98,10 +130,28 @@ let make = () => { } ``` +```js +import ReactConfetti from "react-confetti"; +import * as JsxRuntime from "react/jsx-runtime"; + +var Confetti = {}; + +function Playground(props) { + return JsxRuntime.jsx(ReactConfetti, { + width: 300, + height: 300 + }); +} +``` + + + ## Extending Built-in DOM Nodes To accept existing DOM props for a component, extend the `JsxDOM.domProps` type. + + ```res module Foo = { type fooProps = { @@ -119,4 +169,21 @@ let make = () => { } ``` +```js +import Foo from "foo"; +import * as JsxRuntime from "react/jsx-runtime"; + +var Foo$1 = {}; + +function Playground(props) { + return JsxRuntime.jsx(Foo, { + height: "300px", + width: "300px", + customProp: "bar" + }); +} +``` + + + In this example `width` and `height` can be set because `JsxDOM.domProps` was spread into `fooProps`. From ae0669f77e43d04ebf5f753cffbf5e6a8da0cc20 Mon Sep 17 00:00:00 2001 From: nojaf Date: Mon, 17 Jun 2024 09:38:42 +0200 Subject: [PATCH 4/4] Rename interop to import-export-reactjs --- data/sidebar_react_latest.json | 6 +++--- pages/docs/manual/latest/import-from-export-to-js.mdx | 2 ++ .../react/latest/{interop.mdx => import-export-reactjs.mdx} | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) rename pages/docs/react/latest/{interop.mdx => import-export-reactjs.mdx} (97%) diff --git a/data/sidebar_react_latest.json b/data/sidebar_react_latest.json index 6674659f3..21827eb9d 100644 --- a/data/sidebar_react_latest.json +++ b/data/sidebar_react_latest.json @@ -14,7 +14,8 @@ "context", "styling", "router", - "lazy-components" + "lazy-components", + "import-export-reactjs" ], "Hooks & State Management": [ "hooks-overview", @@ -28,7 +29,6 @@ "Guides": [ "beyond-jsx", "forwarding-refs", - "extensions-of-props", - "interop" + "extensions-of-props" ] } \ No newline at end of file diff --git a/pages/docs/manual/latest/import-from-export-to-js.mdx b/pages/docs/manual/latest/import-from-export-to-js.mdx index 4922ec456..6328666c1 100644 --- a/pages/docs/manual/latest/import-from-export-to-js.mdx +++ b/pages/docs/manual/latest/import-from-export-to-js.mdx @@ -8,6 +8,8 @@ canonical: "/docs/manual/latest/import-from-export-to-js" You've seen how ReScript's idiomatic [Import & Export](import-export.md) works. This section describes how we work with importing stuff from JavaScript and exporting stuff for JavaScript consumption. +If you're looking for react-specific interop guidance, check out the [React JS Interop guide](../../react/latest/import-export-reactjs.mdx). + **Note**: due to JS ecosystem's module compatibility issues, our advice of keeping your ReScript file's compiled JS output open in a tab applies here **more than ever**, as you don't want to subtly output the wrong JS module import/export code, on top of having to deal with Babel/Webpack/Jest/Node's CommonJS \<-> JavaScript module compatibility shims. In short: **make sure your bindings below output what you'd have manually written in JS**. diff --git a/pages/docs/react/latest/interop.mdx b/pages/docs/react/latest/import-export-reactjs.mdx similarity index 97% rename from pages/docs/react/latest/interop.mdx rename to pages/docs/react/latest/import-export-reactjs.mdx index 2b92b72a5..dc4717af7 100644 --- a/pages/docs/react/latest/interop.mdx +++ b/pages/docs/react/latest/import-export-reactjs.mdx @@ -1,10 +1,10 @@ --- -title: Interop +title: Import / Export ReactJS description: "Reusing existing React components" -canonical: "/docs/react/latest/interop" +canonical: "/docs/react/latest/import-export-reactjs" --- -# Interop +# Import / Export ReactJS Reusing existing React components in ReScript is straightforward. This guide will walk you through the steps required to import and use React components within ReScript,