feat(nuget): ship precompiled CSS bundle + fix safelist gap (variant .cs helpers)#22
Merged
Conversation
…lwind classes - Introduced a new `shellui-all.css` file containing Tailwind CSS styles, enhancing the styling capabilities of the ShellUI framework. - Updated `shellui-classes.txt` to include additional Tailwind utility classes, improving the safelist for better integration and usage in consumer projects. - Added various background, border, and text color classes, along with new utility classes for layout and spacing adjustments.
…UI components - Updated the README files for both ShellUI and ShellUI.CLI to introduce a new installation path matrix, clarifying the four available methods for integrating ShellUI components. - Enhanced the descriptions for each installation path, detailing benefits, trade-offs, and setup instructions to improve user experience and understanding. - Added a new section in ShellUI.CLI README to emphasize the CLI's role in source ownership and customization. - Improved clarity in ShellUI.Components README regarding the integration of Tailwind CSS and the usage of the safelist for tree-shaken CSS.
…onents - Introduced a new script `rebuild-precompiled-css.sh` that automates the regeneration of the precompiled Tailwind CSS file `shellui-all.css`. - The script downloads the Tailwind standalone CLI, caches it, and compiles the CSS using a combination of theme and utility classes. - Ensures compatibility across different platforms and integrates with CI workflows to validate no drift in the generated CSS.
- Updated the `ShellUI.SafelistGenerator` to scan both `.razor` and `.cs` files, ensuring comprehensive extraction of Tailwind utility classes. - Introduced a new method `ExtractFromCSharp` to handle class extraction from C# source files, improving the accuracy of the generated safelist. - Modified the output message to reflect the count of classes extracted from both file types, enhancing user feedback during execution.
…elist generation - Renamed the test method for clarity, reflecting the inclusion of both `.razor` and `.cs` files in the safelist generation process. - Enhanced the test to concatenate C# files from the components root directory with the existing Razor files, ensuring comprehensive coverage for Tailwind utility class extraction.
- Added numerous new Tailwind utility classes to the safelist, including background, border, and text color classes, enhancing styling options for ShellUI components. - Introduced additional classes for dark mode and hover states, improving responsiveness and visual appeal. - Updated the structure to include new utility classes for layout and spacing adjustments, ensuring comprehensive coverage for Tailwind's capabilities.
…orkflows - Introduced a new step in both CI and release workflows to verify that the precompiled CSS bundle is up-to-date, preventing stale assets from being shipped. - Implemented checks to ensure the bundle size does not exceed 150KB and that essential Tailwind rules are present, enhancing the reliability of the CSS output. - Added error messages to guide developers in regenerating the CSS bundle if discrepancies are found, improving the development workflow.
- Changed the file mode of `rebuild-precompiled-css.sh` from 644 to 755, ensuring it is executable. This adjustment facilitates the script's execution in CI workflows and local development environments.
…css.sh with bash - Modified the invocation of the `rebuild-precompiled-css.sh` script in both CI and release workflows to use `bash` instead of relying on the file's executable bit. This change ensures compatibility for Windows contributors and simplifies the execution process.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds a “NuGet-only” installation path for ShellUI by shipping a precompiled Tailwind CSS bundle as a static web asset, and fixes a safelist-generation gap by scanning both .razor and .cs sources so Tailwind utilities composed in C# variant helpers are included.
Changes:
- Ship a committed, precompiled
shellui-all.cssbundle for consumers to include via a single<link>tag (no Tailwind pipeline required). - Extend the safelist generator (and drift tests) to scan
.csfiles in addition to.razor, improving coverage for variant/helper-composed class strings. - Update CI/release workflows, rebuild script, and docs to support and validate the new install paths.
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/ShellUI.SafelistGenerator/Program.cs | Adds .cs scanning and C# string-literal extraction for safelist generation. |
| src/ShellUI.Components/wwwroot/shellui-classes.txt | Updated committed safelist output used for Tailwind @source builds. |
| src/ShellUI.Components/wwwroot/shellui-all.css | New committed precompiled Tailwind bundle shipped as a static web asset. |
| src/ShellUI.Components/README.md | Documentation update describing the three NuGet package install paths (A/B/C). |
| src/ShellUI.Components/build/ShellUI.Components.targets | Updated embedded safelist entries written into consumer wwwroot/ at build time. |
| src/ShellUI.CLI/README.md | CLI README reframed to clarify when Path C (CLI) is the right choice. |
| ShellUI.Tests/SafelistDriftTests.cs | Drift test updated to match generator behavior by scanning .razor + .cs. |
| scripts/rebuild-precompiled-css.sh | New script to regenerate the committed shellui-all.css bundle deterministically. |
| README.md | Root docs overhauled to present four install paths (A/B/C/D) and trade-offs. |
| .github/workflows/release.yml | Adds a release-time drift check to ensure the precompiled bundle is up-to-date. |
| .github/workflows/ci.yml | Adds CI drift/size checks and a NuGet-consumer smoke test for the bundle asset. |
Files not reviewed (1)
- src/ShellUI.Components/wwwroot/shellui-all.css: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Added a comment to the .gitignore file regarding the generated Tailwind bundle and instructions for local developers to regenerate it. - Removed the shellui-all.css file as it is now generated in CI, preventing unnecessary drift-check failures.
…bundle - Modified the CI and release workflows to generate the precompiled CSS bundle on every run, eliminating drift-check failures due to platform-specific output differences. - Implemented content validation checks to ensure essential Tailwind rules are present in the generated bundle, enhancing reliability and preventing stale assets from being shipped. - Updated error handling to provide clearer guidance for developers if the bundle is not produced or if critical classes are missing.
…orkflow - Added a step to remove cached ShellUI.Components from the NuGet packages directory to prevent stale versions from interfering with the package restore process. - This change ensures that the latest version of the package is used, improving the reliability of the CI workflow.
…and consumer output - Added diagnostic steps to the CI workflow to verify the contents of the generated nupkg, ensuring essential assets are included. - Implemented checks to list the consumer's build output and NuGet cache, providing clearer error messages if the expected bundle is missing. - These improvements aim to enhance the reliability of the CI process and assist developers in troubleshooting issues related to the precompiled CSS bundle.
- Updated the `rebuild-precompiled-css.sh` script to use a portable form of `mktemp`, ensuring compatibility across different operating systems, including macOS and BSD. - Adjusted the temporary CSS file creation to append the `.css` extension after generating the temporary file, improving clarity and consistency in file handling.
- Revised README files to clarify that `shellui-classes.txt` is an auto-generated safelist of all Tailwind classes used in ShellUI. - Updated `ShellUI.Components.targets` to remove outdated and unnecessary Tailwind classes, streamlining the safelist for better maintainability. - Enhanced the `SafelistDriftTests` to ensure consistent source file enumeration for safelist generation, improving test reliability.
… safelist - Revised the README to specify that `shellui-classes.txt` is an auto-generated safelist of all Tailwind classes used in ShellUI. - Removed outdated Tailwind classes from `shellui-classes.txt`, streamlining the safelist for better maintainability and clarity.
…ist generation - Introduced a new method, `EnumerateSources`, to encapsulate the logic for retrieving both .razor and .cs files, improving code organization and reusability. - Enhanced the extraction process from .cs files to filter out non-class-list strings, ensuring only relevant tokens are included in the safelist. - Added a heuristic to identify class-list strings, reducing the risk of including irrelevant literals in the safelist.
- Replaced manual file retrieval for .razor and .cs files with a call to `Program.EnumerateSources`, aligning the test's source enumeration with the CLI's approach. - This change ensures consistency in file lists used for safelist generation, reducing the risk of false-positive drifts.
- Revised the README to clarify that `shellui-classes.txt` is an auto-generated safelist of every Tailwind class used in ShellUI, enhancing understanding for users.
- Modified the CI workflow to adapt to .NET 10's handling of static web assets, ensuring the correct assertion for the presence of the `shellui-all.css` file in the extracted NuGet cache. - Updated error messages and checks for Tailwind rules in the bundle to improve clarity and accuracy, enhancing the reliability of the CI process.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Delivers the "no Tailwind, no CLI, just add the package and go" install path — Path A: precompiled ~77KB CSS bundle shipped as a static web asset in the NuGet package. Consumers add one
<link>tag and every ShellUI component renders styled.While validating all four install paths end-to-end locally (see
shellui-installation-tests/), discovered a material correctness bug the branch also fixes: the safelist generator only scanned.razorfiles, silently missing ~100 Tailwind classes that live inVariants/*.csC# helpers (BadgeVariants, AlertVariants, etc.). Path A and Path B consumers were shipping with broken Badge padding, borders, and hover states. Path C (CLI) was unaffected because the CLI copies the.csfiles into the user's project.Combined with the safelist path from the previous branch, ShellUI now supports four install paths covering every project shape from raw HTML prototypes to full-source-ownership Blazor apps.
What ships
Path A: the precompiled CSS bundle
src/ShellUI.Components/wwwroot/shellui-all.css(new, committed) — 76,832 bytes minified. 961 CSS rules covering all safelisted classes. Auto-shipped as a static web asset → served at runtime as_content/ShellUI.Components/shellui-all.css.<link>tag +@using ShellUI.Components. Zero Tailwind setup.Safelist generator now scans
.cstoo (the bug fix)tools/ShellUI.SafelistGenerator/Program.cs— dual scan of.razorand.csfiles. Extracts Tailwind-shaped tokens from string literals in variant helpers. Result: 307 → 409 classes (+33% coverage). Every rule the components actually apply is now compiled into both the precompiled bundle and the Path B safelist.Concrete example of what was missing:
BadgeVariants.cscomposes"border-transparent bg-primary text-primary-foreground hover:bg-primary/80"in C#.cs, sopx-2.5,py-0.5,border-transparent,hover:bg-primary/80etc. weren't in the safelistShellUI.Tests/SafelistDriftTests.cs— the drift test was renamed and updated to feed the generator both file types. Regeneration locked into CI, so this can never re-ship.scripts/rebuild-precompiled-css.sh(new)Shared script for local dev and CI. Reads Tailwind version from
TailwindConstants.cs(single source of truth), downloads the standalone CLI (cached at~/.shellui/bin/— reusable across projects), composes a fixture withshellui-theme.css+@source inline("…")containing all safelist classes, compiles a minified bundle.The
@source inline("…")form was a deliberate choice over@source "file.txt"— Tailwind's file-based extractor silently fails on classes with[state=…]arbitrary values.CI validation
.github/workflows/ci.yml:git diff --exit-codeif the committed bundle drifted. 150KB size guard.shellui-all.csslands at_content/ShellUI.Components/shellui-all.cssin the consumer's build output, contains--background:theme var,.bg-background,hover:bg-accent:hover,data-[state=open]selector..github/workflows/release.yml: same drift check before release build.Documentation overhaul
Root
README.mdandsrc/ShellUI.Components/README.mdnow consistently frame four install paths with who each is for, benefits, and trade-offs:dotnet add package+<link>dotnet add package+@sourcedirectiveshellui init+shellui add<link>Each path documents ✅ benefits and ❌ trade-offs. A "Quick decision matrix" leads the section. Cross-path theming comparison table shows where the theme lives and how to edit it for each path.
src/ShellUI.CLI/README.md(ships on nuget.org) now leads with "Is this what I want?" pointing users to Paths A/B/D if the CLI isn't the right fit.shellui-installation-tests/(gitignored, local-only)Four minimal test projects, one per path, for manual verification before shipping:
path-a-precompiled/— Blazor Web App with the bundle wired. Runs at localhost:5100. Showcase page with Button/Card/Alert/Badge.path-b-safelist/— Blazor Web App + hand-composed input.css + standalone Tailwind CLI compilation. Runs at localhost:5100 (after Path A is stopped). Same showcase → surfaced the .cs bug.path-c-cli/— CLI installed locally,shellui init+shellui add. Runs at localhost:5200. Showcase using project-localComponents/UI/*.razor.path-d-cdn/— static HTML using ShellUI's Tailwind classes via jsdelivr URL (or local file for dev).Each subdirectory README covers: what's already set up, what YOU need to do, how to run the demo, how to modify the theme. Top-level README explains the folder's purpose.
Verification
dotnet test ShellUI.Tests— 54/54 passing including the extended drift test that feeds both file typesdotnet pack→ install intodotnet new blazor→dotnet build→ confirmedshellui-all.csslands atbin/Debug/net10.0/wwwroot/_content/ShellUI.Components/shellui-all.css, served at 200 by Kestrel.csscan fix. Before the fix, Badges were flat/broken — proves the bug was real and the fix worksComponents/UI/*.razorrender identically to Path A/B (as expected — same underlying classes)Test plan
dotnet runinshellui-installation-tests/path-a-precompiled— styled showcase at http://localhost:5100dotnet runinshellui-installation-tests/path-c-cli— same showcase, source-owned componentsEnableShellUIAutoBuild=falseescape hatch works for consumers on custom Tailwind pipelines