Skip to content

feat(lib): Enable Nullable analysis and fix warnings - #365

Open
MayaKirova wants to merge 72 commits into
masterfrom
mkirova/nullable
Open

feat(lib): Enable Nullable analysis and fix warnings#365
MayaKirova wants to merge 72 commits into
masterfrom
mkirova/nullable

Conversation

@MayaKirova

@MayaKirova MayaKirova commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Description

Enable nullable analysis repository-wide and fix all warnings that emerged from it.

This change also preserves nullable items in observable data sources. Null insertions, removals, and replacements now propagate through both the JSON and unmarshalled data channels.

The nullable cleanup includes 16 binary-breaking public signature changes documented in CHANGELOG.md. This PR therefore requires a major-version release.

Type of Change (check all that apply):

  • Bug fix
  • New functionality
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactoring
  • Documentation
  • Demos
  • CI/CD
  • Tests
  • Changelog

Component(s) / Area(s) Affected:

All components and shared data-source infrastructure.

How Has This Been Tested?

  • Unit tests
  • Manual testing
  • Automated e2e tests

Unit coverage includes nullable collection insert, remove, and replacement transitions before and after schema inference on both data transport channels.

Checklist:

  • All relevant tags have been applied to this PR
  • This PR includes unit tests covering all the new code
  • This PR includes API docs for newly added methods/properties
  • This PR includes general feature table updates in the root README.MD
  • This PR includes CHANGELOG.MD updates for newly added functionality
  • This PR contains breaking changes
  • This PR includes behavioral changes and the feature specification has been updated with them
  • Accessibility (ARIA, keyboard navigation, focus management) has been verified

Closes #347

Copilot AI lite review requested due to automatic review settings August 25, 2026 12:56
Comment thread src/componentsBase/UnmarshalledDataSource.cs Fixed
Comment thread src/componentsBase/BaseRendererControl.cs Fixed
Comment thread src/componentsBase/BaseRendererControl.cs Fixed

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

Enables C# nullable reference type analysis across the Ignite UI for Blazor codebase (including the Lite project) and updates library code, stories, and tests to address the resulting warnings—primarily by adding nullable annotations, null guards, and safer event JSON decoding.

Changes:

  • Enabled <Nullable>enable</Nullable> for IgniteUI.Blazor.Lite and applied nullable annotations across the library.
  • Updated event args / JSON (de)serialization paths to tolerate null dictionaries and nullable payload members.
  • Updated unit tests and stories to compile under nullable analysis (mostly via ! null-forgiving in assertions/handlers).

Reviewed changes

