From 6d7a0d39cfe7f7a520d38dc882324e0733d43ba1 Mon Sep 17 00:00:00 2001 From: Joost Date: Wed, 27 Dec 2023 10:16:19 +0000 Subject: [PATCH 1/2] Move Feliz before Fable in third party react recipe --- .../javascript/third-party-react-package.md | 103 +++++++++--------- 1 file changed, 50 insertions(+), 53 deletions(-) diff --git a/docs/recipes/javascript/third-party-react-package.md b/docs/recipes/javascript/third-party-react-package.md index 67859f6e..cfede4a7 100644 --- a/docs/recipes/javascript/third-party-react-package.md +++ b/docs/recipes/javascript/third-party-react-package.md @@ -1,60 +1,8 @@ -To use a third-party React library in a SAFE application, you need to write an F# wrapper around it. There are two ways for doing this - using [Fable.React](https://www.nuget.org/packages/Fable.React/) or using [Feliz](https://zaid-ajaj.github.io/Feliz/). +To use a third-party React library in a SAFE application, you need to write an F# wrapper around it. There are two ways for doing this - using [Feliz](https://zaid-ajaj.github.io/Feliz/) or using [Fable.React](https://www.nuget.org/packages/Fable.React/). ## Prerequisites This recipe uses the [react-d3-speedometer NPM package](https://www.npmjs.com/package/react-d3-speedometer) for demonstration purposes. [Add it to your Client](../package-management/add-npm-package-to-client.md) before continuing. -## Fable.React - Setup - -#### 1. Create a new file - -Create an empty file named `ReactSpeedometer.fs` in the Client project above `Index.fs` and insert the following statements at the beginning of the file. - -```fsharp -module ReactSpeedometer - -open Fable.Core -open Fable.Core.JsInterop -open Fable.React -``` - -#### 2. Define the Props -Prop represents the props of the React component. In this recipe, we're using [the props listed here](https://www.npmjs.com/package/react-d3-speedometer) for `react-d3-speedometer`. We model them in Fable.React using a discriminated union. - -```fsharp -type Prop = - | Value of int - | MinValue of int - | MaxValue of int - | StartColor of string -``` - -> One difference to note is that we use **P**ascalCase rather than **c**amelCase. -> -> Note that we can model any props here, both simple values and "event handler"-style ones. - -#### 3. Write the Component -Add the following function to the file. Note that the last argument passed into the `ofImport` function is a list of `ReactElements` to be used as children of the react component. In this case, we are passing an empty list since the component doesn't have children. - -```fsharp -let reactSpeedometer (props : Prop list) : ReactElement = - let propsObject = keyValueList CaseRules.LowerFirst props // converts Props to JS object - ofImport "default" "react-d3-speedometer" propsObject [] // import the default function/object from react-d3-speedometer -``` - -#### 4. Use the Component -With all these in place, you can use the React element in your client like so: - -```fsharp -open ReactSpeedometer - -reactSpeedometer [ - Prop.Value 10 // Since Value is already decalred in HTMLAttr you can use Prop.Value to tell the F# compiler its of type Prop and not HTMLAttr - MaxValue 100 - MinValue 0 - StartColor "red" - ] -``` - ## Feliz - Setup If you don't already have [Feliz](https://www.nuget.org/packages/Feliz/) installed, [add it to your client](../ui/add-feliz.md). @@ -108,5 +56,54 @@ That's the bare minimum needed to get going! Once your component is working you may want to extract out the logic so that it can be used in multiple pages of your app. For a full detailed tutorial head over to [this blog post](https://www.compositional-it.com/news-blog/f-wrappers-for-react-components/)! +## Fable.React - Setup + +#### 1. Create a new file + +Create an empty file named `ReactSpeedometer.fs` in the Client project above `Index.fs` and insert the following statements at the beginning of the file. + +```fsharp +module ReactSpeedometer + +open Fable.Core +open Fable.Core.JsInterop +open Fable.React +``` + +#### 2. Define the Props +Prop represents the props of the React component. In this recipe, we're using [the props listed here](https://www.npmjs.com/package/react-d3-speedometer) for `react-d3-speedometer`. We model them in Fable.React using a discriminated union. + +```fsharp +type Prop = + | Value of int + | MinValue of int + | MaxValue of int + | StartColor of string +``` + +> One difference to note is that we use **P**ascalCase rather than **c**amelCase. +> +> Note that we can model any props here, both simple values and "event handler"-style ones. +#### 3. Write the Component +Add the following function to the file. Note that the last argument passed into the `ofImport` function is a list of `ReactElements` to be used as children of the react component. In this case, we are passing an empty list since the component doesn't have children. + +```fsharp +let reactSpeedometer (props : Prop list) : ReactElement = + let propsObject = keyValueList CaseRules.LowerFirst props // converts Props to JS object + ofImport "default" "react-d3-speedometer" propsObject [] // import the default function/object from react-d3-speedometer +``` +#### 4. Use the Component +With all these in place, you can use the React element in your client like so: + +```fsharp +open ReactSpeedometer + +reactSpeedometer [ + Prop.Value 10 // Since Value is already decalred in HTMLAttr you can use Prop.Value to tell the F# compiler its of type Prop and not HTMLAttr + MaxValue 100 + MinValue 0 + StartColor "red" + ] +``` \ No newline at end of file From 4184f319b66d35ef033c499331fc71e089185fbf Mon Sep 17 00:00:00 2001 From: Joost Date: Wed, 27 Dec 2023 10:20:19 +0000 Subject: [PATCH 2/2] Always separate md elements with whitespace; do not skip header levels --- .../javascript/third-party-react-package.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/docs/recipes/javascript/third-party-react-package.md b/docs/recipes/javascript/third-party-react-package.md index cfede4a7..fed547be 100644 --- a/docs/recipes/javascript/third-party-react-package.md +++ b/docs/recipes/javascript/third-party-react-package.md @@ -1,4 +1,5 @@ To use a third-party React library in a SAFE application, you need to write an F# wrapper around it. There are two ways for doing this - using [Feliz](https://zaid-ajaj.github.io/Feliz/) or using [Fable.React](https://www.nuget.org/packages/Fable.React/). + ## Prerequisites This recipe uses the [react-d3-speedometer NPM package](https://www.npmjs.com/package/react-d3-speedometer) for demonstration purposes. [Add it to your Client](../package-management/add-npm-package-to-client.md) before continuing. @@ -13,6 +14,7 @@ open Fable.Core.JsInterop ``` Within the view function + ```fsharp Feliz.Interop.reactApi.createElement (importDefault "react-d3-speedometer", createObj [ "minValue" ==> 0 @@ -23,15 +25,19 @@ Feliz.Interop.reactApi.createElement (importDefault "react-d3-speedometer", crea - `createElement` from `Feliz.ReactApi.IReactApi` takes the component you're wrapping react-d3-speedometer, the props that component takes and creates a ReactComponent we can use in F#. - `importDefault` from ` Fable.Core.JsInterop` is giving us access to the component and is equivalent to + ```javascript import ReactSpeedometer from "react-d3-speedometer" ``` + The reason for using `importDefault` is the documentation for the component uses a default export "ReactSpeedometer". Please find a list of common import statetments at the end of this recipe As a quick check to ensure that the library is being imported and we have no typos you can `console.log` the following at the top within the view function + ```fsharp Browser.Dom.console.log("REACT-D3-IMPORT", importDefault "react-d3-speedometer") ``` + In the console window (which can be reached by right-clicking and selecting Insepct Element) you should see some output from the above log. If nothing is being seen you may need a slightly different import statement, [please refer to this recipe](../../v4-recipes/javascript/import-js-module.md). @@ -44,7 +50,9 @@ createObj [ "maxValue" ==> 10 ] ``` + Is equivalent to + ```javascript { minValue: 0, maxValue: 10 } ``` @@ -58,7 +66,7 @@ For a full detailed tutorial head over to [this blog post](https://www.compositi ## Fable.React - Setup -#### 1. Create a new file +### 1. Create a new file Create an empty file named `ReactSpeedometer.fs` in the Client project above `Index.fs` and insert the following statements at the beginning of the file. @@ -70,7 +78,8 @@ open Fable.Core.JsInterop open Fable.React ``` -#### 2. Define the Props +### 2. Define the Props + Prop represents the props of the React component. In this recipe, we're using [the props listed here](https://www.npmjs.com/package/react-d3-speedometer) for `react-d3-speedometer`. We model them in Fable.React using a discriminated union. ```fsharp @@ -85,7 +94,8 @@ type Prop = > > Note that we can model any props here, both simple values and "event handler"-style ones. -#### 3. Write the Component +### 3. Write the Component + Add the following function to the file. Note that the last argument passed into the `ofImport` function is a list of `ReactElements` to be used as children of the react component. In this case, we are passing an empty list since the component doesn't have children. ```fsharp @@ -94,7 +104,8 @@ let reactSpeedometer (props : Prop list) : ReactElement = ofImport "default" "react-d3-speedometer" propsObject [] // import the default function/object from react-d3-speedometer ``` -#### 4. Use the Component +### 4. Use the Component + With all these in place, you can use the React element in your client like so: ```fsharp