Skip to content

refactor(Table): redesign auto fill column width logic#7956

Merged
ArgoZhang merged 10 commits intomainfrom
refactor-table-column-order
May 6, 2026
Merged

refactor(Table): redesign auto fill column width logic#7956
ArgoZhang merged 10 commits intomainfrom
refactor-table-column-order

Conversation

@ArgoZhang
Copy link
Copy Markdown
Member

@ArgoZhang ArgoZhang commented May 6, 2026

Link issues

fixes #7955

Summary By Copilot

Regression?

  • Yes
  • No

Risk

  • High
  • Medium
  • Low

Verification

  • Manual (required)
  • Automated

Packaging changes reviewed?

  • Yes
  • No
  • N/A

☑️ Self Check before Merge

⚠️ Please check all items below before review. ⚠️

  • Doc is updated/provided or not needed
  • Demo is updated/provided or not needed
  • Merge the latest code from the main branch

Summary by Sourcery

Unify client-side table column width and visibility persistence into a single state model and adjust related resize, auto-fit, and rendering logic to compute and store integer widths and table width consistently.

Bug Fixes:

  • Ensure table width is recalculated correctly when toggling column visibility or auto-fitting columns, preventing inconsistent layout states.

Enhancements:

  • Replace separate column visibility and width models with a consolidated TableColumnState/column state structure used across JS and C#.
  • Persist combined column state (visibility, widths, table width) in local storage and hydrate default state when none is present.
  • Update resize and auto-fit behaviors to recompute table width from column widths, update local storage, and pass full column state back to .NET callbacks.
  • Change resize callbacks and APIs to work with nullable integer column widths instead of floating-point values and separate table width arguments.
  • Refine Tooltip and style generation to use rounded, positive pixel widths and avoid invalid width values.

Copilot AI review requested due to automatic review settings May 6, 2026 07:26
@bb-auto bb-auto Bot added the enhancement New feature or request label May 6, 2026
@bb-auto bb-auto Bot added this to the v10.6.0 milestone May 6, 2026
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented May 6, 2026

Reviewer's Guide

Refactors the table column width persistence and auto-fit logic to use a unified column state model (name, width, visibility, table width) stored in localStorage, updates JS–.NET interop to pass the full state instead of individual widths, and replaces the old ColumnVisible/ColumnWidth types and APIs with a consolidated TableColumnState-based implementation.

Sequence diagram for column resize and state persistence

sequenceDiagram
    participant U as User
    participant B as Browser_Table_JS
    participant LS as localStorage
    participant C as Blazor_Table_Component

    U->>B: Drag column resizer / double click
    B->>B: autoFitColumnWidth(table,col)
    B->>B: getColumnStateObject(table)
    B->>LS: setItem(bb-table-column-tableName, stateJson)
    B->>C: invokeMethodAsync(ResizeColumnCallback, field, stateJson)

    C->>C: ResizeColumnCallback(name, JsonElement state)
    C->>C: state.Parse<TableColumnLocalstorageStatus>()
    C->>C: Update _tableColumnStateCache.Columns widths
    C->>C: Update _tableColumnStateCache.TableWidth
    alt OnResizeColumnAsync set
        C-->>C: OnResizeColumnAsync(name, column.Width)
    end

    C-->>B: return (JS interop complete)
    B->>B: resetColumnWidthTips(table,col)
Loading

Class diagram for unified Table column state model

