Skip to content

Commit de7760b

Browse files
Port 4 remaining recipes to scenarios
calendar-multiselect, sidebar-nav, async-fetch-list, named-styles. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent e35a28f commit de7760b

9 files changed

Lines changed: 1603 additions & 1 deletion

File tree

samples/scenarios/_generated/scenarios.json

Lines changed: 1349 additions & 1 deletion
Large diffs are not rendered by default.
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// id: async-fetch-list
2+
// intent: fetch async data with UseResource and render loading, error, and reloading states
3+
#:package Microsoft.UI.Reactor@0.0.0-local
4+
#:property Platform=ARM64
5+
6+
using System;
7+
using System.Collections.Generic;
8+
using System.Linq;
9+
using System.Threading;
10+
using System.Threading.Tasks;
11+
using Microsoft.UI.Reactor;
12+
using Microsoft.UI.Reactor.Core;
13+
using Microsoft.UI.Xaml.Controls;
14+
using static Microsoft.UI.Reactor.Factories;
15+
16+
ReactorApp.Run<App>("Async Fetch List", width: 560, height: 520);
17+
18+
record Repo(int Id, string Name, string Description);
19+
20+
static class Api
21+
{
22+
public static async Task<IReadOnlyList<Repo>> ListReposAsync(string owner, CancellationToken cancellationToken)
23+
{
24+
await Task.Delay(800, cancellationToken);
25+
if (owner == "fail")
26+
{
27+
throw new InvalidOperationException("Owner not found");
28+
}
29+
30+
return
31+
[
32+
new(1, $"{owner}/alpha", "first repo"),
33+
new(2, $"{owner}/beta", "second repo"),
34+
new(3, $"{owner}/gamma", "third repo")
35+
];
36+
}
37+
}
38+
39+
class App : Component
40+
{
41+
public override Element Render()
42+
{
43+
var (owner, setOwner) = UseState("microsoft");
44+
var repos = UseResource(cancellationToken => Api.ListReposAsync(owner, cancellationToken), deps: [owner]);
45+
46+
return VStack(12,
47+
TextField(owner, setOwner, placeholder: "GitHub owner"),
48+
Caption("Try \"fail\" to see the error state."),
49+
repos.Match<Element>(
50+
loading: () => HStack(8,
51+
ProgressRing().IsActive(true).Width(20).Height(20),
52+
TextBlock("Loading…")),
53+
data: list => VStack(8,
54+
list.Select(repo =>
55+
Border(
56+
VStack(2,
57+
TextBlock(repo.Name).Bold(),
58+
Caption(repo.Description)))
59+
.Padding(12)
60+
.CornerRadius(6)
61+
.WithKey(repo.Id.ToString())
62+
).ToArray<Element?>()),
63+
error: ex => InfoBar("Error", ex.Message).Severity(InfoBarSeverity.Error),
64+
reloading: previous => VStack(8,
65+
HStack(8,
66+
ProgressRing().IsActive(true).Width(20).Height(20),
67+
TextBlock("Refreshing…")),
68+
VStack(8,
69+
previous.Select(repo =>
70+
TextBlock(repo.Name)
71+
.Opacity(0.5)
72+
.WithKey(repo.Id.ToString()))
73+
.ToArray<Element?>()))))
74+
.Padding(24);
75+
}
76+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"id": "async-fetch-list",
3+
"category": "hooks",
4+
"title": "Async Fetch List",
5+
"intent": "fetch async data with UseResource and render loading, error, and reloading states",
6+
"tags": ["async", "fetch", "resource", "loading", "error", "reloading"],
7+
"factoryAnchors": ["UseResource", "InfoBar", "ProgressRing"],
8+
"notesKey": "UseResource",
9+
"relatedIds": ["list-with-loading"],
10+
"priority": "P0"
11+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// id: calendar-multiselect
2+
// intent: select multiple dates in a calendar and summarize the chosen days
3+
#:package Microsoft.UI.Reactor@0.0.0-local
4+
#:property Platform=ARM64
5+
6+
using System;
7+
using System.Linq;
8+
using Microsoft.UI.Reactor;
9+
using Microsoft.UI.Reactor.Core;
10+
using Microsoft.UI.Xaml.Controls;
11+
using static Microsoft.UI.Reactor.Factories;
12+
13+
ReactorApp.Run<App>("Calendar Multi-select", width: 520, height: 420);
14+
15+
class App : Component
16+
{
17+
public override Element Render()
18+
{
19+
var (dates, setDates) = UseState<IReadOnlyList<DateTimeOffset>>(Array.Empty<DateTimeOffset>());
20+
21+
return VStack(16,
22+
Subtitle("Pick travel days"),
23+
(CalendarView() with { SelectionMode = CalendarViewSelectionMode.Multiple })
24+
.SelectedDates(dates)
25+
.SelectedDatesChanged(setDates),
26+
Body(dates.Count == 0
27+
? "No dates selected."
28+
: $"{dates.Count} selected: {string.Join(", ", dates.Select(d => d.ToString("MMM d")))}"),
29+
Button("Clear", () => setDates(Array.Empty<DateTimeOffset>()))
30+
.SubtleButton())
31+
.Padding(24);
32+
}
33+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"id": "calendar-multiselect",
3+
"category": "inputs",
4+
"title": "Calendar Multi-select",
5+
"intent": "select multiple dates in a CalendarView and summarize the chosen days",
6+
"tags": ["calendar", "multi-select", "dates", "selection"],
7+
"factoryAnchors": ["CalendarView", "UseState"],
8+
"notesKey": "CalendarView",
9+
"relatedIds": ["calendardatepicker"],
10+
"priority": "P0"
11+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// id: named-styles
2+
// intent: apply theme-aware named styles to buttons, hyperlinks, and InfoBars
3+
#:package Microsoft.UI.Reactor@0.0.0-local
4+
#:property Platform=ARM64
5+
6+
using Microsoft.UI.Reactor;
7+
using Microsoft.UI.Reactor.Core;
8+
using static Microsoft.UI.Reactor.Factories;
9+
10+
ReactorApp.Run<App>("Named Styles", width: 560, height: 520);
11+
12+
class App : Component
13+
{
14+
public override Element Render() =>
15+
ScrollView(
16+
VStack(20,
17+
Subtitle("Buttons"),
18+
HStack(8,
19+
Button("Default", () => { }),
20+
Button("Accent", () => { }).AccentButton(),
21+
Button("Subtle", () => { }).SubtleButton(),
22+
Button("Text link", () => { }).TextLink()),
23+
Subtitle("Hyperlinks"),
24+
HyperlinkButton("Open docs").TextLink(),
25+
Subtitle("InfoBars"),
26+
InfoBar("Tip", "You can drag the divider.").Informational(),
27+
InfoBar("Saved", "Changes written to disk.").Success(),
28+
InfoBar("Heads up", "Unsaved changes will be discarded.").Warning(),
29+
InfoBar("Failed", "Couldn't reach the server.").Error())
30+
.Padding(24));
31+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"id": "named-styles",
3+
"category": "layout",
4+
"title": "Named Style Fluents",
5+
"intent": "apply theme-aware named styles to buttons, hyperlinks, and InfoBars",
6+
"tags": ["styles", "theme", "button", "hyperlink", "infobar"],
7+
"factoryAnchors": ["Button", "HyperlinkButton", "InfoBar"],
8+
"notesKey": null,
9+
"relatedIds": ["hyperlink-button"],
10+
"priority": "P0"
11+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// id: sidebar-nav
2+
// intent: typed sidebar routing with NavigationView and NavigationHost
3+
#:package Microsoft.UI.Reactor@0.0.0-local
4+
#:property Platform=ARM64
5+
6+
using System;
7+
using Microsoft.UI.Reactor;
8+
using Microsoft.UI.Reactor.Core;
9+
using static Microsoft.UI.Reactor.Factories;
10+
11+
ReactorApp.Run<Shell>("Sidebar Navigation", width: 1000, height: 700);
12+
13+
enum Route { Home, Library, Settings }
14+
15+
class Shell : Component
16+
{
17+
static string ToTag(Route route) => route.ToString().ToLowerInvariant();
18+
static Route ToRoute(string tag) => Enum.Parse<Route>(tag, ignoreCase: true);
19+
20+
public override Element Render()
21+
{
22+
var nav = UseNavigation(Route.Home);
23+
24+
return NavigationView(
25+
[
26+
NavItem("Home", icon: "", tag: ToTag(Route.Home)),
27+
NavItem("Library", icon: "", tag: ToTag(Route.Library)),
28+
NavItem("Settings", icon: "", tag: ToTag(Route.Settings)),
29+
],
30+
NavigationHost(nav, route => route switch
31+
{
32+
Route.Home => Component<HomePage>(),
33+
Route.Library => Component<LibraryPage>(),
34+
Route.Settings => Component<SettingsPage>(),
35+
_ => TextBlock("Not found")
36+
}))
37+
.WithNavigation(nav, ToTag, ToRoute);
38+
}
39+
}
40+
41+
class HomePage : Component
42+
{
43+
public override Element Render() =>
44+
VStack(12,
45+
Heading("Home"),
46+
TextBlock("Welcome."))
47+
.Padding(24);
48+
}
49+
50+
class LibraryPage : Component
51+
{
52+
public override Element Render() =>
53+
VStack(12,
54+
Heading("Library"),
55+
TextBlock("Your stuff."))
56+
.Padding(24);
57+
}
58+
59+
class SettingsPage : Component
60+
{
61+
public override Element Render()
62+
{
63+
var nav = this.UseNavigation<Route>();
64+
65+
return VStack(12,
66+
Heading("Settings"),
67+
Button("Back to Home", () => nav.Navigate(Route.Home)))
68+
.Padding(24);
69+
}
70+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"id": "sidebar-nav",
3+
"category": "navigation",
4+
"title": "Sidebar Navigation",
5+
"intent": "typed route navigation with NavigationView, NavigationHost, and UseNavigation",
6+
"tags": ["navigation", "sidebar", "route", "navigationview"],
7+
"factoryAnchors": ["NavigationView", "NavigationHost", "UseNavigation"],
8+
"notesKey": "NavigationView",
9+
"relatedIds": [],
10+
"priority": "P0"
11+
}

0 commit comments

Comments
 (0)