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

feat(components): introduce Dropdown component #168

Merged
merged 31 commits into from
Feb 19, 2025
Merged

Conversation

desmondinho
Copy link
Contributor

@desmondinho desmondinho commented Feb 19, 2025

Description

Closes #115

Introducing a new dropdown component.

What's been done?

Added a new dropdown component.

Checklist

  • My code follows the project's coding style and guidelines.
  • I have included inline docs for my changes, where applicable.
  • I have added, updated or removed tests according to my changes.
  • All tests are passing.
  • There's an open issue for the PR that I am making.

Additional Notes

Summary by CodeRabbit

  • New Features

    • Enhanced dropdown and popover components now offer interactive behavior and customizable visual styles, including support for disabled, empty, and dynamic content states.
    • A new UI variant system streamlines styling across menus, dropdowns, and related components to provide a more consistent and flexible interface.
    • Introduction of a new TwVariant service for improved component styling and behavior.
    • New documentation pages for dropdown components, detailing usage, customization options, and API details.
  • Documentation

    • Comprehensive, interactive guides and examples have been added, detailing component usage and customization options to help users leverage the enhanced UI features.

@desmondinho desmondinho self-assigned this Feb 19, 2025
@desmondinho desmondinho linked an issue Feb 19, 2025 that may be closed by this pull request
1 task
Copy link

coderabbitai bot commented Feb 19, 2025

Warning

Rate limit exceeded

@desmondinho has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 25 minutes and 8 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 420d921 and 80945f2.

📒 Files selected for processing (3)
  • src/LumexUI.Variants/SlotCollection.cs (1 hunks)
  • src/LumexUI.Variants/VariantCollection.cs (1 hunks)
  • src/LumexUI.Variants/VariantValueCollection.cs (1 hunks)

Walkthrough

This pull request integrates a new Variants project into the solution and updates numerous components across the LumexUI framework. New types, records, and collections for managing component variants have been added. Many components, including Dropdown, Popover, and Menu, have been refactored to use service-based asynchronous interactions and a slot-based styling system. Additionally, the styling system now leverages variant configuration with Tailwind integration, and documentation pages, examples, and tests have been updated accordingly.

Changes

