[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-tanstack-cell-selection":3,"mdc--saccqe-key":50,"related-repo-tanstack-cell-selection":1612,"related-org-tanstack-cell-selection":1692},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":20,"repoUrl":21,"updatedAt":22,"license":23,"forks":24,"topics":25,"repo":45,"sourceUrl":48,"mdContent":49},"cell-selection","select rectangular cell ranges in tables","Select rectangular cell ranges with cellSelectionFeature: two-corner range state keyed by row and column id, mousedown\u002Fmouseenter handlers, selection edges, render-order resolution under pinning, and autoResetCellSelection. Load when ranges widen unexpectedly after sorting or column reordering, when a drag re-renders the whole table, or when building copy-to-clipboard from a selection.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},"tanstack","TanStack","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Ftanstack.png",[12,16,19],{"name":13,"slug":14,"type":15},"Data Analysis","data-analysis","tag",{"name":17,"slug":18,"type":15},"UI Components","ui-components",{"name":9,"slug":8,"type":15},28175,"https:\u002F\u002Fgithub.com\u002FTanStack\u002Ftable","2026-07-30T05:25:38.403427",null,3539,[26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44],"datagrid","datagrids","datatable","filtering","grid","grouping","hooks","javascript","pagination","react","reactjs","solid","solidjs","sorting","svelte","sveltejs","table","typescript","vue",{"repoUrl":21,"stars":20,"forks":24,"topics":46,"description":47},[26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44],"🤖 Headless UI for building powerful tables & datagrids for TS\u002FJS -  React-Table, Vue-Table, Solid-Table, Svelte-Table","https:\u002F\u002Fgithub.com\u002FTanStack\u002Ftable\u002Ftree\u002FHEAD\u002Fpackages\u002Ftable-core\u002Fskills\u002Fcell-selection","---\nname: cell-selection\ndescription: >\n  Select rectangular cell ranges with cellSelectionFeature: two-corner range state keyed by row and column id, mousedown\u002Fmouseenter handlers, selection edges, render-order resolution under pinning, and autoResetCellSelection. Load when ranges widen unexpectedly after sorting or column reordering, when a drag re-renders the whole table, or when building copy-to-clipboard from a selection.\nmetadata:\n  {\n    type: sub-skill,\n    library: '@tanstack\u002Ftable-core',\n    library_version: '9.0.0-beta.59',\n  }\nrequires: ['core', 'table-features']\nsources:\n  - 'TanStack\u002Ftable:docs\u002Fframework\u002Freact\u002Fguide\u002Fcell-selection.md'\n  - 'TanStack\u002Ftable:packages\u002Ftable-core\u002Fsrc\u002Ffeatures\u002Fcell-selection'\n  - 'TanStack\u002Ftable:examples\u002Freact\u002Fcell-selection'\n---\n\nThis skill builds on `core` and `table-features`. `cellSelection` is an array of rectangles, each stored as two corner cells identified by row and column id. It is not a per-cell map, and it is not positional.\n\n## Setup\n\n```ts\nimport { cellSelectionFeature, tableFeatures } from '@tanstack\u002Ftable-core'\n\ntype Person = { id: string; name: string }\nexport const features = tableFeatures({ cellSelectionFeature })\nexport const options = {\n  getRowId: (row: Person) => row.id,\n}\n```\n\nState shape:\n\n```ts\ntype CellSelectionRange = {\n  anchorRowId: string\n  anchorColumnId: string\n  focusRowId: string\n  focusColumnId: string\n}\ntype CellSelectionState = Array\u003CCellSelectionRange>\n```\n\nThe `anchor` corner stays put; the `focus` corner moves during a drag or Shift-extend. Two corners are what make Shift-extend possible, and they keep a drag across thousands of cells to a two-field write.\n\n## Core Patterns\n\n### Bind both mouse handlers\n\n```ts\nconst onMouseDown = cell.getSelectionStartHandler()\nconst onMouseEnter = cell.getSelectionExtendHandler()\n```\n\nThe start handler attaches its own document-level `mouseup` listener and removes it when the drag ends, so a pointer released outside the table still finishes correctly. Pass a document explicitly (`cell.getSelectionStartHandler(iframeDocument)`) only when the table renders into another document.\n\n### Read the selection\n\n```ts\nconst count = table.getSelectedCellCount()\nconst grids = table.getSelectedCellRangesData() \u002F\u002F [range][row][column]\n```\n\nExpansion APIs are memoized and pull-based, so a table that only highlights cells never pays to enumerate a large selection.\n\n### Draw the outline from edges\n\n`cell.getSelectionEdges()` marks a side `true` when the neighbouring cell in that direction is not selected, which yields one continuous outline around a union of rectangles. All sides are `false` when the cell is not selected.\n\n### Drive keyboard navigation externally\n\nThe feature ships no keydown handling. Call `table.moveCellSelection(direction)`, `table.extendCellSelection(direction)`, `table.setFocusedCell(rowId, columnId)`, `table.selectAllCells()`, and `table.resetCellSelection(true)` from a hotkey library such as `@tanstack\u002Freact-hotkeys`, scoped to the grid element rather than the document.\n\n## Common Mistakes\n\n### [HIGH] Expecting a per-cell selection map\n\nWrong: `const isSelected = table.state.cellSelection[cell.id]`\n\nCorrect: `const isSelected = cell.getIsSelected()`\n\n`cellSelection` holds rectangles, not cell keys. Membership is resolved by comparing the cell's row and column index against the memoized bounds.\n\nSource: `packages\u002Ftable-core\u002Fsrc\u002Ffeatures\u002Fcell-selection\u002FcellSelectionFeature.types.ts`\n\n### [HIGH] Assuming a range is frozen to the cells it originally covered\n\nRanges are anchored to corner ids, so sorting, filtering, and column reordering keep the corners and recompute what sits between them. A range can therefore widen onto columns or rows the user never selected. Reset in userland when the product needs stricter behavior:\n\n```ts\n\u002F\u002F after a column reorder or pin\ntable.resetCellSelection(true)\n```\n\nHiding a column that a corner sits on makes the range inert rather than deleting it; it returns when the column is shown again.\n\nSource: `docs\u002Fframework\u002Freact\u002Fguide\u002Fcell-selection.md#how-ranges-survive-table-changes`\n\n### [HIGH] Binding only mousedown and expecting drag\n\nWrong:\n\n```ts\nconst props = { onMouseDown: cell.getSelectionStartHandler() }\n```\n\nCorrect:\n\n```ts\nconst props = {\n  onMouseDown: cell.getSelectionStartHandler(),\n  onMouseEnter: cell.getSelectionExtendHandler(),\n}\n```\n\nWithout the extend handler a drag selects only the origin cell. Do not add a `mouseup` binding; the start handler already owns one.\n\nSource: `examples\u002Freact\u002Fcell-selection`\n\n### [HIGH] Deriving column position from column definition order\n\nWrong: `const index = column.getIndex()`\n\nCorrect: `const isSelected = cell.getIsSelected()`\n\nCells render start-pinned first, then center, then end. `getVisibleLeafColumns()` and `column.getIndex()` are not pinning-reordered, so indexing a selection against them makes a rectangle visually scattered as soon as a column is pinned. The feature resolves its own render-order index map; use the cell APIs rather than recomputing membership.\n\nSource: `packages\u002Ftable-core\u002Fsrc\u002Ffeatures\u002Fcell-selection\u002FcellSelectionFeature.utils.ts`\n\n### [HIGH] Re-rendering every cell on each drag update\n\nWrong: one subscription wrapping the whole `\u003Ctbody>`.\n\nCorrect: one subscription per row, with a selector returning only what changes that row's appearance.\n\nA drag writes state on every cell boundary crossed. A table-wide subscription reconciles every cell each time. Subscribe per row against `table.atoms.cellSelection` and derive a key from `table.getCellSelectionBounds()` (memoized, so it computes once per change) covering the row itself plus the rows above and below, which decide its top and bottom edges.\n\nSource: `docs\u002Fframework\u002Freact\u002Fguide\u002Fcell-selection.md#performance-with-tablesubscribe`\n\n### [MEDIUM] Drawing selection borders on a border-collapse table\n\nWrong: `.cell-selected { border: 2px solid blue }`\n\nCorrect: `.cell-selected { box-shadow: inset 0 0 0 2px blue }`\n\nOn a `border-collapse` table a thicker border widens the shared grid line, so rows change height as cells become selected. Box-shadow never affects layout.\n\nSource: `examples\u002Freact\u002Fcell-selection\u002Fsrc\u002Findex.css`\n\n### [MEDIUM] Expecting a clipboard string from the table\n\nWrong: `navigator.clipboard.writeText(table.getSelectedCellsAsTsv())`\n\nCorrect: `navigator.clipboard.writeText(toTsv(table.getSelectedCellRangesData()))`\n\nThe table returns raw values only. The delimiter, the representation of `null`, and quoting rules are application decisions, so serialization is userland. Quote any field containing a tab, newline, or quote, or a pasted spreadsheet gains phantom columns.\n\nSource: `docs\u002Fframework\u002Freact\u002Fguide\u002Fcell-selection.md#copying-a-selection`\n\n### [MEDIUM] Persisting a selection and expecting drag state with it\n\n`cellSelection` is safe to persist because drag session state is deliberately non-reactive instance data, not part of the slice. Do not add an `isSelecting` field to the persisted state; a stored `true` would rehydrate into a drag that hovering extends and nothing ever ends.\n\nSource: `packages\u002Ftable-core\u002Fsrc\u002Ffeatures\u002Fcell-selection\u002FcellSelectionFeature.types.ts`\n\n### [MEDIUM] Fighting the automatic reset on data change\n\nSelection resets to `initialState.cellSelection` whenever `data` changes, because new data can invalidate the row ids a range points at or silently re-select cells when ids are reused. Opt out deliberately:\n\n```ts\nexport const keepAcrossDataChanges = { autoResetCellSelection: false }\n```\n\n`autoResetAll` overrides this option.\n\nSource: `packages\u002Ftable-core\u002Fsrc\u002Ffeatures\u002Fcell-selection\u002FcellSelectionFeature.ts`\n\n## API Discovery\n\nInspect `node_modules\u002F@tanstack\u002Ftable-core\u002Fdist\u002Ffeatures\u002Fcell-selection\u002F` for `CellSelectionRange`, `CellSelectionState`, `CellSelectionBounds`, `CellSelectionEdges`, the enablement and `is*Event` options, and the cell and table instance APIs.\n",{"data":51,"body":63},{"name":4,"description":6,"metadata":52,"requires":56,"sources":59},{"type":53,"library":54,"library_version":55},"sub-skill","@tanstack\u002Ftable-core","9.0.0-beta.59",[57,58],"core","table-features",[60,61,62],"TanStack\u002Ftable:docs\u002Fframework\u002Freact\u002Fguide\u002Fcell-selection.md","TanStack\u002Ftable:packages\u002Ftable-core\u002Fsrc\u002Ffeatures\u002Fcell-selection","TanStack\u002Ftable:examples\u002Freact\u002Fcell-selection",{"type":64,"children":65},"root",[66,97,104,399,404,539,560,566,573,649,670,676,757,762,768,795,801,852,858,869,880,891,901,912,922,927,971,976,986,996,1001,1057,1062,1160,1172,1182,1192,1202,1211,1231,1241,1251,1263,1268,1289,1299,1310,1320,1330,1343,1353,1363,1373,1383,1396,1406,1416,1441,1450,1460,1481,1530,1541,1551,1557,1606],{"type":67,"tag":68,"props":69,"children":70},"element","p",{},[71,74,80,82,87,89,95],{"type":72,"value":73},"text","This skill builds on ",{"type":67,"tag":75,"props":76,"children":78},"code",{"className":77},[],[79],{"type":72,"value":57},{"type":72,"value":81}," and ",{"type":67,"tag":75,"props":83,"children":85},{"className":84},[],[86],{"type":72,"value":58},{"type":72,"value":88},". ",{"type":67,"tag":75,"props":90,"children":92},{"className":91},[],[93],{"type":72,"value":94},"cellSelection",{"type":72,"value":96}," is an array of rectangles, each stored as two corner cells identified by row and column id. It is not a per-cell map, and it is not positional.",{"type":67,"tag":98,"props":99,"children":101},"h2",{"id":100},"setup",[102],{"type":72,"value":103},"Setup",{"type":67,"tag":105,"props":106,"children":111},"pre",{"className":107,"code":108,"language":109,"meta":110,"style":110},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { cellSelectionFeature, tableFeatures } from '@tanstack\u002Ftable-core'\n\ntype Person = { id: string; name: string }\nexport const features = tableFeatures({ cellSelectionFeature })\nexport const options = {\n  getRowId: (row: Person) => row.id,\n}\n","ts","",[112],{"type":67,"tag":75,"props":113,"children":114},{"__ignoreMap":110},[115,174,184,248,302,328,390],{"type":67,"tag":116,"props":117,"children":120},"span",{"class":118,"line":119},"line",1,[121,127,133,139,144,149,154,159,164,169],{"type":67,"tag":116,"props":122,"children":124},{"style":123},"--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic",[125],{"type":72,"value":126},"import",{"type":67,"tag":116,"props":128,"children":130},{"style":129},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[131],{"type":72,"value":132}," {",{"type":67,"tag":116,"props":134,"children":136},{"style":135},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[137],{"type":72,"value":138}," cellSelectionFeature",{"type":67,"tag":116,"props":140,"children":141},{"style":129},[142],{"type":72,"value":143},",",{"type":67,"tag":116,"props":145,"children":146},{"style":135},[147],{"type":72,"value":148}," tableFeatures",{"type":67,"tag":116,"props":150,"children":151},{"style":129},[152],{"type":72,"value":153}," }",{"type":67,"tag":116,"props":155,"children":156},{"style":123},[157],{"type":72,"value":158}," from",{"type":67,"tag":116,"props":160,"children":161},{"style":129},[162],{"type":72,"value":163}," '",{"type":67,"tag":116,"props":165,"children":167},{"style":166},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[168],{"type":72,"value":54},{"type":67,"tag":116,"props":170,"children":171},{"style":129},[172],{"type":72,"value":173},"'\n",{"type":67,"tag":116,"props":175,"children":177},{"class":118,"line":176},2,[178],{"type":67,"tag":116,"props":179,"children":181},{"emptyLinePlaceholder":180},true,[182],{"type":72,"value":183},"\n",{"type":67,"tag":116,"props":185,"children":187},{"class":118,"line":186},3,[188,194,200,205,209,215,220,225,230,235,239,243],{"type":67,"tag":116,"props":189,"children":191},{"style":190},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[192],{"type":72,"value":193},"type",{"type":67,"tag":116,"props":195,"children":197},{"style":196},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[198],{"type":72,"value":199}," Person",{"type":67,"tag":116,"props":201,"children":202},{"style":129},[203],{"type":72,"value":204}," =",{"type":67,"tag":116,"props":206,"children":207},{"style":129},[208],{"type":72,"value":132},{"type":67,"tag":116,"props":210,"children":212},{"style":211},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[213],{"type":72,"value":214}," id",{"type":67,"tag":116,"props":216,"children":217},{"style":129},[218],{"type":72,"value":219},":",{"type":67,"tag":116,"props":221,"children":222},{"style":196},[223],{"type":72,"value":224}," string",{"type":67,"tag":116,"props":226,"children":227},{"style":129},[228],{"type":72,"value":229},";",{"type":67,"tag":116,"props":231,"children":232},{"style":211},[233],{"type":72,"value":234}," name",{"type":67,"tag":116,"props":236,"children":237},{"style":129},[238],{"type":72,"value":219},{"type":67,"tag":116,"props":240,"children":241},{"style":196},[242],{"type":72,"value":224},{"type":67,"tag":116,"props":244,"children":245},{"style":129},[246],{"type":72,"value":247}," }\n",{"type":67,"tag":116,"props":249,"children":251},{"class":118,"line":250},4,[252,257,262,267,272,277,282,287,292,297],{"type":67,"tag":116,"props":253,"children":254},{"style":123},[255],{"type":72,"value":256},"export",{"type":67,"tag":116,"props":258,"children":259},{"style":190},[260],{"type":72,"value":261}," const",{"type":67,"tag":116,"props":263,"children":264},{"style":135},[265],{"type":72,"value":266}," features ",{"type":67,"tag":116,"props":268,"children":269},{"style":129},[270],{"type":72,"value":271},"=",{"type":67,"tag":116,"props":273,"children":275},{"style":274},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[276],{"type":72,"value":148},{"type":67,"tag":116,"props":278,"children":279},{"style":135},[280],{"type":72,"value":281},"(",{"type":67,"tag":116,"props":283,"children":284},{"style":129},[285],{"type":72,"value":286},"{",{"type":67,"tag":116,"props":288,"children":289},{"style":135},[290],{"type":72,"value":291}," cellSelectionFeature ",{"type":67,"tag":116,"props":293,"children":294},{"style":129},[295],{"type":72,"value":296},"}",{"type":67,"tag":116,"props":298,"children":299},{"style":135},[300],{"type":72,"value":301},")\n",{"type":67,"tag":116,"props":303,"children":305},{"class":118,"line":304},5,[306,310,314,319,323],{"type":67,"tag":116,"props":307,"children":308},{"style":123},[309],{"type":72,"value":256},{"type":67,"tag":116,"props":311,"children":312},{"style":190},[313],{"type":72,"value":261},{"type":67,"tag":116,"props":315,"children":316},{"style":135},[317],{"type":72,"value":318}," options ",{"type":67,"tag":116,"props":320,"children":321},{"style":129},[322],{"type":72,"value":271},{"type":67,"tag":116,"props":324,"children":325},{"style":129},[326],{"type":72,"value":327}," {\n",{"type":67,"tag":116,"props":329,"children":331},{"class":118,"line":330},6,[332,337,341,346,352,356,360,365,370,375,380,385],{"type":67,"tag":116,"props":333,"children":334},{"style":274},[335],{"type":72,"value":336},"  getRowId",{"type":67,"tag":116,"props":338,"children":339},{"style":129},[340],{"type":72,"value":219},{"type":67,"tag":116,"props":342,"children":343},{"style":129},[344],{"type":72,"value":345}," (",{"type":67,"tag":116,"props":347,"children":349},{"style":348},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic",[350],{"type":72,"value":351},"row",{"type":67,"tag":116,"props":353,"children":354},{"style":129},[355],{"type":72,"value":219},{"type":67,"tag":116,"props":357,"children":358},{"style":196},[359],{"type":72,"value":199},{"type":67,"tag":116,"props":361,"children":362},{"style":129},[363],{"type":72,"value":364},")",{"type":67,"tag":116,"props":366,"children":367},{"style":190},[368],{"type":72,"value":369}," =>",{"type":67,"tag":116,"props":371,"children":372},{"style":135},[373],{"type":72,"value":374}," row",{"type":67,"tag":116,"props":376,"children":377},{"style":129},[378],{"type":72,"value":379},".",{"type":67,"tag":116,"props":381,"children":382},{"style":135},[383],{"type":72,"value":384},"id",{"type":67,"tag":116,"props":386,"children":387},{"style":129},[388],{"type":72,"value":389},",\n",{"type":67,"tag":116,"props":391,"children":393},{"class":118,"line":392},7,[394],{"type":67,"tag":116,"props":395,"children":396},{"style":129},[397],{"type":72,"value":398},"}\n",{"type":67,"tag":68,"props":400,"children":401},{},[402],{"type":72,"value":403},"State shape:",{"type":67,"tag":105,"props":405,"children":407},{"className":107,"code":406,"language":109,"meta":110,"style":110},"type CellSelectionRange = {\n  anchorRowId: string\n  anchorColumnId: string\n  focusRowId: string\n  focusColumnId: string\n}\ntype CellSelectionState = Array\u003CCellSelectionRange>\n",[408],{"type":67,"tag":75,"props":409,"children":410},{"__ignoreMap":110},[411,431,448,464,480,496,503],{"type":67,"tag":116,"props":412,"children":413},{"class":118,"line":119},[414,418,423,427],{"type":67,"tag":116,"props":415,"children":416},{"style":190},[417],{"type":72,"value":193},{"type":67,"tag":116,"props":419,"children":420},{"style":196},[421],{"type":72,"value":422}," CellSelectionRange",{"type":67,"tag":116,"props":424,"children":425},{"style":129},[426],{"type":72,"value":204},{"type":67,"tag":116,"props":428,"children":429},{"style":129},[430],{"type":72,"value":327},{"type":67,"tag":116,"props":432,"children":433},{"class":118,"line":176},[434,439,443],{"type":67,"tag":116,"props":435,"children":436},{"style":211},[437],{"type":72,"value":438},"  anchorRowId",{"type":67,"tag":116,"props":440,"children":441},{"style":129},[442],{"type":72,"value":219},{"type":67,"tag":116,"props":444,"children":445},{"style":196},[446],{"type":72,"value":447}," string\n",{"type":67,"tag":116,"props":449,"children":450},{"class":118,"line":186},[451,456,460],{"type":67,"tag":116,"props":452,"children":453},{"style":211},[454],{"type":72,"value":455},"  anchorColumnId",{"type":67,"tag":116,"props":457,"children":458},{"style":129},[459],{"type":72,"value":219},{"type":67,"tag":116,"props":461,"children":462},{"style":196},[463],{"type":72,"value":447},{"type":67,"tag":116,"props":465,"children":466},{"class":118,"line":250},[467,472,476],{"type":67,"tag":116,"props":468,"children":469},{"style":211},[470],{"type":72,"value":471},"  focusRowId",{"type":67,"tag":116,"props":473,"children":474},{"style":129},[475],{"type":72,"value":219},{"type":67,"tag":116,"props":477,"children":478},{"style":196},[479],{"type":72,"value":447},{"type":67,"tag":116,"props":481,"children":482},{"class":118,"line":304},[483,488,492],{"type":67,"tag":116,"props":484,"children":485},{"style":211},[486],{"type":72,"value":487},"  focusColumnId",{"type":67,"tag":116,"props":489,"children":490},{"style":129},[491],{"type":72,"value":219},{"type":67,"tag":116,"props":493,"children":494},{"style":196},[495],{"type":72,"value":447},{"type":67,"tag":116,"props":497,"children":498},{"class":118,"line":330},[499],{"type":67,"tag":116,"props":500,"children":501},{"style":129},[502],{"type":72,"value":398},{"type":67,"tag":116,"props":504,"children":505},{"class":118,"line":392},[506,510,515,519,524,529,534],{"type":67,"tag":116,"props":507,"children":508},{"style":190},[509],{"type":72,"value":193},{"type":67,"tag":116,"props":511,"children":512},{"style":196},[513],{"type":72,"value":514}," CellSelectionState",{"type":67,"tag":116,"props":516,"children":517},{"style":129},[518],{"type":72,"value":204},{"type":67,"tag":116,"props":520,"children":521},{"style":196},[522],{"type":72,"value":523}," Array",{"type":67,"tag":116,"props":525,"children":526},{"style":129},[527],{"type":72,"value":528},"\u003C",{"type":67,"tag":116,"props":530,"children":531},{"style":196},[532],{"type":72,"value":533},"CellSelectionRange",{"type":67,"tag":116,"props":535,"children":536},{"style":129},[537],{"type":72,"value":538},">\n",{"type":67,"tag":68,"props":540,"children":541},{},[542,544,550,552,558],{"type":72,"value":543},"The ",{"type":67,"tag":75,"props":545,"children":547},{"className":546},[],[548],{"type":72,"value":549},"anchor",{"type":72,"value":551}," corner stays put; the ",{"type":67,"tag":75,"props":553,"children":555},{"className":554},[],[556],{"type":72,"value":557},"focus",{"type":72,"value":559}," corner moves during a drag or Shift-extend. Two corners are what make Shift-extend possible, and they keep a drag across thousands of cells to a two-field write.",{"type":67,"tag":98,"props":561,"children":563},{"id":562},"core-patterns",[564],{"type":72,"value":565},"Core Patterns",{"type":67,"tag":567,"props":568,"children":570},"h3",{"id":569},"bind-both-mouse-handlers",[571],{"type":72,"value":572},"Bind both mouse handlers",{"type":67,"tag":105,"props":574,"children":576},{"className":107,"code":575,"language":109,"meta":110,"style":110},"const onMouseDown = cell.getSelectionStartHandler()\nconst onMouseEnter = cell.getSelectionExtendHandler()\n",[577],{"type":67,"tag":75,"props":578,"children":579},{"__ignoreMap":110},[580,616],{"type":67,"tag":116,"props":581,"children":582},{"class":118,"line":119},[583,588,593,597,602,606,611],{"type":67,"tag":116,"props":584,"children":585},{"style":190},[586],{"type":72,"value":587},"const",{"type":67,"tag":116,"props":589,"children":590},{"style":135},[591],{"type":72,"value":592}," onMouseDown ",{"type":67,"tag":116,"props":594,"children":595},{"style":129},[596],{"type":72,"value":271},{"type":67,"tag":116,"props":598,"children":599},{"style":135},[600],{"type":72,"value":601}," cell",{"type":67,"tag":116,"props":603,"children":604},{"style":129},[605],{"type":72,"value":379},{"type":67,"tag":116,"props":607,"children":608},{"style":274},[609],{"type":72,"value":610},"getSelectionStartHandler",{"type":67,"tag":116,"props":612,"children":613},{"style":135},[614],{"type":72,"value":615},"()\n",{"type":67,"tag":116,"props":617,"children":618},{"class":118,"line":176},[619,623,628,632,636,640,645],{"type":67,"tag":116,"props":620,"children":621},{"style":190},[622],{"type":72,"value":587},{"type":67,"tag":116,"props":624,"children":625},{"style":135},[626],{"type":72,"value":627}," onMouseEnter ",{"type":67,"tag":116,"props":629,"children":630},{"style":129},[631],{"type":72,"value":271},{"type":67,"tag":116,"props":633,"children":634},{"style":135},[635],{"type":72,"value":601},{"type":67,"tag":116,"props":637,"children":638},{"style":129},[639],{"type":72,"value":379},{"type":67,"tag":116,"props":641,"children":642},{"style":274},[643],{"type":72,"value":644},"getSelectionExtendHandler",{"type":67,"tag":116,"props":646,"children":647},{"style":135},[648],{"type":72,"value":615},{"type":67,"tag":68,"props":650,"children":651},{},[652,654,660,662,668],{"type":72,"value":653},"The start handler attaches its own document-level ",{"type":67,"tag":75,"props":655,"children":657},{"className":656},[],[658],{"type":72,"value":659},"mouseup",{"type":72,"value":661}," listener and removes it when the drag ends, so a pointer released outside the table still finishes correctly. Pass a document explicitly (",{"type":67,"tag":75,"props":663,"children":665},{"className":664},[],[666],{"type":72,"value":667},"cell.getSelectionStartHandler(iframeDocument)",{"type":72,"value":669},") only when the table renders into another document.",{"type":67,"tag":567,"props":671,"children":673},{"id":672},"read-the-selection",[674],{"type":72,"value":675},"Read the selection",{"type":67,"tag":105,"props":677,"children":679},{"className":107,"code":678,"language":109,"meta":110,"style":110},"const count = table.getSelectedCellCount()\nconst grids = table.getSelectedCellRangesData() \u002F\u002F [range][row][column]\n",[680],{"type":67,"tag":75,"props":681,"children":682},{"__ignoreMap":110},[683,717],{"type":67,"tag":116,"props":684,"children":685},{"class":118,"line":119},[686,690,695,699,704,708,713],{"type":67,"tag":116,"props":687,"children":688},{"style":190},[689],{"type":72,"value":587},{"type":67,"tag":116,"props":691,"children":692},{"style":135},[693],{"type":72,"value":694}," count ",{"type":67,"tag":116,"props":696,"children":697},{"style":129},[698],{"type":72,"value":271},{"type":67,"tag":116,"props":700,"children":701},{"style":135},[702],{"type":72,"value":703}," table",{"type":67,"tag":116,"props":705,"children":706},{"style":129},[707],{"type":72,"value":379},{"type":67,"tag":116,"props":709,"children":710},{"style":274},[711],{"type":72,"value":712},"getSelectedCellCount",{"type":67,"tag":116,"props":714,"children":715},{"style":135},[716],{"type":72,"value":615},{"type":67,"tag":116,"props":718,"children":719},{"class":118,"line":176},[720,724,729,733,737,741,746,751],{"type":67,"tag":116,"props":721,"children":722},{"style":190},[723],{"type":72,"value":587},{"type":67,"tag":116,"props":725,"children":726},{"style":135},[727],{"type":72,"value":728}," grids ",{"type":67,"tag":116,"props":730,"children":731},{"style":129},[732],{"type":72,"value":271},{"type":67,"tag":116,"props":734,"children":735},{"style":135},[736],{"type":72,"value":703},{"type":67,"tag":116,"props":738,"children":739},{"style":129},[740],{"type":72,"value":379},{"type":67,"tag":116,"props":742,"children":743},{"style":274},[744],{"type":72,"value":745},"getSelectedCellRangesData",{"type":67,"tag":116,"props":747,"children":748},{"style":135},[749],{"type":72,"value":750},"() ",{"type":67,"tag":116,"props":752,"children":754},{"style":753},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[755],{"type":72,"value":756},"\u002F\u002F [range][row][column]\n",{"type":67,"tag":68,"props":758,"children":759},{},[760],{"type":72,"value":761},"Expansion APIs are memoized and pull-based, so a table that only highlights cells never pays to enumerate a large selection.",{"type":67,"tag":567,"props":763,"children":765},{"id":764},"draw-the-outline-from-edges",[766],{"type":72,"value":767},"Draw the outline from edges",{"type":67,"tag":68,"props":769,"children":770},{},[771,777,779,785,787,793],{"type":67,"tag":75,"props":772,"children":774},{"className":773},[],[775],{"type":72,"value":776},"cell.getSelectionEdges()",{"type":72,"value":778}," marks a side ",{"type":67,"tag":75,"props":780,"children":782},{"className":781},[],[783],{"type":72,"value":784},"true",{"type":72,"value":786}," when the neighbouring cell in that direction is not selected, which yields one continuous outline around a union of rectangles. All sides are ",{"type":67,"tag":75,"props":788,"children":790},{"className":789},[],[791],{"type":72,"value":792},"false",{"type":72,"value":794}," when the cell is not selected.",{"type":67,"tag":567,"props":796,"children":798},{"id":797},"drive-keyboard-navigation-externally",[799],{"type":72,"value":800},"Drive keyboard navigation externally",{"type":67,"tag":68,"props":802,"children":803},{},[804,806,812,814,820,821,827,828,834,836,842,844,850],{"type":72,"value":805},"The feature ships no keydown handling. Call ",{"type":67,"tag":75,"props":807,"children":809},{"className":808},[],[810],{"type":72,"value":811},"table.moveCellSelection(direction)",{"type":72,"value":813},", ",{"type":67,"tag":75,"props":815,"children":817},{"className":816},[],[818],{"type":72,"value":819},"table.extendCellSelection(direction)",{"type":72,"value":813},{"type":67,"tag":75,"props":822,"children":824},{"className":823},[],[825],{"type":72,"value":826},"table.setFocusedCell(rowId, columnId)",{"type":72,"value":813},{"type":67,"tag":75,"props":829,"children":831},{"className":830},[],[832],{"type":72,"value":833},"table.selectAllCells()",{"type":72,"value":835},", and ",{"type":67,"tag":75,"props":837,"children":839},{"className":838},[],[840],{"type":72,"value":841},"table.resetCellSelection(true)",{"type":72,"value":843}," from a hotkey library such as ",{"type":67,"tag":75,"props":845,"children":847},{"className":846},[],[848],{"type":72,"value":849},"@tanstack\u002Freact-hotkeys",{"type":72,"value":851},", scoped to the grid element rather than the document.",{"type":67,"tag":98,"props":853,"children":855},{"id":854},"common-mistakes",[856],{"type":72,"value":857},"Common Mistakes",{"type":67,"tag":567,"props":859,"children":861},{"id":860},"high-expecting-a-per-cell-selection-map",[862,867],{"type":67,"tag":116,"props":863,"children":864},{},[865],{"type":72,"value":866},"HIGH",{"type":72,"value":868}," Expecting a per-cell selection map",{"type":67,"tag":68,"props":870,"children":871},{},[872,874],{"type":72,"value":873},"Wrong: ",{"type":67,"tag":75,"props":875,"children":877},{"className":876},[],[878],{"type":72,"value":879},"const isSelected = table.state.cellSelection[cell.id]",{"type":67,"tag":68,"props":881,"children":882},{},[883,885],{"type":72,"value":884},"Correct: ",{"type":67,"tag":75,"props":886,"children":888},{"className":887},[],[889],{"type":72,"value":890},"const isSelected = cell.getIsSelected()",{"type":67,"tag":68,"props":892,"children":893},{},[894,899],{"type":67,"tag":75,"props":895,"children":897},{"className":896},[],[898],{"type":72,"value":94},{"type":72,"value":900}," holds rectangles, not cell keys. Membership is resolved by comparing the cell's row and column index against the memoized bounds.",{"type":67,"tag":68,"props":902,"children":903},{},[904,906],{"type":72,"value":905},"Source: ",{"type":67,"tag":75,"props":907,"children":909},{"className":908},[],[910],{"type":72,"value":911},"packages\u002Ftable-core\u002Fsrc\u002Ffeatures\u002Fcell-selection\u002FcellSelectionFeature.types.ts",{"type":67,"tag":567,"props":913,"children":915},{"id":914},"high-assuming-a-range-is-frozen-to-the-cells-it-originally-covered",[916,920],{"type":67,"tag":116,"props":917,"children":918},{},[919],{"type":72,"value":866},{"type":72,"value":921}," Assuming a range is frozen to the cells it originally covered",{"type":67,"tag":68,"props":923,"children":924},{},[925],{"type":72,"value":926},"Ranges are anchored to corner ids, so sorting, filtering, and column reordering keep the corners and recompute what sits between them. A range can therefore widen onto columns or rows the user never selected. Reset in userland when the product needs stricter behavior:",{"type":67,"tag":105,"props":928,"children":930},{"className":107,"code":929,"language":109,"meta":110,"style":110},"\u002F\u002F after a column reorder or pin\ntable.resetCellSelection(true)\n",[931],{"type":67,"tag":75,"props":932,"children":933},{"__ignoreMap":110},[934,942],{"type":67,"tag":116,"props":935,"children":936},{"class":118,"line":119},[937],{"type":67,"tag":116,"props":938,"children":939},{"style":753},[940],{"type":72,"value":941},"\u002F\u002F after a column reorder or pin\n",{"type":67,"tag":116,"props":943,"children":944},{"class":118,"line":176},[945,949,953,958,962,967],{"type":67,"tag":116,"props":946,"children":947},{"style":135},[948],{"type":72,"value":42},{"type":67,"tag":116,"props":950,"children":951},{"style":129},[952],{"type":72,"value":379},{"type":67,"tag":116,"props":954,"children":955},{"style":274},[956],{"type":72,"value":957},"resetCellSelection",{"type":67,"tag":116,"props":959,"children":960},{"style":135},[961],{"type":72,"value":281},{"type":67,"tag":116,"props":963,"children":965},{"style":964},"--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC",[966],{"type":72,"value":784},{"type":67,"tag":116,"props":968,"children":969},{"style":135},[970],{"type":72,"value":301},{"type":67,"tag":68,"props":972,"children":973},{},[974],{"type":72,"value":975},"Hiding a column that a corner sits on makes the range inert rather than deleting it; it returns when the column is shown again.",{"type":67,"tag":68,"props":977,"children":978},{},[979,980],{"type":72,"value":905},{"type":67,"tag":75,"props":981,"children":983},{"className":982},[],[984],{"type":72,"value":985},"docs\u002Fframework\u002Freact\u002Fguide\u002Fcell-selection.md#how-ranges-survive-table-changes",{"type":67,"tag":567,"props":987,"children":989},{"id":988},"high-binding-only-mousedown-and-expecting-drag",[990,994],{"type":67,"tag":116,"props":991,"children":992},{},[993],{"type":72,"value":866},{"type":72,"value":995}," Binding only mousedown and expecting drag",{"type":67,"tag":68,"props":997,"children":998},{},[999],{"type":72,"value":1000},"Wrong:",{"type":67,"tag":105,"props":1002,"children":1004},{"className":107,"code":1003,"language":109,"meta":110,"style":110},"const props = { onMouseDown: cell.getSelectionStartHandler() }\n",[1005],{"type":67,"tag":75,"props":1006,"children":1007},{"__ignoreMap":110},[1008],{"type":67,"tag":116,"props":1009,"children":1010},{"class":118,"line":119},[1011,1015,1020,1024,1028,1033,1037,1041,1045,1049,1053],{"type":67,"tag":116,"props":1012,"children":1013},{"style":190},[1014],{"type":72,"value":587},{"type":67,"tag":116,"props":1016,"children":1017},{"style":135},[1018],{"type":72,"value":1019}," props ",{"type":67,"tag":116,"props":1021,"children":1022},{"style":129},[1023],{"type":72,"value":271},{"type":67,"tag":116,"props":1025,"children":1026},{"style":129},[1027],{"type":72,"value":132},{"type":67,"tag":116,"props":1029,"children":1030},{"style":211},[1031],{"type":72,"value":1032}," onMouseDown",{"type":67,"tag":116,"props":1034,"children":1035},{"style":129},[1036],{"type":72,"value":219},{"type":67,"tag":116,"props":1038,"children":1039},{"style":135},[1040],{"type":72,"value":601},{"type":67,"tag":116,"props":1042,"children":1043},{"style":129},[1044],{"type":72,"value":379},{"type":67,"tag":116,"props":1046,"children":1047},{"style":274},[1048],{"type":72,"value":610},{"type":67,"tag":116,"props":1050,"children":1051},{"style":135},[1052],{"type":72,"value":750},{"type":67,"tag":116,"props":1054,"children":1055},{"style":129},[1056],{"type":72,"value":398},{"type":67,"tag":68,"props":1058,"children":1059},{},[1060],{"type":72,"value":1061},"Correct:",{"type":67,"tag":105,"props":1063,"children":1065},{"className":107,"code":1064,"language":109,"meta":110,"style":110},"const props = {\n  onMouseDown: cell.getSelectionStartHandler(),\n  onMouseEnter: cell.getSelectionExtendHandler(),\n}\n",[1066],{"type":67,"tag":75,"props":1067,"children":1068},{"__ignoreMap":110},[1069,1088,1121,1153],{"type":67,"tag":116,"props":1070,"children":1071},{"class":118,"line":119},[1072,1076,1080,1084],{"type":67,"tag":116,"props":1073,"children":1074},{"style":190},[1075],{"type":72,"value":587},{"type":67,"tag":116,"props":1077,"children":1078},{"style":135},[1079],{"type":72,"value":1019},{"type":67,"tag":116,"props":1081,"children":1082},{"style":129},[1083],{"type":72,"value":271},{"type":67,"tag":116,"props":1085,"children":1086},{"style":129},[1087],{"type":72,"value":327},{"type":67,"tag":116,"props":1089,"children":1090},{"class":118,"line":176},[1091,1096,1100,1104,1108,1112,1117],{"type":67,"tag":116,"props":1092,"children":1093},{"style":211},[1094],{"type":72,"value":1095},"  onMouseDown",{"type":67,"tag":116,"props":1097,"children":1098},{"style":129},[1099],{"type":72,"value":219},{"type":67,"tag":116,"props":1101,"children":1102},{"style":135},[1103],{"type":72,"value":601},{"type":67,"tag":116,"props":1105,"children":1106},{"style":129},[1107],{"type":72,"value":379},{"type":67,"tag":116,"props":1109,"children":1110},{"style":274},[1111],{"type":72,"value":610},{"type":67,"tag":116,"props":1113,"children":1114},{"style":135},[1115],{"type":72,"value":1116},"()",{"type":67,"tag":116,"props":1118,"children":1119},{"style":129},[1120],{"type":72,"value":389},{"type":67,"tag":116,"props":1122,"children":1123},{"class":118,"line":186},[1124,1129,1133,1137,1141,1145,1149],{"type":67,"tag":116,"props":1125,"children":1126},{"style":211},[1127],{"type":72,"value":1128},"  onMouseEnter",{"type":67,"tag":116,"props":1130,"children":1131},{"style":129},[1132],{"type":72,"value":219},{"type":67,"tag":116,"props":1134,"children":1135},{"style":135},[1136],{"type":72,"value":601},{"type":67,"tag":116,"props":1138,"children":1139},{"style":129},[1140],{"type":72,"value":379},{"type":67,"tag":116,"props":1142,"children":1143},{"style":274},[1144],{"type":72,"value":644},{"type":67,"tag":116,"props":1146,"children":1147},{"style":135},[1148],{"type":72,"value":1116},{"type":67,"tag":116,"props":1150,"children":1151},{"style":129},[1152],{"type":72,"value":389},{"type":67,"tag":116,"props":1154,"children":1155},{"class":118,"line":250},[1156],{"type":67,"tag":116,"props":1157,"children":1158},{"style":129},[1159],{"type":72,"value":398},{"type":67,"tag":68,"props":1161,"children":1162},{},[1163,1165,1170],{"type":72,"value":1164},"Without the extend handler a drag selects only the origin cell. Do not add a ",{"type":67,"tag":75,"props":1166,"children":1168},{"className":1167},[],[1169],{"type":72,"value":659},{"type":72,"value":1171}," binding; the start handler already owns one.",{"type":67,"tag":68,"props":1173,"children":1174},{},[1175,1176],{"type":72,"value":905},{"type":67,"tag":75,"props":1177,"children":1179},{"className":1178},[],[1180],{"type":72,"value":1181},"examples\u002Freact\u002Fcell-selection",{"type":67,"tag":567,"props":1183,"children":1185},{"id":1184},"high-deriving-column-position-from-column-definition-order",[1186,1190],{"type":67,"tag":116,"props":1187,"children":1188},{},[1189],{"type":72,"value":866},{"type":72,"value":1191}," Deriving column position from column definition order",{"type":67,"tag":68,"props":1193,"children":1194},{},[1195,1196],{"type":72,"value":873},{"type":67,"tag":75,"props":1197,"children":1199},{"className":1198},[],[1200],{"type":72,"value":1201},"const index = column.getIndex()",{"type":67,"tag":68,"props":1203,"children":1204},{},[1205,1206],{"type":72,"value":884},{"type":67,"tag":75,"props":1207,"children":1209},{"className":1208},[],[1210],{"type":72,"value":890},{"type":67,"tag":68,"props":1212,"children":1213},{},[1214,1216,1222,1223,1229],{"type":72,"value":1215},"Cells render start-pinned first, then center, then end. ",{"type":67,"tag":75,"props":1217,"children":1219},{"className":1218},[],[1220],{"type":72,"value":1221},"getVisibleLeafColumns()",{"type":72,"value":81},{"type":67,"tag":75,"props":1224,"children":1226},{"className":1225},[],[1227],{"type":72,"value":1228},"column.getIndex()",{"type":72,"value":1230}," are not pinning-reordered, so indexing a selection against them makes a rectangle visually scattered as soon as a column is pinned. The feature resolves its own render-order index map; use the cell APIs rather than recomputing membership.",{"type":67,"tag":68,"props":1232,"children":1233},{},[1234,1235],{"type":72,"value":905},{"type":67,"tag":75,"props":1236,"children":1238},{"className":1237},[],[1239],{"type":72,"value":1240},"packages\u002Ftable-core\u002Fsrc\u002Ffeatures\u002Fcell-selection\u002FcellSelectionFeature.utils.ts",{"type":67,"tag":567,"props":1242,"children":1244},{"id":1243},"high-re-rendering-every-cell-on-each-drag-update",[1245,1249],{"type":67,"tag":116,"props":1246,"children":1247},{},[1248],{"type":72,"value":866},{"type":72,"value":1250}," Re-rendering every cell on each drag update",{"type":67,"tag":68,"props":1252,"children":1253},{},[1254,1256,1262],{"type":72,"value":1255},"Wrong: one subscription wrapping the whole ",{"type":67,"tag":75,"props":1257,"children":1259},{"className":1258},[],[1260],{"type":72,"value":1261},"\u003Ctbody>",{"type":72,"value":379},{"type":67,"tag":68,"props":1264,"children":1265},{},[1266],{"type":72,"value":1267},"Correct: one subscription per row, with a selector returning only what changes that row's appearance.",{"type":67,"tag":68,"props":1269,"children":1270},{},[1271,1273,1279,1281,1287],{"type":72,"value":1272},"A drag writes state on every cell boundary crossed. A table-wide subscription reconciles every cell each time. Subscribe per row against ",{"type":67,"tag":75,"props":1274,"children":1276},{"className":1275},[],[1277],{"type":72,"value":1278},"table.atoms.cellSelection",{"type":72,"value":1280}," and derive a key from ",{"type":67,"tag":75,"props":1282,"children":1284},{"className":1283},[],[1285],{"type":72,"value":1286},"table.getCellSelectionBounds()",{"type":72,"value":1288}," (memoized, so it computes once per change) covering the row itself plus the rows above and below, which decide its top and bottom edges.",{"type":67,"tag":68,"props":1290,"children":1291},{},[1292,1293],{"type":72,"value":905},{"type":67,"tag":75,"props":1294,"children":1296},{"className":1295},[],[1297],{"type":72,"value":1298},"docs\u002Fframework\u002Freact\u002Fguide\u002Fcell-selection.md#performance-with-tablesubscribe",{"type":67,"tag":567,"props":1300,"children":1302},{"id":1301},"medium-drawing-selection-borders-on-a-border-collapse-table",[1303,1308],{"type":67,"tag":116,"props":1304,"children":1305},{},[1306],{"type":72,"value":1307},"MEDIUM",{"type":72,"value":1309}," Drawing selection borders on a border-collapse table",{"type":67,"tag":68,"props":1311,"children":1312},{},[1313,1314],{"type":72,"value":873},{"type":67,"tag":75,"props":1315,"children":1317},{"className":1316},[],[1318],{"type":72,"value":1319},".cell-selected { border: 2px solid blue }",{"type":67,"tag":68,"props":1321,"children":1322},{},[1323,1324],{"type":72,"value":884},{"type":67,"tag":75,"props":1325,"children":1327},{"className":1326},[],[1328],{"type":72,"value":1329},".cell-selected { box-shadow: inset 0 0 0 2px blue }",{"type":67,"tag":68,"props":1331,"children":1332},{},[1333,1335,1341],{"type":72,"value":1334},"On a ",{"type":67,"tag":75,"props":1336,"children":1338},{"className":1337},[],[1339],{"type":72,"value":1340},"border-collapse",{"type":72,"value":1342}," table a thicker border widens the shared grid line, so rows change height as cells become selected. Box-shadow never affects layout.",{"type":67,"tag":68,"props":1344,"children":1345},{},[1346,1347],{"type":72,"value":905},{"type":67,"tag":75,"props":1348,"children":1350},{"className":1349},[],[1351],{"type":72,"value":1352},"examples\u002Freact\u002Fcell-selection\u002Fsrc\u002Findex.css",{"type":67,"tag":567,"props":1354,"children":1356},{"id":1355},"medium-expecting-a-clipboard-string-from-the-table",[1357,1361],{"type":67,"tag":116,"props":1358,"children":1359},{},[1360],{"type":72,"value":1307},{"type":72,"value":1362}," Expecting a clipboard string from the table",{"type":67,"tag":68,"props":1364,"children":1365},{},[1366,1367],{"type":72,"value":873},{"type":67,"tag":75,"props":1368,"children":1370},{"className":1369},[],[1371],{"type":72,"value":1372},"navigator.clipboard.writeText(table.getSelectedCellsAsTsv())",{"type":67,"tag":68,"props":1374,"children":1375},{},[1376,1377],{"type":72,"value":884},{"type":67,"tag":75,"props":1378,"children":1380},{"className":1379},[],[1381],{"type":72,"value":1382},"navigator.clipboard.writeText(toTsv(table.getSelectedCellRangesData()))",{"type":67,"tag":68,"props":1384,"children":1385},{},[1386,1388,1394],{"type":72,"value":1387},"The table returns raw values only. The delimiter, the representation of ",{"type":67,"tag":75,"props":1389,"children":1391},{"className":1390},[],[1392],{"type":72,"value":1393},"null",{"type":72,"value":1395},", and quoting rules are application decisions, so serialization is userland. Quote any field containing a tab, newline, or quote, or a pasted spreadsheet gains phantom columns.",{"type":67,"tag":68,"props":1397,"children":1398},{},[1399,1400],{"type":72,"value":905},{"type":67,"tag":75,"props":1401,"children":1403},{"className":1402},[],[1404],{"type":72,"value":1405},"docs\u002Fframework\u002Freact\u002Fguide\u002Fcell-selection.md#copying-a-selection",{"type":67,"tag":567,"props":1407,"children":1409},{"id":1408},"medium-persisting-a-selection-and-expecting-drag-state-with-it",[1410,1414],{"type":67,"tag":116,"props":1411,"children":1412},{},[1413],{"type":72,"value":1307},{"type":72,"value":1415}," Persisting a selection and expecting drag state with it",{"type":67,"tag":68,"props":1417,"children":1418},{},[1419,1424,1426,1432,1434,1439],{"type":67,"tag":75,"props":1420,"children":1422},{"className":1421},[],[1423],{"type":72,"value":94},{"type":72,"value":1425}," is safe to persist because drag session state is deliberately non-reactive instance data, not part of the slice. Do not add an ",{"type":67,"tag":75,"props":1427,"children":1429},{"className":1428},[],[1430],{"type":72,"value":1431},"isSelecting",{"type":72,"value":1433}," field to the persisted state; a stored ",{"type":67,"tag":75,"props":1435,"children":1437},{"className":1436},[],[1438],{"type":72,"value":784},{"type":72,"value":1440}," would rehydrate into a drag that hovering extends and nothing ever ends.",{"type":67,"tag":68,"props":1442,"children":1443},{},[1444,1445],{"type":72,"value":905},{"type":67,"tag":75,"props":1446,"children":1448},{"className":1447},[],[1449],{"type":72,"value":911},{"type":67,"tag":567,"props":1451,"children":1453},{"id":1452},"medium-fighting-the-automatic-reset-on-data-change",[1454,1458],{"type":67,"tag":116,"props":1455,"children":1456},{},[1457],{"type":72,"value":1307},{"type":72,"value":1459}," Fighting the automatic reset on data change",{"type":67,"tag":68,"props":1461,"children":1462},{},[1463,1465,1471,1473,1479],{"type":72,"value":1464},"Selection resets to ",{"type":67,"tag":75,"props":1466,"children":1468},{"className":1467},[],[1469],{"type":72,"value":1470},"initialState.cellSelection",{"type":72,"value":1472}," whenever ",{"type":67,"tag":75,"props":1474,"children":1476},{"className":1475},[],[1477],{"type":72,"value":1478},"data",{"type":72,"value":1480}," changes, because new data can invalidate the row ids a range points at or silently re-select cells when ids are reused. Opt out deliberately:",{"type":67,"tag":105,"props":1482,"children":1484},{"className":107,"code":1483,"language":109,"meta":110,"style":110},"export const keepAcrossDataChanges = { autoResetCellSelection: false }\n",[1485],{"type":67,"tag":75,"props":1486,"children":1487},{"__ignoreMap":110},[1488],{"type":67,"tag":116,"props":1489,"children":1490},{"class":118,"line":119},[1491,1495,1499,1504,1508,1512,1517,1521,1526],{"type":67,"tag":116,"props":1492,"children":1493},{"style":123},[1494],{"type":72,"value":256},{"type":67,"tag":116,"props":1496,"children":1497},{"style":190},[1498],{"type":72,"value":261},{"type":67,"tag":116,"props":1500,"children":1501},{"style":135},[1502],{"type":72,"value":1503}," keepAcrossDataChanges ",{"type":67,"tag":116,"props":1505,"children":1506},{"style":129},[1507],{"type":72,"value":271},{"type":67,"tag":116,"props":1509,"children":1510},{"style":129},[1511],{"type":72,"value":132},{"type":67,"tag":116,"props":1513,"children":1514},{"style":211},[1515],{"type":72,"value":1516}," autoResetCellSelection",{"type":67,"tag":116,"props":1518,"children":1519},{"style":129},[1520],{"type":72,"value":219},{"type":67,"tag":116,"props":1522,"children":1523},{"style":964},[1524],{"type":72,"value":1525}," false",{"type":67,"tag":116,"props":1527,"children":1528},{"style":129},[1529],{"type":72,"value":247},{"type":67,"tag":68,"props":1531,"children":1532},{},[1533,1539],{"type":67,"tag":75,"props":1534,"children":1536},{"className":1535},[],[1537],{"type":72,"value":1538},"autoResetAll",{"type":72,"value":1540}," overrides this option.",{"type":67,"tag":68,"props":1542,"children":1543},{},[1544,1545],{"type":72,"value":905},{"type":67,"tag":75,"props":1546,"children":1548},{"className":1547},[],[1549],{"type":72,"value":1550},"packages\u002Ftable-core\u002Fsrc\u002Ffeatures\u002Fcell-selection\u002FcellSelectionFeature.ts",{"type":67,"tag":98,"props":1552,"children":1554},{"id":1553},"api-discovery",[1555],{"type":72,"value":1556},"API Discovery",{"type":67,"tag":68,"props":1558,"children":1559},{},[1560,1562,1568,1570,1575,1576,1582,1583,1589,1590,1596,1598,1604],{"type":72,"value":1561},"Inspect ",{"type":67,"tag":75,"props":1563,"children":1565},{"className":1564},[],[1566],{"type":72,"value":1567},"node_modules\u002F@tanstack\u002Ftable-core\u002Fdist\u002Ffeatures\u002Fcell-selection\u002F",{"type":72,"value":1569}," for ",{"type":67,"tag":75,"props":1571,"children":1573},{"className":1572},[],[1574],{"type":72,"value":533},{"type":72,"value":813},{"type":67,"tag":75,"props":1577,"children":1579},{"className":1578},[],[1580],{"type":72,"value":1581},"CellSelectionState",{"type":72,"value":813},{"type":67,"tag":75,"props":1584,"children":1586},{"className":1585},[],[1587],{"type":72,"value":1588},"CellSelectionBounds",{"type":72,"value":813},{"type":67,"tag":75,"props":1591,"children":1593},{"className":1592},[],[1594],{"type":72,"value":1595},"CellSelectionEdges",{"type":72,"value":1597},", the enablement and ",{"type":67,"tag":75,"props":1599,"children":1601},{"className":1600},[],[1602],{"type":72,"value":1603},"is*Event",{"type":72,"value":1605}," options, and the cell and table instance APIs.",{"type":67,"tag":1607,"props":1608,"children":1609},"style",{},[1610],{"type":72,"value":1611},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":1613,"total":1691},[1614,1626,1638,1644,1659,1671,1681],{"slug":1615,"name":1615,"fn":1616,"description":1617,"org":1618,"tags":1619,"stars":20,"repoUrl":21,"updatedAt":1625},"aggregation","perform data aggregation in TanStack Table","Aggregate TanStack Table columns independently of grouping, including grand totals, caller-selected row totals, multiple keyed aggregations, custom context-based definitions, grouped merges, manual values, and worker constraints.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1620,1621,1624],{"name":13,"slug":14,"type":15},{"name":1622,"slug":1623,"type":15},"Frontend","frontend",{"name":9,"slug":8,"type":15},"2026-07-30T05:25:59.429787",{"slug":1627,"name":1627,"fn":1628,"description":1629,"org":1630,"tags":1631,"stars":20,"repoUrl":21,"updatedAt":1637},"api-not-found","diagnose TanStack Table API errors","Diagnose missing TanStack Table v9 exports, options, state slices, and instance methods. Load before inventing an API when code sees a type error, undefined feature method, absent object key, adapter mismatch, or v8-shaped example.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1632,1635,1636],{"name":1633,"slug":1634,"type":15},"Debugging","debugging",{"name":1622,"slug":1623,"type":15},{"name":9,"slug":8,"type":15},"2026-07-30T05:26:05.418735",{"slug":4,"name":4,"fn":5,"description":6,"org":1639,"tags":1640,"stars":20,"repoUrl":21,"updatedAt":22},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1641,1642,1643],{"name":13,"slug":14,"type":15},{"name":9,"slug":8,"type":15},{"name":17,"slug":18,"type":15},{"slug":1645,"name":1645,"fn":1646,"description":1647,"org":1648,"tags":1649,"stars":20,"repoUrl":21,"updatedAt":1658},"client-vs-server","manage TanStack Table data pipelines","Choose client or server ownership for filtering, grouping, sorting, expanding, and pagination in TanStack Table v9. Load for manual* flags, mixed pipelines, server counts, or deciding which dataset each row-model stage receives.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1650,1653,1654,1657],{"name":1651,"slug":1652,"type":15},"Data Pipeline","data-pipeline",{"name":1622,"slug":1623,"type":15},{"name":1655,"slug":1656,"type":15},"Performance","performance",{"name":9,"slug":8,"type":15},"2026-07-30T05:25:45.400104",{"slug":1660,"name":1660,"fn":1661,"description":1662,"org":1663,"tags":1664,"stars":20,"repoUrl":21,"updatedAt":1670},"column-faceting","build faceted filter UIs","Build faceted filter UIs with columnFacetingFeature, facetedRowModel, facetedUniqueValues, and facetedMinMaxValues. Load for facet counts, numeric ranges, own-filter exclusion, or server-page facet completeness.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1665,1668,1669],{"name":1666,"slug":1667,"type":15},"Data Visualization","data-visualization",{"name":1622,"slug":1623,"type":15},{"name":9,"slug":8,"type":15},"2026-07-30T05:25:41.397257",{"slug":1672,"name":1672,"fn":1673,"description":1674,"org":1675,"tags":1676,"stars":20,"repoUrl":21,"updatedAt":1680},"column-filtering","implement column filtering in TanStack Table","Filter columns with columnFilteringFeature, filteredRowModel, filterFns, filterMeta, nested-row direction, and manualFiltering. Load for accessor compatibility, controlled filter updaters, fuzzy metadata, or client\u002Fserver ownership.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1677,1678,1679],{"name":13,"slug":14,"type":15},{"name":1622,"slug":1623,"type":15},{"name":9,"slug":8,"type":15},"2026-07-30T05:25:53.391632",{"slug":1682,"name":1682,"fn":1683,"description":1684,"org":1685,"tags":1686,"stars":20,"repoUrl":21,"updatedAt":1690},"column-ordering","manage TanStack Table column ordering","Control TanStack Table v9 leaf columnOrder with stable IDs while accounting for pinning regions, visibility, and groupedColumnMode precedence. Load for drag-and-drop columns or rendered order that differs from state.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1687,1688,1689],{"name":1622,"slug":1623,"type":15},{"name":9,"slug":8,"type":15},{"name":17,"slug":18,"type":15},"2026-07-30T05:26:03.37801",30,{"items":1693,"total":1790},[1694,1700,1706,1712,1719,1725,1731,1737,1750,1760,1771,1781],{"slug":1615,"name":1615,"fn":1616,"description":1617,"org":1695,"tags":1696,"stars":20,"repoUrl":21,"updatedAt":1625},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1697,1698,1699],{"name":13,"slug":14,"type":15},{"name":1622,"slug":1623,"type":15},{"name":9,"slug":8,"type":15},{"slug":1627,"name":1627,"fn":1628,"description":1629,"org":1701,"tags":1702,"stars":20,"repoUrl":21,"updatedAt":1637},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1703,1704,1705],{"name":1633,"slug":1634,"type":15},{"name":1622,"slug":1623,"type":15},{"name":9,"slug":8,"type":15},{"slug":4,"name":4,"fn":5,"description":6,"org":1707,"tags":1708,"stars":20,"repoUrl":21,"updatedAt":22},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1709,1710,1711],{"name":13,"slug":14,"type":15},{"name":9,"slug":8,"type":15},{"name":17,"slug":18,"type":15},{"slug":1645,"name":1645,"fn":1646,"description":1647,"org":1713,"tags":1714,"stars":20,"repoUrl":21,"updatedAt":1658},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1715,1716,1717,1718],{"name":1651,"slug":1652,"type":15},{"name":1622,"slug":1623,"type":15},{"name":1655,"slug":1656,"type":15},{"name":9,"slug":8,"type":15},{"slug":1660,"name":1660,"fn":1661,"description":1662,"org":1720,"tags":1721,"stars":20,"repoUrl":21,"updatedAt":1670},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1722,1723,1724],{"name":1666,"slug":1667,"type":15},{"name":1622,"slug":1623,"type":15},{"name":9,"slug":8,"type":15},{"slug":1672,"name":1672,"fn":1673,"description":1674,"org":1726,"tags":1727,"stars":20,"repoUrl":21,"updatedAt":1680},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1728,1729,1730],{"name":13,"slug":14,"type":15},{"name":1622,"slug":1623,"type":15},{"name":9,"slug":8,"type":15},{"slug":1682,"name":1682,"fn":1683,"description":1684,"org":1732,"tags":1733,"stars":20,"repoUrl":21,"updatedAt":1690},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1734,1735,1736],{"name":1622,"slug":1623,"type":15},{"name":9,"slug":8,"type":15},{"name":17,"slug":18,"type":15},{"slug":1738,"name":1738,"fn":1739,"description":1740,"org":1741,"tags":1742,"stars":20,"repoUrl":21,"updatedAt":1749},"column-pinning","configure column pinning in TanStack Table","Pin columns into logical start, center, and end regions with columnPinningFeature and renderer-owned sticky CSS. Load for RTL offsets, z-index, backgrounds, overflow, widths, gaps, or overlaps.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1743,1746,1747,1748],{"name":1744,"slug":1745,"type":15},"CSS","css",{"name":1622,"slug":1623,"type":15},{"name":9,"slug":8,"type":15},{"name":17,"slug":18,"type":15},"2026-07-30T05:25:55.377366",{"slug":1751,"name":1751,"fn":1752,"description":1753,"org":1754,"tags":1755,"stars":20,"repoUrl":21,"updatedAt":1759},"column-resizing","implement column resizing in TanStack Table","Wire columnResizingFeature, header.getResizeHandler, resize mode and direction, pointer or touch events, and performant CSS-variable updates. Load when resize state changes but widths do not, or large tables resize slowly.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1756,1757,1758],{"name":1622,"slug":1623,"type":15},{"name":9,"slug":8,"type":15},{"name":17,"slug":18,"type":15},"2026-07-30T05:25:51.400011",{"slug":1761,"name":1761,"fn":1762,"description":1763,"org":1764,"tags":1765,"stars":20,"repoUrl":21,"updatedAt":1770},"column-sizing","configure column sizing in TanStack Table","Use columnSizingFeature numeric size, minSize, maxSize, getSize, getStart, getAfter, and total-size APIs in table, grid, or flex CSS. Load for auto or percentage misconceptions and sizing\u002Fpinning layout mismatch.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1766,1767,1768,1769],{"name":1744,"slug":1745,"type":15},{"name":1622,"slug":1623,"type":15},{"name":9,"slug":8,"type":15},{"name":17,"slug":18,"type":15},"2026-07-30T05:25:48.703799",{"slug":1772,"name":1772,"fn":1773,"description":1774,"org":1775,"tags":1776,"stars":20,"repoUrl":21,"updatedAt":1780},"column-visibility","manage column visibility in TanStack Table","Hide columns with columnVisibilityFeature while rendering visibility-aware header, column, and cell collections. Load when hidden columns remain in the DOM, false-versus-absent state is confused, or enableHiding is misunderstood.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1777,1778,1779],{"name":1622,"slug":1623,"type":15},{"name":9,"slug":8,"type":15},{"name":17,"slug":18,"type":15},"2026-07-30T05:25:47.367943",{"slug":57,"name":57,"fn":1782,"description":1783,"org":1784,"tags":1785,"stars":20,"repoUrl":21,"updatedAt":1789},"build data grids with TanStack Table","Use TanStack Table v9 as a headless data-grid state and row-processing engine. Load for first-table architecture, stable data and columns, row numbering with getDisplayIndex, semantic rendering, framework adapter choice, or deciding what Table owns versus the renderer.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1786,1787,1788],{"name":13,"slug":14,"type":15},{"name":1622,"slug":1623,"type":15},{"name":17,"slug":18,"type":15},"2026-07-30T05:25:52.366295",125]