---
title: "Row Dragging Customisation"
framework: vue
version: "36.1.0"
---

# Row Dragging Customisation

There are some options that can be used to customise the Row Drag experience, so it has a better integration with your application.

## Entire Row Dragging

When using row dragging it is also possible to reorder rows by clicking and dragging anywhere on the row without the need for a drag handle by enabling the `rowDragEntireRow` grid option.

#### Entire Row Dragging

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  NumberFilterModule,
  RowDragModule,
  RowSelectionModule,
  RowSelectionOptions,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  TextFilterModule,
  NumberFilterModule,
  RowDragModule,
  RowSelectionModule,
  ClientSideRowModelModule,
]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :rowDragManaged="true"
      :rowDragEntireRow="true"
      :rowDragMultiRow="true"
      :rowSelection="rowSelection"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      { field: "athlete" },
      { field: "country" },
      { field: "year", width: 100 },
      { field: "date" },
      { field: "sport" },
      { field: "gold" },
      { field: "silver" },
      { field: "bronze" },
    ]);
    const defaultColDef = ref<ColDef>({
      width: 170,
      filter: true,
    });
    const rowSelection = ref<RowSelectionOptions | "single" | "multiple">({
      mode: "multiRow",
    });
    const rowData = ref<IOlympicData[]>(null);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => (rowData.value = data);

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      rowSelection,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Entire Row Dragging](https://www.ag-grid.com/examples/row-dragging-customisation/entire-row-dragging/vue3)

The example above demonstrates entire row dragging with [Multi-Row Dragging](https://www.ag-grid.com/vue-data-grid/row-dragging-managed/#multi-row-dragging). Note the following:

- Reordering rows by clicking and dragging anywhere on a row is possible as `rowDragEntireRow` is enabled.
- Multiple rows can be selected and dragged as `rowDragMultiRow` is also enabled with `rowSelection.mode = 'multiRow'`.
- Row Drag Managed is being used, but it is not a requirement for Entire Row Dragging.

To enable entire row dragging, set the `rowDragEntireRow` property to `true` in the `gridOptions` as shown below:

```ts
<ag-grid-vue
    :columnDefs="columnDefs"
    :rowDragEntireRow="rowDragEntireRow"
    /* other grid options ... */>
</ag-grid-vue>

this.columnDefs = [
    { field: 'country' },
    { field: 'year' },
    { field: 'sport' },
    { field: 'total' }
];
// allows rows to be dragged without the need for drag handles
this.rowDragEntireRow = true;
```

> **Warning**
>
> [Cell Selection](https://www.ag-grid.com/vue-data-grid/cell-selection/) is not supported when `rowDragEntireRow` is enabled.

## Custom Row Drag Text

When a row drag starts, a "floating" DOM element is created to indicate which row is being dragged. By default, this DOM element will contain the same value as the cell that started the row drag. It's possible to override that text by using the `gridOptions.rowDragText` callback.

#### Row Drag With Custom Text

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  IRowDragItem,
  ModuleRegistry,
  NumberFilterModule,
  RowDragModule,
  RowDragTextFunc,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  TextFilterModule,
  NumberFilterModule,
  RowDragModule,
  ClientSideRowModelModule,
]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :rowDragText="rowDragText"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :rowDragManaged="true"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const rowDragText = ref<RowDragTextFunc>(function (params: IRowDragItem) {
      // keep double equals here because data can be a string or number
      if (params.rowNode!.data.year == "2012") {
        return params.defaultTextValue + " (London Olympics)";
      }
      return params.defaultTextValue;
    });
    const columnDefs = ref<ColDef[]>([
      { field: "athlete", rowDrag: true },
      { field: "country" },
      { field: "year", width: 100 },
      { field: "date" },
      { field: "sport" },
      { field: "gold" },
      { field: "silver" },
      { field: "bronze" },
    ]);
    const defaultColDef = ref<ColDef>({
      width: 170,
      filter: true,
    });
    const rowData = ref<IOlympicData[]>(null);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => (rowData.value = data);

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      rowDragText,
      columnDefs,
      defaultColDef,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Row Drag With Custom Text](https://www.ag-grid.com/examples/row-dragging-customisation/custom-drag-text/vue3)

The example above shows dragging with custom text. The following can be noted:

- When you drag a row of the year 2012, the `rowDragText` callback will add **(London Olympics)** to the floating drag element.

To enable custom row drag text, set the `rowDragText` callback in the `gridOptions` as shown below:

```ts
<ag-grid-vue
    :columnDefs="columnDefs"
    :rowDragText="rowDragText"
    /* other grid options ... */>
</ag-grid-vue>

this.columnDefs = [
    {
        field: 'athlete',
        rowDrag: true
    }, {
        field: 'country'
    }
];
this.rowDragText = (params, dragItemCount) => {
    return (
        dragItemCount > 1
            ? (dragItemCount + ' items')
            : params.defaultTextValue + ' is'
    ) + ' being dragged...';
};
```

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `rowDragText` | `RowDragTextFunc` |  |  | A callback that should return a string to be displayed by the `rowDragComp` while dragging a row. If this callback is not set, the current cell value will be used. If the `rowDragText` callback is set in the ColDef it will take precedence over this, except when `rowDragEntireRow=true`. Module: [`RowDragModule`](https://www.ag-grid.com/vue-data-grid/modules/). [Initial](https://www.ag-grid.com/vue-data-grid/grid-interface/#initial-grid-options). |

## Custom Row Drag Text with Multiple Draggers

If the grid has more than one column set with `rowDrag=true`, the `rowDragText` callback can be set in the `colDef`.

#### Row Drag With Custom Text and Multiple Draggers

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  IRowDragItem,
  ModuleRegistry,
  NumberFilterModule,
  RowDragModule,
  RowDragTextFunc,
  RowSelectionModule,
  RowSelectionOptions,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  TextFilterModule,
  NumberFilterModule,
  RowDragModule,
  RowSelectionModule,
  ClientSideRowModelModule,
]);

const athleteRowDragTextCallback = function (
  params: IRowDragItem,
  dragItemCount: number,
) {
  // keep double equals here because data can be a string or number
  return `${dragItemCount} athlete(s) selected`;
};

const rowDragTextCallback = function (params: IRowDragItem) {
  // keep double equals here because data can be a string or number
  if (params.rowNode!.data.year == "2012") {
    return params.defaultTextValue + " (London Olympics)";
  }
  return params.defaultTextValue;
};

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :rowDragManaged="true"
      :rowDragText="rowDragText"
      :rowDragMultiRow="true"
      :rowSelection="rowSelection"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      {
        field: "athlete",
        rowDrag: true,
        rowDragText: athleteRowDragTextCallback,
      },
      { field: "country", rowDrag: true },
      { field: "year", width: 100 },
      { field: "date" },
      { field: "sport" },
      { field: "gold" },
      { field: "silver" },
      { field: "bronze" },
    ]);
    const defaultColDef = ref<ColDef>({
      width: 170,
      filter: true,
    });
    const rowDragText = ref<RowDragTextFunc>(rowDragTextCallback);
    const rowSelection = ref<RowSelectionOptions | "single" | "multiple">({
      mode: "multiRow",
    });
    const rowData = ref<IOlympicData[]>(null);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => (rowData.value = data);

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      rowDragText,
      rowSelection,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Row Drag With Custom Text and Multiple Draggers](https://www.ag-grid.com/examples/row-dragging-customisation/custom-drag-multiple-draggers/vue3)

The example above shows dragging with custom text and multiple column draggers. The following can be noted:

- When you drag a row with a year of 2012 by the country row dragger, the `rowDragText` callback will add **(London Olympics)** to the floating drag element.
- When you drag the row by the athlete row dragger, the `rowDragText` callback in the `gridOptions` will be overridden by the one in the `colDef` and will display the number of **athletes selected**.

To enable custom row drag text per column dragger, set the `rowDragText` callback in the `colDef` as shown below:

```ts
<ag-grid-vue
    :columnDefs="columnDefs"
    :rowDragText="rowDragText"
    /* other grid options ... */>
</ag-grid-vue>

this.columnDefs = [
    {
        field: 'athlete',
        rowDrag: true,
        rowDragText: (params, dragItemCount) => {
            const suffix = dragItemCount == 1 ? 'athlete' : 'athletes';
            return `Dragging ${dragItemCount} ${suffix}`;
        }
    }, {
        field: 'country',
        rowDrag: true,
    }
];
this.rowDragText = (params, dragItemCount) => {
    return (
        dragItemCount > 1
            ? (dragItemCount + ' items')
            : params.defaultTextValue + ' is'
    ) + ' being dragged...';
};
```

## Row Dragger inside Custom Cell Renderers

Due to the complexity of some applications, it could be handy to render the Row Drag Component inside of a Custom Cell Renderer. This can be achieved by using the `registerRowDragger` method in the [ICellRendererParams](https://www.ag-grid.com/vue-data-grid/component-cell-renderer/).

#### Row Drag With Custom Cell Renderer

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./styles.css";
import {
  CellStyleModule,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  NumberFilterModule,
  RowDragModule,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import CustomCellRenderer from "./customCellRendererVue";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  TextFilterModule,
  NumberFilterModule,
  RowDragModule,
  CellStyleModule,
  ClientSideRowModelModule,
]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :rowDragManaged="true"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
    CustomCellRenderer,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      {
        field: "athlete",
        cellClass: "custom-athlete-cell",
        cellRenderer: "CustomCellRenderer",
      },
      { field: "country" },
      { field: "year", width: 100 },
      { field: "date" },
      { field: "sport" },
      { field: "gold" },
      { field: "silver" },
      { field: "bronze" },
    ]);
    const defaultColDef = ref<ColDef>({
      width: 170,
      filter: true,
    });
    const rowData = ref<IOlympicData[]>(null);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => (rowData.value = data);

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Row Drag With Custom Cell Renderer](https://www.ag-grid.com/examples/row-dragging-customisation/dragger-inside-custom-cell-renderer/vue3)

The example above shows a custom cell renderer using the `registerRowDragger` callback to render the Row Dragger inside itself.

- When you hover the cells, an arrow will appear, and this arrow can be used to **drag** the rows.

To register a custom row dragger inside a custom cell renderer, use the `registerRowDragger` method from the `ICellRendererParams` as shown below:

```js
// your custom cell renderer code
mounted() {
    this.params.registerRowDragger(this.$refs.myRef);
}
```

> **Warning**
>
> When using `registerRowDragger` you should **not** set the property `rowDrag=true` in the Column Definition. Doing that will cause the cell to have two row draggers.

## Full Width Row Dragging

It is possible to drag [Full Width Rows](https://www.ag-grid.com/vue-data-grid/full-width-rows/) by registering a [Custom Row Dragger](#row-dragger-inside-custom-cell-renderers).

#### Row Drag with Full Width Rows

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./style.css";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GetRowHeight,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ICellRendererParams,
  IsFullWidthRow,
  IsFullWidthRowParams,
  ModuleRegistry,
  RowDragModule,
  RowHeightParams,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import FullWidthCellRenderer from "./fullWidthCellRendererVue";
import { getData } from "./data";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  TextFilterModule,
  RowDragModule,
  ClientSideRowModelModule,
]);

