Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
03735ac
add breakpoint column
hellovolcano May 14, 2026
c4482c8
add events for context menu, cleanup accessibility
hellovolcano May 21, 2026
5e9df87
lint errors
hellovolcano May 21, 2026
6a89917
Change files
hellovolcano May 21, 2026
0dfed81
fix context menu event
hellovolcano May 21, 2026
c70a4a4
add blazor example
hellovolcano May 21, 2026
380d34d
update storybook docs
hellovolcano May 22, 2026
172e23a
update docs
hellovolcano May 22, 2026
ebdfba1
lint
hellovolcano May 22, 2026
04e871d
fix context menu
hellovolcano May 27, 2026
afe1e5c
Merge remote-tracking branch 'origin/main' into users/vgleason/breakp…
hellovolcano May 28, 2026
5e64d97
use new spright icons
hellovolcano May 28, 2026
9d84a53
fix imports
hellovolcano May 28, 2026
0f29771
cleanup
hellovolcano May 28, 2026
d727a82
fix test
hellovolcano May 28, 2026
7906497
Apply suggestions from code review
hellovolcano Jun 1, 2026
d4c4709
pr feedback
hellovolcano Jun 1, 2026
9cf5d1a
make code column unsortable
hellovolcano Jun 1, 2026
f475ef1
fix keyboard nav
hellovolcano Jun 2, 2026
978f85a
make string observable
hellovolcano Jun 2, 2026
a4c9754
updating tests
hellovolcano Jun 2, 2026
cb4d912
Merge branch 'main' into users/vgleason/breakpoint
hellovolcano Jun 2, 2026
c08ca4e
document keyboard interactions
hellovolcano Jun 2, 2026
184fac4
refactor to use anchored region
hellovolcano Jun 2, 2026
431a7fa
fix blazor example
hellovolcano Jun 2, 2026
bcad109
Merge branch 'users/vgleason/breakpoint' of https://github.com/ni/nim…
hellovolcano Jun 2, 2026
8bb7170
Merge branch 'main' into users/vgleason/breakpoint
hellovolcano Jun 2, 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "add breakpoint column",
"packageName": "@ni/ok-blazor",
"email": "5265744+hellovolcano@users.noreply.github.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
Comment thread
hellovolcano marked this conversation as resolved.
"type": "minor",
"comment": "add breakpoint column",
"packageName": "@ni/ok-components",
"email": "5265744+hellovolcano@users.noreply.github.com",
"dependentChangeType": "patch"
}
2 changes: 1 addition & 1 deletion packages/blazor-workspace/CodeAnalysisDictionary.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
<Recognized>
<Word>args</Word>
<Word>blazor</Word>
<Word>breakpoint</Word>
<Word>bool</Word>
<Word>breakpoint</Word>
<Word>clearable</Word>
<Word>combobox</Word>
<Word>dropdown</Word>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,6 @@
<RectangleSection />
<ExSection />
<FvSection />
<TsSection />
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
@namespace Demo.Shared.Pages.Sections

<div>
<SubContainer Label="Breakpoint Table Column (Ok)">
<NimbleTable TData="BreakpointTableRecord" @ref="_table" IdFieldName="Id" ParentIdFieldName="ParentId" class="breakpoint-table">
<NimbleTableColumnText FieldName="Name" FractionalWidth="2">Name</NimbleTableColumnText>
<OkTsTableColumnBreakpoint
FieldName="BreakpointState"
MenuSlot="breakpoint-menu"
BreakpointContextMenu="OnBreakpointContextMenu"
BreakpointToggle="OnBreakpointToggle">
</OkTsTableColumnBreakpoint>
<NimbleTableColumnNumberText FieldName="LineNumber">Line</NimbleTableColumnNumberText>

