mirror of
https://gitee.com/ant-design-blazor/ant-design-blazor.git
synced 2024-11-29 18:48:50 +08:00
docs: refactor the layout closer to the official document (#100)
* docs: add cli for building demo structured file * docs: cli improvement * docs: generate demo page * fix: style of components page * docs: add prism to mack source code highlight * feat: add menu2json command for cli * fix: markdown highlight * feat: fetch menu data from cli output files * fix: cli * docs: add avatar demo * docs: add button demos * docs: add component-scope style * docs: fix style * docs: add badge demos * fix: rebase conflict * docs: refactor layout * docs: fix navigation * docs: fix rebase conflict * docs: add AntAffix for sider menu * docs: fix affix error * docs: fix rebase confilct
This commit is contained in:
parent
0e8669a982
commit
9351a35072
@ -168,9 +168,9 @@ csharp_indent_switch_labels = true
|
||||
csharp_indent_labels = flush_left
|
||||
|
||||
# Prefer "var" everywhere
|
||||
csharp_style_var_for_built_in_types = false:error
|
||||
csharp_style_var_when_type_is_apparent = false:error
|
||||
csharp_style_var_elsewhere = false:error
|
||||
csharp_style_var_for_built_in_types = true:suggestion
|
||||
csharp_style_var_when_type_is_apparent = true:suggestion
|
||||
csharp_style_var_elsewhere = true:suggestion
|
||||
|
||||
# Prefer method-like constructs to have a block body
|
||||
csharp_style_expression_bodied_methods = false:none
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -346,3 +346,4 @@ package-lock.json
|
||||
/site/AntBlazor.Docs/wwwroot/css/docs.css
|
||||
/site/**/wwwroot/docs
|
||||
/components/AntBlazor.xml
|
||||
/site/AntBlazor.Docs/wwwroot/meta
|
||||
|
@ -23,6 +23,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AntBlazor.Docs.Server", "si
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AntBlazor.Docs.Wasm", "site\AntBlazor.Docs.Wasm\AntBlazor.Docs.Wasm.csproj", "{3F5C09C7-81EB-461C-8E0E-538D3FBAB931}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{D34F1DE5-ECF7-4CF0-8325-B7A38F41D376}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AntBlazor.Docs.Build.CLI", "site\AntBlazor.Docs.Build.CLI\AntBlazor.Docs.Build.CLI.csproj", "{5A765767-0766-433D-B78D-97D8F29CA6A6}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "hosts", "hosts", "{752F5AE8-BA08-4C41-B9B2-D2ED12727E63}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -49,6 +55,10 @@ Global
|
||||
{3F5C09C7-81EB-461C-8E0E-538D3FBAB931}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3F5C09C7-81EB-461C-8E0E-538D3FBAB931}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3F5C09C7-81EB-461C-8E0E-538D3FBAB931}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5A765767-0766-433D-B78D-97D8F29CA6A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5A765767-0766-433D-B78D-97D8F29CA6A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5A765767-0766-433D-B78D-97D8F29CA6A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5A765767-0766-433D-B78D-97D8F29CA6A6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -56,9 +66,10 @@ Global
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{0D3995E9-EBD9-4BBB-9E6C-3A3DE8C4611A} = {C60BCE84-4AF4-4393-8D3E-1B69E29549C1}
|
||||
{E2E6E4E8-2156-4B55-8164-40349D86330B} = {C60BCE84-4AF4-4393-8D3E-1B69E29549C1}
|
||||
{7FD7BCA7-058C-468C-BD8B-8496074651FD} = {C60BCE84-4AF4-4393-8D3E-1B69E29549C1}
|
||||
{B8761D43-B253-49FC-B144-A6CCB061951B} = {C60BCE84-4AF4-4393-8D3E-1B69E29549C1}
|
||||
{3F5C09C7-81EB-461C-8E0E-538D3FBAB931} = {C60BCE84-4AF4-4393-8D3E-1B69E29549C1}
|
||||
{7FD7BCA7-058C-468C-BD8B-8496074651FD} = {752F5AE8-BA08-4C41-B9B2-D2ED12727E63}
|
||||
{B8761D43-B253-49FC-B144-A6CCB061951B} = {752F5AE8-BA08-4C41-B9B2-D2ED12727E63}
|
||||
{3F5C09C7-81EB-461C-8E0E-538D3FBAB931} = {752F5AE8-BA08-4C41-B9B2-D2ED12727E63}
|
||||
{5A765767-0766-433D-B78D-97D8F29CA6A6} = {D34F1DE5-ECF7-4CF0-8325-B7A38F41D376}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {E124DDCB-1F8D-4F96-BF41-D87019D0A412}
|
||||
|
@ -23,17 +23,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<!-- The nuget package icon -->
|
||||
<None Include="date-picker\internal\AntDatePickerDatePanel.razor" />
|
||||
<None Include="date-picker\internal\AntDatePickerDatetimePanel.razor" />
|
||||
<None Include="date-picker\internal\AntDatePickerDecadePanel.razor" />
|
||||
<None Include="date-picker\internal\AntDatePickerFooter.razor" />
|
||||
<None Include="date-picker\internal\AntDatePickerHeader.razor" />
|
||||
<None Include="date-picker\internal\AntDatePickerInput.razor" />
|
||||
<None Include="date-picker\internal\AntDatePickerMonthPanel.razor" />
|
||||
<None Include="date-picker\internal\AntDatePickerPanelChooser.razor" />
|
||||
<None Include="date-picker\internal\AntDatePickerQuarterPanel.razor" />
|
||||
<None Include="date-picker\internal\AntDatePickerTemplate.razor" />
|
||||
<None Include="date-picker\internal\AntDatePickerYearPanel.razor" />
|
||||
<None Include="logo.png" Pack="true" PackagePath="" />
|
||||
</ItemGroup>
|
||||
|
||||
@ -44,6 +33,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Ardalis.SmartEnum" Version="1.0.8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8">
|
||||
|
@ -15,6 +15,7 @@ namespace AntBlazor
|
||||
private bool _affixed;
|
||||
private bool _rendered;
|
||||
private bool _listened;
|
||||
|
||||
private bool Affixed
|
||||
{
|
||||
get => _affixed;
|
||||
@ -31,6 +32,7 @@ namespace AntBlazor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ElementReference _ref;
|
||||
private ElementReference _childRef;
|
||||
private string _hiddenStyle;
|
||||
@ -53,6 +55,9 @@ namespace AntBlazor
|
||||
[Parameter]
|
||||
public uint? OffsetTop { get; set; } = 0;
|
||||
|
||||
[Parameter]
|
||||
public string ContainerSelector { get; set; } = "#BodyContainer";
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the scrollable area DOM node
|
||||
/// </summary>
|
||||
@ -65,7 +70,7 @@ namespace AntBlazor
|
||||
[Parameter]
|
||||
public EventCallback<bool> OnChange { get; set; }
|
||||
|
||||
#endregion
|
||||
#endregion Parameters
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
@ -84,13 +89,12 @@ namespace AntBlazor
|
||||
{
|
||||
if (_listened)
|
||||
{
|
||||
|
||||
await RenderAffixAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
DomEventService.AddEventListener("#BodyContainer", "scroll", OnScroll);
|
||||
DomEventService.AddEventListener("#BodyContainer", "resize", OnWindowResize);
|
||||
DomEventService.AddEventListener(ContainerSelector, "scroll", OnScroll);
|
||||
DomEventService.AddEventListener(ContainerSelector, "resize", OnWindowResize);
|
||||
if (!string.IsNullOrEmpty(Target.Id))
|
||||
{
|
||||
DomEventService.AddEventListener(Target, "scroll", OnScroll);
|
||||
@ -130,7 +134,7 @@ namespace AntBlazor
|
||||
private async Task RenderAffixAsync()
|
||||
{
|
||||
DomRect domRect = await JsInvokeAsync<DomRect>(JSInteropConstants.getBoundingClientRect, _ref);
|
||||
DomRect bodyContainerRect = await JsInvokeAsync<DomRect>(JSInteropConstants.getBoundingClientRect, "#BodyContainer");
|
||||
DomRect bodyContainerRect = await JsInvokeAsync<DomRect>(JSInteropConstants.getBoundingClientRect, ContainerSelector);
|
||||
DomRect containerRect;
|
||||
if (string.IsNullOrEmpty(Target.Id))
|
||||
{
|
||||
|
@ -16,4 +16,10 @@
|
||||
@Text
|
||||
</span>
|
||||
}
|
||||
else if (ChildContent != null)
|
||||
{
|
||||
<span class="ant-avatar-string" @ref="TextEl" style="@_textStyles">
|
||||
@ChildContent
|
||||
</span>
|
||||
}
|
||||
</span>
|
||||
|
@ -9,6 +9,9 @@ namespace AntBlazor
|
||||
{
|
||||
public partial class AntAvatar : AntDomComponentBase
|
||||
{
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string Shape { get; set; } = null;
|
||||
|
||||
|
@ -1,38 +1,49 @@
|
||||
@namespace AntBlazor
|
||||
@inherits AntDomComponentBase
|
||||
|
||||
<span class="@ClassMapper.Class" style="@Style" @ref="Ref" Id="@Id">
|
||||
<span class="@ClassMapper.Class" @ref="Ref" id="@Id">
|
||||
@if (ChildContent != null)
|
||||
{
|
||||
@ChildContent
|
||||
@if (CountTemplate != null)
|
||||
{
|
||||
<span role="img" class="ant-scroll-number-custom-component">@CountTemplate</span>
|
||||
}
|
||||
@if ((CountNumber == 0 && ShowZero) || CountNumber > 0)
|
||||
{
|
||||
<sup class="@($"ant-badge-count {Class}")" style="@Style" title="@(Title ?? DisplayCount)">@DisplayCount</sup>
|
||||
}
|
||||
@if (Dot && CountNumber != 0 || (Dot && ShowZero))
|
||||
{
|
||||
<sup class="ant-scroll-number ant-badge-dot" style="@Style"></sup>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@if (!string.IsNullOrEmpty(Status) && badgeStatusTypes.Contains(Status))
|
||||
{
|
||||
<span class="@($"ant-badge-status-dot ant-badge-status-{Status}")"></span>
|
||||
}
|
||||
@if (!string.IsNullOrEmpty(Color))
|
||||
{
|
||||
if (badgePresetColors.Contains(Color))
|
||||
{
|
||||
<span class="@($"ant-badge-status-dot ant-badge-status-{Color}")"></span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="ant-badge-status-dot" style="background: @Color"></span>
|
||||
}
|
||||
|
||||
@if (ChildContent != null)
|
||||
{
|
||||
@ChildContent
|
||||
@if ((Count == 0 && ShowZero) || Count > 0)
|
||||
{
|
||||
<sup class="@($"ant-badge-count {Class}")" style="@Style" title="@DisplayCount">@DisplayCount</sup>
|
||||
}
|
||||
@if (Dot && Count != 0 || (Dot && ShowZero))
|
||||
{
|
||||
<sup class="ant-scroll-number ant-badge-dot" style="@Style"></sup>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@if (!string.IsNullOrEmpty(Status))
|
||||
{
|
||||
<span class="@($"ant-badge-status-dot ant-badge-status-{Status}")"></span>
|
||||
}
|
||||
@if (!string.IsNullOrEmpty(Color))
|
||||
{
|
||||
<span class="@($"ant-badge-status-dot ant-badge-status-{Color}")"></span>
|
||||
}
|
||||
@if (!string.IsNullOrEmpty(Text))
|
||||
{
|
||||
<span class="ant-badge-status-text">@Text</span>
|
||||
}
|
||||
@if ((Count == 0 && ShowZero) || Count > 0)
|
||||
{
|
||||
<sup class="@($"ant-scroll-number ant-badge-count ant-badge-multiple-words {Class}")" style="@Style" title="@DisplayCount">@DisplayCount</sup>
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</span>
|
||||
@if (!string.IsNullOrEmpty(Text))
|
||||
{
|
||||
<span class="ant-badge-status-text">@Text</span>
|
||||
}
|
||||
@if ((CountNumber == 0 && ShowZero) || CountNumber > 0)
|
||||
{
|
||||
<sup class="@($"ant-scroll-number ant-badge-count ant-badge-multiple-words {Class}")" style="@Style" title="@DisplayCount">@DisplayCount</sup>
|
||||
}
|
||||
}
|
||||
</span>
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using OneOf;
|
||||
using System;
|
||||
|
||||
namespace AntBlazor
|
||||
@ -14,11 +15,11 @@ namespace AntBlazor
|
||||
[Parameter]
|
||||
public string Color { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Number to show in badge
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public int? Count { get; set; }
|
||||
[Parameter] public OneOf<int?, RenderFragment> Count { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to display a red dot instead of count
|
||||
@ -26,12 +27,14 @@ namespace AntBlazor
|
||||
[Parameter]
|
||||
public bool Dot { get; set; } = false;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Set offset of the badge dot, like[x, y]
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Tuple<int, int> Offset { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Max count to show
|
||||
/// </summary>
|
||||
@ -44,30 +47,35 @@ namespace AntBlazor
|
||||
[Parameter]
|
||||
public bool ShowZero { get; set; } = false;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Set Badge as a status dot
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string Status { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// If status is set, text sets the display text of the status dot
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string Text { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Text to show when hovering over the badge
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string Title { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Wrapping this item.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets the default CSS classes.
|
||||
/// </summary>
|
||||
@ -84,9 +92,14 @@ namespace AntBlazor
|
||||
/// <summary>
|
||||
/// Shows the Count and takes into account the OverFlowCount.
|
||||
/// </summary>
|
||||
protected string DisplayCount => Count > OverflowCount ? $"{OverflowCount}+"
|
||||
: Count == 0 && !ShowZero ? string.Empty
|
||||
: Count.ToString();
|
||||
protected string DisplayCount => CountNumber > OverflowCount ? $"{OverflowCount}+"
|
||||
: CountNumber == 0 && !ShowZero ? string.Empty
|
||||
: CountNumber.ToString();
|
||||
|
||||
protected int? CountNumber { get; set; }
|
||||
|
||||
protected RenderFragment CountTemplate { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Startup code
|
||||
@ -96,6 +109,7 @@ namespace AntBlazor
|
||||
base.OnInitialized();
|
||||
if (!string.IsNullOrEmpty(Color) && !string.IsNullOrEmpty(Status))
|
||||
throw new ArgumentException($"You cannot provide a {nameof(Status)} and a {nameof(Color)}, choose one.");
|
||||
|
||||
SetClassMap();
|
||||
}
|
||||
|
||||
@ -106,6 +120,40 @@ namespace AntBlazor
|
||||
{
|
||||
base.OnParametersSet();
|
||||
SetClassMap();
|
||||
|
||||
Count.Switch(_count =>
|
||||
{
|
||||
this.CountNumber = _count;
|
||||
}, _template =>
|
||||
{
|
||||
this.CountTemplate = _template;
|
||||
});
|
||||
}
|
||||
|
||||
private string[] badgePresetColors =
|
||||
{
|
||||
"pink",
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"cyan",
|
||||
"green",
|
||||
"blue",
|
||||
"purple",
|
||||
"geekblue",
|
||||
"magenta",
|
||||
"volcano",
|
||||
"gold",
|
||||
"lime"
|
||||
};
|
||||
|
||||
private string[] badgeStatusTypes =
|
||||
{
|
||||
"success",
|
||||
"processing",
|
||||
"default",
|
||||
"error",
|
||||
"warning"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,9 @@ namespace AntBlazor
|
||||
[Parameter]
|
||||
public bool Disabled { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool Danger { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
@ -45,7 +48,7 @@ namespace AntBlazor
|
||||
|
||||
public IList<AntIcon> Icons { get; set; } = new List<AntIcon>();
|
||||
|
||||
public AntNavLink Link { get; set; }
|
||||
//public AntNavLink Link { get; set; }
|
||||
|
||||
protected string IconStyle { get; set; }
|
||||
|
||||
@ -63,6 +66,7 @@ namespace AntBlazor
|
||||
ClassMapper.Clear()
|
||||
.Add("ant-btn")
|
||||
.If($"{prefixName}-{this.Type}", () => !string.IsNullOrEmpty(Type))
|
||||
.If($"{prefixName}-danger", () => Danger)
|
||||
.If($"{prefixName}-{Shape}", () => !string.IsNullOrEmpty(Shape))
|
||||
.If($"{prefixName}-{sizeMap[this.Size]}", () => sizeMap.ContainsKey(Size))
|
||||
.If($"{prefixName}-loading", () => Loading)
|
||||
@ -76,10 +80,10 @@ namespace AntBlazor
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
if (Link != null && string.IsNullOrEmpty(this.Type))
|
||||
{
|
||||
this.Type = AntButtonType.Link;
|
||||
}
|
||||
//if (Link != null && string.IsNullOrEmpty(this.Type))
|
||||
//{
|
||||
// this.Type = AntButtonType.Link;
|
||||
//}
|
||||
SetClassMap();
|
||||
}
|
||||
|
||||
@ -100,10 +104,10 @@ namespace AntBlazor
|
||||
|
||||
protected async Task OnClick(MouseEventArgs args)
|
||||
{
|
||||
if (Link != null)
|
||||
{
|
||||
NavigationManger.NavigateTo(Link.Href);
|
||||
}
|
||||
//if (Link != null)
|
||||
//{
|
||||
// NavigationManger.NavigateTo(Link.Href);
|
||||
//}
|
||||
|
||||
if (Onclick.HasDelegate)
|
||||
{
|
||||
|
@ -7,29 +7,29 @@ namespace AntBlazor
|
||||
{
|
||||
public enum AntDirectionVHIType
|
||||
{
|
||||
vertical,
|
||||
horizontal,
|
||||
inline
|
||||
Vertical,
|
||||
Horizontal,
|
||||
Inline
|
||||
}
|
||||
|
||||
public enum AntDirectionVHType
|
||||
{
|
||||
vertical,
|
||||
horizontal
|
||||
Vertical,
|
||||
Horizontal
|
||||
}
|
||||
|
||||
public enum AntFourDirectionType
|
||||
{
|
||||
top,
|
||||
bottom,
|
||||
left,
|
||||
right
|
||||
Top,
|
||||
Bottom,
|
||||
Left,
|
||||
Right
|
||||
}
|
||||
|
||||
public enum AntAlignType
|
||||
{
|
||||
top,
|
||||
middle,
|
||||
bottom
|
||||
Top,
|
||||
Middle,
|
||||
Bottom
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ namespace AntBlazor
|
||||
|
||||
public string AsString()
|
||||
{
|
||||
return string.Join(" ", map.Where(i => i.Value()).Select(i => i.Key()));
|
||||
return string.Join(" ", _map.Where(i => i.Value()).Select(i => i.Key()));
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
@ -20,39 +20,39 @@ namespace AntBlazor
|
||||
return AsString();
|
||||
}
|
||||
|
||||
private Dictionary<Func<string>, Func<bool>> map = new Dictionary<Func<string>, Func<bool>>();
|
||||
private readonly Dictionary<Func<string>, Func<bool>> _map = new Dictionary<Func<string>, Func<bool>>();
|
||||
|
||||
public ClassMapper Add(string name)
|
||||
{
|
||||
map.Add(() => name, () => true);
|
||||
_map.Add(() => name, () => true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClassMapper Get(Func<string> funcName)
|
||||
{
|
||||
map.Add(funcName, () => true);
|
||||
_map.Add(funcName, () => true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClassMapper GetIf(Func<string> funcName, Func<bool> func)
|
||||
{
|
||||
map.Add(funcName, func);
|
||||
_map.Add(funcName, func);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClassMapper If(string name, Func<bool> func)
|
||||
{
|
||||
map.Add(() => name, func);
|
||||
_map.Add(() => name, func);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClassMapper Clear()
|
||||
{
|
||||
map.Clear();
|
||||
_map.Clear();
|
||||
|
||||
map.Add(() => OriginalClass, () => !string.IsNullOrEmpty(OriginalClass));
|
||||
_map.Add(() => OriginalClass, () => !string.IsNullOrEmpty(OriginalClass));
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,4 +20,4 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -69,12 +69,6 @@ namespace AntBlazor
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
//await this.setGutterStyle();
|
||||
await base.OnParametersSetAsync();
|
||||
}
|
||||
|
||||
private async Task SetGutterStyle()
|
||||
{
|
||||
string breakPoint = null;
|
||||
|
@ -13,8 +13,7 @@
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool HasSider { get; set; }
|
||||
private bool _hasSider;
|
||||
|
||||
|
||||
protected override void OnInitialized()
|
||||
@ -22,7 +21,13 @@
|
||||
base.OnInitialized();
|
||||
ClassMapper
|
||||
.Add("ant-layout")
|
||||
.If("ant-layout-has-sider", () => HasSider);
|
||||
.If("ant-layout-has-sider", () => _hasSider);
|
||||
}
|
||||
|
||||
internal void SetSider(AntSider sider)
|
||||
{
|
||||
_hasSider = true;
|
||||
InvokeStateHasChanged();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Collections;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Threading.Tasks;
|
||||
using AntBlazor.JsInterop;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
@ -56,6 +57,8 @@ namespace AntBlazor
|
||||
|
||||
private string FlexSetting => $"0 0 {WidthSetting}";
|
||||
|
||||
public event Action<bool> OnCollapsed;
|
||||
|
||||
private string InternalStyle =>
|
||||
$@"flex:{FlexSetting};
|
||||
max-width:{WidthSetting};
|
||||
@ -86,6 +89,8 @@ namespace AntBlazor
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Layout?.SetSider(this);
|
||||
|
||||
DomEventService.AddEventListener<object>("window", "resize", async _ => await WatchMatchMedia());
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
@ -100,6 +105,7 @@ namespace AntBlazor
|
||||
{
|
||||
this.Collapsed = !this.Collapsed;
|
||||
await OnCollapsedChange.InvokeAsync(Collapsed);
|
||||
OnCollapsed?.Invoke(this.Collapsed);
|
||||
}
|
||||
|
||||
public async Task WatchMatchMedia()
|
||||
@ -107,10 +113,11 @@ namespace AntBlazor
|
||||
if (string.IsNullOrEmpty(Breakpoint))
|
||||
return;
|
||||
|
||||
var matchBelow = await JsInvokeAsync<bool>(JSInteropConstants.matchMedia, $"(max-width: {_dimensionMap[Breakpoint]})");
|
||||
bool matchBelow = await JsInvokeAsync<bool>(JSInteropConstants.matchMedia, $"(max-width: {_dimensionMap[Breakpoint]})");
|
||||
this.Below = matchBelow;
|
||||
this.Collapsed = matchBelow;
|
||||
await this.OnCollapsedChange.InvokeAsync(matchBelow);
|
||||
OnCollapsed?.Invoke(this.Collapsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ namespace AntBlazor
|
||||
|
||||
[Parameter] public IEnumerable<object> DataSource { get; set; }
|
||||
|
||||
[Parameter] public AntDirectionVHType ItemLayout { get; set; } = AntDirectionVHType.horizontal;
|
||||
[Parameter] public AntDirectionVHType ItemLayout { get; set; } = AntDirectionVHType.Horizontal;
|
||||
|
||||
[Parameter] public bool Loading { get; set; } = false;
|
||||
|
||||
@ -57,9 +57,11 @@ namespace AntBlazor
|
||||
case "large":
|
||||
sizeCls = "lg";
|
||||
break;
|
||||
|
||||
case "small":
|
||||
sizeCls = "sm";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -70,7 +72,7 @@ namespace AntBlazor
|
||||
.Add($"{_prefixName}-split")
|
||||
.Add($"{_prefixName}-bordered")
|
||||
.If($"{_prefixName}-{sizeCls}", () => !string.IsNullOrEmpty(sizeCls))
|
||||
.If($"{_prefixName}-vertical", () => ItemLayout == AntDirectionVHType.vertical)
|
||||
.If($"{_prefixName}-vertical", () => ItemLayout == AntDirectionVHType.Vertical)
|
||||
.If($"{_prefixName}-loading", () => (Loading))
|
||||
.If($"{_prefixName}-grid", () => true)
|
||||
.If($"{_prefixName}-something-after-last-item", () => false);
|
||||
|
@ -16,13 +16,13 @@ namespace AntBlazor
|
||||
// todo: list
|
||||
[Parameter] public string Actions { get; set; }
|
||||
|
||||
[Parameter] public AntDirectionVHIType ItemLayout { get; set; } = AntDirectionVHIType.horizontal;
|
||||
[Parameter] public AntDirectionVHIType ItemLayout { get; set; } = AntDirectionVHIType.Horizontal;
|
||||
|
||||
[Parameter] public RenderFragment ChildContent { get; set; }
|
||||
|
||||
public bool IsVerticalAndExtra()
|
||||
{
|
||||
return this.ItemLayout == AntDirectionVHIType.vertical && this.Extra != null;
|
||||
return this.ItemLayout == AntDirectionVHIType.Vertical && this.Extra != null;
|
||||
}
|
||||
|
||||
protected override void OnInitialized()
|
||||
|
@ -1,8 +1,8 @@
|
||||
@namespace AntBlazor
|
||||
@namespace AntBlazor
|
||||
@inherits AntDomComponentBase
|
||||
|
||||
<CascadingValue Value="this">
|
||||
<ul class="@ClassMapper.Class" @ref="Ref" style="@Style" id="@Id">
|
||||
<ul class="@ClassMapper.Class" style="@Style" id="@Id" direction="ltr" role="menu">
|
||||
@ChildContent
|
||||
</ul>
|
||||
</CascadingValue>
|
||||
</CascadingValue>
|
@ -1,96 +1,148 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace AntBlazor
|
||||
{
|
||||
public partial class AntMenu : AntDomComponentBase
|
||||
{
|
||||
[CascadingParameter(Name = nameof(PrefixCls))]
|
||||
public string PrefixCls { get; set; } = "ant-menu";
|
||||
private const string PrefixCls = "ant-menu";
|
||||
|
||||
[CascadingParameter]
|
||||
public AntSider Parent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public AntMenuTheme Theme { get; set; } = AntMenuTheme.Light;
|
||||
|
||||
[Parameter]
|
||||
public AntMenuMode Mode { get; set; } = AntMenuMode.Inline;
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public int InlineIndent { get; set; } = 24;
|
||||
public EventCallback<AntSubMenu> OnSubmenuClicked { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string Theme { get; set; } = "light";//'light' | 'dark' = 'light';
|
||||
public EventCallback<AntMenuItem> OnMenuItemClicked { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public AntDirectionVHIType Mode { get; set; } = AntDirectionVHIType.vertical;
|
||||
public bool Accordion { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool InDropDown { get; set; } = false;
|
||||
public bool Selectable { get; set; } = true;
|
||||
|
||||
[Parameter]
|
||||
public bool InlineCollapsed { get; set; } = false;
|
||||
public bool Collapsed { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool Selectable { get; set; }
|
||||
private AntMenuMode _initialMode;
|
||||
internal AntMenuMode InternalMode { get; private set; }
|
||||
private bool _collapsed;
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<AntMenuItem> Click { get; set; }
|
||||
public List<AntSubMenu> Submenus { get; set; } = new List<AntSubMenu>();
|
||||
public List<AntMenuItem> MenuItems { get; set; } = new List<AntMenuItem>();
|
||||
|
||||
internal readonly IList<AntMenuItem> MenuItems = new List<AntMenuItem>();
|
||||
|
||||
internal readonly IList<AntSubMenu> SubMenus = new List<AntSubMenu>();
|
||||
|
||||
private IList<AntSubMenu> _openedSubMenus = new List<AntSubMenu>();
|
||||
|
||||
public bool IsInDropDown { get; set; }
|
||||
|
||||
private AntDirectionVHIType _cacheMode;
|
||||
|
||||
protected override void OnInitialized()
|
||||
public void SelectItem(AntMenuItem item)
|
||||
{
|
||||
base.OnInitialized();
|
||||
SetClassMap();
|
||||
IsInDropDown = InDropDown;
|
||||
_cacheMode = Mode;
|
||||
foreach (AntMenuItem menuitem in MenuItems.Where(x => x != item))
|
||||
{
|
||||
menuitem.Deselect();
|
||||
}
|
||||
|
||||
if (!item.IsSelected)
|
||||
{
|
||||
item.Select();
|
||||
}
|
||||
|
||||
if (OnMenuItemClicked.HasDelegate)
|
||||
OnMenuItemClicked.InvokeAsync(item);
|
||||
}
|
||||
|
||||
private void SetClassMap()
|
||||
public void SelectSubmenu(AntSubMenu menu)
|
||||
{
|
||||
if (Accordion)
|
||||
{
|
||||
foreach (AntSubMenu item in Submenus.Where(x => x != menu && x != menu.Parent))
|
||||
{
|
||||
item.Close();
|
||||
}
|
||||
}
|
||||
|
||||
if (menu.IsOpen)
|
||||
{
|
||||
menu.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
menu.Open();
|
||||
}
|
||||
|
||||
if (OnSubmenuClicked.HasDelegate)
|
||||
OnSubmenuClicked.InvokeAsync(menu);
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private void SetClass()
|
||||
{
|
||||
ClassMapper.Add(PrefixCls)
|
||||
.Add($"{PrefixCls}-root")
|
||||
.Add($"{PrefixCls}-{Theme}")
|
||||
.Add($"{PrefixCls}-{Mode}")
|
||||
.If($"{PrefixCls}-inline-collapsed", () => InlineCollapsed);
|
||||
.Add($"{PrefixCls}-{InternalMode}")
|
||||
.If($"{PrefixCls}-inline-collapsed", () => _collapsed)
|
||||
.If($"{PrefixCls}-unselectable", () => !Selectable);
|
||||
}
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
|
||||
if (InternalMode != AntMenuMode.Inline && _collapsed)
|
||||
throw new ArgumentException($"{nameof(AntMenu)} in the {Mode} mode cannot be {nameof(Collapsed)}");
|
||||
|
||||
_initialMode = Mode;
|
||||
InternalMode = Mode;
|
||||
if (Parent != null)
|
||||
{
|
||||
Parent.OnCollapsed += Update;
|
||||
}
|
||||
|
||||
SetClass();
|
||||
}
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
base.OnParametersSet();
|
||||
await UpdateInLineCollapse();
|
||||
if (Parent == null)
|
||||
{
|
||||
this._collapsed = Collapsed;
|
||||
}
|
||||
Update(_collapsed);
|
||||
}
|
||||
|
||||
private async Task UpdateInLineCollapse()
|
||||
public void Update(bool collapsed)
|
||||
{
|
||||
if (MenuItems.Any())
|
||||
this._collapsed = collapsed;
|
||||
if (collapsed)
|
||||
{
|
||||
if (InlineCollapsed)
|
||||
InternalMode = AntMenuMode.Vertical;
|
||||
foreach (AntSubMenu item in Submenus)
|
||||
{
|
||||
_openedSubMenus = this.SubMenus.Where(x => x.Open).ToList();
|
||||
foreach (var antSubMenu in this.SubMenus)
|
||||
{
|
||||
await antSubMenu.SetOpenState(false);
|
||||
}
|
||||
item.Close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InternalMode = _initialMode;
|
||||
}
|
||||
}
|
||||
|
||||
this.Mode = AntDirectionVHIType.vertical;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var subMenu in _openedSubMenus)
|
||||
{
|
||||
await subMenu.SetOpenState(false);
|
||||
}
|
||||
_openedSubMenus.Clear();
|
||||
this.Mode = this._cacheMode;
|
||||
}
|
||||
StateHasChanged();
|
||||
public void Dispose()
|
||||
{
|
||||
if (Parent != null)
|
||||
{
|
||||
Parent.OnCollapsed -= Update;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
@namespace AntBlazor
|
||||
@namespace AntBlazor
|
||||
@inherits AntDomComponentBase
|
||||
|
||||
<CascadingValue Value=this>
|
||||
<li class="@ClassMapper.Class" @ref="Ref" style="@Style" id="@Id" @onclick="()=> Menu.Click.InvokeAsync(this)">
|
||||
<CascadingValue Value="this">
|
||||
<li class="@ClassMapper.Class" role="menuitem" style="@Style" @onclick="HandleOnClick" @key="Key">
|
||||
@ChildContent
|
||||
</li>
|
||||
</CascadingValue>
|
||||
</CascadingValue>
|
@ -1,80 +1,67 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace AntBlazor
|
||||
{
|
||||
public partial class AntMenuItem : AntDomComponentBase
|
||||
{
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
[CascadingParameter] public AntMenu RootMenu { get; set; }
|
||||
[CascadingParameter] public AntSubMenu ParentMenu { get; set; }
|
||||
[Parameter] public RenderFragment ChildContent { get; set; }
|
||||
[Parameter] public string Key { get; set; }
|
||||
[Parameter] public bool Disabled { get; set; }
|
||||
[Parameter] public EventCallback<MouseEventArgs> OnClicked { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool Disabled { get; set; } = false;
|
||||
public bool IsSelected { get; private set; }
|
||||
|
||||
[Parameter]
|
||||
public bool Selected { get; set; } = false;
|
||||
|
||||
[Parameter]
|
||||
public int? PaddingLeft { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool MatchRouterExact { get; set; } = false;
|
||||
|
||||
[Parameter]
|
||||
public bool MatchRouter { get; set; } = false;
|
||||
|
||||
[CascadingParameter]
|
||||
public AntMenu Menu { get; set; }
|
||||
|
||||
[CascadingParameter]
|
||||
public AntSubMenu SubMenu { get; set; }
|
||||
|
||||
private readonly int _originalPadding = 0;
|
||||
|
||||
private void SetClassMap()
|
||||
private void SetClass()
|
||||
{
|
||||
string prefixName = $"{Menu.PrefixCls}-item";
|
||||
ClassMapper.Clear()
|
||||
.Add(prefixName)
|
||||
.If($"{prefixName}-selected", () => Selected)
|
||||
.If($"{prefixName}-disabled", () => Disabled);
|
||||
}
|
||||
string prefixCls = "ant-menu-item";
|
||||
|
||||
internal void SelectedChanged(bool value)
|
||||
{
|
||||
this.Selected = value;
|
||||
ClassMapper.Add(prefixCls)
|
||||
.If($"{prefixCls}-selected", () => IsSelected)
|
||||
.If($"{prefixCls}-disabled", () => Disabled);
|
||||
}
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
SetClass();
|
||||
|
||||
base.OnInitialized();
|
||||
if (this is AntMenuItem item)
|
||||
{
|
||||
Menu?.MenuItems.Add(item);
|
||||
SubMenu?.Items.Add(item);
|
||||
}
|
||||
|
||||
int? padding = null;
|
||||
if (Menu.Mode == AntDirectionVHIType.inline)
|
||||
{
|
||||
if (PaddingLeft != null)
|
||||
{
|
||||
padding = PaddingLeft;
|
||||
}
|
||||
else
|
||||
{
|
||||
int level = SubMenu?.Level + 1 ?? 1;
|
||||
padding = level * this.Menu.InlineIndent;
|
||||
}
|
||||
}
|
||||
RootMenu.MenuItems.Add(this);
|
||||
}
|
||||
|
||||
if (padding != null)
|
||||
{
|
||||
Style += $"padding-left:{padding}px;";
|
||||
}
|
||||
public async Task HandleOnClick(MouseEventArgs args)
|
||||
{
|
||||
if (!RootMenu.Selectable)
|
||||
return;
|
||||
|
||||
SetClassMap();
|
||||
RootMenu.SelectItem(this);
|
||||
|
||||
if (OnClicked.HasDelegate)
|
||||
await OnClicked.InvokeAsync(args);
|
||||
|
||||
if (ParentMenu == null)
|
||||
return;
|
||||
|
||||
if (RootMenu.Mode != AntMenuMode.Inline)
|
||||
{
|
||||
await ParentMenu?.Collapse();
|
||||
}
|
||||
}
|
||||
|
||||
public void Select()
|
||||
{
|
||||
IsSelected = true;
|
||||
}
|
||||
|
||||
public void Deselect()
|
||||
{
|
||||
IsSelected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,38 +1,21 @@
|
||||
@namespace AntBlazor
|
||||
@namespace AntBlazor
|
||||
@inherits AntDomComponentBase
|
||||
|
||||
<li class="@ClassMapper.Class" @ref="Ref" style="@Style" id="@Id">
|
||||
<div class="@titleClassMapper.Class">
|
||||
@Title
|
||||
<li class="ant-menu-item-group" style="@Style" >
|
||||
<div class="ant-menu-item-group-title">
|
||||
@if (Title.Value != null)
|
||||
{
|
||||
@if (Title.IsT0)
|
||||
{
|
||||
@Title.AsT0
|
||||
}
|
||||
else if (Title.IsT1)
|
||||
{
|
||||
@Title.AsT1
|
||||
}
|
||||
}
|
||||
</div>
|
||||
@ChildContent
|
||||
</li>
|
||||
|
||||
@code {
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string Title { get; set; }
|
||||
|
||||
|
||||
[CascadingParameter]
|
||||
public AntMenu Menu { get; set; }
|
||||
|
||||
private readonly ClassMapper titleClassMapper = new ClassMapper();
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
this.titleClassMapper
|
||||
.If("ant-dropdown-menu-item-group-title", () => !Menu.IsInDropDown)
|
||||
.If("ant-menu-item-group-title", () => !Menu.IsInDropDown)
|
||||
;
|
||||
|
||||
this.ClassMapper
|
||||
.If("ant-dropdown-menu-item-group", () => Menu.IsInDropDown)
|
||||
.If("ant-menu-item-group", () => !Menu.IsInDropDown);
|
||||
}
|
||||
|
||||
}
|
||||
<ul class="ant-menu-item-group-list">
|
||||
@ChildContent
|
||||
</ul>
|
||||
</li>
|
21
components/menu/AntMenuItemGroup.razor.cs
Normal file
21
components/menu/AntMenuItemGroup.razor.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using OneOf;
|
||||
|
||||
namespace AntBlazor
|
||||
{
|
||||
public partial class AntMenuItemGroup : AntDomComponentBase
|
||||
{
|
||||
private static string _prefixCls = "ant-menu-item-group";
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
ClassMapper.Add(_prefixCls);
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public OneOf<string, RenderFragment> Title { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
}
|
||||
}
|
15
components/menu/AntMenuMode.cs
Normal file
15
components/menu/AntMenuMode.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using Ardalis.SmartEnum;
|
||||
|
||||
namespace AntBlazor
|
||||
{
|
||||
public sealed class AntMenuMode : SmartEnum<AntMenuMode>
|
||||
{
|
||||
public static readonly AntMenuMode Vertical = new AntMenuMode(nameof(Vertical).ToLower(), 1);
|
||||
public static readonly AntMenuMode Horizontal = new AntMenuMode(nameof(Horizontal).ToLower(), 2);
|
||||
public static readonly AntMenuMode Inline = new AntMenuMode(nameof(Inline).ToLower(), 3);
|
||||
|
||||
private AntMenuMode(string name, int value) : base(name, value)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
14
components/menu/AntMenuTheme.cs
Normal file
14
components/menu/AntMenuTheme.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using Ardalis.SmartEnum;
|
||||
|
||||
namespace AntBlazor
|
||||
{
|
||||
public sealed class AntMenuTheme : SmartEnum<AntMenuTheme>
|
||||
{
|
||||
public static readonly AntMenuTheme Light = new AntMenuTheme(nameof(Light).ToLowerInvariant(), 1);
|
||||
public static readonly AntMenuTheme Dark = new AntMenuTheme(nameof(Dark).ToLowerInvariant(), 2);
|
||||
|
||||
private AntMenuTheme(string name, int value) : base(name, value)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Rendering;
|
||||
using Microsoft.AspNetCore.Components.Routing;
|
||||
@ -10,11 +11,9 @@ namespace AntBlazor
|
||||
public class AntNavLink : AntDomComponentBase
|
||||
{
|
||||
private const string DefaultActiveClass = "active";
|
||||
|
||||
private bool _isActive;
|
||||
private string _hrefAbsolute;
|
||||
private string _class;
|
||||
|
||||
internal string Href => _hrefAbsolute;
|
||||
|
||||
/// <summary>
|
||||
@ -47,6 +46,9 @@ namespace AntBlazor
|
||||
[CascadingParameter]
|
||||
public AntMenuItem MenuItem { get; set; }
|
||||
|
||||
[CascadingParameter]
|
||||
public AntMenu Menu { get; set; }
|
||||
|
||||
[CascadingParameter]
|
||||
public AntButton Button { get; set; }
|
||||
|
||||
@ -57,10 +59,10 @@ namespace AntBlazor
|
||||
{
|
||||
// We'll consider re-rendering on each location change
|
||||
NavigationManger.LocationChanged += OnLocationChanged;
|
||||
if (Button != null)
|
||||
{
|
||||
Button.Link = this;
|
||||
}
|
||||
//if (Button != null)
|
||||
//{
|
||||
// Button.Link = this;
|
||||
//}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@ -72,18 +74,18 @@ namespace AntBlazor
|
||||
{
|
||||
href = Convert.ToString(obj, CultureInfo.CurrentCulture);
|
||||
}
|
||||
|
||||
_hrefAbsolute = href == null ? null : NavigationManger.ToAbsoluteUri(href).AbsoluteUri;
|
||||
_isActive = ShouldMatch(NavigationManger.Uri);
|
||||
|
||||
_class = (string)null;
|
||||
if (Attributes != null && Attributes.TryGetValue("class", out obj))
|
||||
{
|
||||
_class = Convert.ToString(obj, CultureInfo.CurrentCulture);
|
||||
}
|
||||
|
||||
UpdateCssClass();
|
||||
MenuItem?.SelectedChanged(_isActive);
|
||||
if (MenuItem != null && _isActive)
|
||||
{
|
||||
Menu?.SelectItem(MenuItem);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@ -108,7 +110,10 @@ namespace AntBlazor
|
||||
{
|
||||
_isActive = shouldBeActiveNow;
|
||||
UpdateCssClass();
|
||||
MenuItem?.SelectedChanged(_isActive);
|
||||
if (MenuItem != null && _isActive)
|
||||
{
|
||||
Menu?.SelectItem(MenuItem);
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
@ -119,13 +124,11 @@ namespace AntBlazor
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Match == NavLinkMatch.Prefix
|
||||
&& IsStrictlyPrefixWithSeparator(currentUriAbsolute, _hrefAbsolute))
|
||||
&& IsStrictlyPrefixWithSeparator(currentUriAbsolute, _hrefAbsolute))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -135,7 +138,6 @@ namespace AntBlazor
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (currentUriAbsolute.Length == _hrefAbsolute.Length - 1)
|
||||
{
|
||||
// Special case: highlight links to http://host/path/ even if you're
|
||||
@ -147,12 +149,11 @@ namespace AntBlazor
|
||||
// for http://host/vdir as they do for host://host/vdir/ as it's no
|
||||
// good to display a blank page in that case.
|
||||
if (_hrefAbsolute[^1] == '/'
|
||||
&& _hrefAbsolute.StartsWith(currentUriAbsolute, StringComparison.Ordinal))
|
||||
&& _hrefAbsolute.StartsWith(currentUriAbsolute, StringComparison.Ordinal))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -161,18 +162,16 @@ namespace AntBlazor
|
||||
if (builder != null)
|
||||
{
|
||||
builder.OpenElement(0, "a");
|
||||
|
||||
builder.AddMultipleAttributes(1, Attributes);
|
||||
builder.AddAttribute(2, "class", CssClass);
|
||||
builder.AddContent(3, ChildContent);
|
||||
|
||||
builder.CloseElement();
|
||||
}
|
||||
}
|
||||
|
||||
private static string CombineWithSpace(string str1, string str2)
|
||||
=> str1 == null ? str2
|
||||
: (str2 == null ? str1 : $"{str1} {str2}");
|
||||
=> str1 == null ? str2
|
||||
: (str2 == null ? str1 : $"{str1} {str2}");
|
||||
|
||||
private static bool IsStrictlyPrefixWithSeparator(string value, string prefix)
|
||||
{
|
||||
@ -180,15 +179,15 @@ namespace AntBlazor
|
||||
if (value.Length > prefixLength)
|
||||
{
|
||||
return value.StartsWith(prefix, StringComparison.Ordinal)
|
||||
&& (
|
||||
// Only match when there's a separator character either at the end of the
|
||||
// prefix or right after it.
|
||||
// Example: "/abc" is treated as a prefix of "/abc/def" but not "/abcdef"
|
||||
// Example: "/abc/" is treated as a prefix of "/abc/def" but not "/abcdef"
|
||||
prefixLength == 0
|
||||
|| !char.IsLetterOrDigit(prefix[prefixLength - 1])
|
||||
|| !char.IsLetterOrDigit(value[prefixLength])
|
||||
);
|
||||
&& (
|
||||
// Only match when there's a separator character either at the end of the
|
||||
// prefix or right after it.
|
||||
// Example: "/abc" is treated as a prefix of "/abc/def" but not "/abcdef"
|
||||
// Example: "/abc/" is treated as a prefix of "/abc/def" but not "/abcdef"
|
||||
prefixLength == 0
|
||||
|| !char.IsLetterOrDigit(prefix[prefixLength - 1])
|
||||
|| !char.IsLetterOrDigit(value[prefixLength])
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1,60 +1,16 @@
|
||||
@namespace AntBlazor
|
||||
@namespace AntBlazor
|
||||
@inherits AntDomComponentBase
|
||||
|
||||
<CascadingValue Value=this>
|
||||
<li class="@ClassMapper.Class" @ref="Ref" style="@Style" id="@Id">
|
||||
<div class="@TitleDivClass.Class" style="@titleStyle"
|
||||
@onmouseover="()=>SetMouseEnterState(true)"
|
||||
@onmouseout="()=>SetMouseEnterState(false)"
|
||||
@onclick="()=> ClickSubMenuTitle()">
|
||||
@if (Icon != null)
|
||||
{
|
||||
<AntIcon Type="@Icon"></AntIcon>
|
||||
}
|
||||
|
||||
<span>@((MarkupString)Title)</span>
|
||||
|
||||
@if (Menu.IsInDropDown)
|
||||
{
|
||||
<span class="ant-dropdown-menu-submenu-arrow">
|
||||
<AntIcon Type="right" Class="anticon-right ant-dropdown-menu-submenu-arrow-icon"></AntIcon>
|
||||
</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<i class="ant-menu-submenu-arrow"></i>
|
||||
}
|
||||
</div>
|
||||
@if (Menu.Mode == AntDirectionVHIType.inline)
|
||||
{
|
||||
<ul class="@MenuClassName ant-menu ant-menu-inline ant-menu-sub" style="transition: height 0.5s; @submenuStyle">
|
||||
@ChildContent
|
||||
</ul>
|
||||
}
|
||||
</li>
|
||||
|
||||
@if (Open && Menu.Mode != AntDirectionVHIType.inline)
|
||||
{
|
||||
<div style="position: absolute; top: 0px; left: 0px; width: 100%;">
|
||||
<div class="ant-menu-submenu ant-menu-submenu-popup @PopupClassMapper.Class"
|
||||
style="left:@(_element.offsetLeft+_element.clientWidth+10)px; top:@(_element.offsetTop)px; @(IsMouseHover?"":"display: none;")"
|
||||
@onmouseout="()=>SetMouseEnterState(false)"
|
||||
@onmouseover="()=>SetMouseEnterState(true)"
|
||||
@onmouseout:stopPropagation
|
||||
@onmouseover:stopPropagation>
|
||||
<ul class="@MenuClassName @PopupUlClassMapper.Class ant-menu-submenu-content" style="@(IsMouseHover?"":"display: none;")">
|
||||
@ChildContent
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</CascadingValue>
|
||||
|
||||
|
||||
@code {
|
||||
|
||||
string titleStyle => Menu.Mode == AntDirectionVHIType.inline ?
|
||||
$"padding-left:{(PaddingLeft ?? Level * Menu.InlineIndent)}px" : "";
|
||||
|
||||
string submenuStyle => Open ? "" : "height: 0px; overflow: hidden;";
|
||||
}
|
||||
<li class="@ClassMapper.Class" role="menuitem" @key="Key" @onmouseover="HandleMouseOver" @onmouseout="HandleMouseOut" style="position:relative;@Style">
|
||||
<div class="ant-menu-submenu-title" role="button" @onclick="HandleOnTitleClick" aria-haspopup="true">
|
||||
<span>
|
||||
@Title.Value
|
||||
</span>
|
||||
<i class="ant-menu-submenu-arrow"></i>
|
||||
</div>
|
||||
<ul direction="ltr" class="@SubMenuMapper.Class" role="menu" aria-expanded="@IsOpen">
|
||||
<CascadingValue Value="this">
|
||||
@ChildContent
|
||||
</CascadingValue>
|
||||
</ul>
|
||||
</li>
|
@ -1,141 +1,102 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using OneOf;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using AntBlazor.JsInterop;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace AntBlazor
|
||||
{
|
||||
public partial class AntSubMenu : AntDomComponentBase
|
||||
{
|
||||
public int Level { get; set; } = 1;
|
||||
private const string PrefixCls = "ant-menu-submenu";
|
||||
|
||||
[CascadingParameter]
|
||||
protected AntMenu Menu { get; set; }
|
||||
|
||||
internal IList<AntMenuItem> Items { get; set; } = new List<AntMenuItem>();
|
||||
public AntMenu RootMenu { get; set; }
|
||||
|
||||
[CascadingParameter]
|
||||
protected AntSubMenu ParentSubMenu { get; set; }
|
||||
public AntSubMenu Parent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public OneOf<string, RenderFragment> Title { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string MenuClassName { get; set; }
|
||||
public string Key { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public int? PaddingLeft { get; set; }
|
||||
public bool Disabled { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string Title { get; set; }
|
||||
public EventCallback<MouseEventArgs> OnTitleClicked { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string Icon { get; set; }
|
||||
private ClassMapper SubMenuMapper { get; } = new ClassMapper();
|
||||
|
||||
[Parameter]
|
||||
public bool Open { get; set; } = false;
|
||||
public bool IsOpen { get; private set; }
|
||||
|
||||
[Parameter]
|
||||
public bool Disabled { get; set; } = false;
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<bool> OpenChange { get; set; }
|
||||
|
||||
protected ClassMapper TitleDivClass { get; } = new ClassMapper();
|
||||
|
||||
protected ClassMapper PopupClassMapper { get; } = new ClassMapper();
|
||||
|
||||
protected ClassMapper PopupUlClassMapper { get; } = new ClassMapper();
|
||||
|
||||
private string _placement = "rightTop";
|
||||
|
||||
private bool _isChildMenuSelected = false;
|
||||
protected bool IsMouseHover { get; set; } = false;
|
||||
private bool _hasOpened;
|
||||
|
||||
private Element _element = new Element();
|
||||
|
||||
private void SetClassMap()
|
||||
private void SetClass()
|
||||
{
|
||||
this._isChildMenuSelected = this.Items.Any(x => x.Selected);
|
||||
ClassMapper.Add(PrefixCls)
|
||||
.Add($"{PrefixCls}-{RootMenu.InternalMode}")
|
||||
.If($"{PrefixCls}-open", () => IsOpen);
|
||||
|
||||
string prefixName = Menu.IsInDropDown ? "ant-dropdown-menu-submenu" : "ant-menu-submenu";
|
||||
ClassMapper.Clear()
|
||||
.Add(prefixName)
|
||||
.If($"{prefixName}-disabled", () => Disabled)
|
||||
.If($"{prefixName}-open", () => this.Open)
|
||||
.If($"{prefixName}-selected", () => _isChildMenuSelected)
|
||||
.Add($"{prefixName}-{Menu.Mode}")
|
||||
.If($"{prefixName}-active", () => IsMouseHover && !Disabled)
|
||||
;
|
||||
SubMenuMapper.Add("ant-menu")
|
||||
.Add("ant-menu-sub")
|
||||
.Add($"ant-menu-{(RootMenu.InternalMode == AntMenuMode.Horizontal ? AntMenuMode.Vertical : RootMenu.InternalMode)}")
|
||||
.If($"ant-menu-submenu-popup", () => RootMenu.InternalMode != AntMenuMode.Inline)
|
||||
.If($"ant-menu-disabled", () => Disabled)
|
||||
.If($"ant-menu-hidden", () => !IsOpen);
|
||||
}
|
||||
|
||||
private async Task HandleOnTitleClick(MouseEventArgs args)
|
||||
{
|
||||
RootMenu.SelectSubmenu(this);
|
||||
if (OnTitleClicked.HasDelegate)
|
||||
await OnTitleClicked.InvokeAsync(args);
|
||||
}
|
||||
|
||||
private void HandleMouseOver(MouseEventArgs args)
|
||||
{
|
||||
if (RootMenu.InternalMode == AntMenuMode.Inline)
|
||||
return;
|
||||
|
||||
IsOpen = true;
|
||||
}
|
||||
|
||||
private void HandleMouseOut(MouseEventArgs args)
|
||||
{
|
||||
if (RootMenu.InternalMode == AntMenuMode.Inline)
|
||||
return;
|
||||
|
||||
IsOpen = false;
|
||||
}
|
||||
|
||||
public async Task Collapse()
|
||||
{
|
||||
await Task.Delay(300);
|
||||
IsOpen = false;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
if (this is AntSubMenu subMenu)
|
||||
{
|
||||
this.Menu?.SubMenus.Add(subMenu);
|
||||
}
|
||||
|
||||
this.Level = this.ParentSubMenu?.Level + 1 ?? 1;
|
||||
|
||||
this._hasOpened = Open;
|
||||
this.SetClassMap();
|
||||
base.OnInitialized();
|
||||
|
||||
PopupClassMapper.Clear()
|
||||
.If("ant-menu-light", () => Menu.Theme == "light")
|
||||
.If("ant-menu-dark", () => Menu.Theme == "dark")
|
||||
.If("ant-menu-submenu-placement-bottomLeft", () => Menu.Mode == AntDirectionVHIType.horizontal)
|
||||
.If("ant-menu-submenu-placement-rightTop",
|
||||
() => Menu.Mode == AntDirectionVHIType.vertical && _placement == "rightTop")
|
||||
.If("ant-menu-submenu-placement-leftTop",
|
||||
() => Menu.Mode == AntDirectionVHIType.vertical && _placement == "leftTop")
|
||||
;
|
||||
|
||||
PopupUlClassMapper.Clear()
|
||||
.If("ant-dropdown-menu", () => Menu.IsInDropDown)
|
||||
.If("ant-menu", () => !Menu.IsInDropDown)
|
||||
.If("ant-dropdown-menu-vertical", () => Menu.IsInDropDown)
|
||||
.If("ant-menu-vertical", () => !Menu.IsInDropDown)
|
||||
.If("ant-dropdown-menu-sub", () => Menu.IsInDropDown)
|
||||
.If("ant-menu-sub", () => !Menu.IsInDropDown)
|
||||
;
|
||||
|
||||
TitleDivClass
|
||||
.If("ant-dropdown-menu-submenu-title", () => Menu.IsInDropDown)
|
||||
.If("ant-menu-submenu-title", () => !Menu.IsInDropDown)
|
||||
;
|
||||
RootMenu.Submenus.Add(this);
|
||||
}
|
||||
|
||||
protected async Task SetMouseEnterState(bool value)
|
||||
public void Close()
|
||||
{
|
||||
if (IsMouseHover != value)
|
||||
{
|
||||
this.IsMouseHover = value;
|
||||
this.SetClassMap();
|
||||
|
||||
this._element = await JsInvokeAsync<Element>(JSInteropConstants.getDomInfo, Ref);
|
||||
}
|
||||
IsOpen = false;
|
||||
}
|
||||
|
||||
protected async Task ClickSubMenuTitle()
|
||||
public void Open()
|
||||
{
|
||||
if (Menu.Mode == AntDirectionVHIType.inline && !Menu.IsInDropDown && !this.Disabled)
|
||||
IsOpen = true;
|
||||
if (Parent != null)
|
||||
{
|
||||
this.Open = !this.Open;
|
||||
await OpenChange.InvokeAsync(this.Open);
|
||||
this.SetClassMap();
|
||||
Parent.Open();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SetOpenState(bool value)
|
||||
{
|
||||
this.Open = value;
|
||||
this._hasOpened = value;
|
||||
await OpenChange.InvokeAsync(this.Open);
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
# Ant Design of Blazor [![Github Stars](https://img.shields.io/github/stars/ant-design-blazor/ant-design-blazor?style=social)](https://github.com/ant-design-blazor/ant-design-blazor)
|
||||
---
|
||||
order: 0
|
||||
title: Ant Design of Blazor
|
||||
---
|
||||
|
||||
Following the Ant Design specification, we developed a Blazor Components library `ant-design-blazor` that contains a set of high quality components and demos for building rich, interactive user interfaces.
|
||||
|
@ -1,4 +1,7 @@
|
||||
# Ant Design of Blazor [![Github Stars](https://img.shields.io/github/stars/ant-design-blazor/ant-design-blazor?style=social)](https://github.com/ant-design-blazor/ant-design-blazor)
|
||||
---
|
||||
order: 0
|
||||
title: Ant Design of Blazor
|
||||
---
|
||||
|
||||
这里是 Ant Design 的 Blazor 实现,开发和服务于企业级后台产品。
|
||||
|
||||
@ -32,12 +35,12 @@
|
||||
|
||||
## 🌈 在线示例
|
||||
|
||||
由 WebAssembly 构建,托管在 [GitHub Pages](https://ant-design-blazor.github.io/) ([Gitee Pages 镜像](http://ant-design-blazor.gitee.io/))
|
||||
由 WebAssembly 构建,托管在 Gitee Pages http://ant-design-blazor.gitee.io/
|
||||
|
||||
## 🖥 支持环境
|
||||
|
||||
- .NET Core 3.1
|
||||
- Blazor WebAssembly 3.2 RC 1
|
||||
- Blazor WebAssembly 3.2 rc 1
|
||||
- 支持服务端双向绑定
|
||||
- 支持 WebAssembly 静态文件部署
|
||||
- 主流 4 款现代浏览器,以及 Internet Explorer 11+ (使用 [Blazor Server](https://angular.io/guide/browser-support))
|
@ -228,6 +228,17 @@
|
||||
|
||||
<script src="_framework/blazor.webassembly.js"></script>
|
||||
<script src="_content/AntBlazor/js/ant-design-blazor.js"></script>
|
||||
<script src="_content/AntBlazor.Docs/js/prism.js"></script>
|
||||
<script>
|
||||
window.antBlazor.Prism = {};
|
||||
window.antBlazor.Prism.highlight = function (code, language) {
|
||||
return Prism.highlight(code, Prism.languages[language], language);
|
||||
}
|
||||
|
||||
window.antBlazor.Prism.highlightAll = function () {
|
||||
Prism.highlightAll();
|
||||
}
|
||||
</script>
|
||||
<script>navigator.serviceWorker.register('service-worker.js');</script>
|
||||
</body>
|
||||
|
||||
|
@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Shared\DemoComponent.cs" Link="Shared\DemoComponent.cs" />
|
||||
<Compile Include="..\Shared\MenuItem.cs" Link="Shared\MenuItem.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.CommandLineUtils" Version="1.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.0" />
|
||||
<PackageReference Include="YamlDotnet" Version="8.1.0" />
|
||||
<PackageReference Include="Markdig" Version="0.18.3" />
|
||||
</ItemGroup>
|
||||
</Project>
|
23
site/AntBlazor.Docs.Build.CLI/AppCommandResolver.cs
Normal file
23
site/AntBlazor.Docs.Build.CLI/AppCommandResolver.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
|
||||
namespace AntBlazor.Docs.Build.CLI
|
||||
{
|
||||
public class AppCommandResolver : IAppCommandResolver
|
||||
{
|
||||
private readonly IEnumerable<IAppCommand> _appCommands;
|
||||
|
||||
public AppCommandResolver(IEnumerable<IAppCommand> appCommands)
|
||||
{
|
||||
_appCommands = appCommands;
|
||||
}
|
||||
|
||||
public void Resolve(CommandLineApplication application)
|
||||
{
|
||||
foreach (var command in _appCommands)
|
||||
{
|
||||
application.Command(command.Name, command.Execute);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
152
site/AntBlazor.Docs.Build.CLI/Command/GenerateDemoJsonCommand.cs
Normal file
152
site/AntBlazor.Docs.Build.CLI/Command/GenerateDemoJsonCommand.cs
Normal file
@ -0,0 +1,152 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Text.Json;
|
||||
using AntBlazor.Docs.Build.CLI.Extensions;
|
||||
using AntBlazor.Docs.Build.CLI.Utils;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
|
||||
namespace AntBlazor.Docs.Build.CLI.Command
|
||||
{
|
||||
public class GenerateDemoJsonCommand : IAppCommand
|
||||
{
|
||||
public string Name => "demo2json";
|
||||
|
||||
public void Execute(CommandLineApplication command)
|
||||
{
|
||||
command.Description = "Generate json file of demos";
|
||||
command.HelpOption();
|
||||
|
||||
CommandArgument directoryArgument = command.Argument(
|
||||
"source", "[Required] The directory of demo files.");
|
||||
|
||||
CommandArgument outputArgument = command.Argument(
|
||||
"output", "[Required] The directory where the json file to output");
|
||||
|
||||
command.OnExecute(() =>
|
||||
{
|
||||
string source = directoryArgument.Value;
|
||||
string output = outputArgument.Value;
|
||||
|
||||
if (string.IsNullOrEmpty(source) || !Directory.Exists(source))
|
||||
{
|
||||
Console.WriteLine("Invalid source.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(output))
|
||||
{
|
||||
output = "./";
|
||||
}
|
||||
|
||||
string demoDirectory = Path.Combine(Directory.GetCurrentDirectory(), source);
|
||||
|
||||
GenerateFiles(demoDirectory, output);
|
||||
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
private void GenerateFiles(string demoDirectory, string output)
|
||||
{
|
||||
DirectoryInfo demoDirectoryInfo = new DirectoryInfo(demoDirectory);
|
||||
if (demoDirectoryInfo.Attributes != FileAttributes.Directory)
|
||||
{
|
||||
Console.WriteLine("{0} is not a directory", demoDirectory);
|
||||
return;
|
||||
}
|
||||
|
||||
IList<Dictionary<string, DemoComponent>> componentList = null;
|
||||
|
||||
foreach (FileSystemInfo component in demoDirectoryInfo.GetFileSystemInfos())
|
||||
{
|
||||
if (!(component is DirectoryInfo componentDirectory)) continue;
|
||||
|
||||
FileSystemInfo docDir = componentDirectory.GetFileSystemInfos("doc")[0];
|
||||
FileSystemInfo demoDir = componentDirectory.GetFileSystemInfos("demo")[0];
|
||||
|
||||
Dictionary<string, DemoComponent> componentDic = new Dictionary<string, DemoComponent>();
|
||||
|
||||
foreach (FileSystemInfo docItem in (docDir as DirectoryInfo).GetFileSystemInfos())
|
||||
{
|
||||
string language = docItem.Name.Replace("index.", "").Replace(docItem.Extension, "");
|
||||
string content = File.ReadAllText(docItem.FullName);
|
||||
(Dictionary<string, string> Meta, string Content) docData = DocParser.ParseDemoDoc(content);
|
||||
|
||||
componentDic.Add(language, new DemoComponent()
|
||||
{
|
||||
Title = docData.Meta["title"],
|
||||
SubTitle = docData.Meta.TryGetValue("subtitle", out string subtitle) ? subtitle : null,
|
||||
Type = docData.Meta["type"],
|
||||
Doc = docData.Content
|
||||
});
|
||||
}
|
||||
|
||||
foreach (IGrouping<string, FileSystemInfo> demo in (demoDir as DirectoryInfo).GetFileSystemInfos().GroupBy(x => x.Name.Replace(x.Extension, "").ToLower()))
|
||||
{
|
||||
List<FileSystemInfo> showCaseFiles = demo.ToList();
|
||||
FileSystemInfo razorFile = showCaseFiles.FirstOrDefault(x => x.Extension == ".razor");
|
||||
FileSystemInfo descriptionFile = showCaseFiles.FirstOrDefault(x => x.Extension == ".md");
|
||||
string code = razorFile != null ? File.ReadAllText(razorFile.FullName) : null;
|
||||
(DescriptionYaml Meta, string Style, Dictionary<string, string> Descriptions) descriptionContent = descriptionFile != null ? DocParser.ParseDescription(File.ReadAllText(descriptionFile.FullName)) : default;
|
||||
|
||||
foreach (KeyValuePair<string, string> title in descriptionContent.Meta.Title)
|
||||
{
|
||||
string language = title.Key;
|
||||
List<DemoItem> list = componentDic[language].DemoList ??= new List<DemoItem>();
|
||||
|
||||
list.Add(new DemoItem()
|
||||
{
|
||||
Title = title.Value,
|
||||
Order = descriptionContent.Meta.Order,
|
||||
Code = code,
|
||||
Description = descriptionContent.Descriptions[title.Key],
|
||||
Name = demo.Key,
|
||||
Style = descriptionContent.Style,
|
||||
Type = $"{demoDirectoryInfo.Name}.{component.Name}.{demoDir.Name}.{razorFile.Name.Replace(razorFile.Extension, "")}"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentList ??= new List<Dictionary<string, DemoComponent>>();
|
||||
componentList.Add(componentDic);
|
||||
}
|
||||
|
||||
if (componentList == null)
|
||||
return;
|
||||
|
||||
IEnumerable<IGrouping<string, KeyValuePair<string, DemoComponent>>> componentI18N = componentList
|
||||
.SelectMany(x => x).GroupBy(x => x.Key);
|
||||
|
||||
foreach (IGrouping<string, KeyValuePair<string, DemoComponent>> componentDic in componentI18N)
|
||||
{
|
||||
IEnumerable<DemoComponent> components = componentDic.Select(x => x.Value);
|
||||
string json = JsonSerializer.Serialize(components, new JsonSerializerOptions()
|
||||
{
|
||||
WriteIndented = true,
|
||||
IgnoreNullValues = true,
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
});
|
||||
|
||||
string configFileDirectory = Path.Combine(Directory.GetCurrentDirectory(), output);
|
||||
if (!Directory.Exists(configFileDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(configFileDirectory);
|
||||
}
|
||||
|
||||
string configFilePath = Path.Combine(configFileDirectory, $"demo.{componentDic.Key}.json");
|
||||
Console.WriteLine(json);
|
||||
|
||||
if (File.Exists(configFilePath))
|
||||
{
|
||||
File.Delete(configFilePath);
|
||||
}
|
||||
|
||||
File.WriteAllText(configFilePath, json);
|
||||
Console.WriteLine("Generate demo file to {0}", configFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
254
site/AntBlazor.Docs.Build.CLI/Command/GenerateMenuJsonCommand.cs
Normal file
254
site/AntBlazor.Docs.Build.CLI/Command/GenerateMenuJsonCommand.cs
Normal file
@ -0,0 +1,254 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Text.Json;
|
||||
using AntBlazor.Docs.Build.CLI.Extensions;
|
||||
using AntBlazor.Docs.Build.CLI.Utils;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
|
||||
namespace AntBlazor.Docs.Build.CLI.Command
|
||||
{
|
||||
public class GenerateMenuJsonCommand : IAppCommand
|
||||
|
||||
{
|
||||
public string Name => "menu2json";
|
||||
|
||||
public void Execute(CommandLineApplication command)
|
||||
{
|
||||
command.Description = "Generate json file for menu";
|
||||
command.HelpOption();
|
||||
|
||||
CommandArgument demoDirArgument = command.Argument(
|
||||
"demoDir", "[Required] The directory of docs files.");
|
||||
|
||||
CommandArgument docsDirArgument = command.Argument(
|
||||
"docsDir", "[Required] The directory of docs files.");
|
||||
|
||||
CommandArgument outputArgument = command.Argument(
|
||||
"output", "[Required] The directory where the json file to output");
|
||||
|
||||
command.OnExecute(() =>
|
||||
{
|
||||
string demoDir = demoDirArgument.Value;
|
||||
string docsDir = docsDirArgument.Value;
|
||||
string output = outputArgument.Value;
|
||||
|
||||
if (string.IsNullOrEmpty(demoDir) || !Directory.Exists(demoDir))
|
||||
{
|
||||
Console.WriteLine("Invalid demoDir.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(docsDir) || !Directory.Exists(docsDir))
|
||||
{
|
||||
Console.WriteLine("Invalid docsDir.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(output))
|
||||
{
|
||||
output = "./";
|
||||
}
|
||||
|
||||
string demoDirectory = Path.Combine(Directory.GetCurrentDirectory(), demoDir);
|
||||
string docsDirectory = Path.Combine(Directory.GetCurrentDirectory(), docsDir);
|
||||
|
||||
GenerateFiles(demoDirectory, docsDirectory, output);
|
||||
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
private void GenerateFiles(string demoDirectory, string docsDirectory, string output)
|
||||
{
|
||||
DirectoryInfo demoDirectoryInfo = new DirectoryInfo(demoDirectory);
|
||||
if (demoDirectoryInfo.Attributes != FileAttributes.Directory)
|
||||
{
|
||||
Console.WriteLine("{0} is not a directory", demoDirectory);
|
||||
return;
|
||||
}
|
||||
|
||||
DirectoryInfo docsDirectoryInfo = new DirectoryInfo(docsDirectory);
|
||||
if (docsDirectoryInfo.Attributes != FileAttributes.Directory)
|
||||
{
|
||||
Console.WriteLine("{0} is not a directory", docsDirectory);
|
||||
return;
|
||||
}
|
||||
|
||||
IList<Dictionary<string, DemoComponent>> componentList = null;
|
||||
|
||||
IList<Dictionary<string, MenuItem>> menuList = null;
|
||||
|
||||
Dictionary<string, int> sortMap = new Dictionary<string, int>()
|
||||
{
|
||||
["General"] = 0,
|
||||
["通用"] = 0,
|
||||
["Layout"] = 1,
|
||||
["布局"] = 1,
|
||||
["Navigation"] = 2,
|
||||
["导航"] = 2,
|
||||
["Data Entry"] = 3,
|
||||
["数据录入"] = 3,
|
||||
["Data Display"] = 4,
|
||||
["数据展示"] = 4,
|
||||
["Feedback"] = 5,
|
||||
["反馈"] = 5,
|
||||
["Localization"] = 6,
|
||||
["Other"] = 7,
|
||||
["其他"] = 7
|
||||
};
|
||||
|
||||
foreach (FileSystemInfo component in demoDirectoryInfo.GetFileSystemInfos())
|
||||
{
|
||||
if (!(component is DirectoryInfo componentDirectory))
|
||||
continue;
|
||||
|
||||
Dictionary<string, DemoComponent> componentDic = new Dictionary<string, DemoComponent>();
|
||||
|
||||
FileSystemInfo docDir = componentDirectory.GetFileSystemInfos("doc")[0];
|
||||
|
||||
foreach (FileSystemInfo docItem in (docDir as DirectoryInfo).GetFileSystemInfos())
|
||||
{
|
||||
string language = docItem.Name.Replace("index.", "").Replace(docItem.Extension, "");
|
||||
string content = File.ReadAllText(docItem.FullName);
|
||||
(Dictionary<string, string> Meta, string Content) docData = DocParser.ParseDemoDoc(content);
|
||||
|
||||
componentDic.Add(language, new DemoComponent()
|
||||
{
|
||||
Title = docData.Meta["title"],
|
||||
SubTitle = docData.Meta.TryGetValue("subtitle", out string subtitle) ? subtitle : null,
|
||||
Type = docData.Meta["type"],
|
||||
Doc = docData.Content,
|
||||
});
|
||||
}
|
||||
|
||||
componentList ??= new List<Dictionary<string, DemoComponent>>();
|
||||
componentList.Add(componentDic);
|
||||
}
|
||||
|
||||
if (componentList == null)
|
||||
return;
|
||||
|
||||
List<Dictionary<string, MenuItem>> componentMenuList = new List<Dictionary<string, MenuItem>>();
|
||||
|
||||
IEnumerable<KeyValuePair<string, DemoComponent>> componentI18N = componentList
|
||||
.SelectMany(x => x);
|
||||
|
||||
foreach (IGrouping<string, KeyValuePair<string, DemoComponent>> group in componentI18N.GroupBy(x => x.Value.Type))
|
||||
{
|
||||
Dictionary<string, MenuItem> menu = new Dictionary<string, MenuItem>();
|
||||
|
||||
foreach (IGrouping<string, KeyValuePair<string, DemoComponent>> component in group.GroupBy(x => x.Key))
|
||||
{
|
||||
menu.Add(component.Key, new MenuItem()
|
||||
{
|
||||
Order = sortMap[group.Key],
|
||||
Title = group.Key,
|
||||
Type = "itemGroup",
|
||||
Children = group.Select(x => new MenuItem()
|
||||
{
|
||||
Title = x.Value.Title,
|
||||
SubTitle = x.Value.SubTitle,
|
||||
Url = $"components/{x.Value.Title.ToLower()}",
|
||||
Type = "menuItem"
|
||||
}).ToArray()
|
||||
});
|
||||
}
|
||||
|
||||
componentMenuList.Add(menu);
|
||||
}
|
||||
|
||||
foreach (FileSystemInfo docItem in docsDirectoryInfo.GetFileSystemInfos())
|
||||
{
|
||||
if (docItem.Extension != ".md")
|
||||
continue;
|
||||
|
||||
string[] segments = docItem.Name.Split('.');
|
||||
if (segments.Length != 3)
|
||||
continue;
|
||||
|
||||
string language = segments[1];
|
||||
string content = File.ReadAllText(docItem.FullName);
|
||||
Dictionary<string, string> docData = DocParser.ParseHeader(content);
|
||||
|
||||
menuList ??= new List<Dictionary<string, MenuItem>>();
|
||||
menuList.Add(new Dictionary<string, MenuItem>()
|
||||
{
|
||||
[language] = new MenuItem()
|
||||
{
|
||||
Order = int.TryParse(docData["order"], out int order) ? order : 0,
|
||||
Title = docData["title"],
|
||||
Url = $"docs/{segments[0]}",
|
||||
Type = "menuItem"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (menuList == null)
|
||||
return;
|
||||
|
||||
IEnumerable<IGrouping<string, KeyValuePair<string, MenuItem>>> menuI18N = menuList
|
||||
.SelectMany(x => x).GroupBy(x => x.Key);
|
||||
|
||||
IEnumerable<IGrouping<string, KeyValuePair<string, MenuItem>>> componentMenuI18N = componentMenuList
|
||||
.SelectMany(x => x).GroupBy(x => x.Key);
|
||||
|
||||
foreach (IGrouping<string, KeyValuePair<string, MenuItem>> menuGroup in menuI18N)
|
||||
{
|
||||
var children = menuGroup.Select(x => x.Value).OrderBy(x => x.Order).ToArray();
|
||||
List<MenuItem> menu = new List<MenuItem>
|
||||
{
|
||||
new MenuItem()
|
||||
{
|
||||
Order = 0,
|
||||
Title = menuGroup.Key == "zh-CN" ? "文档" : "Docs",
|
||||
Type = "subMenu",
|
||||
Url = "docs",
|
||||
Children = children
|
||||
}
|
||||
};
|
||||
|
||||
var components = componentMenuI18N.Where(x => x.Key == menuGroup.Key)
|
||||
.SelectMany(x => x)
|
||||
.Select(x => x.Value)
|
||||
.OrderBy(x => x.Order)
|
||||
.ToArray();
|
||||
|
||||
menu.Add(new MenuItem()
|
||||
{
|
||||
Order = 999,
|
||||
Title = menuGroup.Key == "zh-CN" ? "组件" : "Components",
|
||||
Type = "subMenu",
|
||||
Url = "components",
|
||||
Children = components.ToArray()
|
||||
});
|
||||
|
||||
string json = JsonSerializer.Serialize(menu, new JsonSerializerOptions()
|
||||
{
|
||||
WriteIndented = true,
|
||||
IgnoreNullValues = true,
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
});
|
||||
|
||||
string configFileDirectory = Path.Combine(Directory.GetCurrentDirectory(), output);
|
||||
if (!Directory.Exists(configFileDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(configFileDirectory);
|
||||
}
|
||||
|
||||
string configFilePath = Path.Combine(configFileDirectory, $"menu.{menuGroup.Key}.json");
|
||||
Console.WriteLine(json);
|
||||
|
||||
if (File.Exists(configFilePath))
|
||||
{
|
||||
File.Delete(configFilePath);
|
||||
}
|
||||
|
||||
File.WriteAllText(configFilePath, json);
|
||||
Console.WriteLine("Generate demo file to {0}", configFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
using AntBlazor.Docs.Build.CLI.Extensions;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
|
||||
namespace AntBlazor.Docs.Build.CLI
|
||||
{
|
||||
public class CommandLineApplicationFactory
|
||||
{
|
||||
private readonly IAppCommandResolver _appCommandResolver;
|
||||
|
||||
public CommandLineApplicationFactory(IAppCommandResolver appCommandResolver)
|
||||
{
|
||||
_appCommandResolver = appCommandResolver;
|
||||
}
|
||||
|
||||
public CommandLineApplication Create()
|
||||
{
|
||||
var app = new CommandLineApplication
|
||||
{
|
||||
Name = "ant-design-blazor",
|
||||
FullName = "Ant Design Blazor Command Line Tool",
|
||||
Description =
|
||||
"Generate demo structured file for Docs."
|
||||
};
|
||||
|
||||
app.HelpOption();
|
||||
app.VersionOptionFromAssemblyAttributes(typeof(Program).Assembly);
|
||||
|
||||
app.OnExecute(() =>
|
||||
{
|
||||
app.ShowHelp();
|
||||
return 2;
|
||||
});
|
||||
|
||||
_appCommandResolver.Resolve(app);
|
||||
|
||||
return app;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
|
||||
namespace AntBlazor.Docs.Build.CLI.Extensions
|
||||
{
|
||||
internal static class CommandLineApplicationExtensions
|
||||
{
|
||||
public static CommandOption HelpOption(this CommandLineApplication app)
|
||||
=> app.HelpOption("-?|-h|--help");
|
||||
|
||||
public static CommandOption VerboseOption(this CommandLineApplication app)
|
||||
=> app.Option("-v|--verbose", "Show verbose output", CommandOptionType.NoValue, inherited: true);
|
||||
|
||||
public static void OnExecute(this CommandLineApplication app, Action action)
|
||||
=> app.OnExecute(() =>
|
||||
{
|
||||
action();
|
||||
return 0;
|
||||
});
|
||||
|
||||
public static void VersionOptionFromAssemblyAttributes(this CommandLineApplication app, Assembly assembly)
|
||||
=> app.VersionOption("--version", GetInformationalVersion(assembly));
|
||||
|
||||
private static string GetInformationalVersion(Assembly assembly)
|
||||
{
|
||||
var attribute = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>();
|
||||
|
||||
var versionAttribute = attribute == null
|
||||
? assembly.GetName().Version.ToString()
|
||||
: attribute.InformationalVersion;
|
||||
|
||||
return versionAttribute;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace AntBlazor.Docs.Build.CLI.Extensions
|
||||
{
|
||||
public static class ProcessExtensions
|
||||
{
|
||||
public static void Exec(this Process process, string command)
|
||||
{
|
||||
if (!process.HasExited)
|
||||
process.StandardInput.WriteLine(command);
|
||||
}
|
||||
}
|
||||
}
|
11
site/AntBlazor.Docs.Build.CLI/IAppCommand.cs
Normal file
11
site/AntBlazor.Docs.Build.CLI/IAppCommand.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
|
||||
namespace AntBlazor.Docs.Build.CLI
|
||||
{
|
||||
public interface IAppCommand
|
||||
{
|
||||
string Name { get; }
|
||||
|
||||
void Execute(CommandLineApplication command);
|
||||
}
|
||||
}
|
9
site/AntBlazor.Docs.Build.CLI/IAppCommandResolver.cs
Normal file
9
site/AntBlazor.Docs.Build.CLI/IAppCommandResolver.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
|
||||
namespace AntBlazor.Docs.Build.CLI
|
||||
{
|
||||
public interface IAppCommandResolver
|
||||
{
|
||||
void Resolve(CommandLineApplication application);
|
||||
}
|
||||
}
|
51
site/AntBlazor.Docs.Build.CLI/Program.cs
Normal file
51
site/AntBlazor.Docs.Build.CLI/Program.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using AntBlazor.Docs.Build.CLI.Command;
|
||||
using AntBlazor.Docs.Build.CLI.Utils;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace AntBlazor.Docs.Build.CLI
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
private static int Main(string[] args)
|
||||
{
|
||||
return new Program().Run(args);
|
||||
}
|
||||
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
public Program()
|
||||
{
|
||||
_serviceProvider = ConfigureServices();
|
||||
}
|
||||
|
||||
private int Run(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
var app = _serviceProvider.GetRequiredService<CommandLineApplication>();
|
||||
return app.Execute(args);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine($"An error occurred. {e.Message}");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
private IServiceProvider ConfigureServices()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<CommandLineApplicationFactory>();
|
||||
services.AddSingleton(p => p.GetRequiredService<CommandLineApplicationFactory>().Create());
|
||||
services.AddSingleton<IAppCommandResolver, AppCommandResolver>();
|
||||
services.AddSingleton<PlatformInformationArbiter>();
|
||||
services.AddSingleton<DirectoryProvider>();
|
||||
services.AddSingleton<ShellProcessFactory>();
|
||||
services.AddSingleton<IAppCommand, GenerateDemoJsonCommand>();
|
||||
services.AddSingleton<IAppCommand, GenerateMenuJsonCommand>();
|
||||
return services.BuildServiceProvider();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"profiles": {
|
||||
"AntBlazor.Docs.Build.CLI": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "demo2json ../../../../AntBlazor.Docs/Demos ./"
|
||||
//"commandLineArgs": "menu2json ../../../../AntBlazor.Docs/Demos ../../../../../docs ./"
|
||||
}
|
||||
}
|
||||
}
|
19
site/AntBlazor.Docs.Build.CLI/Utils/ConsoleUtils.cs
Normal file
19
site/AntBlazor.Docs.Build.CLI/Utils/ConsoleUtils.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace AntBlazor.Docs.Build.CLI.Utils
|
||||
{
|
||||
public static class ConsoleUtils
|
||||
{
|
||||
public static void WriteLine(string message, ConsoleColor foregroundColor)
|
||||
{
|
||||
var currentForegroundColor = Console.ForegroundColor;
|
||||
Console.ForegroundColor = foregroundColor;
|
||||
Console.WriteLine(message);
|
||||
Console.ForegroundColor = currentForegroundColor;
|
||||
}
|
||||
|
||||
public static void WriteWelcome()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
43
site/AntBlazor.Docs.Build.CLI/Utils/DirectoryProvider.cs
Normal file
43
site/AntBlazor.Docs.Build.CLI/Utils/DirectoryProvider.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace AntBlazor.Docs.Build.CLI.Utils
|
||||
{
|
||||
public class DirectoryProvider
|
||||
{
|
||||
private readonly PlatformInformationArbiter _platformInformation;
|
||||
|
||||
public string TmpDirectory => _platformInformation.GetValue(
|
||||
() => Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"), "AppData\\Local\\Temp"),
|
||||
() => "/tmp",
|
||||
() => "/tmp",
|
||||
() => "/tmp");
|
||||
|
||||
public string DotnetDirectory => _platformInformation.GetValue(
|
||||
() => Path.Combine("C:\\Progra~1", "dotnet"),
|
||||
() => Path.Combine("/usr/local/share", "dotnet"),
|
||||
() => Path.Combine("/usr/local/share", "dotnet"),
|
||||
() => Path.Combine("/usr/local/share", "dotnet"));
|
||||
|
||||
public string AgentPath => "skyapm.agent.aspnetcore";
|
||||
|
||||
public string AdditonalDepsRootDirectory => Path.Combine(DotnetDirectory, "x64", "additionalDeps");
|
||||
|
||||
public string StoreDirectory => Path.Combine(DotnetDirectory, "store");
|
||||
|
||||
public DirectoryProvider(PlatformInformationArbiter platformInformation)
|
||||
{
|
||||
_platformInformation = platformInformation;
|
||||
}
|
||||
|
||||
public string GetAdditonalDepsPath(string additonalName, string frameworkVersion)
|
||||
{
|
||||
return Path.Combine(GetAdditonalDepsDirectory(additonalName), "shared", "Microsoft.NETCore.App", frameworkVersion);
|
||||
}
|
||||
|
||||
public string GetAdditonalDepsDirectory(string additonalName)
|
||||
{
|
||||
return Path.Combine(AdditonalDepsRootDirectory, additonalName);
|
||||
}
|
||||
}
|
||||
}
|
143
site/AntBlazor.Docs.Build.CLI/Utils/DocParser.cs
Normal file
143
site/AntBlazor.Docs.Build.CLI/Utils/DocParser.cs
Normal file
@ -0,0 +1,143 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Markdig;
|
||||
using Markdig.Extensions.Yaml;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Syntax;
|
||||
using YamlDotNet.Serialization;
|
||||
using YamlDotNet.Serialization.NamingConventions;
|
||||
|
||||
namespace AntBlazor.Docs.Build.CLI.Utils
|
||||
{
|
||||
public class DocParser
|
||||
{
|
||||
public static (Dictionary<string, string> Meta, string Content) ParseDemoDoc(string input)
|
||||
{
|
||||
var pipeline = new MarkdownPipelineBuilder()
|
||||
.UseYamlFrontMatter()
|
||||
.Build();
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
var renderer = new HtmlRenderer(writer);
|
||||
pipeline.Setup(renderer);
|
||||
|
||||
MarkdownDocument document = Markdown.Parse(input, pipeline);
|
||||
var yamlBlock = document.Descendants<YamlFrontMatterBlock>().FirstOrDefault();
|
||||
|
||||
Dictionary<string, string> meta = null;
|
||||
if (yamlBlock != null)
|
||||
{
|
||||
string yaml = input.Substring(yamlBlock.Span.Start, yamlBlock.Span.Length).Trim('-');
|
||||
meta = new Deserializer().Deserialize<Dictionary<string, string>>(yaml);
|
||||
}
|
||||
|
||||
renderer.Render(document);
|
||||
writer.Flush();
|
||||
string html = writer.ToString();
|
||||
|
||||
return (meta, html);
|
||||
}
|
||||
|
||||
public static (DescriptionYaml Meta, string Style, Dictionary<string, string> Descriptions) ParseDescription(string input)
|
||||
{
|
||||
var pipeline = new MarkdownPipelineBuilder()
|
||||
.UseYamlFrontMatter()
|
||||
.Build();
|
||||
|
||||
MarkdownDocument document = Markdown.Parse(input, pipeline);
|
||||
var yamlBlock = document.Descendants<YamlFrontMatterBlock>().FirstOrDefault();
|
||||
|
||||
DescriptionYaml meta = null;
|
||||
if (yamlBlock != null)
|
||||
{
|
||||
string yaml = input.Substring(yamlBlock.Span.Start, yamlBlock.Span.Length).Trim('-');
|
||||
meta = Deserializer.FromValueDeserializer(new DeserializerBuilder()
|
||||
.WithNamingConvention(CamelCaseNamingConvention.Instance).BuildValueDeserializer())
|
||||
.Deserialize<DescriptionYaml>(yaml);
|
||||
}
|
||||
|
||||
var isAfterENHeading = false;
|
||||
var isStyleBlock = false;
|
||||
|
||||
var zhPart = "";
|
||||
var enPart = "";
|
||||
var stylePart = "";
|
||||
|
||||
for (int i = yamlBlock?.Line ?? 0; i < document.Count; i++)
|
||||
{
|
||||
var block = document[i];
|
||||
if (block is YamlFrontMatterBlock)
|
||||
continue;
|
||||
|
||||
if (block is HeadingBlock heading && heading.Level == 2 && heading.Inline.FirstChild.ToString() == "en-US")
|
||||
{
|
||||
isAfterENHeading = true;
|
||||
}
|
||||
|
||||
if (block is HtmlBlock htmlBlock && htmlBlock.Type == HtmlBlockType.ScriptPreOrStyle)
|
||||
{
|
||||
isStyleBlock = true;
|
||||
}
|
||||
|
||||
if (block is HeadingBlock h && h.Level == 2)
|
||||
continue;
|
||||
|
||||
using StringWriter writer = new StringWriter();
|
||||
var renderer = new HtmlRenderer(writer);
|
||||
|
||||
var blockHtml = renderer.Render(block);
|
||||
|
||||
if (!isAfterENHeading)
|
||||
{
|
||||
zhPart += blockHtml;
|
||||
}
|
||||
else if (isStyleBlock)
|
||||
{
|
||||
stylePart += blockHtml;
|
||||
}
|
||||
else
|
||||
{
|
||||
enPart += blockHtml;
|
||||
}
|
||||
}
|
||||
|
||||
stylePart = stylePart.Replace("<style>", "").Replace("</style>", "");
|
||||
return (meta, stylePart, new Dictionary<string, string>() { ["zh-CN"] = zhPart, ["en-US"] = enPart });
|
||||
}
|
||||
|
||||
public static Dictionary<string, string> ParseHeader(string input)
|
||||
{
|
||||
var pipeline = new MarkdownPipelineBuilder()
|
||||
.UseYamlFrontMatter()
|
||||
.Build();
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
var renderer = new HtmlRenderer(writer);
|
||||
pipeline.Setup(renderer);
|
||||
|
||||
MarkdownDocument document = Markdown.Parse(input, pipeline);
|
||||
var yamlBlock = document.Descendants<YamlFrontMatterBlock>().FirstOrDefault();
|
||||
|
||||
Dictionary<string, string> meta = null;
|
||||
if (yamlBlock != null)
|
||||
{
|
||||
string yaml = input.Substring(yamlBlock.Span.Start, yamlBlock.Span.Length).Trim('-');
|
||||
meta = new Deserializer().Deserialize<Dictionary<string, string>>(yaml);
|
||||
}
|
||||
|
||||
return meta;
|
||||
}
|
||||
}
|
||||
|
||||
public class DescriptionYaml
|
||||
{
|
||||
public int Order { get; set; }
|
||||
|
||||
public Dictionary<string, string> Iframe { get; set; }
|
||||
|
||||
public Dictionary<string, string> Title { get; set; }
|
||||
|
||||
public bool Debug { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace AntBlazor.Docs.Build.CLI.Utils
|
||||
{
|
||||
public class PlatformInformationArbiter
|
||||
{
|
||||
public T GetValue<T>(Func<T> windowsValueProvider, Func<T> linuxValueProvider, Func<T> osxValueProvider, Func<T> defaultValueProvider)
|
||||
{
|
||||
return RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
|
||||
? windowsValueProvider()
|
||||
: RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
|
||||
? linuxValueProvider()
|
||||
: RuntimeInformation.IsOSPlatform(OSPlatform.OSX)
|
||||
? osxValueProvider()
|
||||
: defaultValueProvider();
|
||||
}
|
||||
|
||||
public void Invoke(Action windowsValueProvider, Action linuxValueProvider, Action osxValueProvider, Action defaultValueProvider)
|
||||
{
|
||||
var invoker = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
|
||||
? windowsValueProvider
|
||||
: RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
|
||||
? linuxValueProvider
|
||||
: RuntimeInformation.IsOSPlatform(OSPlatform.OSX)
|
||||
? osxValueProvider
|
||||
: defaultValueProvider;
|
||||
invoker();
|
||||
}
|
||||
}
|
||||
}
|
99
site/AntBlazor.Docs.Build.CLI/Utils/ShellProcess.cs
Normal file
99
site/AntBlazor.Docs.Build.CLI/Utils/ShellProcess.cs
Normal file
@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace AntBlazor.Docs.Build.CLI.Utils
|
||||
{
|
||||
public class ShellProcess
|
||||
{
|
||||
private readonly object _lock = new object();
|
||||
private readonly Process _process;
|
||||
private bool _isError;
|
||||
private int _exitCode;
|
||||
|
||||
public int ExitCode
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _isError ? 1 : _exitCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ShellProcess(string name, string argument)
|
||||
{
|
||||
var processStartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = name,
|
||||
CreateNoWindow = true,
|
||||
ErrorDialog = true,
|
||||
UseShellExecute = false,
|
||||
RedirectStandardError = true,
|
||||
RedirectStandardInput = true,
|
||||
RedirectStandardOutput = true
|
||||
};
|
||||
if (!string.IsNullOrEmpty(argument))
|
||||
{
|
||||
processStartInfo.Arguments = argument;
|
||||
}
|
||||
|
||||
_process = new Process { StartInfo = processStartInfo };
|
||||
}
|
||||
|
||||
public void Exec(string command)
|
||||
{
|
||||
if (!_isError)
|
||||
{
|
||||
_process.StandardInput.WriteLine(command);
|
||||
}
|
||||
}
|
||||
|
||||
public ShellProcess Start()
|
||||
{
|
||||
_process.Start();
|
||||
_process.OutputDataReceived += ProcessOnOutputDataReceived;
|
||||
_process.ErrorDataReceived += ProcessOnErrorDataReceived;
|
||||
_process.BeginOutputReadLine();
|
||||
_process.BeginErrorReadLine();
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
_process.StandardInput.WriteLine("exit");
|
||||
_process.WaitForExit();
|
||||
_exitCode = _process.ExitCode;
|
||||
_process.OutputDataReceived -= ProcessOnOutputDataReceived;
|
||||
_process.ErrorDataReceived -= ProcessOnErrorDataReceived;
|
||||
_process.Dispose();
|
||||
}
|
||||
|
||||
private void ProcessOnErrorDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrEmpty(e.Data))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.Data.StartsWith("Cloning into"))
|
||||
{
|
||||
Console.WriteLine(e.Data);
|
||||
return;
|
||||
}
|
||||
|
||||
ConsoleUtils.WriteLine(e.Data, ConsoleColor.Yellow);
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
_isError = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessOnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(e.Data))
|
||||
Console.WriteLine(e.Data);
|
||||
}
|
||||
}
|
||||
}
|
16
site/AntBlazor.Docs.Build.CLI/Utils/ShellProcessFactory.cs
Normal file
16
site/AntBlazor.Docs.Build.CLI/Utils/ShellProcessFactory.cs
Normal file
@ -0,0 +1,16 @@
|
||||
namespace AntBlazor.Docs.Build.CLI.Utils
|
||||
{
|
||||
public class ShellProcessFactory
|
||||
{
|
||||
public ShellProcess Create(string name, string argument = null)
|
||||
{
|
||||
return new ShellProcess(name, argument).Start();
|
||||
}
|
||||
|
||||
public int Release(ShellProcess process)
|
||||
{
|
||||
process.Close();
|
||||
return process.ExitCode;
|
||||
}
|
||||
}
|
||||
}
|
@ -20,5 +20,16 @@
|
||||
|
||||
<script src="_framework/blazor.server.js"></script>
|
||||
<script src="_content/AntBlazor/js/ant-design-blazor.js"></script>
|
||||
<script src="_content/AntBlazor.Docs/js/prism.js"></script>
|
||||
<script>
|
||||
window.antBlazor.Prism = {};
|
||||
window.antBlazor.Prism.highlight = function (code, language) {
|
||||
return Prism.highlight(code, Prism.languages[language], language);
|
||||
}
|
||||
|
||||
window.antBlazor.Prism.highlightAll = function () {
|
||||
Prism.highlightAll();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,3 +1,6 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
@ -21,6 +24,15 @@ namespace AntBlazor.Docs.Server
|
||||
{
|
||||
services.AddRazorPages();
|
||||
services.AddServerSideBlazor();
|
||||
services.AddTransient(sp => new HttpClient()
|
||||
{
|
||||
DefaultRequestHeaders =
|
||||
{
|
||||
// Use to call the github API on server side
|
||||
{"User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36 Edg/81.0.416.68"}
|
||||
}
|
||||
});
|
||||
|
||||
services.AddAntBlazorDocs();
|
||||
}
|
||||
|
||||
@ -50,4 +62,4 @@ namespace AntBlazor.Docs.Server
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,10 @@
|
||||
<SolutionDir>../../</SolutionDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="$(SolutionDir)scripts\gh-pages\**" LinkBase="gh-pages" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<DocFiles Include="$(SolutionDir)docs\**\*.*" />
|
||||
</ItemGroup>
|
||||
|
@ -9,7 +9,6 @@
|
||||
<base href="/" />
|
||||
<link rel="icon" href="logo.png" type="image/x-icon">
|
||||
<link href="_content/AntBlazor.Docs/css/docs.css" rel="stylesheet">
|
||||
<!--<link href="manifest.json" rel="manifest" />-->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -199,7 +198,17 @@
|
||||
</app>
|
||||
<script src="_framework/blazor.webassembly.js"></script>
|
||||
<script src="_content/AntBlazor/js/ant-design-blazor.js"></script>
|
||||
<!--<script>navigator.serviceWorker.register('service-worker.js');</script>-->
|
||||
<script src="_content/AntBlazor.Docs/js/prism.js"></script>
|
||||
<script>
|
||||
window.antBlazor.Prism = {};
|
||||
window.antBlazor.Prism.highlight = function (code, language) {
|
||||
return Prism.highlight(code, Prism.languages[language], language);
|
||||
}
|
||||
|
||||
window.antBlazor.Prism.highlightAll = function () {
|
||||
Prism.highlightAll();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -19,8 +19,6 @@ namespace AntBlazor.Docs.WasmHost
|
||||
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
|
||||
services.AddControllersWithViews();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
@ -46,9 +44,8 @@ namespace AntBlazor.Docs.WasmHost
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
endpoints.MapFallbackToFile("index.html");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -28,6 +28,11 @@
|
||||
<EmbeddedResource Include="Resources\*.yml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Shared\DemoComponent.cs" Link="Services\DemoComponent.cs" />
|
||||
<Compile Include="..\Shared\MenuItem.cs" Link="Services\MenuItem.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="DebugEnsureNodeEnv" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('$(SolutionDir)node_modules') ">
|
||||
<!-- Ensure Node.js is installed -->
|
||||
<Exec Command="node --version" ContinueOnError="true">
|
||||
@ -42,6 +47,17 @@
|
||||
<Exec WorkingDirectory="$(SolutionDir)" Command="npm run gulp:docs" />
|
||||
</Target>
|
||||
|
||||
<PropertyGroup>
|
||||
<CLIProjectDir>$(SolutionDir)site/AntBlazor.Docs.Build.CLI</CLIProjectDir>
|
||||
<CLIPath>$(CLIProjectDir)/bin/Debug/netcoreapp3.1/AntBlazor.Docs.Build.CLI.dll</CLIPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="RunCli" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug'">
|
||||
<Exec WorkingDirectory="$(SolutionDir)" Command="dotnet build $(CLIProjectDir)" />
|
||||
<Exec WorkingDirectory="$(SolutionDir)" Command="dotnet $(CLIPath) demo2json $(ProjectDir)Demos $(ProjectDir)wwwroot/meta" />
|
||||
<Exec WorkingDirectory="$(SolutionDir)" Command="dotnet $(CLIPath) menu2json $(ProjectDir)Demos docs $(ProjectDir)wwwroot/meta" />
|
||||
</Target>
|
||||
|
||||
<Target Name="PublishRunGulp" AfterTargets="ComputeFilesToPublish">
|
||||
<Exec WorkingDirectory="$(SolutionDir)" Command="npm install" />
|
||||
<Exec WorkingDirectory="$(SolutionDir)" Command="npm run gulp:docs" />
|
||||
|
@ -1,4 +1,4 @@
|
||||
<ConventionRouter AppAssembly="@typeof(MainLayout).Assembly" DefaultUrl="docs/introduce">
|
||||
<ConventionRouter AppAssembly="@typeof(MainLayout).Assembly" DefaultUrl="docs/introduce">
|
||||
<Found Context="routeData">
|
||||
<RouteView RouteData="routeData" DefaultLayout="@typeof(MainLayout)" />
|
||||
</Found>
|
||||
|
19
site/AntBlazor.Docs/Demos/Alert/demo/Banner.razor
Normal file
19
site/AntBlazor.Docs/Demos/Alert/demo/Banner.razor
Normal file
@ -0,0 +1,19 @@
|
||||
<AntAlert Type="@AntAlertType.Warning"
|
||||
Message="Warning Text"
|
||||
Banner
|
||||
Closable />
|
||||
|
||||
<AntAlert Type="@AntAlertType.Warning"
|
||||
Message="Warning Text"
|
||||
Description="Very long warning text warning text text text text text text text"
|
||||
Banner
|
||||
Closable />
|
||||
|
||||
<AntAlert Type="@AntAlertType.Warning"
|
||||
Message="Warning Text Without Icon"
|
||||
Banner
|
||||
ShowIcon="false" />
|
||||
|
||||
<AntAlert Type="@AntAlertType.Error"
|
||||
Message="Error Text"
|
||||
Banner />
|
1
site/AntBlazor.Docs/Demos/Alert/demo/Basic.razor
Normal file
1
site/AntBlazor.Docs/Demos/Alert/demo/Basic.razor
Normal file
@ -0,0 +1 @@
|
||||
<AntAlert Type="@AntAlertType.Success" Message="Success Text" />
|
17
site/AntBlazor.Docs/Demos/Alert/demo/Closable.razor
Normal file
17
site/AntBlazor.Docs/Demos/Alert/demo/Closable.razor
Normal file
@ -0,0 +1,17 @@
|
||||
<AntAlert Type="@AntAlertType.Warning"
|
||||
Message="Warning Text Warning Text Warning Text Warning Text Warning Text Warning Text Warning Text"
|
||||
Closable
|
||||
OnClose="LogSomething" />
|
||||
|
||||
<AntAlert Type="@AntAlertType.Error"
|
||||
Message="Error Text"
|
||||
Description="Error Description Error Description Error Description Error Description Error Description Error Description"
|
||||
Closable
|
||||
OnClose="LogSomething" />
|
||||
|
||||
@code{
|
||||
private void LogSomething()
|
||||
{
|
||||
Console.WriteLine("Logging Something...");
|
||||
}
|
||||
}
|
1
site/AntBlazor.Docs/Demos/Alert/demo/Close_text.razor
Normal file
1
site/AntBlazor.Docs/Demos/Alert/demo/Close_text.razor
Normal file
@ -0,0 +1 @@
|
||||
<AntAlert Message="Info Text" Type="@AntAlertType.Info" CloseText="Close Now" Closable/>
|
15
site/AntBlazor.Docs/Demos/Alert/demo/Description.razor
Normal file
15
site/AntBlazor.Docs/Demos/Alert/demo/Description.razor
Normal file
@ -0,0 +1,15 @@
|
||||
<AntAlert Message="Success Text"
|
||||
Description="Success Description Success Description Success Description"
|
||||
Type="@AntAlertType.Success" />
|
||||
|
||||
<AntAlert Message="Info Text"
|
||||
Description="Info Description Info Description Info Description Info Description"
|
||||
Type="@AntAlertType.Info" />
|
||||
|
||||
<AntAlert Message="Warning Text"
|
||||
Description="Warning Description Warning Description Warning Description Warning Description"
|
||||
Type="@AntAlertType.Warning" />
|
||||
|
||||
<AntAlert Message="Error Text"
|
||||
Description="Error Description Error Description Error Description Error Description"
|
||||
Type="@AntAlertType.Error" />
|
35
site/AntBlazor.Docs/Demos/Alert/demo/Icon.razor
Normal file
35
site/AntBlazor.Docs/Demos/Alert/demo/Icon.razor
Normal file
@ -0,0 +1,35 @@
|
||||
<AntAlert Type="@AntAlertType.Success"
|
||||
Message="Success Tips"
|
||||
ShowIcon />
|
||||
|
||||
<AntAlert Type="@AntAlertType.Info"
|
||||
Message="Informational Notes"
|
||||
ShowIcon />
|
||||
|
||||
<AntAlert Type="@AntAlertType.Warning"
|
||||
Message="Warning"
|
||||
ShowIcon />
|
||||
|
||||
<AntAlert Type="@AntAlertType.Error"
|
||||
Message="Error"
|
||||
ShowIcon />
|
||||
|
||||
<AntAlert Type="@AntAlertType.Success"
|
||||
Message="Success Tips"
|
||||
Description="Detailed description and advice about successful copywriting."
|
||||
ShowIcon />
|
||||
|
||||
<AntAlert Type="@AntAlertType.Info"
|
||||
Message="Informational Notes"
|
||||
Description="Additional description and information about copywriting."
|
||||
ShowIcon />
|
||||
|
||||
<AntAlert Type="@AntAlertType.Warning"
|
||||
Message="Warning"
|
||||
Description="This is a warning notice about copywriting."
|
||||
ShowIcon />
|
||||
|
||||
<AntAlert Type="@AntAlertType.Error"
|
||||
Message="Error"
|
||||
Description="This is an error message about copywriting."
|
||||
ShowIcon />
|
7
site/AntBlazor.Docs/Demos/Alert/demo/Style.razor
Normal file
7
site/AntBlazor.Docs/Demos/Alert/demo/Style.razor
Normal file
@ -0,0 +1,7 @@
|
||||
<AntAlert Message="Success Text" Type="@AntAlertType.Success" />
|
||||
|
||||
<AntAlert Message="Info Text" Type="@AntAlertType.Info" />
|
||||
|
||||
<AntAlert Message="Warning Text" Type="@AntAlertType.Warning" />
|
||||
|
||||
<AntAlert Message="Error Text" Type="@AntAlertType.Error" />
|
18
site/AntBlazor.Docs/Demos/Alert/demo/banner.md
Normal file
18
site/AntBlazor.Docs/Demos/Alert/demo/banner.md
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
order: 6
|
||||
iframe:
|
||||
height: 220
|
||||
title:
|
||||
zh-CN: 顶部公告
|
||||
en-US: Banner
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
页面顶部通告形式,默认有图标且 `nzType` 为 `'warning'`。
|
||||
|
||||
## en-US
|
||||
|
||||
Display Alert as a banner at top of page.
|
||||
|
||||
|
20
site/AntBlazor.Docs/Demos/Alert/demo/basic.md
Normal file
20
site/AntBlazor.Docs/Demos/Alert/demo/basic.md
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
order: 0
|
||||
title:
|
||||
zh-CN: 基本
|
||||
en-US: Basic
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
最简单的用法,适用于简短的警告提示。
|
||||
|
||||
## en-US
|
||||
|
||||
The simplest usage for short messages.
|
||||
|
||||
<style>
|
||||
.code-box-demo .ant-alert {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
</style>
|
15
site/AntBlazor.Docs/Demos/Alert/demo/closable.md
Normal file
15
site/AntBlazor.Docs/Demos/Alert/demo/closable.md
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
order: 2
|
||||
title:
|
||||
zh-CN: 可关闭的警告提示
|
||||
en-US: Closable
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
显示关闭按钮,点击可关闭警告提示。
|
||||
|
||||
## en-US
|
||||
|
||||
To show close button.
|
||||
|
14
site/AntBlazor.Docs/Demos/Alert/demo/close_text.md
Normal file
14
site/AntBlazor.Docs/Demos/Alert/demo/close_text.md
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
order: 5
|
||||
title:
|
||||
zh-CN: 自定义关闭
|
||||
en-US: Customized Close Text
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
可以自定义关闭,自定义的内容会替换原先的关闭按钮。
|
||||
|
||||
## en-US
|
||||
|
||||
Replace the default icon with customized content.
|
15
site/AntBlazor.Docs/Demos/Alert/demo/description.md
Normal file
15
site/AntBlazor.Docs/Demos/Alert/demo/description.md
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
order: 3
|
||||
title:
|
||||
zh-CN: 含有辅助性文字介绍
|
||||
en-US: Description
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
含有辅助性文字介绍的警告提示。
|
||||
|
||||
## en-US
|
||||
|
||||
Additional description for alert message.
|
||||
|
16
site/AntBlazor.Docs/Demos/Alert/demo/icon.md
Normal file
16
site/AntBlazor.Docs/Demos/Alert/demo/icon.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
order: 4
|
||||
title:
|
||||
zh-CN: 图标
|
||||
en-US: Icon
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
可口的图标让信息类型更加醒目。
|
||||
|
||||
## en-US
|
||||
|
||||
Decent icon make information more clear and more friendly.
|
||||
|
||||
|
16
site/AntBlazor.Docs/Demos/Alert/demo/style.md
Normal file
16
site/AntBlazor.Docs/Demos/Alert/demo/style.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
order: 1
|
||||
title:
|
||||
zh-CN: 四种样式
|
||||
en-US: More types
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
共有四种样式 `success`、`info`、`warning`、`error`。
|
||||
|
||||
## en-US
|
||||
|
||||
There are 4 types of Alert: `success`, `info`, `warning`, `error`.
|
||||
|
||||
|
13
site/AntBlazor.Docs/Demos/Alert/doc/index.en-US.md
Normal file
13
site/AntBlazor.Docs/Demos/Alert/doc/index.en-US.md
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
category: Components
|
||||
type: Feedback
|
||||
title: Alert
|
||||
---
|
||||
|
||||
Alert component for feedback.
|
||||
|
||||
## When To Use
|
||||
|
||||
- When you need to show alert messages to users.
|
||||
- When you need a persistent static container which is closable by user actions.
|
||||
|
13
site/AntBlazor.Docs/Demos/Alert/doc/index.zh-CN.md
Normal file
13
site/AntBlazor.Docs/Demos/Alert/doc/index.zh-CN.md
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
category: Components
|
||||
subtitle: 警告提示
|
||||
type: 反馈
|
||||
title: Alert
|
||||
---
|
||||
|
||||
警告提示,展现需要关注的信息。
|
||||
|
||||
## 何时使用
|
||||
|
||||
- 当某个页面需要向用户显示警告的信息时。
|
||||
- 非浮层的静态展现形式,始终展现,不会自动消失,用户可以点击关闭。
|
12
site/AntBlazor.Docs/Demos/Avatar/demo/Badge.razor
Normal file
12
site/AntBlazor.Docs/Demos/Avatar/demo/Badge.razor
Normal file
@ -0,0 +1,12 @@
|
||||
<div>
|
||||
<span class="avatar-item">
|
||||
<AntBadge Count="1">
|
||||
<AntAvatar Shape="square" Icon="user" />
|
||||
</AntBadge>
|
||||
</span>
|
||||
<span>
|
||||
<AntBadge Dot>
|
||||
<AntAvatar Shape="square" Icon="user"/>
|
||||
</AntBadge>
|
||||
</span>
|
||||
</div>
|
14
site/AntBlazor.Docs/Demos/Avatar/demo/Basic.razor
Normal file
14
site/AntBlazor.Docs/Demos/Avatar/demo/Basic.razor
Normal file
@ -0,0 +1,14 @@
|
||||
<div>
|
||||
<div>
|
||||
<AntAvatar Size="64" Icon="user" />
|
||||
<AntAvatar Size="large" Icon="user" />
|
||||
<AntAvatar Icon="user" />
|
||||
<AntAvatar Size="small" Icon="user" />
|
||||
</div>
|
||||
<div>
|
||||
<AntAvatar Shape="square" Size="64" Icon="user" />
|
||||
<AntAvatar Shape="square" Size="large" Icon="user" />
|
||||
<AntAvatar Shape="square" Icon="user" />
|
||||
<AntAvatar Shape="square" Size="small" Icon="user" />
|
||||
</div>
|
||||
</div>
|
28
site/AntBlazor.Docs/Demos/Avatar/demo/Dynamic.razor
Normal file
28
site/AntBlazor.Docs/Demos/Avatar/demo/Dynamic.razor
Normal file
@ -0,0 +1,28 @@
|
||||
<div>
|
||||
<AntAvatar Style="@($"background-color: {color}; vertical-align: middle;")" Size="large">
|
||||
@user
|
||||
</AntAvatar>
|
||||
<AntButton
|
||||
Size="small"
|
||||
Style="margin:0 16px; vertical-align: middle;"
|
||||
Onclick="_=>changeUser()"
|
||||
>
|
||||
Change
|
||||
</AntButton>
|
||||
</div>
|
||||
|
||||
@code
|
||||
{
|
||||
private static string[] userList = {"U", "Lucy", "Tom", "Edward"};
|
||||
private static string[] colorList = {"#f56a00", "#7265e6", "#ffbf00", "#00a2ae"};
|
||||
|
||||
private string user { get; set; } = userList[0];
|
||||
private string color { get; set; } = colorList[0];
|
||||
|
||||
private void changeUser()
|
||||
{
|
||||
var index = Array.IndexOf(userList, user);
|
||||
user = index < userList.Length - 1 ? userList[index + 1] : userList[0];
|
||||
color = index < colorList.Length - 1 ? colorList[index + 1] : colorList[0];
|
||||
}
|
||||
}
|
8
site/AntBlazor.Docs/Demos/Avatar/demo/Type.razor
Normal file
8
site/AntBlazor.Docs/Demos/Avatar/demo/Type.razor
Normal file
@ -0,0 +1,8 @@
|
||||
<div>
|
||||
<AntAvatar Icon="user" />
|
||||
<AntAvatar>U</AntAvatar>
|
||||
<AntAvatar>USER</AntAvatar>
|
||||
<AntAvatar Src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
|
||||
<AntAvatar Style="color: #f56a00; background-color: #fde3cf; ">U</AntAvatar>
|
||||
<AntAvatar Style="background-color: #87d068" Icon="user" />
|
||||
</div>
|
16
site/AntBlazor.Docs/Demos/Avatar/demo/badge.md
Normal file
16
site/AntBlazor.Docs/Demos/Avatar/demo/badge.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
order: 3
|
||||
title:
|
||||
zh-CN: 带徽标的头像
|
||||
en-US: With Badge
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
通常用于消息提示。
|
||||
|
||||
## en-US
|
||||
|
||||
Usually used for messages remind.
|
||||
|
||||
|
15
site/AntBlazor.Docs/Demos/Avatar/demo/basic.md
Normal file
15
site/AntBlazor.Docs/Demos/Avatar/demo/basic.md
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
order: 0
|
||||
title:
|
||||
zh-CN: 基本
|
||||
en-US: Basic
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
头像有三种尺寸,两种形状可选。
|
||||
|
||||
## en-US
|
||||
|
||||
Three sizes and two shapes are available.
|
||||
|
14
site/AntBlazor.Docs/Demos/Avatar/demo/dynamic.md
Normal file
14
site/AntBlazor.Docs/Demos/Avatar/demo/dynamic.md
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
order: 2
|
||||
title:
|
||||
zh-CN: 自动调整字符大小
|
||||
en-US: Autoset Font Size
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
对于字符型的头像,当字符串较长时,字体大小可以根据头像宽度自动调整。
|
||||
|
||||
## en-US
|
||||
|
||||
For letter type Avatar, when the letters are too long to display, the font size can be automatically adjusted according to the width of the Avatar.
|
14
site/AntBlazor.Docs/Demos/Avatar/demo/type.md
Normal file
14
site/AntBlazor.Docs/Demos/Avatar/demo/type.md
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
order: 1
|
||||
title:
|
||||
zh-CN: 类型
|
||||
en-US: Type
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
支持三种类型:图片、Icon 以及字符,其中 Icon 和字符型可以自定义图标颜色及背景色。
|
||||
|
||||
## en-US
|
||||
|
||||
Image, Icon and letter are supported, and the latter two kinds avatar can have custom colors and background colors.
|
7
site/AntBlazor.Docs/Demos/Avatar/doc/index.en-US.md
Normal file
7
site/AntBlazor.Docs/Demos/Avatar/doc/index.en-US.md
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
category: Components
|
||||
type: Data Display
|
||||
title: Avatar
|
||||
---
|
||||
|
||||
Avatars can be used to represent people or objects. It supports images, `Icon`s, or letters.
|
8
site/AntBlazor.Docs/Demos/Avatar/doc/index.zh-CN.md
Normal file
8
site/AntBlazor.Docs/Demos/Avatar/doc/index.zh-CN.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
category: Components
|
||||
subtitle: 头像
|
||||
type: 数据展示
|
||||
title: Avatar
|
||||
---
|
||||
|
||||
用来代表用户或事物,支持图片、图标或字符展示。
|
15
site/AntBlazor.Docs/Demos/Badge/demo/Basic.razor
Normal file
15
site/AntBlazor.Docs/Demos/Badge/demo/Basic.razor
Normal file
@ -0,0 +1,15 @@
|
||||
<div>
|
||||
<AntBadge Count="5">
|
||||
<a href="#" class="head-example" />
|
||||
</AntBadge>
|
||||
<AntBadge Count="0" ShowZero>
|
||||
<a href="#" class="head-example" />
|
||||
</AntBadge>
|
||||
@{
|
||||
RenderFragment count = @<AntIcon Type="clock-circle" Fill="#f5222d"/>;
|
||||
}
|
||||
<AntBadge Count="@(count)">
|
||||
<a href="#" class="head-example" />
|
||||
</AntBadge>
|
||||
</div>
|
||||
|
45
site/AntBlazor.Docs/Demos/Badge/demo/Change.razor
Normal file
45
site/AntBlazor.Docs/Demos/Badge/demo/Change.razor
Normal file
@ -0,0 +1,45 @@
|
||||
<div>
|
||||
<div>
|
||||
<AntBadge Count="@count">
|
||||
<a href="#" class="head-example" />
|
||||
</AntBadge>
|
||||
<AntButtonGroup>
|
||||
<AntButton @onclick="_=>decline()">
|
||||
<AntIcon Type="minus"></AntIcon>
|
||||
</AntButton>
|
||||
<AntButton @onclick="_=>increase()">
|
||||
<AntIcon Type="plus"></AntIcon>
|
||||
</AntButton>
|
||||
</AntButtonGroup>
|
||||
</div>
|
||||
<div style="margin-top: 10px">
|
||||
<AntBadge Dot="@show">
|
||||
<a href="#" class="head-example" />
|
||||
</AntBadge>
|
||||
<AntSwitch OnChange="onChange" Checked="@show" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
int count = 5;
|
||||
bool show = true;
|
||||
|
||||
void increase()
|
||||
{
|
||||
count++;
|
||||
}
|
||||
|
||||
void decline()
|
||||
{
|
||||
count--;
|
||||
if (count < 0)
|
||||
{
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void onChange(bool show)
|
||||
{
|
||||
this.show = show;
|
||||
}
|
||||
}
|
47
site/AntBlazor.Docs/Demos/Badge/demo/Colorful.razor
Normal file
47
site/AntBlazor.Docs/Demos/Badge/demo/Colorful.razor
Normal file
@ -0,0 +1,47 @@
|
||||
<div>
|
||||
<h4 style="margin-bottom: 16px">Presets:</h4>
|
||||
<div>
|
||||
@foreach (var color in colors)
|
||||
{
|
||||
<div key="@color">
|
||||
<AntBadge Color="@color" Text="@color" />
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<h4 style="margin:16px 0;">Custom:</h4>
|
||||
<div>
|
||||
<AntBadge Color="#f50" Text="#f50" />
|
||||
<br />
|
||||
<AntBadge Color="#2db7f5" Text="#2db7f5" />
|
||||
<br />
|
||||
<AntBadge Color="#87d068" Text="#87d068" />
|
||||
<br />
|
||||
<AntBadge Color="#108ee9" Text="#108ee9" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.ant-tag {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@code
|
||||
{
|
||||
string[] colors =
|
||||
{
|
||||
"pink",
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"cyan",
|
||||
"green",
|
||||
"blue",
|
||||
"purple",
|
||||
"geekblue",
|
||||
"magenta",
|
||||
"volcano",
|
||||
"gold",
|
||||
"lime",
|
||||
};
|
||||
}
|
11
site/AntBlazor.Docs/Demos/Badge/demo/Dot.razor
Normal file
11
site/AntBlazor.Docs/Demos/Badge/demo/Dot.razor
Normal file
@ -0,0 +1,11 @@
|
||||
<div>
|
||||
<AntBadge Dot>
|
||||
<AntIcon Type="notification"/>
|
||||
</AntBadge>
|
||||
<AntBadge Count="0" Dot>
|
||||
<AntIcon Type="notification" />
|
||||
</AntBadge>
|
||||
<AntBadge Dot>
|
||||
<a href="#">Link something</a>
|
||||
</AntBadge>
|
||||
</div>
|
5
site/AntBlazor.Docs/Demos/Badge/demo/Link.razor
Normal file
5
site/AntBlazor.Docs/Demos/Badge/demo/Link.razor
Normal file
@ -0,0 +1,5 @@
|
||||
<a href="#">
|
||||
<AntBadge Count="5">
|
||||
<span class="head-example" />
|
||||
</AntBadge>
|
||||
</a>
|
13
site/AntBlazor.Docs/Demos/Badge/demo/No_wrapper.razor
Normal file
13
site/AntBlazor.Docs/Demos/Badge/demo/No_wrapper.razor
Normal file
@ -0,0 +1,13 @@
|
||||
<div>
|
||||
<AntBadge Count="25" />
|
||||
<AntBadge Count="4" Class="site-badge-count-4" />
|
||||
<AntBadge Class="site-badge-count-109" Count="109" Style="background-color: #52c41a" />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.site-badge-count-4 .ant-badge-count {
|
||||
background-color: #fff;
|
||||
color: #999;
|
||||
box-shadow: 0 0 0 1px #d9d9d9 inset;
|
||||
}
|
||||
</style>
|
14
site/AntBlazor.Docs/Demos/Badge/demo/Overflow.razor
Normal file
14
site/AntBlazor.Docs/Demos/Badge/demo/Overflow.razor
Normal file
@ -0,0 +1,14 @@
|
||||
<div>
|
||||
<AntBadge Count="99">
|
||||
<a href="#" class="head-example" />
|
||||
</AntBadge>
|
||||
<AntBadge Count="100">
|
||||
<a href="#" class="head-example" />
|
||||
</AntBadge>
|
||||
<AntBadge Count="99" OverflowCount="10">
|
||||
<a href="#" class="head-example" />
|
||||
</AntBadge>
|
||||
<AntBadge Count="1000" OverflowCount="999">
|
||||
<a href="#" class="head-example" />
|
||||
</AntBadge>
|
||||
</div>
|
17
site/AntBlazor.Docs/Demos/Badge/demo/Status.razor
Normal file
17
site/AntBlazor.Docs/Demos/Badge/demo/Status.razor
Normal file
@ -0,0 +1,17 @@
|
||||
<div>
|
||||
<AntBadge Status="success" />
|
||||
<AntBadge Status="error" />
|
||||
<AntBadge Status="default" />
|
||||
<AntBadge Status="processing" />
|
||||
<AntBadge Status="warning" />
|
||||
<br />
|
||||
<AntBadge Status="success" Text="Success" />
|
||||
<br />
|
||||
<AntBadge Status="error" Text="Error" />
|
||||
<br />
|
||||
<AntBadge Status="default" Text="Default" />
|
||||
<br />
|
||||
<AntBadge Status="processing" Text="Processing" />
|
||||
<br />
|
||||
<AntBadge Status="warning" Text="Warning" />
|
||||
</div>
|
5
site/AntBlazor.Docs/Demos/Badge/demo/Title.razor
Normal file
5
site/AntBlazor.Docs/Demos/Badge/demo/Title.razor
Normal file
@ -0,0 +1,5 @@
|
||||
<div>
|
||||
<AntBadge Count="5" Title="Custom hover text">
|
||||
<a href="#" class="head-example" />
|
||||
</AntBadge>
|
||||
</div>
|
35
site/AntBlazor.Docs/Demos/Badge/demo/basic.md
Normal file
35
site/AntBlazor.Docs/Demos/Badge/demo/basic.md
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
order: 0
|
||||
title:
|
||||
zh-CN: 基本
|
||||
en-US: Basic
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
简单的徽章展示,当 `count` 为 `0` 时,默认不显示,但是可以使用 `showZero` 修改为显示。
|
||||
|
||||
## en-US
|
||||
|
||||
Simplest Usage. Badge will be hidden when `count` is `0`, but we can use `showZero` to show it.
|
||||
|
||||
<style>
|
||||
.ant-badge:not(.ant-badge-not-a-wrapper) {
|
||||
margin-right: 20px;
|
||||
}
|
||||
.ant-badge.ant-badge-rtl:not(.ant-badge-not-a-wrapper) {
|
||||
margin-right: 0;
|
||||
margin-left: 20px;
|
||||
}
|
||||
.head-example {
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
border-radius: 2px;
|
||||
background: #eee;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
[data-theme="dark"] .head-example {
|
||||
background: rgba(255,255,255,.12);
|
||||
}
|
||||
</style>
|
15
site/AntBlazor.Docs/Demos/Badge/demo/change.md
Normal file
15
site/AntBlazor.Docs/Demos/Badge/demo/change.md
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
order: 4
|
||||
title:
|
||||
zh-CN: 动态
|
||||
en-US: Dynamic
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
展示动态变化的效果。
|
||||
|
||||
## en-US
|
||||
|
||||
The count will be animated as it changes.
|
||||
|
14
site/AntBlazor.Docs/Demos/Badge/demo/colorful.md
Normal file
14
site/AntBlazor.Docs/Demos/Badge/demo/colorful.md
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
order: 8
|
||||
title:
|
||||
zh-CN: 多彩徽标
|
||||
en-US: Colorful Badge
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
我们添加了多种预设色彩的徽标样式,用作不同场景使用。如果预设值不能满足你的需求,可以设置为具体的色值。
|
||||
|
||||
## en-US
|
||||
|
||||
We preset a series of colorful Badge styles for use in different situations. You can also set it to a hex color string for custom color.
|
23
site/AntBlazor.Docs/Demos/Badge/demo/dot.md
Normal file
23
site/AntBlazor.Docs/Demos/Badge/demo/dot.md
Normal file
@ -0,0 +1,23 @@
|
||||
---
|
||||
order: 3
|
||||
title:
|
||||
zh-CN: 讨嫌的小红点
|
||||
en-US: Red badge
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
没有具体的数字。
|
||||
|
||||
## en-US
|
||||
|
||||
This will simply display a red badge, without a specific count. If count equals 0, it won't display the dot.
|
||||
|
||||
<style>
|
||||
.anticon-notification {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
14
site/AntBlazor.Docs/Demos/Badge/demo/link.md
Normal file
14
site/AntBlazor.Docs/Demos/Badge/demo/link.md
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
order: 3
|
||||
title:
|
||||
zh-CN: 可点击
|
||||
en-US: Clickable
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
用 a 标签进行包裹即可。
|
||||
|
||||
## en-US
|
||||
|
||||
The badge can be wrapped with `a` tag to make it linkable.
|
30
site/AntBlazor.Docs/Demos/Badge/demo/no_wrapper.md
Normal file
30
site/AntBlazor.Docs/Demos/Badge/demo/no_wrapper.md
Normal file
@ -0,0 +1,30 @@
|
||||
---
|
||||
order: 1
|
||||
title:
|
||||
zh-CN: 独立使用
|
||||
en-US: Standalone
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
不包裹任何元素即是独立使用,可自定样式展现。
|
||||
|
||||
> 在右上角的 badge 则限定为红色。
|
||||
|
||||
## en-US
|
||||
|
||||
Used in standalone when children is empty.
|
||||
|
||||
<style>
|
||||
.ant-badge-not-a-wrapper:not(.ant-badge-status) {
|
||||
margin-right: 8px;
|
||||
}
|
||||
.ant-badge.ant-badge-rtl:not(.ant-badge-not-a-wrapper) {
|
||||
margin-right: 0;
|
||||
margin-left: 20px;
|
||||
}
|
||||
[data-theme="dark"] .site-badge-count-4 .ant-badge-count {
|
||||
background-color: #141414;
|
||||
box-shadow: 0 0 0 1px #434343 inset;
|
||||
}
|
||||
</style>
|
15
site/AntBlazor.Docs/Demos/Badge/demo/overflow.md
Normal file
15
site/AntBlazor.Docs/Demos/Badge/demo/overflow.md
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
order: 2
|
||||
title:
|
||||
zh-CN: 封顶数字
|
||||
en-US: Overflow Count
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
超过 `overflowCount` 的会显示为 `${overflowCount}+`,默认的 `overflowCount` 为 `99`。
|
||||
|
||||
## en-US
|
||||
|
||||
`${overflowCount}+` is displayed when count is larger than `overflowCount`. The default value of `overflowCount` is `99`.
|
||||
|
15
site/AntBlazor.Docs/Demos/Badge/demo/status.md
Normal file
15
site/AntBlazor.Docs/Demos/Badge/demo/status.md
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
order: 6
|
||||
title:
|
||||
zh-CN: 状态点
|
||||
en-US: Status
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
用于表示状态的小圆点。
|
||||
|
||||
## en-US
|
||||
|
||||
Standalone badge with status.
|
||||
|
37
site/AntBlazor.Docs/Demos/Badge/demo/title.md
Normal file
37
site/AntBlazor.Docs/Demos/Badge/demo/title.md
Normal file
@ -0,0 +1,37 @@
|
||||
---
|
||||
order: 100
|
||||
title:
|
||||
zh-CN: 自定义标题
|
||||
en-US: Title
|
||||
debug: true
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
设置鼠标放在状态点上时显示的文字。
|
||||
|
||||
## en-US
|
||||
|
||||
The badge will display `title` when hovered over, instead of `count`.
|
||||
|
||||
<style>
|
||||
.ant-badge:not(.ant-badge-not-a-wrapper) {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.ant-badge.ant-badge-rtl:not(.ant-badge-not-a-wrapper) {
|
||||
margin-right: 0;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.head-example {
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
border-radius: 2px;
|
||||
background: #eee;
|
||||
display: inline-block;
|
||||
}
|
||||
[data-theme="dark"] .head-example {
|
||||
background: rgba(255,255,255,.12);
|
||||
}
|
||||
</style>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user