Copilot reviewed 158 out of 181 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/IgniteUI.Blazor.Tests/TreeTests.cs Update test asserts for nullable event args/results
tests/IgniteUI.Blazor.Tests/TileManagerTests.cs Update test asserts for nullable event args/results
tests/IgniteUI.Blazor.Tests/TabsTests.cs Update test asserts for nullable event args
tests/IgniteUI.Blazor.Tests/SwitchTests.cs Update test asserts for nullable event args
tests/IgniteUI.Blazor.Tests/StepperTests.cs Update test asserts for nullable event args/results
tests/IgniteUI.Blazor.Tests/SplitterTests.cs Update test asserts for nullable event args
tests/IgniteUI.Blazor.Tests/SelectTests.cs Update test asserts for nullable event args/results
tests/IgniteUI.Blazor.Tests/RangeSliderTests.cs Update test asserts for nullable event args
tests/IgniteUI.Blazor.Tests/RadioTests.cs Update test asserts for nullable event args
tests/IgniteUI.Blazor.Tests/DropdownTests.cs Update test asserts for nullable results
tests/IgniteUI.Blazor.Tests/DateRangePickerTests.cs Update test asserts for nullable event args
tests/IgniteUI.Blazor.Tests/ComboTests.cs Update test asserts for nullable event args/results
tests/IgniteUI.Blazor.Tests/CheckboxTests.cs Update test asserts for nullable event args
tests/IgniteUI.Blazor.Tests/ChatTests.cs Update test asserts for nullable event args
tests/IgniteUI.Blazor.Tests/CalendarTests.cs Update test asserts/casts for nullable event payload
tests/IgniteUI.Blazor.Lite.TestBed/Components/Common/TestUtil.cs Nullability adjustments for date range comparison
stories/Components/Stories/Chat.stories.razor Update story event handlers for nullable message payloads
src/IgniteUI.Blazor.Lite.csproj Enable nullable analysis for Lite project
src/componentsBase/WebViewCallback.cs Nullability adjustments in JS-invokable callbacks/batch handling
src/componentsBase/WebInputs/TreeItem.cs CascadingParameter made nullable
src/componentsBase/WebInputs/Tree.cs Nullable backing field for content items
src/componentsBase/WebInputs/TileManager.cs Nullable backing field for content items
src/componentsBase/WebInputs/Tile.cs CascadingParameter made nullable
src/componentsBase/WebInputs/SelectItem.cs CascadingParameter made nullable
src/componentsBase/WebInputs/Select.cs Nullable backing field for content items
src/componentsBase/WebInputs/Rating.cs Injected logger nullability + parameter coercion nullability
src/componentsBase/WebInputs/Input.cs Injected logger nullability + parameter coercion nullability
src/componentsBase/WebInputs/DropdownItem.cs CascadingParameter made nullable
src/componentsBase/WebInputs/Dropdown.cs Nullable args arrays + nullable backing field for content items
src/componentsBase/WebInputs/DateTimeInput.cs Nullable args arrays passed into interop invocations
src/componentsBase/WebInputs/Chat.cs Nullable args arrays passed into interop invocations
src/componentsBase/WebInputs/Accordion.cs Nullable backing fields + nullable CascadingParameter
src/componentsBase/Utils.cs Update signature for nullable enum member name/out name
src/componentsBase/RuntimeHelper.cs Make runtime/delegates nullable and adjust unmarshalled call plumbing
src/componentsBase/RendererMessage.cs Make payload dictionary values nullable
src/componentsBase/RefSink.cs Ref sink interface updated for nullable ref values/items
src/componentsBase/MarshalByValueFactory.cs Allow nullable typeName / nullable CreateInstance result
src/componentsBase/JsonSerializable.cs Nullability updates for serialization delegate/context/interface
src/componentsBase/IgbTemplateContent.razor Template/context parameters updated for nullable analysis
src/componentsBase/IgbComponentRendererContainer.cs Make component type/root component nullable + nullable event
src/componentsBase/EventCallbackExtensions.cs Reflection field handles made nullable + guarded access
src/componentsBase/DataAdapters.cs Make adapter backing fields/properties nullable for analysis
src/componentsBase/CollectionAdapter.cs Make internal fields nullable + add null-forgiving where needed
src/components/Blazor/VoidEventArgs.cs Nullable event JSON args dictionary types
src/components/Blazor/TreeSelectionEventArgsDetail.cs Nullable selection array + nullable event args dictionaries
src/components/Blazor/TreeSelectionEventArgs.cs Nullable detail + nullable event args dictionaries
src/components/Blazor/TreeItemComponentEventArgs.cs Nullable detail + nullable event args dictionaries
src/components/Blazor/TreeItem.cs Nullable parameters/returns + nullable args arrays for interop calls
src/components/Blazor/ToggleButton.cs Nullable parameters + nullable args arrays for interop calls
src/components/Blazor/TileComponentEventArgs.cs Nullable detail + nullable event args dictionaries
src/components/Blazor/TileChangeStateEventArgsDetail.cs Nullable tile + nullable event args dictionaries
src/components/Blazor/TileChangeStateEventArgs.cs Nullable detail + nullable event args dictionaries
src/components/Blazor/ThemeProvider.cs Nullable args arrays for interop calls
src/components/Blazor/Tabs.cs Nullable backing fields/return + nullable args arrays for interop calls
src/components/Blazor/TabComponentEventArgs.cs Nullable detail + nullable event args dictionaries
src/components/Blazor/Tab.cs Nullable cascading parent + nullable label + nullable args arrays
src/components/Blazor/Step.cs Nullable args arrays for interop calls
src/components/Blazor/SplitterResizeEventArgsDetail.cs Nullable event args dictionaries + null checks
src/components/Blazor/SplitterResizeEventArgs.cs Nullable detail + nullable event args dictionaries
src/components/Blazor/Splitter.cs Nullable args arrays + nullable script refs + nullable callback arg types
src/components/Blazor/Snackbar.cs Nullable parameters + nullable script refs + nullable callback arg types
src/components/Blazor/SliderLabel.cs Nullable args arrays for interop calls
src/components/Blazor/SliderBase.cs Nullable parameters/options + nullable args arrays + null-forgiving cast
src/components/Blazor/SelectItemComponentEventArgs.cs Nullable detail + nullable event args dictionaries
src/components/Blazor/SelectHeader.cs Nullable args arrays for interop calls
src/components/Blazor/SelectGroup.cs Nullable items array + nullable args arrays for interop calls
src/components/Blazor/Ripple.cs Nullable args arrays for interop calls
src/components/Blazor/RatingSymbol.cs Nullable args arrays for interop calls
src/components/Blazor/RangeSliderValueEventArgs.cs Nullable detail + nullable event args dictionaries
src/components/Blazor/RangeSliderValue.cs Nullable event args dictionaries + null checks
src/components/Blazor/RangeSlider.cs Nullable aria labels + nullable script refs + nullable callback arg types
src/components/Blazor/RadioGroup.cs Nullable value/returns + nullable args arrays + nullable script refs
src/components/Blazor/RadioChangeEventArgsDetail.cs Nullable value + nullable event args dictionaries
src/components/Blazor/RadioChangeEventArgs.cs Nullable detail + nullable event args dictionaries
src/components/Blazor/ProgressBase.cs Nullable label format + nullable args arrays
src/components/Blazor/NumberEventArgs.cs Nullable event args dictionaries + null checks
src/components/Blazor/NavDrawerItem.cs Nullable args arrays for interop calls
src/components/Blazor/NavDrawerHeaderItem.cs Nullable args arrays for interop calls
src/components/Blazor/Navbar.cs Nullable args arrays for interop calls
src/components/Blazor/MaskInput.cs Nullable parameters/returns + nullable args arrays + nullable script refs
src/components/Blazor/ListItem.cs Nullable args arrays for interop calls
src/components/Blazor/ListHeader.cs Nullable args arrays for interop calls
src/components/Blazor/List.cs Nullable args arrays for interop calls
src/components/Blazor/Input.cs Nullable parameters/returns + nullable args arrays + nullable script refs
src/components/Blazor/IconMeta.cs Nullable collection + nullable event args dictionaries + fallback name
src/components/Blazor/IconButton.cs Nullable parameters + doc/comment + nullable args arrays for interop calls
src/components/Blazor/Icon.cs Nullable parameters + nullable args arrays for interop calls
src/components/Blazor/HighlightNavigation.cs Nullable event args dictionaries + null checks
src/components/Blazor/Highlight.cs Nullable SearchText + nullable args arrays for interop calls
src/components/Blazor/FormatSpecifier.cs Nullable return values + nullable event args dictionaries
src/components/Blazor/FilteringOptions.cs Nullable filter key
src/components/Blazor/ExpansionPanelComponentEventArgs.cs Nullable detail + nullable event args dictionaries
src/components/Blazor/DropdownItemComponentEventArgs.cs Nullable detail + nullable event args dictionaries
src/components/Blazor/DropdownHeader.cs Nullable args arrays for interop calls
src/components/Blazor/DropdownGroup.cs Nullable args arrays for interop calls
src/components/Blazor/Divider.cs Nullable args arrays for interop calls
src/components/Blazor/Dialog.cs Nullable parameters/refs + nullable args arrays for interop calls
src/components/Blazor/DateRangeValueEventArgs.cs Nullable detail + nullable event args dictionaries
src/components/Blazor/DateRangeValueDetail.cs Nullable event args dictionaries + null checks
src/components/Blazor/DateRangeDescriptor.cs Nullable date range value
src/components/Blazor/CustomDateRange.cs Nullable label/date range
src/components/Blazor/ComponentValueChangedEventArgs.cs Nullable detail + nullable event args dictionaries
src/components/Blazor/ComponentDateValueChangedEventArgs.cs Nullable event args dictionaries + null checks
src/components/Blazor/ComponentDataValueChangedEventArgs.cs Nullable detail + nullable event args dictionaries
src/components/Blazor/ComponentBoolValueChangedEventArgs.cs Nullable event args dictionaries + null checks
src/components/Blazor/ComboChangeEventArgsDetail.cs Nullable arrays/refs/scripts + nullable event args dictionaries
src/components/Blazor/ComboChangeEventArgs.cs Nullable detail + nullable event args dictionaries
src/components/Blazor/CircularGradient.cs Nullable parameters + nullable args arrays
src/components/Blazor/Chip.cs Nullable args arrays + nullable script refs
src/components/Blazor/CheckboxChangeEventArgsDetail.cs Nullable value + nullable event args dictionaries
src/components/Blazor/CheckboxChangeEventArgs.cs Nullable detail + nullable event args dictionaries
src/components/Blazor/ChatRenderContext.cs Nullable instance
src/components/Blazor/ChatOptions.cs Nullable strings/arrays/renderers
src/components/Blazor/ChatMessageRenderContext.cs Nullable message
src/components/Blazor/ChatMessageReactionEventArgs.cs Nullable detail + nullable event args dictionaries
src/components/Blazor/ChatMessageReaction.cs Nullable message/reaction + nullable event args dictionaries
src/components/Blazor/ChatMessageEventArgs.cs Nullable detail + nullable event args dictionaries
src/components/Blazor/ChatMessageAttachmentEventArgs.cs Nullable detail + nullable event args dictionaries
src/components/Blazor/ChatMessageAttachment.cs Nullable fields + nullable event args dictionaries + fallback name
src/components/Blazor/ChatMessage.cs Nullable fields/arrays + nullable event args dictionaries
src/components/Blazor/ChatInputRenderContext.cs Nullable value
src/components/Blazor/ChatDraftMessage.cs Nullable fields/attachments + nullable event args dictionaries
src/components/Blazor/ChatAttachmentRenderContext.cs Nullable attachment
src/components/Blazor/CarouselSlide.cs Nullable args arrays for interop calls
src/components/Blazor/CarouselIndicator.cs Nullable args arrays for interop calls
src/components/Blazor/CardMedia.cs Nullable args arrays for interop calls
src/components/Blazor/CardHeader.cs Nullable args arrays for interop calls
src/components/Blazor/CardContent.cs Nullable args arrays for interop calls
src/components/Blazor/CardActions.cs Nullable args arrays for interop calls
src/components/Blazor/Card.cs Nullable args arrays for interop calls
src/components/Blazor/CalendarResourceStrings.cs Nullable resource string parameters
src/components/Blazor/CalendarFormatOptions.cs Nullable weekday/month + nullable event args dictionaries
src/components/Blazor/CalendarBase.cs Nullable locale/resource strings + nullable args arrays
src/components/Blazor/ButtonGroup.cs Nullable selected items + nullable args arrays + nullable script refs
src/components/Blazor/BaseOptionLike.cs Nullable value + nullable args arrays
src/components/Blazor/BaseComboBox.cs Nullable args arrays for interop calls
src/components/Blazor/BaseAlertLike.cs Nullable args arrays for interop calls
src/components/Blazor/Banner.cs Nullable args arrays + nullable script refs
src/components/Blazor/Badge.cs Nullable args arrays for interop calls
src/components/Blazor/Avatar.cs Nullable parameters + nullable args arrays
src/components/Blazor/ActiveStepChangingEventArgsDetail.cs Nullable event args dictionaries + null checks
src/components/Blazor/ActiveStepChangingEventArgs.cs Nullable detail + nullable event args dictionaries
src/components/Blazor/ActiveStepChangedEventArgsDetail.cs Nullable event args dictionaries + null checks
src/components/Blazor/ActiveStepChangedEventArgs.cs Nullable detail + nullable event args dictionaries
Suppressed comments (1)

