YaYaw TableYaYaw Table

Wire CRUD actions to the table via provider callbacks

Actions API

Provide actions per tableType via getTableActions (passed to DataTable). These connect the table to your data layer. In Next.js you can pass Server Actions so that list, create, update, delete, and bulk operations run on the server. See Server-side & Server Actions for a full example.

Shape

getTableActions: (tableType: string) => ({
  list: async (params) => {
    // params: { filters, advancedFilters, limit, orderBy, page (1-based), search }
    return {
      data: [],
      meta: { pageCount: 1, totalCount: 0 },
    };
  },
  aggregate: async (params) => {
    // params: { filters, advancedFilters, search, calculations, locale }
    return {
      results: {
        price: { raw: 820.64, label: "820,64" },
      },
      meta: { totalCount: 50 },
    };
  },
  create: async (data) => ({ success: true, data }),
  update: async (id, data) => ({ success: true, data }),
  delete: async (id) => ({ success: true }),
  duplicate: async (id) => ({ success: true }),
  bulkDelete: async (ids) => ({ success: true }),
  bulkCopy: async (ids) => ({ success: true, data?: string }),
  bulkUpdate: async (ids, updateData) => ({ success: true }),
})

list response

The list method must return:

{ data: T[]; meta?: { pageCount?: number; totalCount?: number } }

aggregate response (optional)

aggregate is used by footer calculations to compute values on the full filtered dataset (not only the current page).

{
  results: Record<
    string,
    {
      raw: number | string | null;
      label: string;
    }
  >;
  meta?: { totalCount?: number };
}

Notes:

  • calculations in params is a map: columnId -> CalculationType.
  • If aggregate is not provided, the table falls back to paginated list calls.
  • You can return custom labels from your API (label) while keeping machine-readable values in raw.

Bulk actions

DataTable will use these by default if you don't provide explicit callbacks:

  • onBulkEditupdate
  • onBulkDeletedelete
  • onBulkCopyduplicate
  • onBulkExport → internal CSV export of selected rows (client-side)

Inline edit dependency

Inline cell editing depends on the provider update(id, data) action.

  • No extra API route is used.
  • When inlineEdit is enabled on the table or columns, each cell commit calls update(id, { [field]: value }).
  • If update is not configured, inline edit shows an error and does not commit.

To avoid ambiguous branches, return an explicit result object from your bulk callbacks:

type BulkActionResult = {
  success: boolean;
  closeMenu: boolean;
  clearSelection: boolean;
  message?: string;
};

Example:

onBulkDelete: async (rows) => {
  const ids = rows.map((row) => String((row.original as { id: string }).id));
  const response = await deleteManyProducts(ids);

  return {
    success: response.success,
    closeMenu: response.success,
    clearSelection: response.success,
    message: response.success
      ? `Deleted ${ids.length} products`
      : response.error ?? "Delete failed",
  };
};

See also:

On this page