Skip to content

Range Copy Preview

RangeCopyPreviewPlugin shows the copied values that will be applied when a user drags a selected range with the fill handle. It is a view-only companion plugin: the data store is not changed until the existing drop-time range copy flow runs.

Use it when users need confidence that a drag will repeat the selected source range exactly, without AutoFill sequence inference.

Source code
TypeScript ts
import { defineCustomElements } from '@revolist/revogrid/loader';
import { ColumnStretchPlugin, RangeCopyPreviewPlugin, RowOddPlugin } from '@revolist/revogrid-pro';
import { currentTheme } from '../composables/useRandomData';
import { columns, createRows } from './data';

defineCustomElements();
const { isDark } = currentTheme();

export function load(parentSelector: string) {
  const grid = document.createElement('revo-grid') as HTMLRevoGridElement;
  grid.className = 'rounded-lg overflow-hidden';
  grid.range = true;
  grid.theme = isDark() ? 'darkMaterial' : 'material';
  grid.hideAttribution = true;
  grid.columns = columns;
  grid.stretch = 'all';
  grid.plugins = [RangeCopyPreviewPlugin, RowOddPlugin, ColumnStretchPlugin];
  grid.style.minHeight = '520px';
  grid.style.minWidth = '620px';

  document.querySelector(parentSelector)?.appendChild(grid);
  grid.source = createRows();

  return () => grid.remove();
}
Data ts
import type { ColumnRegular, DataType } from '@revolist/revogrid';

export const columns: ColumnRegular[] = [
  { prop: 'task', name: 'Task', size: 180 },
  { prop: 'owner', name: 'Owner', size: 150 },
  { prop: 'region', name: 'Region', size: 140 },
  { prop: 'status', name: 'Status', size: 150 },
  { prop: 'start', name: 'Start Date', size: 150 },
  { prop: 'hours', name: 'Hours', size: 120 },
];

export function createRows(): DataType[] {
  const rows: DataType[] = Array.from({ length: 80 }, () => ({}));
  const sourceRows: DataType[] = [
    {
      task: 'Discovery',
      owner: 'Ana',
      region: 'North',
      status: 'Ready',
      start: '2026-05-12',
      hours: 6,
    },
    {
      task: 'Implementation',
      owner: 'Maks',
      region: 'West',
      status: 'In progress',
      start: '2026-05-13',
      hours: 8,
    },
    {
      task: 'Review',
      owner: 'Sofia',
      region: 'South',
      status: 'Queued',
      start: '2026-05-14',
      hours: 4,
    },
  ];

  sourceRows.forEach((row, index) => {
    Object.assign(rows[index], row);
  });

  return rows;
}
Vue vue
<template>
  <VGrid
    class="rounded-lg overflow-hidden"
    range
    :theme="isDark ? 'darkMaterial' : 'material'"
    :columns="columns"
    :source="rows"
    :plugins="plugins"
    stretch="all"
    hide-attribution
    style="min-height: 520px; min-width: 620px;"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { VGrid } from '@revolist/vue3-datagrid';
import { ColumnStretchPlugin, RangeCopyPreviewPlugin, RowOddPlugin } from '@revolist/revogrid-pro';
import { currentThemeVue } from '../composables/useRandomData';
import { columns, createRows } from './data';

const { isDark } = currentThemeVue();
const plugins = [RangeCopyPreviewPlugin, RowOddPlugin, ColumnStretchPlugin];
const rows = ref(createRows());
</script>
React tsx
import React, { useMemo, useState } from 'react';
import { RevoGrid, type ColumnRegular, type DataType } from '@revolist/react-datagrid';
import { ColumnStretchPlugin, RangeCopyPreviewPlugin, RowOddPlugin } from '@revolist/revogrid-pro';
import { currentTheme } from '../composables/useRandomData';
import { columns as baseColumns, createRows } from './data';

export default function RangeCopyPreview() {
  const { isDark } = currentTheme();
  const theme = useMemo(() => (isDark() ? 'darkMaterial' : 'material'), [isDark]);
  const columns = useMemo<ColumnRegular[]>(() => baseColumns, []);
  const plugins = useMemo(() => [RangeCopyPreviewPlugin, RowOddPlugin, ColumnStretchPlugin], []);
  const [rows] = useState<DataType[]>(createRows);

  return (
    <RevoGrid
      className="rounded-lg overflow-hidden"
      range
      theme={theme}
      columns={columns}
      source={rows}
      plugins={plugins}
      stretch="all"
      hide-attribution
      style={{ minHeight: 520, minWidth: 620 }}
    />
  );
}
Angular ts
import { Component, ViewEncapsulation, type OnInit } from '@angular/core';
import { RevoGrid } from '@revolist/angular-datagrid';
import type { DataType } from '@revolist/revogrid';
import { ColumnStretchPlugin, RangeCopyPreviewPlugin, RowOddPlugin } from '@revolist/revogrid-pro';
import { currentTheme } from '../composables/useRandomData';
import { columns, createRows } from './data';

@Component({
  selector: 'range-copy-preview-grid',
  standalone: true,
  encapsulation: ViewEncapsulation.None,
  imports: [RevoGrid],
  template: `
    <revo-grid
      class="rounded-lg overflow-hidden"
      [range]="true"
      [theme]="theme"
      [columns]="columns"
      [source]="rows"
      [plugins]="plugins"
      [stretch]="'all'"
      [hideAttribution]="true"
      style="min-height: 520px; min-width: 620px;"
    ></revo-grid>
  `,
})
export class RangeCopyPreviewGridComponent implements OnInit {
  theme = currentTheme().isDark() ? 'darkMaterial' : 'material';
  columns = columns;
  plugins = [RangeCopyPreviewPlugin, RowOddPlugin, ColumnStretchPlugin];
  rows: DataType[] = [];

  ngOnInit() {
    this.rows = createRows();
  }
}
import { RangeCopyPreviewPlugin } from '@revolist/revogrid-pro';
const grid = document.createElement('revo-grid');
grid.range = true;
grid.plugins = [RangeCopyPreviewPlugin];

The plugin uses the same core drag signal as range copy. It does not need configuration for the default behavior.

  1. Select a source cell or range.
  2. Drag the fill handle to a larger target range.
  3. Target cells show the exact copied values in a ghost style.
  4. Source cells remain visually unchanged.
  5. Release the mouse to apply the core range copy.

If the temporary range is cleared, the source changes, or the plugin is destroyed, the preview is removed immediately.

AutoFillPreviewPlugin previews smart sequence output from AutoFillPlugin, such as 1, 2 becoming 3, 4 or Mon, Tue becoming Wed.

RangeCopyPreviewPlugin previews exact range copy output:

Draft, Approved -> Draft, Approved, Draft, Approved
North, West -> North, West, North, West

Use one preview plugin at a time for this drag surface:

PluginPreview intent
AutoFillPreviewPluginShow predicted smart AutoFill sequence values.
RangeCopyPreviewPluginShow exact copied source values.

Preview cells receive:

  • attribute: range-copy-preview
  • class: range-copy-preview-cell

Default styling uses reduced opacity and italic text so users can distinguish preview values from committed data.

.range-copy-preview-cell {
opacity: 0.45;
font-style: italic;
}

The plugin does not mutate source, newData, or provider stores. It only overrides the render model during beforecellrender, then refreshes affected row types in a frame batch.