Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
d20292f
Fix CS8625 in base/common files.
MayaKirova Aug 24, 2026
92a5801
Fix CS8625 in component files.
MayaKirova Aug 24, 2026
45e4784
Fix CS8618 by making uninitialized props nullable.
MayaKirova Aug 24, 2026
c42a849
Fix CS8600 - null conversion issues.
MayaKirova Aug 24, 2026
6672f37
Fix for CS8601 - null ref assignments.
MayaKirova Aug 24, 2026
c1d5fa5
Fix CS8602 - mark as not null.
MayaKirova Aug 24, 2026
9c49ff1
Fix CS8603 by marking types/return types as nullable.
MayaKirova Aug 24, 2026
32cbc78
Fix CS8604: Adds guards / ArgumentNullException.ThrowIfNull / signat…
MayaKirova Aug 25, 2026
c69deca
Adding null-forgiving operators where possible.
MayaKirova Aug 25, 2026
825c5a9
Fix CS8769 - set nullable object params so they match props.
MayaKirova Aug 25, 2026
5f58952
Fix casting to nullable types.
MayaKirova Aug 25, 2026
a2c457f
Minor tweaks.
MayaKirova Aug 25, 2026
ed12c2d
Few more tweaks around nullable params.
MayaKirova Aug 25, 2026
0d73f52
Refactor null checks for data sources in DataSourceManager and adjust…
MayaKirova Aug 25, 2026
1a6b9f1
Add more null checks.
MayaKirova Aug 25, 2026
92dc9bd
Merge branch 'master' into mkirova/nullable
MayaKirova Aug 25, 2026
187d80a
Initial plan
Copilot Aug 25, 2026
e56d8c5
Address review feedback: null guards, dash encoding, delegate fix
Copilot Aug 25, 2026
d522e78
Fix type mismatch.
MayaKirova Aug 25, 2026
d0a62ac
Merge pull request #366 from IgniteUI/copilot/fix-comments-in-review-…
MayaKirova Aug 25, 2026
5b1b057
Apply suggestions from code review
MayaKirova Aug 25, 2026
2a7b86a
Avoid null-forgiving operator where possible in favor of actual null …
MayaKirova Aug 26, 2026
30c9576
Replace null-forgiving operator with checks.
MayaKirova Aug 26, 2026
e05e740
Add null checks for collection items in CollectionAdapter
MayaKirova Aug 26, 2026
f79aafd
Remove a few more null-forgiving operators in favor of proper null ch…
MayaKirova Aug 26, 2026
8569a83
Replacing null-forgiving operators with null checks.
MayaKirova Aug 26, 2026
ac1b099
Marking ColumnData as nullable, since it explicitly gets set to null …
MayaKirova Aug 26, 2026
2c1fc66
Fix formatting.
MayaKirova Aug 26, 2026
62fd3bc
Final codeql fixe.s.
MayaKirova Aug 26, 2026
20f3d90
Apply suggestion
MayaKirova Aug 26, 2026
0a5b9be
Fix null check and update _inprocRuntime invocation.
MayaKirova Aug 26, 2026
5bc62b9
Enable nullable warnings in Directory.Build.props and remove nullable…
MayaKirova Aug 27, 2026
054ffc0
Remove redundant null-forgiving operators.
MayaKirova Aug 27, 2026
4305f2e
Remove redundant null-forgiving operators.
MayaKirova Aug 27, 2026
207e0cd
fix: two behavioral changes/regressions from nullable annotation pass
damyanpetev Aug 28, 2026
0ea0534
Merge pull request #372 from IgniteUI/dpetev/nullable-unmarshalled-fix
MayaKirova Aug 28, 2026
40fff10
Make EventArg Detail non-nullable.
MayaKirova Aug 28, 2026
c6570c4
Make DateTime across components non-nullable.
MayaKirova Aug 28, 2026
3e16486
Adjust public props to match type of client component props and defau…
MayaKirova Aug 28, 2026
9d207a7
fix formatting
MayaKirova Aug 28, 2026
c1ea51e
Potential fix for pull request finding 'Constant condition'
MayaKirova Aug 28, 2026
7b7fea6
Remove default object fallback.
MayaKirova Aug 28, 2026
74a0217
Fix tests.
MayaKirova Aug 28, 2026
2b2c844
Merge branch 'mkirova/nullable' of https://github.com/IgniteUI/ignite…
MayaKirova Aug 28, 2026
ee92352
ButtonGroup selection event args are nullable string. So setting it t…
MayaKirova Aug 31, 2026
56586ce
Remove redundant null-forgiving operators.
MayaKirova Aug 31, 2026
2a4099f
Initial plan
Copilot Aug 31, 2026
00dc2d6
Fix review-thread follow-ups and encoding cleanup
Copilot Aug 31, 2026
6d5b296
Merge pull request #384 from IgniteUI/copilot/fix-review-comments
MayaKirova Aug 31, 2026
5ef77b9
Adjust Chat API methods and evt args to match client-side nullability.
MayaKirova Sep 1, 2026
11fdf60
Merge branch 'mkirova/nullable' of https://github.com/IgniteUI/ignite…
MayaKirova Sep 1, 2026
09b2be5
Adjust API methods and evt args to match client-side nullability. Upd…
MayaKirova Sep 1, 2026
611ac49
Purge null forgiving operators in favor of fallbacks or actual null c…
MayaKirova Sep 1, 2026
bb9cb43
Merge branch 'master' into mkirova/nullable
MayaKirova Sep 1, 2026
bc12dd8
Initial plan
Copilot Sep 1, 2026
db82c38
Fix null component TCS race in dynamic content
Copilot Sep 1, 2026
8a2b7fe
Merge pull request #386 from IgniteUI/copilot/fix-review-comment-365
MayaKirova Sep 1, 2026
7e8e8ed
Adjust to wc api.
MayaKirova Sep 1, 2026
7f60486
Merge branch 'mkirova/nullable' of https://github.com/IgniteUI/ignite…
MayaKirova Sep 1, 2026
746f4c4
Merge branch 'master' into mkirova/nullable
MayaKirova Sep 2, 2026
f298c23
Merge branch 'master' into mkirova/nullable
MayaKirova Sep 2, 2026
a473f17
refactor: update DateRangePicker resource strings to support nullable…
MayaKirova Sep 2, 2026
276f875
chore: update changelog with breaking changes for public API nullability
MayaKirova Sep 2, 2026
1b9fe3a
Remove base classes and RenderSerializer.
MayaKirova Sep 2, 2026
fc104be
chore: update changelog to clarify public API nullability changes
MayaKirova Sep 2, 2026
8bbbd91
Merge from master.
MayaKirova Sep 9, 2026
49c709f
Address comments.
MayaKirova Sep 10, 2026
2aab6c2
Keep the date picker members nullable as in 0.1.0
damyanpetev Sep 10, 2026
4e30871
Align component nullability with the web component contracts
damyanpetev Sep 10, 2026
7482cc3
Restore master null handling in the base layer without null-forgiving…
damyanpetev Sep 10, 2026
2b8b7e9
Describe the reference-type nullability changes as clarified, not tig…
damyanpetev Sep 10, 2026
b304ed6
Look up event payloads with TryGetValue
damyanpetev Sep 11, 2026
5d457d6
Merge remote-tracking branch 'origin/master' into mkirova/nullable
damyanpetev Sep 11, 2026
0d3344a
Make required web component members non-nullable on render contexts, …
damyanpetev Sep 11, 2026
92bb7cb
Make chat message attachments, reactions and suggestions non-nullable…
damyanpetev Sep 11, 2026
d797519
Document nullability conventions for C#
damyanpetev Sep 11, 2026
74c3eb1
Merge remote-tracking branch 'origin/master' into mkirova/nullable
damyanpetev Sep 11, 2026
b2c20fa
Keep IgbInput InputMode and Autocomplete unset by default
damyanpetev Sep 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ This repository is the **source code for the Ignite UI for Blazor component libr

