From 2a624d10ebc145d0db96b30bcd8ac23ec7035b87 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Fri, 9 Feb 2024 13:29:24 +0000 Subject: [PATCH 1/4] update versions --- Directory.Packages.props | 20 +++++++++---------- .../Fabulous.Avalonia.ColorPicker.fsproj | 2 +- .../Fabulous.Avalonia.DataGrid.fsproj | 2 +- .../Fabulous.Avalonia.ItemsRepeater.fsproj | 2 +- .../Fabulous.Avalonia.fsproj | 4 ++-- .../blank/.template.config/template.json | 8 ++++---- .../multi/.template.config/template.json | 10 +++++----- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index a22ca6bd7..39efd39fc 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -11,16 +11,16 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/extensions/Fabulous.Avalonia.ColorPicker/Fabulous.Avalonia.ColorPicker.fsproj b/extensions/Fabulous.Avalonia.ColorPicker/Fabulous.Avalonia.ColorPicker.fsproj index ebf0a87fa..4742de1a9 100644 --- a/extensions/Fabulous.Avalonia.ColorPicker/Fabulous.Avalonia.ColorPicker.fsproj +++ b/extensions/Fabulous.Avalonia.ColorPicker/Fabulous.Avalonia.ColorPicker.fsproj @@ -29,7 +29,7 @@ - + diff --git a/extensions/Fabulous.Avalonia.DataGrid/Fabulous.Avalonia.DataGrid.fsproj b/extensions/Fabulous.Avalonia.DataGrid/Fabulous.Avalonia.DataGrid.fsproj index afc741680..be8b7c748 100644 --- a/extensions/Fabulous.Avalonia.DataGrid/Fabulous.Avalonia.DataGrid.fsproj +++ b/extensions/Fabulous.Avalonia.DataGrid/Fabulous.Avalonia.DataGrid.fsproj @@ -30,7 +30,7 @@ - + diff --git a/extensions/Fabulous.Avalonia.ItemsRepeater/Fabulous.Avalonia.ItemsRepeater.fsproj b/extensions/Fabulous.Avalonia.ItemsRepeater/Fabulous.Avalonia.ItemsRepeater.fsproj index fde307f7c..9ad2698b8 100644 --- a/extensions/Fabulous.Avalonia.ItemsRepeater/Fabulous.Avalonia.ItemsRepeater.fsproj +++ b/extensions/Fabulous.Avalonia.ItemsRepeater/Fabulous.Avalonia.ItemsRepeater.fsproj @@ -27,7 +27,7 @@ - + diff --git a/src/Fabulous.Avalonia/Fabulous.Avalonia.fsproj b/src/Fabulous.Avalonia/Fabulous.Avalonia.fsproj index 66cdcc45d..a385c0f72 100644 --- a/src/Fabulous.Avalonia/Fabulous.Avalonia.fsproj +++ b/src/Fabulous.Avalonia/Fabulous.Avalonia.fsproj @@ -223,10 +223,10 @@ This version will be used as the lower bound in the NuGet package --> - + - + \ No newline at end of file diff --git a/templates/content/blank/.template.config/template.json b/templates/content/blank/.template.config/template.json index 79091d025..473d4a1c5 100644 --- a/templates/content/blank/.template.config/template.json +++ b/templates/content/blank/.template.config/template.json @@ -62,25 +62,25 @@ "type": "parameter", "dataType": "string", "replaces": "AvaloniaAndroidPkgVersion", - "defaultValue": "11.0.7" + "defaultValue": "11.0.9" }, "AvaloniaDesktopPkgVersion": { "type": "parameter", "dataType": "string", "replaces": "AvaloniaDesktopPkgVersion", - "defaultValue": "11.0.7" + "defaultValue": "11.0.9" }, "AvaloniaiOSPkgVersion": { "type": "parameter", "dataType": "string", "replaces": "AvaloniaiOSPkgVersion", - "defaultValue": "11.0.7" + "defaultValue": "11.0.9" }, "AvaloniaThemesFluentPkgVersion": { "type": "parameter", "dataType": "string", "replaces": "AvaloniaThemesFluentPkgVersion", - "defaultValue": "11.0.7" + "defaultValue": "11.0.9" } } } \ No newline at end of file diff --git a/templates/content/multi/.template.config/template.json b/templates/content/multi/.template.config/template.json index be75dd383..fea5e7213 100644 --- a/templates/content/multi/.template.config/template.json +++ b/templates/content/multi/.template.config/template.json @@ -62,31 +62,31 @@ "type": "parameter", "dataType": "string", "replaces": "AvaloniaAndroidPkgVersion", - "defaultValue": "11.0.7" + "defaultValue": "11.0.9" }, "AvaloniaBrowserPkgVersion": { "type": "parameter", "dataType": "string", "replaces": "AvaloniaBrowserPkgVersion", - "defaultValue": "11.0.7" + "defaultValue": "11.0.9" }, "AvaloniaDesktopPkgVersion": { "type": "parameter", "dataType": "string", "replaces": "AvaloniaDesktopPkgVersion", - "defaultValue": "11.0.7" + "defaultValue": "11.0.9" }, "AvaloniaiOSPkgVersion": { "type": "parameter", "dataType": "string", "replaces": "AvaloniaiOSPkgVersion", - "defaultValue": "11.0.7" + "defaultValue": "11.0.9" }, "AvaloniaThemesFluentPkgVersion": { "type": "parameter", "dataType": "string", "replaces": "AvaloniaThemesFluentPkgVersion", - "defaultValue": "11.0.7" + "defaultValue": "11.0.9" } } } \ No newline at end of file From c3b0f2635b28a9b0d887e70de9aa39890c912402 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Fri, 9 Feb 2024 14:44:36 +0000 Subject: [PATCH 2/4] Add new IsTransitionReversed to TransitioningContentControl --- .../Pages/TransitioningContentControlPage.fs | 190 +++++------------- .../Controls/TransitioningContentControl.fs | 12 +- 2 files changed, 59 insertions(+), 143 deletions(-) diff --git a/samples/Gallery/Pages/TransitioningContentControlPage.fs b/samples/Gallery/Pages/TransitioningContentControlPage.fs index 1858baaaf..43a881659 100644 --- a/samples/Gallery/Pages/TransitioningContentControlPage.fs +++ b/samples/Gallery/Pages/TransitioningContentControlPage.fs @@ -1,96 +1,26 @@ namespace Gallery open System -open System.Collections.Generic open System.Diagnostics -open System.Threading -open System.Threading.Tasks -open Avalonia open Avalonia.Animation open Avalonia.Controls open Avalonia.Layout open Avalonia.Media -open Avalonia.Media.Imaging -open Avalonia.Styling -open Avalonia.VisualTree open Fabulous.Avalonia open Fabulous +open Avalonia.Animation.Easings -type PageTransition(displayTitle: string) = - let _transition: IPageTransition = null - - member val Transition = _transition with get, set - - member val DisplayTitle = displayTitle - - override this.ToString() = this.DisplayTitle - -type CustomTransition(duration) = - - let mutable _duration: TimeSpan = Unchecked.defaultof<_> - member val Duration = _duration with get, set - - member this.GetVisualParent(from: Visual, to': Visual) = - let p1 = from.GetVisualParent() - let p2 = to'.GetVisualParent() - - if p1 <> null && p2 <> null && p1 <> p2 then - raise(ArgumentException("Controls for PageSlide must have same parent.")) - - if p1 = null then - raise(InvalidOperationException("Cannot determine visual parent.")) - else - p1 - - interface IPageTransition with - member this.Start(from: Visual, to': Visual, forward: bool, cancellationToken: CancellationToken) = - task { - if cancellationToken.IsCancellationRequested then - () - else - let tasks = List() - let parent = this.GetVisualParent(from, to') - let scaleProperty = ScaleTransform.ScaleYProperty - - if from <> null then - let animation = Animation() - let keyFrame = KeyFrame() - keyFrame.Setters.AddRange [ Setter(Property = scaleProperty, Value = 1.) ] - keyFrame.Cue <- Cue(0.) - let keyFrame' = KeyFrame() - keyFrame'.Setters.AddRange [ Setter(Property = scaleProperty, Value = 0.) ] - keyFrame'.Cue <- Cue(1.) - animation.Children.AddRange([ keyFrame; keyFrame' ]) - animation.Duration <- this.Duration - tasks.Add(animation.RunAsync(from, cancellationToken)) - - if to' <> null then - let animation = Animation() - let keyFrame = KeyFrame() - keyFrame.Setters.AddRange [ Setter(Property = scaleProperty, Value = 0.) ] - keyFrame.Cue <- Cue(0.) - let keyFrame' = KeyFrame() - keyFrame'.Setters.AddRange [ Setter(Property = scaleProperty, Value = 1.) ] - keyFrame'.Cue <- Cue(1.) - animation.Children.AddRange([ keyFrame; keyFrame' ]) - animation.Duration <- this.Duration - tasks.Add(animation.RunAsync(to', cancellationToken)) - - do! Task.WhenAll(tasks) - - if from <> null && not cancellationToken.IsCancellationRequested then - from.IsVisible <- false - } open type Fabulous.Avalonia.View module TransitioningContentControlPage = type Model = - { Images: Bitmap list - SelectedImage: Bitmap - PageTransitions: PageTransition list - SelectedTransition: PageTransition - Duration: float option + { Images: string list + SelectedImage: string + PageTransition: IPageTransition + IsReverse: bool + Transitions: string list + Duration: float ClipToBounds: bool } type Msg = @@ -99,60 +29,23 @@ module TransitioningContentControlPage = | TransitionChanged of SelectionChangedEventArgs | DurationChanged of float option | ClipToBoundsChanged of bool - | TransitionsUpdated of PageTransition list - - type CmdMsg = SettingUpTransitions of PageTransition list * int - - let updateTransitions (pageTransitions: PageTransition list) duration = - let transitions = - pageTransitions - |> List.mapi(fun index value -> - match index with - | 1 -> value.Transition <- CrossFade(TimeSpan.FromMilliseconds(duration)) - | 2 -> value.Transition <- PageSlide(TimeSpan.FromMilliseconds(duration), PageSlide.SlideAxis.Horizontal) :> IPageTransition - | 3 -> value.Transition <- PageSlide(TimeSpan.FromMilliseconds(duration), PageSlide.SlideAxis.Vertical) :> IPageTransition - | 4 -> - let compositeTransition = CompositePageTransition() - compositeTransition.PageTransitions.Add(pageTransitions[1].Transition) - compositeTransition.PageTransitions.Add(pageTransitions[2].Transition) - compositeTransition.PageTransitions.Add(pageTransitions[3].Transition) - value.Transition <- compositeTransition :> IPageTransition - | 5 -> value.Transition <- CustomTransition(TimeSpan.FromMilliseconds(duration)) :> IPageTransition - | _ -> value.Transition <- null - - value) - - TransitionsUpdated transitions + | ReverseChanged of bool + type CmdMsg = | NoCmdMsg let mapCmdMsgToCmd cmdMsg = match cmdMsg with - | SettingUpTransitions(pageTransitions, i) -> Cmd.ofMsg(updateTransitions pageTransitions i) - - let pageTransitions = - [ PageTransition("None") - PageTransition("CrossFade") - PageTransition("Slide horizontally") - PageTransition("Slide vertically") - PageTransition("Composite") - PageTransition("Custom") ] + | NoCmdMsg -> Cmd.none let init () = - let images = [ "fabulous-icon.png"; "fsharp-icon.png"; "fabulous-icon.png" ] - - let images = - images - |> List.map(fun image -> - let path = $"avares://Gallery/Assets/Icons/{image}" - ImageSource.fromString path) - - { Images = images - SelectedImage = images[0] - SelectedTransition = pageTransitions[0] - PageTransitions = pageTransitions - Duration = Some 250. + { Images = [ "fabulous-icon.png"; "fsharp-icon.png"; "fabulous-icon.png" ] + SelectedImage = "fabulous-icon.png" + PageTransition = PageSlide(TimeSpan.FromSeconds(250.), PageSlide.SlideAxis.Horizontal) + Transitions = [ "Slide"; "CrossFade"; "3D Rotation"; "Composite" ] + Duration = 250. + IsReverse = false ClipToBounds = false }, - [ SettingUpTransitions(pageTransitions, 500) ] + [] let update msg model = match msg with @@ -161,7 +54,7 @@ module TransitioningContentControlPage = let index = (index + 1) % model.Images.Length { model with - SelectedImage = model.Images[index] }, + SelectedImage = model.Images.[index] }, [] | PrevImage -> @@ -170,12 +63,12 @@ module TransitioningContentControlPage = let index = if index < 0 then model.Images.Length - 1 else index { model with - SelectedImage = model.Images[index] }, + SelectedImage = model.Images.[index] }, [] | DurationChanged duration -> let duration = duration |> Option.defaultValue 500 - { model with Duration = Some duration }, [ SettingUpTransitions(model.PageTransitions, int duration) ] + { model with Duration = duration }, [] | ClipToBoundsChanged clipToBounds -> { model with @@ -185,23 +78,31 @@ module TransitioningContentControlPage = | TransitionChanged selection -> let control = selection.Source :?> ComboBox let selectedItem = control.SelectedIndex - let selection = control.Items[selectedItem] :?> string + let selection = control.Items.[selectedItem] :?> string + + let transition = + match selection with + | "Slide" -> PageSlide(TimeSpan.FromMilliseconds(model.Duration), PageSlide.SlideAxis.Horizontal) :> IPageTransition + | "CrossFade" -> CrossFade(TimeSpan.FromSeconds(model.Duration)) + | "3D Rotation" -> Rotate3DTransition(TimeSpan.FromSeconds(model.Duration), PageSlide.SlideAxis.Horizontal) + | "Composite" -> + let crossFade = CrossFade(TimeSpan.FromSeconds(model.Duration)) + crossFade.FadeInEasing <- BounceEaseIn() + crossFade.FadeOutEasing <- BounceEaseOut() - let selectedTransition = - model.PageTransitions |> List.tryFind(fun x -> x.DisplayTitle = selection) + let compositePageTransition = CompositePageTransition() + compositePageTransition.PageTransitions.Add(Rotate3DTransition(TimeSpan.FromSeconds(model.Duration), PageSlide.SlideAxis.Horizontal)) + compositePageTransition.PageTransitions.Add(crossFade) + compositePageTransition - match selectedTransition with - | None -> model, [] - | Some value -> - { model with - SelectedTransition = selectedTransition.Value }, - [] + | _ -> PageSlide(TimeSpan.FromSeconds(model.Duration), PageSlide.SlideAxis.Horizontal) - | TransitionsUpdated pageTransitions -> { model with - PageTransitions = pageTransitions }, + PageTransition = transition }, [] + | ReverseChanged isReverse -> { model with IsReverse = isReverse }, [] + let program = Program.statefulWithCmdMsg init update mapCmdMsgToCmd |> Program.withTrace(fun (format, args) -> Debug.WriteLine(format, box args)) @@ -227,7 +128,7 @@ module TransitioningContentControlPage = (HStack(5.) { HeaderedContentControl( "Select a transition", - ComboBox(model.PageTransitions |> List.map(_.DisplayTitle), (fun x -> TextBlock(x))) + ComboBox(model.Transitions, (fun x -> TextBlock(x))) .selectedIndex(0) .onSelectionChanged(TransitionChanged) .verticalAlignment(VerticalAlignment.Center) @@ -235,7 +136,7 @@ module TransitioningContentControlPage = HeaderedContentControl( "Duration", - NumericUpDown(100., 1000., model.Duration, DurationChanged) + NumericUpDown(100., 1000., Some model.Duration, DurationChanged) .increment(250.) .verticalAlignment(VerticalAlignment.Center) ) @@ -263,9 +164,14 @@ module TransitioningContentControlPage = Button(">", NextImage).dock(Dock.Right) + CheckBox("Reverse", model.IsReverse, ReverseChanged) + .dock(Dock.Bottom) + .margin(5.) + Border( - TransitioningContentControl(Image(model.SelectedImage)) - .pageTransition(model.SelectedTransition.Transition) + TransitioningContentControl(Image($"avares://Gallery/Assets/Icons/{model.SelectedImage}")) + .pageTransition(model.PageTransition) + .isTransitionReversed(model.IsReverse) .size(200., 200.) ) .margin(5.) diff --git a/src/Fabulous.Avalonia/Views/Controls/TransitioningContentControl.fs b/src/Fabulous.Avalonia/Views/Controls/TransitioningContentControl.fs index 4f9aba885..f87b6d774 100644 --- a/src/Fabulous.Avalonia/Views/Controls/TransitioningContentControl.fs +++ b/src/Fabulous.Avalonia/Views/Controls/TransitioningContentControl.fs @@ -15,6 +15,9 @@ module TransitioningContentControl = let PageTransition = Attributes.defineAvaloniaPropertyWithEquality TransitioningContentControl.PageTransitionProperty + let IsTransitionReversed = + Attributes.defineAvaloniaPropertyWithEquality TransitioningContentControl.IsTransitionReversedProperty + [] module TransitioningContentControlBuilders = type Fabulous.Avalonia.View with @@ -39,5 +42,12 @@ type TransitioningContentControlModifiers = /// Current widget. /// The PageTransition value. [] - static member inline pageTransition(this: WidgetBuilder<'msg, #IFabTransitioningContentControl>, value: IPageTransition) = + static member inline pageTransition(this: WidgetBuilder<'msg, #IFabTransitioningContentControl>, value: #IPageTransition) = this.AddScalar(TransitioningContentControl.PageTransition.WithValue(value)) + + /// Sets the IsTransitionReversed property. + /// Current widget. + /// The IsTransitionReversed value. + [] + static member inline isTransitionReversed(this: WidgetBuilder<'msg, #IFabTransitioningContentControl>, value: bool) = + this.AddScalar(TransitioningContentControl.IsTransitionReversed.WithValue(value)) From eadb2546b168fb9983bbdaadd5c69d9a61c86759 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Fri, 9 Feb 2024 15:58:19 +0000 Subject: [PATCH 3/4] Update TreeDataGrid --- Directory.Packages.props | 2 +- .../Fabulous.Avalonia.TreeDataGrid.fsproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 39efd39fc..ef410d997 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -21,6 +21,6 @@ - + \ No newline at end of file diff --git a/extensions/Fabulous.Avalonia.TreeDataGrid/Fabulous.Avalonia.TreeDataGrid.fsproj b/extensions/Fabulous.Avalonia.TreeDataGrid/Fabulous.Avalonia.TreeDataGrid.fsproj index a21bf628b..1d2a8ce8e 100644 --- a/extensions/Fabulous.Avalonia.TreeDataGrid/Fabulous.Avalonia.TreeDataGrid.fsproj +++ b/extensions/Fabulous.Avalonia.TreeDataGrid/Fabulous.Avalonia.TreeDataGrid.fsproj @@ -27,7 +27,7 @@ - + From 6c9f761e296e86004152c8e0b744a2bb06a61bbe Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Fri, 9 Feb 2024 15:59:22 +0000 Subject: [PATCH 4/4] CHANGELOG --- extensions/Fabulous.Avalonia.ColorPicker/CHANGELOG.md | 4 ++++ extensions/Fabulous.Avalonia.DataGrid/CHANGELOG.md | 4 ++++ .../Fabulous.Avalonia.ItemsRepeater/CHANGELOG.md | 4 ++++ .../Fabulous.Avalonia.TreeDataGrid/CHANGELOG.md | 4 ++++ src/Fabulous.Avalonia/CHANGELOG.md | 11 +++++++++++ templates/CHANGELOG.md | 5 +++++ 6 files changed, 32 insertions(+) diff --git a/extensions/Fabulous.Avalonia.ColorPicker/CHANGELOG.md b/extensions/Fabulous.Avalonia.ColorPicker/CHANGELOG.md index e924cc9fb..3165f8573 100644 --- a/extensions/Fabulous.Avalonia.ColorPicker/CHANGELOG.md +++ b/extensions/Fabulous.Avalonia.ColorPicker/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] _No unreleased changes_ +## [2.4.0-pre1] - 2024-02-09 +### Changed +- Update to use version 11.0.9 + ## [2.3.0] - 2024-01-17 ### Added - No changes diff --git a/extensions/Fabulous.Avalonia.DataGrid/CHANGELOG.md b/extensions/Fabulous.Avalonia.DataGrid/CHANGELOG.md index a30e56864..0e76933c8 100644 --- a/extensions/Fabulous.Avalonia.DataGrid/CHANGELOG.md +++ b/extensions/Fabulous.Avalonia.DataGrid/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] _No unreleased changes_ +## [2.4.0-pre1] - 2024-02-09 +### Changed +- Update to use version 11.0.9 + ## [2.3.0] - 2024-01-17 ### Added - No changes diff --git a/extensions/Fabulous.Avalonia.ItemsRepeater/CHANGELOG.md b/extensions/Fabulous.Avalonia.ItemsRepeater/CHANGELOG.md index 8874624ec..dbef5b778 100644 --- a/extensions/Fabulous.Avalonia.ItemsRepeater/CHANGELOG.md +++ b/extensions/Fabulous.Avalonia.ItemsRepeater/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] _No unreleased changes_ +## [2.4.0-pre1] - 2024-02-09 +### Changed +- Update to use version 11.0.9 + ## [2.3.0] - 2024-01-17 ### Added - No changes diff --git a/extensions/Fabulous.Avalonia.TreeDataGrid/CHANGELOG.md b/extensions/Fabulous.Avalonia.TreeDataGrid/CHANGELOG.md index 7341f13d5..e00e40635 100644 --- a/extensions/Fabulous.Avalonia.TreeDataGrid/CHANGELOG.md +++ b/extensions/Fabulous.Avalonia.TreeDataGrid/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] _No unreleased changes_ +## [2.4.0-pre1] - 2024-02-09 +### Changed +- Update to use version 11.0.2 + ## [2.3.0] - 2024-01-17 ### Added - No changes diff --git a/src/Fabulous.Avalonia/CHANGELOG.md b/src/Fabulous.Avalonia/CHANGELOG.md index 7f315ff99..7ee5dfb3b 100644 --- a/src/Fabulous.Avalonia/CHANGELOG.md +++ b/src/Fabulous.Avalonia/CHANGELOG.md @@ -8,6 +8,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] _No unreleased changes_ +## [2.4.0-pre1] - 2024-02-09 +### Added +- Add support for Components by @TimLariviere at https://github.com/fabulous-dev/Fabulous.Avalonia/pull/206 + +### Changed +- Fix templates after Component API support by @TimLariviere at https://github.com/fabulous-dev/Fabulous.Avalonia/pull/207 +- Fix AutoCompleteBox by @edgarfgp at https://github.com/fabulous-dev/Fabulous.Avalonia/pull/210/files +- Use Fabulous pre8 +- Fix for carrousel page transition modifiers by @edgarfgp at https://github.com/fabulous-dev/Fabulous.Avalonia/pull/218 +- Update to use version 11.0.9 + ## [2.3.0] - 2024-01-17 ### Added - ImageSource constructors and modifiers consolidations diff --git a/templates/CHANGELOG.md b/templates/CHANGELOG.md index e225e3f5c..cafc24ff4 100644 --- a/templates/CHANGELOG.md +++ b/templates/CHANGELOG.md @@ -8,6 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] _No unreleased changes_ +## [2.4.0-pre1] - 2024-02-09 +### Changed +- Fix templates after Component API support by @TimLariviere at https://github.com/fabulous-dev/Fabulous.Avalonia/pull/207 +- Update to use version 11.0.9 + ## [2.3.0] - 2024-01-17 ### Added - No changes