Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion SUPERDATAGRID.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ When your model implements `IDataItem`:

| Parameter | Type | Default | Description |
|---|---|---|---|
| `AllowColumnReorder` | `bool` | `true` | Allow drag-and-drop column reordering |
| `AllowColumnReorder` | `bool` | `true` | Allow column reordering with up/down buttons in the Columns menu |
| `AllowColumnResize` | `bool` | `true` | Allow column resize via drag handles |
| `AllowSorting` | `bool` | `true` | Enable column sorting on header click |
| `AllowFiltering` | `bool` | `true` | Display filter controls in the header row |
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<Nullable>enable</Nullable>
<RootNamespace>SuperBlazorComponents.DataGridExporter</RootNamespace>
<AssemblyName>SuperBlazorComponents.DataGridExporter</AssemblyName>
<VersionPrefix>2.0.12</VersionPrefix>
<VersionPrefix>2.0.13</VersionPrefix>
<PackageId>SuperBlazorComponents.DataGridExporter</PackageId>
<Title>SuperBlazorComponents DataGrid Exporter</Title>
<Authors>Appliman</Authors>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
@implements IDisposable

<div class="@ContainerCssClass" @attributes="@CapturedAttributes">
<button type="button" class="@MainButtonCssClass" @onclick="@OnMainClick" disabled="@Disabled">
<button type="button" class="@(Click.HasDelegate ? MainButtonCssClass : $"{MainButtonCssClass} dropdown-toggle")"
data-bs-toggle="@(Click.HasDelegate ? null : "dropdown")"
aria-expanded="@(Click.HasDelegate ? null : "false")"
@onclick="@OnMainClick" disabled="@Disabled">
@if (!string.IsNullOrWhiteSpace(Icon))
{
<i class="@IconCssClass" title="@Text" aria-hidden="true"></i>
Expand All @@ -27,9 +30,12 @@
}
</button>

<button type="button" class="@ToggleButtonCssClass" data-bs-toggle="dropdown" aria-expanded="false" disabled="@Disabled">
<span class="visually-hidden">Toggle Dropdown</span>
</button>
@if (Click.HasDelegate)
{
<button type="button" class="@ToggleButtonCssClass" data-bs-toggle="dropdown" aria-expanded="false" disabled="@Disabled">
<span class="visually-hidden">Toggle Dropdown</span>
</button>
}

