Releases: AngelMunoz/Navs
v1.0.0-rc-003
No breaking changes on this release, only goodies!
Guards can now redirect correctly after the full refactor mentioned in https://github.com/AngelMunoz/Navs/releases/tag/v1.0.0-rc-002
Full Changelog: v1.0.0-rc-002...v1.0.0-rc-003
v1.0.0-rc-002
We've went through a major refactoring during rc-1 to rc-2, the public API didn't change too much but it did had some breaking changes for most of the projects however Navs required some serious refactorings in order to simplify the routing logic.
Navs
The most important breaking change in navs is the removal of children nested routes from the route definitions, we don't really have a reason to provide a nested route component, neither exposed a public API that allowed consumer s to analyze the route graphs, the whole nested children was making the route resolution and navigation extremely complicated, we will revisit nested routes in v2 if there's enough interest in the feature
Added
IDisposableBag
- In the case of Avalonia (and it could be useful for others as well) registering disposables per route is something quite useful specially when you deal with subscriptions to observables or even monitoring adaptive values via callbacks. The disposable bag will be disposed after a successful deactivation of a route AND if the view is not cached Just remember to calldefiniion |> Route.cache NoCache
when you want to ensure you dispose of objects when a view is unloaded.RouteContext.addDisposable
- ease of access method to add disposables
Navs Breaking changes
- Rename method
Router.get
toRouter.build
RouteDefinition<'View>.children
is not available anymore, please source the nested views to a flattened route list- Guards
- Guard signatures have changed,
RouteContext voption -> RouteContext -> CancellationToken
is the new signature, the first context represents the current activated route (if any) and the second context is the desired route if the guard is successful - Guards lost the
INavigable<'View>
parameter, you can now return aRedirect "/next/destination"
with the desired route instead please keep in mind that the redirection support is not yet in this release, it will be added in the next rc.
- Guard signatures have changed,
Full Changelog: v1.0.0-rc-001...v1.0.0-rc-002
v1.0.0-rc-001
What's Changed
Nothing too crazy
Navs.Avalonia:
- Feat: Add Double Way Binding for Changeable Values (#11)
- Docs: add CVal to Navs-Avalonia.md
Full Changelog: v1.0.0-beta-008...v1.0.0-rc-001
v1.0.0-beta-008
What's Changed
- Feat: Guard Updates by in #9
- Fix Query Param equality check for simple values (sequences are not covered yet in this check)
Full Changelog: v1.0.0-beta-007...v1.0.0-beta-008
v1.0.0-beta-007
What's Changed
- feat: Add contextual information to the router (#5)
- Feat: RouterOutlet (#6)
- Feat: FuncUI RouterOutlet and AVal extensions (#8)
Full Changelog: v1.0.0-beta-006...v1.0.0-beta-007
v1.0.0-beta-006
What's Changed
- Update types and rework router functionality by in #4
This release includes some breaking changes required to stabilize the API at last specially around handler parameters.
but I don't expect more breaking changes from now on unless I find more corner cases while creating sample apps.
Speaking of sample apps, the Navs.Avalonia package includes FSharp.Data.Adaptive
extensions and utility functions so you can integrate seamlessly from both C# and F# while staying true to each language's idioms.
I tried to be as flexible and pragmatic as I can be, here's an example of a counter in both languages.
using FSharp.Data.Adaptive;
using CSharp.Data.Adaptive;
using Navs;
using UrlTemplates.RouteMatcher;
using Navs.Avalonia;
using Navs.Interop;
using Route = Navs.Avalonia.Interop.Route;
using static Navs.Avalonia.AVal.Interop;
Route.Define("home", "/", (_ , _) => {
var (count, setCount) = UseState(0);
return StackPanel()
.Spacing(8)
.Children(
TextBlock().Text("Home"),
TextBlock().Text(count.Map(value => $"Count: {value}").ToBinding()),
Button().Content("Increment").OnClickHandler((_, _) => setCount(count => count + 1)),
Button().Content("Decrement").OnClickHandler((_, _) => setCount(count => count - 1)),
Button().Content("Reset").OnClickHandler((_, _) => setCount(_ => 0))
);
}),
Route.define("home", "/", fun _ _ -> {
let (count, setCount) = AVal.useState 0
return StackPanel()
.spacing(8)
.children(
TextBlock().text("Home"),
TextBlock().text(
adaptive {
let! count = count
return $"Count: {value}"
}
// or count |> AVal.map (fun count -> $"Count: {count}")
|> AVal.toBinding
),
Button().content("Increment").OnClickHandler((_, _) => setCount(fun count -> count + 1)),
Button().content("Decrement").OnClickHandler((_, _) -> setCount(fun count -> count - 1)),
Button().content("Reset").OnClickHandler((_, _) -> setCount(fun _ -> 0))
)
})
it is easier now to use adaptive data to manage local state
Full Changelog: v1.0.0-beta-005...v1.0.0-beta-006
v1.0.0-beta-005
What's Changed
- do not add plain segments to params
- fix wrong validation check
- add utilities to extract parameters
- from query params
- from path
- list of query params
- strip leading slash for child routes
- fix: deactivate guard behavior
- fix: make sure "Navigate doesn't throw when cancelling a navigation
- add testing project for the main Navs library
Full Changelog: v1.0.0-beta-004...v1.0.0-beta-005
v1.0.0-beta-004
What's Changed
- Add test project for UrlTemplates in #1
- Add
UrlMatch
Utility functions to extract values from the parameters
Here's a sample of that from the new Tests project
Note: These functions are extension methods, but standard F# functions are also available.
test "UrlMatchExtensions.getParamSeqFromQuery can return a sequence of query params" {
let template = "/api?name&age<int>&statuses"
let url = "/api?name=john&age=30&statuses=active&statuses=inactive"
let _, _, urlMatch =
RouteMatcher.matchStrings template url
|> Result.defaultWith(fun e ->
failtestf "Expected Ok, got Error %A" e
)
let name = urlMatch.getFromParams<string>("name")
let age = urlMatch.getFromParams<int>("age")
let values = urlMatch.getParamSeqFromQuery<string>("statuses")
let statuses = values |> ValueOption.defaultValue Seq.empty
Expect.equal name (ValueSome "john") "name should match"
Expect.equal age (ValueSome 30) "age should match"
Expect.sequenceContainsOrder
statuses
(seq {
"inactive"
"active"
})
"statuses should match"
}```
**Full Changelog**: https://github.com/AngelMunoz/Navs/compare/v1.0.0-beta-003...v1.0.0-beta-004
v1.0.0-beta-003
In order to enable navigations within the handlers it has been added as a parameter
// Before
Route.define<_>("home", "/", (fun _ ->
// unable to navigate here as you'd need a router reference and it can't be created before routes are defined
))
// After
Route.define<_>("home", "/", (fun (_, nav) ->
return
UIElement
.content(
Label().text("My Text")
Button().onClick(fun _ -> nav.NavigateByName("home") |> ignore)
)
))
Full Changelog: v1.0.0-beta-002...v1.0.0-beta-003
v1.0.0-beta-002
Notable changes
Fixed a situation where QueryParams in templated URLs were not allowed to use -
or _
in thgeir name
Full Changelog: v1.0.0-beta-001...v1.0.0-beta-002