Skip to content

Header (Advanced)

Sophisticated Row Header example based on RowHeaderPlugin. The demo uses a task pipeline layout so the row header has a clear job: it anchors each row, opens row-level actions, and keeps row focus visible while the cells provide richer operational context.

  • Use rowHeaders({ showHeaderFocusBtn: true }) for a dedicated row action rail
  • Open a row ContextMenuPlugin menu directly from the row-header click
  • Combine row headers with custom column templates for status, priority, owner, due date, and progress
  • Focus the whole row from the row header while preserving readable business data in the grid body
  • Style the row-header rail and content cells together so the row action area feels intentional

Source code
TypeScript ts
import './rowHeader.scss';

import { defineCustomElements } from '@revolist/revogrid/loader';
import { rowHeaders, RowHeaderPlugin, ContextMenuPlugin, ColumnStretchPlugin, RowOddPlugin } from '@revolist/revogrid-pro';
import { currentTheme } from '../composables/useRandomData';
import { createRowHeaderColumns, rowHeaderContextMenu, rowHeaderTasks } from './rowHeader.shared';

const { isDark } = currentTheme();

defineCustomElements();

const grid = document.createElement('revo-grid');
grid.className = 'row-header-demo-grid';
grid.columns = createRowHeaderColumns();
grid.plugins = [RowHeaderPlugin, ContextMenuPlugin, ColumnStretchPlugin, RowOddPlugin];
grid.rowHeaders = rowHeaders({ showHeaderFocusBtn: true });
grid.rowContextMenu = rowHeaderContextMenu;
grid.rowSize = 56;
grid.stretch = 'all';
grid.theme = isDark() ? 'darkMaterial' : 'material';
grid.hideAttribution = true;

document.getElementById('demo-wrapper')?.appendChild(grid);
grid.source = rowHeaderTasks;
Vue vue
<script setup lang="ts">
import './rowHeader.scss';

import { computed } from 'vue';
import { VGrid } from '@revolist/vue3-datagrid';
import { rowHeaders, RowHeaderPlugin, ContextMenuPlugin, ColumnStretchPlugin, RowOddPlugin } from '@revolist/revogrid-pro';
import { currentThemeVue } from '../composables/useRandomData';
import { createRowHeaderColumns, rowHeaderContextMenu, rowHeaderTasks } from './rowHeader.shared';

const { isDark } = currentThemeVue();

const theme = computed(() => isDark.value ? 'darkMaterial' : 'material');
const source = rowHeaderTasks;
const columns = createRowHeaderColumns();

const plugins = [RowHeaderPlugin, ContextMenuPlugin, ColumnStretchPlugin, RowOddPlugin];
const rdHeaders = rowHeaders({ showHeaderFocusBtn: true });
</script>

<template>
  <VGrid
    class="row-header-demo-grid grow"
    :theme="theme"
    :source="source"
    :columns="columns"
    :plugins="plugins"
    :rowHeaders="rdHeaders"
    :row-context-menu.prop="rowHeaderContextMenu"
    :rowSize="56"
    stretch="all"
    :hideAttribution="true"
  />
</template>
React tsx
import './rowHeader.scss';

import React, { useMemo } from 'react';
import { RevoGrid } from '@revolist/react-datagrid';
import { rowHeaders, RowHeaderPlugin, ContextMenuPlugin, ColumnStretchPlugin, RowOddPlugin } from '@revolist/revogrid-pro';
import { currentTheme } from '../composables/useRandomData';
import { createRowHeaderColumns, rowHeaderContextMenu, rowHeaderTasks } from './rowHeader.shared';

const RowHeaderDemo: React.FC = () => {
  const theme = currentTheme().isDark() ? 'darkMaterial' : 'material';

  const source = useMemo(() => rowHeaderTasks, []);
  const columns = useMemo(() => createRowHeaderColumns(), []);

  const plugins = useMemo(() => [RowHeaderPlugin, ContextMenuPlugin, ColumnStretchPlugin, RowOddPlugin], []);
  const rdHeaders = useMemo(() => rowHeaders({ showHeaderFocusBtn: true }), []);
  const rowContextMenu = useMemo(() => rowHeaderContextMenu, []);

  return (
    <RevoGrid
      className="row-header-demo-grid grow"
      theme={theme}
      source={source}
      columns={columns}
      plugins={plugins}
      rowHeaders={rdHeaders}
      rowContextMenu={rowContextMenu}
      rowSize={56}
      stretch="all"
      hideAttribution
    />
  );
};

export default RowHeaderDemo;
Angular ts
import { Component, ViewEncapsulation } from '@angular/core';
import { RevoGrid } from '@revolist/angular-datagrid';
import { rowHeaders, RowHeaderPlugin, ContextMenuPlugin, ColumnStretchPlugin, RowOddPlugin } from '@revolist/revogrid-pro';
import { currentTheme } from '../composables/useRandomData';
import { createRowHeaderColumns, rowHeaderContextMenu, rowHeaderTasks } from './rowHeader.shared';

@Component({
  selector: 'row-header-grid',
  standalone: true,
  imports: [RevoGrid],
  encapsulation: ViewEncapsulation.None,
  styleUrls: ['./rowHeader.scss'],
  template: `
    <revo-grid
      class="row-header-demo-grid grow"
      [theme]="theme"
      [source]="source"
      [columns]="columns"
      [plugins]="plugins"
      [rowHeaders]="rdHeaders"
      [additionalData]="additionalData"
      [rowSize]="56"
      stretch="all"
      [hideAttribution]="true"
    ></revo-grid>
  `,
})
export class RowHeaderGridComponent {
  theme = currentTheme().isDark() ? 'darkMaterial' : 'material';
  source = rowHeaderTasks;
  columns = createRowHeaderColumns();

  plugins = [RowHeaderPlugin, ContextMenuPlugin, ColumnStretchPlugin, RowOddPlugin];
  rdHeaders = rowHeaders({ showHeaderFocusBtn: true });
  additionalData = { rowContextMenu: rowHeaderContextMenu };
}