Skip to content

Align component property defaults with the web components, unit & integration checks - #292

Merged
damyanpetev merged 2 commits into
masterfrom
dpetev/align-defaults
Aug 6, 2026
Merged

Align component property defaults with the web components, unit & integration checks#292
damyanpetev merged 2 commits into
masterfrom
dpetev/align-defaults

Conversation

@damyanpetev

Copy link
Copy Markdown
Member

Discovered in #286

The backing fields for 27 wrapper properties were initialized to the C# type default — 0, false, or the first enum member — instead of the default the underlying web component actually starts with. Reading such a property before assigning it reported a value the component never used: Tooltip.ShowDelay returned 0 while the tooltip actually waited 200ms, and Tooltip.Placement returned Top while the popover opened at the bottom.

Why it matters

Rendering was never wrong. A property is serialized only when it has been marked dirty, and _isDirty is set exclusively by MarkPropDirty/OnRefChanged with no bulk-serialize path, so an unassigned property is never sent to the client and the component keeps applying its own default.

The problem is on the read side. The getter returns the backing field, so any code that inspects a property it has not set — a conditional, a computed value, a variable bound to it — sees a number or enum member that does not describe the rendered component. None of these properties expose a Get<Prop>()/Get<Prop>Async() accessor either, so there was no way to obtain the effective value from .NET.

The enum cases are the most likely to cause real trouble: Placement on IgbDropdown, IgbSelect and IgbTooltip, and Theme on IgbThemeProvider.

Changes

Property Was Now (upstream default)
BaseAlertLike.DisplayTime 0 4000
Calendar.VisibleMonths 0 1
DateRangePicker.VisibleMonths 0 2
Carousel.MaximumIndicatorsCount 0 10
CircularGradient.Opacity 0 1
DatePicker.VisibleMonths 0 1
DateTimeInputBase.SpinLoop false true
Dropdown.Placement Top BottomStart
ProgressBase.Max 0 100
ProgressBase.AnimationDuration 0 500
RadioGroup.Alignment Horizontal Vertical
Rating.Max 0 5
Rating.Step 0 1
Select.Placement Top BottomStart
SliderBase.Max 0 100
SliderBase.Step 0 1
Stepper.AnimationDuration 0 320
Textarea.Rows 0 3
Textarea.Spellcheck false true
ThemeProvider.Theme Material Bootstrap
Tile.ColSpan 0 1
Tile.RowSpan 0 1
Tile.Position 0 -1
Tooltip.Offset 0 6
Tooltip.Placement Top Bottom
Tooltip.ShowDelay 0 200
Tooltip.HideDelay 0 300

One line per property; no other production code touched.

Most defaults were taken from custom-elements.json, with the enum ones resolved through each member's [WCEnumName] attribute rather than by name — that is what maps bottom-start to BottomStart. It also shows SliderTickLabelRotation.Zero is not a mismatch despite looking like one: its [WCEnumName("0")] already equals upstream's 0, so it is left as is.

The last four — DateRangePicker.VisibleMonths, SliderBase.Max, SliderBase.Step and Tile.Position — are not in the manifest at all. Upstream implements those members as accessors rather than plain fields, so the metadata records no default and only the running component knows the value (_visibleMonths = 2, _max = 100, _step = 1, _position = -1). They were found by the integration check described below, which is the argument for having it.

Deliberately not changed

Slider/RangeSlider UpperBound also reports 100 on the client, but it is derived rather than stored:

public get upperBound(): number {
  const current = this._upperBound ?? this._max;
  return clamp(current, lower, this._max);
}

Pinning the wrapper to 100 would be wrong the moment Max is set to anything else. It and LowerBound (derived from min the same way, and equal only by coincidence today) are listed in ExcludedDefaultProps instead, with the reason recorded in the config.

Test coverage

