# rn-pivot-grid URL: /docs/native/docyrus/pivot-grid Cross-tabulation pivot grid with multi-dimension rows and columns, aggregation, conditional cell coloring, expand and collapse, pinned value columns, a drilldown action sheet, a toolbar, and CSV, Excel and PDF export. ## Installation ```bash pnpm dlx @docyrus/cli add @docyrus/rn-pivot-grid ``` **Dependencies:** - [jsonata](https://www.npmjs.com/package/jsonata) - [@shopify/flash-list](https://www.npmjs.com/package/@shopify/flash-list) - [expo-file-system (optional)](https://www.npmjs.com/package/expo-file-system) - [expo-sharing (optional)](https://www.npmjs.com/package/expo-sharing) - [expo-print (optional)](https://www.npmjs.com/package/expo-print) The export modules are **optional peers** and are loaded lazily. CSV and Excel exports need `expo-file-system` (SDK 54+ `File` API) and `expo-sharing`. PDF export needs `expo-print` and `expo-sharing`. When a module is missing, the export does nothing. For a server-backed pivot, see [`useDocyrusPivotGrid`](/docs/native/hooks/use-docyrus-pivot-grid). ## Usage ```tsx import { Badge } from '@/components/docyrus-native/badge'; import { PivotGrid, PivotGridView, PivotGridToolbar, PivotGridDrilldownModal, usePivotGrid, type PivotGridDimension, type PivotGridMeasure, } from '@/components/docyrus-native/pivot-grid'; interface SalesRow { region: string; product: string; revenue: number; } const data: SalesRow[] = [ { region: 'North', product: 'Widget A', revenue: 1200 }, { region: 'North', product: 'Widget B', revenue: 850 }, { region: 'South', product: 'Widget A', revenue: 960 }, { region: 'South', product: 'Widget B', revenue: 1100 }, ]; const rowDimensions: PivotGridDimension} /> ); } // Or self-contained (creates its own controller): ``` ## Features - **Multi-dimension pivoting** — 1-3 row/column dimensions with nested grouping - **Aggregation** — sum, count, avg, min, max - **Expand/collapse** — toggle individual rows/columns or expand/collapse all - **Conditional coloring** — JSONata-based cell color rules with Tailwind color support - **Drilldown** — tap a leaf cell to see contributing source rows in an action sheet - **Toolbar** — expand / collapse buttons, the export menu, and `startContent` / `endContent` slots - **Export** — CSV, a real `.xlsx` workbook (merged multi-level headers, frozen panes, styled subtotal and total rows, written by a zero-dependency OOXML writer) and PDF (`expo-print`). Each export opens the native share sheet. - **Pinned value columns** — `pinColumns(ids, 'left' | 'right')` keeps columns sticky while you scroll horizontally. Row headers are always pinned. - **Virtualized scrolling** — FlashList windowing for large datasets - **Synchronized scroll** — row headers and column headers stay in sync with the data grid ## API Reference ### PivotGrid / usePivotGrid props `PivotGrid` takes the same props as `usePivotGrid` (`PivotGridProps = UsePivotGridProps`) and creates its own controller. | Prop | Type | Default | Description | |------|------|---------|-------------| | `data` | `TData[]` | — | Source rows. Required. | | `rowDimensions` | `PivotGridDimension[]` | — | Row grouping dimensions (outermost → innermost). Required. | | `columnDimensions` | `PivotGridDimension[]` | — | Column grouping dimensions. Required. | | `measures` | `PivotGridMeasure[]` | — | Aggregation measures. Required. | | `getRowId` | `(row: TData, index: number) => string` | — | Stable row id. | | `initialState` | `Partial` | — | Initial expanded rows and columns, column pinning and column sizing. | | `cellColorRules` | `PivotGridCellColorRule[]` | — | JSONata-based conditional cell colors. | | `drilldown` | `PivotGridDrilldown` | — | Drilldown columns and title getter. | | `height` | `number` | `480` | Grid height in px. | | `rowHeaderWidth` | `number` | `140` | Width of the first row-header column. | | `childRowHeaderWidth` | `number` | `110` | Width of the other row-header columns. | | `valueColumnWidth` | `number` | `100` | Leaf value column width. | | `subtotalColumnWidth` | `number` | `108` | Subtotal column width. | | `grandTotalColumnWidth` | `number` | `120` | Grand-total column width. | | `rowHeight` | `number` | `40` | Data row height. | | `headerRowHeight` | `number` | `40` | Header row height. | | `exportFileName` | `string` | `'pivot-grid'` | Base file name for CSV, Excel and PDF exports. | | `className` | `string` | — | Container classes. | | `style` | `ViewStyle` | — | Deprecated. Use `className`. | ### PivotGridView Renders a controller from `usePivotGrid`. Use it to share one controller with the toolbar and the drilldown modal. | Prop | Type | Default | Description | |------|------|---------|-------------| | `controller` | `PivotGridController` | — | Controller instance. Required. | | `className` | `string` | `controller.className` | Container classes. | | `style` | `ViewStyle` | — | Deprecated. Use `className`. | ### PivotGridToolbar A horizontally scrolling toolbar with expand rows, collapse rows, expand columns, collapse columns and the export menu. | Prop | Type | Default | Description | |------|------|---------|-------------| | `controller` | `PivotGridController` | — | Controller instance. Required. | | `startContent` | `ReactNode` | — | Rendered before the built-in buttons. | | `endContent` | `ReactNode` | — | Rendered after the export button. | | `showExport` | `boolean` | `true` | Show the export menu button. | | `className` | `string` | — | Classes for the scroll container. | ### PivotGridExportMenu An export button that opens an action sheet with **Export CSV**, **Export Excel** and **Export PDF**. It replaces the web dropdown. | Prop | Type | Default | Description | |------|------|---------|-------------| | `controller` | `PivotGridController` | — | Controller instance. Required. | | `className` | `string` | — | Button classes. | ### PivotGridDrilldownModal An action sheet that lists the source rows behind a tapped leaf cell. | Prop | Type | Default | Description | |------|------|---------|-------------| | `controller` | `PivotGridController` | — | Controller instance. Required. | | `columns` | `NativeDrilldownColumn[]` | `controller.drilldownColumns` | Columns shown for each row. | ### PivotGridController Returned by `usePivotGrid`. | Field | Type | Description | |-------|------|-------------| | `className` | `string \| undefined` | Container classes forwarded from props. | | `rowHeaderColumnIds` | `string[]` | Synthetic row-header ids (`__pivot_row_header_`). | | `valueColumnIds` | `string[]` | Visible value-column ids in render order: left-pinned, center, right-pinned. | | `visibleLeafColumns` | `PivotGridLeafColumn[]` | Visible value columns in render order. | | `headerRows` | `PivotGridHeaderRow[]` | Column header rows (cells carry `pinPosition`). | | `headerDepth` | `number` | Number of header rows. | | `visibleRows` | `PivotGridRenderedRow[]` | Rendered rows (group, leaf, subtotal, grand-total). | | `rowDimensions` | `PivotGridDimension[]` | Row dimensions. | | `cellColorMap` | `Map` | Cell id → background color from the color rules. | | `drilldownColumns` | `NativeDrilldownColumn[] \| undefined` | `drilldown.columns`, or columns derived from the first row's keys. | | `drilldownState` | `PivotGridDrilldownState` | `{ open, cell }`. | | `columnWidths` | `PivotGridColumnWidths` | `{ rowHeaders: number[]; valueColumns: Map }`. | | `columnPinning` | `PivotGridColumnPinningState` | Current value-column pinning. | | `getColumnPinPosition` | `(columnId: string) => PivotGridPinPosition` | `'left'`, `'right'` or `false`. | | `rowHeight` / `headerRowHeight` / `height` | `number` | Resolved sizes. | | `toggleRow` / `toggleColumn` | `(nodeId: string) => void` | Expand or collapse one group. | | `expandAllRows` / `collapseAllRows` / `expandAllColumns` / `collapseAllColumns` | `() => void` | Bulk expand or collapse. | | `pinColumns` | `(columnIds: string[], position: 'left' \| 'right') => void` | Pin value columns (sticky while scrolling horizontally). | | `unpinColumns` | `(columnIds: string[]) => void` | Unpin value columns. | | `openDrilldown` / `closeDrilldown` | `(cell) => void` / `() => void` | Drilldown sheet control. | | `getDrilldownRows` | `(cell: PivotGridRenderedCell) => TData[]` | Source rows of a cell. | | `getDrilldownTitle` | `(cell: PivotGridRenderedCell) => string` | Title (custom `drilldown.getTitle`, or `row path x column path`). | | `exportCsv` | `() => Promise` | Shares a CSV file. | | `exportExcel` | `() => Promise` | Shares an `.xlsx` workbook. | | `exportPdf` | `() => Promise` | Shares a PDF rendered by `expo-print`. | ### PivotGridState | Field | Type | Description | |-------|------|-------------| | `expandedRowIds` | `Record` | Expanded row group ids (default: all expanded). | | `expandedColumnIds` | `Record` | Expanded column group ids. | | `columnPinning` | `PivotGridColumnPinningState` | `{ left?: string[]; right?: string[] }`. Value-column ids only; row headers are always pinned. | | `columnSizing` | `PivotGridColumnSizingState` | `Record` width overrides. Row headers use `__pivot_row_header_`. | ### PivotGridDimension | Field | Type | Description | |-------|------|-------------| | `id` | `string` | Unique dimension id. | | `label` | `string` | Display label. | | `getValue` | `(row: TData) => unknown` | Extracts the dimension value. | | `formatValue` | `(value: unknown) => string` | Optional value formatter. | | `sort` | `(a: unknown, b: unknown) => number` | Optional sort comparator. | | `emptyLabel` | `string` | Label for empty or null values. | ### PivotGridMeasure | Field | Type | Description | |-------|------|-------------| | `id` | `string` | Unique measure id. | | `label` | `string` | Display label. | | `getValue` | `(row: TData) => number \| null \| undefined` | Value accessor (omit to count rows). | | `aggregate` | `PivotGridAggregate` | `'sum' \| 'count' \| 'avg' \| 'min' \| 'max'`. | | `formatValue` | `(value: number) => string` | Output formatter. | ### PivotGridCellColorRule | Field | Type | Description | |-------|------|-------------| | `formula` | `string` | JSONata expression (receives `value`, `measureId`, `rowPath`, `columnPath`, …). | | `color` | `string` | Tailwind color name (for example `'green-100'`) or a hex value. | | `scope` | `PivotGridColorScope` | Optional: `'leaf' \| 'subtotal' \| 'total' \| 'grand-total'`. | ### PivotGridDrilldown / NativeDrilldownColumn | Field | Type | Description | |-------|------|-------------| | `columns` | `NativeDrilldownColumn[]` | `{ id: string; header: string; getValue: (row: TData) => string }[]`. | | `getTitle` | `(cell: PivotGridRenderedCell) => string` | Custom drilldown title. | ## Translations | Key | English fallback | |-----|------------------| | `ui.pivotGrid.expandRows` / `collapseRows` / `expandColumns` / `collapseColumns` | Expand rows / Collapse rows / Expand columns / Collapse columns | | `ui.pivotGrid.export` / `exportCsv` / `exportExcel` / `exportPdf` | Export / Export CSV / Export Excel / Export PDF | | `ui.pivotGrid.noData` | No data to pivot | | `ui.pivotGrid.grandTotal` | Grand Total (drilldown title) | | `ui.pivotGrid.contributingRows` / `rowNumber` / `noRows` | `{count}` contributing row(s) / Row `{index}` / No rows to display | ## Hooks ### usePivotGrid ```tsx const controller = usePivotGrid(props: UsePivotGridProps); ``` Returns a `PivotGridController` with the full view model and every action callback. Use it when `PivotGridView`, `PivotGridToolbar` and `PivotGridDrilldownModal` need to share one controller. ## Components | Component | Description | |-----------|-------------| | `PivotGrid` | Self-contained grid. | | `PivotGridView` | Grid for an external controller. | | `PivotGridToolbar` | Expand / collapse / export toolbar. | | `PivotGridExportMenu` | Export action sheet. | | `PivotGridDrilldownModal` | Drilldown action sheet. | ## Type Exports | Type | Description | |------|-------------| | `PivotGridProps` | Props for `PivotGrid` (alias of `UsePivotGridProps`). | | `UsePivotGridProps` | Props accepted by `usePivotGrid`. | | `PivotGridController` | Controller returned by `usePivotGrid`. | | `PivotGridToolbarProps` | Props for `PivotGridToolbar`. | | `PivotGridExportMenuProps` | Props for `PivotGridExportMenu`. | | `PivotGridDimension` | Dimension definition (row or column). | | `PivotGridMeasure` | Measure definition. | | `PivotGridAggregate` | `'sum' \| 'count' \| 'avg' \| 'min' \| 'max'`. | | `PivotGridCellColorRule` | Conditional cell color rule. | | `PivotGridColorScope` | `'leaf' \| 'subtotal' \| 'total' \| 'grand-total'`. | | `PivotGridState` | Expanded, pinning and sizing state. | | `PivotGridColumnPinningState` | `{ left?: string[]; right?: string[] }`. | | `PivotGridColumnSizingState` | `Record`. | | `PivotGridPinPosition` | `'left' \| 'right' \| false`. | | `PivotGridDrilldown` | Drilldown configuration. | | `PivotGridDrilldownState` | Drilldown open and cell state. | | `PivotGridHeaderRow` / `PivotGridHeaderCell` | Header structures. | | `PivotGridLeafColumn` | Leaf column structure. | | `PivotGridRenderedRow` / `PivotGridRenderedCell` | Rendered row and cell. | | `PivotGridColumnWidths` | Row-header and value-column widths. | | `NativeDrilldownColumn` | Drilldown column definition. | | `PivotGridDemoRow` | Demo row shape (with `createPivotGridDemoRows` and the `pivotGridDemo*` presets). |