- Use the latest C# version supported by the target frameworks; prefer modern features (pattern matching, file-scoped namespaces) when they compile on all TFMs
- Use strict nullability (`#nullable enable`) in new files
- Annotate honestly: a member is `T?` only when `null` is a meaningful state; never use `!`, `null!` or `default!` to satisfy the analyzer, and keep runtime null checks at public entry points, since annotations are not enforced at runtime
- Prefer non-nullable collections: array and collection properties, parameters and return values are non-nullable and default to an empty collection, unless the web component treats a missing collection differently from an empty one
- Mirror the web component contract on data and option types: a field the `.d.ts` declares required is non-nullable (`required` when only user code constructs the type); a field declared optional or `| null` is `T?`; a definite-assignment attribute (`name!: string`) that the template renders with `ifDefined` is optional too, so check the render when the `.d.ts` shows a bare attribute string
- All public types live in `namespace IgniteUI.Blazor.Controls`
- Use PascalCase for public members; camelCase for private fields
- Prefix interfaces with `I` (e.g., `IIgniteUIBlazor`)
Expand Down
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Breaking Changes

#### Public API nullability

> [!NOTE]
> As part of this release the public API was annotated for nullable reference types. Beyond the members listed below, reference-type parameters, properties, and return values now declare whether they accept or produce `null`. Consumers building with nullable reference types enabled may see new nullable warnings — or errors, if warnings are treated as errors — and may need to update their code accordingly.