src/componentsBase/DataAdapters.cs:46

  • RemoteJson.Uri is annotated as nullable, but it is always initialized via the constructor. Keeping it nullable makes ToRef() potentially produce malformed refs ("json:::") and pushes unnecessary nullability into callers.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread stories/Components/Stories/Chat.stories.razor
Comment thread src/components/Blazor/IconButton.cs Outdated
Comment thread src/componentsBase/DataAdapters.cs Outdated
Comment thread src/componentsBase/RuntimeHelper.cs Outdated
Comment thread src/componentsBase/WebViewCallback.cs Outdated
Comment thread src/componentsBase/IgbTemplateContent.razor Outdated
Copilot AI and others added 5 commits August 25, 2026 13:40
Co-authored-by: MayaKirova <10397980+MayaKirova@users.noreply.github.com>
…thread

Fix Copilot review findings: null-safety, dash encoding, delegate mismatch
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Comment thread src/componentsBase/BaseRendererControl.cs Fixed
Comment thread src/componentsBase/BaseRendererControl.cs Fixed
Comment thread src/componentsBase/BaseRendererControl.cs Fixed
Comment thread src/componentsBase/BaseRendererControl.cs Fixed
Comment thread src/componentsBase/BaseRendererControl.cs Fixed
Comment thread src/componentsBase/BaseRendererControl.cs Fixed
@skrustev skrustev self-assigned this Sep 2, 2026
Comment thread src/componentsBase/DataSourceManager.cs Outdated
}

