feat(components): introduce Spinner component#207
Conversation
WalkthroughThis pull request introduces the new LumexSpinner component along with its supporting examples, documentation, and tests. Updates include additions to the navigation store, new Razor component examples demonstrating spinner variants (colors, labels, sizes, usage, and variants), interactive preview components using WebAssembly, and accompanying styles, enums, utilities, and tests. Minor updates to documentation assets and middleware configuration are also included. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant DocsPage
participant NavigationStore
participant PreviewCodes
participant LumexSpinner
User->>DocsPage: Navigate to Documentation
DocsPage->>NavigationStore: Request navigation items
NavigationStore-->>DocsPage: Return items (includes LumexSpinner)
User->>DocsPage: Select Spinner documentation
DocsPage->>PreviewCodes: Load spinner preview (Usage/Sizes/etc.)
PreviewCodes->>LumexSpinner: Render spinner with chosen variant and settings
LumexSpinner-->>PreviewCodes: Return rendered UI component
PreviewCodes-->>DocsPage: Display interactive spinner preview
DocsPage-->>User: Show updated spinner component
Assessment against linked issues
Possibly related PRs
Poem
Tip ⚡🧪 Multi-step agentic review comment chat (experimental)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (8)
docs/LumexUI.Docs.Client/Pages/Components/Spinner/PreviewCodes/Label.razor (1)
5-6: Remove trailing empty line.There appears to be an extra empty line at the end of the file that's not needed.
<PreviewCode Code="@new(name: null, snippet: "Spinner.Code.Label")"> <LumexUI.Docs.Client.Pages.Components.Spinner.Examples.Label /> </PreviewCode> -docs/LumexUI.Docs.Client/Pages/Components/Spinner/PreviewCodes/Colors.razor (1)
5-6: Remove trailing empty line.There appears to be an extra empty line at the end of the file that's not needed.
<PreviewCode Code="@new(name: null, snippet: "Spinner.Code.Colors")"> <LumexUI.Docs.Client.Pages.Components.Spinner.Examples.Colors /> </PreviewCode> -src/LumexUI/Styles/Spinner.cs (1)
259-545: Consider refactoring compound variants to reduce repetition.The compound variants section contains repetitive patterns, especially for color variants. Consider using a helper method or a more concise approach to reduce code duplication.
Example of a potential helper method approach:
// Add a helper method to generate color compound variants + private static CompoundVariant CreateColorCompoundVariant(string variant, string color, string slotName, string textOrBorderClass) + { + return new CompoundVariant() + { + Conditions = new() + { + [nameof(LumexSpinner.Variant)] = variant, + [nameof(LumexSpinner.Color)] = color + }, + Classes = new SlotCollection() + { + [slotName] = textOrBorderClass + } + }; + } // Then use it to generate variants // For Ring variant colors: + var ringColorVariants = new List<CompoundVariant>(); + foreach (var color in Enum.GetNames(typeof(ThemeColor))) + { + if (color == nameof(ThemeColor.None)) continue; + ringColorVariants.Add(CreateColorCompoundVariant( + nameof(SpinnerVariant.Ring), + color, + nameof(SpinnerSlots.Wrapper), + $"text-{color.ToLowerInvariant()}" + )); + }tests/LumexUI.Tests/Components/Spinner/SpinnerTests.razor (1)
1-61: Consider adding tests for size, color, and child content.While the current tests cover variants and accessibility well, consider adding tests for:
- Size parameter to verify that different sizes are applied correctly
- Color parameter to ensure colors are applied
- Child content rendering to verify the label displays the content properly
[Theory] [InlineData(Size.Small)] [InlineData(Size.Medium)] [InlineData(Size.Large)] public void ShouldApplySizeCorrectly(Size size) { var cut = Render( @<LumexSpinner Size="@size" /> ); var wrapper = cut.FindBySlot("wrapper"); // Assert size classes are applied based on the size parameter // This would depend on your exact implementation details if (size == Size.Small) { wrapper!.ClassList.Should().Contain(c => c.Contains("size-5")); } else if (size == Size.Medium) { wrapper!.ClassList.Should().Contain(c => c.Contains("size-8")); } else if (size == Size.Large) { wrapper!.ClassList.Should().Contain(c => c.Contains("size-10") || c.Contains("size-12")); } } [Theory] [InlineData(ThemeColor.Primary)] [InlineData(ThemeColor.Secondary)] [InlineData(ThemeColor.Success)] public void ShouldApplyColorCorrectly(ThemeColor color) { var cut = Render( @<LumexSpinner Color="@color" /> ); // Assert color is applied appropriately // The exact assertion would depend on your implementation } [Fact] public void ShouldRenderChildContent() { var childContent = "Loading Data..."; var cut = Render( @<LumexSpinner>@childContent</LumexSpinner> ); var label = cut.FindBySlot("label"); label!.TextContent.Should().Be(childContent); }src/LumexUI/Components/Spinner/SpinnerSlots.cs (2)
39-47: Documentation requires correction for Circle1 and Circle2 properties.The XML documentation for the
Circle1andCircle2properties incorrectly states they are for the "wrapper slot" rather than their respective slots.- /// Gets or sets the CSS class for the wrapper slot. + /// Gets or sets the CSS class for the circle1 slot.- /// Gets or sets the CSS class for the wrapper slot. + /// Gets or sets the CSS class for the circle2 slot.
49-57: Documentation requires correction for Dots and Bars properties.The XML documentation for the
DotsandBarsproperties incorrectly states they are for the "wrapper slot" rather than their respective slots.- /// Gets or sets the CSS class for the wrapper slot. + /// Gets or sets the CSS class for the dots slot.- /// Gets or sets the CSS class for the wrapper slot. + /// Gets or sets the CSS class for the bars slot.src/LumexUI/Components/Spinner/LumexSpinner.razor.cs (2)
73-73: XML reference has incorrect class name.The XML documentation references
LumexAvatarinstead ofLumexSpinnerin the constructor's documentation.- /// Initializes a new instance of the <see cref="LumexAvatar"/>. + /// Initializes a new instance of the <see cref="LumexSpinner"/>.
93-112: Consider more graceful error handling for GetStyles method.The current implementation throws
NotImplementedExceptionfor missing slots. Consider returning a default or empty value instead, or providing a more specific exception message to help with debugging.private string? GetStyles( string slot ) { if( !_slots.TryGetValue( slot, out var styles ) ) { - throw new NotImplementedException(); + throw new ArgumentException($"Slot '{slot}' is not implemented in LumexSpinner component."); } return slot switch { nameof( SpinnerSlots.Base ) => styles( Classes?.Base, Class ), nameof( SpinnerSlots.Wrapper ) => styles( Classes?.Wrapper ), nameof( SpinnerSlots.Label ) => styles( Classes?.Label ), nameof( SpinnerSlots.Circle1 ) => styles( Classes?.Circle1 ), nameof( SpinnerSlots.Circle2 ) => styles( Classes?.Circle2 ), nameof( SpinnerSlots.Dots ) => styles( Classes?.Dots ), nameof( SpinnerSlots.Bars ) => styles( Classes?.Bars ), - _ => throw new NotImplementedException() + _ => throw new ArgumentException($"Style application for slot '{slot}' is not implemented in LumexSpinner component.") }; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (25)
docs/LumexUI.Docs.Client/Common/Navigation/NavigationStore.cs(2 hunks)docs/LumexUI.Docs.Client/Components/Preview.razor(1 hunks)docs/LumexUI.Docs.Client/Pages/Components/Skeleton/Skeleton.razor(0 hunks)docs/LumexUI.Docs.Client/Pages/Components/Spinner/Examples/Colors.razor(1 hunks)docs/LumexUI.Docs.Client/Pages/Components/Spinner/Examples/Label.razor(1 hunks)docs/LumexUI.Docs.Client/Pages/Components/Spinner/Examples/Sizes.razor(1 hunks)docs/LumexUI.Docs.Client/Pages/Components/Spinner/Examples/Usage.razor(1 hunks)docs/LumexUI.Docs.Client/Pages/Components/Spinner/Examples/Variants.razor(1 hunks)docs/LumexUI.Docs.Client/Pages/Components/Spinner/PreviewCodes/Colors.razor(1 hunks)docs/LumexUI.Docs.Client/Pages/Components/Spinner/PreviewCodes/Label.razor(1 hunks)docs/LumexUI.Docs.Client/Pages/Components/Spinner/PreviewCodes/Sizes.razor(1 hunks)docs/LumexUI.Docs.Client/Pages/Components/Spinner/PreviewCodes/Usage.razor(1 hunks)docs/LumexUI.Docs.Client/Pages/Components/Spinner/PreviewCodes/Variants.razor(1 hunks)docs/LumexUI.Docs.Client/Pages/Components/Spinner/Spinner.razor(1 hunks)docs/LumexUI.Docs/Components/App.razor(1 hunks)docs/LumexUI.Docs/LumexUI.Docs.csproj(1 hunks)docs/LumexUI.Docs/Program.cs(1 hunks)src/LumexUI/Common/Enums/SpinnerVariant.cs(1 hunks)src/LumexUI/Components/Spinner/LumexSpinner.razor(1 hunks)src/LumexUI/Components/Spinner/LumexSpinner.razor.cs(1 hunks)src/LumexUI/Components/Spinner/SpinnerSlots.cs(1 hunks)src/LumexUI/Styles/Spinner.cs(1 hunks)src/LumexUI/Styles/_theme.css(3 hunks)src/LumexUI/Utilities/Variants/TwVariants.cs(2 hunks)tests/LumexUI.Tests/Components/Spinner/SpinnerTests.razor(1 hunks)
💤 Files with no reviewable changes (1)
- docs/LumexUI.Docs.Client/Pages/Components/Skeleton/Skeleton.razor
🧰 Additional context used
🪛 GitHub Check: build-test
src/LumexUI/Common/Enums/SpinnerVariant.cs
[warning] 16-16:
Missing XML comment for publicly visible type or member 'SpinnerVariant.ArcGradient'
[warning] 14-14:
Missing XML comment for publicly visible type or member 'SpinnerVariant.Arc'
[warning] 12-12:
Missing XML comment for publicly visible type or member 'SpinnerVariant.Ring'
🪛 Biome (1.9.4)
src/LumexUI/Styles/_theme.css
[error] 1-1: expected , but instead found @
Remove @
(parse)
[error] 1-1: expected , but instead found layer
Remove layer
(parse)
🔇 Additional comments (46)
docs/LumexUI.Docs.Client/Pages/Components/Spinner/Examples/Usage.razor (1)
1-1: Good basic example implementation!This provides a clear example of the simplest way to use the LumexSpinner component without any customization.
docs/LumexUI.Docs.Client/Pages/Components/Spinner/Examples/Label.razor (1)
1-1: Well-implemented label example!This demonstrates how to use the LumexSpinner component with a label, providing a clear use case.
docs/LumexUI.Docs.Client/Pages/Components/Spinner/PreviewCodes/Label.razor (1)
1-5: Interactive preview implementation looks good.The preview code is correctly set up with the InteractiveWebAssembly render mode and properly references the Label example.
docs/LumexUI.Docs.Client/Pages/Components/Spinner/PreviewCodes/Colors.razor (1)
1-5: Interactive preview implementation looks good.The preview code is correctly set up with the InteractiveWebAssembly render mode and properly references the Colors example.
docs/LumexUI.Docs.Client/Components/Preview.razor (1)
27-27: LGTM! Good enhancement for overflow content.The addition of
overflow-x-autoandscrollbar-hideclasses improves the user experience when preview content exceeds the container width.docs/LumexUI.Docs.Client/Pages/Components/Spinner/Examples/Sizes.razor (1)
1-5: LGTM! Clear demonstration of size variants.The example provides a concise demonstration of the available spinner sizes with appropriate spacing.
docs/LumexUI.Docs.Client/Pages/Components/Spinner/PreviewCodes/Sizes.razor (1)
1-5: LGTM! Follows the established pattern for interactive component previews.The implementation correctly uses WebAssembly for interactivity and properly references the size examples.
docs/LumexUI.Docs.Client/Pages/Components/Spinner/Examples/Variants.razor (1)
1-8: Well-organized variants showcase with clear examples.The implementation provides a comprehensive display of all spinner variants in a clean, responsive layout. The naming is descriptive and the consistent structure makes it easy to understand the available options.
docs/LumexUI.Docs/Program.cs (1)
42-42:Details
❓ Verification inconclusive
Verify static assets handling for the Spinner component.
The change from
UseStaticFiles()toMapStaticAssets()affects how static resources are served. Please ensure that all spinner component assets (CSS, JavaScript, images) are properly handled by this new method, especially if they have special loading requirements.
🏁 Script executed:
#!/bin/bash # Check if MapStaticAssets is defined in the codebase and what files it might handle rg -A 5 "MapStaticAssets" --type csharpLength of output: 402
Attention: Verify Static Assets Mapping for Spinner Component
The change from using
UseStaticFiles()to the customMapStaticAssets()suggests a shift in how static files are served. Please review the implementation ofMapStaticAssets()to ensure that it correctly handles all static assets—including those required by the spinner component (CSS, JavaScript, images)—especially if they have any special loading requirements.docs/LumexUI.Docs.Client/Pages/Components/Spinner/Examples/Colors.razor (1)
1-9: Comprehensive color theme examples with consistent implementation.The code effectively showcases all color variants with a clear, consistent approach. Each spinner appropriately demonstrates both the spinner color and matching label color, providing excellent visual reference for implementation.
docs/LumexUI.Docs.Client/Pages/Components/Spinner/PreviewCodes/Usage.razor (1)
1-5: Effective use of interactive preview for the spinner component.The implementation correctly sets up the WebAssembly interactive mode and appropriately uses the PreviewCode component to display both the rendered example and its corresponding code snippet.
Could you clarify the purpose of the
name: nullparameter in the Code object creation? Understanding whether this is intentional or if it should have a specific value would ensure proper functionality.docs/LumexUI.Docs.Client/Pages/Components/Spinner/PreviewCodes/Variants.razor (1)
1-5: Looks good - PreviewCode component setup is correct.The implementation correctly uses InteractiveWebAssembly rendering mode and properly sets up the PreviewCode component to display spinner variants. The structure follows the established pattern for component examples in the LumexUI documentation.
docs/LumexUI.Docs/Components/App.razor (3)
8-8: CSS reference updated correctly.The stylesheet reference has been updated to use the new CSS output file that will be generated by the updated TailwindCSS build targets.
11-11: Added ImportMap component.The ImportMap component has been added to the head section, which is important for managing JavaScript module dependencies.
15-15:Details
❓ Verification inconclusive
Simplified body tag styling.
The class attributes have been removed from the body tag. Verify that these styles are now applied through another mechanism to maintain consistent styling.
🏁 Script executed:
#!/bin/bash # Check if the background and text styling is defined elsewhere cat docs/LumexUI.Docs/Styles/globals.css | grep -E "body|bg-background|text-foreground"Length of output: 89
I'm not seeing any relevant styles in
globals.cssbased on the initial grep. To further verify if the background and text styling are defined elsewhere, please run the following script to recursively search the repository for occurrences of the keywords"bg-background"or"text-foreground":
🏁 Script executed:
#!/bin/bash # Recursively search the repository for alternative styling definitions using the keywords "bg-background" or "text-foreground" rg -E "bg-background|text-foreground" -n .Length of output: 111
Action Required: Confirm Alternative Styling Application for
<body>Our initial verification using
grepandrgdid not reveal any explicit definitions forbg-background,text-foreground, or alternative styles for the<body>tag in the repository. Please manually verify that the intended background and text styles are applied through another mechanism (e.g., a global CSS configuration, a layout component, or a styling framework integration) so that the removal of class attributes does not lead to unintended styling regressions.
- File Affected:
docs/LumexUI.Docs/Components/App.razor(Line 15)- Environment to Check: Global CSS files, layout components, and any framework configuration (e.g., Tailwind CSS configuration) that may now be handling these styles.
docs/LumexUI.Docs.Client/Common/Navigation/NavigationStore.cs (2)
44-44: Correctly added Spinner to components category.The LumexSpinner component has been properly added to the ComponentsCategory with the appropriate ComponentStatus.New flag, which will help users identify it as a new addition.
91-91: Correctly added Spinner to API category.The LumexSpinner component has been properly added to the ComponentsApiCategory, following the established pattern for component documentation.
docs/LumexUI.Docs/LumexUI.Docs.csproj (2)
50-53: Good implementation of development TailwindCSS build configuration.The TailwindCSS-Dev target is correctly set up to compile CSS without minification in Debug mode, making development easier with readable CSS output. The commands handle both Windows and non-Windows environments appropriately.
55-57: Good implementation of production TailwindCSS build configuration.The TailwindCSS-Prod target correctly includes the --minify flag for production builds, which will optimize the CSS file size. The conditional commands for different operating systems are handled appropriately.
src/LumexUI/Components/Spinner/LumexSpinner.razor (5)
6-24: Well-structured conditional rendering for dot-based variants.The conditional rendering for DotsWave and DotsFade variants is implemented cleanly. The use of a loop to generate the dot elements is efficient and maintainable.
25-51: Good SVG implementation for the Ring variant.The Ring variant uses SVG effectively with proper viewBox, fill attributes, and accessibility. The use of data-slot attributes makes styling and testing easier.
52-70: Efficient implementation of the Classic spinner variant.The Classic spinner variant uses a loop to generate 12 bar elements, with index-based styling. This approach is efficient and maintainable.
71-85: Default spinner implementation is clean and minimal.The default spinner variant is simple and effective, using two circle elements. The consistent structure across all variants makes the component predictable and maintainable.
87-99: Good approach for conditional label rendering.The RenderLabel method efficiently handles both string labels and child content. The null/empty check prevents rendering empty label containers.
docs/LumexUI.Docs.Client/Pages/Components/Spinner/Spinner.razor (4)
6-32: Well-organized documentation structure.The documentation is logically organized into sections covering usage, label, sizes, colors, and variants, providing a comprehensive guide for developers.
34-42: Comprehensive slots documentation.The slots section clearly documents all available styling hooks, making it easier for developers to customize the component.
44-76: Clear API reference and well-structured code section.The API section and the headings array provide good navigation structure. Initialization in OnInitialized follows the pattern used in other component documentation.
77-86: Proper metadata initialization.The layout initialization correctly sets up title, category, description, and other metadata, ensuring consistent documentation structure.
src/LumexUI/Styles/Spinner.cs (5)
14-23: Good singleton pattern implementation for styles.The singleton pattern with lazy initialization is appropriately used for the component variant, which helps with performance.
24-70: Well-structured base styles for spinner slots.The slot definitions are clear and comprehensive, covering all the visual elements needed for the different spinner variants.
72-158: Comprehensive variant styles for size and color.The variant collections for size and color are well-organized and cover all the needed variations.
161-197: Good separation of label styling from spinner styling.The LabelColor variant collection allows for independent styling of the label, which enhances flexibility.
199-257: Thorough implementation of spinner variants.Each spinner variant has appropriate styles defined, with good attention to animation details.
tests/LumexUI.Tests/Components/Spinner/SpinnerTests.razor (3)
4-24: Good variant rendering tests.The theory test with inline data covers all spinner variants to ensure they render correctly without exceptions.
26-36: Proper testing of default accessibility attributes.Testing the default aria-label ensures the component remains accessible even without explicit label configuration.
38-60: Thorough testing of aria-label customization.Tests for both label-based and attribute-based aria-label customization ensure the component handles accessibility properly.
src/LumexUI/Styles/_theme.css (4)
1-5: New CSS layer improves style encapsulation.The addition of a base layer with body styles establishes a clean baseline for text and background colors. This provides consistent styling for the new spinner component.
🧰 Tools
🪛 Biome (1.9.4)
[error] 1-1: expected
,but instead found@Remove @
(parse)
[error] 1-1: expected
,but instead foundlayerRemove layer
(parse)
175-175: Animation timing function change affects visual behavior.Changing from
ease-outtoease-inwill make animations start slowly and accelerate, rather than starting quickly and slowing down. Ensure this is the intended behavior since it will affect all components using this animation.
177-179: New animation properties support the Spinner component.The addition of
--animate-sway,--animate-blink, and--animate-fade-outproperties provides the necessary animation patterns for the different spinner variants.
199-227: Well-defined keyframes for spinner animations.The keyframe definitions for
sway,blink, andfade-outanimations are well structured and provide smooth, visually pleasing animation patterns that will enhance the loading experience.src/LumexUI/Components/Spinner/SpinnerSlots.cs (2)
11-14: Documentation is clear and concise.Good use of XML documentation to describe the purpose of the
SpinnerSlotsclass, with a reference toLumexSpinner.
18-23: Correctly handling deprecated property.The
Rootproperty is appropriately marked as obsolete with a clear explanation to useBaseinstead. Good practice for maintaining backward compatibility while guiding users toward the preferred API.src/LumexUI/Utilities/Variants/TwVariants.cs (2)
5-5: Appropriate access restriction of utility components.Changing the access modifiers from
publictointernaland adding the[ExcludeFromCodeCoverage]attribute is appropriate for utility components that should only be used within the library.Also applies to: 11-16
114-114: Simplified method implementation is more readable.The refactored
CreateComponentSlotmethod uses a more concise array spread syntax for merging class names, making the code more readable while maintaining the same functionality.src/LumexUI/Components/Spinner/LumexSpinner.razor.cs (2)
17-65: Well-designed component API with comprehensive documentation.The
LumexSpinnercomponent provides a flexible API with appropriate defaults and comprehensive XML documentation. The parameters support customization of size, color, label, and variant, which aligns with modern component library best practices.
80-91: Parameter handling follows component design pattern.The
OnParametersSetmethod properly passes all relevant parameters to the styling system, ensuring that the spinner's appearance adapts based on the provided properties.
* feat: support Tailwind CSS v4 (#183) * build(deps): bump TailwindMerge.NET from 0.3.0 to 1.0.0 * feat: add new CSS theme file * feat/build: add custom targets file to improve library usability * chore: move `Plugin` folder one level higher; remove `Scripts` folder * feat/build: pack new theme and custom `.targets` files * build(docs): add `Directory.Build.props` and `Directory.Build.targets` * chore(docs): remove tailwind npm deps; use standalone CLI instead * docs: apply `static` on theme * refactor(theme-provider): simplify names of box-shadow css variables * refactor(theme-provider): opacities are percentage to match `color-mix` function syntax * chore(components): apply `static` on theme; fix some vars * refactor(components): drop Tailwind CSS v3 support * feat(theme): add custom transition variables * fix(theme): correct `default` color; add `default-foreground` color * chore(theme): add reference for the custom transitions approach (it's not in docs afaik) * fix: rename `shadow-sm` to `shadow-xs` * fix: rename `rounded-sm` to `rounded-xs` * fix: rename `rounded` to `rounded-sm` * fix: rename `outline-none` to `outline-hidden` * fix: rename `ring-1` to `ring` * fix(button): add base `cursor-pointer` class * docs: remove `children` custom variant in favor of `*` * fix(theme): correct `enter` custom animation * chore(components): cleanup styles * fix(theme): add missing comma separator in custom transition vars * docs: configure typography * refactor(theme): simplify `scrollbar-hide` utility * chore(theme): apply `inline` on theme * refactor: replace `theme` function with CSS vars * fix(components): correct scale/translate transitions * feat(theme): update colors from hex to oklch * docs(installation): update installation guide * feat(theme): add leading CSS vars * chore(docs): fix prose `<code>` tag ticks * refactor(utils): remove hex luminance calculator * docs(customization): update Theme and Colors pages * docs(colors): remove 'common colors are not configurable' callout * fix(checkbox): correct radius styles * fix(data-grid): correct striped styles * fix(input/select): correct label placement out transitions * fix(input/select): correct outlined variant focus styles * fix(input): add cursor-pointer style on the clear button * fix(input/select): correct flat variant focus styles * fix(docs): correct some component examples * build(docs): adjust Tailwind standalone CLI file download for Linux * build(docs): adjust Tailwind standalone CLI file download for Linux * ci(deploy): try add staging env in the ci/cd * ci(build-test): change trigger branch * ci(deploy): update trigger branches * ci(deploy): change env vars usage (test) * ci: add deploy-dev.yml; revert deploy.yml * ci(deploy): test staging * chore(docs): nits * chore(components): tweak styles of some components * chore(docs): tweak some components examples * chore: coderabbit comments * ci: remove deploy-dev.yml * fix(theme): remove extra shade (950) from the color scales for consistency in dark mode (#199) * fix(theme): remove extra key (950) from the color scales for consistency in dark mode * build(docs): explicitly set Tailwind v4.0.9 * feat(components): introduce Avatar and AvatarGroup components (#201) * feat: add baseline implementation * feat: add slots * feat: add basic slots styles * feat: add appearance params, such as `Color`, `Radius`, `Size` * feat: add `Bordered` and `Disabled` params * feat: add compound variants styles * feat: apply slots styles * docs: add baseline examples page * feat: add `data-loaded` attribute on img * feat: add `ShowFallback` parameter * chore: fix compound style variants * chore: set `showFallback` on after first render * feat(utils): add implicit cast to string for the `ElementClass` * feat: add LumexAvatarGroup component * feat: take into account when LumexAvatar is rendered inside the LumexAvatarGroup * feat: add `AvatarClasses` parameter in the avatar group component * docs: add Avatar page * build(docs): explicitly set Tailwind v4.0.9 * test: add tests for LumexAvatar and LumexAvatarGroup components * chore: simplify condition for fallback render * fix(docs): replace usages of `-foreground-950` CSS classes with `-foreground-900` * fix(docs): remove `dark:prose-invert` CSS class until dark theme is properly configured * feat(components): introduce Skeleton component (#202) * feat(skeleton): add baseline implementation of the component * feat(skeleton): add slots and styles * feat(skeleton): add XML summaries * fix(skeleton): return back `after` pseudo CSS classes to prevent flickering on state change * docs(skeleton): add Skeleton page * test(skeleton): add tests * docs(skeleton): fix Loading example button text * fix(navbar): add a check before toggling navbar menu on navigation (#204) * feat(components): introduce Spinner component (#207) * feat(spinner): add baseline implementation * feat(spinner): add variants and styles * feat(spinner): add slots * docs(spinner): add Spinner page * docs: nits * test(spinner): add tests * docs: map static assets * build(docs): remove extra MSBuild target for the Tailwind prod build * docs: revert static assets changes * docs: update static assets usage * Revert "docs: update static assets usage" This reverts commit 94ae9ec. * feat(components): introduce Chip component (#211) * feat(chip): add baseline implementation * feat(chip): add ChipVariant enum * feat(chip): add appearance parameters and styles * feat(chip): add AvatarContent parameter * feat(chip): adjust paddings when chip has start/end content * docs(chip): add Chip page * feat(chip): add XML summaries * test(chip): add tests * chore(components): add missing XML documentation summaries * feat(components): add new Badge component (#222) * feat(badge): initial * feat(badge): add badge slots * feat(badge): add badge baseline implementation * feat(badge): add base visual-related params * feat(badge): add majority of badge styles * feat(badge): add outline around badge * feat(badge): add `Invisible` param to control badge visibility * feat(badge): add `IsOneChar` param to make badge equilateral * feat(badge): decrease badge dimensions if no content provided * refactor(badge): rename `IsOneChar` param to `OneChar` * fix(badge): use correct type for `Variant` param * feat(badge): apply CSS classes directly to the badge slot * fix(badge): ensure correct placement styles * fix(badge): correct `Content` check condition * fix(badge): allow null for content * fix(badge): properly render Content as RenderFragment * docs(badge): add Badge docs page * test(badge): add tests * test(badge): add more tests * fix(badge): ensure `OneChar` param is taken into account * fix(badge): fix one char switch * chore: apply CodeRabbit suggestions * build(deps): bump requests from 2.32.0 to 2.32.4 in /scripts (#219) Bumps [requests](https://github.com/psf/requests) from 2.32.0 to 2.32.4. - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md) - [Commits](psf/requests@v2.32.0...v2.32.4) --- updated-dependencies: - dependency-name: requests dependency-version: 2.32.4 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat(components): add Tooltip component (#224) * feat(tooltip): initial * refactor(popover): introduce PopoverWrapper to simplify open state * fix(popover): ensure arrow is positioned correctly * fix(popover): ensure popover closes on trigger click if already opened * fix(popover): position flicker * test(popover/dropdown): adjust tests * refactor(popover): remove LastShown meta from popover service * feat(tooltip): add baseline implementation * feat(tooltip): add common visual-related parameters to pass into popover * feat(tooltip): add OpenDelay and CloseDelay params * docs(tooltip): add Tooltip page * feat(tooltip): pass slots to popover * chore(popover): add full radius styles * test(tooltip): add tests * docs(tooltip): minor tweaks * docs(tooltip): typo * feat(components): add Alert component (#225) * feat(alert): add baseline implementation * feat(alert): add styles (may be not complete) * feat(alert): complete styles * feat(button): add full radius styles * feat(alert): apply styles * feat(alert): add close button handler * chore(alert): complete XML docs summaries * chore(docs): adjust background colors for preview and toolbar * chore(components): darken text color for warning flat variant * chore(alert): styling tweaks * feat(docs): add Alert page * chore(alert): add missing close-button slot attribute * chore(alert): ensure TitleContent takes precedence over Title * docs(alert): add callout regarding Title and TitleContent parameters usage * test(alert): add tests * fix(theme): add tw custom CSS class-based dark mode variant (#226) * refactor(theme): replace C# theme config with a new CSS-first approach (#229) * feat(theme): add light and dark theme CSS files * refactor(components): cleanup theme provider * refactor(theme): remove Theme directory * test(theme): remove Theme directory * docs(theme): remove theme config * fix(alert): correct RenderFragment parameters usage * chore(theme): correct theme variables * docs(customization): replace Customization section with Theming * test(theme-provider): remove all tests * feat(theme): introduce a mechanism to toggle light/dark modes (#230) * feat(theme): introduce Theme service to manage and persist theme settings (JS) * feat(theme): introduce Theme service to manage and persist theme settings * docs(*): rename ComponentStatus enum to PageStatus * docs(theming): add Dark Mode page * chore(docs): component rename * feat(button): add new `IconOnly` parameter * docs(button): add demo for `IconOnly` parameter * refactor(*): remove all bundled Google Material Icons and related code (#232) * build: add new shared icons project * feat(icons): add base icon component * feat(icons): add dynamic icon component * feat(icons): add some icons * build(deps): reference icons in components * refactor(accordion): use new icon components * docs(components): use new icons in Callout components * docs(*): use new icons * refactor(icons): add "Icon" suffix; add more icons * docs(*): use new icons * test(*): fix tests * refactor(components): remove `LumexIcon` component * docs(datagrid): formatting * refactor(icons): remove all Google Material Icons * refactor(icons): remove script for downloading/updating icons * feat(components): add dark mode support (#234) * feat(alert): add dark mode support * feat(button): add dark mode support * feat(chip): add dark mode support * feat(datagrid): add dark mode support * feat(textbox/numbox): add dark mode support * feat(listbox): add dark mode support * feat(menu): add dark mode support * feat(select): add dark mode support * feat(tabs): add dark mode support * fix(theme): ensure default values are of correct shade in dark mode * feat(theme): add `color-scheme` in light theme * fix(icons): use better icons for alert component * docs: add dark mode support + theme toggle (#235) * docs: add dark mode support * docs: add missing border for the preview component * docs: remove extra border in the preview code component * chore(badge): improve flat variant contrast in light theme * chore(tabs): remove `EditorRequired` attribute from `Id` param * docs: add null check and theme class cleanup to prevent issues * docs: remove IPopoverService injection from theme toggle component * chore(components): remove unused / redundant types * fix(data-grid): correct outside click handler creation * feat(popover): enable position autoUpdate * refactor(popover): make use of popover trigger component instead of service * feat(dropdown): introduce dropdown trigger component instead of relying on popover service * docs(dark-mode): update theme toggle dropdown example * docs: add Home page with library usage examples (#241) * feat(icons): add more icons * docs: add showcases on home page * chore(components): adjust some styles * docs(overview): update paths * chore(docs): nits * fix(components): add missing popover js parts * chore(docs): nits * fix(popover): use overlay to close instead of custom outside click event * fix(tooltip): remove pressed effect from on trigger hover * chore(showcases): complete column visibility toggling in UserTable example * chore(showcases): adjust legend color in usage chart * test(popover): update tests * chore(docs): coderabbit suggestions * chore(*): migrate to DigitalOcean app platform * fix(*): update custom LumexUI targets to copy theme files before build * chore(*): add missing css files in the pack * v2.0.0-preview.4 * perf(*): optimize fonts in docs app * fix(docs): stylesheets import ordering * perf(docs): optimize docs CSS output * fix(docs): correct linux tailwind executable file name * chore(*): delete update-icons.yml * perf(docs): enable stream rendering on all pages * fix(docs): ensure initial theme is set * docs(overview): update content * docs(installation): update content * docs(design-tokens): update content * docs(customization): update content * docs(dark-mode): update content * docs(accordion): update content * refactor(docs): replace `Callout` with `LumexAlert` * docs(avatar): update content * docs(components): replace `Code` component usages with HTML tag * fix(docs): ensure ThemeSelector sets correct theme value on init * docs(landing): make adaptive * docs(customization): add dark mode for global theme sample * refactor(components): remove deprecated `Root` slot * refactor(utils): remove redundant; update access modifiers * docs(card): update slot names * refactor(docs): make stream rendering global * docs(header): remove active state from links; update stars counter * ci(*): remove deploy.yml * ci: run build-test on PR to main * v2.0.0 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Description
Closes #178
This PR introduces the new Spinner component.
What's been done?
Checklist
Additional Notes
Summary by CodeRabbit