mirror of
https://gitee.com/LongbowEnterprise/BootstrapBlazor.git
synced 2024-11-30 02:58:37 +08:00
feat(DriverJs): add Highlight method (#3997)
* feat: 增加 drive 方法 * refactor: 精简代码 * refactor: 移动回调方法到 Config 中 * doc: 更新示例 * feat: 增加高亮功能 * doc: 更新文档 * doc: 更新高亮示例 * chore: bump version 8.0.1
This commit is contained in:
parent
9cf3d3558c
commit
183e9a7890
@ -39,7 +39,7 @@
|
||||
<PackageReference Include="BootstrapBlazor.CodeEditor" Version="8.0.2" />
|
||||
<PackageReference Include="BootstrapBlazor.Dock" Version="8.1.7" />
|
||||
<PackageReference Include="BootstrapBlazor.DockView" Version="8.0.9" />
|
||||
<PackageReference Include="BootstrapBlazor.DriverJs" Version="8.0.0" />
|
||||
<PackageReference Include="BootstrapBlazor.DriverJs" Version="8.0.1" />
|
||||
<PackageReference Include="BootstrapBlazor.FileViewer" Version="8.0.3" />
|
||||
<PackageReference Include="BootstrapBlazor.FontAwesome" Version="8.0.5" />
|
||||
<PackageReference Include="BootstrapBlazor.Gantt" Version="8.0.1" />
|
||||
|
@ -165,7 +165,7 @@
|
||||
</DriverJs>
|
||||
</DemoBlock>
|
||||
|
||||
<DemoBlock Title="@Localizer["DriverJsDestroyTitle"]"
|
||||
<DemoBlock Title="@Localizer["DriverJsDestroyTitle"]"
|
||||
Introduction="@Localizer["DriverJsDestroyIntro"]"
|
||||
Name="Popover">
|
||||
<section ignore class="bb-guid4">
|
||||
@ -182,7 +182,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<DriverJs @ref="_guideDestroy" Config="_config" OnBeforeDestroyAsync="OnBeforeDestroyAsync" OnDestroyedAsync="OnDestroyedAsync">
|
||||
<DriverJs @ref="_guideDestroy" Config="_configDestroy">
|
||||
<DriverJsStep Selector=".bb-title">
|
||||
<DriverJsPopover Title="@Localizer["DriverJsPopoverTitleText"]" Description="@Localizer["DriverJsPopoverContentText2"]" Side="bottom" Align="center"></DriverJsPopover>
|
||||
</DriverJsStep>
|
||||
@ -198,3 +198,22 @@
|
||||
</DriverJs>
|
||||
<ConsoleLogger @ref="_logger"></ConsoleLogger>
|
||||
</DemoBlock>
|
||||
|
||||
<DemoBlock Title="@Localizer["DriverJsHighlightTitle"]"
|
||||
Introduction="@Localizer["DriverJsHighlightIntro"]"
|
||||
Name="Highlight">
|
||||
<section ignore class="bb-guid5">
|
||||
<div class="row g-2">
|
||||
<div class="col-12 col-sm-6">
|
||||
<BootstrapInputGroup>
|
||||
<BootstrapInput TValue="string"></BootstrapInput>
|
||||
<Button Icon="fa-solid fa-magnifying-glass"></Button>
|
||||
</BootstrapInputGroup>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<Button OnClickWithoutRender="OnStartHighlight" Text="Start" class="btn-guide"></Button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<DriverJs @ref="_guideHighlight"></DriverJs>
|
||||
</DemoBlock>
|
||||
|
@ -13,9 +13,11 @@ public partial class DriverDotnetJs
|
||||
private DriverJs _guidePopover = default!;
|
||||
private DriverJs _guidePopoverStyle = default!;
|
||||
private DriverJs _guideDestroy = default!;
|
||||
private DriverJs _guideHighlight = default!;
|
||||
private DriverJsConfig _config = default!;
|
||||
private DriverJsConfig _configPopover = default!;
|
||||
private DriverJsConfig _configPopoverStyle = default!;
|
||||
private DriverJsConfig _configDestroy = default!;
|
||||
private ConsoleLogger _logger = default!;
|
||||
|
||||
/// <summary>
|
||||
@ -37,6 +39,11 @@ public partial class DriverDotnetJs
|
||||
{
|
||||
PopoverClass = "driverjs-theme"
|
||||
};
|
||||
_configDestroy = new()
|
||||
{
|
||||
OnDestroyStartedAsync = OnBeforeDestroyAsync,
|
||||
OnDestroyedAsync = OnDestroyedAsync
|
||||
};
|
||||
}
|
||||
|
||||
private Task OnStart() => _guide.Start();
|
||||
@ -64,4 +71,20 @@ public partial class DriverDotnetJs
|
||||
_logger.Log("Trigger OnDestroyedAsync");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task OnStartHighlight()
|
||||
{
|
||||
var config = new DriverJsConfig
|
||||
{
|
||||
StagePadding = 20f
|
||||
};
|
||||
var popover = new DriverJsHighlightPopover
|
||||
{
|
||||
Title = "Highlight Demo",
|
||||
Description = "This is a highlight demo",
|
||||
Align = "center",
|
||||
Side = "bottom"
|
||||
};
|
||||
await _guideHighlight.Highlight(config, ".bb-guid5 .col-12", popover);
|
||||
}
|
||||
}
|
||||
|
@ -6587,7 +6587,9 @@
|
||||
"DriverJsPopoverStyleIntro": "By setting <code>PopoverClass=\"driverjs-theme\"</code> custome the popover UI",
|
||||
"DriverJsDestroyTitle": "Destroy callback",
|
||||
"DriverJsDestroyIntro": "Callback method before destruction <code>OnBeforeDestroyAsync</code> or callback method for destruction <code>OnDestroyedAsync</code>",
|
||||
"DriverJsDestroyDesc": "You can use the <code>OnBeforeDestroyAsync</code> callback to add some logic when the user tries to exit the tour. Prevent destruction when the callback method <code>OnBeforeDestroyAsync</code> returns not <code>NULL</code> string. You can also prevent the user from exiting the tour using <code>AllowClose</code> option. This option is useful when you want to force the user to complete the tour before they can exit."
|
||||
"DriverJsDestroyDesc": "You can use the <code>OnBeforeDestroyAsync</code> callback to add some logic when the user tries to exit the tour. Prevent destruction when the callback method <code>OnBeforeDestroyAsync</code> returns not <code>NULL</code> string. You can also prevent the user from exiting the tour using <code>AllowClose</code> option. This option is useful when you want to force the user to complete the tour before they can exit.",
|
||||
"DriverJsHighlightTitle": "Highlight",
|
||||
"DriverJsHighlightIntro": "By calling the <code>DriverJs</code> component instance method <code>Highlight</code>, the specified element is highlighted and focused."
|
||||
},
|
||||
"BootstrapBlazor.Server.Components.Samples.IntersectionObservers": {
|
||||
"IntersectionObserverTitle": "IntersectionObserver",
|
||||
|
@ -6587,7 +6587,9 @@
|
||||
"DriverJsPopoverStyleIntro": "通过设置 <code>PopoverClass=\"driverjs-theme\"</code> 通过自定义样式 <code>driverjs-theme</code> 设置弹窗 UI",
|
||||
"DriverJsDestroyTitle": "销毁回调方法",
|
||||
"DriverJsDestroyIntro": "销毁前回调方法 <code>OnBeforeDestroyAsync</code> 或者销毁回调方法 <code>OnDestroyedAsync</code>",
|
||||
"DriverJsDestroyDesc": "当用户尝试退出游览时,可以使用 <code>OnBeforeDestroyAsync</code> 回调添加销毁前逻辑,返回 <b>非空字符串</b> 时客户端弹窗二次确认是否阻止销毁;可通过设置 <code>AllowClose</code> 阻止用户退出向导"
|
||||
"DriverJsDestroyDesc": "当用户尝试退出游览时,可以使用 <code>OnBeforeDestroyAsync</code> 回调添加销毁前逻辑,返回 <b>非空字符串</b> 时客户端弹窗二次确认是否阻止销毁;可通过设置 <code>AllowClose</code> 阻止用户退出向导",
|
||||
"DriverJsHighlightTitle": "高亮显示",
|
||||
"DriverJsHighlightIntro": "通过调用 <code>DriverJs</code> 组件实例方法 <code>Highlight</code> 使指定元素高亮聚焦显示"
|
||||
},
|
||||
"BootstrapBlazor.Server.Components.Samples.IntersectionObservers": {
|
||||
"IntersectionObserverTitle": "IntersectionObserver 交叉观察器",
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
|
||||
<PropertyGroup>
|
||||
<Version>8.0.0</Version>
|
||||
<Version>8.0.1</Version>
|
||||
<RootNamespace>BootstrapBlazor.Components</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -21,18 +21,6 @@ public partial class DriverJs
|
||||
[Parameter]
|
||||
public DriverJsConfig? Config { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 组件销毁前回调方法 返回 false 时阻止销毁
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<DriverJsConfig, int, Task<string?>>? OnBeforeDestroyAsync { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 组件销毁回调方法
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<Task>? OnDestroyedAsync { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 子组件内容
|
||||
/// </summary>
|
||||
@ -60,15 +48,6 @@ public partial class DriverJs
|
||||
Config.Steps = _steps;
|
||||
Config.ProgressText ??= Localizer[nameof(Config.ProgressText)];
|
||||
|
||||
if (OnBeforeDestroyAsync != null)
|
||||
{
|
||||
Config.OnDestroyStartedAsync = nameof(OnBeforeDestroy);
|
||||
}
|
||||
if (OnBeforeDestroyAsync != null)
|
||||
{
|
||||
Config.OnDestroyedAsync = nameof(OnDestroyed);
|
||||
}
|
||||
|
||||
await InvokeVoidAsync("start", Id, Config, new
|
||||
{
|
||||
AutoDrive,
|
||||
@ -77,18 +56,17 @@ public partial class DriverJs
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 组件销毁前回调方法由 JavaScript 调用 返回 false 阻止销毁
|
||||
/// 组件销毁前回调方法由 JavaScript 调用 返回 非空字符串时客户端 confirm 确认弹窗
|
||||
/// </summary>
|
||||
[JSInvokable]
|
||||
public async Task<string?> OnBeforeDestroy(int index)
|
||||
{
|
||||
string? ret = null;
|
||||
if (OnBeforeDestroyAsync != null)
|
||||
{
|
||||
// Config 不为空
|
||||
ret = await OnBeforeDestroyAsync(Config!, index);
|
||||
}
|
||||
|
||||
if (Config?.OnDestroyStartedAsync != null)
|
||||
{
|
||||
ret = await Config.OnDestroyStartedAsync(Config, index);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -99,9 +77,9 @@ public partial class DriverJs
|
||||
[JSInvokable]
|
||||
public async Task OnDestroyed()
|
||||
{
|
||||
if (OnDestroyedAsync != null)
|
||||
if (Config?.OnDestroyedAsync != null)
|
||||
{
|
||||
await OnDestroyedAsync();
|
||||
await Config.OnDestroyedAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,8 +185,17 @@ public partial class DriverJs
|
||||
/// <summary>
|
||||
/// Look at the DriveStep section of configuration for format of the step
|
||||
/// </summary>
|
||||
/// <param name="config"><see cref="DriverJsConfig"/> 实例</param>
|
||||
/// <param name="selector">target selector</param>
|
||||
/// <param name="popover"><see cref="DriverJsHighlightPopover"/> 实例</param>
|
||||
/// <returns></returns>
|
||||
public Task Highlight() => InvokeVoidAsync("highlight", Id);
|
||||
public async Task Highlight(DriverJsConfig config, string? selector, DriverJsHighlightPopover popover)
|
||||
{
|
||||
config ??= new();
|
||||
config.ProgressText ??= Localizer[nameof(Config.ProgressText)];
|
||||
|
||||
await InvokeVoidAsync("highlight", Id, config, new { element = selector, popover });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加步骤方法
|
||||
|
@ -18,18 +18,20 @@ export function start(id, options, config) {
|
||||
if (d) {
|
||||
d.config = config;
|
||||
const { autoDrive, index } = config;
|
||||
const { onDestroyStartedAsync, onDestroyedAsync } = options;
|
||||
if (onDestroyStartedAsync) {
|
||||
const { hookDestroyStarted, hookDestroyed } = options;
|
||||
if (hookDestroyStarted) {
|
||||
delete options.hookDestroyStarted;
|
||||
options.onDestroyStarted = async (el, step, { state }) => {
|
||||
const content = await d.invoke.invokeMethodAsync(onDestroyStartedAsync, state.activeIndex);
|
||||
const content = await d.invoke.invokeMethodAsync("OnBeforeDestroy", state.activeIndex);
|
||||
if (content === null || confirm(content)) {
|
||||
d.driver.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (onDestroyedAsync) {
|
||||
if (hookDestroyed) {
|
||||
delete options.hookDestroyed;
|
||||
options.onDestroyed = () => {
|
||||
d.invoke.invokeMethodAsync(onDestroyedAsync);
|
||||
d.invoke.invokeMethodAsync("OnDestroyed");
|
||||
};
|
||||
}
|
||||
const driverObj = driver(options);
|
||||
@ -50,6 +52,13 @@ export function dispose(id) {
|
||||
}
|
||||
}
|
||||
|
||||
export function drive(id, index = 0) {
|
||||
const d = Data.get(id);
|
||||
if (d) {
|
||||
d.driver.drive(index);
|
||||
}
|
||||
}
|
||||
|
||||
export function moveNext(id) {
|
||||
const d = Data.get(id);
|
||||
if (d) {
|
||||
@ -131,3 +140,8 @@ export function refresh(id) {
|
||||
d.driver.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
export function highlight(id, options, config) {
|
||||
const driverObj = driver(options);
|
||||
driverObj.highlight(config);
|
||||
}
|
||||
|
@ -125,15 +125,21 @@ public class DriverJsConfig
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? DoneBtnText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 组件销毁前回调方法名称
|
||||
/// </summary>
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull), JsonInclude]
|
||||
internal string? OnDestroyStartedAsync { get; set; }
|
||||
[JsonInclude]
|
||||
private bool HookDestroyStarted => OnDestroyStartedAsync != null;
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 组件销毁前回调方法名称
|
||||
/// </summary>
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull), JsonInclude]
|
||||
internal string? OnDestroyedAsync { get; set; }
|
||||
[JsonIgnore]
|
||||
public Func<DriverJsConfig, int, Task<string?>>? OnDestroyStartedAsync { get; set; }
|
||||
|
||||
[JsonInclude]
|
||||
private bool HookDestroyed => OnDestroyedAsync != null;
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 组件销毁前回调方法名称
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public Func<Task>? OnDestroyedAsync { get; set; }
|
||||
}
|
||||
|
@ -66,13 +66,13 @@ public class DriverJsStep : ComponentBase, IDisposable
|
||||
/// <param name="builder"></param>
|
||||
protected override void BuildRenderTree(RenderTreeBuilder builder)
|
||||
{
|
||||
_popover ??= new InternalDriverJsPopover()
|
||||
_popover ??= new DriverJsHighlightPopover()
|
||||
{
|
||||
Title = Title,
|
||||
Description = Description,
|
||||
PrevBtnText = Localizer[nameof(InternalDriverJsPopover.PrevBtnText)],
|
||||
NextBtnText = Localizer[nameof(InternalDriverJsPopover.NextBtnText)],
|
||||
DoneBtnText = Localizer[nameof(InternalDriverJsPopover.DoneBtnText)]
|
||||
PrevBtnText = Localizer[nameof(DriverJsHighlightPopover.PrevBtnText)],
|
||||
NextBtnText = Localizer[nameof(DriverJsHighlightPopover.NextBtnText)],
|
||||
DoneBtnText = Localizer[nameof(DriverJsHighlightPopover.DoneBtnText)]
|
||||
};
|
||||
builder.OpenComponent<CascadingValue<DriverJsStep>>(0);
|
||||
builder.AddAttribute(1, nameof(CascadingValue<DriverJsStep>.Value), this);
|
||||
@ -106,45 +106,4 @@ public class DriverJsStep : ComponentBase, IDisposable
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// The popover configuration for this step.
|
||||
///// </summary>
|
||||
//public FocusGuidePopover? Popover { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// Callback when the current step is deselected
|
||||
///// </summary>
|
||||
///// <param name="step"></param>
|
||||
///// <param name="config"></param>
|
||||
///// <param name="state"></param>
|
||||
///// <returns></returns>
|
||||
//public Task OnDeselected(FocusGuideStep step, FocusGuideConfig config, FocusGuideState state)
|
||||
//{
|
||||
// return Task.CompletedTask;
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
/////
|
||||
///// </summary>
|
||||
///// <param name="step"></param>
|
||||
///// <param name="config"></param>
|
||||
///// <param name="state"></param>
|
||||
///// <returns></returns>
|
||||
//public Task OnHighlightStarted(FocusGuideStep step, FocusGuideConfig config, FocusGuideState state)
|
||||
//{
|
||||
// return Task.CompletedTask;
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
/////
|
||||
///// </summary>
|
||||
///// <param name="step"></param>
|
||||
///// <param name="config"></param>
|
||||
///// <param name="state"></param>
|
||||
///// <returns></returns>
|
||||
//public Task OnHighlighted(FocusGuideStep step, FocusGuideConfig config, FocusGuideState state)
|
||||
//{
|
||||
// return Task.CompletedTask;
|
||||
//}
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
// Website: https://www.blazor.zone or https://argozhang.github.io/
|
||||
|
||||
namespace BootstrapBlazor.Components;
|
||||
|
||||
internal class InternalDriverJsPopover : IDriverJsPopover
|
||||
{
|
||||
public string? Title { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public string? Side { get; set; }
|
||||
public string? Align { get; set; }
|
||||
public List<string>? ShowButtons { get; set; }
|
||||
public List<string>? DisableButtons { get; set; }
|
||||
public string? NextBtnText { get; set; }
|
||||
public string? PrevBtnText { get; set; }
|
||||
public string? DoneBtnText { get; set; }
|
||||
public bool? ShowProgress { get; set; }
|
||||
public string? ProgressText { get; set; }
|
||||
public string? PopoverClass { get; set; }
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
// Website: https://www.blazor.zone or https://argozhang.github.io/
|
||||
|
||||
namespace BootstrapBlazor.Components;
|
||||
|
||||
/// <summary>
|
||||
/// DriverJsHighlightPopover 实例
|
||||
/// </summary>
|
||||
public class DriverJsHighlightPopover : IDriverJsPopover
|
||||
{
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public string? Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public string? Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Side { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Align { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public List<string>? ShowButtons { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public List<string>? DisableButtons { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? NextBtnText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? PrevBtnText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? DoneBtnText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public bool? ShowProgress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? ProgressText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? PopoverClass { get; set; }
|
||||
}
|
Loading…
Reference in New Issue
Block a user