<NimbleMenu slot="breakpoint-menu">
@if (_contextMenuRecordState == OkBlazor.BreakpointState.Off)
{
<NimbleMenuItem @onchange="@(_ => OnAddBreakpoint())">Add breakpoint</NimbleMenuItem>
<NimbleMenuItem @onchange="@(_ => OnAddConditionalBreakpoint())">Add conditional breakpoint</NimbleMenuItem>
}
else
{
<NimbleMenuItem @onchange="@(_ => OnRemoveBreakpoint())">Remove breakpoint</NimbleMenuItem>
@if (_contextMenuRecordState == OkBlazor.BreakpointState.Enabled
|| _contextMenuRecordState == OkBlazor.BreakpointState.Conditional
|| _contextMenuRecordState == OkBlazor.BreakpointState.Hit)
{
<NimbleMenuItem @onchange="@(_ => OnDisableBreakpoint())">Disable breakpoint</NimbleMenuItem>
}
@if (_contextMenuRecordState == OkBlazor.BreakpointState.Disabled
|| _contextMenuRecordState == OkBlazor.BreakpointState.HitDisabled)
{
<NimbleMenuItem @onchange="@(_ => OnEnableBreakpoint())">Enable breakpoint</NimbleMenuItem>
}
}
</NimbleMenu>

</NimbleTable>
</SubContainer>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using NimbleBlazor;
using OkBlazor;

namespace Demo.Shared.Pages.Sections;

public partial class TsBreakpointTableSection
{
private NimbleTable<BreakpointTableRecord>? _table;
private string? _contextMenuRecordId;
private string _contextMenuRecordState = BreakpointState.Off;

private List<BreakpointTableRecord> _tableData = new()
{
new("1", null, "Main.cs", 12, BreakpointState.Enabled),
new("2", "1", "Helper.cs", 45, BreakpointState.Off),
new("3", "1", "Service.cs", 78, BreakpointState.Disabled),
new("4", null, "Controller.cs", 23, BreakpointState.Hit),
new("5", "4", "Model.cs", 91, BreakpointState.Conditional),
new("6", null, "Startup.cs", 5, BreakpointState.HitDisabled),
new("7", "6", "Program.cs", 1, BreakpointState.Off),
};

protected override async Task OnAfterRenderAsync(bool firstRender)
{
await _table!.SetDataAsync(_tableData);
await base.OnAfterRenderAsync(firstRender);
}

private void OnBreakpointToggle(BreakpointColumnToggleEventArgs e)
{
var record = _tableData.FirstOrDefault(r => r.Id == e.RecordId);
if (record != null)
{
record.BreakpointState = e.NewState;
}
StateHasChanged();
}

private void OnBreakpointContextMenu(BreakpointColumnContextMenuEventArgs e)
{
_contextMenuRecordId = e.RecordId;
_contextMenuRecordState = e.CurrentState;

StateHasChanged();
}

private void OnAddBreakpoint()
{
SetRecordState(BreakpointState.Enabled);
}

private void OnAddConditionalBreakpoint()
{
SetRecordState(BreakpointState.Conditional);
}

private void OnRemoveBreakpoint()
{
SetRecordState(BreakpointState.Off);
}

private void OnDisableBreakpoint()
{
SetRecordState(BreakpointState.Disabled);
}

private void OnEnableBreakpoint()
{
SetRecordState(BreakpointState.Enabled);
}

private void SetRecordState(string newState)
{
var record = _tableData.FirstOrDefault(r => r.Id == _contextMenuRecordId);
if (record != null)
{
record.BreakpointState = newState;
}
StateHasChanged();
}
}