//Console.WriteLine("notifying insert item");
if (refItem == null)

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.

I can't think of a proper case of whether we should we support adding/removing null, but with this if a user tries adding null refName it won't work.
Anyway I think it can stay as is.

NullDataSourceRepro.zip

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I don't think it makes sense to have null objects in the data source.
I can make refItem non-nullable so that users cannot explicitly pass null without getting a warning/error if that makes more sense.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Although, now that I look at the sample, this is not part of the public API. The logic that syncs them is internal, so not sure if we can prevent the user from adding nulls in his own collection.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Currently even just binding to collection that has a null, doesn't work, for example:

    private static ObservableCollection<Product?> CreateProducts() =>
    [
        new(1, "Chai"),
        null,
        new(2, "Chang"),
        new(3, "Aniseed Syrup"),
        
    ];

And if we decide to support nulls all scenarios should work, including things like updating a null value to something else.

For the time being, I don't think we should add support for this.

I guess we should just decide if it's better for nulls to be discarded (like it does now) or if it should throw an error.

@damyanpetev

@damyanpetev damyanpetev Sep 11, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

While null elements in collections are technically possible, it's probably exceeding rare if at all (not like there are null records in a DB tables, a join perhaps could), so while this might be worth looking into and making the behavior explicit and consistent - way out of scope for this PR's goal.
Anyway, the specific change has been reverted and the pre-existing flow restore more/less as it was.