The following public members changed from nullable to non-nullable. Value-type changes (`double?` → `double`) are binary-breaking.

| Type | Member | Before | After |
|------|--------|--------|-------|
| `IgbTile` | `ColStart` | `double?` | `double` |
| `IgbTile` | `RowStart` | `double?` | `double` |
| `IgbCalendar` | `SpecialDates` | `IgbDateRangeDescriptor[]?` | `IgbDateRangeDescriptor[]` |
| `IgbCalendar` | `DisabledDates` | `IgbDateRangeDescriptor[]?` | `IgbDateRangeDescriptor[]` |

## 0.1.0 - 2026-07-14

This release updates the Ignite UI for Blazor to the latest [igniteui-webcomponents@7.2.4 release](https://github.com/IgniteUI/igniteui-webcomponents/releases/tag/7.2.4) and matching related changes from `IgniteUI.Blazor` [25.2.77 (March 2026)](https://www.infragistics.com/products/ignite-ui-blazor/blazor/components/general-changelog-dv-blazor#25277-march-2026), [25.2.102 (May 2026)](https://www.infragistics.com/products/ignite-ui-blazor/blazor/components/general-changelog-dv-blazor#252102-may-2026) and [26.1.51 (June 2026)](https://www.infragistics.com/products/ignite-ui-blazor/blazor/components/general-changelog-dv-blazor#26151-june-2026) with highlights noted below:
Expand Down
1 change: 1 addition & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<Copyright>Infragistics</Copyright>
<Deterministic>true</Deterministic>
<Nullable>enable</Nullable>
<WarningsAsErrors>$(WarningsAsErrors);nullable</WarningsAsErrors>
<ImplicitUsings>enable</ImplicitUsings>
<!-- Run the .editorconfig IDExxxx style rules as analyzers during build
so formatting violations surface as warnings locally and in CI. -->
Expand Down
3 changes: 0 additions & 3 deletions src/IgniteUI.Blazor.Lite.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

<PropertyGroup>
<PackageIdSuffix>.Lite</PackageIdSuffix>
<!-- TODO: opts out of the repo-wide <Nullable>enable</Nullable> for now — the generated
component sources are not annotated and would emit thousands of nullable warnings. -->
<Nullable>disable</Nullable>
</PropertyGroup>

<!-- Removed as pinning the language to an older version prevents building in net10 where global usings files are autogenerated -->
Expand Down
42 changes: 21 additions & 21 deletions src/components/Blazor/Accordion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public bool SingleExpand
}

