Use cases
Trigger this skill when the following problems occur:
- Blank page/blank table area: the canvas exists but does not draw content, or a local area (header/frozen area/body) is missing
- Missing cell content, misalignment, abnormal size, misaligned frozen area, abnormal hover/selection box position
- Custom rendering abnormalities: custom-layout / react-custom-layout does not take effect, renders empty, renders offset, or has incorrect size
- DOM overlay abnormalities: react attribute (DOM container mounting) does not display, is in the wrong position, or is out of sync with the canvas
- React18 works normally, React19 is abnormal: custom-layout blank,
older version of React element, two copies of React coexist, reconciler/hostConfig compatibility issues - React19 reconciler-related direct crash:
ReactCurrentOwner - VTable core customLayout decoding error:
decodeReactDom+type is not a function(the type of rootContainer is not as expected) - Triggered only by specific interactions: disappears after scroll/resize, appears only on hover, misaligned after frozen column switching
Workflow (execute in order)
0) Reproduction/verification workflow (source code troubleshooting scenario)
When troubleshooting and solving problems in the VTable source code, use the following workflow:
Reproduce the problem:
- Find the demo related to the problem in
/packages/vtable/examplesor create a new demo; if it is a gantt problem, you need to find the corresponding demo in/packages/vtable-gantt/examplesor create a new demo; if it is a plugin problem, you need to find the corresponding demo in/packages/vtable-plugins/demoor create a new demo; if it is a sheet spreadsheet problem, you need to find the corresponding demo in/packages/vtable-sheet/examplesor create a new demo; that is, decide which directory to create the demo in depending on the situation. - Modify the demo configuration to reproduce the problem (for example, set
select.disableSelect、customMergeCelletc.) - Start the demo service:
rushx demo(in thepackages/vtabledirectory) - Use Chrome DevTools MCP to connect to the browser and verify whether the problem is reproduced
Verify the fix:
- After modifying the source code, make sure the demo service has reloaded (Vite will automatically hot update)
- Use the same demo to verify whether the problem is resolved
- Check whether the fix introduces new problems (such as affecting other interactions or whether other demos work normally)
Common debugging techniques (with the help of DevTools MCP):
- Dynamically modify configuration for verification: You can inject configuration dynamically through
table.options.select.disableSelect = ...or by modifyingtable.theme.scrollStyleetc., so you can test different boundary cases without frequently modifying code and restarting the service. - Troubleshoot closure/scope issues: VTable's event listeners (such as
pointerleave,pointermove) contain a large number of closure variables. If some logic does not execute as expected, you can use MCP to inject breakpoints or print logs (override prototype chain methods or dynamically add event listeners) to troubleshoot whether the closure variable isundefinedor stale. - Canvas events and Scenegraph hierarchy:
- Distinguish between
stageandtableGroupevents. Hover/Leave-related problems (such as scrollbars or Tooltips disappearing abnormally) are often becausetableGroup'spointerleaveevent is accidentally triggered when the mouse moves to a blank area of the canvas. - Note
e.targetande.relatedTarget: when determining whether a node is inside a container,e.target.isDescendantsOf(stage)whentargetis exactlystageitself will returnfalse。the correct judgment modeshould betarget === stage || target?.isDescendantsOf?.(stage)。
- Distinguish between
- Get State:
- Use
table.getSelectedCellRanges()to check the current selection state. - Use
table.getCellRange(col, row)to check cell merge information.
- Use
Common Pitfalls (NEVER)
- NEVER, when
stage.width/heightis 0 or the parent container height is undefined, dig deep into the scenegraph; first fix the layout and container height - NEVER continue looking at scenegraph details when there are suspected two copies of React/ReactDOM on the same page; first fix the alias/dependency tree to ensure they are from the same source
- NEVER, after detecting Fiber contamination (graphics primitives
attributeshowtag/child/sibling/return/memoizedProps/lanes, etc.), continue doing bounds overlay; go directly back to the reconciler HostConfig (common point:commitUpdateparameter signature) - NEVER draw conclusions by only looking at DOM/console. For canvas-related issues such as missing drawn content, misaligned cells, etc., you must simultaneously verify using the scenegraph tree + bounds comparison
- NEVER ignore
componentGroup: many "problems that look like cell problems", such as selection/tooltip/overlay, are actually component/overlay layer problems - NEVER, when handling mouse interaction problems (Hover/Leave/Enter), take it for granted that
e.target.isDescendantsOf(stage)forstageitself will returntrue. Always usetarget === stage || target?.isDescendantsOf?.(stage)。 - NEVER ignore event interception by internal Groups. If you encounter scrollbars or highlight states disappearing abnormally, do not look for the cause only at the
stagelayer; it is most likely the internaltableGroupor another Group'spointerleave/pointeroutbubbling or executing unexpected hiding logic. - NEVER assume that variables at VTable initialization time are always up to date in closures. Because configuration items (such as
theme,options) may be deep-copied or replaced at runtime, directly destructuring or using variables from the outer scope inside closures such as event listeners may get old values. When encountering problems, use MCPevaluate_scriptto check the actual values at closure runtime. - NEVER, in tree / lazy-load / collapse scenarios, treat the
dataSource.getTableIndex(path)returned by-1as a valid visible row number and continue using it in highlight, focus, hover, selection, or refresh logic.-1usually means "this path is currently invisible". If you continue doing conversions such asrow = rawIndex + headerOffset, the common consequence is that the highlight lands on the header or another visible cell. - NEVER, in interaction logic that depends on visible
row/col(such as customCellStyle arrangement, focus highlight, range box), directly reuse old coordinates across "expand/collapse/sort/filter/data update". Once the layout changes, you must first clear the old arrangement / old cache, then recalculate according to the latest visible layout; otherwise the oldrowwill point to another record, manifesting as "searching for A but highlighting B in yellow". - NEVER rely on
getCellAddressByHeaderPathssuch global coordinate mapping APIs when troubleshooting PivotTable corner header states (such as sort icons, menus, etc.), because when dimensions with the same name exist in rows and columns (for example, both rows and columns are configured with theCategorydimension), such APIs only return the coordinates of the first matching cell. At the same time, NEVER rely only on the corner header cell's ownpivotInfoordimensionKeyto perform single-point state comparison, because the corner header may represent multiple nested levels of dimensions (for example,Sub-Categoryis atCategorythe second level below).Correct troubleshooting approachis: combinecornerSetting.titleOnDimensionandindicatorsAsColconfiguration to precisely determine whether the corner header belongs to the row dimension or the column dimension, then use thecol/rowcoordinates to extract the complete hierarchical path (path keys) fromlayoutMap.rowDimensionKeysorlayoutMap.colDimensionKeys, and then perform a strict length and layer-by-layer comparison with the targetdimensionsarray.
DevTools MCP connection troubleshooting
When encountering an MCP error (for example, DevToolsActivePort not found,Network.enable timed out), first handle it according to snippets.md 's 0) MCP 连接不上 Chrome , and after confirming the DevTools connection is available, continue troubleshooting the scenegraph.
1) First obtain the table and scenegraph (mandatory)
Goal:
- Obtain the VTable instance (ListTable/PivotTable)
- Confirm that
table.scenegraph.stageexists and width/height are normal
MANDATORY: load and use snippets.md 's:
-
- Find the VTable instance on the page
-
- Quickly inspect the childrenCount of each partition group
2) Partition attribution (mandatory)
Quickly determine the troubleshooting partition based on the symptom:
- Header issue:
colHeaderGroup / rowHeaderGroup / cornerHeaderGroup - Content area issue:
bodyGroup / rightFrozenGroup / bottomFrozenGroup - DOM overlay / component issue:
componentGroup
When you need to understand the scenegraph partition structure, load as needed:
3) Structural issues: export the tree + locate the cell (as needed)
When "there is no error but the visuals are wrong":
- Export the shallow tree of the target partition to confirm the node exists
- Find the target cell by col/row, then perform a deep export
MANDATORY: load and use snippets.md 's:
- 3) Find a cell group by col/row in bodyGroup
-
- Export the tree of any group
4) Coordinate issues: bounds overlay comparison (as needed)
When "the node exists but the position/size is wrong":
- Perform a bounds overlay on the target node
- Compare screenshots of "scene tree coordinates" and "screen pixels"
MANDATORY: load and use snippets.md 's:
- 5) Overlay bounds onto the screen (for screenshot comparison)
5) Quick checklist (mandatory)
- First rule out layout issues such as "container height is 0 / stage size is 0 / canvas is obscured"
- Confirm the partition selection is correct (body vs frozen vs header)
- Check the target node
attribute.visible, opacity, clip/culling - When bounds anomalies are found (Infinity/0/negative numbers/extremely large offsets), first suspect size updates/coordinate system transformations/incorrect property writes
- In DOM overlay mode, confirm the container is correct (
table.bodyDomContainer/table.headerDomContainer) and the container size/positioning is usable
6) React18/React19 difference troubleshooting (handled centrally)
When the symptom is "React18 is normal, React19 is abnormal" or "custom-layout is blank/offset under React19", first perform binary troubleshooting according to the dedicated guide (dependency tree/dual React/reconciler/HostConfig/DOM overlay), then return to the scenegraph for detailed localization.
MANDATORY: load and execute from beginning to end react18-react19.md。