# Row Order
URL: https://pro.rv-grid.com/api/row-order/
Source: src/content/docs/api/row-order.md
## Module Extensions

### `HTMLRevoGridElement` (Extended from `@revolist/revogrid`)

```ts
interface HTMLRevoGridElement {
  /**
       * Direct row-order configuration.
       * Set to `false` to disable RowOrderPlugin without removing the plugin.
       */
      rowOrder?: RowOrderPluginConfig | false
}
```

---

### `AdditionalData` (Extended from `@revolist/revogrid`)

```ts
interface AdditionalData {
  /**
       * Additional data property rowOrder
       * @deprecated Use `grid.rowOrder` instead.
       *
       * @example
       * ```typescript
       * const grid = document.createElement('revo-grid');
       * grid.plugins = [RowOrderPlugin];
       * grid.additionalData = {
       *   rowOrder: {
       *     prop: 'name', // column prop, used for drag and drop text information
       *   },
       * };
       * ```
       */
      rowOrder?: RowOrderPluginConfig | false
}
```

---

### `ColumnRegular` (Extended from `@revolist/revogrid`)

```ts
interface ColumnRegular {
  /**
       * Column prop, used for drag and drop text information
       */
      rowDrag?: RowDrag<TModel>
}
```

---

### `HTMLRevoGridElementEventMap` (Extended from `global`)

```ts
interface HTMLRevoGridElementEventMap {
  [ORDER_CHANGED_EVENT]: RowOrderChange;
  [DRAG_START_EVENT]: RowDragStartEvent;
  [BEFORE_ROW_DROP_VALIDATE_EVENT]: RowOrderDropValidationEvent;
  [ROW_DROP_STATE_CHANGE_EVENT]: RowOrderDropStateChange
}
```

## Plugin API

### `RowOrderPlugin`

The `RowOrderPlugin` is a sophisticated plugin for the RevoGrid framework, providing users with the ability
to reorder rows through an intuitive drag-and-drop interface. This plugin enhances user interactivity
by allowing smooth row rearrangement while maintaining data integrity and grid performance.

**Key Features**:
- **Row Drag and Drop**: Users can drag one or multiple rows and reposition them within the grid.
- **Auto-scroll Support**: Automatically scrolls the grid, viewport, or container when rows are dragged
  near the edges, ensuring a seamless drag-and-drop experience.
- **Row Highlighting**: Highlights rows that are being dragged or trimmed, providing visual feedback.
- **Multiple Row Handling**: Supports dragging and selecting multiple rows, enhancing batch operations.
- **Event Integration**: Listens to and dispatches various drag-related events, such as `DRAG_START_EVENT`,
  `DRAG_END_EVENT`, `ORDER_CHANGED_EVENT`, and more, allowing for extensive customization and integration
  with other components.
- **Trimmed Row Management**: Manages trimmed rows by automatically clearing and updating them as necessary
  during drag operations.

**Usage**:
- Integrate `RowOrderPlugin` into a RevoGrid instance to enable advanced row reordering capabilities.
- Customize behavior and appearance through configuration options and event listeners.

### Example
```typescript
import { RowOrderPlugin } from '@revolist/revogrid-pro'

const grid = document.createElement('revo-grid');
grid.plugins = [RowOrderPlugin];
```

This plugin is ideal for applications requiring dynamic, user-driven row management, such as task
prioritization tools, data manipulation applications, or any scenario where row order is significant.

```ts
class RowOrderPlugin {
  /**
     * Drop trigger event
     */
  onMouseOut(_: MouseEvent): void;

  /**
     * Final event
     */
  onMouseUp(e: MouseEvent): void;

  /**
     * Initial event when drag begins
     */
  dragStart(;

  /**
     * Initial row move
     */
  move(e: MouseEvent);

  clearOrder(): void;

  /**
     * Start grid reordering
     */
  orderStart(e: MouseEvent): void;

  /**
     * Clearing local subscription
     */
  clearSubscriptions();

  clearHighlight();
}
```

---

### `RowOrderChangedDetail`

```ts
export type RowOrderChangedDetail = {
  from: number;
  targetRow?: number;
  to: number;
  type: DimensionRows;
};
```

---

### `RowDragStartEvent` (Extended from `index.ts`)

```ts
interface RowDragStartEvent {
  model: CellTemplateProp
}
```

---

### `RowOrderDropValidationResult`

```ts
export type RowOrderDropValidationResult =
  | { valid: true; warning?: string }
  | { valid: false; reason?: string };
```

---

### `RowOrderPreviewContext`

```ts
export type RowOrderPreviewContext = {
  dataItem: CellTemplateProp;
  firstItem?: DataType;
  itemCount: number;
  items: DataType[];
  prop?: ColumnProp;
  type: DimensionRows;
};
```

---

### `RowOrderPreviewContent`

```ts
export type RowOrderPreviewContent = string | number | HTMLElement | undefined;
```

---

### `RowOrderPreviewRenderer`

```ts
export type RowOrderPreviewRenderer = (
  context: RowOrderPreviewContext,
) => RowOrderPreviewContent;
```

