diff --git a/.ai-team/agents/beast/history.md b/.ai-team/agents/beast/history.md index ba0bdf0bd..5bb699144 100644 --- a/.ai-team/agents/beast/history.md +++ b/.ai-team/agents/beast/history.md @@ -47,3 +47,14 @@ Team update (2026-02-27): No-op stub property coverage intentionally limited (41-50% acceptable) deep AJAX infrastructure properties omitted decided by Forge Team update (2026-02-27): UpdatePanel Triggers collection deliberately omitted Blazor rendering model makes it unnecessary decided by Forge + +- **Issue #359 — M6-M8 doc page updates (5 pages):** + 1. **ChangePassword** (`docs/LoginControls/ChangePassword.md`) — Verified already complete. Orientation and TextLayout sections with enum tables, migration examples, and `@using BlazorWebFormsComponents.Enums` tip were already present from a prior session. + 2. **PagerSettings** (`docs/DataControls/PagerSettings.md`) — Verified already complete. Properties reference, enum tables, parent control usage examples, and migration notes all match `PagerSettings.cs` source. + 3. **FormView** (`docs/DataControls/FormView.md`) — Added individual CRUD event names (OnItemDeleting/Deleted, OnItemInserting/Inserted, OnItemUpdating/Updated) to Features section. Added "Web Forms Features NOT Supported" section (DataSourceID, ViewState, Theming, RenderTable). Added CRUD event handling example with FormViewUpdateEventArgs/FormViewDeleteEventArgs. + 4. **DetailsView** (`docs/DataControls/DetailsView.md`) — Added Caption/CaptionAlign attributes to Web Forms declarative syntax. Added all 10 style sub-component elements and PagerSettings child element to the Web Forms syntax block, bringing it to parity with actual Web Forms control markup. + 5. **DataGrid** (`docs/DataControls/DataGrid.md`) — Removed stale "not every syntax element supported" caveat (features were implemented in M6-M8). Enhanced paging section with property reference table, PagerStyle example, and admonition explaining DataGrid's built-in numeric pager vs. GridView/FormView/DetailsView PagerSettings. Added PagerSettings cross-reference in See Also. + - All 5 pages verified present in `mkdocs.yml` nav. No nav changes needed. + - **Pattern discovered:** DataGrid is the only pageable data control without PagerSettings sub-component support — it always uses a numeric pager. Worth noting for future migration guidance. + + Team update (2026-02-28): Cyclops fixed MenuItemStyle Font- attributes (SetFontsFromAttributes) and CheckBox bare input id may need doc updates. Issue #379 (LinkButton CssClass) verified as already fixed in M15, can be closed. diff --git a/.ai-team/agents/colossus/history.md b/.ai-team/agents/colossus/history.md index 5539c4977..ee05af5d8 100644 --- a/.ai-team/agents/colossus/history.md +++ b/.ai-team/agents/colossus/history.md @@ -1,127 +1,47 @@ # Colossus — History - + ## Core Context -Integration test engineer. Built test coverage from M1 through M17. 120+ integration tests (smoke + interaction) covering all milestone sample pages. Key patterns established: `WaitUntilState.DOMContentLoaded` for async-bound components, `Filter(HasTextString)` for specific element targeting, ISO timestamp filtering for console errors, `PressSequentiallyAsync` + Tab for Blazor Server inputs. LoginControls pages require `@using BlazorWebFormsComponents.LoginControls`. Never use external image URLs. Full early history in `history-archive.md`. +Integration test engineer. Built test coverage from M1 through M19. 130+ integration tests (smoke + interaction) covering all milestone sample pages. Key patterns established: `WaitUntilState.DOMContentLoaded` for async-bound components, `Filter(HasTextString)` for specific element targeting, ISO timestamp filtering for console errors, `PressSequentiallyAsync` + Tab for Blazor Server inputs. LoginControls pages require `@using BlazorWebFormsComponents.LoginControls`. Never use external image URLs. Full early history in `history-archive.md`. - Team update (2026-02-23): Milestone 6 Work Plan ratified 54 WIs across P0/P1/P2 tiers decided by Forge - Team update (2026-02-23): UI overhaul requested Colossus assigned integration tests (UI-9) decided by Jeffrey T. Fritz +## Key Learnings (Consolidated) -## Summary: Milestone 7 Integration Tests (2026-02-24) +- FormView/ListView bind data in `OnAfterRenderAsync`/`OnAfterRender` — use `DOMContentLoaded` + `WaitForSelectorAsync`. +- Menu interaction tests: skip console error checks (JS interop produces expected errors in headless Playwright). +- Playwright `text=` locator matches innermost element — use `Filter(HasTextString)` on parent container instead. +- For strict-mode violations with duplicate text, target specific element (e.g., `page.Locator("td").Filter(...).First`). +- Use specific selectors like `button:has-text('Edit')` instead of generic selectors to avoid premature wait resolution. +- When sample data models change, interaction test assertions must be updated in lockstep (smoke tests won't catch text mismatches). +- Panel/BackImageUrl has external URLs — smoke test sufficient, no interaction test needed. +- Timer interaction test needs 3-second wait for 2000ms interval tick. +- AJAX controls form a natural test category group. -Added 9 smoke tests and 9 interaction tests for M7 sample pages: GridView Selection/DisplayProperties, TreeView Selection/ExpandCollapse, Menu Selection, DetailsView Styles/Caption, FormView Events/Styles. Menu Selection test skips console error checks (JS interop). FormView tests use DOMContentLoaded (items bound in OnAfterRenderAsync). Build verified green. +## Summary: M1–M9 (archived) -## Learnings +Covered milestones 1–9: initial smoke tests, Calendar/Chart/FileUpload/ImageMap integration tests, Sprint 2–3 components, M7 data controls (GridView, TreeView, Menu, DetailsView, FormView — 9 smoke + 9 interaction). M9 audit found 105 routes, 100 covered, 5 gaps identified. -- FormView sample pages bind Items in `OnAfterRenderAsync`, so tests must use `WaitUntilState.DOMContentLoaded` + explicit `WaitForSelectorAsync` instead of `NetworkIdle`. -- Menu interaction tests should always skip console error checks — the Menu component's JS interop (`bwfc.Page.AddScriptElement`) produces expected console errors in headless Playwright. -- GridView Selection pages render Select links as `` elements inside `` rows — use `tbody tr:first-child a` with `HasTextString = "Select"` to target them. -- DetailsView Caption renders actual `` HTML elements that can be directly queried. -- **Playwright `text=` locator gotcha:** `page.Locator("text=Label:")` matches the *innermost* element containing that text. When the markup is `

Label: value

`, the locator returns the ``, not the parent `

` — so the value portion is excluded from `TextContentAsync()`. Fix: use `page.Locator("p").Filter(new() { HasTextString = "Label:" })` (or the appropriate parent tag) to match the container element that holds both the label and value. -- For `

