# Column Sizing

## Live example

{% hint style="success" %}
[Column Sizing](https://demos.dikesoft.com/dk-grid/column/sizing) live example.
{% endhint %}

## Column width

When you define a column, this column will have an initial value for the <mark style="color:orange;">`width`</mark> property.

{% hint style="info" %}
If <mark style="color:orange;">`width`</mark> property is not defined, the **default** value will be **200**. The with's unit is **pixels**.
{% endhint %}

## Changing the column width through the UI

### Minimum and Maximum column width

If you want to change the width of a column, you must provide the <mark style="color:orange;">`minWidth`</mark> and <mark style="color:orange;">`maxWidth`</mark> properties.

{% hint style="info" %}
If you do not provide the <mark style="color:orange;">`minWidth`</mark> and <mark style="color:orange;">`maxWidth`</mark> properties, they will take the value of the <mark style="color:orange;">`width`</mark> property.
{% endhint %}

{% hint style="success" %}
If you want the user to change the column width through the UI, mark the column as **resizable**.
{% endhint %}

To see these properties in action, consider the following initial configuration:

{% tabs %}
{% tab title="column-sizing.component.html" %}

```markup
<dike-grid id="grid-col-sizing" height="500px"
    [displayRowId]="gridProperties.displayRowId"
    [gridElevation]="gridProperties.matElevation"
    [gridElevationValue]="gridProperties.elevationValue"
    [striped]="gridProperties.stripeRows"
    [verticalRowLines]="gridProperties.verticalRowLines"
    
    (gridColumnDefInstance)="onColumnDefInstance($event)"
    [datasource]="dkgDataSource">

    <dike-grid-column
        fieldName="employeeId"
        headerText="Employee Id"
        dataType="Text"
        order="0">
    </dike-grid-column>

    <dike-grid-column
        fieldName="firstName"
        headerText="Name"
        dataType="Text"
        width="150"
        order="2"
        resizable>
    </dike-grid-column>

    <dike-grid-column
        fieldName="lastName"
        headerText="Surname"
        dataType="Text"
        width="150"
        minWidth="50"
        maxWidth="300"
        order="1"
        resizable>
    </dike-grid-column>

</dike-grid>
```

{% endtab %}

{% tab title="column-sizing.component.ts" %}

```typescript
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';

import { DikeGridColumnDef, DikeGridDataSourceInput, 
  DikeTextColumnDef 
} from '@dikesoft/angular-data-grid';

import { Employee } from 'app/mock-api/common/employees/data.model';
import { SampleData } from 'app/services/sample-data.service';

@Component({
  selector: 'column-sizing',
  templateUrl: './column-sizing.component.html',
  styleUrls: ['./column-sizing.component.scss'],
  
  encapsulation: ViewEncapsulation.None,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ColumnSizingComponent implements OnInit, OnDestroy {

  dkgDataSource: DikeGridDataSourceInput<Employee>;
  gridProperties: DikeGridProperties;
  
  private columnDef: DikeGridColumnDef<Employee>;
  private changeGridPropertiesSubscription: Subscription = Subscription.EMPTY;
  
  constructor(
    private cdr: ChangeDetectorRef,
    private gridConfig: DikeGridConfig,
    private sampleData: SampleData) { }

  onColumnDefInstance(columnDef: DikeGridColumnDef<Employee>): void {
    // Define the Email column:
    const emailColumn = new DikeTextColumnDef<Employee>('email', 'Email');
    emailColumn.width = 300;
    emailColumn.order = 3;

    // Then, add the colums to the DikeGridComponent instance:
    columnDef.addColumns(emailColumn);
  }

  ngOnInit(): void {
    this.dkgDataSource = this.sampleData.getEmployees(1000);
    
    // Listening to any config property change:
    this.setChangeGridPropertiesSubscription();
  }
  
  ngOnDestroy(): void {
    this.changeGridPropertiesSubscription.unsubscribe();
  }
  
  private setChangeGridPropertiesSubscription(): void {
    this.changeGridPropertiesSubscription.unsubscribe();
    this.changeGridPropertiesSubscription = this.gridConfig.configChange.subscribe((props: DikeGridProperties) => {
      this.gridProperties = props;
      this.cdr.markForCheck();
    });
  }
}
```

{% endtab %}
{% endtabs %}

With the initial configuration, we have the following:

1. The **Employee Id** column does not define its <mark style="color:orange;">`width`</mark> nor its <mark style="color:orange;">`resizable`</mark> property.
2. You can change the **Surname** column width through the UI because the configuration sets the <mark style="color:orange;">`resizable`</mark> property and the <mark style="color:orange;">`minWidth`</mark> and <mark style="color:orange;">`maxWidth`</mark> properties have a different value of <mark style="color:orange;">`width`</mark> property.
3. The **Name** column is **resizable**, and the <mark style="color:orange;">`minWidth`</mark> and <mark style="color:orange;">`maxWidth`</mark> properties will take the same value as the <mark style="color:orange;">`width`</mark> property because this configuration does not set their values. Therefore, you will not be able to change the **Name** column width.
4. Finally, for the **Email** column, only the <mark style="color:orange;">`width`</mark> property is set.

As you can see in the following gif, you can only change the **Surname** column width but not for the **Name** column.

![Changing the column width through the UI](https://3888584995-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpDxfe6pgRLqBLMQgZ0kG%2Fuploads%2F4vuMChgiT7zWQeQvfrX7%2Fcolumn-sizing-change-width-ui.gif?alt=media\&token=bae1c593-7249-4541-abbf-ae2b8eeb11b4)

{% hint style="info" %}
When a column is **resizable**, the cursor changes to **col-resize**, and when you start resizing it, the DikeGrid draws a **vertical line**. The color of the line will be the **accent** color.
{% endhint %}

### Changing the width through the vertical row lines

If the vertical lines per row are visible, you can resize a column using them.

Let us make the vertical lines per row visible. First, open the [Floating Configuration Panel](https://docs.dikesoft.com/overview#floating-configuration-panel), then check the **Vertical Row Lines** checkbox from the **Appearance** group.

![Floating Configuration Panel - Appearance](https://3888584995-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpDxfe6pgRLqBLMQgZ0kG%2Fuploads%2FPLCFDpJj3qDGOZjCXAVq%2Fgrid-structure-vertical-row-lines-enabled.png?alt=media\&token=4a6837bb-eb98-4d2e-9a66-8d696401b547)

In the following gif, you can see how dragging a vertical line changes the size of the column.

![Changing the column width through the vertical row lines](https://3888584995-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpDxfe6pgRLqBLMQgZ0kG%2Fuploads%2FTQgK3IqBy6cyqoA7m1Ce%2Fcolumn-sizing-change-width-vertical-lines.gif?alt=media\&token=b38af87c-8856-404c-8042-4e83c5a0a299)

{% hint style="info" %}
Remember, columns displayed in the **left** or **center** panel have their **gutter-line** at their **right**. See the [Grid Structure - Gutters](https://docs.dikesoft.com/fundamentals/grid-structure/gutters#who-does-the-vertical-gutters-own) section.
{% endhint %}

### Columns in the right panel

Columns displayed in the right panel have their gutter-line at their left. Therefore, these columns change their size in an inverse direction compared to columns displayed in the left or center panel.

When you resize a column in the right panel to increase its width, you must move its gutter-line to the left.

If you want to decrease the column width, move the gutter-line to the right.

Let us create two more columns in the right panel, **Hire Date** and **Age** columns.

{% tabs %}
{% tab title="column-sizing.component.html" %}

```markup
<dike-grid id="grid-col-sizing" height="500px"
    [displayRowId]="gridProperties.displayRowId"
    [gridElevation]="gridProperties.matElevation"
    [gridElevationValue]="gridProperties.elevationValue"
    [striped]="gridProperties.stripeRows"
    [verticalRowLines]="gridProperties.verticalRowLines"

    (gridColumnDefInstance)="onColumnDefInstance($event)"
    [datasource]="dkgDataSource">
    
    <dike-grid-column
        fieldName="hireDate"
        headerText="Hire Date"
        dataType="Date"
        minWidth="50"
        maxWidth="300"
        order="1"
        resizable
        panel="rightPanel">
    </dike-grid-column>

</dike-grid>
```

{% endtab %}

{% tab title="column-sizing.component.ts" %}

```typescript
onColumnDefInstance(columnDef: DikeGridColumnDef<Employee>): void {
  // Define the Email column:
  const emailColumn = new DikeTextColumnDef<Employee>('email', 'Email');
  emailColumn.width = 300;
  emailColumn.order = 3;
  
  // Then, add the colums to the DikeGridComponent instance:
  columnDef.addColumns(emailColumn);
  
  // Define the Age column to be displayed in the right Panel:
  const ageColumn = new DikeTextColumnDef<Employee>('age', 'Age');
  ageColumn.width = 85;
  ageColumn.maxWidth = 150;
  ageColumn.order = 2;
  ageColumn.resizable = true;
  ageColumn.panel = 'rightPanel';
  
  // Add the Age column:
  columnDef.addColumns(ageColumn);
  
  // Grab the DikeGridColumnDef<T> instance:
  this.columnDef = columnDef;
  
  // Once all the columns have been added:
  Promise.resolve().then(() => {
    // Find the Employee Id column:
    const employeeId = this.columnDef.findColumn(column => column.fieldName === 'employeeId');
  
    // Set the initial values in the text boxes:
    if (!!employeeId && isDikeDataColumnDef(employeeId)) {
      this.columnSizingForm.patchValue({
        width: employeeId.width,
        minWidth: employeeId.minWidth,
        maxWidth: employeeId.maxWidth,
        resizable: employeeId.resizable
      });
    }
  });
}
```

{% endtab %}
{% endtabs %}

![Resizing a column in the right panel](https://3888584995-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpDxfe6pgRLqBLMQgZ0kG%2Fuploads%2F7Ho5TvuMoq1VcByT4dMC%2Fcolumn-sizing-change-width-right-panel-ui.gif?alt=media\&token=96446c42-3dd5-4c54-9123-9177bf9a3edc)

#### Dragging the panel division line

When you drag the line that divides two adjacent panels, all columns resize evenly. The resizing operation finishes until all columns reach their minimum or maximum width.

![Dragging the panel division line](https://3888584995-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpDxfe6pgRLqBLMQgZ0kG%2Fuploads%2FOpO7w4Bt9K12GIpoGS5H%2Fcolumn-sizing-change-width-right-panel-line-ui.gif?alt=media\&token=f77bd3a0-6c25-405b-b7f7-d11bbff626c5)

The same occurs for columns displayed in the left panel.

{% hint style="success" %}
You can change the width of the panel division line when the panel is being resized by providing an Injection Token called <mark style="color:blue;">`DIVISION_PANEL_LINE_WIDTH_RESIZING`</mark>. By default, the width is **5 pixels** in width.
{% endhint %}

## DikeGrid Column API

You can change the size properties using the API from the [<mark style="color:green;">`DikeGridColumnDef`</mark>](https://docs.dikesoft.com/reference/dkgrid-api/dkgridcolumndef)service instance.

{% hint style="success" %}
In the [Column Definition](https://docs.dikesoft.com/column-definitions#dikegridcolumndef-less-than-t-greater-than-service) section, see how to grab the [<mark style="color:green;">`DikeGridColumnDef`</mark>](https://docs.dikesoft.com/reference/dkgrid-api/dkgridcolumndef) instance from the corresponding [<mark style="color:green;">`DikeGridComponent`</mark>](https://docs.dikesoft.com/reference/components/dkgridcomponent)<mark style="color:green;">.</mark>
{% endhint %}

### Employee Id column

Since the **Employee Id** column is not resizable and its <mark style="color:orange;">`width`</mark> property is not defined, let us add the UI controls and the corresponding code to change its width using the DikeGrid API.

{% code title="column-sizing.component.html" %}

```markup
<div class="p-4 leading-6 text-secondary"><strong>Employee Id</strong></div>
<form [formGroup]="columnSizingForm"
    class="flex flex-col p-4 overflow-hidden">
    <div class="flex flex-row flex-wrap items-center">
        <mat-form-field class="flex-auto pr-3">
            <mat-label>Width</mat-label>
            <input matInput
                type="number"
                formControlName="width">

            <mat-hint align="end">Numeric value</mat-hint>
            <mat-error *ngIf="getControl('width') as widthControl">
                <div *ngIf="widthControl.errors?.['required']">Required</div>
                <div *ngIf="widthControl.errors?.['min']">Min value 25</div>
                <div *ngIf="widthControl.errors?.['max']">Max value 600</div>
            </mat-error>
        </mat-form-field>

        <mat-form-field class="flex-auto pr-3">
            <mat-label>Min width</mat-label>
            <input matInput
                type="number"
                formControlName="minWidth">

            <mat-hint align="end">Numeric value</mat-hint>
            <mat-error *ngIf="getControl('minWidth') as minWidthControl">
                <div *ngIf="minWidthControl.errors?.['min']">Min value 25</div>
                <div *ngIf="minWidthControl.errors?.['max']">Max value 600</div>
            </mat-error>
        </mat-form-field>

        <mat-form-field class="flex-auto pr-3">
            <mat-label>Max width</mat-label>
            <input matInput
                type="number"
                formControlName="maxWidth">

            <mat-hint align="end">Numeric value</mat-hint>
            <mat-error *ngIf="getControl('maxWidth') as maxWidthControl">
                <div *ngIf="maxWidthControl.errors?.['min']">Min value 25</div>
                <div *ngIf="maxWidthControl.errors?.['max']">Max value 600</div>
            </mat-error>
        </mat-form-field>

        <div class="flex-auto flex flex-row justify-around items-center">
            <button mat-raised-button
                class="w-32"
                color="primary"
                [disabled]="!columnSizingForm.valid"
                (click)="onChangeColumnSize()">Apply
            </button>
            <mat-checkbox class="w-24"
                formControlName="resizable"
                (change)="onResizableChange($event)">Resizable
            </mat-checkbox>
        </div>
    </div>
</form>
```

{% endcode %}

The previous <mark style="color:red;">`form`</mark> is added above the <mark style="color:red;">`dike-grid`</mark> selector generating the following output:

![UI for changing the Employee Id column width](https://3888584995-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpDxfe6pgRLqBLMQgZ0kG%2Fuploads%2FmuPmBv0xmxyXbGe4zDbR%2Fcolum-sizing-employeeId-width.png?alt=media\&token=2f1686b4-192b-486e-8310-2959987acd3c)

Now, you can change the **Employee Id** column's width, min-width, and max-width. If you click on the **checkbox** next to the Apply button, you can **mark** the Employee Id column as **resizable**.

#### Changing the width using the API

Consider the following code:

{% tabs %}
{% tab title="column-sizing.component.html" %}

```markup
<div class="flex-auto flex flex-row justify-around items-center">
    <button mat-raised-button
        class="w-32"
        color="primary"
        [disabled]="!columnSizingForm.valid"
        (click)="onChangeColumnSize()">Apply
    </button>
    <mat-checkbox class="w-24"
        formControlName="resizable"
        (change)="onResizableChange($event)">Resizable
    </mat-checkbox>
</div>
```

{% endtab %}

{% tab title="column-sizing.component.ts" %}

```typescript
onChangeColumnSize(): void {
  // Search the employeeId column:
  const targetColumn = this.columnDef.findColumn(column => column.fieldName === 'employeeId');

  if (!!targetColumn && isDikeDataColumnDef(targetColumn)) {
    // If the column is found:
    const width: number = this.columnSizingForm.get('width').value as number;
    const minWidth: number | null = this.columnSizingForm.get('minWidth').value;
    const maxWidth: number | null = this.columnSizingForm.get('maxWidth').value;

    // Change the column size:
    this.columnDef.changeColumnWidth(targetColumn, { width, minWidth, maxWidth });
  }
}
```

{% endtab %}
{% endtabs %}

Once the input elements pass the validators, the button can invoke the callback method. Inside the callback definition:

1. Firstly, you must find the column to be modified.
2. Notice how the found column instance is narrowing to a reference of type [<mark style="color:green;">`DikeDataColumnDef`</mark>](https://docs.dikesoft.com/reference/classes/columns#dikedatacolumndef-less-than-t-r-greater-than), due to the `findColumn()` method returns a reference of type [<mark style="color:green;">`DikeColumnDef`</mark>](https://docs.dikesoft.com/reference/classes/columns#dikecolumndef).
3. The code uses the `changeColumnWidth()` method to pass the column instance and the size properties, where only the width is mandatory.

{% hint style="info" %}
Internally, the [<mark style="color:green;">`DikeGridComponent`</mark>](https://docs.dikesoft.com/reference/components/dkgridcomponent) validates the **width**, **minWidth**, and **maxWidth** arguments. For instance, if minWidth is greater than the width, the width value is assigned to minWidth.
{% endhint %}

{% hint style="info" %}
Despite the <mark style="color:orange;">`resizable`</mark> property for the **Employee Id** column is not set, the size properties of the column can be changed using the API.
{% endhint %}

#### Setting the resizable property

Remember that the <mark style="color:orange;">`resizable`</mark> property allows the user to change the width of a column or column group.

The following code snippet is the callback attached to the **checkbox change Event**.

{% code title="column-sizing.component.ts" %}

```typescript
onResizableChange(value: MatCheckboxChange): void {
  // Search the employeeId column:
  const targetColumn = this.columnDef.findColumn(column => column.fieldName === 'employeeId');

  if (!!targetColumn) {
    // If the column is found, change its resizable property:
    this.columnDef.setColumnResizable(targetColumn, value.checked);
  }
}
```

{% endcode %}

Once again, the target column must be found, in this case. The method `setColumnResizable()` marks the **Employee Id** column as **resizable**.

![Resizing the Employee Id column after setting it as resizable](https://3888584995-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpDxfe6pgRLqBLMQgZ0kG%2Fuploads%2FbLrO4vNAHWL2DWY9RQUi%2Fcolumn-sizing-change-width-after-api-ui.gif?alt=media\&token=3679b0a8-0d1d-476f-9918-b6dfffe9f9dd)

The previous output shows how the **Employee Id** column is resized after setting it as **resizable**. We must have changed the <mark style="color:orange;">`minWidth`</mark>, or <mark style="color:orange;">`maxWidth`</mark> properties as well.

{% hint style="info" %}
Even though a column is marked as **resizable**, if the <mark style="color:orange;">`minWidth`</mark> and <mark style="color:orange;">`maxWidth`</mark> properties have the same value as the <mark style="color:orange;">`width`</mark> property, the column will not resize using the UI.
{% endhint %}

## Column Sizing Event

If you notice, the last output reports the changes in the <mark style="color:orange;">`width`</mark> property of the **Employee Id** column when this one is being resized.

The [<mark style="color:green;">`DikeGridComponent`</mark>](https://docs.dikesoft.com/reference/components/dkgridcomponent) emits an Event called `columnSizeChange`. This event is emitted every time a data column changes its size.

{% hint style="info" %}
The [<mark style="color:green;">`DikeGridColumnDef`</mark>](https://docs.dikesoft.com/reference/dkgrid-api/dkgridcolumndef)service also emits the `columnSizeChange` event.
{% endhint %}

{% tabs %}
{% tab title="column-sizing.component.html" %}

```markup
<dike-grid id="grid-col-sizing" height="500px"
    (columnSizeChange)="onColumnSizeChange($event)">
</dike-grid>
```

{% endtab %}

{% tab title="column-sizing.component.ts" %}

```typescript
onColumnSizeChange(column: DikeDataColumnDef<Employee, unknown>): void {
  if (column.fieldName === 'employeeId') {
    this.columnSizingForm.patchValue({
      width: column.width,
      minWidth: column.minWidth,
      maxWidth: column.maxWidth
    });
  }
}
```

{% endtab %}
{% endtabs %}

Since the `columnSizeChange` event sends any column that has changed in width, the if statement gives us the **Employee Id** column.

## Resizing Groups

By definition, a column group's width equals the sum of its child columns' width. Therefore, a column group does not have a <mark style="color:orange;">`width`</mark> property.

All descendant columns, marked as **resizable**, will change in width when resizing a group.

{% hint style="info" %}
The `columnSizeChange` event does not send the group itself nor the descendant groups. Instead, it only **sends** the descendant **data columns**.
{% endhint %}

Let us define the following configuration:

1. Firstly, We have a primary group named **Personal Info**.
2. Under the **Personal Info** group, we have the **Complete Name** column group, the **Gender** and **Age** columns.
3. Finally, we have **Name** and **Surname** columns under the **Complete Name** group.
4. Except for the **Complete Name** group, all columns and column groups are resizable.

{% code title="column-sizing.component.ts" %}

```markup
<dike-grid id="grid-col-sizing" height="500px">
    <dike-grid-column
        fieldName="personalInfoGroup"
        headerText="Personal Info"
        order="0"
        resizable>
    
        <dike-grid-column
            fieldName="completeNameGroup"
            headerText="Complete Name">
    
            <dike-grid-column
                fieldName="firstName"
                headerText="Name"
                dataType="Text"
                width="150"
                minWidth="50"
                maxWidth="300"
                resizable>
            </dike-grid-column>
    
            <dike-grid-column
                fieldName="lastName"
                headerText="Surname"
                dataType="Text"
                width="150"
                minWidth="50"
                maxWidth="300"
                resizable>
            </dike-grid-column>
        </dike-grid-column>
    
        <dike-grid-column
            fieldName="gender"
            headerText="Gender"
            dataType="Binary"
            width="110"
            minWidth="50"
            maxWidth="200"
            resizable>
        </dike-grid-column>
    
        <dike-grid-column
            fieldName="age"
            headerText="Age"
            dataType="Numeric"
            contentAlign="center"
            width="85"
            minWidth="50"
            maxWidth="120"
            resizable>
        </dike-grid-column>
    </dike-grid-column>
</dike-grid>
```

{% endcode %}

{% hint style="info" %}
Column groups marked as **resizable** can change in width only from the UI.
{% endhint %}

![Resizing Groups](https://3888584995-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpDxfe6pgRLqBLMQgZ0kG%2Fuploads%2FcwXGpUnnS37MsyCu8Q6A%2Fgroup-sizing.gif?alt=media\&token=4122e784-d88e-485c-af42-4015f509d255)

As you can see in the previous output:

1. When resizing the **Personal Info** group, the operation draws a vertical line with an **accent** color until the columns.
2. The resize process draws the line only into the column's boundary for the **Surname** column.

{% hint style="success" %}
Remember, for resizing a column or a group, you must grab the gutter-line for the column. See the [Grid Structure - Gutters](https://docs.dikesoft.com/fundamentals/grid-structure/gutters#who-does-the-vertical-gutters-own) section for more details.
{% endhint %}

## Summary

Once you define a column at the creation phase, you can change its width at execution time, either from the **UI** or the **API**. Columns that are resizing through the UI must be **resizable**.

The DikeGrid instance only **sends** the changed **data columns** when the resizing operation occurs, not column groups.

### Complete code for this section

{% tabs %}
{% tab title="column-sizing.component.html" %}

```markup
<div class="p-4 leading-6 text-secondary"><strong>Employee Id</strong></div>
<form [formGroup]="columnSizingForm"
    class="flex flex-col p-4 overflow-hidden">
    <div class="flex flex-row flex-wrap items-center">
        <mat-form-field class="flex-auto pr-3">
            <mat-label>Width</mat-label>
            <input matInput
                type="number"
                formControlName="width">

            <mat-hint align="end">Numeric value</mat-hint>
            <mat-error *ngIf="getControl('width') as widthControl">
                <div *ngIf="widthControl.errors?.['required']">Required</div>
                <div *ngIf="widthControl.errors?.['min']">Min value 25</div>
                <div *ngIf="widthControl.errors?.['max']">Max value 600</div>
            </mat-error>
        </mat-form-field>

        <mat-form-field class="flex-auto pr-3">
            <mat-label>Min width</mat-label>
            <input matInput
                type="number"
                formControlName="minWidth">

            <mat-hint align="end">Numeric value</mat-hint>
            <mat-error *ngIf="getControl('minWidth') as minWidthControl">
                <div *ngIf="minWidthControl.errors?.['min']">Min value 25</div>
                <div *ngIf="minWidthControl.errors?.['max']">Max value 600</div>
            </mat-error>
        </mat-form-field>

        <mat-form-field class="flex-auto pr-3">
            <mat-label>Max width</mat-label>
            <input matInput
                type="number"
                formControlName="maxWidth">

            <mat-hint align="end">Numeric value</mat-hint>
            <mat-error *ngIf="getControl('maxWidth') as maxWidthControl">
                <div *ngIf="maxWidthControl.errors?.['min']">Min value 25</div>
                <div *ngIf="maxWidthControl.errors?.['max']">Max value 600</div>
            </mat-error>
        </mat-form-field>

        <div class="flex-auto flex flex-row justify-around items-center">
            <button mat-raised-button
                class="w-32"
                color="primary"
                [disabled]="!columnSizingForm.valid"
                (click)="onChangeColumnSize()">Apply
            </button>
            <mat-checkbox class="w-24"
                formControlName="resizable"
                (change)="onResizableChange($event)">Resizable
            </mat-checkbox>
        </div>
    </div>
</form>

<dike-grid id="grid-col-sizing" height="500px"
    [displayRowId]="gridProperties.displayRowId"
    [gridElevation]="gridProperties.matElevation"
    [gridElevationValue]="gridProperties.elevationValue"
    [striped]="gridProperties.stripeRows"
    [verticalRowLines]="gridProperties.verticalRowLines"

    (gridColumnDefInstance)="onColumnDefInstance($event)"
    (columnSizeChange)="onColumnSizeChange($event)"
    [datasource]="dkgDataSource">

    <dike-grid-column
        fieldName="employeeId"
        headerText="Employee Id"
        dataType="Text"
        order="0">
    </dike-grid-column>

    <dike-grid-column
        fieldName="firstName"
        headerText="Name"
        dataType="Text"
        width="150"
        order="2"
        resizable>
    </dike-grid-column>

    <dike-grid-column
        fieldName="lastName"
        headerText="Surname"
        dataType="Text"
        width="150"
        minWidth="50"
        maxWidth="300"
        order="1"
        resizable>
    </dike-grid-column>

    <dike-grid-column
        fieldName="personalInfoGroup"
        headerText="Personal Info"
        order="0"
        resizable>

        <dike-grid-column
            fieldName="completeNameGroup"
            headerText="Complete Name">

            <dike-grid-column
                fieldName="firstName"
                headerText="Name"
                dataType="Text"
                width="150"
                minWidth="50"
                maxWidth="300"
                resizable>
            </dike-grid-column>

            <dike-grid-column
                fieldName="lastName"
                headerText="Surname"
                dataType="Text"
                width="150"
                minWidth="50"
                maxWidth="300"
                resizable>
            </dike-grid-column>
        </dike-grid-column>

        <dike-grid-column
            fieldName="gender"
            headerText="Gender"
            dataType="Binary"
            width="110"
            minWidth="50"
            maxWidth="200"
            resizable>
        </dike-grid-column>

        <dike-grid-column
            fieldName="age"
            headerText="Age"
            dataType="Numeric"
            contentAlign="center"
            width="85"
            minWidth="50"
            maxWidth="120"
            resizable>
        </dike-grid-column>
    </dike-grid-column>

    <dike-grid-column
        fieldName="hireDate"
        headerText="Hire Date"
        dataType="Date"
        minWidth="50"
        maxWidth="300"
        order="1"
        resizable
        panel="rightPanel">
    </dike-grid-column>
</dike-grid>
```

{% endtab %}

{% tab title="column-sizing.component.ts" %}

```typescript
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { AbstractControl, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { MatCheckboxChange } from '@angular/material/checkbox';

import { Subscription } from 'rxjs';

import { DikeDataColumnDef, DikeGridColumnDef, DikeGridDataSourceInput,
  DikeTextColumnDef, isDikeDataColumnDef } from '@dikesoft/angular-data-grid';

import { Employee } from 'app/mock-api/common/employees/data.model';
import { DikeGridProperties } from 'app/core/config/dike-grid.properties';

import { DikeGridConfig } from 'app/services/dike-grid.config.service';
import { SampleData } from 'app/services/sample-data.service';

@Component({
  selector: 'column-sizing',
  templateUrl: './column-sizing.component.html',
  styleUrls: ['./column-sizing.component.scss'],

  encapsulation: ViewEncapsulation.None,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ColumnSizingComponent implements OnInit, OnDestroy {

  dkgDataSource: DikeGridDataSourceInput<Employee>;
  columnSizingForm: FormGroup;
  gridProperties: DikeGridProperties;

  private columnDef: DikeGridColumnDef<Employee>;
  private changeGridPropertiesSubscription: Subscription = Subscription.EMPTY;

  constructor(
    private cdr: ChangeDetectorRef,
    private formBuilder: FormBuilder,
    private gridConfig: DikeGridConfig,
    private sampleData: SampleData) { }

  onColumnDefInstance(columnDef: DikeGridColumnDef<Employee>): void {
    // Define the Email column:
    const emailColumn = new DikeTextColumnDef<Employee>('email', 'Email');
    emailColumn.width = 300;
    emailColumn.order = 3;

    // Then, add the colums to the DikeGridComponent instance:
    columnDef.addColumns(emailColumn);

    // Define the Age column to be displayed in the right Panel:
    const ageColumn = new DikeTextColumnDef<Employee>('age', 'Age');
    ageColumn.width = 85;
    ageColumn.maxWidth = 150;
    ageColumn.order = 2;
    ageColumn.resizable = true;
    ageColumn.panel = 'rightPanel';

    // Add the Age column:
    columnDef.addColumns(ageColumn);

    // Grab the DikeGridColumnDef<T> instance:
    this.columnDef = columnDef;

    // Once all the columns have been added:
    Promise.resolve().then(() => {
      // Find the Employee Id column:
      const employeeId = this.columnDef.findColumn(column => column.fieldName === 'employeeId');

      // Set the initial values in the text boxes:
      if (!!employeeId && isDikeDataColumnDef(employeeId)) {
        this.columnSizingForm.patchValue({
          width: employeeId.width,
          minWidth: employeeId.minWidth,
          maxWidth: employeeId.maxWidth,
          resizable: employeeId.resizable
        });
      }
    });
  }

  ngOnInit(): void {
    this.dkgDataSource = this.sampleData.getEmployees(1000);
    // Creating the form that binds the UI ontrols:
    this.columnSizingForm = this.createMainForm();
    // Listening to any config property change:
    this.setChangeGridPropertiesSubscription();
  }

  ngOnDestroy(): void {
    this.changeGridPropertiesSubscription.unsubscribe();
  }

  getControl(formControlName: string): AbstractControl {
    return this.columnSizingForm.get(formControlName);
  }

  onColumnSizeChange(column: DikeDataColumnDef<Employee, string>): void {
    if (column.fieldName === 'employeeId') {
      this.columnSizingForm.patchValue({
        width: column.width,
        minWidth: column.minWidth,
        maxWidth: column.maxWidth
      });
    }
  }

  onResizableChange(value: MatCheckboxChange): void {
    // Search the employeeId column:
    const targetColumn = this.columnDef.findColumn(column => column.fieldName === 'employeeId');

    if (!!targetColumn) {
      // If the column is found, change its resizable property:
      this.columnDef.setColumnResizable(targetColumn, value.checked);
    }
  }

  onChangeColumnSize(): void {
    // Search the employeeId column:
    const targetColumn = this.columnDef.findColumn(column => column.fieldName === 'employeeId');

    if (!!targetColumn && isDikeDataColumnDef(targetColumn)) {
      // If the column is found:
      const width: number = this.columnSizingForm.get('width').value as number;
      const minWidth: number | null = this.columnSizingForm.get('minWidth').value;
      const maxWidth: number | null = this.columnSizingForm.get('maxWidth').value;

      // Change the column size:
      this.columnDef.changeColumnWidth(targetColumn, { width, minWidth, maxWidth });
    }
  }

  private createMainForm(): FormGroup {
    const mainForm = this.formBuilder.group({
        resizable: [false]
    });

    const widthControl = new FormControl('',
        [Validators.required, Validators.min(25), Validators.max(600), Validators.pattern('^[0-9]*$')]);
    widthControl.markAllAsTouched();

    const minWidthControl = new FormControl('',
        [Validators.min(25), Validators.max(600), Validators.pattern('^[0-9]*$')]);
    minWidthControl.markAsTouched();

    const maxWidthControl = new FormControl('',
        [Validators.min(25), Validators.max(600), Validators.pattern('^[0-9]*$')]);
    maxWidthControl.markAllAsTouched();

    mainForm.addControl('width', widthControl);
    mainForm.addControl('minWidth', minWidthControl);
    mainForm.addControl('maxWidth', maxWidthControl);

    return mainForm;
  }

  private setChangeGridPropertiesSubscription(): void {
    this.changeGridPropertiesSubscription.unsubscribe();
    this.changeGridPropertiesSubscription = this.gridConfig.configChange.subscribe((props: DikeGridProperties) => {
      this.gridProperties = props;
      this.cdr.markForCheck();
    });
  }
}

```

{% endtab %}
{% endtabs %}
