Skip to content

Data Grid

A powerful data grid built on AG Grid with Cocoar theming. Configure columns, sorting, selection, and cell renderers through a fluent builder API — no raw AG Grid config needed.

Separate Package

The Data Grid depends on AG Grid. Install it separately:

bash
pnpm add @cocoar/vue-data-grid ag-grid-community ag-grid-vue3
ts
import { CoarDataGrid, CoarGridBuilder } from '@cocoar/vue-data-grid';

Basic Usage

Define columns with .field(), .header(), and .flex() / .width(). Pass row data with .rowData().

vue
<template>
  <div style="height: 350px;">
    <CoarDataGrid :builder="builder" />
  </div>
</template>

<script setup lang="ts">
import { CoarDataGrid, CoarGridBuilder } from '@cocoar/vue-data-grid';

interface User {
  name: string;
  email: string;
  role: string;
}

const data: User[] = [
  { name: 'Alice Johnson', email: 'alice@example.com', role: 'Engineer' },
  { name: 'Bob Smith', email: 'bob@example.com', role: 'Designer' },
  { name: 'Carol Williams', email: 'carol@example.com', role: 'Manager' },
  { name: 'David Brown', email: 'david@example.com', role: 'Engineer' },
  { name: 'Eve Davis', email: 'eve@example.com', role: 'Designer' },
];

const builder = CoarGridBuilder.create<User>()
  .columns([
    (col) => col.field('name').header('Name').flex(1),
    (col) => col.field('email').header('Email').flex(1),
    (col) => col.field('role').header('Role').width(120),
  ])
  .rowData(data);
</script>

Column Types

Built-in renderers for dates, numbers, tags, and icons — no custom cell components needed.

vue
<template>
  <div style="height: 350px;">
    <CoarDataGrid :builder="builder" />
  </div>
</template>

<script setup lang="ts">
import { CoarDataGrid, CoarGridBuilder } from '@cocoar/vue-data-grid';

interface Employee {
  name: string;
  joinDate: string;
  salary: number;
  status: 'active' | 'inactive' | 'pending';
  icon: string;
}

const data: Employee[] = [
  { name: 'Alice Johnson', joinDate: '2022-03-15', salary: 95000, status: 'active', icon: 'user' },
  { name: 'Bob Smith', joinDate: '2021-07-01', salary: 85000, status: 'active', icon: 'palette' },
  { name: 'Carol Williams', joinDate: '2020-01-20', salary: 110000, status: 'inactive', icon: 'users' },
  { name: 'David Brown', joinDate: '2023-06-10', salary: 90000, status: 'pending', icon: 'user' },
  { name: 'Eve Davis', joinDate: '2022-11-05', salary: 88000, status: 'active', icon: 'palette' },
];

const builder = CoarGridBuilder.create<Employee>()
  .columns([
    (col) => col.field('name').header('Name').flex(1).sortable(),
    (col) => col.date('joinDate', 'long').header('Joined').width(180).sortable(),
    (col) => col.number('salary').header('Salary').width(120),
    (col) => col.tag('status', {
      variantMap: { active: 'success', inactive: 'error', pending: 'warning' },
    }).header('Status').width(130),
    (col) => col.icon('icon', { size: 's' }).header('Type').fixedWidth(60),
  ])
  .rowData(data);
</script>
MethodDescription
.field(name)Plain text column
.date(field, format?)Formatted date display
.number(field)Numeric formatting
.tag(field, config)Renders a CoarTag with variant mapping
.icon(field, config?)Renders a CoarIcon

Row Selection

Toggle between single-click and multi-select with checkboxes.

vue
<template>
  <div>
    <div style="display: flex; gap: 12px; margin-bottom: 12px;">
      <label style="display: flex; align-items: center; gap: 4px; font-size: 13px; cursor: pointer;">
        <input type="radio" value="single" v-model="mode" /> Single
      </label>
      <label style="display: flex; align-items: center; gap: 4px; font-size: 13px; cursor: pointer;">
        <input type="radio" value="multiple" v-model="mode" /> Multi (Checkboxes)
      </label>
    </div>
    <div style="height: 300px;">
      <CoarDataGrid :key="mode" :builder="builders[mode]" />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { CoarDataGrid, CoarGridBuilder } from '@cocoar/vue-data-grid';

interface User {
  name: string;
  email: string;
  role: string;
}