` containers with multiple `` labels (e.g., TreeView/Menu feedback panels), use `page.Locator("div").Filter(new() { HasTextString = "Target label:" }).Last` to match the specific container div. -- When waiting for FormView to render its item template buttons, use a specific selector like `button:has-text('Edit')` instead of generic `button, input[type='submit']` — the latter matches sidebar/nav buttons that already exist, causing the wait to resolve prematurely before the FormView renders. -- To avoid strict-mode violations when text appears in both rendered output AND code examples, target the specific rendered element (e.g., `page.Locator("td").Filter(new() { HasTextString = "Widget Catalog" }).First`) rather than using bare `text=` locators. +## Summary: Issue #358 — Smoke + Interaction Tests (2026-02-25 to 2026-02-27) - Team update (2026-02-24): Menu auto-ID pattern Menu now auto-generates IDs, JS interop crash fixed decided by Cyclops - Team update (2026-02-24): M8 scope excludes version bump to 1.0 and release decided by Jeffrey T. Fritz - - Team update (2026-02-25): Deployment pipeline patterns established compute Docker version with nbgv before build, gate on secrets, dual NuGet publishing decided by Forge - -## Summary: M9 Integration Test Coverage Audit (WI-11) - -Audited all sample page `@page` routes against ControlSampleTests.cs and InteractiveComponentTests.cs. Found 105 sample routes total; 100 covered by smoke tests, 57 interaction tests exist. Identified **5 pages without any smoke test**: ListView/CrudOperations (M7 — highest priority), Label, Panel/BackImageUrl, LoginControls/Orientation, and DataGrid/Styles. All other M7 features (GridView Selection/DisplayProperties, TreeView Selection/ExpandCollapse, Menu Selection, FormView Events/Styles, DetailsView Styles/Caption) have full smoke + interaction test coverage. Report written to `.ai-team/decisions/inbox/colossus-m9-test-audit.md`. - - Team update (2026-02-25): ToolTip moved to BaseStyledComponent (28+ controls), ValidationSummary comma-split fixed, SkinID boolstring fixed decided by Cyclops - Team update (2026-02-25): M9 plan ratified 12 WIs, migration fidelity decided by Forge - Team update (2026-02-25): Test coverage audit merged 5 gaps identified, P0: ListView CrudOperations decided by Colossus - - Team update (2026-02-25): Consolidated audit reports now use `planning-docs/AUDIT-REPORT-M{N}.md` pattern for all milestone audits decided by Beast - - - Team update (2026-02-25): M12 introduces Migration Analysis Tool PoC (`bwfc-migrate` CLI, regex-based ASPX parsing, 3-phase roadmap) decided by Forge - -## Summary: Issue #358 — 5 Missing Smoke Tests (2026-02-25) - -Added 5 missing smoke test InlineData entries to ControlSampleTests.cs covering all gaps identified in M9 audit: ListView/CrudOperations, Label, Panel/BackImageUrl, LoginControls/Orientation, DataGrid/Styles. All 5 sample pages verified to exist. Tests added as InlineData to existing Theory methods (EditorControl, DataControl, LoginControl). Build verified green (0 errors). - -## Learnings - -- Panel/BackImageUrl sample page uses external placeholder URLs (`via.placeholder.com`). The existing `VerifyPageLoadsWithoutErrors` filter for "Failed to load resource" handles this, so the smoke test works despite the team convention against external image URLs. -- LoginControls/Orientation is at `/ControlSamples/LoginControls/Orientation` (not under `/ControlSamples/Login` or `/ControlSamples/ChangePassword` as initially suggested in the issue). - - - - Team update (2026-02-25): Future milestone work should include a doc review pass to catch stale 'NOT Supported' entries decided by Beast - - Team update (2026-02-25): Shared sub-components of sufficient complexity get their own doc page (e.g., PagerSettings) decided by Beast - - Team update (2026-02-25): All login controls (Login, LoginView, ChangePassword, PasswordRecovery, CreateUserWizard) now inherit from BaseStyledComponent decided by Cyclops - - Team update (2026-02-25): ComponentCatalog.cs now links all sample pages; new samples must be registered there decided by Jubilee - - Team update (2026-02-25): ListView now has full CRUD event parity (7 new events) interaction tests may be needed decided by Cyclops - Team update (2026-02-25): Menu styles use MenuItemStyle with IMenuStyleContainer interaction tests may be needed decided by Cyclops - - Team update (2026-02-25): All new work MUST use feature branches pushed to origin with PR to upstream/dev. Never commit directly to dev. decided by Jeffrey T. Fritz - - - Team update (2026-02-25): Theme core types (#364) use nullable properties for StyleSheetTheme semantics, case-insensitive keys, empty-string default skin key. ThemeProvider is infrastructure, not a WebForms control. GetSkin returns null for missing entries. decided by Cyclops - - - Team update (2026-02-25): SkinID defaults to empty string, EnableTheming defaults to true. [Obsolete] removed these are now functional [Parameter] properties. decided by Cyclops - - - Team update (2026-02-25): ThemeConfiguration CascadingParameter wired into BaseStyledComponent (not BaseWebFormsComponent). ApplySkin runs in OnParametersSet with StyleSheetTheme semantics. Font properties checked individually. decided by Cyclops - - - Team update (2026-02-25): Calendar selection behavior review found 7 issues (1 P0: external SelectedDate sync, 4 P1: SelectWeekText default, SelectedDates sorting/mutability, style layering, 2 P2: test gaps, allocation) decided by Forge - - - Team update (2026-02-25): HTML audit strategy approved decided by Forge - - Team update (2026-02-25): HTML audit milestones M11-M13 defined, existing M12M14, Skins/ThemesM15+ decided by Forge per Jeff's directive - - Team update (2026-02-26): Menu RenderingMode=Table integration tests may need table-mode variants decided by Cyclops - - Team update (2026-02-26): Login+Identity strategy defined integration tests needed when handlers implemented decided by Forge - - Team update (2026-02-26): Data control divergence: normalization pipeline needs stripping and Blazor data control normalization decided by Forge - - Team update (2026-02-26): Post-fix capture: normalizer needs GUID ID stripping and empty style="" removal decided by Rogue - - Team update (2026-02-26): WebFormsPage unified wrapper inherits NamingContainer, adds Theme cascading, replaces separate wrappers decided by Jeffrey T. Fritz, Forge - Team update (2026-02-26): SharedSampleObjects is the single source for sample data parity between Blazor and WebForms decided by Jeffrey T. Fritz +Added 5 smoke test InlineData entries (M9 audit gaps: ListView/CrudOperations, Label, Panel/BackImageUrl, LoginControls/Orientation, DataGrid/Styles). Later added 5 interaction tests: ListView CRUD (2 tests), Label AssociatedControlID, DataGrid Styles, LoginControls Orientation. Panel/BackImageUrl skipped (static). All gaps closed. ## Summary: PR #377 DetailsView Integration Test Fix (2026-02-26) -Fixed 5 stale Customer→Product assertions in InteractiveComponentTests.cs after DetailsView sample pages migrated from Customer to Product model (SharedSampleObjects.Models.Product). Changes: "Customer Details"→"Product Details" (Styles), "Customer Record"→"Product Record" (Caption), "No customers found."→"No products found." (EmptyData), Customer field names→Product field names in EditMode assertion message. All 7 DetailsView integration tests passing. - -## Learnings - -- When sample data models change (e.g., Customer→Product), integration test assertions referencing model-specific text (header text, empty data messages, caption text, field name lists in assertion messages) must be updated in lockstep. Smoke tests won't catch these because they only verify page loads without errors — interactive tests with text-matching assertions are the ones that break. - - Team update (2026-02-26): M15 HTML fidelity strategy full audit pipeline re-run (M15-11) assigned to Colossus after all fixes land decided by Forge - Team update (2026-02-26): Data control analysis found normalization gaps Blazor data control output not normalized, markers need stripping decided by Forge, Rogue - - Team update (2026-02-27): Branching workflow directive feature PRs from personal fork to upstream dev, only devmain on upstream decided by Jeffrey T. Fritz - - Team update (2026-02-27): Issues must be closed via PR references using 'Closes #N' syntax, no manual closures decided by Jeffrey T. Fritz - - - Team update (2026-02-27): M17 AJAX controls implemented ScriptManager/Proxy are no-op stubs, Timer shadows Enabled, UpdatePanel uses ChildContent, UpdateProgress renders hidden, Substitution uses Func callback, new AJAX/Migration Helper categories decided by Cyclops +Fixed 5 stale Customer→Product assertions in InteractiveComponentTests.cs after DetailsView sample pages migrated to Product model. All 7 DetailsView integration tests passing. ## Summary: M17 AJAX Control Integration Tests (2026-02-27) -Added 5 smoke tests for M17 AJAX/Migration Helper sample pages (Timer, UpdatePanel, UpdateProgress, ScriptManager, Substitution) as a new `AjaxControl_Loads_WithoutErrors` Theory group in ControlSampleTests.cs. Added 1 interaction test `Timer_Counter_IncrementsAutomatically` in InteractiveComponentTests.cs that verifies the auto-incrementing counter changes after a 3-second wait (Timer interval is 2000ms). Build verified green (0 errors, 0 warnings). - -## Learnings - -- M17 AJAX controls form a natural test category group ("AJAX / Migration Helper Controls") since they all relate to the Web Forms AJAX toolkit (ScriptManager, Timer, UpdatePanel, UpdateProgress, Substitution). -- Timer interaction test needs a 3-second wait to allow at least one tick at the 2000ms interval. The tick count is displayed inside a `div.alert-info` with text "Tick count:" — use `.Filter(new() { HasTextString = "Tick count:" })` to target it specifically. - - Team update (2026-02-27): Timer duplicate [Parameter] bug fixed; 47 M17 tests established with C# API pattern for Timer decided by Rogue +Added 5 smoke tests (Timer, UpdatePanel, UpdateProgress, ScriptManager, Substitution) as `AjaxControl_Loads_WithoutErrors` Theory group. Added 1 interaction test for Timer auto-increment. Build green. +## Team Updates (Current) - Team update (2026-02-27): M17 audit fixes resolved 5 fidelity issues fixed (EnablePartialRendering default, Scripts collection, CssClass rendering, display:block style, ScriptReference properties). 9 new tests, 1367 total. PR #402 decided by Forge, Cyclops +📌 Team update (2026-02-26): WebFormsPage unified wrapper — inherits NamingContainer, adds Theme cascading — decided by Jeffrey T. Fritz, Forge +📌 Team update (2026-02-26): SharedSampleObjects is the single source for sample data parity — decided by Jeffrey T. Fritz +📌 Team update (2026-02-26): M15 HTML fidelity strategy — full audit pipeline re-run assigned to Colossus — decided by Forge +📌 Team update (2026-02-27): Branching workflow directive — feature PRs from personal fork to upstream dev — decided by Jeffrey T. Fritz +📌 Team update (2026-02-27): Issues must be closed via PR references using 'Closes #N' syntax — decided by Jeffrey T. Fritz +📌 Team update (2026-02-27): M17 AJAX controls implemented — decided by Cyclops +📌 Team update (2026-02-27): M17 audit fixes resolved — 5 fidelity issues, 9 new tests, PR #402 — decided by Forge, Cyclops +📌 Team update (2026-02-27): Timer duplicate [Parameter] bug fixed; 47 M17 tests — decided by Rogue +📌 Team update (2026-02-28): Cyclops fixed CheckBox bare input missing id attribute — integration tests targeting CheckBox by id may now work in no-text scenarios. All 5 M9 audit gap pages now have interaction test coverage. diff --git a/.ai-team/agents/cyclops/history.md b/.ai-team/agents/cyclops/history.md index d5eb6c25a..91840f5d2 100644 --- a/.ai-team/agents/cyclops/history.md +++ b/.ai-team/agents/cyclops/history.md @@ -72,3 +72,20 @@ - **Issue #386 (Stable deterministic IDs):** CheckBox and RadioButtonList already used `ClientID` (from `ComponentIdGenerator`) when developer provides `ID`, falling back to GUID when not. The only fix needed was adding `id="@_inputId"` to CheckBox's bare (no-text) `` element (line 20) which was missing the `id` attribute. RadioButtonList was already correct: `{ClientID}_0`, `{ClientID}_1` pattern for item IDs, and `ClientID` as the `name` attribute for mutual exclusion. Tests in `CheckBox/IDRendering.razor` and `RadioButtonList/StableIds.razor` already cover all scenarios. - **Issue #360 (Menu level styles):** The four style sub-components (`DynamicMenuStyle`, `StaticMenuStyle`, `DynamicMenuItemStyle`, `StaticMenuItemStyle`) were already implemented in `MenuItemStyle.razor.cs` as C# classes inheriting from `MenuItemStyle`. The `IMenuStyleContainer` interface was already wired. The actual fix was that `MenuItemStyle.SetPropertiesFromUnknownAttributes()` did not process `Font-` prefixed attributes (e.g. `Font-Bold`, `Font-Italic`). Added `this.SetFontsFromAttributes(OtherAttributes)` call in `OnInitialized()` after `SetPropertiesFromUnknownAttributes()` to use the existing `HasStyleExtensions.SetFontsFromAttributes` method. This fixed the failing `Menu_StaticMenuItemStyle_FontBold_RendersFontWeight` test. - **Lesson:** When style sub-components use `CaptureUnmatchedValues`, font properties need explicit handling via `SetFontsFromAttributes()` because `Font-Bold` doesn't map to a simple property — it maps to `Font.Bold` on the `FontInfo` sub-object. + +### Issue #379 — LinkButton CssClass Verification (2026-02-27) + +- **Issue #379 (LinkButton CssClass pass-through):** Verified already correct from M15. `LinkButton.razor` already has `class="@GetCssClassOrNull()"` on both `` elements (PostBackUrl null and non-null branches). The `GetCssClassOrNull()` method in the `@code` block correctly returns: CssClass when enabled and non-empty, `null` when enabled and empty (omitting the attribute), and `CssClass + " aspNetDisabled"` when disabled. Six bUnit tests already exist in `LinkButton/Format.razor` covering: CssClass renders, no CssClass omits attribute, disabled adds aspNetDisabled, disabled+CssClass renders both, and CssClass with PostBackUrl. All 25 LinkButton tests pass. No code change needed. +- **Key files:** `src/BlazorWebFormsComponents/LinkButton.razor`, `src/BlazorWebFormsComponents.Test/LinkButton/Format.razor` +- **Lesson:** M15 was thorough — always verify the current state before assuming a bug still exists. The issue was filed before M15 landed. + + Team update (2026-02-28): Rogue noted GetCssClassOrNull() uses IsNullOrEmpty not IsNullOrWhiteSpace whitespace-only CssClass renders class=" " instead of being omitted. Low priority future cleanup. + +### Issue #387 — Normalizer Enhancements (2026-03-01) + +- **Enhancement 1 (case-insensitive matching):** Compare mode now pairs files case-insensitively using lowercase key maps, eliminating false HyperLink/Hyperlink dupes. Preference goes to source A casing for display. +- **Enhancement 2 (boolean attributes):** New `normalizeBooleanAttributes()` collapses `selected=""` and `selected="selected"` to bare `selected` for 6 boolean attrs (selected, checked, disabled, readonly, multiple, nowrap). +- **Enhancement 3 (empty style stripping):** New `stripEmptyStyles()` removes `style=""` attributes before comparison. +- **Enhancement 4 (GUID ID normalization):** New `normalizeGuidIds()` replaces GUID patterns in `id` attribute values with `GUID` placeholder, covering CheckBox/RadioButtonList/FileUpload auto-generated IDs. +- **Key files:** `scripts/normalize-html.mjs`, `scripts/normalize-rules.json` +- **Lesson:** Normalization functions should run in a specific order: regex rules → style normalization → empty style strip → boolean attrs → GUID IDs → attribute sort → artifact cleanup → whitespace. Each step depends on the previous one leaving clean output. diff --git a/.ai-team/agents/forge/history.md b/.ai-team/agents/forge/history.md index 9bfd933c5..858d6e51b 100644 --- a/.ai-team/agents/forge/history.md +++ b/.ai-team/agents/forge/history.md @@ -94,3 +94,16 @@ Line-by-line classification: DataList (110 lines), GridView (33 lines), ListView Team update (2026-02-27): M17 audit fixes resolved 5 fidelity issues fixed (EnablePartialRendering default, Scripts collection, CssClass rendering, display:block style, ScriptReference properties). 9 new tests, 1367 total. PR #402 decided by Forge, Cyclops � Team update (2026-02-27): M17 audit fix test patterns ScriptReference tested via C# instantiation, UpdateProgress CssClass tested with/without value, 9 new tests decided by Rogue + +### Summary: Divergence Registry Update D-11 through D-14 (2026-02-28) + +**By:** Forge +**What:** Added 4 new divergence entries to `planning-docs/DIVERGENCE-REGISTRY.md` based on findings from M15-M18 audit work. Issue #388. + +**New entries:** +- **D-11 (GUID-Based IDs):** CheckBox, RadioButton, RadioButtonList, FileUpload generate GUID-based IDs instead of predictable naming-hierarchy IDs. Status: Fix recommended -- GUIDs are non-deterministic and untargetable. Separate from D-01 (prefix mangling). +- **D-12 (Boolean Attribute Format):** `selected=""` (HTML5) vs `selected="selected"` (XHTML). Status: Intentional -- both are valid HTML per W3C spec. Normalizer should canonicalize. +- **D-13 (Calendar Previous-Month Day Padding):** Web Forms renders full 42-cell grid with adjacent-month days; Blazor may not fill leading cells. Status: Fix recommended -- visible structural content. +- **D-14 (Calendar Style Property Pass-Through):** Web Forms applies inline styles from TitleStyle, DayStyle, TodayDayStyle etc.; Blazor doesn't fully pass through. Status: Fix progressively. + +**Also updated:** Summary table, category definitions (added ID Generation, Attribute Format, Style), revision history, header status line. diff --git a/.ai-team/agents/rogue/history.md b/.ai-team/agents/rogue/history.md index 9d517244a..3e8fb5ad7 100644 --- a/.ai-team/agents/rogue/history.md +++ b/.ai-team/agents/rogue/history.md @@ -96,3 +96,22 @@ All 29 ScriptManager/UpdateProgress/ScriptReference tests pass (0 failures). Bui 📌 Test pattern: UpdateProgress CssClass uses `class="@(string.IsNullOrEmpty(CssClass) ? null : CssClass)"` — when CssClass is empty/null, AngleSharp returns null for `GetAttribute("class")`, matching Web Forms behavior of omitting the class attribute entirely. — Rogue Team update (2026-02-27): M17 audit fixes resolved 5 fidelity issues fixed (EnablePartialRendering default, Scripts collection, CssClass rendering, display:block style, ScriptReference properties). 9 new tests, 1367 total. PR #402 decided by Forge, Cyclops + +### LinkButton CssClass Tests (Issue #379) + +Wrote 8 bUnit tests in `src/BlazorWebFormsComponents.Test/LinkButton/CssClass.razor` verifying CssClass pass-through on the `` element: + +1. `SingleClass_RendersAsClassAttributeOnAnchor` — single class renders correctly +2. `MultipleClasses_RendersSpaceSeparatedOnAnchor` — space-separated classes preserved +3. `NoCssClass_OmitsClassAttribute` — no CssClass param omits class attribute entirely +4. `EmptyCssClass_OmitsClassAttribute` — empty string CssClass also omits attribute +5. `CssClass_WithIdAttribute_BothRenderOnAnchor` — CssClass + ID coexist +6. `CssClass_WithPostBackUrl_RendersOnAnchor` — PostBackUrl branch also renders class +7. `Disabled_NoCssClass_RendersAspNetDisabledOnly` — disabled state adds aspNetDisabled +8. `Disabled_WithCssClass_RendersBothClasses` — disabled + CssClass combines both + +📌 Test pattern: LinkButton has two render branches (PostBackUrl null vs non-null). Both share `GetCssClassOrNull()` which returns null for empty/null CssClass (AngleSharp `HasAttribute("class")` returns false) and appends "aspNetDisabled" when Enabled=false. Must test both branches for CssClass. — Rogue + +📌 Edge case: `GetCssClassOrNull()` uses `string.IsNullOrEmpty()` not `IsNullOrWhiteSpace()` — whitespace-only CssClass like " " would render `class=" "`. Not a blocker for #379 but noted for future audit. — Rogue + + Team update (2026-02-28): Cyclops fixed MenuItemStyle Font- attributes (SetFontsFromAttributes call in OnInitialized) and CheckBox bare input missing id attribute may warrant additional test coverage. Issue #379 confirmed already fixed in M15. diff --git a/.ai-team/decisions.md b/.ai-team/decisions.md index 8c2badaad..31744e648 100644 --- a/.ai-team/decisions.md +++ b/.ai-team/decisions.md @@ -3098,3 +3098,33 @@ The honest bottom line: **This library will never achieve 100% exact HTML match **What:** Added 9 bUnit tests covering all 5 M17 audit fixes (EnablePartialRendering default, Scripts collection, CssClass rendering, display:block;visibility:hidden, ScriptReference properties). Updated 2 existing tests to match new behavior. All 29 ScriptManager/UpdateProgress tests pass. **Why:** Audit fixes change observable behavior — tests must be updated to assert the corrected defaults and new properties. ScriptReference defaults tested via plain C# instantiation (no render needed). UpdateProgress CssClass tested both with and without value to ensure no spurious `class=""` attribute. + +### 2026-02-27: M6-M8 doc pages updated for #359 +**By:** Beast +**What:** Updated 3 of 5 doc pages for Issue #359. ChangePassword and PagerSettings were already complete from prior work. FormView gained explicit CRUD event docs and a "NOT Supported" section. DetailsView Web Forms syntax block now includes Caption/CaptionAlign attributes and all style sub-component/PagerSettings child elements. DataGrid paging docs refreshed stale caveat removed, property table and PagerSettings comparison admonition added. +**Why:** The M9 audit identified these 5 pages as having gaps relative to M6-M8 feature additions. Key finding: DataGrid is the only pageable data control that does NOT support the sub-component. + +### 2026-02-27: Issue #358 5 interaction tests close audit gap +**By:** Colossus +**What:** Added 5 interaction tests in InteractiveComponentTests.cs for pages identified by M9 audit: ListView CrudOperations (2 tests Edit mode, Delete row), Label (AssociatedControlID rendering), DataGrid Styles (caption/header/data rows/GridLines), LoginControls Orientation (4 layout variants). Panel/BackImageUrl skipped static display only, smoke test sufficient. +**Why:** M9 audit identified 5 sample pages without interaction test coverage. Smoke tests were already added in a prior session. All 5 gap pages now have both smoke AND interaction test coverage (except Panel/BackImageUrl which only warrants a smoke test). + +### 2026-02-27: Issue #379 LinkButton CssClass verified as already fixed +**By:** Cyclops +**What:** Issue #379 (LinkButton CssClass not passed to rendered class attribute) was already fixed during M15 (commit 65aedc0). LinkButton.razor already contains class="@GetCssClassOrNull()" on both elements. Six bUnit tests in LinkButton/Format.razor cover all CssClass scenarios. All 25 LinkButton tests pass. +**Why:** No code change needed. Issue #379 can be closed as already resolved. + +### 2026-02-27: MenuItemStyle sub-components must call SetFontsFromAttributes for Font- attributes +**By:** Cyclops +**What:** Added his.SetFontsFromAttributes(OtherAttributes) in MenuItemStyle.OnInitialized() after SetPropertiesFromUnknownAttributes(). This ensures Font-Bold, Font-Italic, Font-Size, etc. attributes declared on style sub-components (like ) are properly applied to the FontInfo sub-object. +**Why:** The SetPropertiesFromUnknownAttributes() method uses reflection to map attribute names to properties, but Font-Bold maps to Font.Bold (a sub-property), not a direct property. Without the explicit SetFontsFromAttributes call, all Font- attributes were silently ignored on menu style sub-components, causing CSS like ont-weight:bold to never appear in rendered output. + +### 2026-02-27: CheckBox must always render id attribute on input element +**By:** Cyclops +**What:** CheckBox.razor's bare (no-text) element was missing the id="@_inputId" attribute. Added it to match the behavior of the text-present code paths. Web Forms always renders an id on CheckBox inputs regardless of whether Text is set. +**Why:** Consistency with Web Forms HTML output and with the text-present code paths in the same component. The bare input path renders class, style, and itle but was missing id, which would break JavaScript targeting and CSS selectors that rely on the control's ID. + +### 2026-02-28: LinkButton CssClass test coverage strategy +**By:** Rogue +**What:** Created dedicated CssClass.razor test file (8 tests) for LinkButton, separate from Format.razor which already had some CssClass tests. Both files coexist Format.razor tests are integration-style (MarkupMatches), CssClass.razor tests are targeted attribute assertions covering edge cases and both render paths (PostBackUrl null vs non-null). +**Why:** Edge case noted: GetCssClassOrNull() uses string.IsNullOrEmpty() not string.IsNullOrWhiteSpace(). Whitespace-only CssClass renders class=" " instead of being omitted. Low priority future cleanup. When testing any component CssClass, verify both "no class" case and disabled state (spNetDisabled appended). diff --git a/.ai-team/decisions/inbox/cyclops-m18-wave2.md b/.ai-team/decisions/inbox/cyclops-m18-wave2.md deleted file mode 100644 index 1dbc1b72b..000000000 --- a/.ai-team/decisions/inbox/cyclops-m18-wave2.md +++ /dev/null @@ -1,9 +0,0 @@ -### 2026-02-27: MenuItemStyle sub-components must call SetFontsFromAttributes for Font- attributes -**By:** Cyclops -**What:** Added `this.SetFontsFromAttributes(OtherAttributes)` in `MenuItemStyle.OnInitialized()` after `SetPropertiesFromUnknownAttributes()`. This ensures `Font-Bold`, `Font-Italic`, `Font-Size`, etc. attributes declared on style sub-components (like ``) are properly applied to the `FontInfo` sub-object. -**Why:** The `SetPropertiesFromUnknownAttributes()` method uses reflection to map attribute names to properties, but `Font-Bold` maps to `Font.Bold` (a sub-property), not a direct property. Without the explicit `SetFontsFromAttributes` call, all Font- attributes were silently ignored on menu style sub-components, causing CSS like `font-weight:bold` to never appear in rendered output. - -### 2026-02-27: CheckBox must always render id attribute on input element -**By:** Cyclops -**What:** CheckBox.razor's bare (no-text) `` element was missing the `id="@_inputId"` attribute. Added it to match the behavior of the text-present code paths. Web Forms always renders an `id` on CheckBox inputs regardless of whether `Text` is set. -**Why:** Consistency with Web Forms HTML output and with the text-present code paths in the same component. The bare input path renders `class`, `style`, and `title` but was missing `id`, which would break JavaScript targeting and CSS selectors that rely on the control's ID. diff --git a/.ai-team/decisions/inbox/cyclops-normalizer.md b/.ai-team/decisions/inbox/cyclops-normalizer.md new file mode 100644 index 000000000..15d32c172 --- /dev/null +++ b/.ai-team/decisions/inbox/cyclops-normalizer.md @@ -0,0 +1,5 @@ +### 2026-03-01: Normalizer pipeline order and compare case-insensitivity + +**By:** Cyclops +**What:** The HTML normalizer pipeline in `scripts/normalize-html.mjs` runs transforms in a fixed order: regex rules → style normalization → empty style strip → boolean attrs → GUID IDs → attribute sort → artifact cleanup → whitespace. Compare mode uses case-insensitive file pairing (lowercase key maps) so that folder casing differences (e.g., HyperLink vs Hyperlink) don't produce false divergences. Boolean attributes are collapsed to bare form, GUIDs in IDs are replaced with `GUID` placeholder, and empty `style=""` attributes are stripped. +**Why:** These 4 enhancements (issue #387) eliminate the main sources of false-positive divergences in the HTML fidelity audit. The pipeline ordering matters because later steps depend on earlier cleanup (e.g., empty style stripping must happen after style normalization). diff --git a/.ai-team/decisions/inbox/forge-divergence-registry.md b/.ai-team/decisions/inbox/forge-divergence-registry.md new file mode 100644 index 000000000..3c247861d --- /dev/null +++ b/.ai-team/decisions/inbox/forge-divergence-registry.md @@ -0,0 +1,33 @@ +# Decision: Divergence Registry D-11 through D-14 + +**Date:** 2026-02-28 +**Author:** Forge (Lead / Web Forms Reviewer) +**Issue:** #388 +**Status:** Recorded + +## Context + +The M15–M18 HTML fidelity audit identified 4 new divergence patterns not covered by D-01 through D-10. These were flagged in multiple audit reports (M11, M12, M15 data control analysis, post-fix capture results, HTML fidelity master report) and needed formal registry entries. + +## Decisions Made + +### D-11: GUID-Based IDs — Fix, don't register as permanent intentional +- **Affected:** CheckBox, RadioButton, RadioButtonList, FileUpload +- **Decision:** These controls should be fixed to use developer-provided ID + `_0`/`_1` suffix convention per Web Forms. GUIDs make HTML non-deterministic and untargetable by CSS/JS. This is a bug, not an architectural divergence. +- **Registered temporarily** so the audit pipeline can normalize GUIDs while the fix is pending. + +### D-12: Boolean Attribute Format — Intentional, no fix +- **Affected:** Any control rendering boolean HTML attributes (selected, checked, disabled) +- **Decision:** `selected=""` vs `selected="selected"` is a platform-level difference. Both are valid HTML5. Register as intentional. Add normalizer rule to canonicalize before comparison. + +### D-13: Calendar Previous-Month Day Padding — Fix recommended +- **Affected:** Calendar +- **Decision:** Web Forms renders a full 42-cell grid with adjacent-month day numbers. This is visible structural content, not infrastructure. Blazor Calendar should match this layout. Registered to track until fixed. + +### D-14: Calendar Style Property Pass-Through — Fix progressively +- **Affected:** Calendar +- **Decision:** The Calendar's style sub-properties (TitleStyle, DayStyle, TodayDayStyle, etc.) are not fully applied to rendered HTML. This is a significant fidelity gap. Fix progressively, prioritizing TitleStyle, DayStyle, and TodayDayStyle first. + +## Rationale + +The divergence registry is the authoritative reference for classifying audit findings. Without these entries, auditors would repeatedly investigate these patterns as potential bugs. D-11, D-13, and D-14 are tracked as "fix recommended" rather than "intentional" — they are registered for visibility but should be resolved. diff --git a/audit-output/diff-report-m19.md b/audit-output/diff-report-m19.md new file mode 100644 index 000000000..91dc84a73 --- /dev/null +++ b/audit-output/diff-report-m19.md @@ -0,0 +1,1003 @@ +# HTML Audit Comparison Report + +Generated: 2026-03-01T19:00:31.861Z + +## Summary +- Controls compared: 128 +- Exact matches: 1 +- Divergences found: 127 + +## Results by Control + +### AdRotator +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| AdRotator | ⚠️ Divergent | Tag structure differs | + +#### AdRotator Diff +```diff +- Visit Bing ++ CSharp +``` + +### BulletedList +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| BulletedList-1 | ⚠️ Divergent | Tag structure differs | +| BulletedList-2 | ⚠️ Divergent | Tag structure differs | +| BulletedList-3 | ⚠️ Divergent | Tag structure differs | + +#### BulletedList-1 Diff +```diff +-
    ++
    • First item
    • Second item
    • Third item
    +-
  • Apple
  • Banana
  • Cherry
  • Date
  • +-