Both directions are now pinned, so this cannot silently regress:

  • Unit — each affected component's existing test file gains a ..._DefaultValues_MatchWebComponent check. ThemeProviderTests already had one, written and skipped with the note "Default should be Bootstrap"; it is un-skipped here.
  • IntegrationTestPropDefaults in the TestBed runs before any property is assigned and compares every comparable property against the value the real component starts with. It is the reverse of the existing TestProps sweep, which only proves that values written from .NET reach the client, and is what surfaced the four accessor-backed defaults. Scoped to booleans, numbers and enums, since strings, objects and dates are left null by the wrapper while the client reports '' or undefined.

Behavior after the change

  • An unassigned property still serializes nothing, so the component's own default continues to apply — unchanged.
  • Assigning the old C# default still transmits: ShowDelay = 0 marks the property dirty because 200 != 0.
  • Assigning the new default also transmits, via the !IsPropDirty arm of the setter.
  • The getter now reports what the component actually uses.

Verification

dotnet build clean; unit suite 902 passed, 0 failed; integration suite 71 passed, 0 failed. The pre-existing assertions on these properties all follow an explicit assignment, so none depended on the old initial values.

Both checks were confirmed to actually fail on a regression: reverting Tooltip.ShowDelay to 0 fails the unit check, and the integration sweep reports it as "Default value mismatch before setting. Prop name: ShowDelay. The wrapper reports:0, but the client component starts with: 200".

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request aligns Ignite UI for Blazor wrapper property backing-field initializers with the actual default values used by the underlying Ignite UI Web Components, so reading an unassigned [Parameter] reflects the rendered component’s effective default. It also adds unit and integration checks to prevent future drift between wrapper defaults and web component defaults.

Changes:

  • Updated backing-field initializers for 27 wrapper properties so getters report upstream defaults instead of C# type defaults.
  • Added per-component unit tests asserting wrapper default values match the web component defaults.
  • Added an integration “default values” sweep in the Lite TestBed (with per-component exclusions for derived client-side defaults).

Reviewed changes