dkamburov
dkamburov previously approved these changes Sep 4, 2026
Comment thread src/components/Blazor/ActiveStepChangedEventArgs.cs Fixed
Comment thread src/components/Blazor/ActiveStepChangingEventArgs.cs Fixed
Comment thread src/components/Blazor/ActiveStepChangedEventArgsDetail.cs Dismissed
Comment thread src/components/Blazor/ActiveStepChangingEventArgsDetail.cs Dismissed
Comment thread src/components/Blazor/ActiveStepChangingEventArgsDetail.cs Dismissed
Comment thread src/components/Blazor/CalendarFormatOptions.cs Dismissed
Comment thread src/components/Blazor/CalendarFormatOptions.cs Dismissed
Comment thread src/components/Blazor/ChatDraftMessage.cs Dismissed
Comment thread src/components/Blazor/ChatDraftMessage.cs Dismissed
return new IgbActiveStepChangedEventArgs();
return new IgbActiveStepChangedEventArgs
{
Detail = new IgbActiveStepChangedEventArgsDetail()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just a small note, I think this is a bit extra for now, unless we plan to do it for all event args.

@skrustev skrustev added the ✅ status: verified Applies to PRs that have passed manual verification label Sep 9, 2026
@damyanpetev damyanpetev added the squash-merge Merge PR with "Squash and Merge" option label Sep 10, 2026
@damyanpetev
damyanpetev added this pull request to stack #408 September 10, 2026 11:03
damyanpetev and others added 4 commits September 10, 2026 19:28
The full product made IgbDatePicker and IgbDateTimeInput Value, Min and Max nullable in 25.1.63, the shipped item templates bind a DateTime? field, and null is the only way to clear the element from Blazor. Generic value binding and EditForm integration for the date components are a separate change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
ReturnToString never returns null, so the getters built on it return string. IgcChatMessage id, text and sender, IgcChatMessageAttachment id and IgcTileChangeStateEventArgs tile are required on the client.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… operators

ConvertReturnValue returns object?, so the ReturnTo* guards and the component-side null checks are live again instead of being hidden behind null!. Dictionary getters return the raw value, the method-wide CS8604 pragmas are replaced by per-site checks, BuildSequenceInfo runs lazily rather than from the constructor, and collection notifications pass null items through as before. IgBlazor keeps the throwing getter: a nullable property would need about 150 guards at the module registration sites.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…htened

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@damyanpetev damyanpetev changed the title Enable Nullable analysis and fix warnings feat: Enable Nullable analysis and fix warnings Sep 11, 2026
@damyanpetev damyanpetev changed the title feat: Enable Nullable analysis and fix warnings feat(lib): Enable Nullable analysis and fix warnings Sep 11, 2026
Comment thread src/components/Blazor/ActiveStepChangedEventArgs.cs Fixed
Comment thread src/components/Blazor/ActiveStepChangingEventArgs.cs Fixed
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Comment thread src/components/Blazor/ChatMessage.cs Dismissed
Comment thread src/components/Blazor/ChatMessage.cs Dismissed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

‼️ breaking-change feature refactoring squash-merge Merge PR with "Squash and Merge" option ✅ status: verified Applies to PRs that have passed manual verification

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enable Nullable analysis

6 participants