Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,15 @@ jobs:
- name: Pack NuGet packages
run: dotnet pack ShellUI.sln --no-build --configuration Release -p:ContinuousIntegrationBuild=true

# ShellUI.Core and ShellUI.Templates are internal-only — they have no public API
# surface that consumers reference. Only the CLI tool and the Components runtime
# library are pushed to NuGet.
- name: Publish to NuGet
run: |
dotnet nuget push src/ShellUI.CLI/bin/Release/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
if ls src/ShellUI.CLI/bin/Release/*.snupkg 1> /dev/null 2>&1; then
dotnet nuget push src/ShellUI.CLI/bin/Release/*.snupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
fi
dotnet nuget push src/ShellUI.Core/bin/Release/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
if ls src/ShellUI.Core/bin/Release/*.snupkg 1> /dev/null 2>&1; then
dotnet nuget push src/ShellUI.Core/bin/Release/*.snupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
fi
dotnet nuget push src/ShellUI.Components/bin/Release/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
if ls src/ShellUI.Components/bin/Release/*.snupkg 1> /dev/null 2>&1; then
dotnet nuget push src/ShellUI.Components/bin/Release/*.snupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
Expand All @@ -73,7 +72,6 @@ jobs:
prerelease: ${{ contains(github.ref, '-') }}
files: |
src/ShellUI.CLI/bin/Release/*.nupkg
src/ShellUI.Core/bin/Release/*.nupkg
src/ShellUI.Components/bin/Release/*.nupkg
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<!-- Centralized ShellUI Version - Update this single file to version all components -->
<PropertyGroup>
<ShellUIVersion>0.3.0</ShellUIVersion>
<ShellUIVersionSuffix>alpha.3</ShellUIVersionSuffix>
<ShellUIVersionSuffix>rc.1</ShellUIVersionSuffix>
</PropertyGroup>

<!-- Common properties for all ShellUI projects -->
Expand Down
90 changes: 27 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,67 +304,43 @@ Simply edit the component file in `Components/UI/` - it's yours to modify!

## 📦 Package Overview

ShellUI consists of 2 packages:
ShellUI ships two NuGet packages — the CLI is the primary install path; the runtime DLL is optional.

| Package | Type | Purpose | When to Use |
|---------|------|---------|-------------|
| `ShellUI.CLI` | Global Tool | Command-line tool for component installation | Development tool, install globally |
| `ShellUI.Components` | NuGet Package | Blazor components and variants | Runtime dependency for your app |
| Package | Type | Required? | Purpose |
|---------|------|-----------|---------|
| `ShellUI.CLI` | .NET global tool | ✅ Yes — primary install path | Sets up Tailwind, theme CSS, patches `App.razor`, and copies component source so Tailwind can scan it |
| `ShellUI.Components` | Razor class library | Optional | Runtime DLL with the same components + `shellui.js` interop + `Shell.Cn` helper. Useful when you want to reference component types from your own code or build a library on top of ShellUI |

**For Users:**
- Install `ShellUI.CLI` as a global tool: `dotnet tool install -g ShellUI.CLI`
- Install `ShellUI.Components` in your project: `dotnet add package ShellUI.Components`
`ShellUI.Core` and `ShellUI.Templates` are internal to the CLI and not published to NuGet — consumers never reference them directly.

## Installation Options
## Installation

ShellUI is a **CLI-first** library. The CLI is what wires up Tailwind, drops the theme into `wwwroot/input.css`, patches `App.razor` with the render mode and theme bootstrap, and copies component source into your project so Tailwind can scan it.

### Option 1: CLI Tool (Recommended)
```bash
dotnet tool install -g ShellUI.CLI
shellui init # Choose your Tailwind method
shellui add button input card dialog
# Note: CLI tool must be installed first with 'dotnet tool install -g ShellUI.CLI'
shellui init # one-time setup
shellui add button card dialog # any time you want more components
```

### Option 2: NuGet Package
```bash
# Add the component package
dotnet add package ShellUI.Components
That's it. Components render styled out of the box. Re-run `shellui add` whenever you want more.

# Manual setup required - detailed steps below
```
### Where does `ShellUI.Components` (the NuGet package) fit?

**📋 NuGet Package Setup Guide:**
The NuGet package ships the same component DLLs, the JS interop (`shellui.js`), and helpers like `Shell.Cn`. It's useful when you want the runtime types referenced directly — e.g. consuming `Shell.Cn` from your own code, or shipping a library that re-exports ShellUI components.

#### 1. **Install Tailwind CSS v4.1.18**
```bash
# Download the standalone Tailwind CLI
curl -L https://github.com/tailwindlabs/tailwindcss/releases/download/v4.1.18/tailwindcss-linux-x64 -o tailwindcss
chmod +x tailwindcss
sudo mv tailwindcss /usr/local/bin/
```
**The NuGet package alone does not produce styled components.** Tailwind v4 builds the CSS at compile time by scanning `.razor` source files. The component source lives inside the DLL, so Tailwind never sees the utility classes used inside ShellUI components and emits no rules for them. The result: components render with the right HTML structure but with most styling missing.

#### 2. **Remove Bootstrap Files**
Delete these files/folders from your `wwwroot` directory:
```bash
# Remove Bootstrap CSS/JS
rm -rf wwwroot/lib/bootstrap/
rm wwwroot/css/bootstrap*.css
rm wwwroot/css/bootstrap*.min.css
```
The supported way to get styled components is:

#### 3. **Include ShellUI Theme CSS**
Add this link to your main layout file (usually `Shared/MainLayout.razor` or similar):
```html
<link rel="stylesheet" href="_content/ShellUI.Components/shellui-theme.css" />
```
1. `dotnet tool install -g ShellUI.CLI`
2. `shellui init` — sets up Tailwind, theme CSS, and patches `App.razor`
3. `shellui add <component-name>` for every component you want styled — this copies the `.razor` source into your project so Tailwind can scan it
4. *(Optional)* `dotnet add package ShellUI.Components --prerelease` if you also want the runtime DLL on hand (most projects don't need both — pick one)

#### 4. **Update _Imports.razor**
Add this line to your `Pages/_Imports.razor` or `Components/_Imports.razor`:
```razor
@using ShellUI.Components
```
We're tracking a proper "NuGet-only with auto-CSS" path for a future release (`v0.4.x`). Until then, run the CLI.

#### 5. **Configure Tailwind CSS**
### Configure Tailwind CSS manually (advanced)
Create/update `wwwroot/tailwind.config.js`:
```javascript
/** @type {import('tailwindcss').Config} */
Expand Down Expand Up @@ -554,27 +530,15 @@ Update `wwwroot/app.css` (or create it):
@import "./input.css";
```

#### 5. **Update _Layout.cshtml or MainLayout.razor**
Add Tailwind CSS to your layout:
#### 5. **Reference the compiled CSS**
Add the link to your layout (`_Layout.cshtml` or `MainLayout.razor`):
```html
<!-- In _Layout.cshtml -->
<link href="~/app.css" rel="stylesheet" />

