@tanstack/ember-table 9.2.5 → 9.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/ember-table",
|
|
3
|
-
"version": "9.2.
|
|
3
|
+
"version": "9.2.6",
|
|
4
4
|
"description": "Headless UI for building powerful tables & datagrids for Ember.",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@embroider/addon-shim": "^1.10.3",
|
|
60
60
|
"@tanstack/store": "^0.11.2",
|
|
61
|
-
"@tanstack/table-core": "9.2.
|
|
61
|
+
"@tanstack/table-core": "9.2.6",
|
|
62
62
|
"decorator-transforms": "2.4.0"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
@@ -1,36 +1,37 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: getting-started
|
|
3
|
-
description:
|
|
4
|
-
Create
|
|
3
|
+
description:
|
|
4
|
+
Create and render Table v9 with the ember adapter. Route reusable createTableHook
|
|
5
|
+
defaults, and framework setup; use table-state for reactive ownership.
|
|
5
6
|
metadata:
|
|
6
7
|
type: framework
|
|
7
8
|
library: '@tanstack/ember-table'
|
|
8
9
|
framework: ember
|
|
9
|
-
library_version: '9.2.
|
|
10
|
+
library_version: '9.2.6'
|
|
10
11
|
requires:
|
|
11
12
|
- '@tanstack/table-core#core'
|
|
12
|
-
- '@tanstack/table-core#table-features'
|
|
13
13
|
sources:
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
14
|
+
- TanStack/table:docs/framework/ember/quick-start.md
|
|
15
|
+
- TanStack/table:examples/ember/basic-table
|
|
16
|
+
- TanStack/table:packages/ember-table/src/index.ts
|
|
17
|
+
- TanStack/table:packages/ember-table/src/use-table.ts
|
|
18
|
+
- TanStack/table:packages/ember-table/src/FlexRender.gts
|
|
19
|
+
- TanStack/table:docs/framework/ember/guide/composable-tables.md
|
|
20
|
+
- TanStack/table:examples/ember/basic-app-table
|
|
21
|
+
- TanStack/table:packages/ember-table/src/create-table-hook.ts
|
|
19
22
|
---
|
|
20
23
|
|
|
21
|
-
|
|
24
|
+
Load `intent load @tanstack/table-core#core` first for the headless model, stable inputs, and column inference.
|
|
22
25
|
|
|
23
|
-
|
|
26
|
+
Ember 5.8 or newer requires Embroider or ember-auto-import v2. Prefer `.gts` or `.gjs` template-tag components with Glint.
|
|
24
27
|
|
|
25
28
|
## Setup
|
|
26
29
|
|
|
27
30
|
```gts
|
|
28
31
|
import Component from '@glimmer/component'
|
|
29
32
|
import { tracked } from '@glimmer/tracking'
|
|
30
|
-
import { on } from '@ember/modifier'
|
|
31
33
|
import {
|
|
32
34
|
FlexRenderCell,
|
|
33
|
-
FlexRenderHeader,
|
|
34
35
|
createColumnHelper,
|
|
35
36
|
tableFeatures,
|
|
36
37
|
useTable,
|
|
@@ -55,41 +56,19 @@ const getAllCells = (
|
|
|
55
56
|
export default class PeopleTable extends Component {
|
|
56
57
|
@tracked data = initialData
|
|
57
58
|
|
|
58
|
-
table = useTable(() => ({
|
|
59
|
+
table = useTable(this, () => ({
|
|
59
60
|
features,
|
|
60
61
|
columns,
|
|
61
62
|
data: this.data,
|
|
62
63
|
getRowId,
|
|
63
64
|
}))
|
|
64
65
|
|
|
65
|
-
get headerGroups() {
|
|
66
|
-
return this.table.getHeaderGroups()
|
|
67
|
-
}
|
|
68
|
-
|
|
69
66
|
get rows() {
|
|
70
67
|
return this.table.getRowModel().rows
|
|
71
68
|
}
|
|
72
69
|
|
|
73
|
-
addPerson = () => {
|
|
74
|
-
this.data = [...this.data, { id: '2', name: 'Grace' }]
|
|
75
|
-
}
|
|
76
|
-
|
|
77
70
|
<template>
|
|
78
|
-
<button type='button' {{on 'click' this.addPerson}}>Add person</button>
|
|
79
71
|
<table>
|
|
80
|
-
<thead>
|
|
81
|
-
{{#each this.headerGroups as |group|}}
|
|
82
|
-
<tr>
|
|
83
|
-
{{#each group.headers as |header|}}
|
|
84
|
-
<th colspan={{header.colSpan}}>
|
|
85
|
-
{{#unless header.isPlaceholder}}
|
|
86
|
-
<FlexRenderHeader @header={{header}} />
|
|
87
|
-
{{/unless}}
|
|
88
|
-
</th>
|
|
89
|
-
{{/each}}
|
|
90
|
-
</tr>
|
|
91
|
-
{{/each}}
|
|
92
|
-
</thead>
|
|
93
72
|
<tbody>
|
|
94
73
|
{{#each this.rows as |row|}}
|
|
95
74
|
<tr>
|
|
@@ -104,57 +83,22 @@ export default class PeopleTable extends Component {
|
|
|
104
83
|
}
|
|
105
84
|
```
|
|
106
85
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
## Ember-Specific Patterns
|
|
110
|
-
|
|
111
|
-
### Preserve method receivers in templates
|
|
112
|
-
|
|
113
|
-
V9 table, column, row, cell, and header methods live on prototypes and require their receiver. Ember templates extract function references, so call methods in a getter or a small module-level helper:
|
|
114
|
-
|
|
115
|
-
```gts
|
|
116
|
-
const getCanSort = (column: Column<typeof features, Person>) =>
|
|
117
|
-
column.getCanSort()
|
|
118
|
-
|
|
119
|
-
const toggleSort =
|
|
120
|
-
(column: Column<typeof features, Person>) => (event: Event) =>
|
|
121
|
-
column.getToggleSortingHandler()?.(event)
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
Pass `toggleSort header.column` to `{{on}}`; do not pass an extracted Table method directly.
|
|
125
|
-
|
|
126
|
-
### Render definitions through the matching component
|
|
127
|
-
|
|
128
|
-
Use `FlexRenderCell`, `FlexRenderHeader`, and `FlexRenderFooter` with their matching object. A definition may return a primitive or `flexRenderComponent(Component, options)`. The rendered component receives `@ctx` and optional `@options`; Table does not instantiate arbitrary component-library markup for you.
|
|
129
|
-
|
|
130
|
-
## Common Mistakes
|
|
131
|
-
|
|
132
|
-
### HIGH Passing an options object instead of a thunk
|
|
133
|
-
|
|
134
|
-
Wrong: `useTable({ features, columns, data: this.data })`.
|
|
135
|
-
|
|
136
|
-
Correct: `useTable(() => ({ features, columns, data: this.data }))`.
|
|
137
|
-
|
|
138
|
-
The thunk is how tracked option reads are connected to the table.
|
|
139
|
-
|
|
140
|
-
### HIGH Passing an unbound prototype method to a template modifier
|
|
141
|
-
|
|
142
|
-
Wrong: `{{on 'click' header.column.getToggleSortingHandler}}`.
|
|
143
|
-
|
|
144
|
-
Correct: wrap the call in a helper that invokes the method on `header.column`, as shown above.
|
|
86
|
+
## Construction and rendering
|
|
145
87
|
|
|
146
|
-
|
|
88
|
+
`useTable` takes an options thunk. Read tracked data inside it, and keep features, atoms, and columns stable. In a component, pass `this` as the owner to bind external-atom cleanup to the component lifecycle. The one-argument thunk form remains available for standalone tables.
|
|
147
89
|
|
|
148
|
-
|
|
90
|
+
Read Table APIs in template-consumed getters. Column, row, cell, and header prototype methods require their receiver, so use a getter or module helper such as `getAllCells(row)` rather than an extracted method. Wrap event calls the same way.
|
|
149
91
|
|
|
150
|
-
|
|
92
|
+
Use `FlexRenderCell`, `FlexRenderHeader`, and `FlexRenderFooter` for the matching object. Rendered components receive `@ctx` and optional `@options` through `flexRenderComponent(Component, options)`.
|
|
151
93
|
|
|
152
|
-
|
|
94
|
+
With `tableFeatures({})`, render `row.getAllCells()`. Register `columnVisibilityFeature` before switching to `row.getVisibleCells()`.
|
|
153
95
|
|
|
154
|
-
|
|
96
|
+
## Read for the task
|
|
155
97
|
|
|
156
|
-
|
|
98
|
+
- When adding or configuring optional features, load `intent load @tanstack/table-core#table-features` and read only references for the requested behavior.
|
|
99
|
+
- For state ownership or reactive reads, read [table-state](../table-state/SKILL.md).
|
|
100
|
+
- When tables share features, defaults, or reusable UI, read [create-table-hook](references/create-table-hook.md).
|
|
157
101
|
|
|
158
|
-
## API
|
|
102
|
+
## API discovery
|
|
159
103
|
|
|
160
|
-
Inspect `node_modules/@tanstack/ember-table/declarations/index.d.ts
|
|
104
|
+
Inspect `node_modules/@tanstack/ember-table/declarations/index.d.ts`, `use-table.d.ts`, `signal.d.ts`, and `FlexRender.d.ts`. Core feature APIs are in `node_modules/@tanstack/table-core/dist/features/`.
|
package/skills/{create-table-hook/SKILL.md → getting-started/references/create-table-hook.md}
RENAMED
|
@@ -1,23 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
type: framework
|
|
7
|
-
library: '@tanstack/ember-table'
|
|
8
|
-
framework: ember
|
|
9
|
-
library_version: '9.2.5'
|
|
10
|
-
requires:
|
|
11
|
-
- '@tanstack/table-core#core'
|
|
12
|
-
- getting-started
|
|
13
|
-
- table-state
|
|
14
|
-
sources:
|
|
15
|
-
- 'TanStack/table:docs/framework/ember/guide/composable-tables.md'
|
|
16
|
-
- 'TanStack/table:examples/ember/basic-app-table'
|
|
17
|
-
- 'TanStack/table:packages/ember-table/src/create-table-hook.ts'
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
This skill builds on `@tanstack/table-core#core`, `getting-started`, and `table-state`. Use an app factory when several tables share real features or defaults; keep a one-off table on `useTable`.
|
|
1
|
+
# Ember reusable table hooks
|
|
2
|
+
|
|
3
|
+
Read when multiple Ember tables share features, defaults, or rendering conventions. Keep standalone construction for tables without shared conventions. For controlled state or reactive reads, read [table-state](../../table-state/SKILL.md).
|
|
4
|
+
|
|
5
|
+
This reference inherits the version of its owning skill.
|
|
21
6
|
|
|
22
7
|
## Setup
|
|
23
8
|
|
|
@@ -53,16 +38,16 @@ const columns = columnHelper.columns([
|
|
|
53
38
|
export default class PeopleTable extends Component {
|
|
54
39
|
@tracked data: Person[] = []
|
|
55
40
|
|
|
56
|
-
table = createAppTable(() => ({
|
|
41
|
+
table = createAppTable(this, () => ({
|
|
57
42
|
columns,
|
|
58
43
|
data: this.data,
|
|
59
44
|
}))
|
|
60
45
|
}
|
|
61
46
|
```
|
|
62
47
|
|
|
63
|
-
Create the hook and column helpers at stable module scope. `createAppTable` preserves the `useTable` options thunk, so tracked reads such as `this.data` remain reactive. Do not pass `features` again at the table call site; the factory owns the feature set and binds it into column inference.
|
|
48
|
+
Create the hook and column helpers at stable module scope. Pass the component as the first `createAppTable` argument to bind external-atom cleanup to its lifecycle; the one-argument thunk form remains supported for standalone tables. `createAppTable` preserves the `useTable` options thunk, so tracked reads such as `this.data` remain reactive. Do not pass `features` again at the table call site; the factory owns the feature set and binds it into column inference.
|
|
64
49
|
|
|
65
|
-
## Composition
|
|
50
|
+
## Composition contract
|
|
66
51
|
|
|
67
52
|
- Hook options supply stable shared `features` and default table options.
|
|
68
53
|
- `createAppColumnHelper<TData>()` binds the feature type while inferring each row type.
|
|
@@ -74,11 +59,11 @@ Shared options intentionally exclude `columns`, `data`, and `state`. Keep model
|
|
|
74
59
|
|
|
75
60
|
Sharing `rowSortingFeature`, `sortedRowModel`, and sorting defaults gives every table sorting capability; it does not make their internal sorting state shared. The factory technically accepts a stable external atom in shared `atoms`, but that deliberately couples tables and their column IDs. Prefer independent state unless synchronized tables are the actual product behavior.
|
|
76
61
|
|
|
77
|
-
## Render
|
|
62
|
+
## Render normally
|
|
78
63
|
|
|
79
|
-
Ember's factory does not register `AppTable`, `AppCell`, `AppHeader`, context hooks, or reusable component registries. Continue rendering with `FlexRenderCell`, `FlexRenderHeader`, and `FlexRenderFooter`. Continue wrapping receiver-dependent v9 methods in Ember template helpers as described by
|
|
64
|
+
Ember's factory does not register `AppTable`, `AppCell`, `AppHeader`, context hooks, or reusable component registries. Continue rendering with `FlexRenderCell`, `FlexRenderHeader`, and `FlexRenderFooter`. Continue wrapping receiver-dependent v9 methods in Ember template helpers as described by [getting-started](../SKILL.md).
|
|
80
65
|
|
|
81
|
-
## Common
|
|
66
|
+
## Common mistakes
|
|
82
67
|
|
|
83
68
|
### HIGH Copying another adapter's component registry
|
|
84
69
|
|
|
@@ -96,7 +81,7 @@ Wrong:
|
|
|
96
81
|
createAppTable(() => ({ features: otherFeatures, columns, data: this.data }))
|
|
97
82
|
```
|
|
98
83
|
|
|
99
|
-
Correct: define a separate app hook when a table needs a
|
|
84
|
+
Correct: define a separate app hook when a table needs a different feature set. `createAppTable` omits `features` from its call-site type.
|
|
100
85
|
|
|
101
86
|
### HIGH Recreating the hook or columns with tracked updates
|
|
102
87
|
|
|
@@ -112,6 +97,12 @@ The hook options omit `state`. Put `state` and matching `on[State]Change` callba
|
|
|
112
97
|
|
|
113
98
|
Use `createAppColumnHelper<Person>()`; do not thread `typeof features` through every column helper after the factory has already captured it.
|
|
114
99
|
|
|
115
|
-
## API
|
|
100
|
+
## API discovery
|
|
116
101
|
|
|
117
102
|
Inspect `node_modules/@tanstack/ember-table/declarations/create-table-hook.d.ts` for the installed factory return shape, omitted options, and merge precedence. Inspect `use-table.d.ts` for thunk reactivity and `node_modules/@tanstack/table-core/dist/features/<feature>/` for the shared feature APIs. Do not infer Ember component/context behavior from another adapter's createTableHook.
|
|
103
|
+
|
|
104
|
+
## Sources
|
|
105
|
+
|
|
106
|
+
- `TanStack/table:docs/framework/ember/guide/composable-tables.md`
|
|
107
|
+
- `TanStack/table:examples/ember/basic-app-table`
|
|
108
|
+
- `TanStack/table:packages/ember-table/src/create-table-hook.ts`
|
|
@@ -1,187 +1,83 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: table-state
|
|
3
|
-
description:
|
|
4
|
-
Read
|
|
3
|
+
description:
|
|
4
|
+
Read and control Table v9 state in ember. Use for tracked reads, subscriptions,
|
|
5
|
+
controlled slices, and framework-specific reactive boundaries.
|
|
5
6
|
metadata:
|
|
6
7
|
type: framework
|
|
7
8
|
library: '@tanstack/ember-table'
|
|
8
9
|
framework: ember
|
|
9
|
-
library_version: '9.2.
|
|
10
|
+
library_version: '9.2.6'
|
|
10
11
|
requires:
|
|
11
|
-
- '@tanstack/table-core#
|
|
12
|
-
- getting-started
|
|
12
|
+
- '@tanstack/table-core#table-state'
|
|
13
13
|
sources:
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
14
|
+
- TanStack/table:docs/framework/ember/guide/table-state.md
|
|
15
|
+
- TanStack/table:examples/ember/basic-external-atoms
|
|
16
|
+
- TanStack/table:examples/ember/basic-external-state
|
|
17
|
+
- TanStack/table:packages/ember-table/src/use-table.ts
|
|
18
|
+
- TanStack/table:packages/ember-table/src/reactivity.ts
|
|
19
|
+
- TanStack/table:packages/ember-table/src/signal.ts
|
|
20
20
|
---
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
Load `intent load @tanstack/table-core#table-state` first for shared ownership, initialization, updater, and reset rules.
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Glimmer tracks Table APIs, atom reads, and store-property reads inside template-consumed getters. A value cached outside tracked consumption is only a snapshot. There is no `table.Subscribe` or selector argument to `useTable`; `table.store.subscribe` is intentionally a no-op and cannot drive rendering.
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- `table.baseAtoms` are the table's internal writable atoms.
|
|
29
|
-
- `table.atoms` are readonly, ownership-aware atoms for each registered slice.
|
|
30
|
-
- `table.store.state` exposes the current flat state.
|
|
31
|
-
- Feature methods such as `setSorting`, `setPageSize`, and `row.toggleSelected()` are the preferred write path.
|
|
32
|
-
|
|
33
|
-
Ember's reactivity feature bridges these reads into Glimmer tracking. There is no `table.Subscribe`, no selector argument to `useTable`, and no need to subscribe during rendering. Read the relevant API inside a template-consumed getter:
|
|
34
|
-
|
|
35
|
-
```gts
|
|
36
|
-
get rows() {
|
|
37
|
-
return this.table.getRowModel().rows
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
get pageIndex() {
|
|
41
|
-
return this.table.atoms.pagination.get().pageIndex
|
|
42
|
-
}
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
`table.store.subscribe` is not the Ember rendering mechanism. The adapter's store is pull-based; Glimmer tracks individual property and atom reads.
|
|
46
|
-
|
|
47
|
-
`features` and `atoms` are construct-time inputs in this adapter. Create them once before `useTable`; rerunning the options thunk updates ordinary live options but does not swap the table's feature set or atom owners.
|
|
48
|
-
|
|
49
|
-
## Choose One Owner Per Slice
|
|
50
|
-
|
|
51
|
-
For a slice such as pagination, choose one source of truth:
|
|
52
|
-
|
|
53
|
-
1. Internal `baseAtoms` by default.
|
|
54
|
-
2. `initialState.pagination` for an internally owned starting value.
|
|
55
|
-
3. An external writable atom in `atoms.pagination`.
|
|
56
|
-
4. A `@tracked` value in `state.pagination`, paired with `onPaginationChange`.
|
|
57
|
-
|
|
58
|
-
Read precedence is `atoms[key]` over `state[key]` over the internal `baseAtoms[key]`. Do not configure multiple owners merely as fallbacks.
|
|
59
|
-
|
|
60
|
-
## Internal and Initial State
|
|
61
|
-
|
|
62
|
-
With no `initialState`, `atoms`, `state`, or `on[State]Change`, Table owns registered state internally. Use `initialState` when only the starting/reset value differs:
|
|
63
|
-
|
|
64
|
-
```gts
|
|
65
|
-
table = useTable(() => ({
|
|
66
|
-
features,
|
|
67
|
-
columns,
|
|
68
|
-
data: this.data,
|
|
69
|
-
initialState: {
|
|
70
|
-
pagination: { pageIndex: 0, pageSize: 25 },
|
|
71
|
-
},
|
|
72
|
-
}))
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Changing `initialState` later does not reset existing state. Prefer feature reset methods such as `resetPagination()`; passing `true` requests that feature's blank/default state. Core `table.reset()` resets internal base atoms and is not the primary reset path for externally owned atoms.
|
|
76
|
-
|
|
77
|
-
## External Ember Atoms
|
|
78
|
-
|
|
79
|
-
Use the adapter's re-exported `createAtom` when a slice should be shared or read directly outside Table. It satisfies the TanStack Store atom contract and its reads are Glimmer-reactive:
|
|
26
|
+
## Controlled tracked setup
|
|
80
27
|
|
|
81
28
|
```gts
|
|
29
|
+
import Component from '@glimmer/component'
|
|
30
|
+
import { tracked } from '@glimmer/tracking'
|
|
31
|
+
import { on } from '@ember/modifier'
|
|
82
32
|
import {
|
|
83
|
-
createAtom,
|
|
84
|
-
useTable,
|
|
85
|
-
type PaginationState,
|
|
86
|
-
} from '@tanstack/ember-table'
|
|
87
|
-
|
|
88
|
-
paginationAtom = createAtom<PaginationState>({
|
|
89
|
-
pageIndex: 0,
|
|
90
|
-
pageSize: 10,
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
table = useTable(() => ({
|
|
94
|
-
features,
|
|
95
|
-
columns,
|
|
96
|
-
data: this.data,
|
|
97
|
-
atoms: { pagination: this.paginationAtom },
|
|
98
|
-
}))
|
|
99
|
-
|
|
100
|
-
get pagination() {
|
|
101
|
-
return this.paginationAtom.get()
|
|
102
|
-
}
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
Feature APIs write through the external atom, so do not add `onPaginationChange` for the same atom-owned slice. Write the external atom itself when using the low-level path.
|
|
106
|
-
|
|
107
|
-
## Controlled Tracked State
|
|
108
|
-
|
|
109
|
-
Use `state` plus the matching callback when a `@tracked` property owns a slice. Resolve both raw values and updater functions:
|
|
110
|
-
|
|
111
|
-
```gts
|
|
112
|
-
import {
|
|
113
|
-
createPaginatedRowModel,
|
|
114
33
|
rowPaginationFeature,
|
|
115
34
|
tableFeatures,
|
|
35
|
+
useTable,
|
|
116
36
|
type PaginationState,
|
|
117
37
|
} from '@tanstack/ember-table'
|
|
118
38
|
|
|
119
|
-
const features = tableFeatures({
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
@tracked pagination: PaginationState = { pageIndex: 0, pageSize: 10 }
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
Do not write `table.atoms.pagination`; it is readonly and may point at an external owner. Infer the complete registered shape with `TableState<typeof features>` and use feature-specific types such as `PaginationState` or `SortingState` for owned fields.
|
|
149
|
-
|
|
150
|
-
## Common Mistakes
|
|
151
|
-
|
|
152
|
-
### CRITICAL Controlling a slice without writing callbacks back
|
|
153
|
-
|
|
154
|
-
Wrong:
|
|
155
|
-
|
|
156
|
-
```gts
|
|
157
|
-
state: { pagination: this.pagination },
|
|
158
|
-
onPaginationChange: () => {},
|
|
39
|
+
const features = tableFeatures({ rowPaginationFeature })
|
|
40
|
+
const columns = [{ accessorKey: 'name' }]
|
|
41
|
+
const data = [{ name: 'Ada' }]
|
|
42
|
+
|
|
43
|
+
export default class PageStatus extends Component {
|
|
44
|
+
@tracked pagination: PaginationState = { pageIndex: 0, pageSize: 10 }
|
|
45
|
+
table = useTable(this, () => ({
|
|
46
|
+
features,
|
|
47
|
+
columns,
|
|
48
|
+
data,
|
|
49
|
+
state: { pagination: this.pagination },
|
|
50
|
+
onPaginationChange: (next) => {
|
|
51
|
+
this.pagination =
|
|
52
|
+
typeof next === 'function' ? next(this.pagination) : next
|
|
53
|
+
},
|
|
54
|
+
}))
|
|
55
|
+
|
|
56
|
+
get pageNumber() {
|
|
57
|
+
return this.table.atoms.pagination.get().pageIndex + 1
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
nextPage = () => this.table.nextPage()
|
|
61
|
+
|
|
62
|
+
<template>
|
|
63
|
+
<button type='button' {{on 'click' this.nextPage}}>Page
|
|
64
|
+
{{this.pageNumber}}</button>
|
|
65
|
+
</template>
|
|
66
|
+
}
|
|
159
67
|
```
|
|
160
68
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
### HIGH Expecting a snapshot read or subscription component
|
|
164
|
-
|
|
165
|
-
Wrong: invent `<table.Subscribe>`, call `table.store.subscribe(...)` for rendering, or cache `table.store.state.pagination` outside a tracked getter.
|
|
166
|
-
|
|
167
|
-
Correct: read `table.atoms.pagination.get()`, `table.store.state.pagination`, or the relevant Table API inside a template-consumed getter.
|
|
168
|
-
|
|
169
|
-
`table.getState()` is removed v8 API, not an Ember state-read alternative.
|
|
170
|
-
|
|
171
|
-
### HIGH Mixing atom and state ownership
|
|
172
|
-
|
|
173
|
-
If both `atoms.pagination` and `state.pagination` are present, the atom wins. Choose one owner so resets and writes have an unambiguous destination.
|
|
174
|
-
|
|
175
|
-
### HIGH Mutating controlled objects in place
|
|
176
|
-
|
|
177
|
-
Wrong: `this.pagination.pageIndex++`.
|
|
69
|
+
## Reactive boundaries
|
|
178
70
|
|
|
179
|
-
|
|
71
|
+
- Read tracked values inside the options thunk and assign callback results back to their tracked owner. Mutating `this.pagination.pageIndex++` does not notify the thunk.
|
|
72
|
+
- `features` and `atoms` are construction-time inputs. Updating ordinary live options does not replace the feature set or atom owners; create them once before `useTable`.
|
|
73
|
+
- Pass the component as the owner for lifecycle cleanup when external atoms are used. The standalone one-argument thunk form remains supported.
|
|
74
|
+
- Use the adapter's `createAtom` for external Glimmer-reactive ownership. Read it in a tracked getter and use feature APIs or the external atom to write.
|
|
75
|
+
- Keep features, columns, and data stable. Call receiver-dependent methods through getters or helpers rather than passing extracted methods to templates.
|
|
180
76
|
|
|
181
|
-
|
|
77
|
+
## Read for the task
|
|
182
78
|
|
|
183
|
-
|
|
79
|
+
For advanced reactive boundaries, shared atoms, or detailed subscription examples, read [reactivity](references/reactivity.md). For construction or rendering setup, read [getting-started](../getting-started/SKILL.md).
|
|
184
80
|
|
|
185
|
-
## API
|
|
81
|
+
## API discovery
|
|
186
82
|
|
|
187
|
-
Inspect `node_modules/@tanstack/ember-table/declarations/use-table.d.ts
|
|
83
|
+
Inspect `node_modules/@tanstack/ember-table/declarations/index.d.ts`, `use-table.d.ts`, `signal.d.ts`, and `FlexRender.d.ts`. Core feature APIs are in `node_modules/@tanstack/table-core/dist/features/`.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Ember Table reactivity
|
|
2
|
+
|
|
3
|
+
Read for Ember subscription boundaries, shared state, or updates that require more than the default rendering behavior.
|
|
4
|
+
|
|
5
|
+
This reference inherits the version of its owning skill.
|
|
6
|
+
|
|
7
|
+
## Own shared state with an Ember atom
|
|
8
|
+
|
|
9
|
+
```gts
|
|
10
|
+
import Component from '@glimmer/component'
|
|
11
|
+
import { on } from '@ember/modifier'
|
|
12
|
+
import {
|
|
13
|
+
createAtom,
|
|
14
|
+
rowPaginationFeature,
|
|
15
|
+
tableFeatures,
|
|
16
|
+
useTable,
|
|
17
|
+
type PaginationState,
|
|
18
|
+
} from '@tanstack/ember-table'
|
|
19
|
+
|
|
20
|
+
const features = tableFeatures({ rowPaginationFeature })
|
|
21
|
+
const columns = [{ accessorKey: 'name' }]
|
|
22
|
+
const data = [{ name: 'Ada' }]
|
|
23
|
+
|
|
24
|
+
export default class SharedPage extends Component {
|
|
25
|
+
paginationAtom = createAtom<PaginationState>({ pageIndex: 0, pageSize: 10 })
|
|
26
|
+
table = useTable(this, () => ({
|
|
27
|
+
features,
|
|
28
|
+
columns,
|
|
29
|
+
data,
|
|
30
|
+
atoms: { pagination: this.paginationAtom },
|
|
31
|
+
}))
|
|
32
|
+
|
|
33
|
+
get pageNumber() {
|
|
34
|
+
return this.paginationAtom.get().pageIndex + 1
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
nextPage = () => this.table.nextPage()
|
|
38
|
+
|
|
39
|
+
<template>
|
|
40
|
+
<button type='button' {{on 'click' this.nextPage}}>Page
|
|
41
|
+
{{this.pageNumber}}</button>
|
|
42
|
+
</template>
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The adapter re-exports `createAtom` with Glimmer-reactive reads. Feature APIs write through to that owner, so omit `onPaginationChange`. Supplying the component owner binds external-atom cleanup to its destruction. Use the one-argument thunk form only when no Ember owner is available.
|
|
47
|
+
|
|
48
|
+
## Construction-time ownership
|
|
49
|
+
|
|
50
|
+
The options thunk updates ordinary live options from tracked reads, but features and external atom owners are fixed during construction. Keep them stable. Replacing an `atoms` object in a getter does not swap the table's owners.
|
|
51
|
+
|
|
52
|
+
## Template tracking is pull-based
|
|
53
|
+
|
|
54
|
+
Read `table.atoms.<slice>.get()`, `table.store.state.<slice>`, or a Table API inside a template-consumed getter. There is no selector argument or `table.Subscribe`; `table.store.subscribe` is a no-op. Subscribe to a supplied external atom when a separate consumer actually needs push notifications.
|
|
55
|
+
|
|
56
|
+
`table.getState()` is removed v8 API. Caching a value outside tracked consumption does not establish Glimmer tracking.
|
|
57
|
+
|
|
58
|
+
## Controlled state pitfalls
|
|
59
|
+
|
|
60
|
+
Resolve value-or-updater callbacks and assign a fresh tracked value. `this.pagination.pageIndex++` mutates an untracked nested property. A no-op callback freezes the controlled slice. Prefer `table.setPageIndex(...)` to invoke the callback with the feature's update rules.
|
|
61
|
+
|
|
62
|
+
An external atom wins over controlled state. Writing an internal base atom cannot replace the external value; use the feature API or write the external owner.
|
|
63
|
+
|
|
64
|
+
## API discovery
|
|
65
|
+
|
|
66
|
+
Inspect `node_modules/@tanstack/ember-table/declarations/index.d.ts`, `use-table.d.ts`, `signal.d.ts`, and `FlexRender.d.ts`. Core feature APIs are in `node_modules/@tanstack/table-core/dist/features/`.
|
|
67
|
+
|
|
68
|
+
## Sources
|
|
69
|
+
|
|
70
|
+
- `TanStack/table:docs/framework/ember/guide/table-state.md`
|
|
71
|
+
- `TanStack/table:examples/ember/basic-external-atoms`
|
|
72
|
+
- `TanStack/table:examples/ember/basic-external-state`
|
|
73
|
+
- `TanStack/table:packages/ember-table/src/use-table.ts`
|
|
74
|
+
- `TanStack/table:packages/ember-table/src/reactivity.ts`
|
|
75
|
+
- `TanStack/table:packages/ember-table/src/signal.ts`
|