diff --git a/src/BootstrapBlazor.Server/Components/Components/TooltipContent.razor b/src/BootstrapBlazor.Server/Components/Components/TooltipContent.razor new file mode 100644 index 00000000000..90ee795c511 --- /dev/null +++ b/src/BootstrapBlazor.Server/Components/Components/TooltipContent.razor @@ -0,0 +1 @@ + diff --git a/src/BootstrapBlazor.Server/Components/Components/TooltipContent.razor.cs b/src/BootstrapBlazor.Server/Components/Components/TooltipContent.razor.cs new file mode 100644 index 00000000000..3b453dc86ca --- /dev/null +++ b/src/BootstrapBlazor.Server/Components/Components/TooltipContent.razor.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the Apache 2.0 License +// See the LICENSE file in the project root for more information. +// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone + +namespace BootstrapBlazor.Server.Components.Components; + +/// +/// TooltipContent 组件用于显示 Tooltip 的内容 +/// +public partial class TooltipContent +{ + [CascadingParameter] + private Tooltip? Tooltip { get; set; } + + private async Task ToggleShow() + { + if (Tooltip == null) + { + return; + } + + await Tooltip.Toggle(); + } +} diff --git a/src/BootstrapBlazor.Server/Components/Samples/Popovers.razor b/src/BootstrapBlazor.Server/Components/Samples/Popovers.razor index 3196a4cc376..90a8c2f40dc 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Popovers.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/Popovers.razor @@ -66,4 +66,19 @@ + +
+
    +
  • @((MarkupString)Localizer["PopoversManualDescLI1"].Value)
  • +
  • @((MarkupString)Localizer["PopoversManualDescLI2"].Value)
  • +
+
+ + + + +
+ diff --git a/src/BootstrapBlazor.Server/Components/Samples/Popovers.razor.cs b/src/BootstrapBlazor.Server/Components/Samples/Popovers.razor.cs index 40c694123cd..c9a32d7ca07 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Popovers.razor.cs +++ b/src/BootstrapBlazor.Server/Components/Samples/Popovers.razor.cs @@ -18,6 +18,16 @@ public sealed partial class Popovers private string? _templateTitle; + private Popover? _popover; + + private async Task ToggleShow() + { + if (_popover != null) + { + await _popover.Toggle(); + } + } + /// /// /// diff --git a/src/BootstrapBlazor.Server/Components/Samples/Tooltips.razor b/src/BootstrapBlazor.Server/Components/Samples/Tooltips.razor index 73434013139..0f4bfad44a5 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Tooltips.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/Tooltips.razor @@ -88,4 +88,19 @@ + +
+
    +
  • @((MarkupString)Localizer["TooltipsManualDescLI1"].Value)
  • +
  • @((MarkupString)Localizer["TooltipsManualDescLI2"].Value)
  • +
