Skip to content

fix: apply type inference pipeline to accessorKey-format grid columns - #903

Merged
hotlong merged 4 commits into
mainfrom
copilot/fix-objectgrid-type-inference
Feb 28, 2026
Merged

fix: apply type inference pipeline to accessorKey-format grid columns#903
hotlong merged 4 commits into
mainfrom
copilot/fix-objectgrid-type-inference

Conversation

CopilotAI commented Feb 28, 2026

Copy link
Copy Markdown
Contributor

ObjectGrid.generateColumns() returned accessorKey-format columns as-is, bypassing inferColumnType()getCellRenderer() entirely. Dates rendered as raw ISO strings, statuses as plain text, progress as raw numbers.

Core fix — ObjectGrid.tsx

The accessorKey branch now iterates columns and applies the same inference + renderer pipeline as the field branch, skipping columns that already have a cell renderer:

if('accessorKey'infirstCol){return(colsasany[]).map((col)=>{if(col.cell)returncol;// preserve custom renderersconstsyntheticCol={field: col.accessorKey,label: col.header,type: col.type};constinferredType=inferColumnType(syntheticCol);if(!inferredType)returncol;constCellRenderer=getCellRenderer(inferredType);// ... build fieldMeta, return col with cell renderer});}

humanizeLabel()fields/src/index.tsx

  • New exported utility: in_progressIn Progress, high-priorityHigh Priority
  • SelectCellRenderer uses it as fallback when no explicit option.label exists
  • Auto-generated select options in both column format branches now humanize labels

PercentCellRenderer normalization — fields/src/index.tsx

Fields matching WHOLE_PERCENT_FIELD_PATTERN (/progress|completion/) treat values as 0–100 directly. Other percent fields (e.g. probability) continue treating 0–1 as fractions. This means progress: 7575% and probability: 0.7575% both render correctly.

Tests

  • 14 new tests in cell-renderers.test.tsx (humanizeLabel edge cases, SelectCellRenderer fallback, PercentCellRenderer progress fields)
  • 5 new tests in accessorKey-inference.test.tsx (inference, date rendering, progress bars, custom renderer preservation)
Original prompt

This section details on the original issue you should resolve

<issue_title>ObjectGrid: accessorKey-format columns bypass type inference — raw dates, no badges, no progress bars</issue_title>
<issue_description>## Summary

The ObjectGrid rendering pipeline completely skips type inference and cell renderer injection when columns use accessorKey format (data-table format) instead of field format (ListColumn format). This causes all type-aware rendering to break — dates show raw ISO strings, status/priority show plain text, progress shows raw numbers, and user fields show raw IDs.

image1

Root Cause

In ObjectGrid.generateColumns(), the accessorKey branch returns columns as-is with no processing:

// packages/plugin-grid/src/ObjectGrid.tsx L506-514if('accessorKey'infirstCol){returncols;// ← BUG: skips entire inference + renderer pipeline}

Meanwhile the field (ListColumn) branch correctly runs inferColumnType()getCellRenderer() → cell renderer injection. This is a platform-level rendering pipeline gap that affects any view using accessorKey-format column definitions.

Symptoms (all caused by the same root cause)

Column TypeCurrent (broken)Expected
Date (start_date, end_date)2024-02-01T00:00:00.000ZFeb 1, 2024 via DateCellRenderer
Status (status)in_progress (plain text)Colored <Badge> via SelectCellRenderer
Priority (priority)high / critical (plain text)Semantic colored badge (orange/red)
Progress (progress)75 (raw number)Mini progress bar + 75% via PercentCellRenderer
Assignee (assignee)2 (raw ID)Avatar + name via UserCellRenderer

Required Changes

1. [P0] Apply inference to accessorKey-format columns

File:packages/plugin-grid/src/ObjectGrid.tsxgenerateColumns() L506-514

When columns are in accessorKey format, iterate and apply inferColumnType() + getCellRenderer() for columns that don't already have a cell renderer:

if('accessorKey'infirstCol){return(colsasany[]).map((col,colIndex)=>{if(col.cell)returncol;// already has custom rendererconstsyntheticCol={field: col.accessorKey,label: col.header,type: col.type};constinferredType=inferColumnType(syntheticCol);if(!inferredType)returncol;constCellRenderer=getCellRenderer(inferredType);constfieldMeta={name: col.accessorKey,type: inferredType};if(inferredType==='select'){constuniqueValues=Array.from(newSet(data.map(row=>row[col.accessorKey]).filter(Boolean)));fieldMeta.options=uniqueValues.map(v=>({value: v,label: humanizeLabel(String(v))}));}return{
...col,headerIcon: getTypeIcon(inferredType),cell: (value,row)=><CellRenderervalue={value}field={fieldMeta}/>,};});}

2. [P1] Auto-humanize snake_case select labels

File:packages/fields/src/index.tsxSelectCellRenderer

Add and export a humanizeLabel() utility, use as fallback when no option.label exists:

exportfunctionhumanizeLabel(value: string): string{returnvalue.replace(/[_-]/g,' ').replace(/\b\w/g,c=>c.toUpperCase());}// In SelectCellRenderer:constlabel=option?.label||humanizeLabel(String(value));

Also apply in ObjectGrid.generateColumns() when auto-generating options from data values.

3. [P1] PercentCellRenderer value normalization for progress fields

File:packages/fields/src/index.tsxPercentCellRenderer

Use field name to disambiguate 0-1 fraction vs 0-100 whole number:

constisWholePercentField=/progress|completion/.test(field?.name?.toLowerCase()||'');constbarValue=isWholePercentField
? numValue
: (numValue>-1&&numValue<1) ? numValue*100 : numValue;

Affected Packages

  • packages/plugin-grid/src/ObjectGrid.tsx — core fix
  • packages/fields/src/index.tsxSelectCellRenderer, PercentCellRenderer, humanizeLabel()

Acceptance Criteria

  • accessorKey-format columns receive type inference via inferColumnType()
  • Inferred types get appropriate getCellRenderer() cell renderers applied
  • Columns with existing cell renderer are NOT overridden
  • snake_case select values display as Title Case (e.g., in_progressIn Progress)
  • Explicit option.label still takes priority over humanized fallback
  • progress field with value 75 renders as 75% with correctly filled bar
  • probability field with value 0.75 renders as 75%
  • All existing tests pass; new tests added for:
    • accessorKey-format inference path
    • humanizeLabel() edge cases
    • PercentCellRenderer with progress-type fields
  • ROADMAP.md updated</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@vercel

vercelBot commented Feb 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
objectuiReadyReadyPreview, CommentFeb 28, 2026 5:14am
objectui-demoReadyReadyPreview, CommentFeb 28, 2026 5:14am
objectui-storybookReadyReadyPreview, CommentFeb 28, 2026 5:14am

Request Review

CopilotAIand others added 3 commits February 28, 2026 05:04
…Label, fix PercentCellRenderer for progress fields
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
…constant
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI changed the title [WIP] Fix ObjectGrid to apply type inference for accessorKey columnsfix: apply type inference pipeline to accessorKey-format grid columnsFeb 28, 2026
@hotlong

Copy link
Copy Markdown
Contributor

@copilot 仔细评估是否已经完成了任务中要求的所有开发

CopilotAI commented Feb 28, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot 仔细评估是否已经完成了任务中要求的所有开发

All acceptance criteria from the issue have been verified complete:

  1. accessorKey-format columns now receive inferColumnType() + getCellRenderer()ObjectGrid.tsx:512-533
  2. ✅ Columns with existing cell renderer are preserved (col.cell guard at line 514)
  3. humanizeLabel() exported from @object-ui/fields — converts in_progressIn Progress; used as fallback in SelectCellRenderer (both single and array values) and in ObjectGrid auto-generated select options
  4. PercentCellRenderer uses WHOLE_PERCENT_FIELD_PATTERN (/progress|completion/) — progress: 7575%, probability: 0.7575%
  5. ✅ 19 new tests added: 7 humanizeLabel edge cases, 3 SelectCellRenderer fallback, 4 PercentCellRenderer progress fields, 5 accessorKey inference path
  6. ✅ All existing tests pass: 327 fields + 293 plugin-grid
  7. ✅ ROADMAP.md updated with 3 new feature entries + test counts

@hotlong
hotlong marked this pull request as ready for review February 28, 2026 05:46
CopilotAI review requested due to automatic review settings February 28, 2026 05:46
@hotlong
hotlong merged commit f8450a1 into mainFeb 28, 2026
7 checks passed

CopilotAI 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

Fixes a rendering pipeline gap in @object-ui/plugin-grid where accessorKey-format columns previously bypassed ObjectGrid’s type inference and cell renderer injection, leading to raw/unstyled cell output for dates, select-like statuses, and percent/progress fields.

Changes:

  • Apply inferColumnType()getCellRenderer() to accessorKey-format columns (while preserving existing custom cell renderers).
  • Add humanizeLabel() to @object-ui/fields and use it as a fallback for select option labels (including auto-generated options).
  • Refine PercentCellRenderer normalization for “whole percent” fields (e.g., progress, completion) and add coverage via new tests.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
packages/plugin-grid/src/ObjectGrid.tsxApplies the inference/renderer pipeline to accessorKey columns and humanizes auto-generated select option labels.
packages/fields/src/index.tsxExports humanizeLabel(), uses it in SelectCellRenderer, and updates percent normalization for progress/completion-style fields.
packages/plugin-grid/src/tests/accessorKey-inference.test.tsxAdds regression tests ensuring accessorKey columns receive inference/renderers and preserve custom cells.
packages/fields/src/tests/cell-renderers.test.tsxAdds tests for humanizeLabel, SelectCellRenderer fallback behavior, and PercentCellRenderer whole-percent handling.
ROADMAP.mdMarks the work as completed and updates reported test counts.


return {
...col,
headerIcon: getTypeIcon(inferredType),

CopilotAIFeb 28, 2026

Copy link

Choose a reason for hiding this comment

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

In the accessorKey branch, inferred columns always overwrite any existing headerIcon on the incoming column object. If a consumer provided a custom headerIcon (but no custom cell), it will be lost. Consider only setting headerIcon when it’s not already present (e.g., prefer col.headerIcon if defined).

Suggested change
headerIcon: getTypeIcon(inferredType),
headerIcon: col.headerIcon??getTypeIcon(inferredType),

Copilot uses AI. Check for mistakes.
Comment on lines +527 to +530

return {
...col,
headerIcon: getTypeIcon(inferredType),

CopilotAIFeb 28, 2026

Copy link

Choose a reason for hiding this comment

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

In the accessorKey inference path, consider setting a default align: 'right' for inferred numeric types (number/currency/percent) when the incoming column doesn’t specify align. The ListColumn branch does this inference, so without it the two column formats render numeric fields with different alignment.

Suggested change
return{
...col,
headerIcon: getTypeIcon(inferredType),
constisNumericType=
inferredType==='number'||
inferredType==='currency'||
inferredType==='percent';
return{
...col,
headerIcon: getTypeIcon(inferredType),
// Respect explicit align, otherwise default right for numeric-like types
align: col.align??(isNumericType ? 'right' : undefined),

Copilot uses AI. Check for mistakes.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ObjectGrid: accessorKey-format columns bypass type inference — raw dates, no badges, no progress bars

3 participants

@hotlong