function countryCellRenderer(params: ICellRendererParams) {
  if (!params.fullWidth) {
    return params.value;
  }
  const flag =
    '<img border="0" width="15" height="10" src="https://www.ag-grid.com/example-assets/flags/' +
    params.data.code +
    '.png">';
  return (
    '<span style="cursor: default;">' + flag + " " + params.value + "</span>"
  );
}

function isFullWidth(data: any) {
  // return true when country is Peru, France or Italy
  return ["Peru", "France", "Italy"].indexOf(data.name) >= 0;
}

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :rowData="rowData"
      :rowDragManaged="true"
      :getRowHeight="getRowHeight"
      :isFullWidthRow="isFullWidthRow"
      :fullWidthCellRenderer="fullWidthCellRenderer"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
    FullWidthCellRenderer,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi | null>(null);
    const columnDefs = ref<ColDef[]>([
      { field: "name", cellRenderer: countryCellRenderer },
      { field: "continent" },
      { field: "language" },
    ]);
    const defaultColDef = ref<ColDef>({
      flex: 1,
      filter: true,
    });
    const rowData = ref<any[] | null>(getData());
    const getRowHeight = ref<GetRowHeight>((params: RowHeightParams) => {
      // return 100px height for full width rows
      if (isFullWidth(params.data)) {
        return 100;
      }
    });
    const isFullWidthRow = ref<IsFullWidthRow>(
      (params: IsFullWidthRowParams) => {
        return isFullWidth(params.rowNode.data);
      },
    );
    const fullWidthCellRenderer = ref<any>("FullWidthCellRenderer");

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      rowData,
      getRowHeight,
      isFullWidthRow,
      fullWidthCellRenderer,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Row Drag with Full Width Rows](https://www.ag-grid.com/examples/row-dragging-customisation/dragger-inside-full-width-row/vue3)

In the example above, only the full width rows are draggable.

## Row Dragger with Custom Start Drag Pixels

By default, the drag event only starts after the **Row Drag Element** has been dragged by `4px`, but sometimes it might be useful to start the drag with a different drag threshold. For example, start dragging as soon as the `mousedown` event happens (dragged by `0px`). For that reason, the `registerRowDragger` takes a second parameter to specify the number of pixels that will start the drag event.

#### Row Drag With Custom Start Drag Pixels

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./styles.css";
import {
  CellStyleModule,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  NumberFilterModule,
  RowDragCancelEvent,
  RowDragEndEvent,
  RowDragEnterEvent,
  RowDragModule,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import CustomCellRenderer from "./customCellRendererVue";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  TextFilterModule,
  NumberFilterModule,
  RowDragModule,
  CellStyleModule,
  ClientSideRowModelModule,
]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :rowDragManaged="true"
      :rowData="rowData"
      @row-drag-enter="onRowDragEnter"
      @row-drag-end="onRowDragEnd"
      @row-drag-cancel="onRowDragCancel"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
    CustomCellRenderer,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      {
        field: "athlete",
        cellClass: "custom-athlete-cell",
        cellRenderer: "CustomCellRenderer",
      },
      { field: "country" },
      { field: "year", width: 100 },
      { field: "date" },
      { field: "sport" },
      { field: "gold" },
      { field: "silver" },
      { field: "bronze" },
    ]);
    const defaultColDef = ref<ColDef>({
      width: 170,
      filter: true,
    });
    const rowData = ref<IOlympicData[]>(null);

    function onRowDragEnter(e: RowDragEnterEvent) {
      console.log("onRowDragEnter: node", e.node.id);
    }
    function onRowDragEnd(e: RowDragEndEvent) {
      console.log("onRowDragEnd: node", e.node.id);
    }
    function onRowDragCancel(e: RowDragCancelEvent) {
      console.log("onRowDragCancel: node", e.node.id);
    }
    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => (rowData.value = data);

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      rowData,
      onGridReady,
      onRowDragEnter,
      onRowDragEnd,
      onRowDragCancel,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Row Drag With Custom Start Drag Pixels](https://www.ag-grid.com/examples/row-dragging-customisation/dragger-inside-custom-start-drag-pixels/vue3)

In the example above, the drag event starts as soon as `mousedown` is fired.

## Custom Drag and Drop Image

The drag and drop image can be customised via the grid properties `dragAndDropImageComponent` and `dragAndDropImageComponentParams`.

Any valid Vue component can be a drag and drop image component, however it must implement the `IDragAndDropImage` interface:

### IDragAndDropImage

```ts

interface IDragAndDropImage {
  setIcon(iconName: string | null, shake: boolean): void;

  setLabel(label: string): void;

}
```

### Custom Params

On top of the parameters provided by the grid, you can also provide your own parameters. This is useful if you want to allow configuring the component. For example, you might have parts of the grid that you want to highlight with a different colour.

```js
colDef = {
    dragAndDropImageComponent: 'MyDragAndDropImageComponent',
    dragAndDropImageComponentParams : {
        accentColour: 'SlateGray'
    }
}
```

#### Custom Drag and Drop Image

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./styles.css";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  NumberFilterModule,
  RowDragModule,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import CustomDragAndDropImage from "./customDragAndDropImageVue";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  TextFilterModule,
  NumberFilterModule,
  RowDragModule,
  ClientSideRowModelModule,
]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :rowDragManaged="true"
      :dragAndDropImageComponent="dragAndDropImageComponent"
      :dragAndDropImageComponentParams="dragAndDropImageComponentParams"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
    CustomDragAndDropImage,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      { field: "athlete", rowDrag: true },
      { field: "country" },
      { field: "year", width: 100 },
      { field: "date" },
      { field: "sport" },
      { field: "gold" },
      { field: "silver" },
      { field: "bronze" },
    ]);
    const defaultColDef = ref<ColDef>({
      width: 170,
      filter: true,
    });
    const dragAndDropImageComponent = ref("CustomDragAndDropImage");
    const dragAndDropImageComponentParams = ref({
      accentColour: "SlateGray",
    });
    const rowData = ref<IOlympicData[]>(null);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => (rowData.value = data);

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      dragAndDropImageComponent,
      dragAndDropImageComponentParams,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Custom Drag and Drop Image](https://www.ag-grid.com/examples/row-dragging-customisation/custom-drag-drop-image/vue3)
