diff --git a/samples/Playground/App.fs b/samples/Playground/App.fs
index fad3c5b..89f81c9 100644
--- a/samples/Playground/App.fs
+++ b/samples/Playground/App.fs
@@ -10,59 +10,65 @@ open Microsoft.Maui.Primitives
open type Fabulous.Maui.View
module App =
- type FieldFocused =
- | Entry1
- | Entry2
- | Entry3
-
- type Model = { Focus: FieldFocused option }
-
+ type Path =
+ | Home
+ | Details
+ | Subdetails of int
+
+ type Model =
+ { Stack: Path list }
+
type Msg =
- | TextChanged of string
- | FocusChanged of FieldFocused * bool
- | SetFocus of FieldFocused option
-
- let init () = { Focus = None }
-
+ | StackUpdated of Path list
+ | GoTo of Path
+ | GoBack
+ | GoToRoot
+
+ let init() =
+ { Stack = [ Home ] }
+
let update msg model =
match msg with
- | TextChanged _ -> model
- | FocusChanged(field, isFocused) ->
- if isFocused then
- { model with Focus = Some field }
- else
- { model with Focus = None }
-
- | SetFocus field -> { model with Focus = field }
-
- let focusChanged field args = FocusChanged(field, args)
+ | StackUpdated stack ->
+ { model with Stack = stack }
+ | GoTo path ->
+ { model with Stack = path :: model.Stack }
+ | GoBack ->
+ { model with Stack = model.Stack |> List.tail }
+ | GoToRoot ->
+ { model with Stack = [model.Stack |> List.last] }
let view model =
Application(
- ContentPage(
- (VStack(spacing = 20.) {
- let text =
- match model.Focus with
- | None -> "None"
- | Some f -> f.ToString()
-
- Label($"Field currently selected: {text}")
-
- Entry("Entry1", TextChanged)
- .focus(model.Focus = Some Entry1, focusChanged Entry1)
-
- Entry("Entry2", TextChanged)
- .focus(model.Focus = Some Entry2, focusChanged Entry2)
-
- Entry("Entry3", TextChanged)
- .focus(model.Focus = Some Entry3, focusChanged Entry3)
-
- Button("Set focus on Entry1", SetFocus(Some Entry1))
- Button("Set focus on Entry2", SetFocus(Some Entry2))
- Button("Set focus on Entry3", SetFocus(Some Entry3))
- Button("Unfocus", SetFocus None)
- })
- .margin(20.)
+ NavigationStack(List.rev model.Stack, StackUpdated, fun path ->
+ match path with
+ | Home ->
+ ContentPage(
+ VStack(spacing = 15.) {
+ Label("Home")
+ Button("Go to Details", GoTo Details)
+ }
+ )
+ .title("Home")
+ | Details ->
+ ContentPage(
+ VStack(spacing = 15.) {
+ Label("Details")
+ for i in 1..3 do
+ Button($"Go to Subdetails {i}", GoTo (Subdetails i))
+ Button("Go back", GoBack)
+ }
+ )
+ .title("Details")
+ | Subdetails i ->
+ ContentPage(
+ VStack(spacing = 15.) {
+ Label($"Subdetails {i}")
+ Button("Go back", GoBack)
+ Button("Go to root", GoToRoot)
+ }
+ )
+ .title($"Subdetails {i}")
)
)
diff --git a/src/Fabulous.MauiControls/Fabulous.MauiControls.fsproj b/src/Fabulous.MauiControls/Fabulous.MauiControls.fsproj
index 3020042..e6a83ff 100644
--- a/src/Fabulous.MauiControls/Fabulous.MauiControls.fsproj
+++ b/src/Fabulous.MauiControls/Fabulous.MauiControls.fsproj
@@ -57,6 +57,7 @@
+
diff --git a/src/Fabulous.MauiControls/Views/Pages/NavigationStack.fs b/src/Fabulous.MauiControls/Views/Pages/NavigationStack.fs
new file mode 100644
index 0000000..6a242ac
--- /dev/null
+++ b/src/Fabulous.MauiControls/Views/Pages/NavigationStack.fs
@@ -0,0 +1,70 @@
+namespace Fabulous.Maui
+
+open System
+open System.Collections.Generic
+open Fabulous
+open Fabulous.Maui
+open Fabulous.StackAllocatedCollections.StackList
+open Microsoft.Maui.Controls
+
+type IFabNavigationStack =
+ inherit IFabNavigationPage
+
+
+
+
+type FabNavigationStack() =
+ inherit NavigationPage()
+
+ let stackUpdated = Event, EventArgs>()
+ let mutable stack: IEnumerable = [||]
+
+ []
+ member _.StackUpdated = stackUpdated.Publish
+
+ member this.Stack
+ with get () = stack
+ and set value =
+ if stack <> value then
+ stack <- value
+ this.ApplyStack()
+
+ member private this.ApplyStack() =
+ // TODO: Diff the stack and only update the pages that changed
+ stackUpdated.Trigger(this, EventArgs())
+
+
+
+
+
+
+
+
+
+
+
+
+module NavigationStack =
+ let WidgetKey = Widgets.register()
+
+ let Stack = Attributes.defineSimpleScalarWithEquality> "NavigationStack_Stack" (fun prevOpt currOpt node ->
+ ()
+ )
+
+[]
+module NavigationStackBuilders =
+ type Fabulous.Maui.View with
+ static member inline NavigationStack(stack: 'path list, onStackUpdated: 'path list -> 'msg, router: 'path -> WidgetBuilder<'msg, #IFabPage>) =
+ let pages = [| for path in stack do (router path).Compile() |]
+ let pages: ArraySlice = (uint16 pages.Length, pages)
+
+ WidgetBuilder<'msg, IFabNavigationStack>(
+ NavigationStack.WidgetKey,
+ AttributesBundle(
+ StackList.empty(),
+ ValueNone,
+ ValueSome [|
+ NavigationPage.Pages.WithValue(pages)
+ |]
+ )
+ )
\ No newline at end of file