Skip to content

Commit c4e9987

Browse files
committed
2 parents cef53c8 + 758c856 commit c4e9987

File tree

3 files changed

+150
-103
lines changed

3 files changed

+150
-103
lines changed

src/Ivy.Docs.Shared/Docs/02_Widgets/02_Layouts/06_SidebarLayout.md

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -79,52 +79,57 @@ The `SidebarMenu` [widget](../../01_Onboarding/02_Concepts/03_Widgets.md) is des
7979
```csharp demo-tabs
8080
public class SidebarMenuExample : ViewBase
8181
{
82+
private enum NavPage { Home, Analytics, Profile, Account, Preferences, Help }
83+
8284
public override object? Build()
8385
{
84-
var selectedPage = UseState("home");
86+
var selectedPage = UseState<NavPage?>(NavPage.Home);
8587
var client = UseService<IClientProvider>();
8688

8789
MenuItem[] menuItems = new[]
8890
{
8991
MenuItem.Default("Dashboard")
90-
.Icon(Icons.LayoutDashboard).Tag("home"),
92+
.Icon(Icons.LayoutDashboard).Tag(NavPage.Home),
9193
MenuItem.Default("Analytics")
92-
.Icon(Icons.TrendingUp).Tag("analytics"),
94+
.Icon(Icons.TrendingUp).Tag(NavPage.Analytics),
9395
MenuItem.Default("Settings")
9496
.Icon(Icons.Settings).Children(
9597
MenuItem.Default("Profile")
96-
.Icon(Icons.User).Tag("profile"),
98+
.Icon(Icons.User).Tag(NavPage.Profile),
9799
MenuItem.Default("Account")
98-
.Icon(Icons.UserCog).Tag("account"),
100+
.Icon(Icons.UserCog).Tag(NavPage.Account),
99101
MenuItem.Default("Preferences")
100-
.Icon(Icons.Settings).Tag("preferences")
102+
.Icon(Icons.Settings).Tag(NavPage.Preferences)
101103
),
102-
MenuItem.Default("Help").Icon(Icons.CircleQuestionMark).Tag("help")
104+
MenuItem.Default("Help").Icon(Icons.CircleQuestionMark).Tag(NavPage.Help)
103105
};
104106

105107
var sidebarMenu = new SidebarMenu(
106108
onSelect: evt => {
107-
selectedPage.Value = evt.Value.ToString()!;
108-
client.Toast($"Navigated to {evt.Value}");
109+
if (Enum.TryParse<NavPage>(evt.Value?.ToString(), ignoreCase: true, out var page))
110+
{
111+
selectedPage.Set(page);
112+
client.Toast($"Navigated to {page}");
113+
}
109114
},
110115
items: menuItems
111116
);
112117

113118
object RenderContent()
114119
{
115-
return selectedPage.Value switch
120+
return (selectedPage.Value ?? NavPage.Home) switch
116121
{
117-
"home" => new Card("Welcome to the Dashboard!")
122+
NavPage.Home => new Card("Welcome to the Dashboard!")
118123
.Title("Dashboard"),
119-
"analytics" => new Card("Analytics and reports go here.")
124+
NavPage.Analytics => new Card("Analytics and reports go here.")
120125
.Title("Analytics"),
121-
"profile" => new Card("User profile settings.")
126+
NavPage.Profile => new Card("User profile settings.")
122127
.Title("Profile"),
123-
"account" => new Card("Account management.")
128+
NavPage.Account => new Card("Account management.")
124129
.Title("Account"),
125-
"preferences" => new Card("User preferences.")
130+
NavPage.Preferences => new Card("User preferences.")
126131
.Title("Preferences"),
127-
"help" => new Card("Help and documentation.")
132+
NavPage.Help => new Card("Help and documentation.")
128133
.Title("Help & Support"),
129134
_ => new Card("Page not found.")
130135
.Title("404")
@@ -251,49 +256,54 @@ The `SidebarMenu` widget is specifically designed for sidebar navigation and pro
251256
```csharp demo-tabs
252257
public class SidebarMenuAdvancedExample : ViewBase
253258
{
259+
private enum DocSection { Install, Quickstart, Examples, Buttons, Forms, Charts, Tables, Hooks, State, Performance }
260+
254261
public override object? Build()
255262
{
256263
var client = UseService<IClientProvider>();
257-
var selectedItem = UseState("");
264+
var selectedItem = UseState<DocSection?>(null);
258265

259266
MenuItem[] menuItems = new[]
260267
{
261268
MenuItem.Default("Getting Started")
262269
.Icon(Icons.Play).Children(
263270
MenuItem.Default("Installation")
264-
.Icon(Icons.Download).Tag("install"),
271+
.Icon(Icons.Download).Tag(DocSection.Install),
265272
MenuItem.Default("Quick Start")
266-
.Icon(Icons.Zap).Tag("quickstart"),
273+
.Icon(Icons.Zap).Tag(DocSection.Quickstart),
267274
MenuItem.Default("Examples")
268-
.Icon(Icons.Code).Tag("examples")
275+
.Icon(Icons.Code).Tag(DocSection.Examples)
269276
),
270277
MenuItem.Default("Components")
271278
.Icon(Icons.Package).Children(
272279
MenuItem.Default("Buttons")
273-
.Icon(Icons.MousePointer).Tag("buttons"),
280+
.Icon(Icons.MousePointer).Tag(DocSection.Buttons),
274281
MenuItem.Default("Forms")
275-
.Icon(Icons.FileText).Tag("forms"),
282+
.Icon(Icons.FileText).Tag(DocSection.Forms),
276283
MenuItem.Default("Charts")
277-
.Icon(Icons.ChartBar).Tag("charts"),
284+
.Icon(Icons.ChartBar).Tag(DocSection.Charts),
278285
MenuItem.Default("Tables")
279-
.Icon(Icons.Table).Tag("tables")
286+
.Icon(Icons.Table).Tag(DocSection.Tables)
280287
),
281288
MenuItem.Default("Advanced")
282289
.Icon(Icons.Cpu).Children(
283290
MenuItem.Default("Hooks")
284-
.Icon(Icons.Link).Tag("hooks"),
291+
.Icon(Icons.Link).Tag(DocSection.Hooks),
285292
MenuItem.Default("State Management")
286-
.Icon(Icons.Database).Tag("state"),
293+
.Icon(Icons.Database).Tag(DocSection.State),
287294
MenuItem.Default("Performance")
288-
.Icon(Icons.Gauge).Tag("performance")
295+
.Icon(Icons.Gauge).Tag(DocSection.Performance)
289296
)
290297
};
291298

292299
var menu = new SidebarMenu(
293300
onSelect: evt =>
294301
{
295-
selectedItem.Value = evt.Value?.ToString() ?? "";
296-
client.Toast($"Selected: {evt.Value}");
302+
if (Enum.TryParse<DocSection>(evt.Value?.ToString(), ignoreCase: true, out var section))
303+
{
304+
selectedItem.Set(section);
305+
client.Toast($"Selected: {section}");
306+
}
297307
},
298308
items: menuItems
299309
);
@@ -302,7 +312,7 @@ public class SidebarMenuAdvancedExample : ViewBase
302312
mainContent: new Card(
303313
Layout.Vertical().Gap(2)
304314
| Text.P("Documentation").Large()
305-
| Text.P($"Currently viewing: {(string.IsNullOrEmpty(selectedItem.Value) ? "None" : selectedItem.Value)}")
315+
| Text.P($"Currently viewing: {(selectedItem.Value?.ToString() ?? "None")}")
306316
).Title("Content Area"),
307317
sidebarContent: menu,
308318
sidebarHeader: Text.Lead("Documentation Menu")

src/Ivy.Docs.Shared/Docs/02_Widgets/03_Common/11_DropDownMenu.md

Lines changed: 96 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,27 @@ new DropDownMenu(@evt => client.Toast("Selected: " + @evt.Value),
3333
Default menu items are the most common type, providing simple clickable options. The second example shows how to add custom tags for more advanced [event handling](../../01_Onboarding/02_Concepts/07_EventHandlers.md).
3434

3535
```csharp demo-tabs
36-
Layout.Horizontal().Gap(2).Center()
37-
| new DropDownMenu(@evt => client.Toast("Selected: " + @evt.Value),
38-
new Button("Default Items"),
39-
MenuItem.Default("Copy"),
40-
MenuItem.Default("Paste"),
41-
MenuItem.Default("Cut"),
42-
MenuItem.Default("Delete"))
43-
| new DropDownMenu(@evt => client.Toast("Selected: " + @evt.Value),
44-
new Button("With Tags"),
45-
MenuItem.Default("Save").Tag("save-action"),
46-
MenuItem.Default("Export").Tag("export-action"),
47-
MenuItem.Default("Import").Tag("import-action"))
36+
public class DefaultMenuItemsDemo : ViewBase
37+
{
38+
private enum MenuAction { Save, Export, Import }
39+
40+
public override object? Build()
41+
{
42+
var client = UseService<IClientProvider>();
43+
return Layout.Horizontal().Gap(2).Center()
44+
| new DropDownMenu(@evt => client.Toast("Selected: " + @evt.Value),
45+
new Button("Default Items"),
46+
MenuItem.Default("Copy"),
47+
MenuItem.Default("Paste"),
48+
MenuItem.Default("Cut"),
49+
MenuItem.Default("Delete"))
50+
| new DropDownMenu(@evt => client.Toast("Selected: " + @evt.Value),
51+
new Button("With Tags"),
52+
MenuItem.Default("Save").Tag(MenuAction.Save),
53+
MenuItem.Default("Export").Tag(MenuAction.Export),
54+
MenuItem.Default("Import").Tag(MenuAction.Import));
55+
}
56+
}
4857
```
4958

5059
Default menu items are the most common type, providing simple clickable options. The second example shows how to add custom tags for more advanced event handling.
@@ -177,23 +186,33 @@ Layout.Horizontal().Gap(2).Center()
177186
Custom event handling allows you to implement complex [business logic](../../03_Hooks/02_Core/11_UseService.md) based on menu selections, making your dropdowns more interactive and useful.
178187

179188
```csharp demo-tabs
180-
new DropDownMenu(@evt => {
181-
var value = @evt.Value?.ToString();
182-
if (value == "delete") {
183-
client.Toast("Deleting item...");
184-
} else if (value == "export") {
185-
client.Toast("Exporting data...");
186-
} else {
187-
client.Toast($"Selected: {value}");
188-
}
189-
},
190-
new Button("Custom Actions"))
191-
| MenuItem.Default("View").Tag("view")
192-
| MenuItem.Default("Edit").Tag("edit")
193-
| MenuItem.Default("Delete").Tag("delete")
194-
| MenuItem.Separator()
195-
| MenuItem.Default("Export").Tag("export")
196-
| MenuItem.Default("Share").Tag("share")
189+
public class CustomActionsDropDownDemo : ViewBase
190+
{
191+
private enum ItemAction { View, Edit, Delete, Export, Share }
192+
193+
public override object? Build()
194+
{
195+
var client = UseService<IClientProvider>();
196+
return new DropDownMenu(@evt => {
197+
if (Enum.TryParse<ItemAction>(@evt.Value?.ToString(), ignoreCase: true, out var action))
198+
{
199+
switch (action)
200+
{
201+
case ItemAction.Delete: client.Toast("Deleting item..."); break;
202+
case ItemAction.Export: client.Toast("Exporting data..."); break;
203+
default: client.Toast($"Selected: {action}"); break;
204+
}
205+
}
206+
},
207+
new Button("Custom Actions"))
208+
| MenuItem.Default("View").Tag(ItemAction.View)
209+
| MenuItem.Default("Edit").Tag(ItemAction.Edit)
210+
| MenuItem.Default("Delete").Tag(ItemAction.Delete)
211+
| MenuItem.Separator()
212+
| MenuItem.Default("Export").Tag(ItemAction.Export)
213+
| MenuItem.Default("Share").Tag(ItemAction.Share);
214+
}
215+
}
197216
```
198217

199218
<WidgetDocs Type="Ivy.DropDownMenu" ExtensionTypes="Ivy.DropDownMenuExtensions" SourceUrl="https://github.com/Ivy-Interactive/Ivy-Framework/blob/main/src/Ivy/Widgets/DropDownMenu.cs"/>
@@ -209,44 +228,54 @@ Complex using
209228
Here's a comprehensive example combining multiple features:
210229

211230
```csharp demo-tabs
212-
Layout.Horizontal().Gap(2).Center()
213-
| new DropDownMenu(@evt => client.Toast("Selected: " + @evt.Value),
214-
new Button("User Menu"),
215-
MenuItem.Separator(),
216-
MenuItem.Default("View Profile").Tag("profile"),
217-
MenuItem.Default("Account Settings").Tag("settings"),
218-
MenuItem.Default("Preferences").Tag("preferences"),
219-
MenuItem.Separator(),
220-
MenuItem.Default("Theme")
221-
.Children(
222-
MenuItem.Checkbox("Light").Tag("theme-light"),
223-
MenuItem.Checkbox("Dark").Checked().Tag("theme-dark"),
224-
MenuItem.Checkbox("System").Tag("theme-system")
225-
),
226-
MenuItem.Default("Notifications")
227-
.Children(
228-
MenuItem.Checkbox("Email").Checked().Tag("notify-email"),
229-
MenuItem.Checkbox("Push").Checked().Tag("notify-push"),
230-
MenuItem.Checkbox("SMS").Tag("notify-sms")
231-
),
232-
MenuItem.Separator(),
233-
MenuItem.Default("Help & Support").Tag("help"),
234-
MenuItem.Default("About").Tag("about"),
235-
MenuItem.Separator(),
236-
MenuItem.Default("Logout").Tag("logout"))
237-
.Header(Text.Muted("Signed in as john.doe@company.com"))
238-
.Top()
239-
.Align(DropDownMenu.AlignOptions.End)
240-
| new DropDownMenu(@evt => client.Toast("Selected: " + @evt.Value),
241-
new Button("Settings Menu"),
242-
MenuItem.Default("General").Tag("general"),
243-
MenuItem.Default("Appearance").Tag("appearance"),
244-
MenuItem.Default("Privacy").Tag("privacy"),
245-
MenuItem.Default("Security").Tag("security"),
246-
MenuItem.Separator(),
247-
MenuItem.Default("Updates").Tag("updates"),
248-
MenuItem.Default("Support").Tag("support"))
249-
.Header(Text.Muted("Application Settings"))
231+
public class ComplexDropDownDemo : ViewBase
232+
{
233+
private enum UserMenuAction { Profile, Settings, Preferences, ThemeLight, ThemeDark, ThemeSystem, NotifyEmail, NotifyPush, NotifySms, Help, About, Logout }
234+
private enum SettingsMenuAction { General, Appearance, Privacy, Security, Updates, Support }
235+
236+
public override object? Build()
237+
{
238+
var client = UseService<IClientProvider>();
239+
return Layout.Horizontal().Gap(2).Center()
240+
| new DropDownMenu(@evt => client.Toast("Selected: " + @evt.Value),
241+
new Button("User Menu"),
242+
MenuItem.Separator(),
243+
MenuItem.Default("View Profile").Tag(UserMenuAction.Profile),
244+
MenuItem.Default("Account Settings").Tag(UserMenuAction.Settings),
245+
MenuItem.Default("Preferences").Tag(UserMenuAction.Preferences),
246+
MenuItem.Separator(),
247+
MenuItem.Default("Theme")
248+
.Children(
249+
MenuItem.Checkbox("Light").Tag(UserMenuAction.ThemeLight),
250+
MenuItem.Checkbox("Dark").Checked().Tag(UserMenuAction.ThemeDark),
251+
MenuItem.Checkbox("System").Tag(UserMenuAction.ThemeSystem)
252+
),
253+
MenuItem.Default("Notifications")
254+
.Children(
255+
MenuItem.Checkbox("Email").Checked().Tag(UserMenuAction.NotifyEmail),
256+
MenuItem.Checkbox("Push").Checked().Tag(UserMenuAction.NotifyPush),
257+
MenuItem.Checkbox("SMS").Tag(UserMenuAction.NotifySms)
258+
),
259+
MenuItem.Separator(),
260+
MenuItem.Default("Help & Support").Tag(UserMenuAction.Help),
261+
MenuItem.Default("About").Tag(UserMenuAction.About),
262+
MenuItem.Separator(),
263+
MenuItem.Default("Logout").Tag(UserMenuAction.Logout))
264+
.Header(Text.Muted("Signed in as john.doe@company.com"))
265+
.Top()
266+
.Align(DropDownMenu.AlignOptions.End)
267+
| new DropDownMenu(@evt => client.Toast("Selected: " + @evt.Value),
268+
new Button("Settings Menu"),
269+
MenuItem.Default("General").Tag(SettingsMenuAction.General),
270+
MenuItem.Default("Appearance").Tag(SettingsMenuAction.Appearance),
271+
MenuItem.Default("Privacy").Tag(SettingsMenuAction.Privacy),
272+
MenuItem.Default("Security").Tag(SettingsMenuAction.Security),
273+
MenuItem.Separator(),
274+
MenuItem.Default("Updates").Tag(SettingsMenuAction.Updates),
275+
MenuItem.Default("Support").Tag(SettingsMenuAction.Support))
276+
.Header(Text.Muted("Application Settings"));
277+
}
278+
}
250279
```
251280

252281
</Body>

src/Ivy.Docs.Shared/Docs/02_Widgets/03_Common/16_Tree.md

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,11 @@ public class TreeClickDemo : ViewBase
7070
```csharp demo-tabs
7171
public class TreeRowActionsDemo : ViewBase
7272
{
73+
private enum RowAction { Edit, More, Duplicate, Delete }
74+
7375
public override object? Build()
7476
{
75-
var lastAction = UseState("None");
77+
var lastAction = UseState<string>("None");
7678

7779
return Layout.Vertical()
7880
| Text.Block($" Last Action: {lastAction.Value}")
@@ -93,13 +95,19 @@ public class TreeRowActionsDemo : ViewBase
9395
new MenuItem("package.json").Icon(Icons.Braces).Tag("package.json")
9496
)
9597
.RowActions(
96-
new MenuItem("Edit").Icon(Icons.Pencil).Tag("edit"),
97-
new MenuItem("More").Icon(Icons.Ellipsis).Children(
98-
new MenuItem("Duplicate").Icon(Icons.Copy).Tag("duplicate"),
99-
new MenuItem("Delete").Icon(Icons.Trash).Tag("delete")
98+
MenuItem.Default(Icons.Pencil).Tag(RowAction.Edit).Label("Edit"),
99+
MenuItem.Default(Icons.Ellipsis).Tag(RowAction.More).Label("More").Children(
100+
MenuItem.Default(Icons.Copy).Tag(RowAction.Duplicate).Label("Duplicate"),
101+
MenuItem.Default(Icons.Trash).Tag(RowAction.Delete).Label("Delete")
100102
)
101103
)
102-
.OnRowAction(e => lastAction.Set($"{e.Value.ActionTag} on {e.Value.ItemValue}"));
104+
.OnRowAction(e => {
105+
var tagStr = e.Value.ActionTag?.ToString();
106+
if (Enum.TryParse<RowAction>(tagStr, ignoreCase: true, out var action))
107+
lastAction.Set($"{action} on {e.Value.ItemValue}");
108+
else if (tagStr != null)
109+
lastAction.Set($"{tagStr} on {e.Value.ItemValue}");
110+
});
103111
}
104112
}
105113
```

0 commit comments

Comments
 (0)