File(s) Change Summary
LumexUI.sln; src/.../LumexUI.Variants.csproj; src/.../LumexUI.csproj Added new project entry for “LumexUI.Variants”, new multi-targeted project file, and updated project references.
src/LumexUI.Variants/* New types for variant management: CompoundVariant, CompoundVariantCollection, SlotCollection, TwVariant, VariantCollection, VariantConfig, and VariantValueCollection; plus extension method AddTailwindVariants.
src/LumexUI/Components/Bases/LumexComponentBase.cs Injected new TwVariant property and updated access modifier for TwMerge.
src/LumexUI/Components/Dropdown/* Introduced new dropdown component files, context (DropdownContext), and slot classes (e.g. DropdownItemSlots, DropdownMenuSlots), along with refactored code-behind files.
src/LumexUI/Components/Popover/* Refactored popover components to replace trigger components with button-driven, asynchronous, service-based triggering; updated slot naming in PopoverSlots.
src/LumexUI/Components/Menu/* Added new menu components and context (MenuContext), with slot classes (MenuItemSlots, MenuSlots) for dynamic item registration.
src/LumexUI/Styles/* Updated styling for Button, Dropdown, Menu, and Popover using variant-based configuration and a unified styling API.
docs/LumexUI.Docs.Client/Pages/Components/Dropdown/* Added several new documentation pages and examples (Usage, ColorsVariants, CustomStyles, etc.) detailing dropdown functionality and customization.
src/LumexUI/Extensions/* New extensions for ParameterView and updated service collection extensions to include Tailwind variants.
src/LumexUI/Services/Popover/* Enhanced IPopoverService and PopoverService with asynchronous triggering and registration via a dictionary keyed by popover ID.
Tests (tests/...) Updated numerous test files to register TwVariant (often replacing or supplementing TwMerge), added new using directives, and modified assertions and project references (e.g. switching from FluentAssertions to AwesomeAssertions).

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Button
    participant IPopoverService
    participant Popover
    User->>Button: Click trigger
    Button->>IPopoverService: TriggerAsync(popoverId)
    IPopoverService->>Popover: Lookup using popoverId
    Popover-->>IPopoverService: Return popover instance
    IPopoverService->>Popover: Invoke TriggerAsync()
    Popover-->>User: Display popover
Loading
sequenceDiagram
    participant Component
    participant TwVariant
    participant VariantEngine
    Component->>TwVariant: Create(VariantConfig)
    TwVariant->>VariantEngine: Process base, overrides, compounds
    VariantEngine-->>TwVariant: Merged style slots
    TwVariant-->>Component: Return ComponentVariant
Loading

Poem

I’m a rabbit hopping through lines of code,
With variants and popovers lightening the load.
New projects sprout like carrots in the field,
Swift interactions now on bright wheels.
My whiskers twitch at each refactored idea,
Celebrating changes with a joyful cheer!
Hop on, dear devs – let your UI shine clear!


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 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. (Beta)
  • @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

codecov bot commented Feb 19, 2025

Codecov Report

Attention: Patch coverage is 90.86957% with 21 lines in your changes missing coverage. Please review.

Project coverage is 94.39%. Comparing base (19b89dc) to head (80945f2).
Report is 101 commits behind head on main.

Files with missing lines Patch % Lines
...UI/Components/Popover/LumexPopoverTrigger.razor.cs 71.43% 3 Missing and 3 partials ⚠️
...c/LumexUI/Components/Popover/LumexPopover.razor.cs 91.23% 3 Missing and 2 partials ⚠️
src/LumexUI/Components/Menu/Menu.razor 75.00% 0 Missing and 2 partials ⚠️
src/LumexUI/Components/Menu/MenuItem.razor 33.33% 0 Missing and 2 partials ⚠️
src/LumexUI/Services/Popover/PopoverService.cs 75.00% 1 Missing and 1 partial ⚠️
...LumexUI/Components/Dropdown/LumexDropdown.razor.cs 92.31% 0 Missing and 1 partial ⚠️
src/LumexUI/Components/Menu/MenuItem.razor.cs 97.14% 0 Missing and 1 partial ⚠️
...mexUI/Components/Popover/LumexPopoverContent.razor 50.00% 0 Missing and 1 partial ⚠️
...UI/Components/Popover/LumexPopoverContent.razor.cs 93.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #168      +/-   ##
==========================================
- Coverage   96.95%   94.39%   -2.56%     
==========================================
  Files          70      115      +45     
  Lines        1542     2658    +1116     
  Branches      150      335     +185     
==========================================
+ Hits         1495     2509    +1014     
- Misses         28       77      +49     
- Partials       19       72      +53     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

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: 23

🔭 Outside diff range comments (1)
tests/LumexUI.Tests/Components/Listbox/ListboxTests.razor (1)

4-6: ⚠️ Potential issue

Add missing import for TwVariant.

The TwVariant type is used in the service registration but its import statement is missing.

Add the following import:

@using Microsoft.Extensions.DependencyInjection
@using TailwindMerge
+@using LumexUI.Variants
🧹 Nitpick comments (78)
tests/LumexUI.Tests/Components/Checkbox/CheckboxGroupTests.cs (1)

18-19: Fix indentation to use spaces instead of tabs.

Lines 18-19 use tabs for indentation while the rest of the file uses spaces. This inconsistency should be fixed to maintain uniform code formatting.

-		Services.AddSingleton<TwVariant>();
-	}
+        Services.AddSingleton<TwVariant>();
+    }
tests/LumexUI.Tests/Components/Divider/DividerTests.cs (1)

19-20: Fix indentation to maintain consistency.

The service registration is correctly implemented, but the indentation uses tabs instead of spaces, which is inconsistent with the rest of the file.

Apply this diff to fix the indentation:

-		Services.AddSingleton<TwVariant>();
-	}
+        Services.AddSingleton<TwVariant>();
+    }
docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/CustomStyles.razor (1)

10-11: Consider making the placement configurable.

While the Right placement works for this example, consider making it configurable through a parameter to enhance reusability.

+    [Parameter]
+    public PopoverPlacement Placement { get; set; } = PopoverPlacement.Right;

-              Placement="@PopoverPlacement.Right"
+              Placement="@Placement"
tests/LumexUI.Tests/Components/Icon/IconTests.cs (1)

18-19: Fix indentation inconsistency.

Lines 18-19 use tabs while the rest of the file uses spaces. Maintain consistent indentation throughout the file.

-		Services.AddSingleton<TwVariant>();
-	}
+        Services.AddSingleton<TwVariant>();
+    }
tests/LumexUI.Tests/Components/Switch/SwitchTests.cs (1)

19-20: Fix indentation inconsistency.

The indentation uses tabs instead of spaces, which is inconsistent with the rest of the file.

Apply this diff to fix the indentation:

-		Services.AddSingleton<TwVariant>();
-	}
+        Services.AddSingleton<TwVariant>();
+    }
tests/LumexUI.Tests/Components/Tabs/TabsTests.razor (1)

12-20: Consider adding tests for variant-related functionality.

While the TwVariant service is now registered, there are no specific tests covering the variant system's functionality with the tabs component. Consider adding test cases to verify:

  • Variant application to tabs
  • Variant inheritance
  • Custom variant overrides

Would you like me to help generate test cases for the variant system integration?

docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Offset.razor (1)

10-17: Consider enhancing accessibility with ARIA attributes.

While the popover implementation is functional, consider adding ARIA attributes to improve accessibility:

-<LumexPopover Id="@_popoverId" Offset="16">
+<LumexPopover Id="@_popoverId" 
+              Offset="16"
+              aria-label="Additional information"
+              role="dialog">
     <LumexPopoverContent>
-        <div class="px-1 py-2">
+        <div class="px-1 py-2" role="presentation">
             <div class="text-small font-bold">Oh, hi there!</div>
             <div class="text-tiny">I am the popover content</div>
         </div>
     </LumexPopoverContent>
 </LumexPopover>
tests/LumexUI.Tests/Components/Listbox/ListboxTests.razor (1)

11-11: Consider adding variant-specific test cases.

While the TwVariant service has been registered, there are no explicit tests covering the variant functionality of the Listbox component. Consider adding test cases to verify:

  • Variant application and inheritance
  • Dynamic variant changes
  • Custom variant configurations

Would you like me to help generate test cases for the variant functionality?

tests/LumexUI.Tests/Components/Link/LinkTests.cs (2)

18-19: Fix indentation to use spaces instead of tabs.

The indentation uses tabs while the rest of the file uses spaces. Maintain consistency with the existing code style.

-		Services.AddSingleton<TwVariant>();
-	}
+        Services.AddSingleton<TwVariant>();
+    }

13-56: Add tests for variant configuration functionality.

While the existing tests cover basic functionality, there are no tests verifying the new variant configuration capabilities. Consider adding tests that:

  1. Verify default variant application
  2. Test custom variant overrides
  3. Validate variant inheritance and composition

Would you like me to help generate test cases for the variant configuration functionality?

src/LumexUI/Theme/Colors/SemanticColors.cs (1)

39-40: Consider surface level consistency.

The change makes Surface1 use pure white background while Surface2 and Surface3 use zinc shades. This creates a more distinct hierarchy but verify if this aligns with the design system's surface level progression.

Let's analyze the surface progression:

  • Surface1: White background, Zinc-900 text
  • Surface2: Zinc-100 background, Zinc-800 text
  • Surface3: Zinc-200 background, Zinc-700 text

The progression shows increasing zinc shade intensity for backgrounds while text color gets lighter, which maintains a logical hierarchy. However, the jump from white to Zinc-100 is more pronounced than the transition between other surface levels.

tests/LumexUI.Tests/Components/Collapse/CollapseTests.cs (3)

20-21: Fix indentation inconsistency.

The service registration looks good, but the indentation uses tabs instead of spaces, which is inconsistent with the rest of the file.

Apply this diff to fix the indentation:

-		Services.AddSingleton<TwVariant>();
-		JSInterop.Setup<int>( "Lumex.elementReference.getScrollHeight", _ => true );
+        Services.AddSingleton<TwVariant>();
+        JSInterop.Setup<int>( "Lumex.elementReference.getScrollHeight", _ => true );

61-61: Address the TODO comment.

The TODO comment indicates that additional test coverage is needed. Since this PR introduces variant-based styling, we should add tests to verify that the Collapse component correctly applies variant styles.

Would you like me to help generate additional test cases for:

  1. Variant style application
  2. Variant style overrides
  3. Default variant behavior

24-59: Consider adding variant-specific test cases.

The existing test methods provide good coverage of core functionality. However, with the introduction of variant-based styling, consider adding test cases to verify:

  1. Default variant application
  2. Custom variant overrides
  3. Dynamic variant changes
  4. Variant inheritance

Would you like me to help generate these additional test cases?

tests/LumexUI.Tests/Components/Popover/PopoverTests.razor (1)

25-32: Consider extracting test data to improve maintainability.

The test markup is duplicated across multiple test methods. Consider extracting common test data to reduce duplication and improve maintainability.

Example approach:

private static RenderFragment GetBasicPopover(string triggerText = "Show Popover") => builder =>
{
    builder.OpenComponent<LumexPopover>(0);
    builder.AddContent(1,
        @<text>
            <LumexPopoverTrigger>@triggerText</LumexPopoverTrigger>
            <LumexPopoverContent>
                <p>This is the content of the popover.</p>
            </LumexPopoverContent>
        </text>);
    builder.CloseComponent();
};

Then use it in tests:

var cut = Render(GetBasicPopover());

Also applies to: 40-47, 62-69, 116-131, 152-159

docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Usage.razor (3)

5-8: Enhance accessibility for the popover trigger button.

Consider adding ARIA attributes to improve accessibility:

 <LumexButton OnClick="@TriggerAsync"
-             data-popoverref="@_popoverId">
+             data-popoverref="@_popoverId"
+             aria-haspopup="true"
+             aria-expanded="false"
+             aria-controls="@_popoverId">

10-17: Enhance semantic structure of the popover content.

Consider adding semantic improvements for better accessibility and user experience:

-<LumexPopover Id="@_popoverId">
+<LumexPopover Id="@_popoverId" role="dialog" aria-modal="true">
     <LumexPopoverContent>
-        <div class="px-1 py-2">
+        <div class="px-1 py-2" role="document">
-            <div class="text-small font-bold">Oh, hi there!</div>
-            <div class="text-tiny">I am the popover content</div>
+            <h2 class="text-small font-bold">Oh, hi there!</h2>
+            <p class="text-tiny">I am the popover content</p>
+            <button class="mt-2" @onclick="TriggerAsync" aria-label="Close popover">
+                Close
+            </button>
         </div>
     </LumexPopoverContent>
 </LumexPopover>

19-26: Consider improving the robustness of the code-behind implementation.

The implementation is clean, but consider these improvements:

 @code {
-    private string _popoverId = "popover-usage";
+    private string _popoverId = $"popover-usage-{Guid.NewGuid():N}";

     private Task TriggerAsync()
     {
-        return PopoverService.TriggerAsync(_popoverId);
+        try
+        {
+            return PopoverService.TriggerAsync(_popoverId);
+        }
+        catch (Exception ex)
+        {
+            // Log the error or handle it appropriately
+            return Task.CompletedTask;
+        }
     }
 }
tests/LumexUI.Tests/Components/RadioGroup/RadioGroupTests.cs (1)

18-20: Fix indentation inconsistency.

The indentation of the service registrations is inconsistent. Line 18 uses spaces while lines 19-20 use tabs.

Apply this diff to maintain consistent indentation:

-        Services.AddSingleton<TwMerge>();
-		Services.AddSingleton<TwVariant>();
-	}
+        Services.AddSingleton<TwMerge>();
+        Services.AddSingleton<TwVariant>();
+    }
src/LumexUI/Styles/Button.cs (2)

45-51: Consider adding XML documentation for size values.

While the implementation is clean, adding XML documentation to describe the exact dimensions and use cases for each size would improve maintainability.

+    /// <summary>
+    /// Gets the size-specific styles for the button.
+    /// </summary>
+    /// <param name="size">
+    /// Size.Small: 16px min-width, 32px height
+    /// Size.Medium: 20px min-width, 40px height
+    /// Size.Large: 24px min-width, 48px height
+    /// </param>
     private static ElementClass GetSizeStyles(Size size)

62-68: Consider extracting duplicated border styles.

The border-2 bg-transparent styles are duplicated for both Outlined and Ghost variants.

     private static ElementClass GetVariantStyles(Variant variant)
     {
+        var transparentStyle = "bg-transparent";
+        var borderedTransparentStyle = $"border-2 {transparentStyle}";
         return ElementClass.Empty()
-            .Add("border-2 bg-transparent", when: variant is Variant.Outlined)
-            .Add("border-2 bg-transparent", when: variant is Variant.Ghost)
-            .Add("bg-transparent", when: variant is Variant.Light);
+            .Add(borderedTransparentStyle, when: variant is Variant.Outlined)
+            .Add(borderedTransparentStyle, when: variant is Variant.Ghost)
+            .Add(transparentStyle, when: variant is Variant.Light);
src/LumexUI/Components/Popover/LumexPopoverContent.razor (1)

10-14: Verify ARIA attributes for dialog accessibility.

While the dialog role is correctly set, consider adding aria-modal and aria-labelledby attributes to enhance accessibility.

 <div role="dialog"
+     aria-modal="true"
+     aria-labelledby="@($"popover-{Popover.Id}-title")"
      class="@Popover.Slots["Base"](Popover.Classes?.Base, Popover.Class)"
      tabindex="-1"
tests/LumexUI.Tests/Components/RadioGroup/RadioTests.cs (2)

19-20: Fix indentation inconsistency.

The indentation of the closing brace uses tabs instead of spaces. This inconsistency should be fixed to maintain uniform code formatting.

-		Services.AddSingleton<TwVariant>();
-	}
+        Services.AddSingleton<TwVariant>();
+    }

22-32: Consider adding variant-related test cases.

While the existing test covers the radio group constraint, consider adding test cases to verify the component's behavior with different variants, given the new TwVariant service integration.

Would you like me to help generate additional test cases for variant-related scenarios?

docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/_Radius.razor (2)

5-7: Leverage the implicit string conversion when building IDs.

You can shorten the expression by removing the explicit .ToString() call since string interpolation can handle enumeration values automatically:

- var id = $"popover-radius-{radius.ToString()}";
+ var id = $"popover-radius-{radius}";

9-14: Consider accessibility enhancements for the popover-triggering button.

While the current setup is functional, consider adding ARIA attributes or labeling to improve accessibility (e.g., aria-haspopup="true", aria-controls="...").

docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Sizes.razor (1)

27-30: Consider handling potential errors from TriggerAsync.
As it stands, returning PopoverService.TriggerAsync(id) is acceptable if the service handles its own internal errors or retries. If there’s a possibility of exceptions, consider using a try/catch block or error logging to enhance debugging.

src/LumexUI/Services/Popover/PopoverService.cs (1)

26-29: Consider handling duplicate popover IDs.

If another popover with the same Id is already added, Add(id, popover) will throw an exception. Decide whether to overwrite, skip, or throw a custom exception if duplicates occur.

src/LumexUI.Variants/TwVariant.cs (1)

15-100: Ensure safe handling of non-existent variant values.

The multi-step merging logic is structured well, but consider gracefully handling cases where selectedValue might not appear in values. Currently, the code does:

if (!string.IsNullOrEmpty(selectedValue) && values[selectedValue] is SlotCollection variantSlots)
{
    ...
}

If selectedValue is not in values, this pattern is fine as is, but double-check that it won't cause runtime issues or confusion. Otherwise, the logic is well-organized.

src/LumexUI/Styles/Popover.cs (1)

16-18: Consider potential concurrency or multi-usage implications of static ComponentVariant? _variant.
Storing variant configuration in a static field could lead to inconsistent styling across different usages of the Popover class if multiple components manipulate _variant in parallel or in different contexts. Consider using a caching dictionary keyed by relevant style parameters or storing this variant configuration in instance scope if you anticipate complex usage scenarios.

src/LumexUI/Styles/Menu.cs (1)

16-606: Reduce repetition in compound variants by introducing helper functions or centralized mappings.
The extensive blocks of repeated CompoundVariant definitions may hinder maintainability. Creating reusable functions or dictionaries can streamline the process of registering hover effects for each variant-color combination, making it simpler to extend and reduce the risk of errors.

src/LumexUI/Components/Dropdown/LumexDropdown.razor (1)

1-8: LGTM! Well-structured dropdown implementation.

The component correctly inherits from LumexPopover and properly uses CascadingValue for context sharing.

Consider adding XML documentation and clarifying builder naming.

  1. Add XML documentation comments to describe the component's purpose and usage.
  2. Consider renaming __builder2 to a more descriptive name like builder for better clarity.
src/LumexUI.Variants/CompoundVariant.cs (1)

7-12: Add XML documentation and consider making properties init-only.

The class and its properties would benefit from XML documentation to explain their purpose and usage. Additionally, consider making the properties init-only to promote immutability.

Apply this diff to improve documentation and immutability:

+/// <summary>
+/// Represents a compound variant that combines conditions with associated classes.
+/// </summary>
 public class CompoundVariant
 {
+    /// <summary>
+    /// Gets or sets the conditions that determine when this variant applies.
+    /// </summary>
-    public Dictionary<string, string> Conditions { get; set; } = [];
+    public Dictionary<string, string> Conditions { get; init; } = [];

+    /// <summary>
+    /// Gets or sets the collection of classes to apply when conditions are met.
+    /// </summary>
-    public SlotCollection Classes { get; set; } = [];
+    public SlotCollection Classes { get; init; } = [];
 }
src/LumexUI.Variants/Extensions/SeviceCollectionExtensions.cs (3)

11-15: Complete the XML documentation.

The XML documentation for the AddTailwindVariants method is empty. Please add a description of what the method does and the purpose of the services parameter.


18-18: Remove or implement the commented code.

The commented registration for TwMerge should either be implemented if needed or removed if not required.


1-21: Fix the filename typo.

The filename contains a typo: "SeviceCollectionExtensions.cs" should be "ServiceCollectionExtensions.cs".

src/LumexUI/Extensions/ParameterViewExtensions.cs (1)

11-11: Justify the exclusion from code coverage.

The [ExcludeFromCodeCoverage] attribute suggests this utility method isn't being tested. Consider removing this attribute and adding unit tests to ensure reliability, as this method could be critical for parameter handling across components.

Would you like me to help create unit tests for this extension method?

src/LumexUI.Variants/CompoundVariantCollection.cs (1)

9-23: LGTM! Clean collection implementation with modern C# features.

The implementation is concise and correctly implements IEnumerable<CompoundVariant>. Consider these potential enhancements for future iterations:

  1. Add methods like Remove, Clear, etc., for better collection management
  2. Consider implementing ICollection<T> for richer collection functionality
  3. Add capacity management for performance optimization
tests/LumexUI.Tests/Extensions/AngleSharpExtensions.cs (1)

11-21: Add logging and specific exception handling.

The error handling could be improved in the following ways:

  1. Add logging for caught exceptions to aid debugging
  2. Catch specific exceptions instead of all exceptions
  3. Consider adding XML documentation to clarify the null return case
+using Microsoft.Extensions.Logging;

 internal static class AngleSharpExtensions
 {
-    public static IElement? FindByTestId( this IRenderedFragment fragment, string id )
+    /// <summary>
+    /// Finds an element by its test ID.
+    /// </summary>
+    /// <returns>The element if found, null if not found or if an error occurs during search.</returns>
+    public static IElement? FindByTestId( this IRenderedFragment fragment, string id, ILogger? logger = null )
     {
         try
         {
             return fragment.Find( $"[data-testid={id}]" );
         }
-        catch
+        catch (Exception ex) when (ex is ArgumentException || ex is InvalidOperationException)
         {
+            logger?.LogDebug(ex, "Failed to find element with test ID: {Id}", id);
             return null;
         }
     }
docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/EmptyContent.razor (2)

5-9: Add accessibility attributes to improve user experience.

Consider adding ARIA attributes to enhance accessibility:

 <LumexButton Variant="@Variant.Outlined"
              OnClick="@TriggerAsync"
-             data-popoverref="@_dropdownId">
+             data-popoverref="@_dropdownId"
+             aria-haspopup="true"
+             aria-expanded="false"
+             aria-controls="@_dropdownId">
     Open Dropdown
 </LumexButton>

20-20: Consider using a GUID for the dropdown ID.

Using a hardcoded ID might cause conflicts if multiple instances of this component are rendered. Consider generating a unique ID:

-    private string _dropdownId = "dropdown-empty-content";
+    private string _dropdownId = $"dropdown-empty-content-{Guid.NewGuid():N}";
docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Arrow.razor (1)

20-20: Generate a unique ID for the popover.

Using a hardcoded ID could lead to conflicts if multiple instances of this component are used on the same page.

Apply this diff to generate a unique ID:

-    private string _popoverId = "popover-arrow";
+    private string _popoverId = $"popover-arrow-{Guid.NewGuid()}";
src/LumexUI/Styles/Dropdown.cs (1)

15-15: Reconsider using a singleton pattern for the variant.

The singleton pattern for _variant could be problematic if different variants are needed for different dropdown instances. Consider making this instance-specific or allowing variant overrides.

src/LumexUI.Variants/VariantConfig.cs (1)

7-13: Add XML documentation for the record and its properties.

Consider adding XML documentation to describe the purpose of the record and its properties, making it easier for other developers to understand their usage.

Add documentation like this:

+/// <summary>
+/// Represents a configuration for component variants, including base styles, slots, and variant collections.
+/// </summary>
 public record VariantConfig
 {
+    /// <summary>
+    /// Gets the base styles applied to the component.
+    /// </summary>
     public string? Base { get; init; }
+    /// <summary>
+    /// Gets the collection of slots for the component.
+    /// </summary>
     public SlotCollection? Slots { get; init; }
+    /// <summary>
+    /// Gets the collection of variants for the component.
+    /// </summary>
     public VariantCollection? Variants { get; init; }
+    /// <summary>
+    /// Gets the collection of compound variants for the component.
+    /// </summary>
     public CompoundVariantCollection? CompoundVariants { get; init; }
docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Colors.razor (2)

5-5: Consider documenting the reason for skipping the first enum value.

The code skips the first value of ThemeColor enum using [1..]. If this is intentionally skipping a default/none value, consider adding a comment explaining why.


26-29: Consider adding error handling for the async operation.

The TriggerAsync method directly returns the service call without error handling. Consider wrapping it in a try-catch block to handle potential failures gracefully.

 private Task TriggerAsync( string id )
 {
-    return PopoverService.TriggerAsync( id );
+    try
+    {
+        return PopoverService.TriggerAsync( id );
+    }
+    catch (Exception ex)
+    {
+        // Log error or show user-friendly message
+        throw;
+    }
 }
docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/Usage.razor (2)

11-20: Consider adding ARIA labels for better accessibility.

The dropdown menu items could benefit from ARIA labels to improve accessibility.

-<LumexDropdownItem>New file</LumexDropdownItem>
+<LumexDropdownItem aria-label="Create new file">New file</LumexDropdownItem>
-<LumexDropdownItem>Edit file</LumexDropdownItem>
+<LumexDropdownItem aria-label="Edit existing file">Edit file</LumexDropdownItem>
-<LumexDropdownItem>Share file</LumexDropdownItem>
+<LumexDropdownItem aria-label="Share file with others">Share file</LumexDropdownItem>
-<LumexDropdownItem Color="@ThemeColor.Danger" Class="text-danger">
+<LumexDropdownItem Color="@ThemeColor.Danger" Class="text-danger" aria-label="Delete file permanently">
     Delete file
 </LumexDropdownItem>

23-23: Consider using a constant for the dropdown ID.

The dropdown ID is hardcoded as a string. Consider defining it as a constant to improve maintainability.

-private string _dropdownId = "dropdown-usage";
+private const string DropdownId = "dropdown-usage";
src/LumexUI/Common/Enums/MenuVariant.cs (1)

7-11: Consider enhancing documentation with usage examples.

The XML documentation is good but could be improved by adding code examples showing how to use each variant.

 /// <summary>
 /// Specifies the visual variants for menu-like components, 
 /// such as <see cref="LumexDropdown"/>, and others.
+/// <example>
+/// <code>
+/// var menu = new LumexDropdown { Variant = MenuVariant.Solid };
+/// </code>
+/// </example>
 /// </summary>
docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Shadows.razor (1)

9-14: Consider making button styling configurable.

The button styling (success color and flat variant) is hardcoded. Consider making it configurable to improve reusability.

+@code {
+    [Parameter]
+    public ThemeColor ButtonColor { get; set; } = ThemeColor.Success;
+
+    [Parameter]
+    public Variant ButtonVariant { get; set; } = Variant.Flat;
+}

-<LumexButton Color="@ThemeColor.Success"
-             Variant="@Variant.Flat"
+<LumexButton Color="@ButtonColor"
+             Variant="@ButtonVariant"
src/LumexUI.Variants/SlotCollection.cs (1)

1-34: Add XML documentation for public members.

Please add XML documentation for the class and its public members to improve code maintainability and IntelliSense support.

Add documentation like this:

+/// <summary>
+/// Represents a collection of slots and their associated values.
+/// </summary>
 public class SlotCollection : IEnumerable<KeyValuePair<string, string>>
 {
     private readonly Dictionary<string, string?> _dictionary = [];
 
+    /// <summary>
+    /// Gets or sets the value associated with the specified slot name.
+    /// </summary>
+    /// <param name="slotName">The name of the slot.</param>
+    /// <returns>The value associated with the slot, or null if the slot doesn't exist.</returns>
     public string? this[string slotName]
docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/Disabled.razor (1)

16-20: Enhance accessibility for disabled menu item.

Add ARIA attributes to improve accessibility for screen readers.

Apply this diff:

 <LumexDropdownItem Disabled="@true"
                    Color="@ThemeColor.Danger"
-                    Class="text-danger">
+                    Class="text-danger"
+                    aria-disabled="true"
+                    aria-label="Delete file (disabled)">
     Delete file
 </LumexDropdownItem>
src/LumexUI.Variants/VariantValueCollection.cs (1)

35-35: Fix inconsistent line ending.

Remove the extra blank line at the end of the file.

 }
-
src/LumexUI.Variants/VariantCollection.cs (2)

35-35: Fix inconsistent line ending.

Remove the extra blank line at the end of the file.

 }
-

11-11: Consider adding validation for variant names.

The collection allows any string as a variant name without validation. Consider adding checks for null, empty, or whitespace names.

Example implementation:

+private void ValidateVariantName(string variantName)
+{
+    if (string.IsNullOrWhiteSpace(variantName))
+    {
+        throw new ArgumentException("Variant name cannot be null or whitespace.", nameof(variantName));
+    }
+}

 public VariantValueCollection? this[string variantName]
 {
     get
     {
+        ValidateVariantName(variantName);
         _dictionary.TryGetValue(variantName, out var variantValues);
         return variantValues;
     }
     set
     {
+        ValidateVariantName(variantName);
         _dictionary[variantName] = value;
     }
 }

Also applies to: 26-27

docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/DisabledItems.razor (1)

11-22: Consider adding ARIA attributes for better accessibility.

While the disabled items are correctly implemented using the DisabledItems property, consider enhancing accessibility by adding ARIA attributes.

-<LumexDropdownMenu DisabledItems="@(["share", "delete"])">
+<LumexDropdownMenu DisabledItems="@(["share", "delete"])"
+                   aria-label="File operations">
     <LumexDropdownItem Id="@("new")">New file</LumexDropdownItem>
     <LumexDropdownItem Id="@("edit")">Edit file</LumexDropdownItem>
-    <LumexDropdownItem Id="@("share")">Share file</LumexDropdownItem>
+    <LumexDropdownItem Id="@("share")"
+                       aria-disabled="true">Share file</LumexDropdownItem>
-    <LumexDropdownItem Id="@("delete")"
-                       Color="@ThemeColor.Danger"
-                       Class="text-danger">
+    <LumexDropdownItem Id="@("delete")"
+                       Color="@ThemeColor.Danger"
+                       Class="text-danger"
+                       aria-disabled="true">
         Delete file
     </LumexDropdownItem>
docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Placements.razor (1)

5-27: Consider using CSS Grid areas for better layout control.

While the current layout using flex and grid works, consider using CSS Grid areas for more precise control over the placement examples.

-<div class="flex flex-wrap md:inline-grid md:grid-cols-3 gap-4">
+<div class="grid grid-areas-placement gap-4">
src/LumexUI/Components/Dropdown/LumexDropdown.razor.cs (1)

17-19: Consider initializing _slots in the constructor.

The _slots field is initialized using collection expression syntax, but it might be clearer to initialize it in the constructor along with other fields.

-private Dictionary<string, ComponentSlot> _slots = [];
+private Dictionary<string, ComponentSlot> _slots;

 public LumexDropdown()
 {
     _context = new DropdownContext(this);
+    _slots = new Dictionary<string, ComponentSlot>();
src/LumexUI/Components/Menu/MenuSlots.cs (2)

21-22: Consider adding a migration guide for the deprecated Root slot.

The Root property is marked as obsolete, but it would be helpful to provide more detailed migration instructions in the deprecation message.

-[Obsolete("Deprecated. This will be removed in the future releases. Use the 'Base' slot instead.")]
+[Obsolete("Deprecated. This will be removed in v2.0.0. Migrate to the 'Base' slot by replacing Root with Base in your slot assignments. For example: Classes.Root = 'my-class' becomes Classes.Base = 'my-class'.")]

27-37: Consider adding validation for slot class names.

The slot properties accept any string value without validation. Consider adding validation to ensure class names follow CSS naming conventions.

+using System.Text.RegularExpressions;

 public class MenuSlots : ISlot
 {
+    private static readonly Regex ValidClassNamePattern = new("^[a-zA-Z0-9_-][a-zA-Z0-9_-]*$");
+    private string? _base;
+    private string? _list;
+    private string? _emptyContent;
+
+    private void ValidateClassName(string? value, string propertyName)
+    {
+        if (value is not null && !ValidClassNamePattern.IsMatch(value))
+        {
+            throw new ArgumentException($"Invalid CSS class name: {value}", propertyName);
+        }
+    }
+
     public string? Base
     {
-        get; set;
+        get => _base;
+        set
+        {
+            ValidateClassName(value, nameof(Base));
+            _base = value;
+        }
     }
src/LumexUI/Services/Popover/IPopoverService.cs (1)

35-40: Complete the XML documentation for TriggerAsync.

The XML documentation for the TriggerAsync method is incomplete. Please add descriptions for the method, parameter, and return value.

Apply this diff to improve the documentation:

 /// <summary>
-/// 
+/// Triggers the popover with the specified identifier.
 /// </summary>
-/// <param name="id"></param>
-/// <returns></returns>
+/// <param name="id">The unique identifier of the popover to trigger.</param>
+/// <returns>A task representing the asynchronous operation.</returns>
src/LumexUI/Components/Dropdown/LumexDropdownItem.cs (1)

41-52: Consider using StateHasChanged instead of Rerender.

The Rerender call after async operations might be better handled using StateHasChanged(). This would be more idiomatic in Blazor and could prevent potential race conditions.

Apply this diff to improve the implementation:

 private protected override async Task OnClickAsync( MouseEventArgs args )
 {
   if( _disabled || ReadOnly )
   {
     return;
   }

   await Dropdown.HideAsync();
   await OnClick.InvokeAsync( args );

-  Dropdown.Rerender();
+  StateHasChanged();
 }
src/LumexUI/Components/Menu/Menu.razor (2)

14-20: Follow consistent slot naming conventions.

The slot names "Base" and "List" should follow a consistent naming pattern. Consider using kebab-case for all slot names to match the "empty-content" slot.

-            <div class="@_slots["Base"]( Classes?.Base, Class )"
+            <div class="@_slots["base"]( Classes?.Base, Class )"
                 style="@Style"
                 data-slot="base"
                 @attributes="@AdditionalAttributes">
                <LumexComponent As="@As"
-                            Class="@_slots["List"]( Classes?.List )"
+                            Class="@_slots["list"]( Classes?.List )"
                            data-slot="list">

35-41: Optimize rendering for large item collections.

The current implementation iterates through all items synchronously. Consider implementing virtualization or pagination for better performance with large lists.

src/LumexUI/Components/Dropdown/LumexDropdownMenu.cs (2)

17-28: Enhance parameter documentation.

The XML documentation for Classes and ItemClasses parameters should include examples and explain the inheritance relationship with the base Menu class.


46-51: Add error handling for BuildRenderTree.

The BuildRenderTree method should include error handling for cases where the base.BuildRenderTree delegate fails.

 protected override void BuildRenderTree( RenderTreeBuilder builder )
 {
     builder.OpenComponent<LumexPopoverContent>( 0 );
-    builder.AddComponentParameter( 1, nameof( ChildContent ), (RenderFragment)base.BuildRenderTree );
+    builder.AddComponentParameter( 1, nameof( ChildContent ), (RenderFragment)(builderInner =>
+    {
+        try
+        {
+            base.BuildRenderTree(builderInner);
+        }
+        catch (Exception ex)
+        {
+            // Log error and render fallback content
+            builderInner.AddMarkupContent(0, "<div class=\"error\">Failed to render menu content</div>");
+        }
+    }));
     builder.CloseComponent();
 }
tests/LumexUI.Tests/Components/Card/CardTests.cs (1)

18-20: Add tests for variant functionality.

With the addition of TwVariant service, consider adding tests to verify variant-specific behavior of the Card component.

[Fact]
public void Card_WithVariant_ShouldRenderCorrectly()
{
    var variant = "custom";
    var component = RenderComponent<LumexCard>(p => p
        .Add(c => c.Variant, variant));
    
    component.MarkupMatches($"<div class=\"custom-variant\">");
}
docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/StartEndContent.razor (1)

31-50: Refactor icon definitions for better maintainability.

Consider extracting the icon definitions to a separate method or component to improve code organization and reusability.

+private RenderFragment CreateIcon(string icon, bool isDanger = false) =>
+    @<LumexIcon Icon="@icon"
+                Size="@new("20")"
+                Class="@(isDanger ? "shrink-0" : "text-default-500 shrink-0")" />;

-private RenderFragment _newFile =
-    @<LumexIcon Icon="@Icons.Rounded.LibraryAdd"
-       Size="@new("20")"
-       Class="text-default-500 shrink-0" />;
+private RenderFragment _newFile = CreateIcon(Icons.Rounded.LibraryAdd);
src/LumexUI/Components/Menu/MenuItem.razor (2)

4-6: Add error handling for context registration.

Consider adding error handling to gracefully handle potential registration failures.

@{
+    try {
         Context.Register( this );
+    }
+    catch (Exception ex) {
+        // Log the error or handle it appropriately
+        Console.WriteLine($"Failed to register MenuItem: {ex.Message}");
+    }
}

9-13: Complete the XML documentation.

The XML documentation is missing content. Please add a description of the method and its parameter.

/// <summary>
-///
+/// Renders the menu item component using the provided RenderTreeBuilder.
/// </summary>
-/// <param name="__builder"></param>
+/// <param name="__builder">The RenderTreeBuilder instance used to construct the component's render tree.</param>
docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/ColorsVariants.razor (1)

31-40: Consider adding a tooltip for color selection.

The color selection UI could benefit from tooltips explaining the impact of each color on the dropdown's appearance.

-        <LumexRadio Value="@color" Color="@color">
+        <LumexRadio Value="@color" Color="@color" Title="@($"Apply {color} theme to dropdowns")">
docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/Description.razor (1)

35-53: Reduce code duplication in icon definitions.

Consider extracting common icon properties into a reusable method or component to reduce duplication.

+    private RenderFragment CreateIcon(string icon, bool isDanger = false) =>
+        @<LumexIcon Icon="@icon"
+                    Size="@new("20")"
+                    Class="@($"{(isDanger ? "" : "text-default-500")} shrink-0")" />;
+
     private RenderFragment _newFile =
-        @<LumexIcon Icon="@Icons.Rounded.LibraryAdd"
-                    Size="@new("20")"
-                    Class="text-default-500 shrink-0" />;
+        CreateIcon(Icons.Rounded.LibraryAdd);

     // Apply similar changes to other icon definitions
src/LumexUI/Components/Menu/Menu.razor.cs (1)

60-60: Consider using the new collection expression syntax.

The empty dictionary initialization can be simplified using the new collection expression syntax.

-private Dictionary<string, ComponentSlot> _slots = [];
+private Dictionary<string, ComponentSlot> _slots = {};
src/LumexUI/Components/Popover/LumexPopoverTrigger.razor.cs (1)

17-17: Consider adding a migration guide link.

The obsolete message should include a link to the migration guide or documentation explaining the new approach.

-[Obsolete("Deprecated. This will be removed in the future releases. See the Popover usage in the docs.")]
+[Obsolete("Deprecated. This will be removed in the future releases. See the migration guide at https://lumexui.com/docs/migration/popover")]
docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/CustomStyles.razor (1)

34-41: Consider using LumexSelect for theme selection.

The native select element breaks the consistent styling of the dropdown menu. Consider using the LumexSelect component for better UI consistency.

-                <select id="theme"
-                        name="theme"
-                        class="z-10 outline-none w-16 py-0.5 rounded-md text-tiny group-hover:border-default-500 border border-default-300 bg-transparent text-default-500">
-                    <option>Light</option>
-                    <option>Dark</option>
-                    <option>System</option>
-                </select>
+                <LumexSelect Id="theme" 
+                            Size="@Size.Small"
+                            Class="w-16">
+                    <LumexSelectItem Value="@("light")">Light</LumexSelectItem>
+                    <LumexSelectItem Value="@("dark")">Dark</LumexSelectItem>
+                    <LumexSelectItem Value="@("system")">System</LumexSelectItem>
+                </LumexSelect>
docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Dropdown.razor (2)

71-72: Fix typo in the Custom Styles section.

There's a typo in the word "supports".

-        This component suppots named slots (represented as <code>data-*</code> attributes) that
+        This component supports named slots (represented as <code>data-*</code> attributes) that

108-116: Remove commented-out code.

The commented-out DocsSlotsSection should be either implemented or removed to maintain code cleanliness.

-@* <DocsSlotsSection Slots="@_slots">
-    <div>
-        <h4 class="font-semibold">Dropdown</h4>
-        <ul>
-            <li><Code>Class</Code></li>
-            <li><Code>Classes</Code></li>
-        </ul>
-    </div>
-</DocsSlotsSection> *@
tests/LumexUI.Tests/Components/Dropdown/DropdownTests.razor (1)

16-37: Enhance test coverage with specific assertions.

While the test verifies basic rendering, consider adding more specific assertions to validate the rendered output, such as:

  • Verify the presence of specific elements (button, menu).
  • Check the correct nesting of components.
  • Validate the data attributes.
 [Fact]
 public void ShouldRenderCorrectly()
 {
     var id = "1";
-    var action = () => Render(
+    var cut = Render(
         @<text>
             <LumexButton data-popoverref="@id">
                 Trigger
             </LumexButton>
             <LumexDropdown Id="@id">
                 <LumexDropdownMenu>
                     <LumexDropdownItem>New file</LumexDropdownItem>
                     <LumexDropdownItem>Edit file</LumexDropdownItem>
                     <LumexDropdownItem>Share file</LumexDropdownItem>
                     <LumexDropdownItem>Delete file</LumexDropdownItem>
                 </LumexDropdownMenu>
             </LumexDropdown>
         </text>
     );

-    action.Should().NotThrow();
+    // Verify button
+    cut.Find("[data-popoverref]").Should().NotBeNull();
+    
+    // Verify dropdown structure
+    var dropdown = cut.Find($"#{id}");
+    dropdown.Should().NotBeNull();
+    
+    // Verify menu items
+    var items = cut.FindAll("li");
+    items.Should().HaveCount(4);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 234ef56 and 43e5c28.

📒 Files selected for processing (95)
  • LumexUI.sln (3 hunks)
  • docs/LumexUI.Docs.Client/Common/Navigation/NavigationStore.cs (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Dropdown.razor (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/ColorsVariants.razor (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/CustomStyles.razor (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/Description.razor (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/Disabled.razor (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/DisabledItems.razor (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/EmptyContent.razor (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/StartEndContent.razor (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/Usage.razor (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Dropdown/PreviewCodes/ColorsVariants.razor (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Dropdown/PreviewCodes/CustomStyles.razor (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Dropdown/PreviewCodes/Description.razor (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Dropdown/PreviewCodes/Disabled.razor (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Dropdown/PreviewCodes/DisabledItems.razor (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Dropdown/PreviewCodes/EmptyContent.razor (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Dropdown/PreviewCodes/StartEndContent.razor (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Dropdown/PreviewCodes/Usage.razor (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Arrow.razor (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Colors.razor (2 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/CustomStyles.razor (2 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Offset.razor (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Placements.razor (2 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Shadows.razor (2 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Sizes.razor (2 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Usage.razor (1 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/_Radius.razor (2 hunks)
  • docs/LumexUI.Docs.Client/Pages/Components/Popover/Popover.razor (1 hunks)
  • src/LumexUI.Variants/CompoundVariant.cs (1 hunks)
  • src/LumexUI.Variants/CompoundVariantCollection.cs (1 hunks)
  • src/LumexUI.Variants/Extensions/SeviceCollectionExtensions.cs (1 hunks)
  • src/LumexUI.Variants/LumexUI.Variants.csproj (1 hunks)
  • src/LumexUI.Variants/SlotCollection.cs (1 hunks)
  • src/LumexUI.Variants/TwVariant.cs (1 hunks)
  • src/LumexUI.Variants/VariantCollection.cs (1 hunks)
  • src/LumexUI.Variants/VariantConfig.cs (1 hunks)
  • src/LumexUI.Variants/VariantValueCollection.cs (1 hunks)
  • src/LumexUI/Common/Enums/MenuVariant.cs (1 hunks)
  • src/LumexUI/Components/Bases/LumexComponentBase.cs (2 hunks)
  • src/LumexUI/Components/Dropdown/DropdownContext.cs (1 hunks)
  • src/LumexUI/Components/Dropdown/DropdownItemSlots.cs (1 hunks)
  • src/LumexUI/Components/Dropdown/DropdownMenuSlots.cs (1 hunks)
  • src/LumexUI/Components/Dropdown/LumexDropdown.razor (1 hunks)
  • src/LumexUI/Components/Dropdown/LumexDropdown.razor.cs (1 hunks)
  • src/LumexUI/Components/Dropdown/LumexDropdownItem.cs (1 hunks)
  • src/LumexUI/Components/Dropdown/LumexDropdownMenu.cs (1 hunks)
  • src/LumexUI/Components/Menu/Menu.razor (1 hunks)
  • src/LumexUI/Components/Menu/Menu.razor.cs (1 hunks)
  • src/LumexUI/Components/Menu/MenuContext.cs (1 hunks)
  • src/LumexUI/Components/Menu/MenuItem.razor (1 hunks)
  • src/LumexUI/Components/Menu/MenuItem.razor.cs (1 hunks)
  • src/LumexUI/Components/Menu/MenuItemSlots.cs (1 hunks)
  • src/LumexUI/Components/Menu/MenuSlots.cs (1 hunks)
  • src/LumexUI/Components/Popover/LumexPopover.razor.cs (2 hunks)
  • src/LumexUI/Components/Popover/LumexPopoverContent.razor (1 hunks)
  • src/LumexUI/Components/Popover/LumexPopoverContent.razor.cs (1 hunks)
  • src/LumexUI/Components/Popover/LumexPopoverTrigger.razor.cs (1 hunks)
  • src/LumexUI/Components/Popover/PopoverSlots.cs (1 hunks)
  • src/LumexUI/Extensions/ParameterViewExtensions.cs (1 hunks)
  • src/LumexUI/Extensions/ServiceCollectionExtensions.cs (3 hunks)
  • src/LumexUI/LumexUI.csproj (1 hunks)
  • src/LumexUI/Services/Popover/IPopoverService.cs (1 hunks)
  • src/LumexUI/Services/Popover/PopoverService.cs (2 hunks)
  • src/LumexUI/Styles/Button.cs (1 hunks)
  • src/LumexUI/Styles/Dropdown.cs (1 hunks)
  • src/LumexUI/Styles/Menu.cs (1 hunks)
  • src/LumexUI/Styles/Popover.cs (1 hunks)
  • src/LumexUI/Theme/Colors/SemanticColors.cs (1 hunks)
  • tests/LumexUI.Tests/Components/Accordion/AccordionTests.cs (2 hunks)
  • tests/LumexUI.Tests/Components/Bases/InputBaseTests.cs (2 hunks)
  • tests/LumexUI.Tests/Components/Button/ButtonTests.cs (2 hunks)
  • tests/LumexUI.Tests/Components/Card/CardTests.cs (2 hunks)
  • tests/LumexUI.Tests/Components/Checkbox/CheckboxGroupTests.cs (2 hunks)
  • tests/LumexUI.Tests/Components/Checkbox/CheckboxTests.cs (2 hunks)
  • tests/LumexUI.Tests/Components/Collapse/CollapseTests.cs (2 hunks)
  • tests/LumexUI.Tests/Components/DataGrid/DataGridTests.razor (1 hunks)
  • tests/LumexUI.Tests/Components/Divider/DividerTests.cs (2 hunks)
  • tests/LumexUI.Tests/Components/Dropdown/DropdownTests.razor (1 hunks)
  • tests/LumexUI.Tests/Components/Icon/IconTests.cs (2 hunks)
  • tests/LumexUI.Tests/Components/Link/LinkTests.cs (2 hunks)
  • tests/LumexUI.Tests/Components/Listbox/ListboxTests.razor (1 hunks)
  • tests/LumexUI.Tests/Components/Navbar/NavbarTests.razor (1 hunks)
  • tests/LumexUI.Tests/Components/Numbox/NumboxTests.razor (1 hunks)
  • tests/LumexUI.Tests/Components/Popover/PopoverTests.razor (1 hunks)
  • tests/LumexUI.Tests/Components/Providers/ThemeProviderTests.cs (1 hunks)
  • tests/LumexUI.Tests/Components/RadioGroup/RadioGroupTests.cs (2 hunks)
  • tests/LumexUI.Tests/Components/RadioGroup/RadioTests.cs (2 hunks)
  • tests/LumexUI.Tests/Components/Select/SelectTests.razor (1 hunks)
  • tests/LumexUI.Tests/Components/Switch/SwitchTests.cs (2 hunks)
  • tests/LumexUI.Tests/Components/Tabs/TabsTests.razor (1 hunks)
  • tests/LumexUI.Tests/Components/Textbox/TextboxTests.razor (1 hunks)
  • tests/LumexUI.Tests/Extensions/AngleSharpExtensions.cs (1 hunks)
  • tests/LumexUI.Tests/LumexUI.Tests.csproj (1 hunks)
  • tests/LumexUI.Tests/_Imports.razor (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • docs/LumexUI.Docs.Client/Common/Navigation/NavigationStore.cs
  • tests/LumexUI.Tests/_Imports.razor
  • src/LumexUI.Variants/LumexUI.Variants.csproj
🧰 Additional context used
🪛 GitHub Check: build-test
src/LumexUI/Styles/Popover.cs

[warning] 45-45:
'PopoverSlots.Trigger' is obsolete: 'Deprecated. This will be removed in the future releases. Use the 'Base' slot instead.'

🪛 GitHub Check: codecov/patch
src/LumexUI/Components/Popover/LumexPopoverTrigger.razor.cs

[warning] 62-62: src/LumexUI/Components/Popover/LumexPopoverTrigger.razor.cs#L62
Added line #L62 was not covered by tests


[warning] 66-67: src/LumexUI/Components/Popover/LumexPopoverTrigger.razor.cs#L66-L67
Added lines #L66 - L67 were not covered by tests

src/LumexUI/Services/Popover/PopoverService.cs

[warning] 46-46: src/LumexUI/Services/Popover/PopoverService.cs#L46
Added line #L46 was not covered by tests

src/LumexUI/Components/Popover/LumexPopover.razor.cs

[warning] 141-141: src/LumexUI/Components/Popover/LumexPopover.razor.cs#L141
Added line #L141 was not covered by tests


[warning] 160-161: src/LumexUI/Components/Popover/LumexPopover.razor.cs#L160-L161
Added lines #L160 - L161 were not covered by tests

src/LumexUI/Components/Popover/LumexPopoverContent.razor.cs

[warning] 67-67: src/LumexUI/Components/Popover/LumexPopoverContent.razor.cs#L67
Added line #L67 was not covered by tests

🔇 Additional comments (106)
tests/LumexUI.Tests/Components/Select/SelectTests.razor (1)

12-12: LGTM! Service registration aligns with variant system integration.

The singleton registration of TwVariant is consistent with other service registrations and supports the new variant configuration system.

tests/LumexUI.Tests/Components/DataGrid/DataGridTests.razor (2)

20-21: LGTM! Service registration aligns with variant system integration.

The addition of TwVariant service registration alongside TwMerge is consistent with the broader changes to integrate the variant configuration system.


29-731: Comprehensive test coverage maintained.

The test suite provides thorough coverage of DataGrid functionality including:

  • Basic rendering
  • Empty/loading states
  • Selection modes
  • Sorting
  • Editing
  • Validation
  • Error handling

The unchanged tests suggest backward compatibility with the variant system integration.

tests/LumexUI.Tests/Components/Textbox/TextboxTests.razor (1)

12-14: LGTM! Consider adding variant-specific test cases.

The addition of the TwVariant singleton service aligns with the variant system integration. While the service registration is correct, consider adding test cases to verify the variant functionality of the Textbox component.

Would you like me to help generate test cases for variant-specific scenarios?

tests/LumexUI.Tests/Components/Checkbox/CheckboxGroupTests.cs (2)

5-5: LGTM!

The using statement is correctly placed and properly organized.


18-18: LGTM! Service registration aligns with the new variant system.

The TwVariant service is correctly registered as a singleton, matching the lifetime scope of the existing TwMerge service.

tests/LumexUI.Tests/Components/Divider/DividerTests.cs (1)

6-6: LGTM!

The import statement for LumexUI.Variants is correctly placed and necessary for the TwVariant service registration.

docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/CustomStyles.razor (3)

1-3: LGTM! Clean service integration.

The service setup follows Blazor's dependency injection pattern correctly.


5-8: LGTM! Well-structured trigger implementation.

The button implementation follows best practices with clear event handling and proper reference binding.


33-38: LGTM! Clean async implementation.

The trigger method follows async/await best practices with proper encapsulation of the popover ID.

tests/LumexUI.Tests/Components/Icon/IconTests.cs (3)

5-6: LGTM! Using statement properly organized.

The new using statement for LumexUI.Variants is correctly placed and follows the project's organization standards.


17-18: LGTM! Service registration properly configured.

The TwVariant service is correctly registered as a singleton, matching the registration pattern used for TwMerge and aligning with the broader variant system integration across test files.


21-39: Consider adding variant-related test cases.

With the introduction of the variant system, consider adding test cases that verify:

  1. Icon rendering with different variants
  2. Variant class application
  3. Variant style overrides

Would you like me to help generate additional test cases for variant-specific scenarios?

tests/LumexUI.Tests/Components/Switch/SwitchTests.cs (2)

16-20: Add test coverage for variant functionality.

The TwVariant service has been added, but there are no tests verifying its integration with the Switch component.

Consider adding test cases to verify:

  1. Default variant styling
  2. Custom variant application
  3. Variant overrides

22-136: Excellent test coverage for core functionality!

The test suite provides comprehensive coverage of the Switch component's features:

  • Basic rendering and child content
  • Icon customization (thumb, start, end positions)
  • Value changes and validation
  • Disabled/ReadOnly states
  • Async operations
tests/LumexUI.Tests/Components/Tabs/TabsTests.razor (1)

15-15: LGTM! Service registration follows the established pattern.

The TwVariant singleton registration aligns with the existing service registration pattern and integrates well with the test setup.

docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Offset.razor (3)

1-3: LGTM! Clean service injection setup.

The dependency injection follows Blazor best practices and aligns with the architectural shift to a service-based approach.


5-8: LGTM! Accessible button implementation.

The button implementation follows accessibility best practices by using data attributes for reference binding, and the click handler is properly bound to an async method.


19-26: LGTM! Clean and focused implementation.

The code-behind implementation follows C# best practices with proper async/await pattern usage and clear naming conventions.

tests/LumexUI.Tests/Components/Link/LinkTests.cs (2)

5-5: LGTM!

The using statement for the Variants namespace is correctly placed and organized with other using statements.


18-18: LGTM!

The TwVariant service is correctly registered as a singleton, consistent with the TwMerge registration pattern.

src/LumexUI/Theme/Colors/SemanticColors.cs (1)

39-40: Verify color contrast for accessibility.

The change from Zinc-50/Zinc-700 to White/Zinc-900 increases contrast, which is good for accessibility. However, let's verify the contrast ratio meets WCAG guidelines.

#!/usr/bin/env python3
import math

def luminance(r, g, b):
    rgb = [r/255, g/255, b/255]
    rgb = [x/12.92 if x <= 0.03928 else ((x+0.055)/1.055)**2.4 for x in rgb]
    return 0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2]

def contrast_ratio(l1, l2):
    lighter = max(l1, l2)
    darker = min(l1, l2)
    return (lighter + 0.05) / (darker + 0.05)

# White background (255, 255, 255)
white_lum = luminance(255, 255, 255)

# Zinc-900 foreground (24, 24, 27) - approximated values
zinc900_lum = luminance(24, 24, 27)

ratio = contrast_ratio(white_lum, zinc900_lum)
print(f"Contrast ratio: {ratio:.2f}")
print(f"Meets WCAG AA for normal text (4.5:1): {ratio >= 4.5}")
print(f"Meets WCAG AAA for normal text (7:1): {ratio >= 7}")

[skip_cloning]

tests/LumexUI.Tests/Components/Collapse/CollapseTests.cs (1)

5-5: LGTM!

The new using directive is correctly placed and necessary for the TwVariant service.

src/LumexUI/LumexUI.csproj (1)

61-64: New Project Reference Added for LumexUI.Variants.

The addition of <ProjectReference Include="..\LumexUI.Variants\LumexUI.Variants.csproj" /> integrates the new Variants project as intended. Please verify that the relative path is correct with respect to the current project file location.

tests/LumexUI.Tests/Components/Numbox/NumboxTests.razor (1)

13-14:

✅ Verification successful

LGTM! Verify broader integration with variant system.

The addition of the TwVariant service registration is consistent with the broader changes for variant support across components.

Let's verify the integration with other test files:


🏁 Script executed:

#!/bin/bash
# Description: Verify consistent TwVariant registration across test files

# Search for TwVariant service registration in test files
rg -l "Services\.AddSingleton<TwVariant>\(\)" "tests/LumexUI.Tests/Components"

# Search for any test files that might be missing the registration
fd -e razor$ . "tests/LumexUI.Tests/Components" --exec grep -L "Services\.AddSingleton<TwVariant>"

Length of output: 1408


TwVariant Registration Consistent Across All Test Files

The singleton registration for TwVariant is applied consistently in all component test files, including the one in NumboxTests.razor. No missing registrations were detected across the codebase.

tests/LumexUI.Tests/Components/Popover/PopoverTests.razor (2)

14-14: LGTM! Service registration for TwVariant is properly configured.

The singleton registration for TwVariant is correctly placed and follows the established pattern for service registration in the test context.


85-111: Verify if the commented-out test case is still relevant.

This test appears to cover an important edge case for popover behavior when triggering an already shown popover. If this is still a valid scenario, consider either:

  1. Implementing and enabling the test
  2. Adding a comment explaining why it's disabled
  3. Removing it if no longer needed
docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Usage.razor (1)

1-4: LGTM! Clean service injection implementation.

The service-based approach follows Blazor best practices with proper dependency injection and clear separation of concerns.

tests/LumexUI.Tests/Components/RadioGroup/RadioGroupTests.cs (2)

22-320: Test coverage looks comprehensive!

The test suite thoroughly covers various scenarios including:

  • Basic rendering and value changes
  • ReadOnly/Disabled states
  • Boolean parsing
  • Support for nullable value and reference types

The test methods are well-structured with clear assertions and error cases.


5-5:

✅ Verification successful

Verify if TwMerge is still needed.

Both TwMerge and TwVariant services are registered. If TwVariant is intended to replace TwMerge, consider removing the TwMerge registration to avoid potential confusion and redundancy.

Run this script to check if TwMerge is still used in the RadioGroup component:

Also applies to: 18-20


🏁 Script executed:

#!/bin/bash
# Search for TwMerge usage in RadioGroup-related files
rg -l "TwMerge" --type cs | grep -i "radiogroup"

Length of output: 217


Confirmed: TwMerge is still in use.
The search results indicate that TwMerge is referenced not only in the RadioGroupTests.cs file but also in RadioTests.cs and the main component file LumexRadioGroup.razor.cs. Given these findings, both the TwMerge and TwVariant services appear to be actively utilized. Please ensure that if a transition toward exclusively using TwVariant is intended, all references to TwMerge are removed and refactored accordingly.

  • Current Usage:
    • tests/LumexUI.Tests/Components/RadioGroup/RadioGroupTests.cs
    • tests/LumexUI.Tests/Components/RadioGroup/RadioTests.cs
    • src/LumexUI/Components/Radio/LumexRadioGroup.razor.cs

For now, retaining both registrations is necessary until a comprehensive refactor is pursued.

docs/LumexUI.Docs.Client/Pages/Components/Dropdown/PreviewCodes/StartEndContent.razor (2)

1-1: LGTM! Appropriate render mode for interactive components.

The InteractiveWebAssembly render mode is well-suited for the dropdown component as it enables client-side interactivity.


3-5:

✅ Verification successful

Verify the snippet path and consider improving maintainability.

The code looks good, but let's ensure the snippet path exists and consider using a constant for better maintainability.

Run this script to verify the snippet path:

Consider defining the snippet path as a constant to improve maintainability:

+@code {
+    private const string SnippetPath = "Dropdown.Code.StartEndContent";
+}
-<PreviewCode Code="@new(name: null, snippet: "Dropdown.Code.StartEndContent")">
+<PreviewCode Code="@new(name: null, snippet: SnippetPath)">

🏁 Script executed:

#!/bin/bash
# Description: Verify that the Dropdown.Code.StartEndContent snippet exists
rg -l "Dropdown\.Code\.StartEndContent" --type-add 'razor:*.razor' --type razor

Length of output: 167


Snippet path verified; consider a constant for improved maintainability.

  • The snippet path "Dropdown.Code.StartEndContent" was confirmed to exist.

  • The current inline usage is correct, but to enhance maintainability, consider defining the snippet path as a constant in the code block. For example:

    +@code {
    +    private const string SnippetPath = "Dropdown.Code.StartEndContent";
    +}
    -<PreviewCode Code="@new(name: null, snippet: "Dropdown.Code.StartEndContent")">
    +<PreviewCode Code="@new(name: null, snippet: SnippetPath)">
tests/LumexUI.Tests/Components/Checkbox/CheckboxTests.cs (1)

22-135: Test coverage looks comprehensive!

The test methods thoroughly cover component functionality, including rendering, interactions, state changes, and edge cases. The transition from TwMerge to TwVariant doesn't impact the test assertions as they focus on component behavior rather than styling implementation.

src/LumexUI/Styles/Button.cs (2)

15-34: LGTM! Well-structured base styles implementation.

The base styles are well-organized with clear separation of concerns (layout, typography, transitions, focus states). The use of ElementClass builder pattern makes the code maintainable and easy to understand.


108-121: LGTM! Well-structured composition of styles.

The GetStyles method effectively combines all style components in a logical order, with proper handling of states and options.

docs/LumexUI.Docs.Client/Pages/Components/Dropdown/PreviewCodes/EmptyContent.razor (1)

1-1: LGTM! Appropriate rendering mode for interactive components.

The InteractiveWebAssembly render mode is well-suited for dropdown components that require client-side interactivity.

tests/LumexUI.Tests/Components/Bases/InputBaseTests.cs (1)

7-7: LGTM!

The using directive is correctly placed and necessary for the TwVariant service.

src/LumexUI/Components/Popover/LumexPopoverContent.razor (3)

4-9: LGTM! State management refactor improves code clarity.

The refactoring from Context.Owner to Popover property improves readability while maintaining the same functionality. The wrapper's positioning and z-index ensure proper stacking context.


15-21: LGTM! Slot-based styling enhances customization.

The use of slots for styling provides better customization options while maintaining a clean separation of concerns.


22-26: LGTM! Arrow implementation follows best practices.

The arrow implementation using slots allows for consistent styling and positioning.

src/LumexUI/Components/Popover/LumexPopoverContent.razor.cs (2)

20-31: LGTM! Well-structured component setup with proper dependency injection.

The component is well-organized with clear parameter definitions and proper dependency injection.


69-88: LGTM! Robust disposal implementation with proper error handling.

The disposal implementation properly handles resource cleanup and gracefully handles client disconnection scenarios.

tests/LumexUI.Tests/Components/RadioGroup/RadioTests.cs (2)

6-6: LGTM! Import added for variant support.

The import is properly placed and necessary for the TwVariant service registration.


18-19:

❓ Verification inconclusive

Verify if both TwMerge and TwVariant services are needed.

Both services are registered as singletons. Based on the AI summary, there seems to be a transition from TwMerge to TwVariant across the codebase. Please verify if both services are required during this transition period.


🏁 Script executed:

#!/bin/bash
# Search for TwMerge usage in the codebase
echo "Searching for TwMerge usage..."
rg "TwMerge" -l

echo -e "\nSearching for TwVariant usage..."
rg "TwVariant" -l

Length of output: 4996


Confirm Service Registrations and Standardize Indentation

  • Both TwMerge and TwVariant are registered as singletons. The codebase search shows that references to both services exist across multiple files, suggesting they are concurrently needed during the transition phase. Please verify whether maintaining both registrations is still intentional or if the legacy service (TwMerge) can be phased out.
  • There is an indentation inconsistency in the registration block (one line uses spaces while the other uses a tab). Please update the formatting to conform to the project's styling guidelines.
docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/_Radius.razor (3)

1-3: Good use of dependency injection and service import.

Injecting IPopoverService is consistent with the new popover architecture. This is a straightforward and effective approach to keep UI logic cleanly separated from the service layer.


16-16: Popover setup looks correct.

Using the dynamic id for both button and popover ensures a direct reference link, aligning well with the new popover architecture.


27-30: Asynchronous signature is appropriate for service-based triggers.

Returning the Task from PopoverService.TriggerAsync is concise. If adding further logic, mark the method async and use await. For now, this is sufficient.

docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Sizes.razor (2)

1-3: No issues detected with the added using statement and service injection.
The import and injection of IPopoverService are well-structured and align with service-oriented best practices.


5-16: Ensure compatibility with older .NET versions.
Enum.GetValues<TEnum>() is available starting from .NET 5. If you plan to support older versions, consider using Enum.GetValues(typeof(Size)) and casting to Size. Otherwise, this approach is concise and clear. Additionally, the dynamic runtime generation of popover elements via enumeration is a good pattern.

Would you like a script to search your project files for .csproj frameworks, to verify you’re already on .NET 5+?

src/LumexUI/Services/Popover/PopoverService.cs (1)

35-36: Unregistration behavior looks fine.

Removing a popover by Id gracefully handles scenarios where the Id might not exist, returning false without throwing. This logic is acceptable unless you need explicit feedback when removal fails.

src/LumexUI.Variants/TwVariant.cs (2)

1-14: File header and delegates look good.

The licensing information, namespaces, and delegate signatures are appropriate. No immediate issues or suggestions here.


102-107: Override retrieval is straightforward.

GetOverrideValue returning an empty string as a fallback is logically consistent and succinct.

src/LumexUI/Components/Menu/MenuItem.razor.cs (9)

1-14: File header and namespace usage.

Licensing, using statements, and namespace definition follow a consistent pattern. Nothing problematic here.


15-39: Parameter definitions for content and ID.

The usage of [Parameter] for ChildContent, StartContent, EndContent, and Id is clear. Generating unique IDs with Identifier.New() is helpful, though you may want to confirm if collisions are possible across the application lifetime.


40-60: Variant and color defaults are well-defined.

Providing default values (e.g., MenuVariant.Solid and ThemeColor.Default) ensures consistent styling if parameters are not explicitly set by the consumer.


61-80: Clickable, disabled, and divider configuration look good.

The design is flexible, giving users the option to mark items as read-only, disabled, or visually separated with a divider. The OnClick callback parameter aligns with standard Blazor patterns.


81-96: Constructor and _slots initialization.

Defining As = "li" in the constructor clarifies the default HTML tag for this component. _slots = [] is presumably a shorthand for an empty dictionary if you're targeting newer C# versions; verify it compiles as expected across your supported runtime environments.


98-108: Parameter fallback logic is elegant.

Using GetParameterProperty to respect local parameter settings before falling back to Menu properties is a solid approach.


110-115: Cascading context check is valid.

Throwing an exception if Context is null ensures that the component is only used within a valid Menu context, preventing runtime confusion.


116-130: Slot-building logic is robust.

Merging styles/slots with TwVariant neatly encapsulates the styling concerns in one place. This approach is coherent with the library’s variant-based design.


132-133: Abstract click handler.

Declaring OnClickAsync as abstract encourages derived classes to provide their specific click logic. This design fosters consistency across different menu items.

src/LumexUI/Components/Popover/LumexPopover.razor.cs (1)

141-161: Increase test coverage for the parameter validation and popover toggling logic.
Lines 141 and 160-161 are not covered by tests. The exception path at line 141 (ID not set) and the logic at lines 160-161 (unsetting last shown popover) should be validated with unit tests to ensure code correctness and prevent regressions.

Would you like assistance generating unit tests to cover these code paths?

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 141-141: src/LumexUI/Components/Popover/LumexPopover.razor.cs#L141
Added line #L141 was not covered by tests


[warning] 160-161: src/LumexUI/Components/Popover/LumexPopover.razor.cs#L160-L161
Added lines #L160 - L161 were not covered by tests

docs/LumexUI.Docs.Client/Pages/Components/Dropdown/PreviewCodes/Usage.razor (1)

1-5: LGTM! Well-structured documentation example.

The component follows the standard documentation pattern and correctly uses InteractiveWebAssembly for interactive functionality.

docs/LumexUI.Docs.Client/Pages/Components/Dropdown/PreviewCodes/Disabled.razor (1)

1-5: LGTM! Consistent with documentation standards.

The component maintains consistency with other preview code files and correctly implements the disabled dropdown example.

docs/LumexUI.Docs.Client/Pages/Components/Dropdown/PreviewCodes/Description.razor (1)

1-5: LGTM! Maintains documentation consistency.

The component follows the established pattern for preview code files and correctly implements the description example.

docs/LumexUI.Docs.Client/Pages/Components/Dropdown/PreviewCodes/CustomStyles.razor (1)

1-5: LGTM!

The component is well-structured and follows the project's conventions. The use of @rendermode InteractiveWebAssembly is appropriate for interactive components.

docs/LumexUI.Docs.Client/Pages/Components/Dropdown/PreviewCodes/DisabledItems.razor (1)

1-5: LGTM!

The component follows the established pattern and maintains consistency with other preview files.

docs/LumexUI.Docs.Client/Pages/Components/Dropdown/PreviewCodes/ColorsVariants.razor (1)

1-5: LGTM!

The component maintains consistency with other preview files and follows the established pattern.

src/LumexUI.Variants/CompoundVariant.cs (1)

1-4: LGTM!

The license header is properly formatted and includes all necessary information.

src/LumexUI/Components/Dropdown/DropdownContext.cs (1)

9-12: LGTM! Well-structured implementation.

The class follows best practices with appropriate access modifiers, immutability, and modern C# features.

src/LumexUI/Components/Dropdown/DropdownMenuSlots.cs (1)

11-16: LGTM! Well-documented type marker.

The class appropriately inherits from MenuSlots and includes clear XML documentation.

src/LumexUI/Components/Dropdown/DropdownItemSlots.cs (1)

11-16: LGTM! Well-documented type marker.

The class appropriately inherits from MenuItemSlots and includes clear XML documentation.

src/LumexUI/Extensions/ParameterViewExtensions.cs (1)

14-17: LGTM! Clean and type-safe parameter retrieval.

The implementation is concise and provides a safe way to retrieve parameter values with fallback support.

docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/EmptyContent.razor (1)

11-17: LGTM! Clean and focused empty content implementation.

The dropdown structure is well-organized and provides a good example of empty content handling.

docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Arrow.razor (2)

1-17: LGTM!

The implementation correctly uses dependency injection for the popover service and properly associates the button with the popover using the data-popoverref attribute.


22-25: LGTM!

The TriggerAsync method correctly delegates to the PopoverService.

src/LumexUI/Styles/Dropdown.cs (1)

17-27: LGTM!

The base styles provide a good foundation for the dropdown component with appropriate width and padding settings.

src/LumexUI.Variants/VariantConfig.cs (1)

14-24: LGTM!

The Deconstruct method is well-implemented, enabling pattern matching and destructuring of the record.

src/LumexUI/Components/Menu/MenuContext.cs (1)

10-37: LGTM!

The overall implementation is clean and well-structured:

  • Uses primary constructor for dependency injection
  • Properly manages item collection lifecycle
  • Provides clear API for registering items
docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Colors.razor (1)

7-23: LGTM! Well-structured popover implementation.

The implementation follows good practices:

  • Unique ID generation for each color variant
  • Proper data attribute linking button to popover
  • Consistent styling and content structure
docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/Usage.razor (1)

5-9: LGTM! Clean button implementation.

The button implementation follows good practices:

  • Uses outlined variant for visual distinction
  • Properly links to dropdown via data attribute
  • Clear, descriptive button text
src/LumexUI/Common/Enums/MenuVariant.cs (1)

11-37: LGTM! Well-structured and documented enum.

The enum implementation follows best practices:

  • Clear and descriptive variant names
  • Comprehensive XML documentation for each value
  • Logical organization of variants
docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Shadows.razor (1)

27-30: Consider adding error handling for the async operation.

Similar to Colors.razor, the TriggerAsync method should include error handling.

docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/DisabledItems.razor (2)

5-9: LGTM! Button implementation follows best practices.

The button correctly uses data-popoverref to link with the dropdown and implements the click handler.


27-30: LGTM! Async method follows best practices.

The TriggerAsync method correctly returns the task from PopoverService.TriggerAsync.

docs/LumexUI.Docs.Client/Pages/Components/Popover/Examples/Placements.razor (1)

30-33: LGTM! Async method follows best practices.

The TriggerAsync method correctly returns the task from PopoverService.TriggerAsync.

src/LumexUI/Components/Dropdown/LumexDropdown.razor.cs (1)

31-44: Consider adding null check for TwVariant.

The OnParametersSet method uses TwVariant without checking for null, which could potentially cause issues.

 protected override void OnParametersSet()
 {
     base.OnParametersSet();
 
+    if (TwVariant is null)
+    {
+        return;
+    }
+
     var dropdown = Dropdown.Style(TwVariant);
     _slots = dropdown();
src/LumexUI/Components/Menu/MenuItemSlots.cs (1)

11-43: LGTM!

The MenuItemSlots class is well-structured with:

  • Clear XML documentation for all properties
  • Proper obsolescence handling for the Root property
  • Consistent naming conventions for slot properties
src/LumexUI/Components/Popover/PopoverSlots.cs (1)

21-33: LGTM!

The changes properly handle the transition from Root and Trigger slots to the new Base slot by:

  • Adding clear obsolescence messages
  • Introducing the new Base property with proper documentation
  • Maintaining backward compatibility
src/LumexUI/Components/Dropdown/LumexDropdownItem.cs (1)

16-39: LGTM!

The implementation is well-structured with:

  • Clear inheritance hierarchy and interface implementation
  • Proper context validation
  • Correct parameter handling
src/LumexUI/Components/Menu/MenuItem.razor (1)

13-49: LGTM! Well-structured component with flexible styling.

The component implementation is well-organized with:

  • Proper use of slots for styling customization
  • Conditional rendering for description
  • Appropriate handling of disabled and readonly states
  • Event handling for click interactions
src/LumexUI/Components/Bases/LumexComponentBase.cs (1)

41-42:

✅ Verification successful

Verify the impact of access modifier changes.

The access modifier change for TwMerge from private protected to internal and the addition of internal TwVariant could expose these properties to a broader scope.

Run this script to check for potential misuse of these properties outside the intended scope:


🏁 Script executed:

#!/bin/bash
# Description: Check for usage of TwMerge and TwVariant outside the LumexUI assembly

# Search for TwMerge usage
echo "Checking TwMerge usage..."
rg "TwMerge" --type cs -C 3

# Search for TwVariant usage
echo "Checking TwVariant usage..."
rg "TwVariant" --type cs -C 3

Length of output: 53004


Access Modifier Change Verified: No Unintended Exposure Detected

The verification confirms that the changes—from using a more restricted private protected modifier to internal—are not leading to unintended exposure. Searches for both TwMerge and TwVariant indicate that they are only used within the LumexUI assembly (including components and tests), and no external misuse is evident.

  • File Affected: src/LumexUI/Components/Bases/LumexComponentBase.cs
  • Updates:
     [Inject] internal TwMerge TwMerge { get; set; } = default!;
     [Inject] internal TwVariant TwVariant { get; set; } = default!;
  • Outcome: The broader internal access is appropriate given the scope of usage within the assembly. No changes are needed based on the current usage.
docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/ColorsVariants.razor (2)

6-28: LGTM! Well-structured dropdown examples.

The implementation effectively demonstrates different variants with:

  • Unique ID generation for each dropdown
  • Proper event handling
  • Consistent color application

42-63: LGTM! Clean implementation of variant mapping.

The code section is well-organized with:

  • Clear variant mapping logic
  • Proper async handling
  • Good use of pattern matching
docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/Description.razor (2)

5-9: LGTM! Clean button implementation.

The button implementation is well-structured with proper event handling and data attributes.


55-60: LGTM! Clean async implementation.

The dropdown handling is well-implemented with proper async/await pattern.

src/LumexUI/Components/Menu/Menu.razor.cs (1)

74-79: Verify the TwVariant initialization.

The OnParametersSet method initializes styles but doesn't handle potential null values or exceptions. Consider adding null checks and error handling.

protected override void OnParametersSet()
{
+    if (TwVariant is null)
+    {
+        throw new InvalidOperationException("TwVariant service is not initialized");
+    }
+
    var menu = Styles.Menu.Style(TwVariant);
+    if (menu is null)
+    {
+        throw new InvalidOperationException("Failed to initialize menu styles");
+    }
    _slots = menu();
}
src/LumexUI/Extensions/ServiceCollectionExtensions.cs (1)

31-33: LGTM! Clean integration of TailwindVariants.

The addition of AddTailwindVariants() is well-placed in the service registration chain and consistently applied across both overloads.

Also applies to: 44-46

src/LumexUI/Components/Popover/LumexPopoverTrigger.razor.cs (1)

62-67: Add test coverage for click handling.

The static analysis indicates that the click handling code paths are not covered by tests.

Could you add tests to cover:

  1. The disabled state early return
  2. The OnClick event invocation
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 62-62: src/LumexUI/Components/Popover/LumexPopoverTrigger.razor.cs#L62
Added line #L62 was not covered by tests


[warning] 66-67: src/LumexUI/Components/Popover/LumexPopoverTrigger.razor.cs#L66-L67
Added lines #L66 - L67 were not covered by tests

tests/LumexUI.Tests/Components/Button/ButtonTests.cs (1)

19-21: LGTM! Clean integration of TwVariant service.

The TwVariant service registration is properly added to the test context.

docs/LumexUI.Docs.Client/Pages/Components/Dropdown/Examples/CustomStyles.razor (2)

5-9: LGTM! Button implementation looks good.

The button is correctly configured with the Outlined variant and properly references the dropdown ID.


56-72: LGTM! Styling classes are well-organized.

The styling classes are properly structured using PopoverSlots and DropdownItemSlots for consistent theming.

tests/LumexUI.Tests/Components/Navbar/NavbarTests.razor (1)

11-13: LGTM! Service registration follows the established pattern.

The TwVariant service is correctly registered as a singleton, consistent with the TwMerge service registration.

LumexUI.sln (1)

33-34: LGTM! Project structure is correctly configured.

The LumexUI.Variants project is properly added to the solution with correct configurations and nesting.

Also applies to: 69-72, 85-85

tests/LumexUI.Tests/Components/Providers/ThemeProviderTests.cs (1)

55-56: LGTM!

The CSS variable values have been updated to match the new design specifications:

  • --lumex-surface1: 0 0% 100% (pure white)
  • --lumex-surface1-foreground: 240 5.88% 10% (darker text for better contrast)
tests/LumexUI.Tests/Components/Accordion/AccordionTests.cs (1)

19-20: LGTM!

The changes enhance the test context by:

  • Adding TwVariant service for variant functionality testing
  • Maintaining JSInterop setup for scroll height functionality

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: 4

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 43e5c28 and e5bf5af.

📒 Files selected for processing (7)
  • src/LumexUI.Variants/SlotCollection.cs (1 hunks)
  • src/LumexUI.Variants/TwVariant.cs (1 hunks)
  • src/LumexUI.Variants/VariantCollection.cs (1 hunks)
  • src/LumexUI.Variants/VariantValueCollection.cs (1 hunks)
  • src/LumexUI/LumexUI.csproj (1 hunks)
  • src/LumexUI/Services/Popover/PopoverService.cs (2 hunks)
  • src/LumexUI/Styles/Button.cs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/LumexUI.Variants/VariantValueCollection.cs
  • src/LumexUI/Styles/Button.cs
  • src/LumexUI/LumexUI.csproj
  • src/LumexUI.Variants/SlotCollection.cs
  • src/LumexUI.Variants/VariantCollection.cs
🧰 Additional context used
🪛 GitHub Check: build-test
src/LumexUI.Variants/TwVariant.cs

[warning] 45-45:
Dereference of a possibly null reference.


[warning] 45-45:
Dereference of a possibly null reference.

🔇 Additional comments (5)
src/LumexUI.Variants/TwVariant.cs (4)

1-8: LGTM!

The file header, license information, and namespace organization follow standard C# conventions.


9-11: LGTM!

The delegate declarations are well-designed with appropriate use of nullable types and flexible parameter handling.


13-14: LGTM!

The class effectively uses C# 12's primary constructor feature for dependency injection of TwMerge.


102-116: LGTM!

The helper methods are well-implemented:

  • GetOverrideValue handles null checks appropriately
  • CreateComponentSlot effectively uses modern C# features for string manipulation and array creation
src/LumexUI/Services/Popover/PopoverService.cs (1)

12-12: Use a proper dictionary initializer instead of =[].

In most C# versions, =[] on a Dictionary isn't valid. If you're targeting C# 9 or higher, you can use = new(); for a concise initializer. Otherwise, use = new Dictionary<string, LumexPopover>(); to avoid compilation issues.

Comment on lines +44 to +46
if( !string.IsNullOrEmpty( selectedValue ) &&
values[selectedValue] is SlotCollection variantSlots )
{
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add null check for values to prevent potential NullReferenceException.

The current code could throw a NullReferenceException if values is null when accessing values[selectedValue].

Apply this diff to add the necessary null check:

     if( !string.IsNullOrEmpty( selectedValue ) &&
+        values is not null &&
         values[selectedValue] is SlotCollection variantSlots )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if( !string.IsNullOrEmpty( selectedValue ) &&
values[selectedValue] is SlotCollection variantSlots )
{
if( !string.IsNullOrEmpty( selectedValue ) &&
values is not null &&
values[selectedValue] is SlotCollection variantSlots )
{
🧰 Tools
🪛 GitHub Check: build-test

[warning] 45-45:
Dereference of a possibly null reference.


[warning] 45-45:
Dereference of a possibly null reference.

Comment on lines 33 to +36
public void Unregister( LumexPopover popover )
{
_registeredPopovers.Remove( popover );
_registeredPopovers.Remove( popover.Id );
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add parameter validation and existence check.

The Unregister method needs additional validation:

  1. Add null check for the popover parameter
  2. Verify the Id exists before removal

Apply this diff to improve robustness:

 public void Unregister( LumexPopover popover )
 {
-    _registeredPopovers.Remove( popover.Id );
+    ArgumentNullException.ThrowIfNull(popover);
+    if (!string.IsNullOrEmpty(popover.Id) && _registeredPopovers.ContainsKey(popover.Id))
+    {
+        _registeredPopovers.Remove(popover.Id);
+    }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public void Unregister( LumexPopover popover )
{
_registeredPopovers.Remove( popover );
_registeredPopovers.Remove( popover.Id );
}
public void Unregister( LumexPopover popover )
{
ArgumentNullException.ThrowIfNull(popover);
if (!string.IsNullOrEmpty(popover.Id) && _registeredPopovers.ContainsKey(popover.Id))
{
_registeredPopovers.Remove(popover.Id);
}
}

Comment on lines 24 to 30
public void Register( LumexPopover popover )
{
_registeredPopovers.Add( popover );
if( !string.IsNullOrEmpty( popover.Id ) )
{
_registeredPopovers.Add( popover.Id, popover );
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add parameter validation and error handling.

The Register method needs additional validation and error handling:

  1. Add null check for the popover parameter
  2. Handle duplicate Ids gracefully
  3. Add try-catch for dictionary Add operation

Apply this diff to improve robustness:

 public void Register( LumexPopover popover )
 {
+    ArgumentNullException.ThrowIfNull(popover);
     if( !string.IsNullOrEmpty( popover.Id ) )
     {
-        _registeredPopovers.Add( popover.Id, popover );
+        try
+        {
+            _registeredPopovers[popover.Id] = popover;
+        }
+        catch (Exception ex)
+        {
+            // Log the error if logging is available
+            throw new InvalidOperationException($"Failed to register popover with Id: {popover.Id}", ex);
+        }
     }
+    else
+    {
+        throw new ArgumentException("Popover Id cannot be null or empty", nameof(popover));
+    }
 }

Comment on lines +38 to 47
/// <inheritdoc />
public Task TriggerAsync( string id )
{
if( _registeredPopovers.TryGetValue( id, out var popover ) )
{
return popover.TriggerAsync();
}

return Task.CompletedTask;
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve parameter validation and documentation.

The TriggerAsync method needs improvements:

  1. Add parameter validation
  2. Remove trailing semicolon after if block
  3. Add XML documentation for the return value
  4. Consider logging for non-existent ids

Apply this diff to improve the implementation:

 /// <inheritdoc />
+/// <returns>
+/// A task that completes when the popover trigger operation is finished.
+/// Returns a completed task if the popover with the specified id is not found.
+/// </returns>
 public Task TriggerAsync( string id )
 {
+    ArgumentException.ThrowIfNullOrEmpty(id);
     if( _registeredPopovers.TryGetValue( id, out var popover ) )
     {
-        return popover.TriggerAsync();
+        return popover.TriggerAsync();
     }
+    // Consider adding logging here for non-existent ids
     return Task.CompletedTask;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/// <inheritdoc />
public Task TriggerAsync( string id )
{
if( _registeredPopovers.TryGetValue( id, out var popover ) )
{
return popover.TriggerAsync();
}
return Task.CompletedTask;
}
/// <inheritdoc />
/// <returns>
/// A task that completes when the popover trigger operation is finished.
/// Returns a completed task if the popover with the specified id is not found.
/// </returns>
public Task TriggerAsync( string id )
{
ArgumentException.ThrowIfNullOrEmpty(id);
if( _registeredPopovers.TryGetValue( id, out var popover ) )
{
return popover.TriggerAsync();
}
// Consider adding logging here for non-existent ids
return Task.CompletedTask;
}

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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e5bf5af and 420d921.

📒 Files selected for processing (3)
  • src/LumexUI.Variants/SlotCollection.cs (1 hunks)
  • src/LumexUI.Variants/VariantCollection.cs (1 hunks)
  • src/LumexUI.Variants/VariantValueCollection.cs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/LumexUI.Variants/VariantValueCollection.cs
  • src/LumexUI.Variants/VariantCollection.cs
🔇 Additional comments (5)
src/LumexUI.Variants/SlotCollection.cs (5)

1-4: LGTM!

The license header is properly formatted and includes the current year and valid license URL.


9-10: LGTM!

The class declaration and interface implementation are properly aligned with matching types.


19-20: LGTM!

The properties safely expose read-only collections of slots and values.


22-26: LGTM!

The enumerator implementations are correct and follow best practices.


11-11:

❓ Verification inconclusive

Verify C# version compatibility.

The collection expression syntax [] requires C# 12.0 or later. Please ensure your project's target framework supports this feature.

Run this script to check the project's language version:


🏁 Script executed:

#!/bin/bash
# Description: Check C# language version in project file
fd -e csproj -x cat {} | grep -i "LangVersion\|TargetFramework"

Length of output: 818


C# Version Compatibility & Target Frameworks

The collection expression syntax [] for initializing the dictionary requires C# 12.0 or later. The project files indicate several targets:

  • Projects targeting net9.0 should support C# 12 features by default.
  • Projects targeting net8.0 may not automatically enable C# 12 unless an explicit LangVersion setting is provided.

Please verify that any project targeting net8.0 either sets its LangVersion to 12.0 (or later) or is updated to a framework that guarantees C# 12 support. This will ensure consistent behavior across your codebase.

Comment on lines 13 to 17
public string this[string slotName]
{
get => _dictionary[slotName];
set => _dictionary[slotName] = value;
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add parameter validation and error handling.

The indexer should validate the input parameter and handle missing slots gracefully.

Apply this diff to improve robustness:

 public string this[string slotName]
 {
-    get => _dictionary[slotName];
-    set => _dictionary[slotName] = value;
+    get
+    {
+        ArgumentNullException.ThrowIfNull(slotName);
+        return _dictionary.TryGetValue(slotName, out var value)
+            ? value
+            : throw new KeyNotFoundException($"Slot '{slotName}' not found.");
+    }
+    set
+    {
+        ArgumentNullException.ThrowIfNull(slotName);
+        ArgumentNullException.ThrowIfNull(value);
+        _dictionary[slotName] = value;
+    }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public string this[string slotName]
{
get => _dictionary[slotName];
set => _dictionary[slotName] = value;
}
public string this[string slotName]
{
get
{
ArgumentNullException.ThrowIfNull(slotName);
return _dictionary.TryGetValue(slotName, out var value)
? value
: throw new KeyNotFoundException($"Slot '{slotName}' not found.");
}
set
{
ArgumentNullException.ThrowIfNull(slotName);
ArgumentNullException.ThrowIfNull(value);
_dictionary[slotName] = value;
}
}

@desmondinho desmondinho merged commit b5b60e1 into main Feb 19, 2025
4 checks passed
@desmondinho desmondinho deleted the feat/dropdown branch February 19, 2025 03:18
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.

[Feature]: Option Menu Component
1 participant