Copilot reviewed 43 out of 43 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/IgniteUI.Blazor.Tests/TooltipTests.cs Adds a unit test asserting IgbTooltip default values match the web component.
tests/IgniteUI.Blazor.Tests/ToastTests.cs Adds a unit test asserting IgbToast.DisplayTime default matches the web component.
tests/IgniteUI.Blazor.Tests/TileManagerTests.cs Adds a unit test asserting IgbTile default values match the web component.
tests/IgniteUI.Blazor.Tests/ThemeProviderTests.cs Unskips/updates the default-values test to validate Bootstrap as the default theme.
tests/IgniteUI.Blazor.Tests/TextareaTests.cs Adds a unit test asserting IgbTextarea defaults (rows/spellcheck) match the web component.
tests/IgniteUI.Blazor.Tests/StepperTests.cs Adds a unit test asserting IgbStepper.AnimationDuration default matches the web component.
tests/IgniteUI.Blazor.Tests/SnackbarTests.cs Adds a unit test asserting IgbSnackbar.DisplayTime default matches the web component.
tests/IgniteUI.Blazor.Tests/SliderTests.cs Adds a unit test asserting IgbSlider defaults (max/step) match the web component.
tests/IgniteUI.Blazor.Tests/SelectTests.cs Adds a unit test asserting IgbSelect.Placement default matches the web component.
tests/IgniteUI.Blazor.Tests/RatingTests.cs Adds a unit test asserting IgbRating defaults (max/step) match the web component.
tests/IgniteUI.Blazor.Tests/RangeSliderTests.cs Adds a unit test asserting IgbRangeSlider defaults (max/step) match the web component.
tests/IgniteUI.Blazor.Tests/RadioTests.cs Adds a unit test asserting IgbRadioGroup.Alignment default matches the web component.
tests/IgniteUI.Blazor.Tests/LinearProgressTests.cs Adds a unit test asserting IgbLinearProgress defaults (max/animation duration) match the web component.
tests/IgniteUI.Blazor.Tests/DropdownTests.cs Adds a unit test asserting IgbDropdown.Placement default matches the web component.
tests/IgniteUI.Blazor.Tests/DateTimeInputTests.cs Adds a unit test asserting IgbDateTimeInput.SpinLoop default matches the web component.
tests/IgniteUI.Blazor.Tests/DateRangePickerTests.cs Adds a unit test asserting IgbDateRangePicker.VisibleMonths default matches the web component.
tests/IgniteUI.Blazor.Tests/DatePickerTests.cs Adds a unit test asserting IgbDatePicker.VisibleMonths default matches the web component.
tests/IgniteUI.Blazor.Tests/CircularProgressTests.cs Adds a unit test asserting IgbCircularProgress defaults (max/animation duration) match the web component.
tests/IgniteUI.Blazor.Tests/CircularGradientTests.cs Adds a unit test asserting IgbCircularGradient.Opacity default matches the web component.
tests/IgniteUI.Blazor.Tests/CarouselTests.cs Adds a unit test asserting IgbCarousel.MaximumIndicatorsCount default matches the web component.
tests/IgniteUI.Blazor.Tests/CalendarTests.cs Adds a unit test asserting IgbCalendar.VisibleMonths default matches the web component.
tests/IgniteUI.Blazor.Lite.TestBed/componentsConfig.json Adds ExcludedDefaultProps entries to exclude derived client-side defaults (UpperBound/LowerBound) from default comparison.
tests/IgniteUI.Blazor.Lite.TestBed/Components/Pages/Home.razor Adds a TestPropDefaults integration sweep and wires per-component excluded-default configuration.
tests/IgniteUI.Blazor.Lite.TestBed/Components/Common/TestUtil.cs Adds HasComparableDefault helper to scope default comparisons to comparable primitive/enum types.
tests/IgniteUI.Blazor.Lite.TestBed/Components/Common/ReflectionUtils.cs Adds excludedDefaultProps storage used by the integration default-values sweep.
src/components/Blazor/Tooltip.cs Updates tooltip defaults (Offset, Placement, ShowDelay, HideDelay) to match web component behavior.
src/components/Blazor/Tile.cs Updates tile defaults (ColSpan, RowSpan, Position) to match web component behavior.
src/components/Blazor/ThemeProvider.cs Updates theme provider default theme to Bootstrap.
src/components/Blazor/Textarea.cs Updates textarea defaults (Rows, Spellcheck) to match web component behavior.
src/components/Blazor/Stepper.cs Updates stepper default AnimationDuration to match web component behavior.
src/components/Blazor/SliderBase.cs Updates slider base defaults (Max, Step) to match web component behavior.
src/components/Blazor/Select.cs Updates select default Placement to match web component behavior.
src/components/Blazor/Rating.cs Updates rating defaults (Max, Step) to match web component behavior.
src/components/Blazor/RadioGroup.cs Updates radio group default Alignment to match web component behavior.
src/components/Blazor/ProgressBase.cs Updates progress defaults (Max, AnimationDuration) to match web component behavior.
src/components/Blazor/Dropdown.cs Updates dropdown default Placement to match web component behavior.
src/components/Blazor/DateTimeInputBase.cs Updates date-time input base default SpinLoop to match web component behavior.
src/components/Blazor/DateRangePicker.cs Updates date range picker default VisibleMonths to match web component behavior.
src/components/Blazor/DatePicker.cs Updates date picker default VisibleMonths to match web component behavior.
src/components/Blazor/CircularGradient.cs Updates circular gradient default Opacity to match web component behavior.
src/components/Blazor/Carousel.cs Updates carousel default MaximumIndicatorsCount to match web component behavior.
src/components/Blazor/Calendar.cs Updates calendar default VisibleMonths to match web component behavior.
src/components/Blazor/BaseAlertLike.cs Updates alert-like default DisplayTime to match web component behavior.

@dkamburov
dkamburov requested a review from MayaKirova August 5, 2026 07:54
@damyanpetev
damyanpetev disabled auto-merge August 6, 2026 07:10
@damyanpetev
damyanpetev merged commit f26c09c into master Aug 6, 2026
8 of 10 checks passed
@damyanpetev
damyanpetev deleted the dpetev/align-defaults branch August 6, 2026 07:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐛 bug Something isn't working e2e 🧪 ci: tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants