diff --git a/.github/workflows/ci-publish.yml b/.github/workflows/ci-publish.yml index 6813778..0fed1fa 100644 --- a/.github/workflows/ci-publish.yml +++ b/.github/workflows/ci-publish.yml @@ -2,10 +2,10 @@ on: push: - branches: [main] + branches: [prod] tags: ['v*'] pull_request: - branches: [main] + branches: [prod] workflow_dispatch: env: diff --git a/src/SuperBlazorComponents.DataGridExporter/Components/SuperDataGridCsvExportButton.razor b/src/SuperBlazorComponents.DataGridExporter/Components/SuperDataGridCsvExportButton.razor index 0bd34d9..8fab3be 100644 --- a/src/SuperBlazorComponents.DataGridExporter/Components/SuperDataGridCsvExportButton.razor +++ b/src/SuperBlazorComponents.DataGridExporter/Components/SuperDataGridCsvExportButton.razor @@ -8,7 +8,8 @@ Size="@Size" Outline="@Outline" Disabled="@IsDisabled" - Click="@OpenDialogAsync" /> + Click="@OpenDialogAsync" + @attributes="AdditionalAttributes" /> @code { protected override SuperDataGridExportFormat Format => SuperDataGridExportFormat.Csv; diff --git a/src/SuperBlazorComponents.DataGridExporter/Components/SuperDataGridExcelExportButton.razor b/src/SuperBlazorComponents.DataGridExporter/Components/SuperDataGridExcelExportButton.razor index c832664..decb160 100644 --- a/src/SuperBlazorComponents.DataGridExporter/Components/SuperDataGridExcelExportButton.razor +++ b/src/SuperBlazorComponents.DataGridExporter/Components/SuperDataGridExcelExportButton.razor @@ -8,7 +8,8 @@ Size="@Size" Outline="@Outline" Disabled="@IsDisabled" - Click="@OpenDialogAsync" /> + Click="@OpenDialogAsync" + @attributes="AdditionalAttributes" /> @code { protected override SuperDataGridExportFormat Format => SuperDataGridExportFormat.Excel; diff --git a/src/SuperBlazorComponents.DataGridExporter/Components/SuperDataGridExportButtonBase.cs b/src/SuperBlazorComponents.DataGridExporter/Components/SuperDataGridExportButtonBase.cs index 4e6db00..250f67c 100644 --- a/src/SuperBlazorComponents.DataGridExporter/Components/SuperDataGridExportButtonBase.cs +++ b/src/SuperBlazorComponents.DataGridExporter/Components/SuperDataGridExportButtonBase.cs @@ -44,6 +44,13 @@ public abstract class SuperDataGridExportButtonBase : ComponentBase [Parameter] public bool IconOnly { get; set; } + /// + /// Additional attributes applied to the underlying , + /// such as class or style. + /// + [Parameter(CaptureUnmatchedValues = true)] + public Dictionary AdditionalAttributes { get; set; } = new(); + protected abstract SuperDataGridExportFormat Format { get; } protected abstract string DefaultText { get; } protected abstract string DialogTitle { get; } @@ -52,6 +59,36 @@ public abstract class SuperDataGridExportButtonBase : ComponentBase private SuperDataGrid? EffectiveGrid => Grid ?? CascadedGrid; protected bool IsDisabled => Disabled || EffectiveGrid is null; + public override async Task SetParametersAsync(ParameterView parameters) + { + var normalized = new Dictionary(StringComparer.OrdinalIgnoreCase); + string? htmlStyle = null; + var hasHtmlStyle = false; + + foreach (var parameter in parameters) + { + if (string.Equals(parameter.Name, "style", StringComparison.OrdinalIgnoreCase) + && (parameter.Value is string || parameter.Value is null)) + { + hasHtmlStyle = true; + htmlStyle = parameter.Value as string; + continue; + } + + normalized[parameter.Name] = parameter.Value; + } + + if (!hasHtmlStyle) + { + await base.SetParametersAsync(parameters); + return; + } + + await base.SetParametersAsync(ParameterView.FromDictionary(normalized)); + if (htmlStyle is not null) + AdditionalAttributes["style"] = htmlStyle; + } + protected async Task OpenDialogAsync(MouseEventArgs _) { var grid = EffectiveGrid; diff --git a/src/SuperBlazorComponents/Components/Buttons/SuperButton.razor.cs b/src/SuperBlazorComponents/Components/Buttons/SuperButton.razor.cs index 1692b3b..46b3a79 100644 --- a/src/SuperBlazorComponents/Components/Buttons/SuperButton.razor.cs +++ b/src/SuperBlazorComponents/Components/Buttons/SuperButton.razor.cs @@ -152,6 +152,15 @@ private string CssClass protected override void OnParametersSet() { + if (CapturedHtmlStyleAttribute is not null) + { + CapturedAttributes["style"] = CapturedHtmlStyleAttribute; + } + else + { + CapturedAttributes.Remove("style"); + } + CapturedAttributes.TryGetValue("class", out var cls); _additionalCssClass = cls?.ToString(); diff --git a/src/SuperBlazorComponents/Components/Buttons/SuperButtonBase.cs b/src/SuperBlazorComponents/Components/Buttons/SuperButtonBase.cs index be36364..aea3ebc 100644 --- a/src/SuperBlazorComponents/Components/Buttons/SuperButtonBase.cs +++ b/src/SuperBlazorComponents/Components/Buttons/SuperButtonBase.cs @@ -5,6 +5,8 @@ namespace SuperBlazorComponents.Components.Buttons; public abstract class SuperButtonBase : ComponentBase { + protected string? CapturedHtmlStyleAttribute { get; private set; } + [Parameter] public EventCallback Click { get; set; } @@ -20,6 +22,34 @@ public abstract class SuperButtonBase : ComponentBase [Parameter] public bool IsBusy { get; set; } = false; + public override async Task SetParametersAsync(ParameterView parameters) + { + var normalized = new Dictionary(StringComparer.OrdinalIgnoreCase); + var hasHtmlStyle = false; + CapturedHtmlStyleAttribute = null; + + foreach (var parameter in parameters) + { + if (string.Equals(parameter.Name, "style", StringComparison.OrdinalIgnoreCase) + && (parameter.Value is string || parameter.Value is null)) + { + hasHtmlStyle = true; + CapturedHtmlStyleAttribute = parameter.Value as string; + continue; + } + + normalized[parameter.Name] = parameter.Value; + } + + if (!hasHtmlStyle) + { + await base.SetParametersAsync(parameters); + return; + } + + await base.SetParametersAsync(ParameterView.FromDictionary(normalized)); + } + private bool _isBusy; protected bool IsDisabled => _isBusy || IsBusy || Disabled || CapturedAttributes.ContainsKey("disabled"); diff --git a/tests/SuperBlazorComponents.Tests/SuperDataGridExporterTests.cs b/tests/SuperBlazorComponents.Tests/SuperDataGridExporterTests.cs index a367be3..e61b77e 100644 --- a/tests/SuperBlazorComponents.Tests/SuperDataGridExporterTests.cs +++ b/tests/SuperBlazorComponents.Tests/SuperDataGridExporterTests.cs @@ -262,6 +262,22 @@ public void ExportButtons_IconOnlyHidesTextAndKeepsAccessibleLabel() Assert.HasCount(1, button.QuerySelectorAll(".fa-file-csv")); } + [TestMethod] + public void ExportButtons_ForwardClassAndStyleToUnderlyingButton() + { + using var context = new BunitContext(); + context.JSInterop.Mode = JSRuntimeMode.Loose; + context.Services.AddSuperComponents(); + + var button = context.Render>(parameters => parameters + .AddUnmatched("class", "me-2") + .AddUnmatched("style", "margin-inline-end: 0.5rem")) + .Find("button"); + + StringAssert.Contains(button.GetAttribute("class")!, "me-2"); + Assert.AreEqual("margin-inline-end: 0.5rem", button.GetAttribute("style")); + } + [TestMethod] public void ExportDialog_AfterGenerationDisplaysDownloadLink() {