diff --git a/docs/integrations/angular.md b/docs/integrations/angular.md
index f6903987..84000cf2 100644
--- a/docs/integrations/angular.md
+++ b/docs/integrations/angular.md
@@ -115,4 +115,107 @@ Finally don't forget to add gridjs theme in your index.html
}
```
-## Can I use Angular components in plugins, formatters, etc? Not yet
+## Can I use Angular components in plugins, formatters, etc? Yes!
+
+```ts
+import { AfterViewInit, Component, ElementRef, Input, TemplateRef, ViewChild, ViewContainerRef, inject } from '@angular/core';
+import { bootstrapApplication } from '@angular/platform-browser';
+import 'zone.js';
+import * as gridjs from 'gridjs';
+import {TColumn} from 'gridjs/dist/src/types';
+
+export interface IData {
+ name: string;
+}
+
+@Component({standalone: true, template: `
+ {{row?.name ?? 'no name'}}
+`})
+export class MyComponent{
+ @Input()
+ row?: IData;
+}
+
+@Component({
+ selector: 'app-root',
+ standalone: true,
+ imports: [],
+ template: `
+
+
+ {{row.name ?? 'no name'}}
+
+ `,
+})
+export class App implements AfterViewInit {
+ @ViewChild('grid') grid!: ElementRef;
+ @ViewChild('myTemplate') template!: TemplateRef;
+
+ readonly host = inject(ElementRef);
+ readonly viewContainerRef = inject(ViewContainerRef);
+
+ ngAfterViewInit() {
+ const grid = new gridjs.Grid({
+ columns: [{
+ id: 'name',
+ name: 'name (gridjs binding)'
+ }, {
+ id: 'angular-component-binding',
+ name: 'name (angular component binding)',
+ formatter: (cell, row) => {
+ return this.createComponent(MyComponent, {row: this.createRowObject(row, grid)})
+ }
+ }, {
+ id: 'angular-template-binding',
+ name: 'name (angular template binding)',
+ formatter: (cell, row) => this.createTemplate(this.template, {cell, row, rowObj: this.createRowObject(row, grid)})
+ }],
+ data: [{
+ name: 'Joe'
+ }]
+ });
+ grid.render(this.grid.nativeElement);
+ }
+
+ createRowObject(row: any, grid: gridjs.Grid) {
+ return grid.config.columns.reduce((acc, col, i) => {
+ (acc as Record)[(col as TColumn).id!] = row.cells[i].data;
+ return acc;
+ }, {} as Record);
+ }
+
+ createTemplate(templateRef: TemplateRef, context: any = {}) {
+ const ref = gridjs.createRef();
+ const div = gridjs.h('div', {ref});
+ setTimeout(() => {
+ const wrapper = ref.current as HTMLDivElement;
+ if (wrapper?.children.length === 0) {
+ const tRef = this.viewContainerRef.createEmbeddedView(templateRef, context);
+ wrapper.innerHTML = '';
+ wrapper.append(...tRef.rootNodes);
+ }
+ })
+ return div;
+ }
+
+ createComponent(componentType: any, bindInputs: Record = {}) {
+ const ref = gridjs.createRef();
+ const div = gridjs.h('div', {ref});
+ setTimeout(() => {
+ const wrapper = ref.current as HTMLDivElement;
+ if (wrapper?.children.length === 0) {
+ const componentRef = this.viewContainerRef.createComponent(componentType);
+ Object.entries(bindInputs).forEach(e => {
+ componentRef.setInput(e[0], e[1]);
+ })
+ wrapper.appendChild(componentRef.location.nativeElement);
+ }
+ })
+ return div;
+ }
+}
+
+bootstrapApplication(App);
+```
+
+See this example on StackBlitz: