- @for (cell of row.getVisibleCells(); track cell.id) {
+ @for (cell of row.getAllCells(); track cell.id) {
> = [
@Component({
selector: 'app-root',
standalone: true,
- imports: [RouterOutlet, FlexRenderDirective],
+ imports: [FlexRenderDirective],
templateUrl: './app.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent {
- data = signal>(defaultData)
+ readonly data = signal>(defaultData)
+
+ readonly tableFeatures = tableFeatures({})
table = injectTable(() => ({
+ _features: this.tableFeatures, // new required option in V9. Tell the table which features you are importing and using (better tree-shaking)
+ _rowModels: {}, // `Core` row model is now included by default, but you can still override it here
data: this.data(),
columns: defaultColumns,
- getCoreRowModel: createCoreRowModel(),
debugTable: true,
+ // other options here
}))
rerender() {
diff --git a/examples/angular/column-ordering/src/app/app.component.ts b/examples/angular/column-ordering/src/app/app.component.ts
index c5058b6e87..f88252ba45 100644
--- a/examples/angular/column-ordering/src/app/app.component.ts
+++ b/examples/angular/column-ordering/src/app/app.component.ts
@@ -6,6 +6,8 @@ import {
} from '@angular/core'
import {
FlexRenderDirective,
+ columnOrderingFeature,
+ columnVisibilityFeature,
createCoreRowModel,
injectTable,
} from '@tanstack/angular-table'
@@ -84,12 +86,15 @@ export class AppComponent {
readonly table = injectTable(() => ({
data: this.data(),
+ _features: {
+ columnVisibilityFeature,
+ columnOrderingFeature,
+ },
columns: defaultColumns,
state: {
columnOrder: this.columnOrder(),
columnVisibility: this.columnVisibility(),
},
- getCoreRowModel: createCoreRowModel(),
onColumnVisibilityChange: (updaterOrValue) => {
typeof updaterOrValue === 'function'
? this.columnVisibility.update(updaterOrValue)
diff --git a/examples/angular/column-pinning-sticky/src/app/app.component.ts b/examples/angular/column-pinning-sticky/src/app/app.component.ts
index 5ad8414ae9..f81394dc23 100644
--- a/examples/angular/column-pinning-sticky/src/app/app.component.ts
+++ b/examples/angular/column-pinning-sticky/src/app/app.component.ts
@@ -1,6 +1,11 @@
import { Component, computed, signal } from '@angular/core'
import {
FlexRenderDirective,
+ columnOrderingFeature,
+ columnPinningFeature,
+ columnResizingFeature,
+ columnSizingFeature,
+ columnVisibilityFeature,
createCoreRowModel,
injectTable,
} from '@tanstack/angular-table'
@@ -74,7 +79,7 @@ const defaultColumns: Array> = [
@Component({
selector: 'app-root',
standalone: true,
- imports: [FlexRenderDirective, SlicePipe, NgTemplateOutlet, NgStyle],
+ imports: [FlexRenderDirective, NgStyle],
templateUrl: './app.component.html',
})
export class AppComponent {
@@ -82,17 +87,26 @@ export class AppComponent {
readonly data = signal>(makeData(30))
readonly columnVisibility = signal({})
readonly columnOrder = signal([])
- readonly columnPinning = signal({})
+ readonly columnPinning = signal({
+ left: [],
+ right: [],
+ })
readonly split = signal(false)
table = injectTable(() => ({
data: this.data(),
+ _features: {
+ columnPinningFeature,
+ columnVisibilityFeature,
+ columnSizingFeature,
+ columnOrderingFeature,
+ columnResizingFeature,
+ },
columns: this.columns(),
- getCoreRowModel: createCoreRowModel(),
debugTable: true,
debugHeaders: true,
debugColumns: true,
- columnResizeMode: 'onChange',
+ columnResizeMode: 'onChange' as const,
}))
stringifiedColumnPinning = computed(() => {
diff --git a/examples/angular/column-pinning/src/app/app.component.ts b/examples/angular/column-pinning/src/app/app.component.ts
index 07fceb21c8..2915048b7a 100644
--- a/examples/angular/column-pinning/src/app/app.component.ts
+++ b/examples/angular/column-pinning/src/app/app.component.ts
@@ -6,8 +6,12 @@ import {
} from '@angular/core'
import {
FlexRenderDirective,
+ columnOrderingFeature,
+ columnPinningFeature,
+ columnVisibilityFeature,
createCoreRowModel,
injectTable,
+ rowPinningFeature,
} from '@tanstack/angular-table'
import { faker } from '@faker-js/faker'
import { NgTemplateOutlet, SlicePipe } from '@angular/common'
@@ -91,11 +95,19 @@ export class AppComponent {
readonly data = signal>(makeData(5000))
readonly columnVisibility = signal({})
readonly columnOrder = signal([])
- readonly columnPinning = signal({})
+ readonly columnPinning = signal({
+ left: [],
+ right: [],
+ })
readonly split = signal(false)
table = injectTable(() => ({
data: this.data(),
+ _features: {
+ columnPinningFeature,
+ columnOrderingFeature,
+ columnVisibilityFeature,
+ },
columns: defaultColumns,
state: {
columnVisibility: this.columnVisibility(),
@@ -117,7 +129,6 @@ export class AppComponent {
? this.columnPinning.update(updaterOrValue)
: this.columnPinning.set(updaterOrValue)
},
- getCoreRowModel: createCoreRowModel(),
debugTable: true,
debugHeaders: true,
debugColumns: true,
diff --git a/examples/angular/grouping/src/app/app.component.html b/examples/angular/grouping/src/app/app.component.html
index 198a34644a..d60f34234e 100644
--- a/examples/angular/grouping/src/app/app.component.html
+++ b/examples/angular/grouping/src/app/app.component.html
@@ -42,7 +42,7 @@
@for (row of table.getRowModel().rows; track row.id) {
- @for (cell of row.getVisibleCells(); track cell.id) {
+ @for (cell of row.getAllCells(); track cell.id) {
([])
+ readonly data = signal(makeData(10000))
+ readonly grouping = signal([])
- stringifiedGrouping = computed(() => JSON.stringify(this.grouping(), null, 2))
-
- tableOptions = computed(() =>
- tableOptions({
- data: this.data(),
- columns: columns,
- state: {
- grouping: this.grouping(),
- },
- onGroupingChange: (updaterOrValue: Updater) => {
- const groupingState =
- typeof updaterOrValue === 'function'
- ? updaterOrValue([...this.grouping()])
- : updaterOrValue
- this.grouping.set(groupingState)
- },
- getExpandedRowModel: createExpandedRowModel(),
- getGroupedRowModel: createGroupedRowModel(),
- getCoreRowModel: createCoreRowModel(),
- getPaginatedRowModel: createPaginatedRowModel(),
- getFilteredRowModel: createFilteredRowModel(),
- debugTable: true,
- }),
+ readonly stringifiedGrouping = computed(() =>
+ JSON.stringify(this.grouping(), null, 2),
)
- table = injectTable(this.tableOptions)
+ readonly table = injectTable(() => ({
+ data: this.data(),
+ columns: columns,
+ initialState: {
+ pagination: { pageSize: 20, pageIndex: 0 },
+ },
+ state: {
+ grouping: this.grouping(),
+ },
+ _features: {
+ columnGroupingFeature,
+ rowPaginationFeature,
+ columnFilteringFeature,
+ rowExpandingFeature,
+ },
+ _rowModels: {
+ groupedRowModel: createGroupedRowModel(),
+ expandedRowModel: createExpandedRowModel(),
+ paginatedRowModel: createPaginatedRowModel(),
+ filteredRowModel: createFilteredRowModel(),
+ },
+ onGroupingChange: (updaterOrValue: Updater) => {
+ const groupingState =
+ typeof updaterOrValue === 'function'
+ ? updaterOrValue([...this.grouping()])
+ : updaterOrValue
+ this.grouping.set(groupingState)
+ },
+ }))
onPageInputChange(event: any): void {
const page = event.target.value ? Number(event.target.value) - 1 : 0
diff --git a/examples/angular/row-selection-signal/src/app/app.component.html b/examples/angular/row-selection-signal/src/app/app.component.html
index c2dfb725f7..f50c2d0052 100644
--- a/examples/angular/row-selection-signal/src/app/app.component.html
+++ b/examples/angular/row-selection-signal/src/app/app.component.html
@@ -20,8 +20,9 @@
@if (header.column.getCanFilter()) {
diff --git a/examples/angular/row-selection-signal/src/app/app.component.ts b/examples/angular/row-selection-signal/src/app/app.component.ts
index 908f667cdf..8c480ee9d2 100644
--- a/examples/angular/row-selection-signal/src/app/app.component.ts
+++ b/examples/angular/row-selection-signal/src/app/app.component.ts
@@ -7,10 +7,13 @@ import {
} from '@angular/core'
import {
FlexRenderDirective,
- createCoreRowModel,
+ columnFilteringFeature,
+ columnVisibilityFeature,
createFilteredRowModel,
createPaginatedRowModel,
injectTable,
+ rowPaginationFeature,
+ rowSelectionFeature,
} from '@tanstack/angular-table'
import { FilterComponent } from './filter'
import { makeData } from './makeData'
@@ -97,6 +100,16 @@ export class AppComponent {
table = injectTable(() => ({
data: this.data(),
+ _features: {
+ rowSelectionFeature,
+ rowPaginationFeature,
+ columnFilteringFeature,
+ columnVisibilityFeature,
+ },
+ _rowModels: {
+ filteredRowModel: createFilteredRowModel(),
+ paginatedRowModel: createPaginatedRowModel(),
+ },
columns: this.columns,
state: {
rowSelection: this.rowSelection(),
@@ -110,9 +123,6 @@ export class AppComponent {
: updaterOrValue,
)
},
- getCoreRowModel: createCoreRowModel(),
- getFilteredRowModel: createFilteredRowModel(),
- getPaginatedRowModel: createPaginatedRowModel(),
debugTable: true,
}))
diff --git a/examples/angular/row-selection-signal/src/app/filter.ts b/examples/angular/row-selection-signal/src/app/filter.ts
index bd3319c687..c21fcc3807 100644
--- a/examples/angular/row-selection-signal/src/app/filter.ts
+++ b/examples/angular/row-selection-signal/src/app/filter.ts
@@ -1,7 +1,7 @@
import { CommonModule } from '@angular/common'
import { Component, input } from '@angular/core'
import type { OnInit } from '@angular/core'
-import type { Column, Table } from '@tanstack/angular-table'
+import type { Column, RowData, Table } from '@tanstack/angular-table'
@Component({
selector: 'app-table-filter',
@@ -39,10 +39,10 @@ import type { Column, Table } from '@tanstack/angular-table'
standalone: true,
imports: [CommonModule],
})
-export class FilterComponent implements OnInit {
+export class FilterComponent implements OnInit {
column = input.required>()
- table = input.required>()
+ table = input.required>()
columnType!: string
diff --git a/examples/angular/row-selection-signal/src/app/selection-column.component.ts b/examples/angular/row-selection-signal/src/app/selection-column.component.ts
index 50d057b84c..2a6cb75670 100644
--- a/examples/angular/row-selection-signal/src/app/selection-column.component.ts
+++ b/examples/angular/row-selection-signal/src/app/selection-column.component.ts
@@ -1,5 +1,5 @@
import { ChangeDetectionStrategy, Component, input } from '@angular/core'
-import type { Row, Table } from '@tanstack/angular-table'
+import type { Row, RowData, Table } from '@tanstack/angular-table'
@Component({
template: `
@@ -16,7 +16,7 @@ import type { Row, Table } from '@tanstack/angular-table'
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
})
-export class TableHeadSelectionComponent {
+export class TableHeadSelectionComponent {
// Your component should also reflect the fields you use as props in flexRenderer directive.
// Define the fields as input you want to use in your component
// ie. In this case, you are passing HeaderContext object as props in flexRenderer directive.
@@ -25,7 +25,7 @@ export class TableHeadSelectionComponent {
// column = input.required>()
// header = input.required>()
- table = input.required>()
+ table = input.required>()
}
@Component({
@@ -42,6 +42,6 @@ export class TableHeadSelectionComponent {
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
})
-export class TableRowSelectionComponent {
- row = input.required>()
+export class TableRowSelectionComponent {
+ row = input.required>()
}
diff --git a/examples/angular/row-selection/src/app/app.component.html b/examples/angular/row-selection/src/app/app.component.html
index c2dfb725f7..109bc93f63 100644
--- a/examples/angular/row-selection/src/app/app.component.html
+++ b/examples/angular/row-selection/src/app/app.component.html
@@ -20,8 +20,9 @@
@if (header.column.getCanFilter()) {
@@ -35,7 +36,7 @@
@for (row of table.getRowModel().rows; track row.id) {
- @for (cell of row.getVisibleCells(); track cell.id) {
+ @for (cell of row.getAllCells(); track cell.id) {
>('ageHeaderCell')
- readonly columns: Array> = [
- {
- id: 'select',
- header: () => {
- return new FlexRenderComponent(TableHeadSelectionComponent)
- },
- cell: () => {
- return new FlexRenderComponent(TableRowSelectionComponent)
- },
- },
- {
- header: 'Name',
- footer: (props) => props.column.id,
- columns: [
- {
- accessorKey: 'firstName',
- cell: (info) => info.getValue(),
- footer: (props) => props.column.id,
- header: 'First name',
- },
- {
- accessorFn: (row) => row.lastName,
- id: 'lastName',
- cell: (info) => info.getValue(),
- header: () => 'Last Name',
- footer: (props) => props.column.id,
+ readonly columns: Array> =
+ [
+ {
+ id: 'select',
+ header: () => {
+ return new FlexRenderComponent(TableHeadSelectionComponent)
},
- ],
- },
- {
- header: 'Info',
- footer: (props) => props.column.id,
- columns: [
- {
- accessorKey: 'age',
- header: () => this.ageHeaderCell(),
- footer: (props) => props.column.id,
+ cell: () => {
+ return new FlexRenderComponent(TableRowSelectionComponent)
},
- {
- header: 'More Info',
- columns: [
- {
- accessorKey: 'visits',
- header: () => 'Visits',
- footer: (props) => props.column.id,
- },
- {
- accessorKey: 'status',
- header: 'Status',
- footer: (props) => props.column.id,
- },
- {
- accessorKey: 'progress',
- header: 'Profile Progress',
- footer: (props) => props.column.id,
- },
- ],
- },
- ],
- },
- ]
+ },
+ {
+ header: 'Name',
+ footer: (props) => props.column.id,
+ columns: [
+ {
+ accessorKey: 'firstName',
+ cell: (info) => info.getValue(),
+ footer: (props) => props.column.id,
+ header: 'First name',
+ },
+ {
+ accessorFn: (row) => row.lastName,
+ id: 'lastName',
+ cell: (info) => info.getValue(),
+ header: () => 'Last Name',
+ footer: (props) => props.column.id,
+ },
+ ],
+ },
+ {
+ header: 'Info',
+ footer: (props) => props.column.id,
+ columns: [
+ {
+ accessorKey: 'age',
+ header: () => this.ageHeaderCell(),
+ footer: (props) => props.column.id,
+ },
+ {
+ header: 'More Info',
+ columns: [
+ {
+ accessorKey: 'visits',
+ header: () => 'Visits',
+ footer: (props) => props.column.id,
+ },
+ {
+ accessorKey: 'status',
+ header: 'Status',
+ footer: (props) => props.column.id,
+ },
+ {
+ accessorKey: 'progress',
+ header: 'Profile Progress',
+ footer: (props) => props.column.id,
+ },
+ ],
+ },
+ ],
+ },
+ ]
- table = injectTable(() => ({
+ table = tableHelper.injectTable(() => ({
data: this.data(),
columns: this.columns,
state: {
@@ -116,10 +133,6 @@ export class AppComponent {
: updaterOrValue,
)
},
- getCoreRowModel: createCoreRowModel(),
- getFilteredRowModel: createFilteredRowModel(),
- getPaginatedRowModel: createPaginatedRowModel(),
- debugTable: true,
}))
readonly stringifiedRowSelection = computed(() =>
@@ -129,7 +142,6 @@ export class AppComponent {
readonly rowSelectionLength = computed(
() => Object.keys(this.rowSelection()).length,
)
-
onPageInputChange(event: Event): void {
const inputElement = event.target as HTMLInputElement
const page = inputElement.value ? Number(inputElement.value) - 1 : 0
diff --git a/examples/angular/row-selection/src/app/filter.ts b/examples/angular/row-selection/src/app/filter.ts
index bd3319c687..71b4d66404 100644
--- a/examples/angular/row-selection/src/app/filter.ts
+++ b/examples/angular/row-selection/src/app/filter.ts
@@ -40,8 +40,8 @@ import type { Column, Table } from '@tanstack/angular-table'
imports: [CommonModule],
})
export class FilterComponent implements OnInit {
- column = input.required>()
-
+ column = input.required>()
+ // @ts-expect-error TODO: Should fix types
table = input.required>()
columnType!: string
diff --git a/examples/angular/row-selection/src/app/selection-column.component.ts b/examples/angular/row-selection/src/app/selection-column.component.ts
index 63ad19f1b1..1ed10d8f1c 100644
--- a/examples/angular/row-selection/src/app/selection-column.component.ts
+++ b/examples/angular/row-selection/src/app/selection-column.component.ts
@@ -18,7 +18,10 @@ import type { CellContext, HeaderContext } from '@tanstack/angular-table'
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TableHeadSelectionComponent {
- context = injectFlexRenderContext>()
+ context = injectFlexRenderContext<
+ // @ts-expect-error TODO: Should fix types
+ HeaderContext<{ rowSelectionFeature: {} }, T, unknown>
+ >()
}
@Component({
@@ -36,5 +39,7 @@ export class TableHeadSelectionComponent {
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TableRowSelectionComponent {
- context = injectFlexRenderContext>()
+ context =
+ // @ts-expect-error TODO: Should fix types
+ injectFlexRenderContext>()
}
diff --git a/examples/angular/signal-input/src/app/person-table/person-table.component.ts b/examples/angular/signal-input/src/app/person-table/person-table.component.ts
index a04aaeb5f4..3431cd045f 100644
--- a/examples/angular/signal-input/src/app/person-table/person-table.component.ts
+++ b/examples/angular/signal-input/src/app/person-table/person-table.component.ts
@@ -1,16 +1,29 @@
import { ChangeDetectionStrategy, Component, input, model } from '@angular/core'
import {
FlexRenderDirective,
+ columnVisibilityFeature,
createCoreRowModel,
createExpandedRowModel,
createFilteredRowModel,
createGroupedRowModel,
createPaginatedRowModel,
+ createTableHelper,
injectTable,
+ rowPaginationFeature,
} from '@tanstack/angular-table'
import type { ColumnDef, PaginationState } from '@tanstack/angular-table'
import type { Person } from '../makeData'
+const tableHelper = createTableHelper({
+ _features: {
+ rowPaginationFeature,
+ columnVisibilityFeature,
+ },
+ _rowModels: {
+ paginatedRowModel: createPaginatedRowModel(),
+ },
+})
+
@Component({
selector: 'app-person-table',
templateUrl: 'person-table.component.html',
@@ -37,7 +50,7 @@ export class PersonTableComponent {
},
]
- table = injectTable(() => {
+ readonly table = tableHelper.injectTable(() => {
return {
data: this.data(),
columns: this.columns,
@@ -49,11 +62,6 @@ export class PersonTableComponent {
? this.pagination.update(updaterOrValue)
: this.pagination.set(updaterOrValue)
},
- getExpandedRowModel: createExpandedRowModel(),
- getGroupedRowModel: createGroupedRowModel(),
- getCoreRowModel: createCoreRowModel(),
- getPaginatedRowModel: createPaginatedRowModel(),
- getFilteredRowModel: createFilteredRowModel(),
debugTable: true,
}
})
diff --git a/examples/react/basic/src/main.tsx b/examples/react/basic/src/main.tsx
index 3d1ccbd1fa..6b4f3d1a95 100644
--- a/examples/react/basic/src/main.tsx
+++ b/examples/react/basic/src/main.tsx
@@ -80,7 +80,10 @@ const columns: Array> = [
accessorFn: (row) => Number(row.age), // accessorFn used to transform the data
id: 'age',
header: () => 'Age',
- cell: (info) => info.renderValue(),
+ cell: (info) => {
+ console.log('info test value')
+ return info.renderValue()
+ },
},
{
accessorKey: 'visits',
diff --git a/packages/angular-table/package.json b/packages/angular-table/package.json
index 161699803d..1417755551 100644
--- a/packages/angular-table/package.json
+++ b/packages/angular-table/package.json
@@ -60,6 +60,7 @@
"@angular/core": "^19.0.0",
"@angular/platform-browser": "^19.0.0",
"@angular/platform-browser-dynamic": "^19.0.0",
+ "@vitest/ui": "^2.1.5",
"ng-packagr": "^19.0.0"
},
"peerDependencies": {
diff --git a/packages/angular-table/src/constructTableHelper.ts b/packages/angular-table/src/constructTableHelper.ts
new file mode 100644
index 0000000000..156a803393
--- /dev/null
+++ b/packages/angular-table/src/constructTableHelper.ts
@@ -0,0 +1,109 @@
+import { createColumnHelper } from '@tanstack/table-core'
+import type {
+ ColumnHelper,
+ RowData,
+ Table,
+ TableFeatures,
+ TableOptions,
+} from '@tanstack/table-core'
+import type { Signal } from '@angular/core'
+
+/**
+ * Options for creating a table helper to share common options across multiple tables
+ * columnsFeature, data, and state are excluded from this type and reserved for only the `useTable`/`createTable` functions
+ */
+export type TableHelperOptions<
+ TFeatures extends TableFeatures,
+ TData extends RowData = any,
+> = Omit<
+ TableOptions>,
+ 'columns' | 'data' | 'state'
+> & {
+ _features: TFeatures
+ TData?: TData // provide a cast for the TData type
+}
+
+/**
+ * Internal type that each adapter package will build off of to create a table helper
+ */
+export type TableHelper_Core<
+ TFeatures extends TableFeatures,
+ TData extends RowData = any,
+> = {
+ columnHelper: ColumnHelper
+ createColumnHelper: () => ColumnHelper<
+ TFeatures,
+ TData
+ >
+ features: TFeatures
+ options: Omit, 'columns' | 'data' | 'state'>
+ tableCreator: (
+ tableOptions: () => Omit<
+ TableOptions,
+ '_features' | '_rowModels' | '_rowModelFns'
+ >,
+ ) => Table
+}
+
+/**
+ * Internal function to create a table helper that each adapter package will use to create their own table helper
+ */
+export function constructTableHelper<
+ TFeatures extends TableFeatures,
+ TData extends RowData = any,
+>(
+ tableCreator: (
+ tableOptions: () => TableOptions,
+ ) => Table & Signal>,
+ tableHelperOptions: TableHelperOptions,
+): TableHelper_Core {
+ const { TData: _TData, ..._tableHelperOptions } = tableHelperOptions
+ return {
+ columnHelper: createColumnHelper(),
+ createColumnHelper,
+ features: tableHelperOptions._features,
+ options: _tableHelperOptions as any,
+ tableCreator: (tableOptions) =>
+ // @ts-expect-error Fix this
+ tableCreator(() => ({
+ ...tableHelperOptions,
+ ...tableOptions(),
+ })),
+ }
+}
+
+// test
+
+// // eslint-disable-next-line import/first, import/order
+// import { constructTable } from '../core/table/constructTable'
+// // eslint-disable-next-line import/first, import/order
+// import { type ColumnDef } from '../types/ColumnDef'
+
+// type Person = {
+// firstName: string
+// lastName: string
+// age: number
+// }
+
+// const tableHelper = constructTableHelper(constructTable, {
+// _features: { rowSelectionFeature: {} },
+// _rowModels: {},
+// TData: {} as Person,
+// })
+
+// const columns = [
+// tableHelper.columnHelper.accessor('firstName', {
+// header: 'First Name',
+// cell: (info) => info.getValue(),
+// }),
+// tableHelper.columnHelper.accessor('lastName', { header: 'Last Name' }),
+// tableHelper.columnHelper.accessor('age', { header: 'Age' }),
+// tableHelper.columnHelper.display({ header: 'Actions', id: 'actions' }),
+// ] as Array>
+
+// const data: Array = []
+
+// tableHelper.tableCreator({
+// columns,
+// data,
+// })
diff --git a/packages/angular-table/src/createTableHelper.ts b/packages/angular-table/src/createTableHelper.ts
new file mode 100644
index 0000000000..b4f6d2a787
--- /dev/null
+++ b/packages/angular-table/src/createTableHelper.ts
@@ -0,0 +1,68 @@
+import { Signal } from '@angular/core'
+import { constructTableHelper } from './constructTableHelper'
+import { injectTable } from './injectTable'
+import type {
+ RowData,
+ Table,
+ TableFeatures,
+ TableHelperOptions,
+ TableHelper_Core,
+ TableOptions,
+} from '@tanstack/table-core'
+
+export type TableHelper<
+ TFeatures extends TableFeatures,
+ TData extends RowData = any,
+> = Omit, 'tableCreator'> & {
+ injectTable: (
+ tableOptions: () => Omit<
+ TableOptions,
+ '_features' | '_rowModels' | '_rowModelFns'
+ >,
+ ) => Table
+}
+
+export function createTableHelper<
+ TFeatures extends TableFeatures,
+ TData extends RowData = any,
+>(
+ tableHelperOptions: TableHelperOptions,
+): TableHelper {
+ const tableHelper = constructTableHelper(
+ injectTable as unknown as (
+ tableOptions: () => TableOptions,
+ ) => Table & Signal>,
+ tableHelperOptions,
+ )
+ return {
+ ...tableHelper,
+ injectTable: tableHelper.tableCreator,
+ } as any
+}
+
+// test
+
+// type Person = {
+// firstName: string
+// lastName: string
+// age: number
+// }
+
+// const tableHelper = createTableHelper({
+// _features: { rowSelectionFeature: {} },
+// TData: {} as Person,
+// })
+
+// const columns = [
+// tableHelper.columnHelper.accessor('firstName', { header: 'First Name' }),
+// tableHelper.columnHelper.accessor('lastName', { header: 'Last Name' }),
+// tableHelper.columnHelper.accessor('age', { header: 'Age' }),
+// tableHelper.columnHelper.display({ header: 'Actions', id: 'actions' }),
+// ] as Array>
+
+// const data: Array = []
+
+// tableHelper.createTable({
+// columns,
+// data,
+// })
diff --git a/packages/angular-table/src/flex-render.ts b/packages/angular-table/src/flex-render.ts
index a584af7ac6..70b36a829a 100644
--- a/packages/angular-table/src/flex-render.ts
+++ b/packages/angular-table/src/flex-render.ts
@@ -13,7 +13,8 @@ import {
inject,
isSignal,
} from '@angular/core'
-import type { OnChanges, SimpleChanges } from '@angular/core'
+import type { DoCheck, OnChanges, SimpleChanges } from '@angular/core'
+import type { Table } from '@tanstack/table-core'
export type FlexRenderContent> =
| string
@@ -29,7 +30,7 @@ export type FlexRenderContent> =
standalone: true,
})
export class FlexRenderDirective>
- implements OnChanges
+ implements OnChanges, DoCheck
{
@Input({ required: true, alias: 'flexRender' })
content:
@@ -45,6 +46,8 @@ export class FlexRenderDirective>
@Input({ required: false, alias: 'flexRenderInjector' })
injector: Injector = inject(Injector)
+ ref?: ComponentRef | EmbeddedViewRef | null = null
+
constructor(
@Inject(ViewContainerRef)
private readonly viewContainerRef: ViewContainerRef,
@@ -52,12 +55,13 @@ export class FlexRenderDirective>
private readonly templateRef: TemplateRef,
) {}
- ref?: ComponentRef | EmbeddedViewRef | null = null
-
- ngOnChanges(changes: SimpleChanges) {
+ ngDoCheck(): void {
if (this.ref instanceof ComponentRef) {
this.ref.injector.get(ChangeDetectorRef).markForCheck()
}
+ }
+
+ ngOnChanges(changes: SimpleChanges) {
if (!changes['content']) {
return
}
@@ -69,12 +73,11 @@ export class FlexRenderDirective>
const { content, props } = this
if (content === null || content === undefined) {
this.ref = null
- return
}
if (typeof content === 'function') {
- return this.renderContent(content(props))
+ this.ref = this.renderContent(content(props))
} else {
- return this.renderContent(content)
+ this.ref = this.renderContent(content)
}
}
diff --git a/packages/angular-table/src/index.ts b/packages/angular-table/src/index.ts
index b0b52b8882..f9bd9c806d 100644
--- a/packages/angular-table/src/index.ts
+++ b/packages/angular-table/src/index.ts
@@ -4,3 +4,4 @@ export * from './flex-render'
export * from './proxy'
export * from './lazy-signal-initializer'
export * from './injectTable'
+export * from './createTableHelper'
diff --git a/packages/angular-table/src/injectTable.ts b/packages/angular-table/src/injectTable.ts
index 748299f34b..f53b3ab95e 100644
--- a/packages/angular-table/src/injectTable.ts
+++ b/packages/angular-table/src/injectTable.ts
@@ -7,40 +7,52 @@ import {
} from '@tanstack/table-core'
import { lazyInit } from './lazy-signal-initializer'
import { proxifyTable } from './proxy'
-import type { Signal } from '@angular/core'
import type {
+ CreateRowModels_All,
RowData,
Table,
TableFeatures,
TableOptions,
TableState,
} from '@tanstack/table-core'
+import type { Signal } from '@angular/core'
+
+export type AngularTableOptions<
+ TFeatures extends TableFeatures,
+ TData extends RowData,
+> = Omit, '_rowModels'> & {
+ _rowModels?: CreateRowModels_All
+ // TODO: no exported
+ // _rowModelsFns: RowModelFns
+}
export function injectTable<
TFeatures extends TableFeatures,
TData extends RowData,
>(
- options: () => TableOptions,
+ options: () => AngularTableOptions,
): Table & Signal> {
return lazyInit(() => {
- const resolvedOptions = {
- ...options(),
- _features: {
+ const features = () => {
+ return {
...coreFeatures,
...options()._features,
- },
+ }
}
- const table = constructTable(resolvedOptions)
-
// By default, manage table state here using the table's initial state
const state = signal>(
- getInitialTableState(
- resolvedOptions._features,
- resolvedOptions.initialState,
- ),
+ getInitialTableState(features(), options().initialState),
)
+ const resolvedOptions: TableOptions = {
+ ...options(),
+ _features: features(),
+ state: { ...state(), ...options().state },
+ } as TableOptions
+
+ const table = constructTable(resolvedOptions)
+
// Compose table options using computed.
// This is to allow `tableSignal` to listen and set table option
const updatedOptions = computed>(() => {
@@ -48,10 +60,12 @@ export function injectTable<
const tableState = state()
// listen to input options changed
const tableOptions = options()
+
return {
...table.options,
...resolvedOptions,
...tableOptions,
+ _features: features(),
state: { ...tableState, ...tableOptions.state },
onStateChange: (updater) => {
const value = isFunction(updater) ? updater(tableState) : updater
diff --git a/packages/angular-table/src/proxy.ts b/packages/angular-table/src/proxy.ts
index 86a65434ab..04bf80f522 100644
--- a/packages/angular-table/src/proxy.ts
+++ b/packages/angular-table/src/proxy.ts
@@ -19,9 +19,9 @@ export function proxifyTable<
apply() {
return tableSignal()
},
- get(target, property: keyof Table): any {
- if (target[property]) {
- return target[property]
+ get(target, property): any {
+ if (Reflect.has(target, property)) {
+ return Reflect.get(target, property)
}
const table = untracked(tableSignal)
/**
@@ -29,25 +29,25 @@ export function proxifyTable<
* excluding handlers as they do not retain any reactive value
*/
if (
+ typeof property === 'string' &&
property.startsWith('get') &&
!property.endsWith('Handler') &&
!property.endsWith('Model')
) {
- const maybeFn = table[property] as Function | never
+ const maybeFn = (table as any)[property] as Function | never
if (typeof maybeFn === 'function') {
Object.defineProperty(target, property, {
value: toComputed(tableSignal, maybeFn),
configurable: true,
enumerable: true,
})
- return target[property]
+ return (target as any)[property]
}
}
- // @ts-expect-error
- return (target[property] = table[property])
+ return ((target as any)[property] = (table as any)[property])
},
- has(_, prop: keyof Table) {
- return !!untracked(tableSignal)[prop]
+ has(_, prop) {
+ return Reflect.has(untracked(tableSignal), prop)
},
ownKeys() {
return Reflect.ownKeys(untracked(tableSignal))
diff --git a/packages/angular-table/tests/createTableHelper.test-d.ts b/packages/angular-table/tests/createTableHelper.test-d.ts
new file mode 100644
index 0000000000..e8a22c9555
--- /dev/null
+++ b/packages/angular-table/tests/createTableHelper.test-d.ts
@@ -0,0 +1,63 @@
+import { expectTypeOf, test } from 'vitest'
+import {
+ createPaginatedRowModel,
+ createTableHelper,
+ stockFeatures,
+} from '../src'
+import type { ColumnDef, StockTableFeatures, Table, TableHelper } from '../src'
+
+test('infer data type from TData', () => {
+ type TestDataType = { firstName: string; lastName: string; age: number }
+
+ const tableHelper = createTableHelper({
+ _features: stockFeatures,
+ _rowModels: {
+ paginatedRowModel: createPaginatedRowModel(),
+ },
+ TData: {} as TestDataType,
+ })
+
+ expectTypeOf().toEqualTypeOf<
+ TableHelper, TestDataType>
+ >()
+
+ expectTypeOf<(typeof tableHelper)['features']>().toEqualTypeOf<
+ Required
+ >()
+
+ const columns = [
+ tableHelper.columnHelper.accessor('firstName', { header: 'First Name' }),
+ tableHelper.columnHelper.accessor('lastName', { header: 'Last Name' }),
+ tableHelper.columnHelper.accessor('age', { header: 'Age' }),
+ tableHelper.columnHelper.display({ header: 'Actions', id: 'actions' }),
+ ] as const
+
+ expectTypeOf().toMatchTypeOf<
+ ReadonlyArray>
+ >()
+})
+
+test('infer data type given by injectTable', () => {
+ type TestDataType = { firstName: string; lastName: string }
+
+ const tableHelper = createTableHelper({
+ _features: stockFeatures,
+ _rowModels: {
+ paginatedRowModel: createPaginatedRowModel(),
+ },
+ })
+
+ expectTypeOf().toEqualTypeOf<
+ TableHelper, any>
+ >()
+
+ const injectTable = tableHelper.injectTable
+ const table = injectTable(() => ({
+ data: [] as Array,
+ columns: [],
+ }))
+
+ expectTypeOf().toEqualTypeOf<
+ Table, TestDataType>
+ >()
+})
diff --git a/packages/angular-table/tests/flex-render.test.ts b/packages/angular-table/tests/flex-render.test.ts
index 02e3c33003..c88bbc1e16 100644
--- a/packages/angular-table/tests/flex-render.test.ts
+++ b/packages/angular-table/tests/flex-render.test.ts
@@ -1,5 +1,5 @@
-import { Component, ViewChild, input, type TemplateRef } from '@angular/core'
-import { TestBed, type ComponentFixture } from '@angular/core/testing'
+import { Component, ViewChild, input } from '@angular/core'
+import { TestBed } from '@angular/core/testing'
import { createColumnHelper } from '@tanstack/table-core'
import { describe, expect, test } from 'vitest'
import {
@@ -8,6 +8,8 @@ import {
injectFlexRenderContext,
} from '../src/flex-render'
import { setFixtureSignalInput, setFixtureSignalInputs } from './test-utils'
+import type { ComponentFixture } from '@angular/core/testing'
+import type { TemplateRef } from '@angular/core'
interface Data {
id: string
@@ -18,7 +20,7 @@ interface Data {
}
describe('FlexRenderDirective', () => {
- const helper = createColumnHelper()
+ const helper = createColumnHelper<{}, Data>()
test('should render primitives', async () => {
const fixture = TestBed.createComponent(TestRenderComponent)
diff --git a/packages/angular-table/tests/createAngularTable.test.ts b/packages/angular-table/tests/injectTable.test.ts
similarity index 70%
rename from packages/angular-table/tests/createAngularTable.test.ts
rename to packages/angular-table/tests/injectTable.test.ts
index 1ab38422df..55630f0eb5 100644
--- a/packages/angular-table/tests/createAngularTable.test.ts
+++ b/packages/angular-table/tests/injectTable.test.ts
@@ -1,9 +1,13 @@
import { describe, expect, test } from 'vitest'
import { Component, input, isSignal, signal, untracked } from '@angular/core'
import { TestBed } from '@angular/core/testing'
-import { createCoreRowModel, injectTable } from '../src/injectTable'
-import { setSignalInputs } from './test-utils'
-import type { ColumnDef, Table } from '../src/injectTable'
+import { ColumnDef, stockFeatures } from '@tanstack/table-core'
+import { injectTable } from '../src/injectTable'
+import {
+ experimentalReactivity_testShouldBeComputedProperty,
+ setSignalInputs,
+ testShouldBeComputedProperty,
+} from './test-utils'
describe('injectTable', () => {
test('should render with required signal inputs', () => {
@@ -17,8 +21,8 @@ describe('injectTable', () => {
table = injectTable(() => ({
data: this.data(),
+ _features: stockFeatures,
columns: [],
- getCoreRowModel: createCoreRowModel(),
}))
}
@@ -39,8 +43,8 @@ describe('injectTable', () => {
]
const table = injectTable(() => ({
data: data(),
+ _features: stockFeatures,
columns: columns,
- getCoreRowModel: createCoreRowModel(),
getRowId: (row) => row.id,
}))
const tablePropertyKeys = Object.keys(table())
@@ -50,7 +54,7 @@ describe('injectTable', () => {
})
test('supports "in" operator', () => {
- expect('getCoreRowModel' in table).toBe(true)
+ expect('_features' in table).toBe(true)
expect('options' in table).toBe(true)
expect('notFound' in table).toBe(false)
})
@@ -71,21 +75,3 @@ describe('injectTable', () => {
})
})
})
-
-const testShouldBeComputedProperty = (
- table: Table,
- propertyName: string,
-) => {
- if (propertyName.endsWith('Handler') || propertyName.endsWith('Model')) {
- return false
- }
-
- if (propertyName.startsWith('get')) {
- // Only properties with no arguments are computed
- const fn = table[propertyName as keyof Table]
- // Cannot test if is lazy computed since we return the unwrapped value
- return fn instanceof Function && fn.length === 0
- }
-
- return false
-}
diff --git a/packages/angular-table/tests/lazy-init.test.ts b/packages/angular-table/tests/lazy-init.test.ts
index fa3a43f553..ba9854fb2b 100644
--- a/packages/angular-table/tests/lazy-init.test.ts
+++ b/packages/angular-table/tests/lazy-init.test.ts
@@ -2,7 +2,6 @@ import { describe, expect, test, vi } from 'vitest'
import {
ChangeDetectionStrategy,
Component,
- type WritableSignal,
computed,
effect,
input,
@@ -11,6 +10,7 @@ import {
import { TestBed } from '@angular/core/testing'
import { lazyInit } from '../src/lazy-signal-initializer'
import { flushQueue, setFixtureSignalInputs } from './test-utils'
+import type { WritableSignal } from '@angular/core'
describe('lazyInit', () => {
test('should init lazily in next tick when not accessing manually', async () => {
@@ -51,7 +51,7 @@ describe('lazyInit', () => {
test('should init lazily and only once', async () => {
const initCallFn = vi.fn()
- const registerDataValue = vi.fn<[number]>()
+ const registerDataValue = vi.fn<(arg0: number) => void>()
let value!: { data: WritableSignal }
const outerSignal = signal(0)
@@ -84,7 +84,7 @@ describe('lazyInit', () => {
await flushQueue()
expect(initCallFn).toHaveBeenCalledTimes(1)
- expect(registerDataValue).toHaveBeenCalledTimes(2)
+ expect(registerDataValue).toHaveBeenCalledTimes(1)
})
test('should support required signal input', async () => {
diff --git a/packages/angular-table/tests/test-utils.ts b/packages/angular-table/tests/test-utils.ts
index 28b788e0bf..443f091a06 100644
--- a/packages/angular-table/tests/test-utils.ts
+++ b/packages/angular-table/tests/test-utils.ts
@@ -1,6 +1,7 @@
-import type { InputSignal } from '@angular/core'
import { SIGNAL, signalSetFn } from '@angular/core/primitives/signals'
+import type { InputSignal } from '@angular/core'
import type { ComponentFixture } from '@angular/core/testing'
+import { Table } from '@tanstack/table-core'
type ToSignalInputUpdatableMap = {
[K in keyof T as T[K] extends InputSignal
@@ -60,3 +61,42 @@ function componentHasSignalInputProperty(
export async function flushQueue() {
await new Promise(setImmediate)
}
+
+export const experimentalReactivity_testShouldBeComputedProperty = (
+ testObj: any,
+ propertyName: string,
+) => {
+ if (propertyName.startsWith('_rootNotifier')) {
+ return true
+ }
+ if (propertyName.endsWith('Handler')) {
+ return false
+ }
+
+ if (propertyName.startsWith('get')) {
+ // Only properties with no arguments are computed
+ const fn = testObj[propertyName]
+ // Cannot test if is lazy computed since we return the unwrapped value
+ return fn instanceof Function && fn.length === 0
+ }
+
+ return false
+}
+
+export const testShouldBeComputedProperty = (
+ testObj: any,
+ propertyName: string,
+) => {
+ if (propertyName.endsWith('Handler') || propertyName.endsWith('Model')) {
+ return false
+ }
+
+ if (propertyName.startsWith('get')) {
+ // Only properties with no arguments are computed
+ const fn = testObj[propertyName]
+ // Cannot test if is lazy computed since we return the unwrapped value
+ return fn instanceof Function && fn.length === 0
+ }
+
+ return false
+}
diff --git a/packages/angular-table/vite.config.ts b/packages/angular-table/vite.config.ts
index 523b22e583..1ba318b695 100644
--- a/packages/angular-table/vite.config.ts
+++ b/packages/angular-table/vite.config.ts
@@ -9,5 +9,9 @@ export default defineConfig({
environment: 'jsdom',
setupFiles: ['./tests/test-setup.ts'],
globals: true,
+ typecheck: {
+ enabled: true,
+ tsconfig: './tsconfig.json',
+ },
},
})
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 7051a5c73d..f5baad1c9f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -70,7 +70,7 @@ importers:
version: 5.4.11(@types/node@22.9.1)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)
vitest:
specifier: ^2.1.5
- version: 2.1.5(@types/node@22.9.1)(jsdom@25.0.1)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)
+ version: 2.1.5(@types/node@22.9.1)(@vitest/ui@2.1.5)(jsdom@25.0.1)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)
examples/angular/basic:
dependencies:
@@ -2955,6 +2955,9 @@ importers:
'@angular/platform-browser-dynamic':
specifier: ^19.0.0
version: 19.0.0(@angular/common@19.0.0(@angular/core@19.0.0(rxjs@7.8.1)(zone.js@0.15.0))(rxjs@7.8.1))(@angular/compiler@19.0.0(@angular/core@19.0.0(rxjs@7.8.1)(zone.js@0.15.0)))(@angular/core@19.0.0(rxjs@7.8.1)(zone.js@0.15.0))(@angular/platform-browser@19.0.0(@angular/animations@19.0.0(@angular/core@19.0.0(rxjs@7.8.1)(zone.js@0.15.0)))(@angular/common@19.0.0(@angular/core@19.0.0(rxjs@7.8.1)(zone.js@0.15.0))(rxjs@7.8.1))(@angular/core@19.0.0(rxjs@7.8.1)(zone.js@0.15.0)))
+ '@vitest/ui':
+ specifier: ^2.1.5
+ version: 2.1.5(vitest@2.1.5)
ng-packagr:
specifier: ^19.0.0
version: 19.0.0(@angular/compiler-cli@19.0.0(@angular/compiler@19.0.0(@angular/core@19.0.0(rxjs@7.8.1)(zone.js@0.15.0)))(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3)
@@ -5102,6 +5105,9 @@ packages:
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
+ '@polka/url@1.0.0-next.28':
+ resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==}
+
'@popperjs/core@2.11.8':
resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
@@ -5812,6 +5818,11 @@ packages:
'@vitest/spy@2.1.5':
resolution: {integrity: sha512-aWZF3P0r3w6DiYTVskOYuhBc7EMc3jvn1TkBg8ttylFFRqNN2XGD7V5a4aQdk6QiUzZQ4klNBSpCLJgWNdIiNw==}
+ '@vitest/ui@2.1.5':
+ resolution: {integrity: sha512-ERgKkDMTfngrZip6VG5h8L9B5D0AH/4+bga4yR1UzGH7c2cxv3LWogw2Dvuwr9cP3/iKDHYys7kIFLDKpxORTg==}
+ peerDependencies:
+ vitest: 2.1.5
+
'@vitest/utils@2.1.5':
resolution: {integrity: sha512-yfj6Yrp0Vesw2cwJbP+cl04OC+IHFsuQsrsJBL9pyGeQXE56v1UAOQco+SR55Vf1nQzfV0QJg1Qum7AaWUwwYg==}
@@ -7182,6 +7193,9 @@ packages:
picomatch:
optional: true
+ fflate@0.8.2:
+ resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==}
+
figures@3.2.0:
resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==}
engines: {node: '>=8'}
@@ -9394,6 +9408,10 @@ packages:
simple-git@3.27.0:
resolution: {integrity: sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==}
+ sirv@3.0.0:
+ resolution: {integrity: sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==}
+ engines: {node: '>=18'}
+
size-limit@11.1.6:
resolution: {integrity: sha512-S5ux2IB8rU26xwVgMskmknGMFkieaIAqDLuwgKiypk6oa4lFsie8yFPrzRFV+yrLDY2GddjXuCaVk5PveVOHiQ==}
engines: {node: ^18.0.0 || >=20.0.0}
@@ -9761,6 +9779,10 @@ packages:
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
engines: {node: '>=0.6'}
+ totalist@3.0.1:
+ resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
+ engines: {node: '>=6'}
+
tough-cookie@5.0.0:
resolution: {integrity: sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==}
engines: {node: '>=16'}
@@ -12697,6 +12719,8 @@ snapshots:
'@pkgjs/parseargs@0.11.0':
optional: true
+ '@polka/url@1.0.0-next.28': {}
+
'@popperjs/core@2.11.8': {}
'@rollup/plugin-json@6.1.0(rollup@4.26.0)':
@@ -13516,6 +13540,17 @@ snapshots:
dependencies:
tinyspy: 3.0.2
+ '@vitest/ui@2.1.5(vitest@2.1.5)':
+ dependencies:
+ '@vitest/utils': 2.1.5
+ fflate: 0.8.2
+ flatted: 3.3.1
+ pathe: 1.1.2
+ sirv: 3.0.0
+ tinyglobby: 0.2.10
+ tinyrainbow: 1.2.0
+ vitest: 2.1.5(@types/node@22.9.1)(@vitest/ui@2.1.5)(jsdom@25.0.1)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)
+
'@vitest/utils@2.1.5':
dependencies:
'@vitest/pretty-format': 2.1.5
@@ -15217,6 +15252,8 @@ snapshots:
optionalDependencies:
picomatch: 4.0.2
+ fflate@0.8.2: {}
+
figures@3.2.0:
dependencies:
escape-string-regexp: 1.0.5
@@ -17633,6 +17670,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ sirv@3.0.0:
+ dependencies:
+ '@polka/url': 1.0.0-next.28
+ mrmime: 2.0.0
+ totalist: 3.0.1
+
size-limit@11.1.6:
dependencies:
bytes-iec: 3.1.1
@@ -18030,6 +18073,8 @@ snapshots:
toidentifier@1.0.1: {}
+ totalist@3.0.1: {}
+
tough-cookie@5.0.0:
dependencies:
tldts: 6.1.61
@@ -18350,7 +18395,7 @@ snapshots:
optionalDependencies:
vite: 5.4.11(@types/node@22.9.1)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)
- vitest@2.1.5(@types/node@22.9.1)(jsdom@25.0.1)(less@4.2.0)(sass@1.80.7)(terser@5.36.0):
+ vitest@2.1.5(@types/node@22.9.1)(@vitest/ui@2.1.5)(jsdom@25.0.1)(less@4.2.0)(sass@1.80.7)(terser@5.36.0):
dependencies:
'@vitest/expect': 2.1.5
'@vitest/mocker': 2.1.5(vite@5.4.11(@types/node@22.9.1)(less@4.2.0)(sass@1.80.7)(terser@5.36.0))
@@ -18374,6 +18419,7 @@ snapshots:
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 22.9.1
+ '@vitest/ui': 2.1.5(vitest@2.1.5)
jsdom: 25.0.1
transitivePeerDependencies:
- less
| | |