Hooks

useDocyrusPivotGrid

Pivot grid backed by a Docyrus data source. Aggregates on the device from raw records, or in the database through a pivot matrix and calculations, and returns a controller for the native PivotGrid components.

iOSAndroidExpo Go

Installation

pnpm dlx @docyrus/cli add @docyrus/rn-hooks-use-docyrus-pivot-grid
Required Packages(2 packages)
pnpm add @docyrus/api-client @tanstack/react-query

A straight port of the web hook, with the same signature. It fetches /v1/apps/{appSlug}/data-sources/{dataSourceSlug}/items through TanStack Query and feeds the rows into the native usePivotGrid. The result's controller plugs into PivotGridView, PivotGridToolbar, PivotGridExportMenu and PivotGridDrilldownModal. It needs an authenticated RestApiClient and a QueryClientProvider above it.

Two aggregation modes are available:

  • 'client' (default): fetches raw records (columns is auto-derived from the dimensions and measures, limit defaults to 5000) and aggregates on the device. Simple, but not suited to large datasets.
  • 'server': sends a pivot.matrix + calculations payload so the database aggregates. The response has one row per dimension combination, so it scales to any dataset size. A date dimension with dateFormat is bucketed on the server with to_char[format]@field over a dateRange axis.

Usage

import { useMemo } from 'react';
import { View } from 'react-native';

import { useDocyrusClient } from '@docyrus/signin/react-native';

import {
  PivotGridDrilldownModal,
  PivotGridToolbar,
  PivotGridView
} from '@/components/docyrus-native/pivot-grid';
import { useDocyrusPivotGrid } from '@/hooks/docyrus-native/use-docyrus-pivot-grid';

export function TimeEntryReport() {
  const client = useDocyrusClient();

  const rowDimensions = useMemo(() => [
    { id: 'user', label: 'User', field: 'record_owner', subField: 'name', emptyLabel: 'Unassigned' }
  ], []);

  const columnDimensions = useMemo(() => [
    {
      id: 'month',
      label: 'Month',
      field: 'date',
      dateFormat: 'YYYY-MM',
      dateRange: { interval: 'day', min: '2026-01-01', max: '2026-06-30' }
    }
  ], []);

  const measures = useMemo(() => [
    { id: 'logged', label: 'Logged (h)', field: 'duration', aggregate: 'sum' as const, transform: (s: number) => s / 3600 }
  ], []);

  const { controller, isLoading, error, refetch } = useDocyrusPivotGrid({
    client: client!,
    appSlug: 'base',
    dataSourceSlug: 'time_entry',
    mode: 'server',
    rowDimensions,
    columnDimensions,
    measures,
    height: 420,
    enabled: Boolean(client)
  });

  return (
    <View className="gap-3">
      <PivotGridToolbar controller={controller} />
      <PivotGridView controller={controller} />
      <PivotGridDrilldownModal controller={controller} />
    </View>
  );
}

Memoize rowDimensions, columnDimensions and measures. They are part of the query payload and the pivot structure, so new arrays on every render rebuild both.

API Reference

Options (UseDocyrusPivotGridOptions<TData>)

OptionTypeDefaultDescription
clientRestApiClient—Authenticated API client. Required.
appSlugstring—App slug of the data source. Required.
dataSourceSlugstring—Data source slug. Required.
mode'client' | 'server''client'Where to aggregate.
rowDimensionsDocyrusPivotGridDimension<TData>[]—Row grouping dimensions (outermost → innermost). Required.
columnDimensionsDocyrusPivotGridDimension<TData>[]—Column grouping dimensions. Required.
measuresDocyrusPivotGridMeasure<TData>[]—Measures aggregated in each cell. Required.
columnsstringautocolumns expression. In client mode it is auto-derived from the dimensions and measures (relation dimensions become ...field(subField)). In server mode the default is 'id'.
filtersunknown—Server-side filters forwarded verbatim.
orderBystring—orderBy expression. Client mode only.
limitnumber5000Maximum records fetched. Client mode only.
getRowId(row: TData, index: number) => string—Stable row id forwarded to usePivotGrid.
initialStatePartial<PivotGridState>—Initial expand, pin and size state.
cellColorRulesPivotGridCellColorRule[]—JSONata cell color rules.
drilldownPivotGridDrilldown<TData>—Drilldown configuration (NativeDrilldownColumn columns).
heightnumber | 'auto'600Grid height in px. Native has no auto height (the list is virtualized), so 'auto' resolves to 600.
classNamestring—Container classes, applied by PivotGridView.
exportFileNamestring'pivot-grid'Native only. Base file name for CSV, Excel and PDF exports.
enabledbooleantrueEnable the query. It also waits for client, appSlug and dataSourceSlug.
staleTimenumber30_000TanStack Query stale time in ms.

The query key is ['docyrus', 'pivot-grid', mode, appSlug, dataSourceSlug, payload].

DocyrusPivotGridDimension

FieldTypeDescription
idstringUnique id. In server mode the column alias is dim_<id>.
labelstringHeader label.
fieldstringField slug on the data source.
subFieldstringSub-field of a relation (for example 'name' for record_owner.name).
dateFormatstringServer mode. Postgres to_char format ('YYYY-MM', 'YYYY') for date bucketing.
dateRange{ interval: string; increment?: number; min: string; max: string }Needed with dateFormat. The date axis passed to the pivot matrix.
getValue(row: TData) => unknownCustom value extractor. Takes precedence over the automatic accessor.
formatValue(value: unknown) => stringLabel formatter.
sort(a: unknown, b: unknown) => numberSort comparator.
emptyLabelstringLabel for empty values.

DocyrusPivotGridMeasure

FieldTypeDescription
idstringUnique id. Also the server calculation alias.
labelstringHeader label.
fieldstringField to aggregate ('id' for count).
aggregate'sum' | 'count' | 'avg' | 'min' | 'max'Aggregation function.
transform(value: number) => numberApplied after reading the value (for example seconds → hours).
getValue(row: TData) => number | null | undefinedCustom extractor. Takes precedence over field.
formatValue(value: number) => stringCell formatter.

Result (UseDocyrusPivotGridResult<TData>)

FieldTypeDescription
controllerPivotGridController<TData>Pass it to PivotGridView, PivotGridToolbar, PivotGridExportMenu and PivotGridDrilldownModal.
itemsTData[]Rows returned by the API: raw records in client mode, aggregated rows in server mode.
isLoadingbooleanFirst load in progress.
isFetchingbooleanAny fetch in progress (including refetches).
errorError | nullQuery error.
refetch() => voidRefetch the items.

Differences from web

  • height is a pixel value. 'auto' falls back to 600.
  • className is forwarded through the controller and applied by PivotGridView.
  • drilldown.columns are NativeDrilldownColumns ({ id, header, getValue }) instead of TanStack ColumnDefs.
  • Adds exportFileName for the share-sheet exports.

Type Exports

TypeDescription
UseDocyrusPivotGridOptionsHook options.
UseDocyrusPivotGridResultHook result.
DocyrusPivotGridDimensionDocyrus-field dimension descriptor.
DocyrusPivotGridMeasureDocyrus-field measure descriptor.
DocyrusPivotGridMode'client' | 'server'.
PivotRowRecord<string, unknown> (default row type).
PivotGridAggregateRe-exported aggregate union.

On this page