public class BreakpointTableRecord
{
public BreakpointTableRecord(string id, string? parentId, string name, int lineNumber, string breakpointState)
{
Id = id;
ParentId = parentId;
Name = name;
LineNumber = lineNumber;
BreakpointState = breakpointState;
}

public string Id { get; set; }
public string? ParentId { get; set; }
public string Name { get; set; }
public int LineNumber { get; set; }
public string BreakpointState { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@namespace Demo.Shared.Pages.Sections

<TsBreakpointTableSection />
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace OkBlazor;

[EventHandler("onokbreakpointcolumntoggle", typeof(BreakpointColumnToggleEventArgs), enableStopPropagation: true, enablePreventDefault: false)]
[EventHandler("onokbreakpointcolumncontextmenu", typeof(BreakpointColumnContextMenuEventArgs), enableStopPropagation: true, enablePreventDefault: false)]
public static class EventHandlers
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace OkBlazor;

/// <summary>
/// The possible states of a breakpoint indicator.
/// </summary>
public static class BreakpointState
{
public const string Off = "off";
public const string Enabled = "enabled";
public const string Disabled = "disabled";
public const string Hit = "hit";
public const string Conditional = "conditional";
public const string HitDisabled = "hit-disabled";
}

/// <summary>
/// Event args for the breakpoint-column-toggle event.
/// </summary>
public class BreakpointColumnToggleEventArgs : EventArgs
{
public string RecordId { get; set; } = string.Empty;
public string NewState { get; set; } = string.Empty;
public string OldState { get; set; } = string.Empty;
}

/// <summary>
/// Event args for the breakpoint-column-context-menu event.
/// </summary>
public class BreakpointColumnContextMenuEventArgs : EventArgs
{
public string RecordId { get; set; } = string.Empty;
public string CurrentState { get; set; } = string.Empty;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@namespace OkBlazor

<ok-ts-table-column-breakpoint
column-id="@ColumnId"
field-name="@FieldName"
column-hidden="@ColumnHidden"
menu-slot="@MenuSlot"
@onokbreakpointcolumntoggle="BreakpointToggle"
@onokbreakpointcolumncontextmenu="BreakpointContextMenu"
@attributes="AdditionalAttributes">
</ok-ts-table-column-breakpoint>
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Components;

namespace OkBlazor;

public partial class OkTsTableColumnBreakpoint : ComponentBase
{
/// <summary>
/// The ID of the column.
/// </summary>
[Parameter]
public string? ColumnId { get; set; }

/// <summary>
/// Gets or sets the field in the data record that contains the breakpoint state value.
/// </summary>
[Parameter]
[DisallowNull]
public string FieldName { get; set; } = null!;

/// <summary>
/// The name of the slot in which to render the context menu for this breakpoint column. If not provided, no context menu will be rendered.
/// </summary>
[Parameter]
public string? MenuSlot { get; set; }

/// <summary>
/// Whether or not the column should be hidden.
/// </summary>
[Parameter]
public bool? ColumnHidden { get; set; }

/// <summary>
/// Gets or sets a callback invoked when a breakpoint is toggled (clicked).
/// </summary>
[Parameter]
public EventCallback<BreakpointColumnToggleEventArgs> BreakpointToggle { get; set; }

/// <summary>
/// Gets or sets a callback invoked when a context menu is requested on a breakpoint.
/// </summary>
[Parameter]
public EventCallback<BreakpointColumnContextMenuEventArgs> BreakpointContextMenu { get; set; }

/// <summary>
/// Any additional attributes that did not match known properties.
/// </summary>
[Parameter(CaptureUnmatchedValues = true)]
public IDictionary<string, object>? AdditionalAttributes { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,26 @@ function registerEvents(Blazor) {

hasRegisteredEvents = true;

/* Register any custom events here
Blazor.registerCustomEventType('okeventname', {
browserEventName: 'foo',
Blazor.registerCustomEventType('okbreakpointcolumntoggle', {
browserEventName: 'breakpoint-column-toggle',
createEventArgs: event => {
return {
recordId: event.detail.recordId,
newState: event.detail.newState,
oldState: event.detail.oldState
};
}
});
*/

Blazor.registerCustomEventType('okbreakpointcolumncontextmenu', {
browserEventName: 'breakpoint-column-context-menu',
createEventArgs: event => {
return {
recordId: event.detail.recordId,
currentState: event.detail.currentState
};
}
});
}

function handleRuntimeStarted() {
Expand Down
1 change: 1 addition & 0 deletions packages/ok-components/src/ts/all-ts.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
import './icon-dynamic';
import './table-column/breakpoint';
Loading