/// <inheritdoc />
public override object FindByName(string name)
public override object? FindByName(string name)
{
var baseResult = base.FindByName(name);
if (baseResult != null)
Expand All @@ -103,34 +103,34 @@ public override object FindByName(string name)
/// </summary>
public async Task HideAllAsync()
{
await InvokeMethod("hideAll", new object[] { }, new string[] { });
await InvokeMethod("hideAll", new object?[] { }, new string[] { });
}

/// <summary>
/// Hides all of the child expansion panels' contents.
/// </summary>
public void HideAll()
{
InvokeMethodSync("hideAll", new object[] { }, new string[] { });
InvokeMethodSync("hideAll", new object?[] { }, new string[] { });
}
/// <summary>
/// Shows all of the child expansion panels' contents.
/// </summary>
public async Task ShowAllAsync()
{
await InvokeMethod("showAll", new object[] { }, new string[] { });
await InvokeMethod("showAll", new object?[] { }, new string[] { });
}

/// <summary>
/// Shows all of the child expansion panels' contents.
/// </summary>
public void ShowAll()
{
InvokeMethodSync("showAll", new object[] { }, new string[] { });
InvokeMethodSync("showAll", new object?[] { }, new string[] { });
}

private string _openingRef = null;
private string _openingScript = null;
private string? _openingRef = null;
private string? _openingScript = null;

/// <summary>
/// Name of a client-side function that handles the <see cref="Opening"/> event in the browser instead.
Expand All @@ -140,15 +140,15 @@ public void ShowAll()
/// <c>igRegisterScript("MyHandler", function (args) { }, false)</c>.
/// </remarks>
[Parameter]
public string OpeningScript
public string? OpeningScript
{

set
{
if (value != this._openingScript)
{
this._openingScript = value;
this.OnRefChanged("Opening", null, value, true, false, (string refName, object oldValue, object newValue) =>
this.OnRefChanged("Opening", null, value, true, false, (string refName, object? oldValue, object? newValue) =>
{
this._openingRef = refName;
this.MarkPropDirty("OpeningRef");
Expand Down Expand Up @@ -201,8 +201,8 @@ public EventCallback<IgbExpansionPanelComponentEventArgs> Opening
}
}

private string _openedRef = null;
private string _openedScript = null;
private string? _openedRef = null;
private string? _openedScript = null;

/// <summary>
/// Name of a client-side function that handles the <see cref="Opened"/> event in the browser instead.
Expand All @@ -212,15 +212,15 @@ public EventCallback<IgbExpansionPanelComponentEventArgs> Opening
/// <c>igRegisterScript("MyHandler", function (args) { }, false)</c>.
/// </remarks>
[Parameter]
public string OpenedScript
public string? OpenedScript
{

set
{
if (value != this._openedScript)
{
this._openedScript = value;
this.OnRefChanged("Opened", null, value, true, false, (string refName, object oldValue, object newValue) =>
this.OnRefChanged("Opened", null, value, true, false, (string refName, object? oldValue, object? newValue) =>
{
this._openedRef = refName;
this.MarkPropDirty("OpenedRef");
Expand Down Expand Up @@ -273,8 +273,8 @@ public EventCallback<IgbExpansionPanelComponentEventArgs> Opened
}
}

private string _closingRef = null;
private string _closingScript = null;
private string? _closingRef = null;
private string? _closingScript = null;

/// <summary>
/// Name of a client-side function that handles the <see cref="Closing"/> event in the browser instead.
Expand All @@ -284,15 +284,15 @@ public EventCallback<IgbExpansionPanelComponentEventArgs> Opened
/// <c>igRegisterScript("MyHandler", function (args) { }, false)</c>.
/// </remarks>
[Parameter]
public string ClosingScript
public string? ClosingScript
{

set
{
if (value != this._closingScript)
{
this._closingScript = value;
this.OnRefChanged("Closing", null, value, true, false, (string refName, object oldValue, object newValue) =>
this.OnRefChanged("Closing", null, value, true, false, (string refName, object? oldValue, object? newValue) =>
{
this._closingRef = refName;
this.MarkPropDirty("ClosingRef");
Expand Down Expand Up @@ -345,8 +345,8 @@ public EventCallback<IgbExpansionPanelComponentEventArgs> Closing
}
}

private string _closedRef = null;
private string _closedScript = null;
private string? _closedRef = null;
private string? _closedScript = null;

/// <summary>
/// Name of a client-side function that handles the <see cref="Closed"/> event in the browser instead.
Expand All @@ -356,15 +356,15 @@ public EventCallback<IgbExpansionPanelComponentEventArgs> Closing
/// <c>igRegisterScript("MyHandler", function (args) { }, false)</c>.
/// </remarks>
[Parameter]
public string ClosedScript
public string? ClosedScript
{

set
{
if (value != this._closedScript)
{
this._closedScript = value;
this.OnRefChanged("Closed", null, value, true, false, (string refName, object oldValue, object newValue) =>
this.OnRefChanged("Closed", null, value, true, false, (string refName, object? oldValue, object? newValue) =>
{
this._closedRef = refName;
this.MarkPropDirty("ClosedRef");
Expand Down
13 changes: 7 additions & 6 deletions src/components/Blazor/ActiveStepChangedEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public partial class IgbActiveStepChangedEventArgs : BaseRendererElement

private static bool _marshalByValue = true;

private IgbActiveStepChangedEventArgsDetail _detail;
private IgbActiveStepChangedEventArgsDetail _detail = new IgbActiveStepChangedEventArgsDetail();

/// <summary>
/// The payload of the event, carrying the index of the step that became active.
Expand All @@ -25,15 +25,16 @@ public IgbActiveStepChangedEventArgsDetail Detail
set
{
MarkPropDirty("Detail");

if (this._detail != null)
{
this.DetachChild(this._detail);
}
this._detail = value;
if (value != null)
{
this.AttachChild(value);
}
this._detail = value;
}

}
Expand All @@ -48,7 +49,7 @@ internal override void SerializeCore(RendererSerializer ser)
}

/// <inheritdoc />
protected internal override void ToEventJson(BaseRendererControl control, Dictionary<string, object> args)
protected internal override void ToEventJson(BaseRendererControl control, Dictionary<string, object?> args)
{
base.ToEventJson(control, args);

Expand All @@ -58,13 +59,13 @@ protected internal override void ToEventJson(BaseRendererControl control, Dictio
}

/// <inheritdoc />
protected internal override void FromEventJson(BaseRendererControl control, Dictionary<string, object> args)
protected internal override void FromEventJson(BaseRendererControl control, Dictionary<string, object?>? args)
{
base.FromEventJson(control, args);
this.SuppressParentNotify = true;

if (args.ContainsKey("detail"))
{ this.Detail = (IgbActiveStepChangedEventArgsDetail)ConvertReturnValue(args["detail"], "ActiveStepChangedEventArgsDetail", true); }
if (args != null && args.TryGetValue("detail", out var detailObj) && ConvertReturnValue(detailObj, "ActiveStepChangedEventArgsDetail", true) is IgbActiveStepChangedEventArgsDetail detail)
{ this.Detail = detail; }

this.SuppressParentNotify = false;
}
Expand Down
6 changes: 3 additions & 3 deletions src/components/Blazor/ActiveStepChangedEventArgsDetail.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ internal override void SerializeCore(RendererSerializer ser)
}

/// <inheritdoc />
protected internal override void ToEventJson(BaseRendererControl control, Dictionary<string, object> args)
protected internal override void ToEventJson(BaseRendererControl control, Dictionary<string, object?> args)
{
base.ToEventJson(control, args);

Expand All @@ -52,12 +52,12 @@ protected internal override void ToEventJson(BaseRendererControl control, Dictio
}

/// <inheritdoc />
protected internal override void FromEventJson(BaseRendererControl control, Dictionary<string, object> args)
protected internal override void FromEventJson(BaseRendererControl control, Dictionary<string, object?>? args)
{
base.FromEventJson(control, args);
this.SuppressParentNotify = true;

if (args.ContainsKey("index"))
if (args != null && args.ContainsKey("index"))
Comment thread
MayaKirova marked this conversation as resolved.
Dismissed
{ this.Index = ReturnToDouble(args["index"]); }

this.SuppressParentNotify = false;
Expand Down
12 changes: 6 additions & 6 deletions src/components/Blazor/ActiveStepChangingEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public partial class IgbActiveStepChangingEventArgs : BaseRendererElement

private static bool _marshalByValue = true;

private IgbActiveStepChangingEventArgsDetail _detail;
private IgbActiveStepChangingEventArgsDetail _detail = new IgbActiveStepChangingEventArgsDetail();

/// <summary>
/// The payload of the event, carrying the index of the currently active step and the index of
Expand All @@ -30,11 +30,11 @@ public IgbActiveStepChangingEventArgsDetail Detail
{
this.DetachChild(this._detail);
}
this._detail = value;
if (value != null)
{
this.AttachChild(value);
}
this._detail = value;
}

}
Expand All @@ -49,7 +49,7 @@ internal override void SerializeCore(RendererSerializer ser)
}

/// <inheritdoc />
protected internal override void ToEventJson(BaseRendererControl control, Dictionary<string, object> args)
protected internal override void ToEventJson(BaseRendererControl control, Dictionary<string, object?> args)
{
base.ToEventJson(control, args);

Expand All @@ -59,13 +59,13 @@ protected internal override void ToEventJson(BaseRendererControl control, Dictio
}

/// <inheritdoc />
protected internal override void FromEventJson(BaseRendererControl control, Dictionary<string, object> args)
protected internal override void FromEventJson(BaseRendererControl control, Dictionary<string, object?>? args)
{
base.FromEventJson(control, args);
this.SuppressParentNotify = true;

if (args.ContainsKey("detail"))
{ this.Detail = (IgbActiveStepChangingEventArgsDetail)ConvertReturnValue(args["detail"], "ActiveStepChangingEventArgsDetail", true); }
if (args != null && args.TryGetValue("detail", out var detailObj) && ConvertReturnValue(detailObj, "ActiveStepChangingEventArgsDetail", true) is IgbActiveStepChangingEventArgsDetail detail)
{ this.Detail = detail; }

this.SuppressParentNotify = false;
}
Expand Down
8 changes: 4 additions & 4 deletions src/components/Blazor/ActiveStepChangingEventArgsDetail.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ internal override void SerializeCore(RendererSerializer ser)
}

/// <inheritdoc />
protected internal override void ToEventJson(BaseRendererControl control, Dictionary<string, object> args)
protected internal override void ToEventJson(BaseRendererControl control, Dictionary<string, object?> args)
{
base.ToEventJson(control, args);

Expand All @@ -75,14 +75,14 @@ protected internal override void ToEventJson(BaseRendererControl control, Dictio
}

/// <inheritdoc />
protected internal override void FromEventJson(BaseRendererControl control, Dictionary<string, object> args)
protected internal override void FromEventJson(BaseRendererControl control, Dictionary<string, object?>? args)
{
base.FromEventJson(control, args);
this.SuppressParentNotify = true;

if (args.ContainsKey("oldIndex"))
if (args != null && args.ContainsKey("oldIndex"))
Comment thread
MayaKirova marked this conversation as resolved.
Dismissed
{ this.OldIndex = ReturnToDouble(args["oldIndex"]); }
if (args.ContainsKey("newIndex"))
if (args != null && args.ContainsKey("newIndex"))
Comment thread
MayaKirova marked this conversation as resolved.
Dismissed
{ this.NewIndex = ReturnToDouble(args["newIndex"]); }

this.SuppressParentNotify = false;
Expand Down
Loading