Basic grid

demo.component.html
<ftui-grid-toolbar [instance]="userGrid"></ftui-grid-toolbar>
<ftui-grid
    id="userGrid"
    #userGrid
    [source]="users"
    [columns]="columns">
</ftui-grid>
demo.component.ts
protected columns: FtuiGridColumn<User>[] =  [
    {
        datafield: "id",
        name: "app.common.id",
        type: "number",
    },
    {
        datafield: "name",
        name: "app.common.name",
        type: "string",
    },
    {
        datafield: "deadline",
        name: "app.common.deadline",
        format: "dd. MMMM yyyy",
        type: 'date'
    }
];

protected users: User[] = {
    {
        id: 0,
        name: "Lynn Hermiston",
        deadline: new Date("2001-09-09")
    }
    {
        id: 0,
        name: "Mario Mertz",
        deadline: new Date("2001-09-09")
    }
    {
        id: 0,
        name: "Ada Lovelace",
        deadline: new Date("2001-09-09")
    }
}

Color cells based on containing data

Use the classes callback to define additional CSS classes.

demo.component.ts
import { isAfter } from "date-fns";

// ...

const coloredColumns: FtuiGridColumn<User>[] = [
    {
        datafield: "deadline",
        name: "app.common.deadline",
        format: "dd. MMMM yyyy",
        type: 'date',
        classes: (data: Date, row: User) => {
            if (isAfter(data, new Date())) return 'bg-warning bg-opacity-50';
            return 'bg-success bg-opacity-50';
        }
    }
];
These classes must be global (e.g. defined in the global styles.scss). If they are just defined in the component’s stylesheet they won’t cascade through Angular’s view encapsulation. Bootstrap’s utility classes are globally available and cover many options.

Act on row select

Enable row selection, query the grid instance via a template variable and the @ViewChild decorator and subscribe to selection events.

demo.component.html
<ftui-grid
    id="userGrid"
    #userGrid
    [source]="users"
    [options]="options"
    [columns]="columns">
</ftui-grid>
demo.component.ts
@ViewCHild('userGrid') userGrid!: FtuiGridComponent<User>;

protected options: FtuiGridOptions = {
    rowSelect: "single" // "dynamic" is default
};

public ngAfterViewInit() {
    // grid instance is rendered and can be queried at this point in the component's life cycle
    this.userGrid.selectedRows$.subscribe((rows: User[]) => {
      console.log(rows);
      // don't forget to unsubscribe!
    });
}

Drag and drop

Enable drag and drop between two Grids. The draggable Grid provides the selected rows as the dragged data.

demo.component.html
<ftui-grid
    id="source-grid"
    [source]="users"
    [options]="options"
    [columns]="columns">
</ftui-grid>

<ftui-grid
    id="target-grid"
    (dropped)="handleDrop($event)"
    [source]="approvedUsers"
    [columns]="columnsDeclined">
</ftui-grid>
demo.component.ts
protected options: FtuiGridOptions = {
    draggable: true,
    dragSource: () => "identifierOfSourceGrid" // defaults to Grid's id
};

protected onDataDrop(event: FtuiDropEvent<User[], number>) {
    console.log("Data: ", event.data);
    console.log("From source: ", event.source);
    console.log("Dropped before row: ", event.dropContext);
  }

See the docs for FtuiDropEvent for further information.

Contextmenu

Consider putting the menu definition in a variable and apply it to all columns, so the user doesn’t need to search for certain menu items across the Grid.
const columns: FtuiGridColumn<Machine>[] = [
    {
        datafield: "value",
        name: "app.common.value",
        type: 'number',
        menu: [
            {
                label: "app.common.boost",
                icon: "plus",
                disabled: (data: number, row: Machine) => data > 0,
                action: (data: number, row: Machine) => this.boostValue(row)
            },
            {
                label: "app.common.export",
                icon: "file-excel",
                action: (data: number, row: Machine) => this.export(row)
            }
        ],
    },
    // ...
];
Unfortunately right now, the icon property requires a IconProp, not an IconDefinition.