classDiagram
    class TableColumnState {
        +string Name
        +string? DisplayName
        +bool Visible
        +int? Width
    }

    class TableColumnLocalstorageStatus {
        +List~TableColumnState~ Columns
        +int TableWidth
    }

    class Table~TItem~ {
        -TableColumnLocalstorageStatus _tableColumnStateCache
        -List~TableColumnState~ _columnVisibleItems
        +Task ReloadColumnStatesFromBrowserAsync()
        -void RebuildTableColumnFromCache(List~ITableColumn~ cols)
        -List~TableColumnState~ GetColumnVisibleItems(List~ITableColumn~ cols)
        +void ResetVisibleColumns(IEnumerable~TableColumnState~ columns)
        +Task ResizeColumnCallback(string name, JsonElement state)
        -Task OnToggleColumnVisible(TableColumnState item, bool visible)
    }

    class JsonElementExtensions {
        +T? Parse~T~(JsonSerializerDefaults options)
    }

    class ITableColumn {
        <<interface>>
        +string GetFieldName()
        +bool GetIgnore()
        +bool GetVisible()
        +string GetDisplayName()
        +int? Width
        +bool Visible
    }

    TableColumnLocalstorageStatus "1" o-- "*" TableColumnState : contains
    Table~TItem~ "1" o-- "1" TableColumnLocalstorageStatus : uses_cache
    Table~TItem~ "1" o-- "*" TableColumnState : visible_items
    Table~TItem~ ..> JsonElementExtensions : uses_Parse
    Table~TItem~ --> ITableColumn : rebuilds_from
Loading

File-Level Changes

Change Details Files
Unify column visibility and width persistence into a single TableColumnState model synchronized between Blazor and JavaScript.
  • Replace ColumnVisibleItem and ColumnWidthState with a new TableColumnState class that includes name, display name, visibility, and optional width.
  • Update TableColumnLocalstorageStatus to store a flat list of TableColumnState entries and a single table width value, matching the new JS payload shape.
  • Adjust Table.razor, Toolbar, Checkbox handlers, and sample usage to work with List instead of separate visibility/width structures, including ResetVisibleColumns and column list rendering.
src/BootstrapBlazor/Components/Table/TableColumnLocalstorageStatus.cs
src/BootstrapBlazor/Components/Table/TableColumnState.cs
src/BootstrapBlazor/Components/Table/Table.razor.cs
src/BootstrapBlazor/Components/Table/Table.razor.Toolbar.cs
src/BootstrapBlazor/Components/Table/Table.razor.Checkbox.cs
src/BootstrapBlazor.Server/Components/Samples/Table/TablesColumnList.razor.cs
src/BootstrapBlazor/Components/Table/Table.razor
Redesign client-side column width auto-fit and table width calculation, and persist combined column state in localStorage.
  • Remove obsolete functions for fitting all columns and resetting table width; instead compute table width from COLGROUP or fallback to rendered width with integer truncation.
  • Introduce getColumnStateObject/getColumnWidth/getTableWidth to derive a unified state (columns + table width) from the DOM, and saveColumnStateToLocalstorage to persist it under a new bb-table-column-{tableName} key.
  • Change getColumnStates to preferentially read the new unified state, with backward compatibility that merges legacy width and visibility entries, and add helpers to remove old keys if needed.
  • Update resize/mouseup/auto-fit handlers to compute table width, refresh tooltip labels, save the unified state, and invoke the .NET resize callback with the full state object instead of discrete values.
  • Normalize column and table widths to integers using bitwise OR with 0 before persisting or displaying in tooltips.
src/BootstrapBlazor/Components/Table/Table.razor.js
Update .NET-side resize and persistence APIs to consume the unified column state JSON from JavaScript and expose a simplified resize callback signature to consumers.
  • Change JSInvokable ResizeColumnCallback to accept a column name and a JsonElement containing the full state, deserialize it with a new JsonElementExtensions.Parse helper, and update the in-memory cache widths and table width accordingly.
  • Modify OnResizeColumnAsync parameter type from Func<string,float,Task> to Func<string,int?,Task> and update all call sites to pass the selected column's nullable int width extracted from the state.
  • Ensure initial load and rebuild paths (ReloadColumnStatesFromBrowserAsync, RebuildTableColumnFromCache, GetColumnVisibleItems, GetTableStyleString) use the new TableColumnLocalstorageStatus shape and fall back to component parameters when no persisted state exists.
  • Add GetColWidthString guard to ignore non-positive widths when generating inline width styles.
src/BootstrapBlazor/Components/Table/Table.razor.cs
src/BootstrapBlazor/Extensions/JsonElementExtesions.cs

Assessment against linked issues

Issue Objective Addressed Explanation
#7955 Redesign and refactor the Table component’s auto-fill/auto-fit column width logic, including how widths are computed, persisted, and communicated between JavaScript and .NET.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@ArgoZhang ArgoZhang merged commit 4f47a1b into main May 6, 2026
5 of 6 checks passed
@ArgoZhang ArgoZhang deleted the refactor-table-column-order branch May 6, 2026 07:27
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 2 issues, and left some high level feedback:

  • The new JsonElementExtensions class appears to use invalid C# syntax (extension(JsonElement element) and an inner Parse method); this should likely be refactored into a standard static extension method signature such as public static T? Parse<T>(this JsonElement element, JsonSerializerDefaults options = JsonSerializerDefaults.Web) at the class level.
  • In getTableWidth, colgroup is assumed to exist and colgroup.children is accessed unguarded; consider handling the case where the table has no COLGROUP to avoid a runtime error in those scenarios.
  • The new combined column state (width + visibility) handling introduces several storage keys (bb-table-column-*), but the old keys for width/visibility are only partially cleaned up (commented out removals in getColumnStates); consider either fully migrating/cleaning legacy keys or documenting why they must be preserved to avoid inconsistent state between versions.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new JsonElementExtensions class appears to use invalid C# syntax (`extension(JsonElement element)` and an inner `Parse` method); this should likely be refactored into a standard static extension method signature such as `public static T? Parse<T>(this JsonElement element, JsonSerializerDefaults options = JsonSerializerDefaults.Web)` at the class level.
- In `getTableWidth`, `colgroup` is assumed to exist and `colgroup.children` is accessed unguarded; consider handling the case where the table has no COLGROUP to avoid a runtime error in those scenarios.
- The new combined column state (width + visibility) handling introduces several storage keys (`bb-table-column-*`), but the old keys for width/visibility are only partially cleaned up (commented out removals in `getColumnStates`); consider either fully migrating/cleaning legacy keys or documenting why they must be preserved to avoid inconsistent state between versions.

## Individual Comments

### Comment 1
<location path="src/BootstrapBlazor/Extensions/JsonElementExtesions.cs" line_range="10-12" />
<code_context>
+
+namespace BootstrapBlazor.Components;
+
+static class JsonElementExtensions
+{
+    extension(JsonElement element)
+    {
+        public T? Parse<T>(JsonSerializerDefaults options = JsonSerializerDefaults.Web)
</code_context>
<issue_to_address>
**issue (bug_risk):** The JsonElementExtensions type is not valid C# and will not compile; it should be a static class with a proper extension method signature.

To define `Parse<T>` as an extension method on `JsonElement`, rewrite this as a static class with a proper extension signature, for example:

```csharp
namespace BootstrapBlazor.Components;

internal static class JsonElementExtensions
{
    public static T? Parse<T>(this JsonElement element, JsonSerializerDefaults options = JsonSerializerDefaults.Web)
    {
        try
        {
            return element.Deserialize<T>(new JsonSerializerOptions(options));
        }
        catch
        {
            return default;
        }
    }
}
```

You may also want to decide whether this class should be `internal` or `public` based on where it needs to be used.
</issue_to_address>

### Comment 2
<location path="src/BootstrapBlazor/Components/Table/Table.razor.js" line_range="852" />
<code_context>
 }

 export function getColumnStates(tableName) {
-    const columnVisibleStates = getColumnVisibleState(tableName);
+    const state = getColumnStateFromLocalstorage(tableName);
</code_context>
<issue_to_address>
**issue (complexity):** Consider extracting the legacy-to-new state migration and the state-building logic into dedicated helpers so `getColumnStates` and `saveColumnStateToLocalstorage` have simpler, clearer responsibilities.

You can keep the new combined column state while reducing the cognitive load by separating concerns a bit more. Two concrete areas:

---

### 1. Extract legacy–>new migration from `getColumnStates`

`getColumnStates` currently mixes:

- read new state
- read legacy width state
- merge legacy visibility into width
- (commented-out) cleanup

You can move the migration logic into a dedicated helper so `getColumnStates` is a simple “get or migrate” call:

```js
export function getColumnStates(tableName) {
    return getColumnStateFromLocalstorage(tableName)
        ?? migrateLegacyColumnState(tableName);
}

const migrateLegacyColumnState = tableName => {
    const columnWidthState = getColumnWidthState(tableName);
    if (!columnWidthState) {
        return null;
    }

    const columnVisibleStates = getColumnVisibleState(tableName);
    if (columnVisibleStates) {
        for (const item of columnWidthState.cols) {
            const { name } = item;
            const column = columnVisibleStates.find(i => i.name === name);
            item.visible = column ? column.visible : true;
        }

        // optional: once you’re ready to remove legacy keys:
        // removeColumnVisibleState(tableName);
        // removeColumnWidthState(tableName);
    }

    return columnWidthState;
};
```

This keeps all existing behavior, but limits `getColumnStates` to a trivial control flow and localizes the migration (including the commented-out cleanup) into one place.

---

### 2. Separate building state vs persisting state

`saveColumnStateToLocalstorage` both computes the state and writes it, which makes call sites harder to reason about (sometimes it uses the passed `state`, sometimes it recomputes).

You can keep the same functionality but make the API more explicit:

```js
const buildColumnState = table => {
    const cols = table.options.visibleColumns;
    return {
        cols: cols.map(col => ({
            name: col.name,
            width: getColumnWidth(col, table.columns),
            visible: col.visible
        })),
        table: getTableWidth(table.tables[0])
    };
};

const saveColumnStateToLocalstorage = (table, state) => {
    const { options: { tableName } } = table;
    if (!tableName) return;

    const columnStateKey = `bb-table-column-${tableName}`;
    const columnState = state ?? buildColumnState(table);
    localStorage.setItem(columnStateKey, JSON.stringify(columnState));
};
```

Call sites that already have the state stay clear:

```js
const state = buildColumnState(table);
saveColumnStateToLocalstorage(table, state);
await table.invoke.invokeMethodAsync(table.options.resizeColumnCallback, field, state);
```

And places that don’t care about the state can keep the convenience:

```js
// e.g. in resetColumns
table.options.visibleColumns = visibleColumns;
saveColumnStateToLocalstorage(table); // computes via buildColumnState
```

This keeps all behavior intact while making “what this function does” easier to understand at each call site.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +10 to +12
static class JsonElementExtensions
{
extension(JsonElement element)
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.

issue (bug_risk): The JsonElementExtensions type is not valid C# and will not compile; it should be a static class with a proper extension method signature.

To define Parse<T> as an extension method on JsonElement, rewrite this as a static class with a proper extension signature, for example:

namespace BootstrapBlazor.Components;

internal static class JsonElementExtensions
{
    public static T? Parse<T>(this JsonElement element, JsonSerializerDefaults options = JsonSerializerDefaults.Web)
    {
        try
        {
            return element.Deserialize<T>(new JsonSerializerOptions(options));
        }
        catch
        {
            return default;
        }
    }
}

You may also want to decide whether this class should be internal or public based on where it needs to be used.

@@ -880,25 +850,59 @@
}

export function getColumnStates(tableName) {
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.

issue (complexity): Consider extracting the legacy-to-new state migration and the state-building logic into dedicated helpers so getColumnStates and saveColumnStateToLocalstorage have simpler, clearer responsibilities.

You can keep the new combined column state while reducing the cognitive load by separating concerns a bit more. Two concrete areas:


1. Extract legacy–>new migration from getColumnStates

getColumnStates currently mixes:

  • read new state
  • read legacy width state
  • merge legacy visibility into width
  • (commented-out) cleanup

You can move the migration logic into a dedicated helper so getColumnStates is a simple “get or migrate” call:

export function getColumnStates(tableName) {
    return getColumnStateFromLocalstorage(tableName)
        ?? migrateLegacyColumnState(tableName);
}

const migrateLegacyColumnState = tableName => {
    const columnWidthState = getColumnWidthState(tableName);
    if (!columnWidthState) {
        return null;
    }

    const columnVisibleStates = getColumnVisibleState(tableName);
    if (columnVisibleStates) {
        for (const item of columnWidthState.cols) {
            const { name } = item;
            const column = columnVisibleStates.find(i => i.name === name);
            item.visible = column ? column.visible : true;
        }

        // optional: once you’re ready to remove legacy keys:
        // removeColumnVisibleState(tableName);
        // removeColumnWidthState(tableName);
    }

    return columnWidthState;
};

This keeps all existing behavior, but limits getColumnStates to a trivial control flow and localizes the migration (including the commented-out cleanup) into one place.


2. Separate building state vs persisting state

saveColumnStateToLocalstorage both computes the state and writes it, which makes call sites harder to reason about (sometimes it uses the passed state, sometimes it recomputes).

You can keep the same functionality but make the API more explicit:

const buildColumnState = table => {
    const cols = table.options.visibleColumns;
    return {
        cols: cols.map(col => ({
            name: col.name,
            width: getColumnWidth(col, table.columns),
            visible: col.visible
        })),
        table: getTableWidth(table.tables[0])
    };
};

const saveColumnStateToLocalstorage = (table, state) => {
    const { options: { tableName } } = table;
    if (!tableName) return;

    const columnStateKey = `bb-table-column-${tableName}`;
    const columnState = state ?? buildColumnState(table);
    localStorage.setItem(columnStateKey, JSON.stringify(columnState));
};

Call sites that already have the state stay clear:

const state = buildColumnState(table);
saveColumnStateToLocalstorage(table, state);
await table.invoke.invokeMethodAsync(table.options.resizeColumnCallback, field, state);

And places that don’t care about the state can keep the convenience:

// e.g. in resetColumns
table.options.visibleColumns = visibleColumns;
saveColumnStateToLocalstorage(table); // computes via buildColumnState

This keeps all behavior intact while making “what this function does” easier to understand at each call site.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors the Table component’s client-side column persistence by consolidating column visibility and width into a unified “column state” model, and revises the JS↔.NET resize callback to pass the full state payload (supporting the redesigned auto-fill/width logic from #7955).

Changes:

  • Replaced the old ColumnVisibleItem + separate column-width state model with TableColumnState (visibility + width) and a simplified localStorage payload { cols, table }.
  • Updated Table JS to save/restore the combined state and updated the JSInvokable resize callback to accept a JSON state object.
  • Added a JsonElement parsing helper extension and updated demo usage to the new state type.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/BootstrapBlazor/Extensions/JsonElementExtesions.cs Adds a JsonElement extension to safely deserialize JS-provided JSON payloads.
src/BootstrapBlazor/Components/Table/TableColumnState.cs Introduces TableColumnState (visibility + width) replacing the prior visibility-only type.
src/BootstrapBlazor/Components/Table/TableColumnLocalstorageStatus.cs Simplifies persisted table state to cols + table width.
src/BootstrapBlazor/Components/Table/Table.razor.Toolbar.cs Switches internal column visibility list to TableColumnState.
src/BootstrapBlazor/Components/Table/Table.razor.js Reworks localStorage read/write and resize persistence to use combined column state.
src/BootstrapBlazor/Components/Table/Table.razor.cs Updates state reload/apply logic and changes resize callback to accept JSON state.
src/BootstrapBlazor/Components/Table/Table.razor.Checkbox.cs Updates column visibility toggle logic to work with the unified state/cache model.
src/BootstrapBlazor/Components/Table/Table.razor Updates column list rendering to use TableColumnState.
src/BootstrapBlazor/Components/Table/ColumnWidthState.cs Removes the old standalone persisted table-width/column-width model.
src/BootstrapBlazor/Components/Table/ColumnWidth.cs Removes the old per-column width DTO used by the legacy persistence model.
src/BootstrapBlazor.Server/Components/Samples/Table/TablesColumnList.razor.cs Updates sample code to call ResetVisibleColumns with TableColumnState.
Comments suppressed due to low confidence (2)

src/BootstrapBlazor/Components/Table/TableColumnState.cs:16

  • This renames/remodels the previously public ColumnVisibleItem into TableColumnState without providing a compatibility type/alias/constructors. This is a breaking public API change for downstream apps (and existing tests in this repo) that still reference ColumnVisibleItem and its constructors (e.g., new("Name", true)). Consider keeping ColumnVisibleItem as an [Obsolete] wrapper around TableColumnState (or type-forwarding) and/or adding equivalent constructors on TableColumnState to preserve source compatibility.
    src/BootstrapBlazor/Components/Table/TableColumnState.cs:13
  • The XML doc summary still describes this as a “column visibility” type, but the class now also persists column width (and is used as the unified client-side column state). Please update the summary to reflect its broader responsibility (visibility + width/state) to avoid misleading API docs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 90 to 98
if (isVisible(table.el) === false) {
table.loopCheckHeightHandler = requestAnimationFrame(() => check(table));
return;
}

observeHeight(table)
}

export function fitAllColumnWidth(id) {
const table = Data.get(id)
if (table === null) {
return;
}

const columns = [...table.tables[0].querySelectorAll('.col-resizer')];
columns.forEach(async col => {
await autoFitColumnWidth(table, col);
});
saveColumnWidth();
}

const observeHeight = table => {
Comment on lines +865 to +874
for (const item of columnWidthState.cols) {
const { name } = item;
const column = columnVisibleStates.find(i => i.name === name);
if (column) {
item.visible = column.visible;
}
else {
item.visible = true;
}
}
Comment on lines 1449 to 1456
/// <para lang="zh">设置 列可见方法</para>
/// <para lang="en">Set Column Visible Method</para>
/// </summary>
/// <param name="columns"></param>
public void ResetVisibleColumns(IEnumerable<ColumnVisibleItem> columns)
public void ResetVisibleColumns(IEnumerable<TableColumnState> columns)
{
// https://github.com/dotnetcore/BootstrapBlazor/issues/6823
foreach (var col in columns)
Comment on lines 1821 to 1827
/// <summary>
/// <para lang="zh">获得/设置 设置列宽回调方法</para>
/// <para lang="en">Gets or sets Resize Column Callback</para>
/// </summary>
[Parameter]
public Func<string, float, Task>? OnResizeColumnAsync { get; set; }
public Func<string, int?, Task>? OnResizeColumnAsync { get; set; }

Comment on lines 1896 to 1904
{
// 调整列宽时返回所有列状态,更新缓存数据中列宽度与可见性
var columnState = state.Parse<TableColumnLocalstorageStatus>();
if (columnState == null)
{
return;
}

if (!string.IsNullOrEmpty(ClientTableName))
Comment on lines 1296 to +1311
var state = await InvokeAsync<TableColumnLocalstorageStatus>("getColumnStates", ClientTableName);
if (state != null)
if (state == null)
{
state.ColumnWidthState ??= new();
state.ColumnVisibleStates ??= new();
state = new();

_tableColumnStateCache = state;
// 开启客户端持久化后未设置列状态的列默认使用组件参数值
state.Columns.AddRange(Columns.Where(i => !i.GetIgnore()).Select(i => new TableColumnState()
{
Name = i.GetFieldName(),
Visible = i.GetVisible(),
DisplayName = i.GetDisplayName(),
Width = i.Width
}));
}

_tableColumnStateCache = state;
Comment on lines +8 to +11
namespace BootstrapBlazor.Components;

static class JsonElementExtensions
{
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor(Table): redesign auto fill column width logic

2 participants