Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge main into alpha #5907

Merged
merged 25 commits into from
Feb 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
05ecd5e
feat(angular-table): Refactor Flex render implementation - Zoneless, …
riccardoperra Jan 20, 2025
0caf695
release: v8.21.0
tannerlinsley Jan 20, 2025
0baabdd
docs(angular): add editable, row-dnd and performant column resizing e…
riccardoperra Jan 21, 2025
190c669
docs(angular): add missing faker-js deps (#5883)
riccardoperra Jan 21, 2025
9763877
fix(lit-table): dynamic data updates in the Lit Table Adapter (#5884)
lschierer Jan 27, 2025
8d6e19f
docs: add experimental virtualization example (#5895)
KevinVandy Feb 3, 2025
64e10bc
release: v8.21.1
tannerlinsley Feb 3, 2025
57703a4
docs: example name
KevinVandy Feb 3, 2025
099e1a4
docs(angular): add expanding and sub components examples (#5898)
riccardoperra Feb 3, 2025
067792f
Merge remote-tracking branch 'origin/main' into alpha_merge_latest_main
riccardoperra Feb 3, 2025
e35226e
fix conflicts in lit package
riccardoperra Feb 3, 2025
849a7cb
remove angular package non-fesm export
riccardoperra Feb 3, 2025
9e6987d
docs: exp virtual - remeasure when table state changes
KevinVandy Feb 4, 2025
827b098
docs: virtualizer tbody from onchange
KevinVandy Feb 4, 2025
9774cf4
update all angular examples
riccardoperra Feb 5, 2025
462d94f
Merge remote-tracking branch 'origin/main' into alpha_merge_latest_main
riccardoperra Feb 5, 2025
3bacaa5
fix conflicts in examples/react
riccardoperra Feb 5, 2025
fdf1336
ci: apply automated fixes
autofix-ci[bot] Feb 5, 2025
d2fc9c1
fix tests
riccardoperra Feb 5, 2025
d391407
ci: apply automated fixes
autofix-ci[bot] Feb 5, 2025
6f13e13
fix tests
riccardoperra Feb 5, 2025
eaed1b9
ci: apply automated fixes
autofix-ci[bot] Feb 5, 2025
fdfca13
angular: update vite config to support vitest workspaces
riccardoperra Feb 5, 2025
a04e39e
docs(angular): fix examples
riccardoperra Feb 8, 2025
1150b7d
ci: apply automated fixes
autofix-ci[bot] Feb 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions docs/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -435,9 +435,29 @@
"to": "framework/angular/examples/row-selection",
"label": "Row Selection"
},
{
"to": "framework/angular/examples/expanding",
"label": "Expanding"
},
{
"to": "framework/angular/examples/sub-components",
"label": "Sub Components"
},
{
"to": "framework/angular/examples/signal-input",
"label": "Signal Input"
},
{
"to": "framework/angular/examples/editable",
"label": "Editable data"
},
{
"to": "framework/angular/examples/row-dnd",
"label": "Row DnD"
},
{
"to": "framework/angular/examples/column-resizing-performant",
"label": "Performant Column Resizing"
}
]
},
Expand Down Expand Up @@ -594,10 +614,18 @@
"to": "framework/react/examples/virtualized-columns",
"label": "Virtualized Columns"
},
{
"to": "framework/react/examples/virtualized-columns-experimental",
"label": "Virtualized Columns (Experimental)"
},
{
"to": "framework/react/examples/virtualized-rows",
"label": "Virtualized Rows"
},
{
"to": "framework/react/examples/virtualized-rows-experimental",
"label": "Virtualized Rows (Experimental)"
},
{
"to": "framework/react/examples/virtualized-infinite-scrolling",
"label": "Virtualized Infinite Scrolling"
Expand Down
184 changes: 162 additions & 22 deletions docs/framework/angular/angular-table.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,41 +40,181 @@ FlexRender supports any type of content supported by Angular:
- A [TemplateRef](https://angular.dev/api/core/TemplateRef)
- A [Component](https://angular.dev/api/core/Component) wrapped into `FlexRenderComponent`

Example:
You can just use the `cell.renderValue` or `cell.getValue` APIs to render the cells of your table. However,
these APIs will only spit out the raw cell values (from accessor functions).
If you are using the `cell: () => any` column definition options, you will want to use the `FlexRenderDirective` from the adapter.

Cell column definition is **reactive** and runs into an **injection context**, then you can inject services or make use of signals to automatically modify the rendered content.

#### Example

```ts
@Component({
imports: [FlexRenderDirective],
//...
})
class YourComponent {}
```

```angular-html

<tbody>
@for (row of table.getRowModel().rows; track row.id) {
<tr>
@for (cell of row.getVisibleCells(); track cell.id) {
<td>
<ng-container
*flexRender="
<tr>
@for (cell of row.getVisibleCells(); track cell.id) {
<td>
<ng-container
*flexRender="
cell.column.columnDef.cell;
props: cell.getContext();
let cell
"
>
<!-- if you want to render a simple string -->
{{ cell }}
<!-- if you want to render an html string -->
<div [innerHTML]="cell"></div>
</ng-container>
</td>
}
</tr>
>
<!-- if you want to render a simple string -->
{{ cell }}
<!-- if you want to render an html string -->
<div [innerHTML]="cell"></div>
</ng-container>
</td>
}
</tr>
}
</tbody>
```

#### Rendering a Component

To render a Component into a specific column header/cell/footer, you can pass a `FlexRenderComponent` instantiated with
your `ComponentType, with the ability to include parameters such as inputs, outputs and a custom injector.

```ts
import {flexRenderComponent} from "./flex-render-component";
import {ChangeDetectionStrategy, input, output} from "@angular/core";

@Component({
template: `
...
`,
standalone: true,
changeDetectionStrategy: ChangeDetectionStrategy.OnPush,
host: {
'(click)': 'clickEvent.emit($event)'
}
})
class CustomCell {
readonly content = input.required<string>();
readonly cellType = input<MyType>();

// An output that will emit for every cell click
readonly clickEvent = output<Event>();
}

class AppComponent {
columns: ColumnDef<unknown>[] = [
{
id: 'custom-cell',
header: () => {
const translateService = inject(TranslateService);
return translateService.translate('...');
},
cell: (context) => {
return flexRenderComponent(
MyCustomComponent,
{
injector, // Optional injector
inputs: {
// Mandatory input since we are using `input.required()
content: context.row.original.rowProperty,
// cellType? - Optional input
},
outputs: {
clickEvent: () => {
// Do something
}
}
}
)
},
},
]
}
```

Underneath, this utilizes
the [ViewContainerRef#createComponent](https://angular.dev/api/core/ViewContainerRef#createComponent) api.
Therefore, you should declare your custom inputs using the @Input decorator or input/model signals.

You can still access the table cell context through the `injectFlexRenderContext` function, which returns the context
value based on the props you pass to the `FlexRenderDirective`.

```ts

@Component({
// ...
})
class CustomCellComponent {
// context of a cell component
readonly context = injectFlexRenderContext<CellContext<TData, TValue>>();
// context of a header/footer component
readonly context = injectFlexRenderContext<HeaderContext<TData, TValue>>();
}
```

Alternatively, you can render a component into a specific column header, cell, or footer by passing the component type
to the corresponding column definitions. These column definitions will be provided to the `flexRender` directive along
with the `context`.

```ts
class AppComponent {
columns: ColumnDef<Person>[] = [
{
id: 'select',
header: () => TableHeadSelectionComponent<Person>,
cell: () => TableRowSelectionComponent<Person>,
},
]
}
```

```angular-html
<ng-container
*flexRender="
header.column.columnDef.header;
props: header.getContext();
let headerCell
"
>
{{ headerCell }}
</ng-container>
```

Properties of `context` provided in the `flexRender` directive will be accessible to your component.
You can explicitly define the context properties required by your component.
In this example, the context provided to flexRender is of type HeaderContext.
Input signal `table`, which is a property of HeaderContext together with `column` and `header` properties,
is then defined to be used in the component. If any of the context properties are
needed in your component, feel free to use them. Please take note that only input signal is supported,
when defining access to context properties, using this approach.

```angular-ts
@Component({
template: `
<input
type="checkbox"
[checked]="table().getIsAllRowsSelected()"
[indeterminate]="table().getIsSomeRowsSelected()"
(change)="table().toggleAllRowsSelected()"
/>
`,
// ...
})
export class TableHeadSelectionComponent<T> {
//column = input.required<Column<T, unknown>>()
//header = input.required<Header<T, unknown>>()
table = input.required<Table<T>>()
}
```

#### Rendering a TemplateRef

In order to render a TemplateRef into a specific column header/cell/footer, you can pass the TemplateRef into the column
Expand Down Expand Up @@ -214,7 +354,7 @@ class CustomCellComponent {
}
```

Alternatively, you can render a component into a specific column header, cell, or footer by passing the component type
Alternatively, you can render a component into a specific column header, cell, or footer by passing the component type
to the corresponding column definitions. These column definitions will be provided to the `flexRender` directive along with the `context`.

```ts
Expand Down Expand Up @@ -243,12 +383,12 @@ class AppComponent {
</ng-container>
```

Properties of `context` provided in the `flexRender` directive will be accessible to your component.
You can explicitly define the context properties required by your component.
In this example, the context provided to flexRender is of type HeaderContext.
Properties of `context` provided in the `flexRender` directive will be accessible to your component.
You can explicitly define the context properties required by your component.
In this example, the context provided to flexRender is of type HeaderContext.
Input signal `table`, which is a property of HeaderContext together with `column` and `header` properties,
is then defined to be used in the component. If any of the context properties are
needed in your component, feel free to use them. Please take note that only input signal is supported,
is then defined to be used in the component. If any of the context properties are
needed in your component, feel free to use them. Please take note that only input signal is supported,
when defining access to context properties, using this approach.

```angular-ts
Expand All @@ -268,4 +408,4 @@ export class TableHeadSelectionComponent<T> {
//header = input.required<Header<T, unknown>>()
table = input.required<Table<T>>()
}
```
```
20 changes: 10 additions & 10 deletions examples/angular/basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@
},
"private": true,
"dependencies": {
"@angular/common": "^19.0.5",
"@angular/compiler": "^19.0.5",
"@angular/core": "^19.0.5",
"@angular/forms": "^19.0.5",
"@angular/platform-browser": "^19.0.5",
"@angular/platform-browser-dynamic": "^19.0.5",
"@angular/router": "^19.0.5",
"@angular/common": "^19.1.4",
"@angular/compiler": "^19.1.4",
"@angular/core": "^19.1.4",
"@angular/forms": "^19.1.4",
"@angular/platform-browser": "^19.1.4",
"@angular/platform-browser-dynamic": "^19.1.4",
"@angular/router": "^19.1.4",
"@tanstack/angular-table": "^9.0.0-alpha.10",
"rxjs": "~7.8.1",
"zone.js": "~0.15.0"
},
"devDependencies": {
"@angular/build": "^19.0.6",
"@angular/cli": "^19.0.6",
"@angular/compiler-cli": "^19.0.5",
"@angular/build": "^19.1.5",
"@angular/cli": "^19.1.5",
"@angular/compiler-cli": "^19.1.4",
"@types/jasmine": "~5.1.5",
"jasmine-core": "~5.5.0",
"tslib": "^2.8.1",
Expand Down
18 changes: 9 additions & 9 deletions examples/angular/column-ordering/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@
},
"private": true,
"dependencies": {
"@angular/common": "^19.0.5",
"@angular/compiler": "^19.0.5",
"@angular/core": "^19.0.5",
"@angular/forms": "^19.0.5",
"@angular/platform-browser": "^19.0.5",
"@angular/platform-browser-dynamic": "^19.0.5",
"@angular/common": "^19.1.4",
"@angular/compiler": "^19.1.4",
"@angular/core": "^19.1.4",
"@angular/forms": "^19.1.4",
"@angular/platform-browser": "^19.1.4",
"@angular/platform-browser-dynamic": "^19.1.4",
"@tanstack/angular-table": "^9.0.0-alpha.10",
"rxjs": "~7.8.1",
"zone.js": "~0.15.0"
},
"devDependencies": {
"@angular/build": "^19.0.6",
"@angular/cli": "^19.0.6",
"@angular/compiler-cli": "^19.0.5",
"@angular/build": "^19.1.5",
"@angular/cli": "^19.1.5",
"@angular/compiler-cli": "^19.1.4",
"tslib": "^2.8.1",
"typescript": "5.6.3"
}
Expand Down
18 changes: 9 additions & 9 deletions examples/angular/column-pinning-sticky/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@
},
"private": true,
"dependencies": {
"@angular/common": "^19.0.5",
"@angular/compiler": "^19.0.5",
"@angular/core": "^19.0.5",
"@angular/forms": "^19.0.5",
"@angular/platform-browser": "^19.0.5",
"@angular/platform-browser-dynamic": "^19.0.5",
"@angular/common": "^19.1.4",
"@angular/compiler": "^19.1.4",
"@angular/core": "^19.1.4",
"@angular/forms": "^19.1.4",
"@angular/platform-browser": "^19.1.4",
"@angular/platform-browser-dynamic": "^19.1.4",
"@faker-js/faker": "^9.3.0",
"@tanstack/angular-table": "^9.0.0-alpha.10",
"rxjs": "~7.8.1",
"zone.js": "~0.15.0"
},
"devDependencies": {
"@angular/build": "^19.0.6",
"@angular/cli": "^19.0.6",
"@angular/compiler-cli": "^19.0.5",
"@angular/build": "^19.1.5",
"@angular/cli": "^19.1.5",
"@angular/compiler-cli": "^19.1.4",
"tslib": "^2.8.1",
"typescript": "5.6.3"
}
Expand Down
Loading
Loading