feat(Theme): add Fluent UI theme - #8345
Conversation
- add fluent.min.css theme pack ported from microsoft/fluentui (Fluent 2) design tokens - register Fluent UI in the theme chooser with a site chrome companion css - fix theme list fixed height clipping the 6th theme item
Reviewer's GuideAdds a new Fluent UI theme for BootstrapBlazor, wires it into the demo app as an optional theme alongside Motronic, and updates the theme chooser, documentation, and tests to validate CSS variables and flyout behavior. Sequence diagram for the updated ThemeChooser behaviorsequenceDiagram
actor User
participant ThemeButton as ThemeChooserButton
participant ThemeList as ThemeListPanel
participant Document
User ->> ThemeButton: click
ThemeButton ->> ThemeList: classList.toggle(is-open)
alt Close button exists
User ->> ThemeList: click .btn-close
ThemeList ->> ThemeList: classList.remove(is-open)
end
User ->> ThemeList: click .theme-item
ThemeList ->> ThemeList: classList.remove(is-open)
ThemeButton ->> Document: EventHandler.on(click, outsideClick)
Note over Document,ThemeList: outsideClick handler stored as el.themeOutsideClick
User ->> Document: click outside ThemeButton & ThemeList
Document ->> ThemeList: classList.remove(is-open)
ThemeButton ->> ThemeButton: dispose(id)
ThemeButton ->> ThemeButton: EventHandler.off(click)
ThemeButton ->> Document: EventHandler.off(click, el.themeOutsideClick)
ThemeButton ->> ThemeButton: delete el.themeOutsideClick
ThemeButton ->> ThemeList: EventHandler.off(click)
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Pull request overview
This PR adds a new Fluent UI theme to BootstrapBlazor (including light/dark tokens and component-specific variable overrides), wires it into the demo site’s theme switching flow, and introduces regression tests to guard theme CSS variable integrity and minified asset quality.
Changes:
- Add Fluent UI theme assets (
fluent.css+fluent.min.css) with broad Bootstrap/BootstrapBlazor token + component coverage. - Update the demo site to treat themes as optional (Motronic no longer globally loaded), register Fluent as a selectable theme, and expand the Theme page with a component preview wall.
- Add Sass/unit tests validating Fluent theme semantic variables, var() references, minified banner preservation, and minified/source variable-set parity.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| test/UniTest.Sass/FluentThemeTest.cs | Adds automated checks for Fluent theme CSS correctness and minified asset expectations |
| src/BootstrapBlazor/wwwroot/css/fluent.css | Adds readable Fluent UI theme source (tokens + component overrides) |
| src/BootstrapBlazor/wwwroot/css/fluent.min.css | Adds minified Fluent UI theme with preserved banner header |
| src/BootstrapBlazor.Server/wwwroot/css/fluent.css | Adds demo-site-only Fluent styling variables (site appearance overrides) |
| src/BootstrapBlazor.Server/Locales/zh-CN.json | Adds/updates localized strings for Install/Theme pages to reference Fluent theme |
| src/BootstrapBlazor.Server/Locales/en-US.json | Adds/updates localized strings for Install/Theme pages to reference Fluent theme |
| src/BootstrapBlazor.Server/Components/Pages/Theme.razor.css | Fixes Table preview sizing inside the new preview wall |
| src/BootstrapBlazor.Server/Components/Pages/Theme.razor | Updates theme docs and adds a large component preview wall |
| src/BootstrapBlazor.Server/Components/Pages/Install.razor | Adds Fluent theme link snippet to install instructions |
| src/BootstrapBlazor.Server/Components/Components/ThemeChooser.razor.js | Improves chooser UX: close-on-select, outside-click close, safer element checks |
| src/BootstrapBlazor.Server/Components/Components/ThemeChooser.razor.css | Improves chooser mobile behavior (max-height, scrolling, sticky header) |
| src/BootstrapBlazor.Server/Components/App.razor | Stops globally loading Motronic theme CSS |
| src/BootstrapBlazor.Server/appsettings.json | Registers Fluent and Motronic as optional selectable themes |
| docs/fluentui-parity-review.md | Adds a Fluent parity review/report and execution notes |
Files not reviewed (1)
- src/BootstrapBlazor/wwwroot/css/fluent.min.css: Generated file
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| var banner = BannerRegex().Match(source).Value; | ||
| var body = min[banner.Length..]; | ||
|
|
| // 正文为单行(不存在多行规则)且平均行长远超可读版本 | ||
| var bodyLines = body.Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); | ||
| Assert.Single(bodyLines); | ||
| Assert.True(bodyLines[0].Length > 10000, "压缩文件正文疑似未被压缩"); |
| <h4>Component preview</h4> | ||
|
|
||
| <p>Sections below exercise the core components with minimal parameters. Use the theme button at the bottom-right corner of this site to switch between Fluent UI, Motronic and Bootstrap in light or dark mode and eyeball the result in one place.</p> | ||
|
|
||
| <h4>Buttons</h4> |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8345 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 771 771
Lines 34546 34546
=========================================
Hits 34546 34546
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- Theme.razor introduces a large amount of hardcoded English UI text (e.g. section titles and descriptions) alongside localized strings; consider moving these into the existing localization resources to keep the page fully localizable.
- ThemeChooser.razor.js dispose still queries
.theme-list .btn-closebut does not detach its handler anymore; either remove the unusedcloselookup or consistently unregister any remaining listeners to keep the cleanup logic straightforward.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Theme.razor introduces a large amount of hardcoded English UI text (e.g. section titles and descriptions) alongside localized strings; consider moving these into the existing localization resources to keep the page fully localizable.
- ThemeChooser.razor.js dispose still queries `.theme-list .btn-close` but does not detach its handler anymore; either remove the unused `close` lookup or consistently unregister any remaining listeners to keep the cleanup logic straightforward.
## Individual Comments
### Comment 1
<location path="src/BootstrapBlazor.Server/Components/Pages/Theme.razor" line_range="251" />
<code_context>
+
+<div class="row g-3">
+ <div class="col-12 col-md-4">
+ <DateTimePicker TValue="DateTime" Value="DateTime.Today" />
+ </div>
+ <div class="col-12 col-md-4">
</code_context>
<issue_to_address>
**issue (bug_risk):** Bind the DateTimePicker Value as a C# expression rather than a string literal.
`Value="DateTime.Today"` is treated as a string, not a `DateTime`. Use `Value="@DateTime.Today"` (or bind to a `DateTime` property) so the picker receives the correct type and avoids compile/runtime binding errors.
</issue_to_address>
### Comment 2
<location path="docs/fluentui-parity-review.md" line_range="176" />
<code_context>
+|---|---|---|---|
+| Icon / SvgIcon / BootstrapBlazorIcon | FluentIcon | ✅ | Fluent 图标体系(Fluent System Icons)是独立资产包 |
+| ThemeProvider | FluentDesignTheme / FluentDesignSystemProvider | 🟡 | 都能切明暗主题;Fluent 的设计令牌体系更完整 |
+| Dropzone(DragDrap) | FluentDragContainer / FluentDropZone | 🟡 | 都是拖放容器,交互模型不同 |
+| Logout / LogoutLink | FluentProfileMenu | 🟡 | |
+| FullScreen / GoTop / Affix / Transition | — | ❌ | |
</code_context>
<issue_to_address>
**issue (typo):** Typo in the term "DragDrap" — should likely be "DragDrop".
In the Dropzone row, correct the label from "DragDrap" to "DragDrop" to match the drag-and-drop terminology and avoid confusion.
```suggestion
| Dropzone(DragDrop) | FluentDragContainer / FluentDropZone | 🟡 | 都是拖放容器,交互模型不同 |
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
|
||
| <div class="row g-3"> | ||
| <div class="col-12 col-md-4"> | ||
| <DateTimePicker TValue="DateTime" Value="DateTime.Today" /> |
There was a problem hiding this comment.
issue (bug_risk): Bind the DateTimePicker Value as a C# expression rather than a string literal.
Value="DateTime.Today" is treated as a string, not a DateTime. Use Value="@DateTime.Today" (or bind to a DateTime property) so the picker receives the correct type and avoids compile/runtime binding errors.
| |---|---|---|---| | ||
| | Icon / SvgIcon / BootstrapBlazorIcon | FluentIcon | ✅ | Fluent 图标体系(Fluent System Icons)是独立资产包 | | ||
| | ThemeProvider | FluentDesignTheme / FluentDesignSystemProvider | 🟡 | 都能切明暗主题;Fluent 的设计令牌体系更完整 | | ||
| | Dropzone(DragDrap) | FluentDragContainer / FluentDropZone | 🟡 | 都是拖放容器,交互模型不同 | |
There was a problem hiding this comment.
issue (typo): Typo in the term "DragDrap" — should likely be "DragDrop".
In the Dropzone row, correct the label from "DragDrap" to "DragDrop" to match the drag-and-drop terminology and avoid confusion.
| | Dropzone(DragDrap) | FluentDragContainer / FluentDropZone | 🟡 | 都是拖放容器,交互模型不同 | | |
| | Dropzone(DragDrop) | FluentDragContainer / FluentDropZone | 🟡 | 都是拖放容器,交互模型不同 | |
Link issues
fixes #8344
Summary By Copilot
新增一套完整的 Fluent UI 主题,主要变更:
fluent.css/fluent.min.css,覆盖 Fluent UI 设计令牌(圆角、阴影、色彩、间距)与全部组件样式适配Theme.razor页面新增 Fluent UI 主题入口,并提供组件预览墙(component preview wall)FluentThemeTest.cs做 CSS 变量回归校验Regression?
Risk
Verification
Packaging changes reviewed?
☑️ Self Check before Merge
Summary by Sourcery
Add an optional Fluent UI theme with complete light and dark styling, demo coverage, documentation, and regression validation.
New Features:
Bug Fixes:
Enhancements:
Documentation:
Tests: