diff --git a/.gitignore b/.gitignore index bba847b..8110b70 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ Directory.Build.props docs/output temp paket-files +.ionide diff --git a/.paket/Paket.Restore.targets b/.paket/Paket.Restore.targets index 7c61070..b4f593e 100644 --- a/.paket/Paket.Restore.targets +++ b/.paket/Paket.Restore.targets @@ -17,23 +17,43 @@ native /Library/Frameworks/Mono.framework/Commands/mono mono - - $(PaketToolsPath)paket - $(PaketRootPath)paket.exe - $(PaketToolsPath)paket.exe - $(PaketToolsPath)paket.exe - $(PaketToolsPath)paket + + $(PaketRootPath)paket.bootstrapper.exe + $(PaketToolsPath)paket.bootstrapper.exe + $([System.IO.Path]::GetDirectoryName("$(PaketBootStrapperExePath)"))\ + + + + + $(PaketRootPath)paket.exe + $(PaketToolsPath)paket.exe + $(PaketToolsPath)paket.exe + $(_PaketBootStrapperExeDir)paket.exe + paket.exe + + + $(PaketRootPath)paket + $(PaketToolsPath)paket + $(PaketToolsPath)paket + + + $(PaketRootPath)paket.exe + $(PaketToolsPath)paket.exe + + + $(PaketBootStrapperExeDir)paket.exe + + + paket <_PaketExeExtension>$([System.IO.Path]::GetExtension("$(PaketExePath)")) dotnet "$(PaketExePath)" - "$(PaketExePath)" $(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)" - "$(PaketExePath)" + "$(PaketExePath)" + - $(PaketRootPath)paket.bootstrapper.exe - $(PaketToolsPath)paket.bootstrapper.exe "$(PaketBootStrapperExePath)" $(MonoPath) --runtime=v4.0.30319 "$(PaketBootStrapperExePath)" @@ -151,15 +171,17 @@ + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',').Length) $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0]) $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1]) $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[4]) - $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5]) + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5]) %(PaketReferencesFileLinesInfo.PackageVersion) All - runtime + runtime + runtime true @@ -192,19 +214,27 @@ false + $(MSBuildVersion) + 15.8.0 <_NuspecFilesNewLocation Include="$(BaseIntermediateOutputPath)$(Configuration)\*.nuspec"/> + + $(MSBuildProjectDirectory)/$(MSBuildProjectFile) true - false - true + false + true + false + true + false + true $(BaseIntermediateOutputPath)$(Configuration) $(BaseIntermediateOutputPath) @@ -219,9 +249,52 @@ - - + + - = 4.5.2) - restriction: >= netstandard2.0 - Fable.Elmish (2.0) - Fable.Core (>= 2.0) - restriction: >= netstandard2.0 + Fable.Elmish (3.0.0-beta-2) + Fable.Core (>= 2.0.1) - restriction: >= netstandard2.0 Fable.PowerPack (>= 2.0.1) - restriction: >= netstandard2.0 FSharp.Core (>= 4.5.2) - restriction: >= netstandard2.0 Fable.Import.Browser (1.3) - restriction: >= netstandard2.0 Fable.Core (>= 1.3.17) - restriction: >= netstandard1.6 - Fable.PowerPack (2.0.1) + Fable.PowerPack (2.0.2) - restriction: >= netstandard1.6 Fable.Core (>= 2.0) - restriction: >= netstandard2.0 Fable.Import.Browser (>= 1.3) - restriction: >= netstandard2.0 FSharp.Core (>= 4.5.2) - restriction: >= netstandard2.0 @@ -24,7 +24,7 @@ NUGET Fable.PowerPack (>= 1.3.2) - restriction: >= netstandard1.6 Fable.React (>= 1.2.2) - restriction: >= netstandard1.6 FSharp.Core (>= 4.2.3) - restriction: >= netstandard1.6 - FSharp.Core (4.5.2) - content: none, redirects: force + FSharp.Core (4.5.3) - content: none, redirects: force System.Collections (>= 4.0.11) - restriction: && (< net45) (>= netstandard1.6) (< netstandard2.0) System.Console (>= 4.0) - restriction: && (< net45) (>= netstandard1.6) (< netstandard2.0) System.Diagnostics.Debug (>= 4.0.11) - restriction: && (< net45) (>= netstandard1.6) (< netstandard2.0) diff --git a/src/Fable.Elmish.React.fsproj b/src/Fable.Elmish.React.fsproj index 9d33599..4cec691 100644 --- a/src/Fable.Elmish.React.fsproj +++ b/src/Fable.Elmish.React.fsproj @@ -10,5 +10,8 @@ + + + \ No newline at end of file diff --git a/src/common.fs b/src/common.fs index 80d0ff4..5e84ed9 100644 --- a/src/common.fs +++ b/src/common.fs @@ -1,9 +1,6 @@ namespace Elmish.React -open System -open Fable.Import.React -open Fable.Helpers.React -open Fable.Core +open Fable.React open Elmish type LazyProps<'model> = { diff --git a/src/paket.references b/src/paket.references index d665bb2..3305d29 100644 --- a/src/paket.references +++ b/src/paket.references @@ -1,5 +1,4 @@ FSharp.Core Fable.Core -Fable.PowerPack -Fable.React -Fable.Elmish +#Fable.React +Fable.Elmish \ No newline at end of file diff --git a/src/react-native.fs b/src/react-native.fs index 59a9b31..f5adf00 100644 --- a/src/react-native.fs +++ b/src/react-native.fs @@ -1,7 +1,6 @@ namespace Elmish.ReactNative -open System -open Fable.Import.React +open Fable.React open Fable.Core open Elmish @@ -33,18 +32,17 @@ module Components = [] type AppRegistry = - static member registerComponent(appKey:string, getComponentFunc:unit->ComponentClass<_>) : unit = + static member registerComponent(appKey:string, getComponentFunc:unit->ReactElementType<_>) : unit = failwith "JS only" [] module Program = - open Fable.Core.JsInterop open Elmish.React open Components /// Setup rendering of root ReactNative component let withReactNative appKey (program:Program<_,_,_,_>) = - AppRegistry.registerComponent(appKey, fun () -> unbox typeof) + AppRegistry.registerComponent(appKey, fun () -> unbox JsInterop.jsConstructor) let render m d = match appState with | Some state -> diff --git a/src/react.fs b/src/react.fs index 27b7f2d..305f316 100644 --- a/src/react.fs +++ b/src/react.fs @@ -1,17 +1,12 @@ namespace Elmish.React -open System -open Fable.Import.React -open Fable.Core -open Fable.Helpers.React - [] module Helpers = - open Fable.Helpers.React.Props + open Fable.React.Props open Fable.Core.JsInterop /// `Ref` callback that sets the value of an input textbox after DOM element is created. - /// Can be used override input box value. + /// Can be used instead of `DefaultValue` and `Value` props to override input box value. let inline valueOrDefault value = Ref <| (fun e -> if e |> isNull |> not && !!e?value <> !!value then e?value <- !!value) @@ -20,9 +15,9 @@ module Program = module Internal = - open Fable.Import.Browser + open Fable.Browser.Dom - let withReactUsing lazyView2With placeholderId (program:Elmish.Program<_,_,_,_>) = + let withReactBatchedUsing lazyView2With placeholderId (program:Elmish.Program<_,_,_,_>) = let mutable lastRequest = None let setState model dispatch = match lastRequest with @@ -30,16 +25,16 @@ module Program = | _ -> () lastRequest <- Some (window.requestAnimationFrame (fun _ -> - Fable.Import.ReactDom.render( + Fable.ReactDom.render( lazyView2With (fun x y -> obj.ReferenceEquals(x,y)) program.view model dispatch, document.getElementById(placeholderId) ))) { program with setState = setState } - let withReactUnoptimizedUsing lazyView2With placeholderId (program:Elmish.Program<_,_,_,_>) = + let withReactSynchronousUsing lazyView2With placeholderId (program:Elmish.Program<_,_,_,_>) = let setState model dispatch = - Fable.Import.ReactDom.render( + Fable.ReactDom.render( lazyView2With (fun x y -> obj.ReferenceEquals(x,y)) program.view model dispatch, document.getElementById(placeholderId) ) @@ -48,22 +43,32 @@ module Program = let withReactHydrateUsing lazyView2With placeholderId (program:Elmish.Program<_,_,_,_>) = let setState model dispatch = - Fable.Import.ReactDom.hydrate( + Fable.ReactDom.hydrate( lazyView2With (fun x y -> obj.ReferenceEquals(x,y)) program.view model dispatch, document.getElementById(placeholderId) ) { program with setState = setState } - /// Setup rendering of root React component inside html element identified by placeholderId + /// Renders React root component inside html element identified by placeholderId. + /// Uses `requestAnimationFrame` to batch updates to prevent drops in frame rate. + /// NOTE: This may have unexpected effects in React controlled inputs, see https://github.com/elmish/react/issues/12 + let withReactBatched placeholderId (program:Elmish.Program<_,_,_,_>) = + Internal.withReactBatchedUsing lazyView2With placeholderId program + + /// Renders React root component inside html element identified by placeholderId. + /// New renders are triggered immediately after an update. + let withReactSynchronous placeholderId (program:Elmish.Program<_,_,_,_>) = + Internal.withReactSynchronousUsing lazyView2With placeholderId program + + [] let withReact placeholderId (program:Elmish.Program<_,_,_,_>) = - Internal.withReactUsing lazyView2With placeholderId program + Internal.withReactBatchedUsing lazyView2With placeholderId program - /// `withReact` uses `requestAnimationFrame` to optimize rendering in scenarios with updates at a higher rate than 60FPS, but this makes the cursor jump to the end in `input` elements. - /// This function works around the glitch if you don't need the optimization (see https://github.com/elmish/react/issues/12). + [] let withReactUnoptimized placeholderId (program:Elmish.Program<_,_,_,_>) = - Internal.withReactUnoptimizedUsing lazyView2With placeholderId program + Internal.withReactSynchronousUsing lazyView2With placeholderId program - /// Setup rendering of root React component inside html element identified by placeholderId using React.hydrate + /// Renders React root component inside html element identified by placeholderId using `React.hydrate`. let withReactHydrate placeholderId (program:Elmish.Program<_,_,_,_>) = Internal.withReactHydrateUsing lazyView2With placeholderId program