Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MarkdownViewer extra component (#10111) #10211

Open
wants to merge 18 commits into
base: develop
Choose a base branch
from

Conversation

msynk
Copy link
Member

@msynk msynk commented Mar 8, 2025

closes #10111

Summary by CodeRabbit

  • New Features

    • Added a Markdown Viewer component that renders Markdown content with asynchronous processing.
    • Introduced a demo page featuring basic and advanced usage examples.
    • Enhanced navigation with a new link to the Markdown Viewer demo.
  • Style

    • Updated styling assets and configuration to ensure consistent and responsive Markdown rendering.

@msynk msynk requested review from ysmoradi and Cyrus-Sushiant March 8, 2025 16:55
Copy link

coderabbitai bot commented Mar 8, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The changes introduce a new MarkdownViewer component in the Bit.BlazorUI.Extras library. This includes Razor and code-behind files to render Markdown content using the markedjs library, supporting JS interop and custom styling. Additional TypeScript, SCSS, and JavaScript files facilitate initialization, parsing, and styling. The demo application is updated with a dedicated page, navigation links, and configuration adjustments to showcase the new MarkdownViewer.

Changes

File(s) Change Summary
src/BlazorUI/Bit.BlazorUI.Extras/Components/MarkdownViewer/BitMarkdownViewer.razor
.../BitMarkdownViewer.razor.cs
.../BitMarkdownViewer.scss
.../BitMarkdownViewer.ts
.../BitMarkdownViewerJsRuntimeExtensions.cs
.../marked.d.ts
Added a new MarkdownViewer component that renders Markdown using markedjs, supports JS interop, accepts HTML attributes, and includes custom styling and TypeScript definitions.
src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/marked/marked-15.0.7.js Introduced the marked (v15.0.7) JavaScript library with tokenization, rendering, and parsing functionalities for converting Markdown to HTML.
src/BlazorUI/Bit.BlazorUI.Extras/Styles/bit.blazorui.extras.scss
src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss
Updated SCSS imports (switching to extra-general and extra-components) and imported MarkdownViewer styles into the extras stylesheet.
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/MarkdownViewer/BitMarkdownViewerDemo.razor
.../BitMarkdownViewerDemo.razor.cs
.../BitMarkdownViewerDemo.razor.scss
Added a new demo page and accompanying files to demonstrate the MarkdownViewer component, including basic and advanced usage examples.
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Home/ComponentsSection.razor
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Shared/MainLayout.razor.NavItems.cs
Added a navigation link and component entry for the MarkdownViewer demo in the home components section and main layout navigation.
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/compilerconfig.json Added a configuration entry to compile the SCSS file for the MarkdownViewer demo page without minification and source maps.

Sequence Diagram(s)

sequenceDiagram
    participant Component as BitMarkdownViewer Component
    participant JSRuntime as IJSRuntime
    participant ViewerTS as MarkdownViewer (TS)
    participant MarkedJS as Marked (JS Library)

    Component->>JSRuntime: Call BitMarkdownViewerInit(scripts)
    JSRuntime->>ViewerTS: Load and initialize scripts
    Component->>JSRuntime: Call BitMarkdownViewerParse(Markdown)
    JSRuntime->>ViewerTS: Execute parse method
    ViewerTS->>MarkedJS: Process Markdown via markedjs
    MarkedJS-->>ViewerTS: Return parsed HTML
    ViewerTS-->>JSRuntime: Deliver parsed HTML
    JSRuntime-->>Component: Return HTML markup
    Component->>Component: Update UI with new HTML
Loading

Poem

I’m a rabbit coding through the night,
Hopping on Markdown with pure delight.
New components bloom in Blazor’s light,
Scripts and styles all set just right.
With marked magic and UI so bright,
I celebrate changes with a joyful bite!
🥕🐇 Happy hopping in the code insight!


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (12)
src/BlazorUI/Bit.BlazorUI.Extras/Components/MarkdownViewer/BitMarkdownViewer.scss (1)

6-8: Consider if a more targeted reset approach is needed.

Using all: revert on all child elements is a heavy-handed approach. This might cause inconsistencies if specific elements within the Markdown content need custom styling. Consider whether a more targeted reset for specific elements might be more appropriate.

src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/MarkdownViewer/BitMarkdownViewerDemo.razor.scss (1)

1-7: Consider moving responsive image styling to the component itself.

The responsive image styling is appropriate for ensuring images scale properly, but this behavior might be desirable for all implementations of the MarkdownViewer, not just the demo. Consider moving this style to the component's base SCSS file so all implementers benefit from responsive images by default.

// In BitMarkdownViewer.scss
.bit-mdv {
    all: revert;

    * {
        all: revert;
    }
+    
+    img {
+        max-width: 100%;
+    }
}
src/BlazorUI/Bit.BlazorUI.Extras/Components/MarkdownViewer/BitMarkdownViewer.ts (2)

2-41: Consider refactoring to use standalone functions instead of a static class.

The MarkdownViewer class contains only static methods, which is flagged by static analysis. Consider using standalone functions within the namespace for a more functional approach.

namespace BitBlazorUI {
-    export class MarkdownViewer {
-        private static _initPromise?: Promise<unknown>;
+    let _initPromise?: Promise<unknown>;

-        public static async init(scripts: string[]) {
+    export async function init(scripts: string[]) {
-            if (MarkdownViewer._initPromise) {
-                await MarkdownViewer._initPromise;
+            if (_initPromise) {
+                await _initPromise;
            }

            const allScripts = Array.from(document.scripts).map(s => s.src);
            const notAppenedScripts = scripts.filter(s => !allScripts.find(as => as.endsWith(s)));

            if (notAppenedScripts.length == 0) return Promise.resolve();

            const promise = new Promise(async (resolve: any, reject: any) => {
                try {
                    for (let url of notAppenedScripts) await addScript(url);
                    resolve();
                } catch (e: any) {
                    reject(e);
                }
            });
-            MarkdownViewer._initPromise = promise;
+            _initPromise = promise;
            return promise;

            async function addScript(url: string) {
                return new Promise((res, rej) => {
                    const script = document.createElement('script');
                    script.src = url;
                    script.onload = res;
                    script.onerror = rej;
                    document.body.appendChild(script);
                })
            }
        }

-        public static async parse(md: string) {
+    export async function parse(md: string) {
            const html = await marked.parse(md, { async: true });
            return html;
        }
-    }
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 2-41: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)


[error] 15-22: Promise executor functions should not be async.

(lint/suspicious/noAsyncPromiseExecutor)


11-12: Correct typo in variable name notAppenedScripts.

There's a typo in the variable name notAppenedScripts. It should be notAppendedScripts.

-            const notAppenedScripts = scripts.filter(s => !allScripts.find(as => as.endsWith(s)));
+            const notAppendedScripts = scripts.filter(s => !allScripts.find(as => as.endsWith(s)));
src/BlazorUI/Bit.BlazorUI.Extras/Components/MarkdownViewer/BitMarkdownViewerJsRuntimeExtensions.cs (2)

3-4: Consider changing the access modifier to match component usage patterns.

The class is marked internal but contains public methods. If this is intended to be used only within the library, consider making the methods internal as well for consistency.

-internal static class BitMarkdownViewerJsRuntimeExtensions
+internal static class BitMarkdownViewerJsRuntimeExtensions
{
-    public static ValueTask BitMarkdownViewerInit(this IJSRuntime jsRuntime, IEnumerable<string> scripts)
+    internal static ValueTask BitMarkdownViewerInit(this IJSRuntime jsRuntime, IEnumerable<string> scripts)
    {
        return jsRuntime.InvokeVoid("BitBlazorUI.MarkdownViewer.init", scripts);
    }

-    public static ValueTask<string> BitMarkdownViewerParse(this IJSRuntime jsRuntime, string markdown)
+    internal static ValueTask<string> BitMarkdownViewerParse(this IJSRuntime jsRuntime, string markdown)
    {
        return jsRuntime.Invoke<string>("BitBlazorUI.MarkdownViewer.parse", markdown);
    }
}

1-14: Add missing using directives and parameter documentation.

The file is missing using directives for System.Threading.Tasks and Microsoft.JSInterop. Also consider adding XML documentation for the methods and parameters.

namespace Bit.BlazorUI;
+
+using System.Threading.Tasks;
+using Microsoft.JSInterop;

internal static class BitMarkdownViewerJsRuntimeExtensions
{
+    /// <summary>
+    /// Initializes the Markdown viewer by loading required scripts.
+    /// </summary>
+    /// <param name="jsRuntime">The JS runtime instance.</param>
+    /// <param name="scripts">The list of script URLs to load.</param>
+    /// <returns>A ValueTask representing the asynchronous operation.</returns>
    public static ValueTask BitMarkdownViewerInit(this IJSRuntime jsRuntime, IEnumerable<string> scripts)
    {
        return jsRuntime.InvokeVoid("BitBlazorUI.MarkdownViewer.init", scripts);
    }

+    /// <summary>
+    /// Parses Markdown content into HTML.
+    /// </summary>
+    /// <param name="jsRuntime">The JS runtime instance.</param>
+    /// <param name="markdown">The Markdown content to parse.</param>
+    /// <returns>A ValueTask containing the HTML string result.</returns>
    public static ValueTask<string> BitMarkdownViewerParse(this IJSRuntime jsRuntime, string markdown)
    {
        return jsRuntime.Invoke<string>("BitBlazorUI.MarkdownViewer.parse", markdown);
    }
}
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/MarkdownViewer/BitMarkdownViewerDemo.razor (2)

5-5: Fix inconsistent casing in description.

The description uses lowercase "markdownviewer" which is inconsistent with the component name "MarkdownViewer" used elsewhere.

-            Description="markdownviewer component of the bit BlazorUI components" />
+            Description="MarkdownViewer component of the bit BlazorUI components" />

17-21: Consider adding responsive image styling by default.

In the advanced example, you're wrapping the BitMarkdownViewer in a div without any purpose. Consider adding the responsive image styles directly to the component parameters.

-    <DemoSection Title="Advanced" RazorCode="@example2RazorCode" CsharpCode="@example2CsharpCode" Id="example2">
-        <div>
-            <BitMarkdownViewer Markdown="@advancedMarkdown" Class="advanced" />
-        </div>
+    <DemoSection Title="Advanced" RazorCode="@example2RazorCode" CsharpCode="@example2CsharpCode" Id="example2">
+        <BitMarkdownViewer Markdown="@advancedMarkdown" Class="advanced" />
     </DemoSection>
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/MarkdownViewer/BitMarkdownViewerDemo.razor.cs (3)

5-14: Consider adding more component parameters.

The demo page only shows one parameter "Markdown" for the BitMarkdownViewer component. If there are other parameters like "Class" that can be used, consider adding them to the componentParameters list.

    private readonly List<ComponentParameter> componentParameters =
    [
         new()
         {
            Name = "Markdown",
            Type = "string?",
            DefaultValue = "null",
            Description = "The Markdown string value to render as an html element.",
         },
+        new()
+        {
+            Name = "Class",
+            Type = "string?",
+            DefaultValue = "null",
+            Description = "Additional CSS class to apply to the component."
+        }
    ];

93-106: Inconsistent string interpolation in example code.

The example code uses string interpolation with raw strings which would require many escape characters in real C# code. Consider simplifying to improve readability.

For example2RazorCode, you might want to use a verbatim string without escaping double quotes:

-    private readonly string example1RazorCode = @"
-<BitMarkdownViewer Markdown=""@(""# Marked in the browser\n\nRendered by **marked**."")"" />";
+    private readonly string example1RazorCode = @"
+<BitMarkdownViewer Markdown=""@(""# Marked in the browser\n\nRendered by **marked**."")"" />";

This is a minor issue, but could be confusing to developers looking at the demo.


25-26: Simplify Markdown string with verbatim strings.

The Markdown string has many escape sequences for double quotes. Consider using C#'s verbatim string literals with alternate quote delimiter to simplify this.

In C# 11+ you can use raw string literals with triple quotes to avoid escaping:

-[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/bitfoundation/bitplatform.svg)](http://isitmaintained.com/project/bitfoundation/bitplatform ""Average time to resolve an issue"")
-[![Percentage of issues still open](http://isitmaintained.com/badge/open/bitfoundation/bitplatform.svg)](http://isitmaintained.com/project/bitfoundation/bitplatform ""Percentage of issues still open"")
+[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/bitfoundation/bitplatform.svg)](http://isitmaintained.com/project/bitfoundation/bitplatform """Average time to resolve an issue""")
+[![Percentage of issues still open](http://isitmaintained.com/badge/open/bitfoundation/bitplatform.svg)](http://isitmaintained.com/project/bitfoundation/bitplatform """Percentage of issues still open""")
src/BlazorUI/Bit.BlazorUI.Extras/Components/MarkdownViewer/marked.d.ts (1)

609-609: Avoid confusing 'void' in union types
Static analysis highlights that using void within a union type can be misleading. Replace it with undefined or rework the type to be more descriptive (e.g., null | Promise<void>).

- declare type MaybePromise = void | Promise<void>;
+ declare type MaybePromise = undefined | Promise<void>;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fbca734 and 8863bfd.

📒 Files selected for processing (15)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/MarkdownViewer/BitMarkdownViewer.razor (1 hunks)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/MarkdownViewer/BitMarkdownViewer.razor.cs (1 hunks)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/MarkdownViewer/BitMarkdownViewer.scss (1 hunks)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/MarkdownViewer/BitMarkdownViewer.ts (1 hunks)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/MarkdownViewer/BitMarkdownViewerJsRuntimeExtensions.cs (1 hunks)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/MarkdownViewer/marked.d.ts (1 hunks)
  • src/BlazorUI/Bit.BlazorUI.Extras/Styles/bit.blazorui.extras.scss (1 hunks)
  • src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss (1 hunks)
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/marked/marked-15.0.7.js (1 hunks)
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/MarkdownViewer/BitMarkdownViewerDemo.razor (1 hunks)
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/MarkdownViewer/BitMarkdownViewerDemo.razor.cs (1 hunks)
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/MarkdownViewer/BitMarkdownViewerDemo.razor.scss (1 hunks)
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Home/ComponentsSection.razor (1 hunks)
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Shared/MainLayout.razor.NavItems.cs (1 hunks)
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/compilerconfig.json (1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/BlazorUI/Bit.BlazorUI.Extras/Components/MarkdownViewer/BitMarkdownViewer.ts

[error] 2-41: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)


[error] 15-22: Promise executor functions should not be async.

(lint/suspicious/noAsyncPromiseExecutor)

src/BlazorUI/Bit.BlazorUI.Extras/Components/MarkdownViewer/marked.d.ts

[error] 401-401: void is confusing inside a union type.

Unsafe fix: Use undefined instead.

(lint/suspicious/noConfusingVoidType)

src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/marked/marked-15.0.7.js

[error] 6-6: Redundant use strict directive.

The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.

(lint/suspicious/noRedundantUseStrict)


[error] 6-6: Unexpected control character in a regular expression.

Control characters are unusual and potentially incorrect inputs, so they are disallowed.

(lint/suspicious/noControlCharactersInRegex)


[error] 6-6: Unexpected control character in a regular expression.

Control characters are unusual and potentially incorrect inputs, so they are disallowed.

(lint/suspicious/noControlCharactersInRegex)


[error] 6-6: Unexpected control character in a regular expression.

Control characters are unusual and potentially incorrect inputs, so they are disallowed.

(lint/suspicious/noControlCharactersInRegex)


[error] 6-6: Unexpected control character in a regular expression.

Control characters are unusual and potentially incorrect inputs, so they are disallowed.

(lint/suspicious/noControlCharactersInRegex)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build and test
🔇 Additional comments (11)
src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss (1)

6-6: Import for the new MarkdownViewer component looks good.

The import is properly placed following the alphabetical order of the existing component imports.

src/BlazorUI/Bit.BlazorUI.Extras/Components/MarkdownViewer/BitMarkdownViewer.scss (1)

3-9:

❓ Verification inconclusive

Consider browser compatibility with the all: revert property.

The all: revert approach effectively resets styles to browser defaults, which is good for Markdown content. However, be aware that this property might have limited support in older browsers. Consider documenting this requirement or providing fallback styles for browsers that don't support this property.


🌐 Web query:

Browser compatibility for CSS all:revert property

💡 Result:

The all: revert CSS property resets an element's styles to the browser's default user-agent stylesheet values, ignoring any author-defined CSS. This is particularly useful for overriding inherited styles or resetting components to their base appearance. Browser support is generally good in modern browsers, with some limitations in older versions.

Browser Compatibility Overview

Browser Supported Versions Notes
Chrome 84+ (✅ Full support) Pre-Chrome 84 lacks support [1][2]
Firefox 67+ (✅ Full support) Earlier versions unsupported [1][2][7]
Safari 9.1+ (✅ Full support) iOS Safari 9.3+ supported [1][2]
Edge 84+ (✅ Full support) Legacy Edge (12-83) unsupported [1][2]
Opera 73+ (✅ Full support)
Internet Explorer ❌ No support All IE versions lack support [1][2]

Key Details

  • Mobile Browsers:

    • Chrome for Android/Firefox for Android: Full support [1][2]
    • Samsung Internet: 14+ [2]
    • iOS Safari: 9.3+ [1][2]
  • Special Cases:

    • revert works as a standalone value (e.g., color: revert) and with all [7][8].
    • Older browsers like Chrome ≤83 or Firefox ≤66 will ignore revert entirely [1][2].

Practical Considerations

  1. Fallbacks: Use unset or initial as progressive enhancements for older browsers [3][7].
  2. Reset Scope: all: revert affects all properties except direction and unicode-bidi [8].
  3. Cascade Layers: In modern browsers, revert-layer provides more granular control [4].

For projects requiring IE11 support, avoid all: revert entirely. Always test on target browsers using tools like LambdaTest[1] or CanIUse[2] to verify compatibility.

Citations:


Attention: Browser Compatibility Consideration

Your Markdown viewer’s CSS reset using all: revert is effective for reverting styles to the browser’s default user-agent settings. However, note that while modern browsers (e.g., Chrome 84+, Firefox 67+, Safari 9.1+, Edge 84+, and Opera 73+) fully support this property, legacy browsers—most notably Internet Explorer and pre-Chrome 84/Firefox 67 versions—do not.

  • Please verify if support for these older browsers is required.
  • If so, consider adding fallback styles (using alternatives like unset or initial) or document this limitation clearly within the project’s guidelines or inline comments.
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Shared/MainLayout.razor.NavItems.cs (1)

159-159: Navigation item placement is correct.

The MarkdownViewer navigation item is appropriately placed in the "Extras" category, following the same pattern as other components.

src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Home/ComponentsSection.razor (1)

265-267: Link for MarkdownViewer component added correctly.

The new BitLink component for MarkdownViewer follows the established pattern and maintains consistent styling with other component links in the Extras section.

src/BlazorUI/Bit.BlazorUI.Extras/Components/MarkdownViewer/BitMarkdownViewer.razor (1)

1-11: Component structure follows BitComponentBase pattern appropriately.

The component is properly structured with:

  • Correct namespace declaration
  • Inheritance from BitComponentBase
  • Appropriate div element with reference, attributes, and styling
  • Proper handling of Markdown content via MarkupString

The implementation aligns with the architectural patterns used in other Bit.BlazorUI components.

src/BlazorUI/Bit.BlazorUI.Extras/Styles/bit.blazorui.extras.scss (1)

1-2: Import statements updated to use more specific stylesheets.

The change from generic "general.scss" and "components.scss" to more specific "extra-general.scss" and "extra-components.scss" improves organization by better separating core and extra component styles.

src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/compilerconfig.json (1)

80-85: Compiler configuration for BitMarkdownViewerDemo properly added.

The new configuration entry for BitMarkdownViewerDemo follows the same pattern as other components, with appropriate output/input paths and consistent minify/sourceMap settings.

src/BlazorUI/Bit.BlazorUI.Extras/Components/MarkdownViewer/BitMarkdownViewer.ts (1)

37-40: Add error handling for the marked library dependency.

The parse method assumes that the marked library is available globally, but there's no check to verify this. If the library isn't loaded, this will cause runtime errors.

Consider adding a check for the marked library's availability before using it:

    public static async parse(md: string) {
+        if (typeof marked === 'undefined') {
+            throw new Error('The marked library is not loaded. Make sure to call init() first.');
+        }
        const html = await marked.parse(md, { async: true });
        return html;
    }
src/BlazorUI/Bit.BlazorUI.Extras/Components/MarkdownViewer/BitMarkdownViewer.razor.cs (2)

1-7: Overall Implementation Looks Good
No errors are detected in the fundamental structure, parameter declarations, or the class definition. The summary documentation is clear and concise, and the code style is consistent.


33-33: Verify the method name for JavaScript initialization
The method _js.BitPdfReaderInit appears to be mismatched for a Markdown viewer context. It may be a leftover reference from a PDF component. Consider renaming it to match the Markdown functionality if that is the intended usage.

Would you like me to open a new issue to rename it (e.g., _js.BitMarkdownViewerInit) for clarity?

src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/marked/marked-15.0.7.js (1)

6-6: Address static analysis findings or confirm integrity of third-party code
Static analysis reports a redundant 'use strict' directive and potential control characters in the regular expressions. Usually, this file is an external dependency, so modifying minified library code may be risky. Verify if an official distribution of the same version can replace or confirm no actual harmful control characters are present.

🧰 Tools
🪛 Biome (1.9.4)

[error] 6-6: Redundant use strict directive.

The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.

(lint/suspicious/noRedundantUseStrict)


[error] 6-6: Unexpected control character in a regular expression.

Control characters are unusual and potentially incorrect inputs, so they are disallowed.

(lint/suspicious/noControlCharactersInRegex)


[error] 6-6: Unexpected control character in a regular expression.

Control characters are unusual and potentially incorrect inputs, so they are disallowed.

(lint/suspicious/noControlCharactersInRegex)


[error] 6-6: Unexpected control character in a regular expression.

Control characters are unusual and potentially incorrect inputs, so they are disallowed.

(lint/suspicious/noControlCharactersInRegex)


[error] 6-6: Unexpected control character in a regular expression.

Control characters are unusual and potentially incorrect inputs, so they are disallowed.

(lint/suspicious/noControlCharactersInRegex)

@ysmoradi ysmoradi marked this pull request as draft March 9, 2025 14:54
@ysmoradi ysmoradi marked this pull request as ready for review March 9, 2025 15:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

The BlazorUI library is missing a Markdown viewer component
3 participants