+
+ + + + +
+ diff --git a/src/BootstrapBlazor.Server/Components/Samples/Tooltips.razor.cs b/src/BootstrapBlazor.Server/Components/Samples/Tooltips.razor.cs index f6392484fa3..ca0274194e4 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Tooltips.razor.cs +++ b/src/BootstrapBlazor.Server/Components/Samples/Tooltips.razor.cs @@ -20,6 +20,16 @@ public partial class Tooltips private static string HtmlString => "This is Blazor tooltip"; + private Tooltip? _tooltip; + + private async Task ToggleShow() + { + if (_tooltip != null) + { + await _tooltip.Toggle(); + } + } + /// /// 获得属性方法 /// diff --git a/src/BootstrapBlazor.Server/Locales/en-US.json b/src/BootstrapBlazor.Server/Locales/en-US.json index 78596d35a69..3f262a8381b 100644 --- a/src/BootstrapBlazor.Server/Locales/en-US.json +++ b/src/BootstrapBlazor.Server/Locales/en-US.json @@ -108,7 +108,11 @@ "TooltipsCustomClassIntro": "Set the custom style by setting the CustomClass parameter", "BootstrapTooltipIntro": "Try to make a new component that is more comfortable to use, you can use it early, the name of the component may be changed later", "BootstrapTooltipTips1": "Wrap other components or HTML elements through BootstrapTooltip so that the wrapped object has the function of Tooltip", - "BootstrapTooltipTips2": "In this example, an icon is wrapped by BootstrapTooltip. When the mouse moves over the icon, the default Tooltip is displayed, which is easier and faster to use." + "BootstrapTooltipTips2": "In this example, an icon is wrapped by BootstrapTooltip. When the mouse moves over the icon, the default Tooltip is displayed, which is easier and faster to use.", + "TooltipsManualTitle": "Manual", + "TooltipsManualIntro": "Use code to control the tooltip state by setting Trigger=\"manual\"", + "TooltipsManualDescLI1": "The child component uses the cascade parameters to get the Tooltip instance and then calls its methods Show Hide Toggle", + "TooltipsManualDescLI2": "Get the Tooltip instance through @ref and call its instances method" }, "BootstrapBlazor.Server.Components.Samples.Toasts": { "ToastsTitle": "Toast Lightweight Popup", @@ -348,7 +352,11 @@ "PopoversCssClassTitle": "custom style", "PopoversCssClassIntro": "Customize the pop-up window by setting the Popover parameter CssClass", "PopoversCssClassDescription": "set up Popover parameter CssClass=\"custom-popover\" make custom styles", - "PopoversCssClassButtonText": "Click to activate/deactivate" + "PopoversCssClassButtonText": "Click to activate/deactivate", + "PopoversManualTitle": "Manual", + "PopoversManualIntro": "Use code to control the popover state by setting Trigger=\"manual\"", + "PopoversManualDescLI1": "The child component uses the cascade parameters to get the Popover instance and then calls its methods Show Hide Toggle", + "PopoversManualDescLI2": "Get the Popover instance through @ref and call its instances method" }, "BootstrapBlazor.Server.Components.Samples.Progress": { "ProgressTitle": "Progress progress bar", diff --git a/src/BootstrapBlazor.Server/Locales/zh-CN.json b/src/BootstrapBlazor.Server/Locales/zh-CN.json index 7d7e6e3498a..53c6acca4c0 100644 --- a/src/BootstrapBlazor.Server/Locales/zh-CN.json +++ b/src/BootstrapBlazor.Server/Locales/zh-CN.json @@ -108,7 +108,11 @@ "TooltipsCustomClassIntro": "通过设置 CustomClass 参数进行自定义样式设置", "BootstrapTooltipIntro": "尝试新做一个用起来比较舒服的组件,可尝鲜使用,后期组件名字可能会更改", "BootstrapTooltipTips1": "通过 BootstrapTooltip 对其他组件或者 HTML 元素进行包裹,使其被包裹对象具有 Tooltip 功能", - "BootstrapTooltipTips2": "本例中通过 BootstrapTooltip 包裹一个图标,鼠标移动到图标上时,显示预设 Tooltip 使用更简单快捷" + "BootstrapTooltipTips2": "本例中通过 BootstrapTooltip 包裹一个图标,鼠标移动到图标上时,显示预设 Tooltip 使用更简单快捷", + "TooltipsManualTitle": "手动控制状态", + "TooltipsManualIntro": "通过设置 Trigger=\"manual\" 使用代码控制提示栏状态", + "TooltipsManualDescLI1": "子组件使用级联参数得到 Tooltip 实例,然后调用其相应方法 Show Hide Toggle", + "TooltipsManualDescLI2": "通过 @ref 获得 Tooltip 实例调用其对应方法" }, "BootstrapBlazor.Server.Components.Samples.Toasts": { "ToastsTitle": "Toast 轻量弹窗", @@ -348,7 +352,11 @@ "PopoversCssClassTitle": "自定义样式", "PopoversCssClassIntro": "通过设置 Popover 参数 CssClass 对弹窗进行自定义样式", "PopoversCssClassDescription": "设置 Popover 参数 CssClass=\"custom-popover\" 进行自定义样式", - "PopoversCssClassButtonText": "Click 激活/关闭" + "PopoversCssClassButtonText": "Click 激活/关闭", + "PopoversManualTitle": "手动控制状态", + "PopoversManualIntro": "通过设置 Trigger=\"manual\" 使用代码控制提示栏状态", + "PopoversManualDescLI1": "子组件使用级联参数得到 Popover 实例,然后调用其相应方法 Show Hide Toggle", + "PopoversManualDescLI2": "通过 @ref 获得 Popover 实例调用其对应方法" }, "BootstrapBlazor.Server.Components.Samples.Progress": { "ProgressTitle": "Progress 进度条", diff --git a/src/BootstrapBlazor/BootstrapBlazor.csproj b/src/BootstrapBlazor/BootstrapBlazor.csproj index 12f00e1294c..b444c814a51 100644 --- a/src/BootstrapBlazor/BootstrapBlazor.csproj +++ b/src/BootstrapBlazor/BootstrapBlazor.csproj @@ -1,7 +1,7 @@  - 9.9.3-beta02 + 9.9.3-beta03 diff --git a/src/BootstrapBlazor/Components/Popover/Popover.razor b/src/BootstrapBlazor/Components/Popover/Popover.razor index b2751275abc..318ac5215ef 100644 --- a/src/BootstrapBlazor/Components/Popover/Popover.razor +++ b/src/BootstrapBlazor/Components/Popover/Popover.razor @@ -4,7 +4,8 @@ diff --git a/src/BootstrapBlazor/Components/Popover/Popover.razor.cs b/src/BootstrapBlazor/Components/Popover/Popover.razor.cs index c30c51a9328..32cdc4d947c 100644 --- a/src/BootstrapBlazor/Components/Popover/Popover.razor.cs +++ b/src/BootstrapBlazor/Components/Popover/Popover.razor.cs @@ -30,10 +30,11 @@ public partial class Popover private string? _lastContent; - /// - /// - /// - protected override string? CustomClassString => CssBuilder.Default(CustomClass) + private string? ClassString => CssBuilder.Default("bb-popover") + .AddClassFromAttributes(AdditionalAttributes) + .Build(); + + private string? CustomClassString => CssBuilder.Default(CustomClass) .AddClass("shadow", ShowShadow) .Build(); diff --git a/src/BootstrapBlazor/Components/Popover/Popover.razor.js b/src/BootstrapBlazor/Components/Popover/Popover.razor.js index 6dd1bfd2339..5994ab60cbd 100644 --- a/src/BootstrapBlazor/Components/Popover/Popover.razor.js +++ b/src/BootstrapBlazor/Components/Popover/Popover.razor.js @@ -9,6 +9,42 @@ export function init(id, options) { } } +export function show(id, delay) { + const el = document.getElementById(id) + if (el) { + const pop = bootstrap.Popover.getInstance(el); + if (pop) { + setTimeout(() => { + pop.show(); + }, delay || 0); + } + } +} + +export function hide(id, delay) { + const el = document.getElementById(id) + if (el) { + const pop = bootstrap.Popover.getInstance(el); + if (pop) { + setTimeout(() => { + pop.hide(); + }, delay || 0); + } + } +} + +export function toggle(id, delay) { + const el = document.getElementById(id) + if (el) { + const pop = bootstrap.Popover.getInstance(el); + if (pop) { + setTimeout(() => { + pop.toggle(); + }, delay || 0); + } + } +} + export function dispose(id) { const el = document.getElementById(id) if (el) { diff --git a/src/BootstrapBlazor/Components/Tooltip/ITooltip.cs b/src/BootstrapBlazor/Components/Tooltip/ITooltip.cs index 8fcbcbdf2dd..8ffda90c231 100644 --- a/src/BootstrapBlazor/Components/Tooltip/ITooltip.cs +++ b/src/BootstrapBlazor/Components/Tooltip/ITooltip.cs @@ -26,8 +26,9 @@ public interface ITooltip bool IsHtml { get; set; } /// - /// 获得/设置 触发方式 可组合 click focus hover 默认为 focus hover + /// 获得/设置 触发方式 可组合 click focus hover manual 默认为 focus hover /// + /// 设置 manual 时,请使用 组件实例方法 对弹窗状态进行控制 string? Trigger { get; set; } /// @@ -39,6 +40,7 @@ public interface ITooltip /// /// 获得/设置 显示隐藏延时 默认 null /// + /// Delay showing and hiding the tooltip (ms)—doesn’t apply to manual trigger type. If a number is supplied, delay is applied to both hide/show. Object structure is: delay: { "show": 500, "hide": 100 }. string? Delay { get; set; } /// diff --git a/src/BootstrapBlazor/Components/Tooltip/Tooltip.razor b/src/BootstrapBlazor/Components/Tooltip/Tooltip.razor index f3ccbc1af45..2ff453a0a18 100644 --- a/src/BootstrapBlazor/Components/Tooltip/Tooltip.razor +++ b/src/BootstrapBlazor/Components/Tooltip/Tooltip.razor @@ -4,7 +4,7 @@ diff --git a/src/BootstrapBlazor/Components/Tooltip/Tooltip.razor.cs b/src/BootstrapBlazor/Components/Tooltip/Tooltip.razor.cs index 5999ea3625e..bcba585290e 100644 --- a/src/BootstrapBlazor/Components/Tooltip/Tooltip.razor.cs +++ b/src/BootstrapBlazor/Components/Tooltip/Tooltip.razor.cs @@ -25,10 +25,7 @@ public partial class Tooltip : ITooltip /// protected string? HtmlString => IsHtml ? "true" : null; - /// - /// component class - /// - protected string? ClassString => CssBuilder.Default() + private string? ClassString => CssBuilder.Default("bb-tooltip") .AddClassFromAttributes(AdditionalAttributes) .Build(); @@ -50,7 +47,7 @@ public partial class Tooltip : ITooltip public string? Selector { get; set; } /// - /// 获得/设置 显示内容 + /// /// [Parameter] public string? Title { get; set; } @@ -62,7 +59,7 @@ public partial class Tooltip : ITooltip public Func>? GetTitleCallback { get; set; } /// - /// 获得/设置 显示文字是否为 Html 默认为 false + /// /// [Parameter] public bool IsHtml { get; set; } @@ -74,7 +71,7 @@ public partial class Tooltip : ITooltip public bool Sanitize { get; set; } = true; /// - /// 获得/设置 位置 默认为 Placement.Top + /// /// [Parameter] public Placement Placement { get; set; } = Placement.Top; @@ -92,14 +89,13 @@ public partial class Tooltip : ITooltip public string? Offset { get; set; } /// - /// 获得/设置 自定义样式 默认 null + /// /// - /// 由 data-bs-custom-class 实现 [Parameter] public string? CustomClass { get; set; } /// - /// 获得/设置 触发方式 可组合 click focus hover 默认为 focus hover + /// /// [Parameter] public string? Trigger { get; set; } @@ -110,11 +106,6 @@ public partial class Tooltip : ITooltip [Parameter] public RenderFragment? ChildContent { get; set; } - /// - /// 获得 CustomClass 字符串 - /// - protected virtual string? CustomClassString => CustomClass; - /// /// /// @@ -156,4 +147,25 @@ public void SetParameters(string title, Placement placement = Placement.Auto, st if (!string.IsNullOrEmpty(offset)) Offset = offset; StateHasChanged(); } + + /// + /// 显示 Tooltip 弹窗方法 + /// + /// 延时指定毫秒后显示弹窗 默认 null 不延时 + /// + public Task Show(int? delay = null) => InvokeVoidAsync("show", Id, delay); + + /// + /// 关闭 Tooltip 弹窗方法 + /// + /// 延时指定毫秒后关闭弹窗 默认 null 不延时 + /// + public Task Hide(int? delay = null) => InvokeVoidAsync("hide", Id, delay); + + /// + /// 切换 Tooltip 弹窗当前状态方法 + /// + /// 延时指定毫秒后切换弹窗方法 默认 null 不延时 + /// + public Task Toggle(int? delay = null) => InvokeVoidAsync("toggle", Id, delay); } diff --git a/src/BootstrapBlazor/Components/Tooltip/Tooltip.razor.js b/src/BootstrapBlazor/Components/Tooltip/Tooltip.razor.js index b7591813b75..47f34c789c6 100644 --- a/src/BootstrapBlazor/Components/Tooltip/Tooltip.razor.js +++ b/src/BootstrapBlazor/Components/Tooltip/Tooltip.razor.js @@ -20,6 +20,33 @@ export function init(id) { } } +export function show(id, delay) { + const tip = Data.get(id) + const { tooltip } = tip; + + setTimeout(() => { + tooltip.show(); + }, delay || 0); +} + +export function hide(id, delay) { + const tip = Data.get(id) + const { tooltip } = tip; + + setTimeout(() => { + tooltip.hide(); + }, delay || 0); +} + +export function toggle(id, delay) { + const tip = Data.get(id) + const { tooltip } = tip; + + setTimeout(() => { + tooltip.toggle(); + }, delay || 0); +} + export function dispose(id) { const tip = Data.get(id) Data.remove(id) diff --git a/test/UnitTest/Components/TooltipTest.cs b/test/UnitTest/Components/TooltipTest.cs index d62219e83a7..3b346362122 100644 --- a/test/UnitTest/Components/TooltipTest.cs +++ b/test/UnitTest/Components/TooltipTest.cs @@ -176,4 +176,17 @@ public void FallbackPlacements_Ok() }); cut.Contains("data-bs-fallbackPlacements=\"top,left\""); } + + [Fact] + public async Task Toggle_Ok() + { + var cut = Context.RenderComponent(pb => + { + pb.Add(a => a.Title, "test_tooltip"); + pb.Add(a => a.Trigger, "manual"); + }); + await cut.InvokeAsync(() => cut.Instance.Show()); + await cut.InvokeAsync(() => cut.Instance.Hide()); + await cut.InvokeAsync(() => cut.Instance.Toggle()); + } }