+``` + +#### BulletedList-2 Diff +```diff +-
    ++
    • Item One
    • Item Two
    • Item Three
    • Item Four
    +-
  1. First
  2. Second
  3. Third
  4. +-
+``` + +#### BulletedList-3 Diff +```diff +- +``` + +### Button +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| Button-1 | ⚠️ Divergent | Tag structure differs | +| Button-2 | ❌ Missing in source B | File only exists in first directory | +| Button-3 | ❌ Missing in source B | File only exists in first directory | +| Button-4 | ❌ Missing in source B | File only exists in first directory | +| Button-5 | ❌ Missing in source B | File only exists in first directory | + +#### Button-1 Diff +```diff +- ++ +``` + +### Calendar +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| Calendar-1 | ⚠️ Divergent | Tag structure differs | +| Calendar-2 | ⚠️ Divergent | Tag structure differs | +| Calendar-3 | ⚠️ Divergent | Tag structure differs | +| Calendar-4 | ⚠️ Divergent | Tag structure differs | +| Calendar-5 | ⚠️ Divergent | Tag structure differs | +| Calendar-6 | ⚠️ Divergent | Tag structure differs | +| Calendar-7 | ⚠️ Divergent | Tag structure differs | + +#### Calendar-1 Diff +```diff +- ++
<February 2026>
SunMonTueWedThuFriSat
1234567
891011121314
15161718192021
22232425262728
1234567
891011121314
+- +- +-
<February 2026>
SunMonTueWedThuFriSat25262728293031123456789101112131415161718192021222324252627281234567 +- +``` + +#### Calendar-2 Diff +```diff +- ++
<February 2026>
SunMonTueWedThuFriSat
1234567
891011121314
15161718192021
22232425262728
1234567
891011121314
+- +- +-
<February 2026>
SunMonTueWedThuFriSat25262728293031123456789101112131415161718192021222324252627281234567 +- +``` + +#### Calendar-3 Diff +```diff +- ++
<February 2026>
SunMonTueWedThuFriSat
1234567
891011121314
15161718192021
22232425262728
1234567
891011121314
+- +- +-
<February 2026>
SunMonTueWedThuFriSat>25262728293031>1234567>891011121314>15161718192021>22232425262728>1234567 +- +``` + +#### Calendar-4 Diff +```diff +- ++
<February 2026>
SunMonTueWedThuFriSat
>>1234567
>>891011121314
>>15161718192021
>>22232425262728
>>1234567
>>891011121314
+- +- +-
<February 2026>
>>SunMonTueWedThuFriSat>25262728293031>1234567>891011121314>15161718192021>22232425262728>1234567 +- +``` + +#### Calendar-5 Diff +```diff +- ++
>>
<February 2026>
SunMonTueWedThuFriSat
>>1234567
>>891011121314
>>15161718192021
>>22232425262728
>>1234567
>>891011121314
+- +- +-
<February 2026>
SuMoTuWeThFrSa25262728293031123456789101112131415161718192021222324252627281234567 +- +``` + +#### Calendar-6 Diff +```diff +- ++
<February 2026>
SunMonTueWedThuFriSat
1234567
891011121314
15161718192021
22232425262728
1234567
891011121314
+- +- +-
« PrevFebruary 2026Next »
SunMonTueWedThuFriSat25262728293031123456789101112131415161718192021222324252627281234567 +- +``` + +#### Calendar-7 Diff +```diff +- ++
SunMonTueWedThuFriSat
1234567
891011121314
15161718192021
22232425262728
1234567
891011121314
+- +- +-
<February 2026>
SunMonTueWedThuFriSat25262728293031123456789101112131415161718192021222324252627281234567 +- +``` + +### ChangePassword +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| ChangePassword-1 | ❌ Missing in source B | File only exists in first directory | +| ChangePassword-2 | ❌ Missing in source B | File only exists in first directory | + +### CheckBox +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| CheckBox-1 | ⚠️ Divergent | Tag structure differs | +| CheckBox-2 | ⚠️ Divergent | Tag structure differs | +| CheckBox-3 | ⚠️ Divergent | Tag structure differs | + +#### CheckBox-1 Diff +```diff +- ++ ++ +``` + +#### CheckBox-2 Diff +```diff +- ++ ++ +``` + +#### CheckBox-3 Diff +```diff +- ++ ++ +``` + +### CheckBoxList +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| CheckBoxList-1 | ⚠️ Divergent | Tag structure differs | +| CheckBoxList-2 | ⚠️ Divergent | Tag structure differs | + +#### CheckBoxList-1 Diff +```diff +- ++
+- +- +- +- +- +- +- +- +- +- +``` + +#### CheckBoxList-2 Diff +```diff +- ++ +- +- +- +- +- +-
+``` + +### CompareValidator +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| CompareValidator-1 | ❌ Missing in source B | File only exists in first directory | +| CompareValidator-2 | ❌ Missing in source B | File only exists in first directory | +| CompareValidator-3 | ❌ Missing in source B | File only exists in first directory | +| CompareValidator-Submit | ❌ Missing in source B | File only exists in first directory | + +### CreateUserWizard +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| CreateUserWizard-1 | ❌ Missing in source B | File only exists in first directory | +| CreateUserWizard-2 | ❌ Missing in source B | File only exists in first directory | + +### CustomValidator +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| CustomValidator-1 | ❌ Missing in source B | File only exists in first directory | +| CustomValidator-2 | ❌ Missing in source B | File only exists in first directory | +| CustomValidator-Submit | ❌ Missing in source B | File only exists in first directory | + +### DataList +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| DataList | ⚠️ Divergent | 106 line differences | + +#### DataList Diff +```diff +- ++
Simple Widgets
First Widget - $7.99
Second Widget - $13.99
Third Widget - $100.99
Fourth Widget - $10.99
Fifth Widget - $5.99
Sixth Widget - $6.99
Seventh Widget - $12.99
Eighth Widget - $8.99
Ninth Widget - $2.99
Tenth Widget - $3.99
Eleventh Widget - $16.99
Fritz's Widget - $52.70
End of Line
+- +- This is my caption +- +- +- My Widget List +- +- +- +- First Widget +-
+- $7.99 +- +- +- Hi! I'm a separator! I keep things apart +- +- +- Second Widget +-
+- $13.99 +- +- +- Hi! I'm a separator! I keep things apart +- +- +- Third Widget +-
+- $100.99 +- +- +- Hi! I'm a separator! I keep things apart +- +- +- Fourth Widget +-
+- $10.99 +- +- +- Hi! I'm a separator! I keep things apart +... (truncated) +``` + +### DataPager +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| DataPager | ❌ Missing in source B | File only exists in first directory | + +### DetailsView +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| DetailsView-1 | ❌ Missing in source A | File only exists in second directory | +| DetailsView-2 | ❌ Missing in source A | File only exists in second directory | +| DetailsView-3 | ❌ Missing in source A | File only exists in second directory | +| DetailsView-4 | ❌ Missing in source A | File only exists in second directory | +| DetailsView | ❌ Missing in source B | File only exists in first directory | + +### DropDownList +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| DropDownList-1 | ⚠️ Divergent | Tag structure differs | +| DropDownList-2 | ⚠️ Divergent | Tag structure differs | +| DropDownList-3 | ⚠️ Divergent | Tag structure differs | +| DropDownList-4 | ⚠️ Divergent | Tag structure differs | +| DropDownList-5 | ⚠️ Divergent | Tag structure differs | +| DropDownList-6 | ⚠️ Divergent | Tag structure differs | + +#### DropDownList-1 Diff +```diff +- +- +- +- +- +- +``` + +#### DropDownList-2 Diff +```diff +- +- +- +- +- +``` + +#### DropDownList-3 Diff +```diff +- +- +- +- +- +``` + +#### DropDownList-4 Diff +```diff +- +- +- +``` + +#### DropDownList-5 Diff +```diff +- +- +- +``` + +#### DropDownList-6 Diff +```diff +- +- +- +``` + +### FileUpload +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| FileUpload | ⚠️ Divergent | Tag structure differs | + +#### FileUpload Diff +```diff +- ++ +- +``` + +### FormView +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| FormView | ❌ Missing in source B | File only exists in first directory | + +### GridView +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| GridView | ⚠️ Divergent | Tag structure differs | + +#### GridView Diff +```diff +-
++
IDCompanyNameFirstNameLastName&nbsp;&nbsp;
1VirusJohnSmith
2BoringJoseRodriguez
3Fun MachinesJasonRamirez
+- +- +- +- +- +- +- +- +- +- +-
CustomerIDCompanyNameFirstNameLastName  
1VirusJohnSmith +- +- Search for Virus
2BoringJoseRodriguez +- +- Search for Boring
3Fun MachinesJasonRamirez +- +- Search for Fun Machines
+-
+``` + +### HiddenField +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| HiddenField | ⚠️ Divergent | Tag structure differs | + +#### HiddenField Diff +```diff +- ++ +``` + +### Hyperlink +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| HyperLink-1 | ⚠️ Divergent | Tag structure differs | +| HyperLink-2 | ⚠️ Divergent | Tag structure differs | +| HyperLink-3 | ⚠️ Divergent | Tag structure differs | +| HyperLink-4 | ⚠️ Divergent | Tag structure differs | + +#### HyperLink-1 Diff +```diff +- Blue Button ++ GitHub +``` + +#### HyperLink-2 Diff +```diff +- Blue Button ++ GitHub +``` + +#### HyperLink-3 Diff +```diff +- ++ GitHub +``` + +#### HyperLink-4 Diff +```diff +- Blue Button ++ GitHub +``` + +### Image +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| Image-1 | ⚠️ Divergent | Tag structure differs | +| Image-2 | ⚠️ Divergent | Tag structure differs | + +#### Image-1 Diff +```diff +- Banner image ++ Sample placeholder image +``` + +#### Image-2 Diff +```diff +- Sized image ++ Image with tooltip +``` + +### ImageButton +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| ImageButton-1 | ⚠️ Divergent | Tag structure differs | +| ImageButton-2 | ⚠️ Divergent | Tag structure differs | + +#### ImageButton-1 Diff +```diff +- ++ +``` + +#### ImageButton-2 Diff +```diff +- ++ +``` + +### ImageMap +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| ImageMap | ⚠️ Divergent | Tag structure differs | + +#### ImageMap Diff +```diff +- Navigate ++ Navigation demo imageGo to Button samplesGo to CheckBox samplesGo to Image samples +- Go to BingGo to GitHub +- +``` + +### Label +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| Label-1 | ⚠️ Divergent | Tag structure differs | +| Label-2 | ⚠️ Divergent | Tag structure differs | +| Label-3 | ⚠️ Divergent | Tag structure differs | + +#### Label-1 Diff +```diff +- Hello World ++ Hello, World! +``` + +#### Label-2 Diff +```diff +- Styled Label ++ Important notice +``` + +#### Label-3 Diff +```diff +- Emphasized ++ +``` + +### LinkButton +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| LinkButton-1 | ⚠️ Divergent | Tag structure differs | +| LinkButton-2 | ⚠️ Divergent | Tag structure differs | +| LinkButton-3 | ⚠️ Divergent | Tag structure differs | + +#### LinkButton-1 Diff +```diff +- Click Me ++ LinkButton1 with Command +``` + +#### LinkButton-2 Diff +```diff +- Submit Form ++ LinkButton2 with Command +``` + +#### LinkButton-3 Diff +```diff +- Disabled Link ++ Click me!! +``` + +### ListBox +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| ListBox-1 | ⚠️ Divergent | Tag structure differs | +| ListBox-2 | ⚠️ Divergent | Tag structure differs | + +#### ListBox-1 Diff +```diff +- +- +- +- +- +- +- +- +``` + +#### ListBox-2 Diff +```diff +- +- +- +- +- +- +``` + +### ListView +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| ListView | ⚠️ Divergent | 158 line differences | + +#### ListView Diff +```diff +- ++
+- ++ +- ++ +- ++ +- ++ +- ++ +- ++ +- ++ +- ++ +- ++ +- ++ +- ++ +- ++ +- ++ +- ++ +- ++ +- ++ +- ++ +- ++ +- ++ +... (truncated) +``` + +### Literal +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| Literal-1 | ⚠️ Divergent | Tag structure differs | +| Literal-2 | ⚠️ Divergent | Tag structure differs | +| Literal-3 | ✅ Match | - | + +#### Literal-1 Diff +```diff +- This is literal content. ++ Literal +``` + +#### Literal-2 Diff +```diff +- This is <b>encoded</b> content. ++ <b>Literal</b> +``` + +### Login +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| Login-1 | ❌ Missing in source B | File only exists in first directory | +| Login-2 | ❌ Missing in source B | File only exists in first directory | + +### LoginName +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| LoginName-1 | ❌ Missing in source B | File only exists in first directory | +| LoginName-2 | ❌ Missing in source B | File only exists in first directory | + +### LoginStatus +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| LoginStatus-1 | ❌ Missing in source B | File only exists in first directory | +| LoginStatus-2 | ❌ Missing in source B | File only exists in first directory | + +### LoginView +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| LoginView-1 | ❌ Missing in source B | File only exists in first directory | + +### Menu +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| Menu-1 | ❌ Missing in source B | File only exists in first directory | +| Menu-2 | ❌ Missing in source B | File only exists in first directory | +| Menu-3 | ❌ Missing in source B | File only exists in first directory | +| Menu-4 | ❌ Missing in source B | File only exists in first directory | +| Menu-5 | ❌ Missing in source B | File only exists in first directory | +| Menu-6 | ❌ Missing in source B | File only exists in first directory | +| Menu-7 | ❌ Missing in source B | File only exists in first directory | +| Menu-8 | ❌ Missing in source B | File only exists in first directory | +| Menu-9 | ❌ Missing in source B | File only exists in first directory | + +### MultiView +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| MultiView-1 | ❌ Missing in source B | File only exists in first directory | + +### Panel +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| Panel-1 | ⚠️ Divergent | Tag structure differs | +| Panel-2 | ⚠️ Divergent | Tag structure differs | +| Panel-3 | ⚠️ Divergent | Tag structure differs | + +#### Panel-1 Diff +```diff +-
++