<ul class="@DropdownMenuCssClass">
<CascadingValue Value="this" IsFixed="true">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
@if (DisplaySelectionColumn
|| HeaderTemplate is not null
|| DisplayRefreshButton
|| AllowColumnResize && !string.IsNullOrWhiteSpace(GridId)
|| DisplayColumnVisibilityToggle)
{
<div class="sdg-header-section">
Expand All @@ -37,12 +36,6 @@
<SuperDatagridRefreshButton TItem="TItem" SuperDataGrid="this" Size="Components.Buttons.SuperButtonSize.Small" />
</div>
}
@if (AllowColumnResize && !string.IsNullOrWhiteSpace(GridId))
{
<div class="me-1">
<SuperDatagridResetButton TItem="TItem" SuperDataGrid="this" Size="Components.Buttons.SuperButtonSize.Small" />
</div>
}
@if (DisplayColumnVisibilityToggle)
{
<div class="me-1">
Expand Down Expand Up @@ -190,28 +183,9 @@
@foreach (var column in visibleColumns)
{
<th class="@GetColumnHeaderClass(column)"
style="@GetColumnHeaderStyle(column)"
@ondragover="@(e => OnColumnDragOver(e, column))"
@ondragover:preventDefault
@ondrop="@(e => OnColumnDrop(e, column))">
style="@GetColumnHeaderStyle(column)">
<div class="sdg-header-content"
draggable="@(AllowColumnReorder.ToString().ToLower())"
@ondragstart="@(e => OnColumnDragStart(e, column))"
@ondragend="OnColumnDragEnd"
@onclick="@(() => OnHeaderClick(column))">
@if (AllowColumnReorder && column.Reorderable)
{
<span class="sdg-drag-handle" @onclick:stopPropagation>
<svg width="10" height="16" viewBox="0 0 10 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="2.5" cy="2.5" r="1.5" fill="currentColor" />
<circle cx="7.5" cy="2.5" r="1.5" fill="currentColor" />
<circle cx="2.5" cy="8" r="1.5" fill="currentColor" />
<circle cx="7.5" cy="8" r="1.5" fill="currentColor" />
<circle cx="2.5" cy="13.5" r="1.5" fill="currentColor" />
<circle cx="7.5" cy="13.5" r="1.5" fill="currentColor" />
</svg>
</span>
}
@if (column.HeaderTemplate is not null)
{
@column.HeaderTemplate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public partial class SuperDataGrid<TItem> : IAsyncDisposable
private bool _isLoading;
private bool _defaultSettingsApplied;
private List<DataGridColumn<TItem>> _columns = [];
private DataGridColumn<TItem>? _draggedColumn;
private readonly List<DataGridColumn<TItem>> _defaultColumns = [];
private string? _sortColumn;
private SortDirection _sortDirection = SortDirection.None;
private bool _settingsLoaded;
Expand Down Expand Up @@ -190,7 +190,7 @@ public partial class SuperDataGrid<TItem> : IAsyncDisposable
public int FreezeRightColumns { get; set; }

/// <summary>
/// Whether columns can be reordered by drag and drop.
/// Whether columns can be reordered using the Columns menu.
/// </summary>
[Parameter]
public bool AllowColumnReorder { get; set; } = true;
Expand Down Expand Up @@ -549,6 +549,8 @@ public Task CollapseAllAsync()
/// </summary>
public async Task ResetColumnSettingsAsync()
{
_columns = [.. _defaultColumns];
_loadedColumnSettings = null;
foreach (var column in _columns)
{
column.ResetToDefaults();
Expand All @@ -560,6 +562,7 @@ public async Task ResetColumnSettingsAsync()
}

InvalidateColumnStyleCache();
await ColumnSettingsChanged.InvokeAsync(GetColumnSettings());
NotifyColumnStateChanged();
StateHasChanged();
}
Expand Down Expand Up @@ -662,6 +665,8 @@ public void AddColumn(int position, DataGridColumn<TItem> column)
targetIndex = Math.Clamp(position, 0, _columns.Count);
}

_defaultColumns.Remove(column);
_defaultColumns.Insert(Math.Clamp(position, 0, _defaultColumns.Count), column);
_columns.Insert(targetIndex, column);
column.MarkRegistrationState(true);
ApplyLoadedColumnSettingsIfAvailable();
Expand All @@ -684,6 +689,7 @@ internal void AddColumnCore(DataGridColumn<TItem> column)
}

_columns.Add(column);
_defaultColumns.Add(column);
column.MarkRegistrationState(true);
ApplyLoadedColumnSettingsIfAvailable();
InvalidateColumnStyleCache();
Expand All @@ -692,6 +698,7 @@ internal void AddColumnCore(DataGridColumn<TItem> column)

internal void RemoveColumn(DataGridColumn<TItem> column)
{
_defaultColumns.Remove(column);
if (_columns.Remove(column))
{
column.MarkRegistrationState(false);
Expand Down Expand Up @@ -1160,11 +1167,6 @@ private string GetColumnHeaderClass(DataGridColumn<TItem> column)
classes.Add("sdg-sortable");
}

if (_draggedColumn == column)
{
classes.Add("sdg-dragging");
}

if (!string.IsNullOrEmpty(column.HeaderCssClass))
{
classes.Add(column.HeaderCssClass);
Expand Down Expand Up @@ -1497,46 +1499,32 @@ private bool IsRowDeleted(TItem item)
return DisplayRowDeleted?.Invoke(item) == true;
}

private void OnColumnDragStart(DragEventArgs e, DataGridColumn<TItem> column)
/// <summary>Checks whether a column can swap with its immediate neighbor.</summary>
public bool CanMoveColumn(int columnIndex, int direction)
{
if (!AllowColumnReorder)
{
return;
}

_draggedColumn = column;
var targetIndex = columnIndex + direction;
return AllowColumnReorder && (direction == -1 || direction == 1)
&& columnIndex >= 0 && columnIndex < _columns.Count
&& targetIndex >= 0 && targetIndex < _columns.Count
&& _columns[columnIndex].Reorderable && _columns[targetIndex].Reorderable;
}

private void OnColumnDragEnd(DragEventArgs e)
/// <summary>Moves a column one position up (-1) or down (1) in the Columns menu.</summary>
public async Task MoveColumnAsync(int columnIndex, int direction)
{
_draggedColumn = null;
}

private void OnColumnDragOver(DragEventArgs e, DataGridColumn<TItem> column)
{
// Allow drop
}

private async Task OnColumnDrop(DragEventArgs e, DataGridColumn<TItem> targetColumn)
{
if (_draggedColumn is null || _draggedColumn == targetColumn || !AllowColumnReorder)
if (!CanMoveColumn(columnIndex, direction))
{
return;
}

var draggedIndex = _columns.IndexOf(_draggedColumn);
var targetIndex = _columns.IndexOf(targetColumn);

_columns.RemoveAt(draggedIndex);
_columns.Insert(targetIndex, _draggedColumn);

_draggedColumn = null;

var targetIndex = columnIndex + direction;
(_columns[columnIndex], _columns[targetIndex]) = (_columns[targetIndex], _columns[columnIndex]);
_loadedColumnSettings = NormalizeColumnSettings(GetColumnSettings());
InvalidateColumnStyleCache();
await SaveSettingsAsync();
await ColumnSettingsChanged.InvokeAsync(GetColumnSettings());
NotifyColumnStateChanged();
StateHasChanged();
await InvokeAsync(StateHasChanged);
}

private async Task OnResizeStart(MouseEventArgs e, DataGridColumn<TItem> column)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,38 +314,6 @@
background-color: inherit;
}

/* Drag Handle */
.sdg-drag-handle {
display: inline-flex;
align-items: center;
justify-content: center;
margin-right: 0.1rem;
padding: 0.1rem;
cursor: grab;
color: var(--bs-secondary, #6c757d);
opacity: 0.7;
transition: opacity 0.15s ease-in-out, color 0.15s ease-in-out;
flex-shrink: 0;
border-radius: 3px;
}

.sdg-drag-handle:hover {
opacity: 1;
cursor: grab;
color: var(--bs-body-color, #212529);
background-color: rgba(0, 0, 0, 0.05);
}

.sdg-drag-handle:active {
cursor: grabbing;
background-color: rgba(0, 0, 0, 0.1);
}

.sdg-drag-handle svg {
display: block;
vertical-align: middle;
}

.sdg-sortable .sdg-header-content {
cursor: pointer;
}
Expand Down Expand Up @@ -433,16 +401,6 @@
opacity: 0.3;
}

/* Column Drag Styling */
.sdg-dragging {
opacity: 0.5;
background-color: var(--bs-primary-bg-subtle, #cfe2ff) !important;
}

.sdg-drag-over {
border-left: 3px solid var(--bs-primary, #0d6efd) !important;
}

/* Base styles for all th and td */
.sdg-container th,
.sdg-container td {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* VirtualDataGrid - JavaScript Isolation Module
* Handles column resizing and drag-drop operations
* Handles column resizing and overflow previews
*/

const gridInstances = new Map();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,20 @@
<i class="fa-solid fa-eye me-2" aria-hidden="true"></i>
@Loc["DataGrid.Columns.Visible"]
</li>
@foreach (var column in _columns)
@if (_effectiveSuperDataGrid.AllowColumnReorder || _effectiveSuperDataGrid.AllowColumnResize)
{
<li>
<button type="button" class="dropdown-item" title="@Loc["DataGrid.Reset.Tooltip"]"
@onclick="_effectiveSuperDataGrid.ResetColumnSettingsAsync">
<i class="fa-solid fa-rotate-left me-2" aria-hidden="true"></i>
@Loc["DataGrid.Columns.Reset"]
</button>
</li>
<li><hr class="dropdown-divider" /></li>
}
@foreach (var column in _columns)
{
<li class="super-datagrid-column-row" @key="_effectiveSuperDataGrid.ColumnsCollection[column.ColumnIndex]">
<label class="dropdown-item super-datagrid-column-item">
<input type="checkbox"
class="form-check-input"
Expand All @@ -35,6 +46,25 @@
@onchange="@(args => OnColumnVisibilityChangedAsync(column, args))" />
<span>@column.DisplayName</span>
</label>
@if (_effectiveSuperDataGrid.AllowColumnReorder)
{
<div class="super-datagrid-column-move">
<button type="button" class="btn btn-outline-secondary btn-sm"
title="@Loc["DataGrid.Columns.MoveUp", column.DisplayName]"
aria-label="@Loc["DataGrid.Columns.MoveUp", column.DisplayName]"
disabled="@(!_effectiveSuperDataGrid.CanMoveColumn(column.ColumnIndex, -1))"
@onclick="@(() => _effectiveSuperDataGrid.MoveColumnAsync(column.ColumnIndex, -1))">
<i class="fa-solid fa-arrow-up" aria-hidden="true"></i>
</button>
<button type="button" class="btn btn-outline-secondary btn-sm"
title="@Loc["DataGrid.Columns.MoveDown", column.DisplayName]"
aria-label="@Loc["DataGrid.Columns.MoveDown", column.DisplayName]"
disabled="@(!_effectiveSuperDataGrid.CanMoveColumn(column.ColumnIndex, 1))"
@onclick="@(() => _effectiveSuperDataGrid.MoveColumnAsync(column.ColumnIndex, 1))">
<i class="fa-solid fa-arrow-down" aria-hidden="true"></i>
</button>
</div>
}
</li>
}
</ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
}

.super-datagrid-columns-menu {
min-width: 220px;
min-width: min(300px, calc(100vw - 1rem));
max-width: calc(100vw - 1rem);
max-height: 320px;
overflow-y: auto;
padding: 0.35rem;
Expand All @@ -25,3 +26,32 @@
.super-datagrid-column-item .form-check-input {
margin-top: 0;
}

.super-datagrid-column-row {
display: flex;
align-items: center;
}

.super-datagrid-column-item {
flex: 1;
min-width: 0;
margin-bottom: 0;
white-space: normal;
overflow-wrap: anywhere;
}

.super-datagrid-column-item .form-check-input {
flex-shrink: 0;
}

.super-datagrid-column-move {
display: flex;
flex-shrink: 0;
gap: 0.25rem;
margin-left: auto;
}

.super-datagrid-column-move .btn {
min-width: 28px;
min-height: 28px;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
{
"DataGrid.Columns.Reset": "Reset columns",
"DataGrid.Columns.MoveUp": "Move column {0} up",
"DataGrid.Columns.MoveDown": "Move column {0} down",

"DataGrid.Refresh.Tooltip": "Refresh list contents",
"DataGrid.Reset.Tooltip": "Reset grid configuration and remove saved preferences",
"DataGrid.Columns.Label": "Columns",
Expand Down
Loading
Loading