diff --git a/docs/Masa.Blazor.Docs/Examples/labs/toggles/Menu.razor b/docs/Masa.Blazor.Docs/Examples/labs/toggles/Menu.razor
new file mode 100644
index 0000000000..73f83a3dc6
--- /dev/null
+++ b/docs/Masa.Blazor.Docs/Examples/labs/toggles/Menu.razor
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+ @foreach (var item in items)
+ {
+
+ }
+
+
+
+
+
+@code {
+
+ private bool _on;
+
+ string[] items =
+ [
+ "Click Me",
+ "Click Me",
+ "Click Me",
+ "Click Me 2"
+ ];
+
+}
\ No newline at end of file
diff --git a/docs/Masa.Blazor.Docs/Examples/labs/toggles/TData.razor b/docs/Masa.Blazor.Docs/Examples/labs/toggles/TData.razor
new file mode 100644
index 0000000000..9a0516acd4
--- /dev/null
+++ b/docs/Masa.Blazor.Docs/Examples/labs/toggles/TData.razor
@@ -0,0 +1,18 @@
+
+
+
+ @context.Data?.Label
+
+
+
+
+@code {
+
+ private bool _on;
+
+ private record Model(string Label, string Icon);
+
+ private Model _dataOn = new Model("On", "mdi-check");
+ private Model _dataOff = new Model("Off", "mdi-close");
+
+}
\ No newline at end of file
diff --git a/docs/Masa.Blazor.Docs/Examples/labs/toggles/Usage.razor b/docs/Masa.Blazor.Docs/Examples/labs/toggles/Usage.razor
new file mode 100644
index 0000000000..6525b3a9e8
--- /dev/null
+++ b/docs/Masa.Blazor.Docs/Examples/labs/toggles/Usage.razor
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+@code {
+
+ private bool _on;
+
+}
\ No newline at end of file
diff --git a/docs/Masa.Blazor.Docs/wwwroot/data/apis/toggles/MToggle-en-US.json b/docs/Masa.Blazor.Docs/wwwroot/data/apis/toggles/MToggle-en-US.json
new file mode 100644
index 0000000000..369a7b12df
--- /dev/null
+++ b/docs/Masa.Blazor.Docs/wwwroot/data/apis/toggles/MToggle-en-US.json
@@ -0,0 +1,10 @@
+{
+ "props": {
+ "dataOn": "The data when `Value` is `true`",
+ "dataOff": "The data when `Value` is `false`"
+ },
+ "events": {
+ },
+ "contents": {
+ }
+}
\ No newline at end of file
diff --git a/docs/Masa.Blazor.Docs/wwwroot/data/apis/toggles/MToggle-zh-CN.json b/docs/Masa.Blazor.Docs/wwwroot/data/apis/toggles/MToggle-zh-CN.json
new file mode 100644
index 0000000000..3fb6a1b7b5
--- /dev/null
+++ b/docs/Masa.Blazor.Docs/wwwroot/data/apis/toggles/MToggle-zh-CN.json
@@ -0,0 +1,10 @@
+{
+ "props": {
+ "dataOn": "当 `Value` 为`true`时的值",
+ "dataOff": "当 `Value` 为`false`时的值"
+ },
+ "events": {
+ },
+ "contents": {
+ }
+}
\ No newline at end of file
diff --git a/docs/Masa.Blazor.Docs/wwwroot/data/nav.json b/docs/Masa.Blazor.Docs/wwwroot/data/nav.json
index af04211baa..f8b42b2abf 100644
--- a/docs/Masa.Blazor.Docs/wwwroot/data/nav.json
+++ b/docs/Masa.Blazor.Docs/wwwroot/data/nav.json
@@ -349,6 +349,11 @@
"state": "new",
"releasedOn": "v1.0.4"
},
+ {
+ "title": "toggles",
+ "state": "new",
+ "releasedOn": "v1.7.0"
+ },
{
"title": "watermark",
"state": "new",
diff --git a/docs/Masa.Blazor.Docs/wwwroot/pages/labs/toggles/en-US.md b/docs/Masa.Blazor.Docs/wwwroot/pages/labs/toggles/en-US.md
new file mode 100644
index 0000000000..64161b3580
--- /dev/null
+++ b/docs/Masa.Blazor.Docs/wwwroot/pages/labs/toggles/en-US.md
@@ -0,0 +1,26 @@
+---
+title: Toggle
+desc: "The Toggle component is a wrapper that allows you to switch between two states."
+related:
+ - /blazor/components/buttons
+ - /blazor/components/icons
+ - /blazor/components/switches
+---
+
+## Usage
+
+
+
+## Examples
+
+### Props
+
+#### TData
+
+
+
+### Misc
+
+#### Menu
+
+
\ No newline at end of file
diff --git a/docs/Masa.Blazor.Docs/wwwroot/pages/labs/toggles/zh-CN.md b/docs/Masa.Blazor.Docs/wwwroot/pages/labs/toggles/zh-CN.md
new file mode 100644
index 0000000000..4e99abdf4d
--- /dev/null
+++ b/docs/Masa.Blazor.Docs/wwwroot/pages/labs/toggles/zh-CN.md
@@ -0,0 +1,26 @@
+---
+title: Toggle(切换)
+desc: "切换组件是一个包装器,允许您在两种状态之间切换。"
+related:
+ - /blazor/components/buttons
+ - /blazor/components/icons
+ - /blazor/components/switches
+---
+
+## 使用 {#usage}
+
+
+
+## 示例 {#examples}
+
+### 属性 {#props}
+
+#### TData
+
+
+
+### 其他 {#misc}
+
+#### 菜单 {#menu}
+
+
\ No newline at end of file
diff --git a/docs/Masa.Docs.Shared/Components/Menus/NotificationsMenu.razor b/docs/Masa.Docs.Shared/Components/Menus/NotificationsMenu.razor
index 6a52787160..b53bcb64dd 100644
--- a/docs/Masa.Docs.Shared/Components/Menus/NotificationsMenu.razor
+++ b/docs/Masa.Docs.Shared/Components/Menus/NotificationsMenu.razor
@@ -9,16 +9,21 @@
Width="520"
MaxWidth="@("100%")">
-
-
- @{
- var outline = _menu ? "" : "-outline";
- }
-
-
-
+ @{
+ var outline = _menu ? "" : "-outline";
+ }
+
+
+
+
+
+
+
diff --git a/docs/Masa.Docs.Shared/Components/ThemeToggle.razor b/docs/Masa.Docs.Shared/Components/ThemeToggle.razor
index 1e7879a318..517de115e0 100644
--- a/docs/Masa.Docs.Shared/Components/ThemeToggle.razor
+++ b/docs/Masa.Docs.Shared/Components/ThemeToggle.razor
@@ -3,11 +3,13 @@
@inject IJSRuntime JSRuntime
@implements IDisposable
-
-
+
+
+
+
@code {
diff --git a/docs/Masa.Docs.Shared/wwwroot/locale/en-US.json b/docs/Masa.Docs.Shared/wwwroot/locale/en-US.json
index 7473acdb44..f4706b542b 100644
--- a/docs/Masa.Docs.Shared/wwwroot/locale/en-US.json
+++ b/docs/Masa.Docs.Shared/wwwroot/locale/en-US.json
@@ -255,6 +255,7 @@
"simple-tables": "Simple tables",
"tabs": "Tabs",
"timelines": "Timelines",
+ "toggles": "Toggles",
"enqueued-snackbars": "Enqueued snackbars",
"tooltips": "Tooltips",
"treeview": "Treeview",
diff --git a/docs/Masa.Docs.Shared/wwwroot/locale/zh-CN.json b/docs/Masa.Docs.Shared/wwwroot/locale/zh-CN.json
index 1d725ed514..a237570ff8 100644
--- a/docs/Masa.Docs.Shared/wwwroot/locale/zh-CN.json
+++ b/docs/Masa.Docs.Shared/wwwroot/locale/zh-CN.json
@@ -251,6 +251,7 @@
"simple-tables": "Simple tables(简单表格)",
"tabs": "Tabs(选项卡)",
"timelines": "Timelines(时间轴)",
+ "toggles": "Toggles(切换)",
"enqueued-snackbars": "Enqueued snackbars(消息队列)",
"tooltips": "Tooltips(工具提示)",
"treeview": "Treeview(树形视图)",
diff --git a/src/Masa.Blazor.Docs.ApiGenerator/ApiGenerator.cs b/src/Masa.Blazor.Docs.ApiGenerator/ApiGenerator.cs
index 516c962811..c3a4b78bd2 100644
--- a/src/Masa.Blazor.Docs.ApiGenerator/ApiGenerator.cs
+++ b/src/Masa.Blazor.Docs.ApiGenerator/ApiGenerator.cs
@@ -181,8 +181,7 @@ private static void AnalyzeParameters(INamedTypeSymbol classSymbol, List attr.AttributeClass?.Name == BlazorParameterAttributeName))
{
- var type = parameterSymbol.Type as INamedTypeSymbol;
- if (type is null || ignoreParameters.Contains(parameterSymbol.Name))
+ if (ignoreParameters.Contains(parameterSymbol.Name))
{
continue;
}
@@ -196,32 +195,42 @@ private static void AnalyzeParameters(INamedTypeSymbol classSymbol, List attr.AttributeClass?.Name == "ObsoleteAttribute") is not null;
- if (!s_typeDescCache.TryGetValue(typeText, out var typeDesc))
+ if (parameterSymbol.Type is ITypeParameterSymbol typeParameterSymbol)
{
- typeDesc = GetTypeDesc(type);
- if (!string.IsNullOrWhiteSpace(typeDesc))
- {
- s_typeDescCache.Add(typeText, typeDesc!);
- }
+ defaultParameters.Add(new ParameterInfo(parameterSymbol.Name, typeParameterSymbol.Name, null,
+ defaultValue, isObsolete, false, releasedOn));
}
+ else if (parameterSymbol.Type is INamedTypeSymbol namedTypeSymbol)
+ {
+ var typeText = GetTypeText(namedTypeSymbol);
- var isObsolete = attrs.FirstOrDefault(attr => attr.AttributeClass?.Name == "ObsoleteAttribute") is not null;
+ if (!s_typeDescCache.TryGetValue(typeText, out var typeDesc))
+ {
+ typeDesc = GetTypeDesc(namedTypeSymbol);
+ if (!string.IsNullOrWhiteSpace(typeDesc))
+ {
+ s_typeDescCache.Add(typeText, typeDesc!);
+ }
+ }
- var parameterInfo = new ParameterInfo(parameterSymbol.Name, typeText, typeDesc, defaultValue, isObsolete, false, releasedOn);
+ var parameterInfo = new ParameterInfo(parameterSymbol.Name, typeText, typeDesc, defaultValue,
+ isObsolete, false, releasedOn);
- if (type.Name.StartsWith("RenderFragment"))
- {
- contentParameters.Add(parameterInfo);
- }
- else if (type.Name.StartsWith("EventCallback"))
- {
- eventParameters.Add(parameterInfo);
- }
- else
- {
- defaultParameters.Add(parameterInfo);
+ if (namedTypeSymbol.Name.StartsWith("RenderFragment"))
+ {
+ contentParameters.Add(parameterInfo);
+ }
+ else if (namedTypeSymbol.Name.StartsWith("EventCallback"))
+ {
+ eventParameters.Add(parameterInfo);
+ }
+ else
+ {
+ defaultParameters.Add(parameterInfo);
+ }
}
}
}
diff --git a/src/Masa.Blazor/Components/Toggle/MToggle.cs b/src/Masa.Blazor/Components/Toggle/MToggle.cs
new file mode 100644
index 0000000000..3b6d324476
--- /dev/null
+++ b/src/Masa.Blazor/Components/Toggle/MToggle.cs
@@ -0,0 +1,30 @@
+namespace Masa.Blazor;
+
+public class MToggle : ComponentBase
+{
+ [Parameter] public bool Value { get; set; }
+
+ [Parameter] public EventCallback ValueChanged { get; set; }
+
+ [Parameter] public TData? DataOn { get; set; }
+
+ [Parameter] public TData? DataOff { get; set; }
+
+ [Parameter] public RenderFragment>? ChildContent { get; set; }
+
+ private async Task OnToggle()
+ {
+ Value = !Value;
+ await ValueChanged.InvokeAsync(Value);
+ }
+
+ protected override void BuildRenderTree(RenderTreeBuilder builder)
+ {
+ builder.AddContent(
+ 0,
+ ChildContent?.Invoke(new ToggleContext(OnToggle, Value ? DataOn : DataOff, Value))
+ );
+ }
+}
+
+public record ToggleContext(Func Toggle, TData? Data, bool On);
\ No newline at end of file