name: canvas-table-integration
description: >-
Use when integrating @qfei-design/canvas-table into an existing app or page.
Covers consumer-side local or virtual tables, public props/methods/events,
row-head suffix actions, selection, drag, fixed columns, summary rows, empty
states, lightweight render + TextShape + shape click interactions, host-side
cell-edit architecture, schema-driven Make field editors, customEdit,
commit/cancel, object autoClose, relatedElements, overlayOptions,
editApplyMode: controlled, attachment editors, and Make field-display
columns with value normalization, ExpensePoc-derived field renderers, and
overflow-only tooltip behavior. Only supports @qfei-design/canvas-table,
never UI-library tables. Read package AI docs first, choose Track A, B, or C,
use documented public APIs, and do not modify the table library itself.
canvas-table-integration
Use this skill only for consumer-side integration of @qfei-design/canvas-table. It does not support Ant Design Table, Arco Table, TDesign Table, native HTML tables, or any other table implementation as the product table.
This skill has three tracks:
- Track A: first-version base integration
- basic local table
- virtual remote table
- common public props / methods / events
- default row sequence numbers and hover-revealed open-detail row-head suffix action
- optional row selection / drag / summary / empty state
- row-head suffix actions such as an open-detail icon after the sequence number
- lightweight
render + TextShape + shape click
- Track B: second-version cell-edit enhancement
editType/customEditcommit/cancel- object
autoClose relatedElements/overlayOptions/destroyeditApplyMode: "controlled"- host-side edit controller architecture
- editor-container patterns
- field-editor mappings
- ExpensePoc-derived editable-cell defaults: double-click enters edit, clipped cells scroll fully into view before editing, popup editors open immediately, inline editors fill the active cell, and unchanged values do not call save APIs
- ExpensePoc-derived popup visibility, empty-value, no-double-border, and attachment-panel visual rules
- schema field-type mappings for display value vs submit value
- draft save layer vs immediate save layer
- positioning / scroll / popup close handling
- attachment editor integration
- Track C: Make field-display integration
- schema-driven columns for supported Make field types
- pure value normalization before canvas rendering
- text / URL / number / date / tag / user / department / attachment / lookup renderers
- default overflow-only tooltip behavior for text, tags, users, files, and lookup values
- folder separation for
config,renderers,hooks,types, and value adapters
Choose the track first. Do not mix a basic table integration request with a full cell-edit architecture refactor unless the user clearly wants the editing workflow.
If the user says display-only, field type display, or schema field rendering, choose Track C and leave cell editing out unless explicitly requested.
For new Make App projects or pages that display Make schema records, choose Track C by default even when the user only says "add a table" or "show a list". Use Track A only for @qfei-design/canvas-table pages whose columns are not Make schema-driven.
Quick start
- Confirm this is a consumer-side table integration, not table-library maintenance.
- Check package installation and read the package AI docs in the required order below.
- Choose exactly one primary track: Track A display table, Track B editable cells, or Track C Make field display. If Make schema fields are in scope, Track C is the default.
- For Make schema tables, load and normalize schema fields before initializing the table; build
IColumn[]plus renderers from the normalized field types. - Read only the track references from the topic map.
- Start from the package recipe/example when available, then adapt with the smallest project-local diff.
- Enable table row defaults unless the user explicitly opts out:
showSNsequence numbers plus a hover-revealed open-detail action throughbodyRowHeadSuffixOptions. - For Make schema tables, apply the ExpensePoc-derived field renderer defaults. Text-bearing overflow must show ellipsis, and tooltip is enabled by default only for ellipsized overflow or hidden
+Ncontent; do not require the user to ask for it. - When the object/entity/schema key changes, reset table interaction state and scroll position. Do not carry the previous object's horizontal or vertical scroll into the next object.
- Add only the capabilities the user explicitly needs now; pagination, selection, grouping, and editing are not defaults.
- Before finishing, read the relevant pitfalls reference and verify one concrete table path.
Typical requests
Track A: base integration
- 在页面里接入
canvas-table - 把现有列表替换成 canvas table
- 接一个本地数据表格
- 接后端分页 / 虚拟滚动表格(仅在用户明确要求分页或虚拟加载时)
- 只要接入表格,默认显示行序号,行 hover 时在行头显示进入详情图标;除非用户明确说不需要详情入口
- 按需做行选择、汇总、空状态、固定列
- 在序号列 / 行头后面添加进入详情、展开、快捷操作图标
- 把单元格渲染成可点击文本 / 链接
- 把 JSON meta 转成
IColumn[]
Track B: cell-edit enhancement
- 给 canvas table 增加单元格编辑
- 设计或接入
customEdit - 复用项目已有输入框 / 下拉 / 日期 / 人员 / 部门 / 附件组件
- 让表格 cell editor 的 Make 字段映射与 Drawer 表单保持一致
- 按 ExpensePoc 默认方式处理双击进入编辑、编辑前滚动到可见、编辑器定位、弹窗左右/上下边界、关闭、保存、回显、回填、回滚
- 增加文本 / 数字 / 日期 / 选项 / 人员 / 部门 / 附件字段编辑
- 按后端字段类型补齐 18 种 Make 字段的展示和可编辑/只读边界
- 把现有项目字段编辑器接进 canvas table
- 修复双击进入编辑后弹窗没有立即打开、被遮挡单元格没有先滚动到可见、编辑器没有铺满单元格、回显缺失、未修改仍调用接口等单元格编辑问题
Track C: Make field-display integration
- 根据 Make 字段类型生成 canvas table 展示列
- 新 Make 项目中只要是 schema 驱动的业务表格,默认按当前 ExpensePoc 表格展示基线生成;除非用户明确要求不同展示
- 把 18 种字段类型按展示族分类处理
- 默认处理列宽溢出:文本内容超出时显示省略号并展示 tooltip,未超出不展示 tooltip;多值被折叠为
+N时,+Ntooltip 展示完整列表 - 按 ExpensePoc 表格默认渲染附件、lookup、下拉标签、人员、部门、日期、金额等字段
- 把后端字段返回值规范化后展示在 canvas 表格中
- 拆分
config/renderers/hooks/types/ value adapter - 只处理展示,不做单元格编辑
Do not use this skill for
- publishing
@qfei-design/canvas-table - editing the table library itself
- generating or keeping another product table implementation instead of
@qfei-design/canvas-table - maintaining
package.ai.json,recipes.json, examples, or docs inside the table library repo - configuring private npm registries
- treating grouped-table architecture as the default answer
- forcing a new UI component library into a project that already has an editor/component system
Pre-flight check
Before editing code:
- Confirm
@qfei-design/canvas-tableis installed in the current project. - If there is no
package.json, stop and tell the user the current directory is not an npm package. - If the package is missing, detect the package manager from the lockfile and install it before continuing:
pnpm-lock.yaml->pnpm add @qfei-design/canvas-tableyarn.lock->yarn add @qfei-design/canvas-tablepackage-lock.json->npm install @qfei-design/canvas-table
- If no lockfile exists, default to
npm install @qfei-design/canvas-table. - If install fails, stop and report the command and error.
Use @qfei-design/canvas-table consistently. If an existing codebase uses a different package name, stop and ask before changing the consumer app dependency.
If an existing Make record list uses another table component, the expected integration target is still @qfei-design/canvas-table. Do not preserve a UI-library table as the main record table unless the user explicitly says this page is out of scope for canvas-table.
Required read order
Prefer reading from the installed package:
node_modules/<pkg>/package.ai.jsonnode_modules/<pkg>/docs/agent-usage.mdnode_modules/<pkg>/recipes.jsonnode_modules/<pkg>/capabilities.jsonnode_modules/<pkg>/PUBLIC_API.md
If the project is working directly inside the table monorepo, use the source paths instead:
packages/table/package.ai.jsonpackages/table/docs/agent-usage.mdpackages/table/recipes.jsonpackages/table/capabilities.jsonpackages/table/PUBLIC_API.md
Then choose the track-specific references.
Topic reference map
| Task / topic | Read |
|---|---|
| Public props, methods, events, setup, cleanup | references/core-props-methods-events.md |
| Row-head sequence number or open-detail action | references/row-head-action-patterns.md |
| Virtual loading / paginated backend integration | references/virtual-table-patterns.md |
Schema/meta to IColumn[] |
references/column-patterns.md |
| Custom clickable cell shapes | references/shape-render-patterns.md |
| Track A pitfalls | references/common-pitfalls.md |
| Cell-edit contract | references/edit-contract.md |
| Host-side edit architecture | references/edit-host-architecture.md |
| Edit lifecycle, positioning, close/commit/rollback | references/edit-interaction-lifecycle.md |
| ExpensePoc-derived Make editable-cell defaults | references/make-cell-edit-defaults.md |
| Field editor mapping | references/field-editor-patterns.md |
| Host component choice | references/editor-component-selection.md |
| Attachment editor integration | references/attachment-editor-patterns.md |
| Track B pitfalls | references/edit-common-pitfalls.md |
| Make field display | references/make-field-display-patterns.md |
| Proven downstream usage and unvalidated areas | references/validated-usage-notes.md |
| Track workflows, capability checklists, output templates | references/track-workflows.md |
For Track A: base integration
Read as needed:
references/core-props-methods-events.mdreferences/row-head-action-patterns.mdwhen adding an icon or action to the body row head / sequence-number areareferences/virtual-table-patterns.mdwhen using paginated virtual loadingreferences/column-patterns.mdwhen shaping columnsreferences/shape-render-patterns.mdwhen adding custom clickable cell contentreferences/common-pitfalls.mdbefore finalizing changes
For Track B: cell-edit enhancement
Read in this order:
- package-level cell-edit docs and source entry points
references/edit-contract.mdreferences/edit-host-architecture.mdreferences/edit-interaction-lifecycle.mdreferences/make-cell-edit-defaults.mdreferences/field-editor-patterns.mdreferences/editor-component-selection.mdreferences/attachment-editor-patterns.mdwhen attachment fields are in scopereferences/edit-common-pitfalls.mdbefore finalizing changes
If any required package file is missing, stop and tell the user exactly which file is missing.
For Track C: Make field-display integration
Read:
references/make-field-display-patterns.mdreferences/shape-render-patterns.mdwhen adding canvas shapesreferences/column-patterns.mdwhen derivingIColumn[]from field schemasreferences/common-pitfalls.mdbefore finalizing changes
Track A: first-version base integration scope
Use Track A for:
basic local tablevirtual remote table, only when the user explicitly asks for pagination, virtual loading, or paginated backend integration- common public
IColumn/TableCanvasProps/ instance-method usage - stable event-bus wiring
- default sequence-number row head through
showSNfor every table unless explicitly disabled - default hover-revealed open-detail icon through
bodyRowHeadSuffixOptionsfor every table unless explicitly disabled - optional row selection when the user asks for selection, batch actions, or multi-record operations
- row drag
- column drag
- fixed columns
- body row-head suffix actions through
bodyRowHeadSuffixOptions - summary rows
- empty states
- lightweight
render + TextShape + shape clickbusiness interaction
Do not turn a first-pass integration into a grouped-table or cell-edit project unless the user explicitly wants that deeper path.
Track B: second-version cell-edit enhancement scope
Use Track B when the user explicitly needs editable cells or a host-side field-editor system.
This track covers:
editTypecustomEdit- host-side edit controller design
- editor-container design
focus()/updateVal()style editor interfaces- submit-style vs realtime-style field editors
- click-outside save/close patterns through
autoCloseandrelatedElements - positioning and scroll-follow behavior for editor overlays
- value validation, commit, rollback, and cell backfill
- attachment-field editor integration
This track does not require a fixed UI library. Prefer the current project's existing editor components and component library.
For Make schema-driven editable tables, default to the ExpensePoc-proven edit baseline unless the user explicitly asks for a different interaction:
- Make editable cells enter edit on double-click by default. Keyboard/programmatic edit entry may still be supported, but a pointer user must not need a third click after the double-click activation.
- popup editors such as date, date range, select, user, department, lookup selector, and attachment panel open during the same cell-edit activation; never require an extra click after edit mode starts
- before mounting or showing the real editor/popup, partially hidden target cells must finish scrolling into the visible body viewport so the active cell and editor anchor are not clipped
- popup editor triggers inside the active cell are borderless and shadowless; the only blue editing border should be the canvas-table active-cell outline or the attachment popup panel itself
- inline editors such as text, textarea, number, currency, and percent fill the entire active cell with no extra wrapper border, margin, or outer padding
- every editor must echo the current cell value on entry using normalized backend value shapes, not formatted display strings
- all edits use a shared value contract with separate
renderValue,submitValue, and optionaldisplayValue - in single-field cell editing, every close path must compare normalized old/new values first; unchanged values close without calling save APIs, marking dirty state, or writing table data
- after edit commit/cancel/rollback, keep the table at the current scrollLeft/scrollTop. Do not reset to the left/top, remount the table, change the table identity key, or call
scrollTo(0, 0)for a same-object edit result
Track C: Make field-display integration scope
Use Track C when the task is to show Make platform fields correctly in canvas-table. In new Make App projects, this is the default for every Make schema-driven business table unless the user explicitly asks for a different table style. Keep it display-only: normalize backend values into a small display model, then route by display group to focused renderers. The 18 field types are the current backend contract, but implementation names and folder names may adapt to the host project.
Default grouping:
- text:
Make.Field.ID,Make.Field.Text,Make.Field.TextArea - url:
Make.Field.URL - number:
Make.Field.Number,Make.Field.Currency,Make.Field.Percent - date:
Make.Field.Date,Make.Field.DateTime,Make.Field.DateRange - select:
Make.Field.SingleSelect,Make.Field.MultiSelect - user:
Make.Field.SingleUser,Make.Field.MultiUser - department:
Make.Field.SingleDepartment,Make.Field.MultiDepartment - file:
Make.Field.File - lookup:
Make.Field.Lookup
Prefer this shape:
config/: schema field -> column config (width,align,showEllipsis,renderKind)renderers/: canvas shape renderers by display group (text,tag,user,attachment,lookup)hooks/: field option data needed for display, such as department candidates; never fetch per celltypes/: shared table/display contracts when they are used across modules- value adapter: pure functions that return
{ group, kind, text, labels, href, attachments, users, empty }
This is guidance, not a required folder taxonomy. Preserve an existing project structure when it already separates these responsibilities clearly.
Default Make schema table baseline:
- initialize the table only after runtime schema fields are available; missing schema is a blocking loading/error state, not a reason to infer columns from row keys
- derive columns from normalized runtime schema fields; do not pass raw remote schema objects or hand-maintain static columns for dynamic Make objects
- each generated column should retain
fieldType,fieldSchema, andrenderKindor equivalent metadata for renderer dispatch - normalize field values once through a pure adapter before canvas rendering
- route display by field type group, not by business field names, except for explicit business roles such as a primary code link
- use the ExpensePoc-proven renderer families by default: text/link, tag list, compact user avatar/name list, attachment list, lookup reference text, and safe generic fallback
- number, currency, and percent renderers must only format finite parsed numbers; blank, invalid,
NaN,Infinity, or unparseable values render the empty placeholder-and must never displayNaN - apply ellipsis plus overflow-only tooltip by default: visible text/tag/user/lookup labels must show ellipsis when truncated and get tooltip only when ellipsized; attachment/tag/user/lookup
+Nbadges get a tooltip with the full hidden value list - keep option, user, department, file, and lookup candidate loading outside cell renderers. Generated Make App table editors use the same default UI-Service candidate contract as forms:
GET /api/users?keyword=&page=&size=andGET /api/departments?keyword=&page=&size=, or host equivalent routes, normalized touserId/userNameanddepartmentId/departmentName - treat object/entity/schema key as table identity. On identity change, rebuild or reset the table so scrollLeft/scrollTop, active edit state, selection, hover/suffix state, and header popups do not leak from the previous object
- preserve row defaults:
showSNsequence numbers plus hover-revealed detail entry throughbodyRowHeadSuffixOptions
Safety rules and defaults
Treat these as safety rules:
- browser / client-only; never instantiate during SSR
- use a real DOM container with explicit width and height
- use only documented public APIs
- never import from
srcordist - use
@qfei-design/canvas-tablefor product tables; do not substitute UI-library tables - use
table.tableIdas the namespace key forglobalEventBus.onWithNamespace(...) - destroy the table instance on unmount / cleanup
- reset scroll and transient table state when switching object/entity/schema routes. Reusing the same React component for
/objects/:objectKeyis fine only if the table is keyed by that identity or the integration explicitly resets the canvas-table instance/state on identity change - never pass raw meta directly into the table runtime
- convert meta into
IColumn[]before creating the table - for Make schema tables, do not create the table with generic placeholder columns or row-key-inferred columns while waiting for schema
- never render numeric parser failures as
NaN,Infinity, or exception text; normalize them to an empty display value before canvas rendering - do not put
aria-hiddenorinerton the visual canvas-table host, or on any ancestor that can contain the package-created focusable canvas - if a screen-reader fallback table is needed, keep it as a separate visually-hidden structure and give the visual host its own non-hidden accessible label
- pagination is opt-in: do not add visible pagination controls, page-size selectors, page state, page query params, total-count handling, paginated fetch logic,
virtualOptions, ordata:loadwiring unless the user explicitly asks for pagination, virtual loading, or paginated backend integration
Detailed workflows and maintenance references
- For track workflows, capability checklists, avoid lists, deferred topics, and final response templates, read
references/track-workflows.md. - Before using a capability that is not obviously covered by the current project or package docs, read
references/validated-usage-notes.mdto distinguish validated downstream patterns from less-proven package capabilities.