diff --git a/components/Loading/OpenSolution.bat b/components/Loading/OpenSolution.bat
new file mode 100644
index 00000000..814a56d4
--- /dev/null
+++ b/components/Loading/OpenSolution.bat
@@ -0,0 +1,3 @@
+@ECHO OFF
+
+powershell ..\..\tooling\ProjectHeads\GenerateSingleSampleHeads.ps1 -componentPath %CD% %*
\ No newline at end of file
diff --git a/components/Loading/samples/Assets/Loading.png b/components/Loading/samples/Assets/Loading.png
new file mode 100644
index 00000000..59790fce
Binary files /dev/null and b/components/Loading/samples/Assets/Loading.png differ
diff --git a/components/Loading/samples/Dependencies.props b/components/Loading/samples/Dependencies.props
new file mode 100644
index 00000000..e622e1df
--- /dev/null
+++ b/components/Loading/samples/Dependencies.props
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/Loading/samples/Loading.Samples.csproj b/components/Loading/samples/Loading.Samples.csproj
new file mode 100644
index 00000000..b4decfde
--- /dev/null
+++ b/components/Loading/samples/Loading.Samples.csproj
@@ -0,0 +1,16 @@
+
+
+ Loading
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
+
+
diff --git a/components/Loading/samples/Loading.md b/components/Loading/samples/Loading.md
new file mode 100644
index 00000000..c49f12b6
--- /dev/null
+++ b/components/Loading/samples/Loading.md
@@ -0,0 +1,17 @@
+---
+title: Loading
+author: nmetulev
+description: The Loading control helps to show content with animation to the user while the app is doing some calculation..
+keywords: Loading, Control, loader, progress
+dev_langs:
+ - csharp
+category: Controls
+subcategory: StatusAndInfo
+discussion-id: 0
+issue-id: 0
+icon: Assets/Loading.png
+---
+
+The [Loading](/dotnet/api/microsoft.toolkit.uwp.ui.controls.loading) control is for showing an animation with some content when the user should wait in some tasks of the app.
+
+> [!Sample LoadingSample]
diff --git a/components/Loading/samples/LoadingSample.xaml b/components/Loading/samples/LoadingSample.xaml
new file mode 100644
index 00000000..2c50204e
--- /dev/null
+++ b/components/Loading/samples/LoadingSample.xaml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/Loading/samples/LoadingSample.xaml.cs b/components/Loading/samples/LoadingSample.xaml.cs
new file mode 100644
index 00000000..945d7264
--- /dev/null
+++ b/components/Loading/samples/LoadingSample.xaml.cs
@@ -0,0 +1,17 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace LoadingExperiment.Samples;
+
+[ToolkitSampleTextOption("LoadingContent", "Loading content..", Title = "Content")]
+[ToolkitSampleBoolOption("LoadingState", true, Title = "IsLoading")]
+
+[ToolkitSample(id: nameof(LoadingSample), "Loading", description: $"A sample for showing how to create and use a {nameof(CommunityToolkit.WinUI.Controls.Loading)} control.")]
+public sealed partial class LoadingSample : Page
+{
+ public LoadingSample()
+ {
+ this.InitializeComponent();
+ }
+}
diff --git a/components/Loading/src/CommunityToolkit.WinUI.Controls.Loading.csproj b/components/Loading/src/CommunityToolkit.WinUI.Controls.Loading.csproj
new file mode 100644
index 00000000..6b886970
--- /dev/null
+++ b/components/Loading/src/CommunityToolkit.WinUI.Controls.Loading.csproj
@@ -0,0 +1,12 @@
+
+
+ Loading
+ This package contains Loading.
+
+
+ CommunityToolkit.WinUI.Controls.LoadingRns
+
+
+
+
+
diff --git a/components/Loading/src/Dependencies.props b/components/Loading/src/Dependencies.props
new file mode 100644
index 00000000..e622e1df
--- /dev/null
+++ b/components/Loading/src/Dependencies.props
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/Loading/src/Loading.Properties.cs b/components/Loading/src/Loading.Properties.cs
new file mode 100644
index 00000000..bf1c244b
--- /dev/null
+++ b/components/Loading/src/Loading.Properties.cs
@@ -0,0 +1,43 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace CommunityToolkit.WinUI.Controls;
+
+///
+/// Loading control allows to show an loading animation with some xaml in it.
+///
+public partial class Loading
+{
+ ///
+ /// Identifies the dependency property.
+ ///
+ public static readonly DependencyProperty IsLoadingProperty = DependencyProperty.Register(
+ nameof(IsLoading), typeof(bool), typeof(Loading), new PropertyMetadata(default(bool), IsLoadingPropertyChanged));
+
+ ///
+ /// Gets or sets a value indicating whether the control is in the loading state.
+ ///
+ /// Set this to true to show the Loading control, false to hide the control.
+ public bool IsLoading
+ {
+ get { return (bool)GetValue(IsLoadingProperty); }
+ set { SetValue(IsLoadingProperty, value); }
+ }
+
+ private static void IsLoadingPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ if (d is Loading control)
+ {
+ if (control._presenter == null)
+ {
+ if (control.GetTemplateChild("ContentGrid") is FrameworkElement content)
+ {
+ control._presenter = content;
+ }
+ }
+
+ control?.Update();
+ }
+ }
+}
diff --git a/components/Loading/src/Loading.cs b/components/Loading/src/Loading.cs
new file mode 100644
index 00000000..8ed7b1c6
--- /dev/null
+++ b/components/Loading/src/Loading.cs
@@ -0,0 +1,36 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace CommunityToolkit.WinUI.Controls;
+
+///
+/// Loading control allows to show an loading animation with some xaml in it.
+///
+[TemplateVisualState(Name = "LoadingIn", GroupName = "CommonStates")]
+[TemplateVisualState(Name = "LoadingOut", GroupName = "CommonStates")]
+public partial class Loading : ContentControl
+{
+ private FrameworkElement? _presenter;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public Loading()
+ {
+ DefaultStyleKey = typeof(Loading);
+ }
+
+ ///
+ protected override void OnApplyTemplate()
+ {
+ base.OnApplyTemplate();
+
+ Update();
+ }
+
+ private void Update()
+ {
+ VisualStateManager.GoToState(this, IsLoading ? "LoadingIn" : "LoadingOut", true);
+ }
+}
diff --git a/components/Loading/src/Loading.xaml b/components/Loading/src/Loading.xaml
new file mode 100644
index 00000000..4bf8b58f
--- /dev/null
+++ b/components/Loading/src/Loading.xaml
@@ -0,0 +1,122 @@
+
+
+
+
+
diff --git a/components/Loading/src/MultiTarget.props b/components/Loading/src/MultiTarget.props
new file mode 100644
index 00000000..b11c1942
--- /dev/null
+++ b/components/Loading/src/MultiTarget.props
@@ -0,0 +1,9 @@
+
+
+
+ uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android;
+
+
\ No newline at end of file
diff --git a/components/Loading/src/Themes/Generic.xaml b/components/Loading/src/Themes/Generic.xaml
new file mode 100644
index 00000000..488457c7
--- /dev/null
+++ b/components/Loading/src/Themes/Generic.xaml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/components/Loading/tests/ExampleLoadingTestClass.cs b/components/Loading/tests/ExampleLoadingTestClass.cs
new file mode 100644
index 00000000..65ab605b
--- /dev/null
+++ b/components/Loading/tests/ExampleLoadingTestClass.cs
@@ -0,0 +1,134 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using CommunityToolkit.Tooling.TestGen;
+using CommunityToolkit.Tests;
+using CommunityToolkit.WinUI.Controls;
+
+namespace LoadingExperiment.Tests;
+
+[TestClass]
+public partial class ExampleLoadingTestClass : VisualUITestBase
+{
+ // If you don't need access to UI objects directly or async code, use this pattern.
+ [TestMethod]
+ public void SimpleSynchronousExampleTest()
+ {
+ var assembly = typeof(Loading).Assembly;
+ var type = assembly.GetType(typeof(Loading).FullName ?? string.Empty);
+
+ Assert.IsNotNull(type, "Could not find Loading type.");
+ Assert.AreEqual(typeof(Loading), type, "Type of Loading does not match expected type.");
+ }
+
+ // If you don't need access to UI objects directly, use this pattern.
+ [TestMethod]
+ public async Task SimpleAsyncExampleTest()
+ {
+ await Task.Delay(250);
+
+ Assert.IsTrue(true);
+ }
+
+ // Example that shows how to check for exception throwing.
+ [TestMethod]
+ public void SimpleExceptionCheckTest()
+ {
+ // If you need to check exceptions occur for invalid inputs, etc...
+ // Use Assert.ThrowsException to limit the scope to where you expect the error to occur.
+ // Otherwise, using the ExpectedException attribute could swallow or
+ // catch other issues in setup code.
+ Assert.ThrowsException(() => throw new NotImplementedException());
+ }
+
+ // The UIThreadTestMethod automatically dispatches to the UI for us to work with UI objects.
+ [UIThreadTestMethod]
+ public void SimpleUIAttributeExampleTest()
+ {
+ var component = new Loading();
+ Assert.IsNotNull(component);
+ }
+
+ // The UIThreadTestMethod can also easily grab a XAML Page for us by passing its type as a parameter.
+ // This lets us actually test a control as it would behave within an actual application.
+ // The page will already be loaded by the time your test is called.
+ [UIThreadTestMethod]
+ public void SimpleUIExamplePageTest(ExampleLoadingTestPage page)
+ {
+ // You can use the Toolkit Visual Tree helpers here to find the component by type or name:
+ var component = page.FindDescendant();
+
+ Assert.IsNotNull(component);
+
+ var componentByName = page.FindDescendant("LoadingControl");
+
+ Assert.IsNotNull(componentByName);
+ }
+
+ // You can still do async work with a UIThreadTestMethod as well.
+ [UIThreadTestMethod]
+ public async Task SimpleAsyncUIExamplePageTest(ExampleLoadingTestPage page)
+ {
+ // This helper can be used to wait for a rendering pass to complete.
+ // Note, this is already done by loading a Page with the [UIThreadTestMethod] helper.
+ await CompositionTargetHelper.ExecuteAfterCompositionRenderingAsync(() => { });
+
+ var component = page.FindDescendant();
+
+ Assert.IsNotNull(component);
+ }
+
+ //// ----------------------------- ADVANCED TEST SCENARIOS -----------------------------
+
+ // If you need to use DataRow, you can use this pattern with the UI dispatch still.
+ // Otherwise, checkout the UIThreadTestMethod attribute above.
+ // See https://github.com/CommunityToolkit/Labs-Windows/issues/186
+ [TestMethod]
+ public async Task ComplexAsyncUIExampleTest()
+ {
+ await EnqueueAsync(() =>
+ {
+ var component = new Loading();
+ Assert.IsNotNull(component);
+ });
+ }
+
+ // If you want to load other content not within a XAML page using the UIThreadTestMethod above.
+ // Then you can do that using the Load/UnloadTestContentAsync methods.
+ [TestMethod]
+ public async Task ComplexAsyncLoadUIExampleTest()
+ {
+ await EnqueueAsync(async () =>
+ {
+ var component = new Loading();
+ Assert.IsNotNull(component);
+ Assert.IsFalse(component.IsLoaded);
+
+ await LoadTestContentAsync(component);
+
+ Assert.IsTrue(component.IsLoaded);
+
+ await UnloadTestContentAsync(component);
+
+ Assert.IsFalse(component.IsLoaded);
+ });
+ }
+
+ // You can still use the UIThreadTestMethod to remove the extra layer for the dispatcher as well:
+ [UIThreadTestMethod]
+ public async Task ComplexAsyncLoadUIExampleWithoutDispatcherTest()
+ {
+ var component = new Loading();
+ Assert.IsNotNull(component);
+ Assert.IsFalse(component.IsLoaded);
+
+ await LoadTestContentAsync(component);
+
+ Assert.IsTrue(component.IsLoaded);
+
+ await UnloadTestContentAsync(component);
+
+ Assert.IsFalse(component.IsLoaded);
+ }
+}
diff --git a/components/Loading/tests/ExampleLoadingTestPage.xaml b/components/Loading/tests/ExampleLoadingTestPage.xaml
new file mode 100644
index 00000000..7513ee79
--- /dev/null
+++ b/components/Loading/tests/ExampleLoadingTestPage.xaml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
diff --git a/components/Loading/tests/ExampleLoadingTestPage.xaml.cs b/components/Loading/tests/ExampleLoadingTestPage.xaml.cs
new file mode 100644
index 00000000..e8d964a3
--- /dev/null
+++ b/components/Loading/tests/ExampleLoadingTestPage.xaml.cs
@@ -0,0 +1,16 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace LoadingExperiment.Tests;
+
+///
+/// An empty page that can be used on its own or navigated to within a Frame.
+///
+public sealed partial class ExampleLoadingTestPage : Page
+{
+ public ExampleLoadingTestPage()
+ {
+ this.InitializeComponent();
+ }
+}
diff --git a/components/Loading/tests/Loading.Tests.projitems b/components/Loading/tests/Loading.Tests.projitems
new file mode 100644
index 00000000..dc2dc043
--- /dev/null
+++ b/components/Loading/tests/Loading.Tests.projitems
@@ -0,0 +1,23 @@
+
+
+
+ $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
+ true
+ 339D88E6-64F0-4AB0-B97F-403E3846766F
+
+
+ LoadingExperiment.Tests
+
+
+
+
+ ExampleLoadingTestPage.xaml
+
+
+
+
+ Designer
+ MSBuild:Compile
+
+
+
\ No newline at end of file
diff --git a/components/Loading/tests/Loading.Tests.shproj b/components/Loading/tests/Loading.Tests.shproj
new file mode 100644
index 00000000..80870f40
--- /dev/null
+++ b/components/Loading/tests/Loading.Tests.shproj
@@ -0,0 +1,13 @@
+
+
+
+ 339D88E6-64F0-4AB0-B97F-403E3846766F
+ 14.0
+
+
+
+
+
+
+
+