<!-- Or in MainLayout.razor -->
<link href="app.css" rel="stylesheet" />
```

**📋 NuGet Package Checklist:**
- ✅ Install package: `dotnet add package ShellUI.Components`
- ✅ **Remove Bootstrap**: Delete `wwwroot/lib/bootstrap/` folder and `wwwroot/css/bootstrap*.css` files
- ✅ **Install Tailwind**: Download Tailwind CLI v4.1.18
- ✅ **Include theme CSS**: Add ShellUI theme CSS link to your main layout
- ✅ **Add using**: `@using ShellUI.Components` in `_Imports.razor`
- ✅ **Create config**: `wwwroot/tailwind.config.js`
- ✅ **Create CSS**: `wwwroot/input.css` and `wwwroot/app.css`
- ✅ **Update layout**: Add CSS link to your main layout file

**⚠️ Important:** ShellUI components require Tailwind CSS. The NuGet package includes components only - you'll need to set up Tailwind separately.
This is what `shellui init` does for you automatically; documented here for the manual path.

**⚠️ Reminder:** even with all the manual setup above, you still need to copy each component's `.razor` source into your project (`shellui add <name>`) so Tailwind sees the classes it uses. There's no way around this for Tailwind v4 short of pre-compiling a complete CSS bundle and shipping it with the package — which is what the [v0.4.x NuGet-only path](https://github.com/shellui-dev/shellui/issues) will deliver.

## Contributing

Expand Down
111 changes: 111 additions & 0 deletions docs/RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,114 @@
# ShellUI v0.3.0-rc.1 🚦

> Release candidate for v0.3.0. Five branches of integration-tested fixes against the alpha series, surfaced from real-world Blazor Server consumer use. If no critical reports come in during the soak window, this code ships as `v0.3.0` stable with the suffix dropped — no further code changes. Report issues via [GitHub Issues](https://github.com/shellui-dev/shellui/issues).

## TL;DR

`shellui init` + `shellui add` now produce a project that compiles and runs end-to-end without manual host patching. Every alpha.3 install-time papercut documented in the integration notes is fixed and guarded by tests + CI:

- Three chart/dashboard templates no longer ship uncompilable C# verbatim strings
- `SidebarTrigger` mobile hamburger renders (was an invisible FontAwesome class)
- `ThemeToggle` no longer uses `eval` and no longer crashes during Blazor Server prerender
- `shellui init` patches `App.razor` with `@rendermode`, theme bootstrap script, and `shellui.js` link tag — and writes the full default theme to `input.css` instead of just `@import "tailwindcss";`
- `shellui add data-table` actually installs `DataTableModels.cs` and auto-runs `dotnet add package System.Linq.Dynamic.Core`
- `shellui add chart` auto-runs `dotnet add package Blazor-ApexCharts` and the chart tooltip CSS finally renders readable text instead of invisible white-on-white
- New `did you mean …?` typo suggestion (`shellui add datatable` → `Did you mean 'data-table'?`)

Component count corrected across docs: **68 installable** top-level components (not the 100 previously claimed; sub-components and variants ship as auto-installed dependencies).

## 🐛 Critical fixes

### Templates that shipped uncompilable C#
- **`ChartVariants`** — every JS-attribute quote inside the tooltip `Custom = @"..."` block now escapes as `""x""` (the verbatim-string form) instead of bare `"x"` (which terminated the outer string)
- **`PieChart`** — same class of bug but using `\"x\"` (which decoded to literal backslashes in rendered HTML); fixed to `""x""`
- **`DashboardLayout02`** — unterminated empty-string literal in `BuildBreadcrumb` (`segments[0] == ""))` → `segments[0] == """"))`)
- Live `PieChart.razor` in the library had the same backslash bug; fixed to remove visible `\"` from rendered tooltip HTML

### SidebarTrigger + ThemeToggle runtime
- **`SidebarTrigger`** — `<i class="fa-solid fa-bars-staggered">` swapped for inline SVG hamburger. FontAwesome is not a ShellUI dependency, so mobile users on a fresh install previously saw an invisible toggle button
- **`ThemeToggle`** — `JSRuntime.InvokeVoidAsync("eval", …)` dropped in favor of the `ShellUI.addClassToDocument` / `ShellUI.removeClassFromDocument` helpers already shipped in `shellui.js`. No more CSP-blockable `eval`, no new JS surface area
- **`ThemeToggle`** — localStorage read moved from `OnInitializedAsync` (where `IJSRuntime` is unavailable during Blazor Server prerender) to `OnAfterRenderAsync(firstRender)`
- **`InputOTP`** — same `eval` removal applied; now uses `ShellUI.focusElement` for digit-to-digit focus
- **`ThemeService`** — same `eval` cleanup as `ThemeToggle`

### `shellui init` produces a working host
- **App.razor patching** — `<HeadOutlet />` → `<HeadOutlet @rendermode="InteractiveServer" />`, same for `<Routes />`. Existing `@rendermode` values are preserved (won't overwrite `InteractiveAuto`/`InteractiveWebAssembly`)
- **Theme bootstrap `<script>` injected into `<head>`** — reads `localStorage.theme` and applies the `dark` class before paint to avoid the light-flash on dark pages
- **`<script src="shellui.js">` injected** before `_framework/blazor.web.js` (handles both the modern `@Assets[...]` wrapper and the bare form)
- **`wwwroot/index.html` patched** for Blazor WebAssembly standalone projects (theme bootstrap + `shellui.js` only — no render-mode pattern in WASM)
- **`input.css` ships the full default theme** — `:root` light vars, `.dark` dark vars, `@theme inline` mapping for Tailwind v4, `@custom-variant dark`, `@layer base` defaults, and Loading-component animation keyframes. Previously emitted only `@import "tailwindcss";`, so any component using theme variables rendered unstyled
- **`tailwind.config.js` (npm)** — dropped the redundant `hsl(var(--x))` color block; Tailwind v4 reads the palette from `@theme inline` in `input.css`
- **All patching is idempotent** — running `shellui init` twice produces no duplicate scripts or tags

### `shellui add data-table` is no longer a half-install
- **`data-table-models` registered** — the template existed on disk but was missing from `ComponentRegistry`, so the CLI reported `Component 'data-table-models' not found` and left the consumer project unable to compile
- **NuGet auto-install** — new `NuGetDependencies` field on `ComponentMetadata`. `data-table` declares `System.Linq.Dynamic.Core 1.7.1`, `chart` declares `Blazor-ApexCharts 6.0.2`. The CLI walks the dep graph and runs `dotnet add package` once per unique package after all source files are written
- **Did-you-mean suggestions** — Levenshtein-based hint surfaces close matches when a user mistypes a component name. `shellui add datatable` → `Did you mean 'data-table'?` Hidden sub-components are excluded from suggestions

### `shellui add chart` tooltip is finally readable
- **`chart-styles` registered** — the CSS template existed but, like `data-table-models`, was never wired into the registry. Hovering a chart point previously showed an invisible white-on-white tooltip because nothing styled the `.custom-tooltip-*` classes the chart HTML emits
- **`chart` depends on `chart-styles`** — the recursive install walk transitively pulls the CSS in for every chart-family component
- **CSS lands in the right place** — `FilePath` corrected from a path that would have buried the file in `Components/UI/wwwroot/css/` (unreachable) to `../../wwwroot/css/charts.css` (project root)
- **`<link>` auto-injected into App.razor** — same idempotent rewriter pattern used for `shellui.js`. Generic by design: any future `wwwroot/`-targeting CSS asset gets the same treatment

## 🔧 Improvements

- **`docs/RELEASE_NOTES.md`** is now the source of truth that `release.yml` uses as the GitHub Release body — no more drift between the tag description and the file
- **Component count audit** — README, ARCHITECTURE, COMPONENT_ROADMAP, PROJECT_STATUS, COMPARISON, FAQ, QUICKSTART, CLI_SYNTAX, VERSIONING_STRATEGY, and the three package READMEs all now report **68 installable components**, with category breakdowns rederived from `ComponentRegistry` (Form 17, Layout 12, Navigation 7, Overlay 8, Data Display 13, Feedback 9, Utility 2)
- **Preview pipeline restored** — `actions/configure-pages@v4` now passes `enablement: true` so the GitHub Pages site is created on first run instead of erroring with `HttpError: Not Found`

## 🧪 Tests + CI

This release adds three independent layers of regression coverage. The previous alpha shipped with zero of these:

- **`TemplateCompileTests`** (8 tests) — Roslyn `CSharpSyntaxTree.ParseText` over every fixed template's generated content. Pure-C# templates parse whole content; Razor templates extract the `@code` block via a quote/comment-aware brace-balancing tokenizer. When extraction fails (unterminated string), falls back to a class-wrapped parse filtered to literal-related diagnostic IDs (`CS1010`, etc.) so the failure message points at the offending line
- **`TemplateSyncTests`** (3 tests) — for every component that has both a live `.razor` in `src/ShellUI.Components/Components/` and a CLI template, compares the `@code` blocks after normalization (strip comments, blank lines, whitespace). Catches the class of bug that shipped in alpha.3 where someone added a parameter to the live `ThemeToggle.razor` but forgot to mirror it in the template. `AllowedDrift` exception list exists but is empty
- **`InitBootstrapTests`** (8 tests) — direct tests of the App.razor / index.html rewriter. Covers render-mode injection, theme bootstrap placement, script-tag ordering, idempotency, existing-render-mode preservation, and both the modern `@Assets[...]` and bare `<script src="…">` forms
- **`NuGetDepsAndSuggestionsTests`** (15 tests) — Levenshtein matcher, `did-you-mean` exclusions, NuGet metadata, chart-family transitive dependency proofs, namespace convention
- **`ChartStylesTests`** (10 tests) — registry wiring, `FilePath` targets wwwroot, CSS content covers both `.custom-tooltip-*` and `.apexcharts-*` classes with theme variables, link injector + `ResolveHostStylesheetHref` semantics, idempotency
- **CI smoke step** — packs the CLI, installs as a global tool, `dotnet new blazor` → `shellui init` → `shellui add chart pie-chart dashboard-02 data-table` → `dotnet build`. Asserts the auto-injected pieces (`@rendermode`, theme bootstrap, `shellui.js` script, `charts.css` link, NuGet refs, `DataTableModels.cs` presence, full theme in `input.css`) all appear in the produced files. The previous CI did neither tests-on-PR nor end-to-end scaffolding

**Test total:** 53 unit tests (was 0). All pass in Release. Drift canary verified by stashing a fix, observing the precise line-level diff in the test output, and restoring.

## 📦 Installation

```bash
# CLI (prerelease channel — the suffix is intentional)
dotnet tool install -g ShellUI.CLI --version 0.3.0-rc.1

# or upgrade from any alpha
dotnet tool update -g ShellUI.CLI --version 0.3.0-rc.1

shellui init
shellui add button card dialog
```

```bash
# NuGet packages (prerelease channel)
dotnet add package ShellUI.Core --version 0.3.0-rc.1 --prerelease
dotnet add package ShellUI.Components --version 0.3.0-rc.1 --prerelease
```

If `shellui init` runs cleanly and `dotnet build` succeeds on a fresh `dotnet new blazor`, you have everything. There are no manual `<script>` / `<link>` / `@rendermode` patches to make.

## ⏭ What's next

- **`v0.3.0`** stable — same code as rc.1 with the suffix dropped, after a soak window. No further alphas planned for the 0.3 line
- **`v0.4.0-alpha.1`** — .NET 10 upgrade. Begins after 0.3.0 ships. TFM bump, package updates, CI matrix
- **`v0.4.0` and beyond** — generic `DataPicker<TItem, TKey>` (Fix 11 from integration notes), Preview app rewrite, ApexCharts chrome restyle (default legend / axis text Tailwind-styled to match shadcn polish)

See [docs/COMPONENT_ROADMAP.md](COMPONENT_ROADMAP.md) for the longer view.

## 🔗 Links

- **Documentation**: https://shellui.dev
- **GitHub**: https://github.com/shellui-dev/shellui
- **NuGet**: https://www.nuget.org/packages/ShellUI.Components

**Full Changelog**: https://github.com/shellui-dev/shellui/compare/v0.3.0-alpha.3...v0.3.0-rc.1

---

# ShellUI v0.3.0-alpha.3 🚧

> Third alpha of v0.3.0 — dashboard sidebar blocks, JS install fixes, and NuGet Core packaging. Report issues via [GitHub Issues](https://github.com/shellui-dev/shellui/issues).
Expand Down
Loading
Loading