const data: User[] = [
  { name: 'Alice Johnson', email: 'alice@example.com', role: 'Engineer' },
  { name: 'Bob Smith', email: 'bob@example.com', role: 'Designer' },
  { name: 'Carol Williams', email: 'carol@example.com', role: 'Manager' },
  { name: 'David Brown', email: 'david@example.com', role: 'Engineer' },
  { name: 'Eve Davis', email: 'eve@example.com', role: 'Designer' },
];

const cols = [
  (col: any) => col.field('name').header('Name').flex(1),
  (col: any) => col.field('email').header('Email').flex(1),
  (col: any) => col.field('role').header('Role').width(120),
];

const mode = ref<'single' | 'multiple'>('single');

const builders = {
  single: CoarGridBuilder.create<User>().columns(cols).rowData(data).rowSelection('single'),
  multiple: CoarGridBuilder.create<User>().columns(cols).rowData(data).rowSelection('multiple', { checkboxes: true }),
};
</script>

Reactive Data

Bind a ref with .rowDataRef() and the grid updates automatically when your data changes.

3 rows
vue
<template>
  <div>
    <div style="display: flex; gap: 8px; margin-bottom: 12px;">
      <CoarButton size="s" @click="addRow">Add Row</CoarButton>
      <CoarButton size="s" variant="secondary" @click="reset">Reset</CoarButton>
      <span style="font-size: 13px; color: var(--coar-text-neutral-secondary); align-self: center;">
        {{ data.length }} rows
      </span>
    </div>
    <div style="height: 300px;">
      <CoarDataGrid :builder="builder" />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { CoarButton } from '@cocoar/vue-ui';
import { CoarDataGrid, CoarGridBuilder } from '@cocoar/vue-data-grid';

interface User {
  id: number;
  name: string;
  email: string;
  role: string;
}

const initialData: User[] = [
  { id: 1, name: 'Alice Johnson', email: 'alice@example.com', role: 'Engineer' },
  { id: 2, name: 'Bob Smith', email: 'bob@example.com', role: 'Designer' },
  { id: 3, name: 'Carol Williams', email: 'carol@example.com', role: 'Manager' },
];

const allRows: User[] = [
  ...initialData,
  { id: 4, name: 'David Brown', email: 'david@example.com', role: 'Engineer' },
  { id: 5, name: 'Eve Davis', email: 'eve@example.com', role: 'Designer' },
  { id: 6, name: 'Frank Miller', email: 'frank@example.com', role: 'Engineer' },
  { id: 7, name: 'Grace Wilson', email: 'grace@example.com', role: 'Manager' },
  { id: 8, name: 'Henry Taylor', email: 'henry@example.com', role: 'Designer' },
];

const data = ref<User[]>([...initialData]);

const builder = CoarGridBuilder.create<User>()
  .columns([
    (col) => col.field('name').header('Name').flex(1),
    (col) => col.field('email').header('Email').flex(1),
    (col) => col.field('role').header('Role').width(120),
  ])
  .rowDataRef(data);

function addRow() {
  const next = allRows[data.value.length % allRows.length];
  if (next) {
    data.value = [...data.value, { ...next, id: Date.now() }];
  }
}

function reset() {
  data.value = [...initialData];
}
</script>

Sorting

Make columns sortable and set a default sort order.

ts
const builder = CoarGridBuilder.create<Row>()
  .columns([
    (col) => col.field('name').header('Name').flex(1).sortable(),
    (col) => col.number('salary').header('Salary').width(120).sortable(),
  ])
  .rowData(data)
  .defaultSort('name', 'asc');

API

CoarDataGrid Props

PropTypeDefaultDescription
builderCoarGridBuilder<T>Grid configuration builder (required)
themeThemecocoarThemeAG Grid theme override

CoarGridBuilder Methods

MethodParametersDescription
.columns(defs)ColumnDefFn<T>[]Define column configuration
.rowData(data)T[]Set static row data
.rowDataRef(ref)Ref<T[]>Bind reactive row data
.rowSelection(mode, opts?)'single' | 'multiple'Enable row selection
.defaultSort(field, dir)string, 'asc' | 'desc'Set default sort column
.rowClassRules(rules)RowClassRules<T>Conditional row CSS classes

CoarGridColumnBuilder Methods

MethodParametersDescription
.field(name)keyof TSet column data field
.header(text)stringSet column header text
.flex(value)numberFlexible column width
.width(px)numberFixed column width
.fixedWidth(px)numberNon-resizable fixed width
.sortable()Enable column sorting
.date(field, format?)keyof T, string?Date cell renderer
.number(field)keyof TNumber cell renderer
.tag(field, config)keyof T, TagConfigTag cell renderer
.icon(field, config?)keyof T, IconConfig?Icon cell renderer

Released under the Apache-2.0 License.