---

### `RowOrderDropValidationContext`

```ts
export type RowOrderDropValidationContext = {
  dataItem: CellTemplateProp;
  dropPosition: RowOrderDropPosition;
  from: number;
  items: Map<number, DataType>;
  originalEvent: MouseEvent;
  targetIndex: number;
  targetRow: number;
  to: number;
  type: DimensionRows;
  /**
   * Visible row indexes that are part of the active drag selection.
   */
  visibleRowIndexes?: number[];
};
```

---

### `RowOrderDropValidationEvent` (Extended from `index.ts`)

```ts
export type RowOrderDropValidationEvent = RowOrderDropValidationContext & {
  result: RowOrderDropValidationResult;
};
```

---

### `RowOrderDropStateChange` (Extended from `index.ts`)

```ts
export type RowOrderDropStateChange = RowOrderDropValidationContext & {
  previous?: RowOrderDropValidationResult;
  result: RowOrderDropValidationResult;
};
```

---

### `RowOrderDropPosition`

```ts
export type RowOrderDropPosition = 'before' | 'inside' | 'after';
```

---

### `RowOrderPluginConfig`

```ts
interface RowOrderPluginConfig {
  prop?: ColumnProp;
  // column prop, used for drag and drop text information
    preview?: 'compact' | 'none' | RowOrderPreviewRenderer;
  previewProp?: ColumnProp | RowOrderPreviewRenderer;
  validateDrop?: (
      context: RowOrderDropValidationContext,
    ) => RowOrderDropValidationResult | boolean | void;
  allowPinnedRows?: boolean;
  allowCrossRowType?: boolean;
  /**
     * Flashes moved rows after a successful reorder when `CellFlashPlugin` is
     * installed. Enabled by default. Set to `false` to keep `CellFlashPlugin`
     * active for other grid changes without flashing row-order drops.
     */
    flashOnDrop?: boolean;
  /**
     * When grouped rows are reordered into another group, apply the target group
     * values to the moved rows and emit regular beforeedit/afteredit events.
     * Disabled by default, so grouped rows can only be reordered inside the same
     * group path.
     */
    applyTargetGroupOnDrop?: boolean
}
```

---

### `RowOrderServiceConfig`

```ts
interface RowOrderServiceConfig {
  dimension: PluginProviders['dimension'];
  orderStart(e: MouseEvent): void;
  positionChanged(e: MouseEvent, detail: RowOrderChangedDetail): void
}
```

---

### `DragEventsData` (Extended from `index.ts`)

```ts
interface DragEventsData {
  text?: string | number
}
```

---

### `RowOrderChange` (Extended from `index.ts`)

```ts
interface RowOrderChange {
  // ; // models
    dropPosition?: RowOrderDropPosition;
  originalEvent: MouseEvent;
  /**
     * Visible row index that the pointer resolved to before row-order target-index
     * normalization. Tree integrations use it to resolve the insertion boundary
     * against the current hierarchy.
     */
    targetRow?: number;
  /**
     * Visible row indexes that are part of the active drag selection.
     */
    visibleRowIndexes?: number[]
}
```

---

### `LocalSubscription`

```ts
export type LocalSubscription = {
  target: Element | Document;
  callback(...params: any[]): void;
};
```

---

### `StaticData`

```ts
export type StaticData = {
  dataItem: CellTemplateProp;
  dataEl: HTMLElement;
  scrollEl: Element;
  gridEl: HTMLElement;
  items: Map<number, DataType>;
};
```

---

### `draggableRender`

```ts
export function draggableRender(
  h: HyperFunc<VNode>,
  data: DragEventsData,
  _?: any
);
```

---

### `OrderHandler`

```ts
class OrderHandler {
  renderAutoscroll(_: MouseEvent, parent: HTMLElement | null): void;

  autoscroll(y: number, dataContainerHeight: number): void;

  start(
    e: MouseEvent,;

  stop(): void;

  moveTip(;

  showHandler(y: number, gridHeight: number): void;

  showValidationAt(y: number, gridHeight: number): void;

  setValidation(validation: RowOrderDropValidationResult): void;

  render(h: HyperFunc<VNode>, pluginId: string);
}
```

---

### `getTopRelative`

Get coordinate relative to the grid

```ts
export function getTopRelative(
  absoluteY: number,;
```

---

### `getRow`

Calculate cell based on x, y position

```ts
export function getRow(y: number, e: EventData): PositionItem;
```

---

### `getRowContentEnd`

```ts
export function getRowContentEnd(rows: DimensionSettingsState): number;
```

---

### `isRowInsideContent`

```ts
export function isRowInsideContent(y: number, e: EventData): boolean;
```

---

### `clampRowToContent`

```ts
export function clampRowToContent(row: number, e: EventData): number;
```

---

### `getCell`

Calculate cell based on x, y position

```ts
export function getCell(;
```

---

### `EventData`

