using Microsoft.AspNetCore.Components.Web; namespace MudBlazor; public partial class MudCodeHighlight : MudComponentBase, IDisposable { private ElementReference _ref; private CodeBlockTheme _theme; private IMudMarkdownThemeService? _themeService; private bool _isFirstThemeSet; /// /// Code text to render /// [Parameter] public string Text { get; set; } = string.Empty; /// /// Language of the /// [Parameter] public string Language { get; set; } = string.Empty; /// /// Theme of the code block.
/// Browse available themes here: https://highlightjs.org/static/demo/
/// Default is ///
#if NET7_0 #pragma warning disable BL0007 #endif [Parameter] public CodeBlockTheme Theme { get => _theme; set { if (_theme == value) return; _theme = value; Task.Run(SetThemeAsync); } } #if NET7_0 #pragma warning restore BL0007 #endif [Inject] private IJSRuntime Js { get; init; } = default!; [Inject] private IServiceProvider? ServiceProvider { get; init; } public void Dispose() { if (_themeService != null) _themeService.CodeBlockThemeChanged -= OnCodeBlockThemeChanged; GC.SuppressFinalize(this); } protected override bool ShouldRender() => !string.IsNullOrEmpty(Text); protected override void BuildRenderTree(RenderTreeBuilder builder) { var i = 0; builder.OpenElement(i++, "div"); builder.AddAttribute(i++, "class", "snippet-clipboard-content overflow-auto"); // Copy button builder.OpenComponent(i++); builder.AddAttribute(i++, nameof(MudIconButton.Icon), Icons.Material.Rounded.ContentCopy); builder.AddAttribute(i++, nameof(MudIconButton.Variant), Variant.Filled); builder.AddAttribute(i++, nameof(MudIconButton.Color), Color.Primary); builder.AddAttribute(i++, nameof(MudIconButton.Size), Size.Medium); builder.AddAttribute(i++, nameof(MudIconButton.Class), "snippet-clipboard-copy-icon m-2"); builder.AddAttribute(i++, nameof(MudIconButton.OnClick), EventCallback.Factory.Create(this, CopyTextToClipboardAsync)); builder.CloseComponent(); // Code block builder.OpenElement(i++, "pre"); builder.OpenElement(i++, "code"); if (!string.IsNullOrEmpty(Language)) builder.AddAttribute(i++, "class", $"language-{Language}"); builder.AddElementReferenceCapture(i++, x => _ref = x); builder.AddContent(i++, Text); builder.CloseElement(); builder.CloseElement(); builder.CloseElement(); } protected override void OnInitialized() { base.OnInitialized(); _themeService = ServiceProvider?.GetService(); if (_themeService != null) _themeService.CodeBlockThemeChanged += OnCodeBlockThemeChanged; } protected override async Task OnAfterRenderAsync(bool firstRender) { if (!firstRender) return; await Js.InvokeVoidAsync("highlightCodeElement", _ref) .ConfigureAwait(false); if (!_isFirstThemeSet) { await SetThemeAsync() .ConfigureAwait(false); } } private void OnCodeBlockThemeChanged(object? sender, CodeBlockTheme e) => Theme = e; private async Task SetThemeAsync() { var stylesheetPath = Theme.GetStylesheetPath(); await Js.InvokeVoidAsync("setHighlightStylesheet", stylesheetPath) .ConfigureAwait(false); _isFirstThemeSet = true; } private async Task CopyTextToClipboardAsync(MouseEventArgs args) { var ok = await Js.InvokeAsync("copyTextToClipboard", Text) .ConfigureAwait(false); if (ok) return; var clipboardService = ServiceProvider?.GetService(); if (clipboardService != null) { await clipboardService.CopyToClipboardAsync(Text) .ConfigureAwait(false); } } }