!3639 doc(#I672HV): update Ajax demo

* refactor: 更新触发逻辑
* doc: 格式化代码
* feat: 增加按钮脚本逻辑
* chore: 更新 DemoBlock 样式
* feat: 页脚代码块增加显示 Toolbar 设置
* feat: Pre 组件增加按钮工具栏
* feat: Pre 组件增加 ShowToolbar 参数用户控制是否显示工具栏
* refactor: 更新命名空间顺序
* doc: 增加 User 类
* Merge branch 'main' into doc/site
* Merge branch 'main' into doc/site
* refactor: 改用 BBLogo 统一设置
* feat: 增加 BBLogo 组件
* doc: 更新 ajax 改造示例
* feat: 基础组件 DemoBlock/Pre 支持获取代码片段新方式
* feat: 实现通过 Demo 参数获取源码逻辑
* feat: 增加 Converter 负责讲配置名字转化为 Type
This commit is contained in:
Argo 2022-12-22 10:41:13 +00:00
parent a5f6173a0d
commit fb9539180e
10 changed files with 181 additions and 34 deletions

View File

@ -14,7 +14,7 @@
{
<div class="card-footer">
<div class="card-footer-code collapse" id="@Id">
<Pre @key="@RazorFileName" CodeFile="@RazorFileName" BlockTitle="@BlockTitle" Demo="@Demo"></Pre>
<Pre @key="@RazorFileName" CodeFile="@RazorFileName" BlockTitle="@BlockTitle" Demo="@Demo" ShowToolbar="true"></Pre>
</div>
<a class="card-footer-control collapsed" href="#@Id" data-bs-toggle="collapse" role="button" aria-label="show code">
<i class="fa-solid fa-caret-up"></i>

View File

@ -24,28 +24,28 @@
background-color: transparent;
}
.card-footer .card-footer-code {
margin: -.5rem -1rem 0 -1rem;
border-bottom: 1px solid rgba(0, 0, 0, 0.125);
.card-footer-code {
margin: -.5rem -1rem 0 -1rem;
border-bottom: 1px solid rgba(0, 0, 0, 0.125);
}
.card-footer-code.show + a {
margin-top: .5rem;
}
.card-footer .card-footer-code.show + a {
margin-top: .5rem;
}
.card-footer .card-footer-code .loading {
padding: .5rem;
}
.card-footer .card-footer-code ::deep code {
border: none;
}
.card-footer ::deep pre {
color: #e83e8c;
margin-bottom: 0;
.card-footer-code .loading {
padding: .5rem;
}
.card-footer-code ::deep code {
border: none;
}
::deep pre {
color: #e83e8c;
margin-bottom: 0;
}
.card-footer-control {
text-align: center;
color: #d3dce6;
@ -71,11 +71,11 @@
}
.card-footer-control .card-text:before {
content: "隐藏代码";
content: "Hide";
opacity: 0;
transition: opacity .3s linear;
}
.card-footer-control.collapsed .card-text:before {
content: "显示代码";
content: "Show";
}

View File

@ -8,10 +8,17 @@
}
else
{
<pre><code>@ChildContent</code></pre>
<pre style="max-height: 260px;"><code>@ChildContent</code></pre>
@if (ShowToolbar)
{
<div class="btn-group">
<Button TooltipPlacement="Placement.Top" TooltipText="@PlusTooltipTitle" TooltipTrigger="hover" Icon="fa-solid fa-plus" class="btn-plus"></Button>
<Button TooltipPlacement="Placement.Top" TooltipText="@MinusTooltipTitle" TooltipTrigger="hover" Icon="fa-solid fa-minus" class="btn-minus"></Button>
</div>
}
@if (CanCopy)
{
<Button TooltipPlacement="Placement.Left" TooltipText="@TooltipTitle">Copy</Button>
<Button TooltipPlacement="Placement.Top" TooltipText="@TooltipTitle" TooltipTrigger="hover" class="btn-copy">Copy</Button>
}
}
</div>

View File

@ -52,6 +52,12 @@ public partial class Pre
[Parameter]
public string? Demo { get; set; }
/// <summary>
/// 获得/设置 是否显示工具按钮组
/// </summary>
[Parameter]
public bool ShowToolbar { get; set; }
[Inject]
[NotNull]
private IStringLocalizer<Pre>? Localizer { get; set; }
@ -60,6 +66,10 @@ public partial class Pre
private string? TooltipTitle { get; set; }
private string? PlusTooltipTitle { get; set; }
private string? MinusTooltipTitle { get; set; }
private string? CopiedText { get; set; }
/// <summary>
@ -90,6 +100,8 @@ public partial class Pre
LoadingText ??= Localizer[nameof(LoadingText)];
TooltipTitle ??= Localizer[nameof(TooltipTitle)];
PlusTooltipTitle ??= Localizer[nameof(PlusTooltipTitle)];
MinusTooltipTitle ??= Localizer[nameof(MinusTooltipTitle)];
CopiedText ??= Localizer[nameof(CopiedText)];
}

View File

@ -5,7 +5,7 @@
::deep .btn-primary {
position: absolute;
top: .65rem;
right: .65rem;
right: 1.5rem;
font-size: 65%;
--bs-btn-color: var(--bs-primary);
--bs-btn-bg: #fff;
@ -13,8 +13,14 @@
--bs-btn-padding-x: .5rem;
}
::deep .btn-primary:hover {
--bs-btn-hover-color: #fff;
::deep .btn-group {
position: absolute;
top: 0;
right: 3rem;
}
::deep .btn-group .btn-primary {
position: relative;
}
code {

View File

@ -0,0 +1,94 @@
@using BootstrapBlazor.Components
@using System.Text.Json
<div class="my-2">
<b>特别注意:</b>
</div>
<div>这里只是进行了登录模拟,并没有真正的调用 <code>HttpContext.SignInAsync</code>,真实使用时需要在登录完成后对页面进行刷新,否则无法真正的登录成功。</div>
<div class="mb-3"><code>@ResultMessage</code></div>
<Button OnClick="Success">登录成功</Button>
<Button OnClick="Fail">登录失败</Button>
@code
{
private string? ResultMessage { get; set; }
[Inject]
[NotNull]
private AjaxService? AjaxService { get; set; }
[Inject]
[NotNull]
private SwalService? SwalService { get; set; }
private async Task Success()
{
var option = new AjaxOption
{
Url = "/api/Login",
Data = new User() { UserName = "admin", Password = "123456" }
};
var result = await AjaxService.InvokeAsync(option);
if (result == null)
{
ResultMessage = "响应失败";
}
else
{
ResultMessage = result;
var doc = JsonDocument.Parse(result);
if (200 == doc.RootElement.GetProperty("code").GetInt32())
{
await SwalService.Show(new SwalOption() { Content = "登录成功!", Category = SwalCategory.Success });
}
else
{
await SwalService.Show(new SwalOption() { Content = $"登录失败:{doc.RootElement.GetProperty("message").GetString()}", Category = SwalCategory.Error });
}
}
}
private async Task Fail()
{
var option = new AjaxOption
{
Url = "/api/Login",
Data = new User() { UserName = "admin", Password = "1234567" }
};
var result = await AjaxService.InvokeAsync(option);
if (result == null)
{
ResultMessage = "响应失败";
}
else
{
ResultMessage = result;
var doc = JsonDocument.Parse(result);
if (200 == doc.RootElement.GetProperty("code").GetInt32())
{
await SwalService.Show(new SwalOption() { Content = "登录成功!", Category = SwalCategory.Success });
}
else
{
await SwalService.Show(new SwalOption() { Content = $"登录失败:{doc.RootElement.GetProperty("message").GetString()}", Category = SwalCategory.Error });
}
}
}
/// <summary>
/// 登录模拟类
/// </summary>
class User
{
/// <summary>
/// 用户名
/// </summary>
public string? UserName { get; set; }
/// <summary>
/// 密码
/// </summary>
public string? Password { get; set; }
}
}

View File

@ -7,6 +7,8 @@
"BootstrapBlazor.Shared.Components.Pre": {
"LoadingText": "Loading ...",
"TooltipTitle": "Copy",
"PlusTooltipTitle": "Plus lines",
"MinusTooltipTitle": "Minus lines",
"CopiedText": "Copied"
},
"BootstrapBlazor.Shared.Pages.Index": {

View File

@ -7,6 +7,8 @@
"BootstrapBlazor.Shared.Components.Pre": {
"LoadingText": "正在加载 ...",
"TooltipTitle": "点击复制代码",
"PlusTooltipTitle": "点击增加显示行数",
"MinusTooltipTitle": "点击减少显示行数",
"CopiedText": "复制代码成功"
},
"BootstrapBlazor.Shared.Pages.Index": {

View File

@ -5,7 +5,7 @@
<h4>@Localizer["H4"]</h4>
<DemoBlock Introduction="@Localizer["NormalIntro"]" Title="@Localizer["NormalTitle"]" Name="Normal">
<DemoBlock Introduction="@Localizer["NormalIntro"]" Title="@Localizer["NormalTitle"]" Name="Normal" Demo="Ajax.AjaxNormal">
<p>
<b>@Localizer["NormalB"]</b>
<div>@((MarkupString)Localizer["NormalDiv"].Value)</div>
@ -16,9 +16,6 @@
Data = new User() { UserName = "admin", Password = "1234567" }
};
var result = await AjaxService.InvokeAsync(option);</Pre>
<div class="mb-3"><code>@ResultMessage</code></div>
<Button OnClick="Success">@Localizer["NormalButtonText1"]</Button>
<Button OnClick="Fail">@Localizer["NormalButtonText2"]</Button>
</DemoBlock>
<DemoBlock Introduction="@Localizer["GotoIntro"]" Title="@Localizer["GotoTitle"]" Name="Goto">

View File

@ -1,17 +1,19 @@
import BlazorComponent from "../../../_content/BootstrapBlazor/modules/base/blazor-component.js"
import EventHandler from "../../../_content/BootstrapBlazor/modules/base/event-handler.js"
import { copy, getDescribedElement, addLink, addScript } from "../../../_content/BootstrapBlazor/modules/base/utility.js"
import { copy, getDescribedElement, addLink, addScript, getHeight } from "../../../_content/BootstrapBlazor/modules/base/utility.js"
export class Pre extends BlazorComponent {
_init() {
addLink('_content/BootstrapBlazor.Shared/lib/highlight/vs.css')
addScript('_content/BootstrapBlazor.Shared/lib/highlight/highlight.min.js')
this._pre = this._element.querySelector('pre')
this._code = this._pre.querySelector('code')
this._setListeners()
}
_setListeners() {
EventHandler.on(this._element, 'click', 'button', e => {
const text = e.delegateTarget.previousElementSibling.querySelector('code').textContent;
EventHandler.on(this._element, 'click', '.btn-copy', e => {
const text = e.delegateTarget.parentNode.querySelector('code').textContent;
copy(text)
const tooltip = getDescribedElement(e.delegateTarget)
@ -19,6 +21,29 @@ export class Pre extends BlazorComponent {
tooltip.querySelector('.tooltip-inner').innerHTML = this._config.title
}
})
EventHandler.on(this._element, 'click', '.btn-plus', e => {
e.preventDefault()
e.stopPropagation();
let preHeight = getHeight(this._pre)
const codeHeight = getHeight(this._code)
if (preHeight < codeHeight) {
preHeight = Math.min(codeHeight, preHeight + 100)
}
this._pre.style.maxHeight = `${preHeight}px`
})
EventHandler.on(this._element, 'click', '.btn-minus', e => {
e.preventDefault()
e.stopPropagation();
let preHeight = getHeight(this._pre)
if (preHeight > 260) {
preHeight = Math.max(260, preHeight - 100)
}
this._pre.style.maxHeight = `${preHeight}px`
})
}
_execute(args) {
@ -55,6 +80,8 @@ export class Pre extends BlazorComponent {
_dispose() {
this._clearInterval()
EventHandler.off(this._element, 'click', 'button');
EventHandler.off(this._element, 'click', '.btn-copy')
EventHandler.off(this._element, 'click', '.btn-plus')
EventHandler.off(this._element, 'click', '.btn-minus')
}
}