Skip to content

Commit 6415183

Browse files
authored
feat: cell selection feature (TanStack#6455)
* feat: cell selection feature * pr feedback and fix svelte loop * fix test
1 parent 21538a6 commit 6415183

279 files changed

Lines changed: 20233 additions & 268 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

_artifacts/domain_map.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,23 @@ skills:
528528
- 'Expecting row pinning to add sticky CSS or render top/center/bottom collections in the correct order automatically.'
529529
- 'Ignoring keepPinnedRows, so pinned rows remain visible outside the center row model when the desired product behavior was to filter or paginate them away.'
530530

531+
- slug: cell-selection
532+
package: '@tanstack/table-core'
533+
domain: feature-plugins
534+
type: feature
535+
purpose: 'Maintain spreadsheet-style rectangular cell ranges anchored to row and column ids across sorting, filtering, pagination, and column layout changes.'
536+
sources:
537+
[
538+
'TanStack/table:docs/framework/react/guide/cell-selection.md',
539+
'TanStack/table:packages/table-core/src/features/cell-selection',
540+
'TanStack/table:examples/react/cell-selection',
541+
]
542+
failure_modes:
543+
- 'Expecting cellSelection to be a per-cell map; it is an array of two-corner rectangles, so a range widens onto new cells when sorting or column order changes what sits between its corners.'
544+
- 'Binding only the mousedown handler and expecting drag selection, or reimplementing mouseup even though the start handler owns its own document listener.'
545+
- 'Drawing the selection outline with borders on a border-collapse table, which changes row heights as cells become selected.'
546+
- 'Re-rendering every cell on each drag update instead of subscribing per row to table.atoms.cellSelection.'
547+
531548
- slug: row-selection
532549
package: '@tanstack/table-core'
533550
domain: feature-plugins

_artifacts/skill_tree.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,19 @@ skills:
291291
- 'TanStack/table:packages/table-core/src/features/row-pinning'
292292
- 'TanStack/table:examples/react/row-pinning'
293293

294+
- name: 'Cell Selection'
295+
slug: cell-selection
296+
type: sub-skill
297+
domain: feature-plugins
298+
path: 'packages/table-core/skills/cell-selection/SKILL.md'
299+
package: 'packages/table-core'
300+
description: 'Select rectangular cell ranges with cellSelectionFeature: two-corner range state, drag and Shift and Ctrl handlers, selection edges, and render-order resolution under pinning. Load when ranges widen unexpectedly after sorting or reordering, or when drag re-renders the whole table.'
301+
requires: ['core', 'table-features']
302+
sources:
303+
- 'TanStack/table:docs/framework/react/guide/cell-selection.md'
304+
- 'TanStack/table:packages/table-core/src/features/cell-selection'
305+
- 'TanStack/table:examples/react/cell-selection'
306+
294307
- name: 'Row Selection'
295308
slug: row-selection
296309
type: sub-skill

docs/config.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@
201201
{
202202
"label": "alpine",
203203
"children": [
204+
{ "label": "Cell Selection", "to": "framework/alpine/guide/cell-selection" },
204205
{ "label": "Column Ordering", "to": "framework/alpine/guide/column-ordering" },
205206
{ "label": "Column Pinning", "to": "framework/alpine/guide/column-pinning" },
206207
{ "label": "Column Sizing", "to": "framework/alpine/guide/column-sizing" },
@@ -222,6 +223,7 @@
222223
{
223224
"label": "angular",
224225
"children": [
226+
{ "label": "Cell Selection", "to": "framework/angular/guide/cell-selection" },
225227
{ "label": "Column Ordering", "to": "framework/angular/guide/column-ordering" },
226228
{ "label": "Column Pinning", "to": "framework/angular/guide/column-pinning" },
227229
{ "label": "Column Sizing", "to": "framework/angular/guide/column-sizing" },
@@ -244,6 +246,7 @@
244246
{
245247
"label": "ember",
246248
"children": [
249+
{ "label": "Cell Selection", "to": "framework/ember/guide/cell-selection" },
247250
{ "label": "Column Ordering", "to": "framework/ember/guide/column-ordering" },
248251
{ "label": "Column Pinning", "to": "framework/ember/guide/column-pinning" },
249252
{ "label": "Column Sizing", "to": "framework/ember/guide/column-sizing" },
@@ -265,6 +268,7 @@
265268
{
266269
"label": "lit",
267270
"children": [
271+
{ "label": "Cell Selection", "to": "framework/lit/guide/cell-selection" },
268272
{ "label": "Column Ordering", "to": "framework/lit/guide/column-ordering" },
269273
{ "label": "Column Pinning", "to": "framework/lit/guide/column-pinning" },
270274
{ "label": "Column Sizing", "to": "framework/lit/guide/column-sizing" },
@@ -287,6 +291,7 @@
287291
{
288292
"label": "react",
289293
"children": [
294+
{ "label": "Cell Selection", "to": "framework/react/guide/cell-selection" },
290295
{ "label": "Column Ordering", "to": "framework/react/guide/column-ordering" },
291296
{ "label": "Column Pinning", "to": "framework/react/guide/column-pinning" },
292297
{ "label": "Column Sizing", "to": "framework/react/guide/column-sizing" },
@@ -309,6 +314,7 @@
309314
{
310315
"label": "preact",
311316
"children": [
317+
{ "label": "Cell Selection", "to": "framework/preact/guide/cell-selection" },
312318
{ "label": "Column Ordering", "to": "framework/preact/guide/column-ordering" },
313319
{ "label": "Column Pinning", "to": "framework/preact/guide/column-pinning" },
314320
{ "label": "Column Sizing", "to": "framework/preact/guide/column-sizing" },
@@ -331,6 +337,7 @@
331337
{
332338
"label": "solid",
333339
"children": [
340+
{ "label": "Cell Selection", "to": "framework/solid/guide/cell-selection" },
334341
{ "label": "Column Ordering", "to": "framework/solid/guide/column-ordering" },
335342
{ "label": "Column Pinning", "to": "framework/solid/guide/column-pinning" },
336343
{ "label": "Column Sizing", "to": "framework/solid/guide/column-sizing" },
@@ -353,6 +360,7 @@
353360
{
354361
"label": "svelte",
355362
"children": [
363+
{ "label": "Cell Selection", "to": "framework/svelte/guide/cell-selection" },
356364
{ "label": "Column Ordering", "to": "framework/svelte/guide/column-ordering" },
357365
{ "label": "Column Pinning", "to": "framework/svelte/guide/column-pinning" },
358366
{ "label": "Column Sizing", "to": "framework/svelte/guide/column-sizing" },
@@ -375,6 +383,7 @@
375383
{
376384
"label": "vue",
377385
"children": [
386+
{ "label": "Cell Selection", "to": "framework/vue/guide/cell-selection" },
378387
{ "label": "Column Ordering", "to": "framework/vue/guide/column-ordering" },
379388
{ "label": "Column Pinning", "to": "framework/vue/guide/column-pinning" },
380389
{ "label": "Column Sizing", "to": "framework/vue/guide/column-sizing" },
@@ -1060,6 +1069,7 @@
10601069
{
10611070
"label": "alpine",
10621071
"children": [
1072+
{ "to": "framework/alpine/examples/cell-selection", "label": "Cell Selection" },
10631073
{ "to": "framework/alpine/examples/filters", "label": "Column Filters" },
10641074
{ "to": "framework/alpine/examples/filters-faceted", "label": "Column Filters (Faceted)" },
10651075
{ "to": "framework/alpine/examples/filters-faceted-bucketed", "label": "Bucketed Faceted Filters" },
@@ -1087,6 +1097,7 @@
10871097
"label": "angular",
10881098
"children": [
10891099
{ "label": "Kitchen Sink (All Features)", "to": "framework/angular/examples/kitchen-sink" },
1100+
{ "label": "Cell Selection", "to": "framework/angular/examples/cell-selection" },
10901101
{ "label": "Column Filters", "to": "framework/angular/examples/filters" },
10911102
{ "label": "Column Filters (Faceted)", "to": "framework/angular/examples/filters-faceted" },
10921103
{ "label": "Bucketed Faceted Filters", "to": "framework/angular/examples/filters-faceted-bucketed" },
@@ -1114,6 +1125,7 @@
11141125
"label": "ember",
11151126
"children": [
11161127
{ "label": "Kitchen Sink (All Features)", "to": "framework/ember/examples/kitchen-sink" },
1128+
{ "label": "Cell Selection", "to": "framework/ember/examples/cell-selection" },
11171129
{ "label": "Column Filters", "to": "framework/ember/examples/filters" },
11181130
{ "label": "Column Filters (Faceted)", "to": "framework/ember/examples/filters-faceted" },
11191131
{ "label": "Bucketed Faceted Filters", "to": "framework/ember/examples/filters-faceted-bucketed" },
@@ -1141,6 +1153,7 @@
11411153
"label": "lit",
11421154
"children": [
11431155
{ "label": "Kitchen Sink (All Features)", "to": "framework/lit/examples/kitchen-sink" },
1156+
{ "label": "Cell Selection", "to": "framework/lit/examples/cell-selection" },
11441157
{ "label": "Column Filters", "to": "framework/lit/examples/filters" },
11451158
{ "label": "Column Filters (Faceted)", "to": "framework/lit/examples/filters-faceted" },
11461159
{ "label": "Bucketed Faceted Filters", "to": "framework/lit/examples/filters-faceted-bucketed" },
@@ -1169,6 +1182,7 @@
11691182
"label": "react",
11701183
"children": [
11711184
{ "label": "Kitchen Sink (All Features)", "to": "framework/react/examples/kitchen-sink" },
1185+
{ "label": "Cell Selection", "to": "framework/react/examples/cell-selection" },
11721186
{ "label": "Column Filters", "to": "framework/react/examples/filters" },
11731187
{ "label": "Column Filters (Faceted)", "to": "framework/react/examples/filters-faceted" },
11741188
{ "label": "Bucketed Faceted Filters", "to": "framework/react/examples/filters-faceted-bucketed" },
@@ -1198,6 +1212,7 @@
11981212
"label": "solid",
11991213
"children": [
12001214
{ "label": "Kitchen Sink (All Features)", "to": "framework/solid/examples/kitchen-sink" },
1215+
{ "label": "Cell Selection", "to": "framework/solid/examples/cell-selection" },
12011216
{ "label": "Column Filters", "to": "framework/solid/examples/filters" },
12021217
{ "label": "Column Filters (Faceted)", "to": "framework/solid/examples/filters-faceted" },
12031218
{ "label": "Bucketed Faceted Filters", "to": "framework/solid/examples/filters-faceted-bucketed" },
@@ -1225,6 +1240,7 @@
12251240
"label": "svelte",
12261241
"children": [
12271242
{ "label": "Kitchen Sink (All Features)", "to": "framework/svelte/examples/kitchen-sink" },
1243+
{ "label": "Cell Selection", "to": "framework/svelte/examples/cell-selection" },
12281244
{ "label": "Column Filters", "to": "framework/svelte/examples/filtering" },
12291245
{ "label": "Column Filters (Faceted)", "to": "framework/svelte/examples/filters-faceted" },
12301246
{ "label": "Bucketed Faceted Filters", "to": "framework/svelte/examples/filters-faceted-bucketed" },
@@ -1252,6 +1268,7 @@
12521268
"label": "vue",
12531269
"children": [
12541270
{ "label": "Kitchen Sink (All Features)", "to": "framework/vue/examples/kitchen-sink" },
1271+
{ "label": "Cell Selection", "to": "framework/vue/examples/cell-selection" },
12551272
{ "label": "Column Filters", "to": "framework/vue/examples/filters" },
12561273
{ "label": "Column Filters (Faceted)", "to": "framework/vue/examples/filters-faceted" },
12571274
{ "label": "Bucketed Faceted Filters", "to": "framework/vue/examples/filters-faceted-bucketed" },
@@ -1279,6 +1296,7 @@
12791296
"label": "preact",
12801297
"children": [
12811298
{ "label": "Kitchen Sink (All Features)", "to": "framework/preact/examples/kitchen-sink" },
1299+
{ "label": "Cell Selection", "to": "framework/preact/examples/cell-selection" },
12821300
{ "label": "Column Filters", "to": "framework/preact/examples/filters" },
12831301
{ "label": "Column Filters (Faceted)", "to": "framework/preact/examples/filters-faceted" },
12841302
{ "label": "Bucketed Faceted Filters", "to": "framework/preact/examples/filters-faceted-bucketed" },

0 commit comments

Comments
 (0)