Docyrus

TimesheetPivot

A horizontal pivot table for time tracking with heatmap coloring, column totals, and striped rows.

iOSAndroid
Preview TimesheetPivot on your device

Scan with Expo Go

Download Expo Go, then scan the QR code to preview native components.

Installation

pnpm dlx @docyrus/cli add @docyrus/rn-timesheet-pivot

Usage

import { TimesheetPivot } from '@/components/docyrus-native/timesheet-pivot';

const columns = [
  { key: 'mon', label: 'Mon' },
  { key: 'tue', label: 'Tue' },
  { key: 'wed', label: 'Wed' },
  { key: 'thu', label: 'Thu' },
  { key: 'fri', label: 'Fri' },
];

const rows = [
  {
    id: 'project-1',
    title: 'Project Atlas',
    subtitle: 'Mobile sprint',
    values: { mon: 2.5, tue: 1.5, wed: 4, thu: 3.5, fri: 2 },
  },
  {
    id: 'project-2',
    title: 'Project Northwind',
    values: { mon: 1, tue: 2, wed: 0, thu: 2.5, fri: 3 },
  },
];

<TimesheetPivot
  columns={columns}
  rows={rows}
  messages={{ row: 'Project' }}
  valueKind="hours"
  showTotals
/>

Features

  • Heatmap coloring — cells are tinted based on value intensity relative to the max value
  • Column totals footer — a summary row showing totals per column and a grand total
  • Striped rows — alternating row backgrounds for readability
  • FlatList rendering — virtualized row rendering with getItemLayout for O(1) scroll performance
  • Three value formats — raw, hours (2.5h), minutes (2h 30m)
  • Custom formatter — override cell display with valueFormatter
  • Row press — optional onRowPress callback for navigation
  • Dark mode — fully theme-aware with light/dark opacity adjustments

API Reference

TimesheetPivotProps

PropTypeDefaultDescription
columnsTimesheetPivotColumn[]—Column definitions (key + label)
rowsTimesheetPivotRow[]—Row data with values per column
messagesPartial<TimesheetPivotMessages>—App-supplied copy; each key wins over the translation provider
isLoadingbooleanfalseShows loading state
emptyMessagestring—Optional empty state override
showTotalsbooleantrueShows total column per row + footer totals row
emptyValuestring'—'Placeholder for empty/zero cells
valueKind'raw' | 'hours' | 'minutes''raw'Default numeric formatter
onRowPress(row: TimesheetPivotRow) => void—Row press callback
valueFormatter(value, columnKey, row) => string—Custom cell value formatter
classNamestring—Additional wrapper className

TimesheetPivotColumn

FieldTypeDescription
keystringUnique column identifier (used as key in values)
labelstringDisplay label in header

TimesheetPivotRow

FieldTypeDescription
idstringUnique row identifier
titlestringPrimary row label
subtitlestring?Secondary label (shown below title)
valuesRecord<string, CellValue>Cell values keyed by column key
totalCellValue?Explicit total (auto-computed if omitted)

TimesheetPivotMessages

Every field is optional in the messages prop and falls back to <UiTranslationProvider>.

FieldTypeFallback keyEnglish fallbackDescription
loadingstringui.timesheetPivot.loadingLoading timesheet...Loading state label
emptystringui.timesheetPivot.emptyNo time recordedEmpty state label
totalstringui.timesheetPivot.totalTotalTotal column/row header label
rowstringui.timesheetPivot.rowItemFirst column header label

TimesheetPivotCellValue

type TimesheetPivotCellValue = number | string | null | undefined;

Value Formatting

The component supports three built-in formatters via valueKind:

KindInputOutput
raw2.52.5
hours2.52.5h
minutes1502h 30m

For custom formatting, use valueFormatter:

<TimesheetPivot
  valueFormatter={(value, columnKey, row) => {
    if (columnKey === '__total__') return `${value}h total`;
    return typeof value === 'number' ? `${value}h` : '—';
  }}
/>

Components

ComponentDescription
TimesheetPivotHorizontal pivot table — the mobile timesheet view (conceptually the native counterpart of web PivotCalendar)

Type Exports

TypeDescription
TimesheetPivotPropsProps for TimesheetPivot
TimesheetPivotColumn{ key, label } column definition
TimesheetPivotRowRow with per-column values
TimesheetPivotCellValuenumber | string | null | undefined
TimesheetPivotValueKind'raw' | 'hours' | 'minutes'
TimesheetPivotMessagesCopy keys

On this page