This content is inside a basic Panel.

+-
++

A Panel renders as a div element by default.

+- +- User Info +- +- Name: +- +- +-
+``` + +#### Panel-2 Diff +```diff +-
++
User Information +-

First paragraph of content inside the scrollable panel.

++

Name: John Doe

+-

Second paragraph of content inside the scrollable panel.

++

Email: john@example.com

+-

Third paragraph of content inside the scrollable panel.

+-

Fourth paragraph of content inside the scrollable panel.

+-
+``` + +#### Panel-3 Diff +```diff +-
++

This panel has custom colors and border.

+- +- +-
+``` + +### PasswordRecovery +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| PasswordRecovery-1 | ❌ Missing in source B | File only exists in first directory | +| PasswordRecovery-2 | ❌ Missing in source B | File only exists in first directory | + +### PlaceHolder +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| PlaceHolder | ⚠️ Divergent | Tag structure differs | + +#### PlaceHolder Diff +```diff +-

This content was added programmatically.

PlaceHolder renders no HTML of its own.

++

This content is inside a PlaceHolder.

++

Note: No extra wrapper element is rendered around this content.

+``` + +### RadioButton +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| RadioButton-1 | ❌ Missing in source B | File only exists in first directory | +| RadioButton-2 | ❌ Missing in source B | File only exists in first directory | +| RadioButton-3 | ❌ Missing in source B | File only exists in first directory | + +### RadioButtonList +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| RadioButtonList-1 | ⚠️ Divergent | Tag structure differs | +| RadioButtonList-2 | ⚠️ Divergent | Tag structure differs | + +#### RadioButtonList-1 Diff +```diff +-
Id
Name
PriceIdLast Update
Name
1PriceFirst WidgetLast Update$7.99
2/26/2026
2Second Widget
$13.99
2/26/2026
31Third WidgetFirst Widget$100.99$7.992/26/2026
42/26/2026Fourth Widget
$10.99
2/26/2026
5 Fifth Widget
$5.99
2/26/2026
6
++
++ ++ ++
+-
+-
+-
+- +- +- +- +- +- +- +``` + +#### RadioButtonList-2 Diff +```diff +- ++
++ ++ ++ ++
+-
+- +-
+-
+- +- +``` + +### RangeValidator +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| RangeValidator-1 | ❌ Missing in source B | File only exists in first directory | +| RangeValidator-2 | ❌ Missing in source B | File only exists in first directory | +| RangeValidator-3 | ❌ Missing in source B | File only exists in first directory | +| RangeValidator-Submit | ❌ Missing in source B | File only exists in first directory | + +### RegularExpressionValidator +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| RegularExpressionValidator-1 | ❌ Missing in source B | File only exists in first directory | +| RegularExpressionValidator-2 | ❌ Missing in source B | File only exists in first directory | +| RegularExpressionValidator-3 | ❌ Missing in source B | File only exists in first directory | +| RegularExpressionValidator-Submit | ❌ Missing in source B | File only exists in first directory | + +### Repeater +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| Repeater | ⚠️ Divergent | 62 line differences | + +#### Repeater Diff +```diff +- This is a list of widgets ++ +-
  • First Widget
  • ++ +-
    ++ +-
  • Second Widget
  • ++ +-
    ++ +-
  • Third Widget
  • ++ +-
    ++ +-
  • Fourth Widget
  • ++ +-
    ++ +-
  • Fifth Widget
  • ++ +-
    ++ +-
  • Sixth Widget
  • ++ +-
    ++ +-
  • Seventh Widget
  • ++ +-
    ++ +-
  • Eighth Widget
  • ++ +-
    ++ +-
  • Ninth Widget
  • ++ +-
    ++ +-
  • Tenth Widget
  • ++ +... (truncated) +``` + +### RequiredFieldValidator +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| RequiredFieldValidator-1 | ❌ Missing in source B | File only exists in first directory | +| RequiredFieldValidator-2 | ❌ Missing in source B | File only exists in first directory | +| RequiredFieldValidator-3 | ❌ Missing in source B | File only exists in first directory | +| RequiredFieldValidator-Submit | ❌ Missing in source B | File only exists in first directory | + +### SiteMapPath +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| SiteMapPath-1 | ⚠️ Divergent | Tag structure differs | +| SiteMapPath-2 | ⚠️ Divergent | Tag structure differs | + +#### SiteMapPath-1 Diff +```diff +- Skip Navigation LinksHome > SiteMapPath ++ Home > Products > Electronics > Phones +``` + +#### SiteMapPath-2 Diff +```diff +- Skip Navigation LinksHome > SiteMapPath ++ Home / Products / Electronics / Phones +``` + +### Table +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| Table-1 | ⚠️ Divergent | Tag structure differs | +| Table-2 | ⚠️ Divergent | Tag structure differs | +| Table-3 | ❌ Missing in source B | File only exists in first directory | + +#### Table-1 Diff +```diff +-
    1First Widget$7.992/26/2026

    2Second Widget$13.992/26/2026

    3Third Widget$100.992/26/2026

    4Fourth Widget$10.992/26/2026

    5Fifth Widget$5.992/26/2026

    6Sixth Widget$6.992/26/2026

    7Seventh Widget
    ++ Header 1 +- ++ Header 2 +- ++ Header 3 +- ++ Cell 1 +- ++ Cell 2 +- ++ Cell 3 +- ++ Cell 4 +- ++ Cell 5 +- ++ Cell 6 +- +-
    NameCategoryPrice
    Widget AHardware$9.99
    Widget BSoftware$19.99
    Widget CHardware$14.99
    +``` + +#### Table-2 Diff +```diff +- ++ Product +- ++ Price +- ++ Widget +- ++ $10.00 +- ++ Gadget +- ++ $25.00 +- +- +- +- +-
    IDProductIn Stock
    1AlphaYes
    2BetaNo
    3GammaYes
    +``` + +### TextBox +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| TextBox-1 | ❌ Missing in source B | File only exists in first directory | +| TextBox-2 | ❌ Missing in source B | File only exists in first directory | +| TextBox-3 | ❌ Missing in source B | File only exists in first directory | +| TextBox-4 | ❌ Missing in source B | File only exists in first directory | +| TextBox-5 | ❌ Missing in source B | File only exists in first directory | +| TextBox-6 | ❌ Missing in source B | File only exists in first directory | +| TextBox-7 | ❌ Missing in source B | File only exists in first directory | + +### TreeView +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| TreeView | ⚠️ Divergent | 27 line differences | + +#### TreeView Diff +```diff +- Skip Navigation Links.
    ++ +- +-
    +- +- +- +- +-
    Page1
    +- +- +- +-
    Page 2
    +-
    +-
    +``` + +### ValidationSummary +| Variant | Status | Diff Summary | +|---------|--------|-------------| +| ValidationSummary-1 | ❌ Missing in source B | File only exists in first directory | +| ValidationSummary-2 | ❌ Missing in source B | File only exists in first directory | +| ValidationSummary-3 | ❌ Missing in source B | File only exists in first directory | +| ValidationSummary-Submit | ❌ Missing in source B | File only exists in first directory | diff --git a/audit-output/normalized/blazor/Button/Button-1.html b/audit-output/normalized/blazor/Button/Button-1.html index 2dcc3f66c..004755347 100644 --- a/audit-output/normalized/blazor/Button/Button-1.html +++ b/audit-output/normalized/blazor/Button/Button-1.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/blazor/CheckBox/CheckBox-1.html b/audit-output/normalized/blazor/CheckBox/CheckBox-1.html index 1daa973d6..b88461bb5 100644 --- a/audit-output/normalized/blazor/CheckBox/CheckBox-1.html +++ b/audit-output/normalized/blazor/CheckBox/CheckBox-1.html @@ -1,2 +1,2 @@ - + \ No newline at end of file diff --git a/audit-output/normalized/blazor/CheckBox/CheckBox-2.html b/audit-output/normalized/blazor/CheckBox/CheckBox-2.html index ef160c5da..e1e5a7727 100644 --- a/audit-output/normalized/blazor/CheckBox/CheckBox-2.html +++ b/audit-output/normalized/blazor/CheckBox/CheckBox-2.html @@ -1,2 +1,2 @@ - + \ No newline at end of file diff --git a/audit-output/normalized/blazor/CheckBox/CheckBox-3.html b/audit-output/normalized/blazor/CheckBox/CheckBox-3.html index 184ec5d2f..9fd50c2d7 100644 --- a/audit-output/normalized/blazor/CheckBox/CheckBox-3.html +++ b/audit-output/normalized/blazor/CheckBox/CheckBox-3.html @@ -1,2 +1,2 @@ - + \ No newline at end of file diff --git a/audit-output/normalized/blazor/CheckBoxList/CheckBoxList-1.html b/audit-output/normalized/blazor/CheckBoxList/CheckBoxList-1.html index 2667a7f78..b9092fda8 100644 --- a/audit-output/normalized/blazor/CheckBoxList/CheckBoxList-1.html +++ b/audit-output/normalized/blazor/CheckBoxList/CheckBoxList-1.html @@ -1 +1 @@ -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/audit-output/normalized/blazor/CheckBoxList/CheckBoxList-2.html b/audit-output/normalized/blazor/CheckBoxList/CheckBoxList-2.html index ea9d548ac..44b294174 100644 --- a/audit-output/normalized/blazor/CheckBoxList/CheckBoxList-2.html +++ b/audit-output/normalized/blazor/CheckBoxList/CheckBoxList-2.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/blazor/DropDownList/DropDownList-1.html b/audit-output/normalized/blazor/DropDownList/DropDownList-1.html index da06081b9..ca98463f2 100644 --- a/audit-output/normalized/blazor/DropDownList/DropDownList-1.html +++ b/audit-output/normalized/blazor/DropDownList/DropDownList-1.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/blazor/DropDownList/DropDownList-2.html b/audit-output/normalized/blazor/DropDownList/DropDownList-2.html index 0ac734516..e405e9a0e 100644 --- a/audit-output/normalized/blazor/DropDownList/DropDownList-2.html +++ b/audit-output/normalized/blazor/DropDownList/DropDownList-2.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/blazor/DropDownList/DropDownList-6.html b/audit-output/normalized/blazor/DropDownList/DropDownList-6.html index f7226c3c9..bc9fe96ec 100644 --- a/audit-output/normalized/blazor/DropDownList/DropDownList-6.html +++ b/audit-output/normalized/blazor/DropDownList/DropDownList-6.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/blazor/FileUpload/FileUpload.html b/audit-output/normalized/blazor/FileUpload/FileUpload.html index 9cfcddecf..44078354d 100644 --- a/audit-output/normalized/blazor/FileUpload/FileUpload.html +++ b/audit-output/normalized/blazor/FileUpload/FileUpload.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/blazor/GridView/GridView.html b/audit-output/normalized/blazor/GridView/GridView.html index 3f779d70b..77cc6a8a6 100644 --- a/audit-output/normalized/blazor/GridView/GridView.html +++ b/audit-output/normalized/blazor/GridView/GridView.html @@ -1 +1 @@ -
    IDCompanyNameFirstNameLastName&nbsp;&nbsp;
    1VirusJohnSmith
    2BoringJoseRodriguez
    3Fun MachinesJasonRamirez
    \ No newline at end of file +
    IDCompanyNameFirstNameLastName&nbsp;&nbsp;
    1VirusJohnSmith
    2BoringJoseRodriguez
    3Fun MachinesJasonRamirez
    \ No newline at end of file diff --git a/audit-output/normalized/blazor/HiddenField/HiddenField.html b/audit-output/normalized/blazor/HiddenField/HiddenField.html index 9fdb7a038..aab3c94e5 100644 --- a/audit-output/normalized/blazor/HiddenField/HiddenField.html +++ b/audit-output/normalized/blazor/HiddenField/HiddenField.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/blazor/ImageButton/ImageButton-1.html b/audit-output/normalized/blazor/ImageButton/ImageButton-1.html index 6fb4c1962..a44b6e807 100644 --- a/audit-output/normalized/blazor/ImageButton/ImageButton-1.html +++ b/audit-output/normalized/blazor/ImageButton/ImageButton-1.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/blazor/ImageButton/ImageButton-2.html b/audit-output/normalized/blazor/ImageButton/ImageButton-2.html index 97e2028da..6ca6ca6f3 100644 --- a/audit-output/normalized/blazor/ImageButton/ImageButton-2.html +++ b/audit-output/normalized/blazor/ImageButton/ImageButton-2.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/blazor/ListBox/ListBox-2.html b/audit-output/normalized/blazor/ListBox/ListBox-2.html index 03be277d9..a7354c8f9 100644 --- a/audit-output/normalized/blazor/ListBox/ListBox-2.html +++ b/audit-output/normalized/blazor/ListBox/ListBox-2.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/blazor/RadioButtonList/RadioButtonList-1.html b/audit-output/normalized/blazor/RadioButtonList/RadioButtonList-1.html index 524851ef1..c9bd19e8b 100644 --- a/audit-output/normalized/blazor/RadioButtonList/RadioButtonList-1.html +++ b/audit-output/normalized/blazor/RadioButtonList/RadioButtonList-1.html @@ -1,4 +1,4 @@ - diff --git a/audit-output/normalized/webforms/ChangePassword/ChangePassword-2.html b/audit-output/normalized/webforms/ChangePassword/ChangePassword-2.html index aa0444824..35ea587a6 100644 --- a/audit-output/normalized/webforms/ChangePassword/ChangePassword-2.html +++ b/audit-output/normalized/webforms/ChangePassword/ChangePassword-2.html @@ -4,15 +4,15 @@ - + - + - + - +
    -
    -
    +
    +
    +
    \ No newline at end of file diff --git a/audit-output/normalized/blazor/RadioButtonList/RadioButtonList-2.html b/audit-output/normalized/blazor/RadioButtonList/RadioButtonList-2.html index d0b7e4d27..493e19f31 100644 --- a/audit-output/normalized/blazor/RadioButtonList/RadioButtonList-2.html +++ b/audit-output/normalized/blazor/RadioButtonList/RadioButtonList-2.html @@ -1,5 +1,5 @@ - - + - + - + - +
    - - - +
    + + +
    \ No newline at end of file diff --git a/audit-output/normalized/blazor/TreeView/TreeView.html b/audit-output/normalized/blazor/TreeView/TreeView.html index fcbd9e644..a3b50c923 100644 --- a/audit-output/normalized/blazor/TreeView/TreeView.html +++ b/audit-output/normalized/blazor/TreeView/TreeView.html @@ -1,4 +1,4 @@ \ No newline at end of file diff --git a/audit-output/normalized/webforms/Button/Button-2.html b/audit-output/normalized/webforms/Button/Button-2.html index 4fb0845e5..f3dfaad77 100644 --- a/audit-output/normalized/webforms/Button/Button-2.html +++ b/audit-output/normalized/webforms/Button/Button-2.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/Button/Button-3.html b/audit-output/normalized/webforms/Button/Button-3.html index ec4996d7c..46900449d 100644 --- a/audit-output/normalized/webforms/Button/Button-3.html +++ b/audit-output/normalized/webforms/Button/Button-3.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/Button/Button-4.html b/audit-output/normalized/webforms/Button/Button-4.html index d430d12a2..3e940fdc3 100644 --- a/audit-output/normalized/webforms/Button/Button-4.html +++ b/audit-output/normalized/webforms/Button/Button-4.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/Button/Button-5.html b/audit-output/normalized/webforms/Button/Button-5.html index 550dba8ce..6449b0dfb 100644 --- a/audit-output/normalized/webforms/Button/Button-5.html +++ b/audit-output/normalized/webforms/Button/Button-5.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/ChangePassword/ChangePassword-1.html b/audit-output/normalized/webforms/ChangePassword/ChangePassword-1.html index 7a563f05d..afec574e4 100644 --- a/audit-output/normalized/webforms/ChangePassword/ChangePassword-1.html +++ b/audit-output/normalized/webforms/ChangePassword/ChangePassword-1.html @@ -4,15 +4,15 @@
    Change Your Password
    Update Your Password
    diff --git a/audit-output/normalized/webforms/CheckBox/CheckBox-1.html b/audit-output/normalized/webforms/CheckBox/CheckBox-1.html index 94e42e31e..a89b2c89a 100644 --- a/audit-output/normalized/webforms/CheckBox/CheckBox-1.html +++ b/audit-output/normalized/webforms/CheckBox/CheckBox-1.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/CheckBox/CheckBox-2.html b/audit-output/normalized/webforms/CheckBox/CheckBox-2.html index 07c409857..24f9ce9e8 100644 --- a/audit-output/normalized/webforms/CheckBox/CheckBox-2.html +++ b/audit-output/normalized/webforms/CheckBox/CheckBox-2.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/CheckBox/CheckBox-3.html b/audit-output/normalized/webforms/CheckBox/CheckBox-3.html index ceb176976..0c0da5627 100644 --- a/audit-output/normalized/webforms/CheckBox/CheckBox-3.html +++ b/audit-output/normalized/webforms/CheckBox/CheckBox-3.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/CheckBoxList/CheckBoxList-1.html b/audit-output/normalized/webforms/CheckBoxList/CheckBoxList-1.html index e9069e23e..b23f20ead 100644 --- a/audit-output/normalized/webforms/CheckBoxList/CheckBoxList-1.html +++ b/audit-output/normalized/webforms/CheckBoxList/CheckBoxList-1.html @@ -1,11 +1,11 @@ - + - + - + - +
    \ No newline at end of file diff --git a/audit-output/normalized/webforms/CheckBoxList/CheckBoxList-2.html b/audit-output/normalized/webforms/CheckBoxList/CheckBoxList-2.html index 0279fc77f..d00c4ddf1 100644 --- a/audit-output/normalized/webforms/CheckBoxList/CheckBoxList-2.html +++ b/audit-output/normalized/webforms/CheckBoxList/CheckBoxList-2.html @@ -1,7 +1,7 @@ - + - +
    \ No newline at end of file diff --git a/audit-output/normalized/webforms/CompareValidator/CompareValidator-1.html b/audit-output/normalized/webforms/CompareValidator/CompareValidator-1.html index c8864d02c..22d6da3b6 100644 --- a/audit-output/normalized/webforms/CompareValidator/CompareValidator-1.html +++ b/audit-output/normalized/webforms/CompareValidator/CompareValidator-1.html @@ -1,3 +1,3 @@ -Password:
    -Confirm: +Password:
    +Confirm: \ No newline at end of file diff --git a/audit-output/normalized/webforms/CompareValidator/CompareValidator-2.html b/audit-output/normalized/webforms/CompareValidator/CompareValidator-2.html index 4bc6f9f72..f08a2e780 100644 --- a/audit-output/normalized/webforms/CompareValidator/CompareValidator-2.html +++ b/audit-output/normalized/webforms/CompareValidator/CompareValidator-2.html @@ -1,3 +1,3 @@ Enter a number greater than 10: - + \ No newline at end of file diff --git a/audit-output/normalized/webforms/CompareValidator/CompareValidator-3.html b/audit-output/normalized/webforms/CompareValidator/CompareValidator-3.html index 0616944ed..356156af1 100644 --- a/audit-output/normalized/webforms/CompareValidator/CompareValidator-3.html +++ b/audit-output/normalized/webforms/CompareValidator/CompareValidator-3.html @@ -1,3 +1,3 @@ Enter a date: - + \ No newline at end of file diff --git a/audit-output/normalized/webforms/CompareValidator/CompareValidator-Submit.html b/audit-output/normalized/webforms/CompareValidator/CompareValidator-Submit.html index 67e9832c6..83c86efc9 100644 --- a/audit-output/normalized/webforms/CompareValidator/CompareValidator-Submit.html +++ b/audit-output/normalized/webforms/CompareValidator/CompareValidator-Submit.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/CreateUserWizard/CreateUserWizard-1.html b/audit-output/normalized/webforms/CreateUserWizard/CreateUserWizard-1.html index fe03eac61..7fa7f0773 100644 --- a/audit-output/normalized/webforms/CreateUserWizard/CreateUserWizard-1.html +++ b/audit-output/normalized/webforms/CreateUserWizard/CreateUserWizard-1.html @@ -6,17 +6,17 @@ Sign Up for Your New Account - + - + - + - + - + - + @@ -26,7 +26,7 @@ - +
    diff --git a/audit-output/normalized/webforms/CreateUserWizard/CreateUserWizard-2.html b/audit-output/normalized/webforms/CreateUserWizard/CreateUserWizard-2.html index 7dbf4dec6..d5899f538 100644 --- a/audit-output/normalized/webforms/CreateUserWizard/CreateUserWizard-2.html +++ b/audit-output/normalized/webforms/CreateUserWizard/CreateUserWizard-2.html @@ -6,17 +6,17 @@ Sign Up for Your New Account - + - + - + - + - + - + @@ -26,7 +26,7 @@ - +
    diff --git a/audit-output/normalized/webforms/CustomValidator/CustomValidator-1.html b/audit-output/normalized/webforms/CustomValidator/CustomValidator-1.html index c29d80249..461ebb11c 100644 --- a/audit-output/normalized/webforms/CustomValidator/CustomValidator-1.html +++ b/audit-output/normalized/webforms/CustomValidator/CustomValidator-1.html @@ -1,3 +1,3 @@ Enter an even number: - + \ No newline at end of file diff --git a/audit-output/normalized/webforms/CustomValidator/CustomValidator-2.html b/audit-output/normalized/webforms/CustomValidator/CustomValidator-2.html index dd43186ca..46787efb1 100644 --- a/audit-output/normalized/webforms/CustomValidator/CustomValidator-2.html +++ b/audit-output/normalized/webforms/CustomValidator/CustomValidator-2.html @@ -1,2 +1,2 @@ - + \ No newline at end of file diff --git a/audit-output/normalized/webforms/CustomValidator/CustomValidator-Submit.html b/audit-output/normalized/webforms/CustomValidator/CustomValidator-Submit.html index 67e9832c6..83c86efc9 100644 --- a/audit-output/normalized/webforms/CustomValidator/CustomValidator-Submit.html +++ b/audit-output/normalized/webforms/CustomValidator/CustomValidator-Submit.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/DropDownList/DropDownList-2.html b/audit-output/normalized/webforms/DropDownList/DropDownList-2.html index e975d5f2d..feb61c19a 100644 --- a/audit-output/normalized/webforms/DropDownList/DropDownList-2.html +++ b/audit-output/normalized/webforms/DropDownList/DropDownList-2.html @@ -1,5 +1,5 @@ \ No newline at end of file diff --git a/audit-output/normalized/webforms/DropDownList/DropDownList-4.html b/audit-output/normalized/webforms/DropDownList/DropDownList-4.html index fe22d3b35..4f6549133 100644 --- a/audit-output/normalized/webforms/DropDownList/DropDownList-4.html +++ b/audit-output/normalized/webforms/DropDownList/DropDownList-4.html @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/audit-output/normalized/webforms/FileUpload/FileUpload.html b/audit-output/normalized/webforms/FileUpload/FileUpload.html index a111da251..6b7bb30a1 100644 --- a/audit-output/normalized/webforms/FileUpload/FileUpload.html +++ b/audit-output/normalized/webforms/FileUpload/FileUpload.html @@ -1,2 +1,2 @@ - - \ No newline at end of file + + \ No newline at end of file diff --git a/audit-output/normalized/webforms/HiddenField/HiddenField.html b/audit-output/normalized/webforms/HiddenField/HiddenField.html index 96b2617a2..4f8043e73 100644 --- a/audit-output/normalized/webforms/HiddenField/HiddenField.html +++ b/audit-output/normalized/webforms/HiddenField/HiddenField.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/ImageButton/ImageButton-1.html b/audit-output/normalized/webforms/ImageButton/ImageButton-1.html index 57c518cc5..e89d1b6dd 100644 --- a/audit-output/normalized/webforms/ImageButton/ImageButton-1.html +++ b/audit-output/normalized/webforms/ImageButton/ImageButton-1.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/ImageButton/ImageButton-2.html b/audit-output/normalized/webforms/ImageButton/ImageButton-2.html index 0d528fb36..40df73c83 100644 --- a/audit-output/normalized/webforms/ImageButton/ImageButton-2.html +++ b/audit-output/normalized/webforms/ImageButton/ImageButton-2.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/ListBox/ListBox-2.html b/audit-output/normalized/webforms/ListBox/ListBox-2.html index cf44165b5..535a10b65 100644 --- a/audit-output/normalized/webforms/ListBox/ListBox-2.html +++ b/audit-output/normalized/webforms/ListBox/ListBox-2.html @@ -1,6 +1,6 @@ - - - + + \ No newline at end of file diff --git a/audit-output/normalized/webforms/Login/Login-1.html b/audit-output/normalized/webforms/Login/Login-1.html index 5590f6720..1f10dd899 100644 --- a/audit-output/normalized/webforms/Login/Login-1.html +++ b/audit-output/normalized/webforms/Login/Login-1.html @@ -4,13 +4,13 @@ Log In - + - + - + - + diff --git a/audit-output/normalized/webforms/Login/Login-2.html b/audit-output/normalized/webforms/Login/Login-2.html index 047821bae..0e4d0b52c 100644 --- a/audit-output/normalized/webforms/Login/Login-2.html +++ b/audit-output/normalized/webforms/Login/Login-2.html @@ -4,11 +4,11 @@ Member Login - + - + - + diff --git a/audit-output/normalized/webforms/Menu/Menu-9.html b/audit-output/normalized/webforms/Menu/Menu-9.html index 5457c39a5..67190b2f8 100644 --- a/audit-output/normalized/webforms/Menu/Menu-9.html +++ b/audit-output/normalized/webforms/Menu/Menu-9.html @@ -1,9 +1,9 @@ Skip Navigation Links
    \ No newline at end of file diff --git a/audit-output/normalized/webforms/MultiView/MultiView-1.html b/audit-output/normalized/webforms/MultiView/MultiView-1.html index 73814468f..a06db95c3 100644 --- a/audit-output/normalized/webforms/MultiView/MultiView-1.html +++ b/audit-output/normalized/webforms/MultiView/MultiView-1.html @@ -1,4 +1,4 @@

    Step 1: Personal Information

    -

    Name:

    -

    Email:

    - \ No newline at end of file +

    Name:

    +

    Email:

    + \ No newline at end of file diff --git a/audit-output/normalized/webforms/Panel/Panel-1.html b/audit-output/normalized/webforms/Panel/Panel-1.html index dd706b4cb..5c751c10a 100644 --- a/audit-output/normalized/webforms/Panel/Panel-1.html +++ b/audit-output/normalized/webforms/Panel/Panel-1.html @@ -4,6 +4,6 @@ User Info Name: - +
    \ No newline at end of file diff --git a/audit-output/normalized/webforms/Panel/Panel-3.html b/audit-output/normalized/webforms/Panel/Panel-3.html index fbdee2a18..3a99f0319 100644 --- a/audit-output/normalized/webforms/Panel/Panel-3.html +++ b/audit-output/normalized/webforms/Panel/Panel-3.html @@ -1,4 +1,4 @@
    - - + +
    \ No newline at end of file diff --git a/audit-output/normalized/webforms/PasswordRecovery/PasswordRecovery-1.html b/audit-output/normalized/webforms/PasswordRecovery/PasswordRecovery-1.html index d26dc42d4..db0b909c1 100644 --- a/audit-output/normalized/webforms/PasswordRecovery/PasswordRecovery-1.html +++ b/audit-output/normalized/webforms/PasswordRecovery/PasswordRecovery-1.html @@ -6,9 +6,9 @@ Enter your User Name to receive your password. - + - + diff --git a/audit-output/normalized/webforms/PasswordRecovery/PasswordRecovery-2.html b/audit-output/normalized/webforms/PasswordRecovery/PasswordRecovery-2.html index a1aa561ae..80b05d1f7 100644 --- a/audit-output/normalized/webforms/PasswordRecovery/PasswordRecovery-2.html +++ b/audit-output/normalized/webforms/PasswordRecovery/PasswordRecovery-2.html @@ -6,9 +6,9 @@ Enter your User Name to receive your password. - + - + diff --git a/audit-output/normalized/webforms/RadioButton/RadioButton-1.html b/audit-output/normalized/webforms/RadioButton/RadioButton-1.html index 6c3bf4a4c..d67b890ab 100644 --- a/audit-output/normalized/webforms/RadioButton/RadioButton-1.html +++ b/audit-output/normalized/webforms/RadioButton/RadioButton-1.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/RadioButton/RadioButton-2.html b/audit-output/normalized/webforms/RadioButton/RadioButton-2.html index b20eab4bd..0dcf5a66e 100644 --- a/audit-output/normalized/webforms/RadioButton/RadioButton-2.html +++ b/audit-output/normalized/webforms/RadioButton/RadioButton-2.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/RadioButton/RadioButton-3.html b/audit-output/normalized/webforms/RadioButton/RadioButton-3.html index 9bbc29202..9c72a22ad 100644 --- a/audit-output/normalized/webforms/RadioButton/RadioButton-3.html +++ b/audit-output/normalized/webforms/RadioButton/RadioButton-3.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/RadioButtonList/RadioButtonList-1.html b/audit-output/normalized/webforms/RadioButtonList/RadioButtonList-1.html index f9c67b363..bcf88260f 100644 --- a/audit-output/normalized/webforms/RadioButtonList/RadioButtonList-1.html +++ b/audit-output/normalized/webforms/RadioButtonList/RadioButtonList-1.html @@ -1,11 +1,11 @@ - + - + - + - +
    \ No newline at end of file diff --git a/audit-output/normalized/webforms/RadioButtonList/RadioButtonList-2.html b/audit-output/normalized/webforms/RadioButtonList/RadioButtonList-2.html index ed66b291a..f282cd463 100644 --- a/audit-output/normalized/webforms/RadioButtonList/RadioButtonList-2.html +++ b/audit-output/normalized/webforms/RadioButtonList/RadioButtonList-2.html @@ -1,7 +1,7 @@ - + - +
    \ No newline at end of file diff --git a/audit-output/normalized/webforms/RangeValidator/RangeValidator-1.html b/audit-output/normalized/webforms/RangeValidator/RangeValidator-1.html index 13f327381..809844a79 100644 --- a/audit-output/normalized/webforms/RangeValidator/RangeValidator-1.html +++ b/audit-output/normalized/webforms/RangeValidator/RangeValidator-1.html @@ -1,3 +1,3 @@ Enter a number between 1 and 100: - + \ No newline at end of file diff --git a/audit-output/normalized/webforms/RangeValidator/RangeValidator-2.html b/audit-output/normalized/webforms/RangeValidator/RangeValidator-2.html index 8f821d945..aaca0a85b 100644 --- a/audit-output/normalized/webforms/RangeValidator/RangeValidator-2.html +++ b/audit-output/normalized/webforms/RangeValidator/RangeValidator-2.html @@ -1,3 +1,3 @@ Enter a date in 2024: - + \ No newline at end of file diff --git a/audit-output/normalized/webforms/RangeValidator/RangeValidator-3.html b/audit-output/normalized/webforms/RangeValidator/RangeValidator-3.html index adc9d54c0..292f67415 100644 --- a/audit-output/normalized/webforms/RangeValidator/RangeValidator-3.html +++ b/audit-output/normalized/webforms/RangeValidator/RangeValidator-3.html @@ -1,3 +1,3 @@ Enter a price ($1.00 - $999.99): - + \ No newline at end of file diff --git a/audit-output/normalized/webforms/RangeValidator/RangeValidator-Submit.html b/audit-output/normalized/webforms/RangeValidator/RangeValidator-Submit.html index 67e9832c6..83c86efc9 100644 --- a/audit-output/normalized/webforms/RangeValidator/RangeValidator-Submit.html +++ b/audit-output/normalized/webforms/RangeValidator/RangeValidator-Submit.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/RegularExpressionValidator/RegularExpressionValidator-1.html b/audit-output/normalized/webforms/RegularExpressionValidator/RegularExpressionValidator-1.html index 3f816409e..91da39323 100644 --- a/audit-output/normalized/webforms/RegularExpressionValidator/RegularExpressionValidator-1.html +++ b/audit-output/normalized/webforms/RegularExpressionValidator/RegularExpressionValidator-1.html @@ -1,3 +1,3 @@ Email: - + \ No newline at end of file diff --git a/audit-output/normalized/webforms/RegularExpressionValidator/RegularExpressionValidator-2.html b/audit-output/normalized/webforms/RegularExpressionValidator/RegularExpressionValidator-2.html index ee07a3912..0580fb4c5 100644 --- a/audit-output/normalized/webforms/RegularExpressionValidator/RegularExpressionValidator-2.html +++ b/audit-output/normalized/webforms/RegularExpressionValidator/RegularExpressionValidator-2.html @@ -1,3 +1,3 @@ Phone (xxx-xxx-xxxx): - + \ No newline at end of file diff --git a/audit-output/normalized/webforms/RegularExpressionValidator/RegularExpressionValidator-3.html b/audit-output/normalized/webforms/RegularExpressionValidator/RegularExpressionValidator-3.html index 3a43ac55a..5116606d6 100644 --- a/audit-output/normalized/webforms/RegularExpressionValidator/RegularExpressionValidator-3.html +++ b/audit-output/normalized/webforms/RegularExpressionValidator/RegularExpressionValidator-3.html @@ -1,3 +1,3 @@ Zip Code: - + \ No newline at end of file diff --git a/audit-output/normalized/webforms/RegularExpressionValidator/RegularExpressionValidator-Submit.html b/audit-output/normalized/webforms/RegularExpressionValidator/RegularExpressionValidator-Submit.html index 67e9832c6..83c86efc9 100644 --- a/audit-output/normalized/webforms/RegularExpressionValidator/RegularExpressionValidator-Submit.html +++ b/audit-output/normalized/webforms/RegularExpressionValidator/RegularExpressionValidator-Submit.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/RequiredFieldValidator/RequiredFieldValidator-1.html b/audit-output/normalized/webforms/RequiredFieldValidator/RequiredFieldValidator-1.html index a8fba7f5f..6d63177f7 100644 --- a/audit-output/normalized/webforms/RequiredFieldValidator/RequiredFieldValidator-1.html +++ b/audit-output/normalized/webforms/RequiredFieldValidator/RequiredFieldValidator-1.html @@ -1,2 +1,2 @@ - + \ No newline at end of file diff --git a/audit-output/normalized/webforms/RequiredFieldValidator/RequiredFieldValidator-2.html b/audit-output/normalized/webforms/RequiredFieldValidator/RequiredFieldValidator-2.html index 2a820a67e..fb78c984c 100644 --- a/audit-output/normalized/webforms/RequiredFieldValidator/RequiredFieldValidator-2.html +++ b/audit-output/normalized/webforms/RequiredFieldValidator/RequiredFieldValidator-2.html @@ -1,2 +1,2 @@ - + \ No newline at end of file diff --git a/audit-output/normalized/webforms/RequiredFieldValidator/RequiredFieldValidator-3.html b/audit-output/normalized/webforms/RequiredFieldValidator/RequiredFieldValidator-3.html index 4fb4e11f2..e8ee9251e 100644 --- a/audit-output/normalized/webforms/RequiredFieldValidator/RequiredFieldValidator-3.html +++ b/audit-output/normalized/webforms/RequiredFieldValidator/RequiredFieldValidator-3.html @@ -1,2 +1,2 @@ - + \ No newline at end of file diff --git a/audit-output/normalized/webforms/RequiredFieldValidator/RequiredFieldValidator-Submit.html b/audit-output/normalized/webforms/RequiredFieldValidator/RequiredFieldValidator-Submit.html index 67e9832c6..83c86efc9 100644 --- a/audit-output/normalized/webforms/RequiredFieldValidator/RequiredFieldValidator-Submit.html +++ b/audit-output/normalized/webforms/RequiredFieldValidator/RequiredFieldValidator-Submit.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/TextBox/TextBox-1.html b/audit-output/normalized/webforms/TextBox/TextBox-1.html index daa9a09ba..63ac75c15 100644 --- a/audit-output/normalized/webforms/TextBox/TextBox-1.html +++ b/audit-output/normalized/webforms/TextBox/TextBox-1.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/TextBox/TextBox-2.html b/audit-output/normalized/webforms/TextBox/TextBox-2.html index 42853b238..3f9826b24 100644 --- a/audit-output/normalized/webforms/TextBox/TextBox-2.html +++ b/audit-output/normalized/webforms/TextBox/TextBox-2.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/TextBox/TextBox-3.html b/audit-output/normalized/webforms/TextBox/TextBox-3.html index a042da3cc..14181ec77 100644 --- a/audit-output/normalized/webforms/TextBox/TextBox-3.html +++ b/audit-output/normalized/webforms/TextBox/TextBox-3.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/TextBox/TextBox-4.html b/audit-output/normalized/webforms/TextBox/TextBox-4.html index 6535ae8a2..0f6a07d52 100644 --- a/audit-output/normalized/webforms/TextBox/TextBox-4.html +++ b/audit-output/normalized/webforms/TextBox/TextBox-4.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/TextBox/TextBox-5.html b/audit-output/normalized/webforms/TextBox/TextBox-5.html index f4f8a01cd..00d07d8c3 100644 --- a/audit-output/normalized/webforms/TextBox/TextBox-5.html +++ b/audit-output/normalized/webforms/TextBox/TextBox-5.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/TextBox/TextBox-6.html b/audit-output/normalized/webforms/TextBox/TextBox-6.html index 07c752fde..4c8b08ea1 100644 --- a/audit-output/normalized/webforms/TextBox/TextBox-6.html +++ b/audit-output/normalized/webforms/TextBox/TextBox-6.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/audit-output/normalized/webforms/TreeView/TreeView.html b/audit-output/normalized/webforms/TreeView/TreeView.html index cc72630e4..9dfd0b813 100644 --- a/audit-output/normalized/webforms/TreeView/TreeView.html +++ b/audit-output/normalized/webforms/TreeView/TreeView.html @@ -1,22 +1,22 @@ Skip Navigation Links.
    - +
    This is the home image tooltipHomeThis is the home image tooltipHome
    diff --git a/audit-output/normalized/webforms/ValidationSummary/ValidationSummary-Submit.html b/audit-output/normalized/webforms/ValidationSummary/ValidationSummary-Submit.html index bb4f27608..529abfc67 100644 --- a/audit-output/normalized/webforms/ValidationSummary/ValidationSummary-Submit.html +++ b/audit-output/normalized/webforms/ValidationSummary/ValidationSummary-Submit.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/DataControls/DataGrid.md b/docs/DataControls/DataGrid.md index a6908c826..04a01ae06 100644 --- a/docs/DataControls/DataGrid.md +++ b/docs/DataControls/DataGrid.md @@ -165,8 +165,6 @@ The following DataGrid features from Web Forms are not currently supported: ## Blazor Syntax -Currently, not every syntax element of Web Forms DataGrid is supported. In the meantime, the following DataGrid in Blazor syntax will only include the implemented ones. **Custom paging and footer templates will be included later**. - ```html ` instead of ``, improv DataKeyField="CustomerID" SelectMethod="GetCustomers" PageIndexChanged="HandlePageChanged"> + @code { @@ -391,7 +390,19 @@ When `true`, header cells render as `` instead of ``, improv } ``` -When `AllowPaging="true"` and `PageSize` is set, the DataGrid automatically renders a numeric pager row. The pager displays page numbers and highlights the current page. Clicking a page number fires `PageIndexChanged` and navigates to that page. +When `AllowPaging="true"` and `PageSize` is set, the DataGrid automatically renders a numeric pager row in the table footer. The pager displays page numbers — the current page as plain text, others as clickable links. Clicking a page number fires `PageIndexChanged` and navigates to that page. + +!!! note "DataGrid Paging vs. GridView/FormView/DetailsView Paging" + DataGrid uses a **built-in numeric pager** and does not support the `` sub-component that GridView, FormView, and DetailsView use. If you need configurable pager modes (NextPrevious, NumericFirstLast, etc.), consider migrating to [GridView](GridView.md) which offers full [PagerSettings](PagerSettings.md) support. + +| Property | Type | Default | Description | +|----------|------|---------|-------------| +| `AllowPaging` | `bool` | `false` | Enables or disables paging | +| `PageSize` | `int` | `10` | Number of items displayed per page | +| `CurrentPageIndex` | `int` | `0` | The zero-based index of the current page | +| `PageIndexChanged` | `EventCallback` | — | Fires when the page changes | + +The `PagerStyle` sub-component controls the visual appearance of the pager row. ### DataGrid with Sorting @@ -443,3 +454,4 @@ When migrating DataGrid from Web Forms to Blazor: - [GridView](GridView.md) - The recommended data grid control for new projects - [DataList](DataList.md) - For custom layout of repeating data - [Repeater](Repeater.md) - For lightweight data repetition +- [PagerSettings](PagerSettings.md) - Shared pager configuration (used by GridView, FormView, DetailsView) diff --git a/docs/DataControls/DetailsView.md b/docs/DataControls/DetailsView.md index e9d9f1ccb..2c071d25e 100644 --- a/docs/DataControls/DetailsView.md +++ b/docs/DataControls/DetailsView.md @@ -53,6 +53,8 @@ Original Microsoft documentation: https://docs.microsoft.com/en-us/dotnet/api/sy AutoGenerateEditButton="True|False" AutoGenerateInsertButton="True|False" AutoGenerateRows="True|False" + Caption="string" + CaptionAlign="NotSet|Top|Bottom|Left|Right" CellPadding="integer" CellSpacing="integer" CssClass="string" @@ -79,6 +81,26 @@ Original Microsoft documentation: https://docs.microsoft.com/en-us/dotnet/api/sy Visible="True|False" runat="server" > + + + + + + + + + + + diff --git a/docs/DataControls/FormView.md b/docs/DataControls/FormView.md index 4d108298a..3817a1982 100644 --- a/docs/DataControls/FormView.md +++ b/docs/DataControls/FormView.md @@ -6,7 +6,10 @@ The FormView component is meant to emulate the asp:FormView control in markup an - Numerical Pager - OnDataBinding and OnDataBound events trigger - ModeChanging and ModeChanged events - - Insert, Edit, Update, Delete actions and supporting events + - Insert, Edit, Update, Delete actions and supporting events: + - **OnItemDeleting** / **OnItemDeleted** — before and after delete operations + - **OnItemInserting** / **OnItemInserted** — before and after insert operations + - **OnItemUpdating** / **OnItemUpdated** — before and after update operations - **ItemCommand** event — fires when any command button within the FormView is clicked - **ItemCreated** event — fires when the FormView is first created and data-bound - **PageIndexChanging** / **PageIndexChanged** events — fires when paging occurs (cancellable) @@ -18,6 +21,13 @@ The FormView component is meant to emulate the asp:FormView control in markup an - **Style sub-components** (RowStyle, EditRowStyle, InsertRowStyle, HeaderStyle, FooterStyle, EmptyDataRowStyle, PagerStyle) - **[PagerSettings](PagerSettings.md)** — configurable pager button modes, text, images, and position +## Web Forms Features NOT Supported + +- **DataSourceID** — Blazor does not use server-side data source controls; bind data directly via `DataSource` +- **ViewState / EnableViewState** — Not needed; Blazor preserves component state natively +- **Theming / SkinID / EnableTheming** — Not applicable to Blazor +- **RenderTable** — Not implemented; the FormView always renders a table + ## Usage Notes - **ItemType attribute** - Required to specify the type of items in the collection @@ -390,6 +400,47 @@ Each style component accepts standard style properties: `BackColor`, `ForeColor` ``` +### CRUD Event Handling + +```razor + + +

    @Item.Name — @Item.Email

    +
    + +

    Editing: @Item.Name

    +
    +
    + +@code { + private List Customers = new(); + + private void HandleUpdating(FormViewUpdateEventArgs e) + { + // Validate and apply changes; set e.Cancel = true to abort + } + + private void HandleUpdated(FormViewUpdatedEventArgs e) + { + // Post-update logic (e.g., refresh data, show notification) + } + + private void HandleDeleting(FormViewDeleteEventArgs e) + { + // Perform delete; e.RowIndex gives the current position + } + + private void HandleCommand(FormViewCommandEventArgs e) + { + // Fires for any command button — check e.CommandName + } +} +``` + ## See Also - [GridView](GridView.md) - For tabular data display diff --git a/planning-docs/DIVERGENCE-REGISTRY.md b/planning-docs/DIVERGENCE-REGISTRY.md index 45141e36b..f73cb13d5 100644 --- a/planning-docs/DIVERGENCE-REGISTRY.md +++ b/planning-docs/DIVERGENCE-REGISTRY.md @@ -2,7 +2,7 @@ **Created:** 2026-02-26 **Author:** Forge (Lead / Web Forms Reviewer) -**Status:** Initial — will be updated incrementally through M11–M13 +**Status:** Updated through M18 — 14 entries (D-01 through D-14) **Milestone:** M11-02 --- @@ -31,6 +31,10 @@ This document catalogs every **known intentional difference** between HTML rende | D-08 | Calendar Day Selection | JS Interop | Calendar | None | High | | D-09 | Login Control Infrastructure | Infrastructure | Login, LoginName, LoginStatus, LoginView, ChangePassword, CreateUserWizard, PasswordRecovery | None | Low | | D-10 | Validator Client-Side Scripts | JS Interop | RequiredFieldValidator, CompareValidator, RangeValidator, RegularExpressionValidator, CustomValidator, ValidationSummary | None | High | +| D-11 | GUID-Based IDs | ID Generation | CheckBox, RadioButton, RadioButtonList, FileUpload | Medium | Medium | +| D-12 | Boolean Attribute Format | Attribute Format | DropDownList, ListBox, CheckBoxList, RadioButtonList | None | None | +| D-13 | Calendar Previous-Month Day Padding | Structural | Calendar | Low | None | +| D-14 | Calendar Style Property Pass-Through | Style | Calendar | Medium | None | --- @@ -186,6 +190,74 @@ This document catalogs every **known intentional difference** between HTML rende --- +### D-11: GUID-Based IDs + +| Field | Value | +|-------|-------| +| **Control** | CheckBox, RadioButton, RadioButtonList, FileUpload | +| **Divergence** | Web Forms generates predictable IDs from the control naming hierarchy (e.g., `MainContent_CheckBox1`, `MainContent_RadioButtonList1_0`, `MainContent_RadioButtonList1_1`). Blazor generates GUID-based IDs for some controls (e.g., `5f017a2765e3...`), making the HTML non-deterministic across renders. | +| **Category** | ID Generation | +| **Reason** | This is a **separate concern from D-01** (which covers `ctl00_` prefix mangling). D-01 addresses the naming-container prefix — a structural difference that is always intentional. D-11 addresses the fact that certain Blazor controls use `Guid.NewGuid()` to generate internal IDs for linking `` and `