```ts
export type EventData = {
  el: HTMLElement;
  elScroll: Element;
  elRect: DOMRect;
  gridRect: DOMRect;
  yOffset: number;
  dataItem: DragEventsData;
  type: DimensionRows;
  rows: DimensionSettingsState;
  cols: DimensionSettingsState;
};
```

---

### `default`

```ts
class RowOrderService {
  /** Drag finished, calculate and apply changes */
  endOrder(e: MouseEvent, data: EventData): void;

  start(e: MouseEvent): void;

  /** Drag started, reserve initial cell for farther use */
  startOrder(cell: Cell);

  move(e: MouseEvent, data: EventData): PositionItem | null;

  /** Drag stopped, probably cursor outside of document area */
  clear(): void;
}
```

---

### `isRowOrderConfigEnabled`

```ts
export function isRowOrderConfigEnabled(
  config: RowOrderPluginConfig | false | undefined,
): boolean;
```

---

### `resolveRowDrag`

```ts
export function resolveRowDrag(
  rowDrag: RowDrag | undefined,
  model: CellTemplateProp,
): boolean;
```

---

### `normalizeDropRow`

```ts
export function normalizeDropRow(from: number, hoverRow: number): number;
```

---

### `getTargetIndex`

```ts
export function getTargetIndex(
  from: number,
  to: number,
  itemCount: number,
): number;
```

---

### `isNoopDrop`

```ts
export function isNoopDrop(
  range: RowOrderRange,
  targetIndex: number,
  rowIndexes?: RowOrderVisibleRowIndex[],
): boolean;
```

---

### `normalizeRowOrderIndexes`

```ts
export function normalizeRowOrderIndexes(
  rowIndexes: RowOrderVisibleRowIndex[],
  itemCount: number,
): RowOrderVisibleRowIndex[];
```

---

### `rangeToRowOrderIndexes`

```ts
export function rangeToRowOrderIndexes(
  range: RowOrderRange,
): RowOrderVisibleRowIndex[];
```

---

### `getRowOrderSelectionRange`

```ts
export function getRowOrderSelectionRange(
  rowIndexes: RowOrderVisibleRowIndex[],
): RowOrderRange;
```

---

### `getRowOrderTargetIndex`

```ts
export function getRowOrderTargetIndex(;
```

---

### `resolveRowOrderEditColumn`

```ts
export function resolveRowOrderEditColumn(
  columns: ColumnRegular[],
  prop: ColumnProp,
): RowOrderEditColumnResolution;
```

---

### `buildRowOrderMutation`

```ts
export function buildRowOrderMutation(;
```

---

### `resolveMovedRowFlashTargets`

```ts
export function resolveMovedRowFlashTargets(;
```

---

### `normalizeValidationResult`

```ts
export function normalizeValidationResult(
  result: RowOrderDropValidationResult | boolean | void,
): RowOrderDropValidationResult;
```

---

### `buildPreviewContext`

```ts
export function buildPreviewContext(;
```

---

### `resolvePreviewContent`

```ts
export function resolvePreviewContent(;
```

---

### `buildDropValidationContext`

```ts
export function buildDropValidationContext(;
```

---

### `getRowDimensionState`

```ts
export function getRowDimensionState(
  stores: RowDimensionStateStores,
  type: DimensionRows,
): DimensionSettingsState;
```

---

### `resolveGroupedDrop`

```ts
export function resolveGroupedDrop(;
```

---

### `RowOrderRange`

```ts
export type RowOrderRange = {
  from: number;
  to: number;
};
```

---

### `RowOrderVisibleRowIndex`

```ts
export type RowOrderVisibleRowIndex = number;
```

---

### `RowOrderMutation`

```ts
export type RowOrderMutation = {
  targetIndex: number;
  itemsOrder: number[];
  prevItems: number[];
  proxyItems: number[];
};
```

---

### `RowOrderFlashRowTarget`

```ts
export type RowOrderFlashRowTarget = {
  rowIndex: number;
  type: DimensionRows;
  direction: 'changed';
};
```

---

### `RowDimensionStateStores`

```ts
export type RowDimensionStateStores = Record<DimensionRows, {
  getCurrentState(): DimensionSettingsState;
}>;
```

---

### `GroupedDropEdit`

```ts
export type GroupedDropEdit = {
  physicalIndex: number;
  prop: ColumnProp;
  value: unknown;
};
```

---

### `GroupedDropResolution`

```ts
export type GroupedDropResolution =
  | { valid: true; edits: GroupedDropEdit[]; targetValues?: Record<string, unknown> }
  | { valid: false; reason: string };
```

---

### `GroupedDropOptions`

```ts
export type GroupedDropOptions = {
  groupProps: ColumnProp[];
  items: number[];
  movedItems: Map<number, DataType>;
  source: DataType[];
  targetIndex: number;
  applyTargetGroupOnDrop?: boolean;
  isGroupingRow(model?: DataType): boolean;
  getGroupPath(model: DataType): unknown[] | null;
};
```

---

### `RowOrderEditColumnResolution`

```ts
export type RowOrderEditColumnResolution = {
  column: ColumnRegular;
  index: number;
};
```
