npm package: @strucura/visualizations-react
Description: [![npm version](https://img.shields.io/npm/v/@strucura/visualizations-react.svg)](https://www.npmjs.com/package/@strucura/visualizations-react) [![npm downloads](https://img.shields.io/npm/dm/@strucura/visualizations-react.svg)](https://www.npmjs.com/pack
Latest version: 0.1.1

# @strucura/visualizations-react

[![npm version](https://img.shields.io/npm/v/@strucura/visualizations-react.svg)](https://www.npmjs.com/package/@strucura/visualizations-react)
[![npm downloads](https://img.shields.io/npm/dm/@strucura/visualizations-react.svg)](https://www.npmjs.com/package/@strucura/visualizations-react)
[![Tests](https://github.com/strucura/visualizations-react/actions/workflows/tests.yml/badge.svg)](https://github.com/strucura/visualizations-react/actions/workflows/tests.yml)
[![codecov](https://codecov.io/gh/strucura/visualizations-react/branch/main/graph/badge.svg)](https://codecov.io/gh/strucura/visualizations-react)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.7+-blue.svg)](https://www.typescriptlang.org/)

Headless React hooks and types for building data visualizations — datagrids, charts, and dashboards. This package provides the state management and data-fetching layer; pair it with `@strucura/visualizations-shadcn` (or your own UI components) for rendering.

## Installation

```bash
npm install @strucura/visualizations-react
```

### Peer Dependencies

- `react` ^19.0.0
- `react-dom` ^19.0.0

## Overview

This package exports three categories of building blocks:

1. **Hooks** — Manage data fetching, filtering, sorting, pagination, and editor state
2. **Types** — TypeScript interfaces for schemas, controllers, filters, sorts, and more
3. **Utilities** — Helpers for formatting, filter construction, and serialization

## Hooks

### `useDataGrid`

Manages the full lifecycle of a datagrid: schema fetching, data loading, filtering, sorting, pagination, column visibility, row selection, and inline/bulk actions.

Controllers should be Wayfinder-generated controllers, not hand-built URL strings. Wayfinder generates typed controller objects from your Laravel routes that provide `.url()` methods.

```tsx
import { useDataGrid } from '@strucura/visualizations-react';
import UserDataGrid from '@/actions/App/DataGrids/UserDataGrid';

const grid = useDataGrid({
    controller: UserDataGrid,
});

// grid.schema       — column definitions, actions, floating filters
// grid.rows         — current page of data
// grid.loading      — whether data is being fetched
// grid.filterSets   — active filter sets
// grid.sorts        — active sorts
// grid.pagination   — { current_page, last_page, total, per_page }
// grid.toggleColumnSort(column)
// grid.resetFilterSets(filterSets)
// grid.setPage(page)
// grid.selectRow(key, selected)
// grid.executeInlineAction(name, key)
// grid.executeBulkAction(name)
```

### `useDataGridViews`

Manages saved views (named configurations of filters, sorts, and column visibility) for a datagrid.

```tsx
import { useDataGridViews } from '@strucura/visualizations-react';
import UserDataGrid from '@/actions/App/DataGrids/UserDataGrid';

const views = useDataGridViews({
    controller: UserDataGrid,
});

// views.views       — array of saved DataGridView objects
// views.saveView({ name, filterSets, sorts, columns })
// views.deleteView(viewId)
// views.applyView(view, gridHandlers)
// views.resetView(schema, gridHandlers)
```

### `useChartData`

Fetches chart schema and data with support for filtering.

```tsx
import { useChartData } from '@strucura/visualizations-react';
import RevenueChart from '@/actions/App/Charts/RevenueChart';

const chart = useChartData({
    controller: RevenueChart,
});

// chart.schema              — label, datasets, chart type
// chart.data                — array of data points
// chart.loading             — whether data is being fetched
// chart.filterSets          — active filter sets
// chart.addFilterSet()
// chart.removeFilterSet(index)
// chart.updateFilterSetOperator(index, operator)
// chart.addFilter(setIndex)
// chart.removeFilter(setIndex, filterIndex)
// chart.updateFilter(setIndex, filterIndex, changes)
// chart.resetFilterSets(filterSets)
// chart.clearFilterSets()
// chart.activeFilterCount   — number of active filters
// chart.sorts               — active sorts
// chart.setSorts(sorts)
// chart.hasFloatingFilters  — whether schema defines floating filters
// chart.showFloatingFilters / chart.setShowFloatingFilters(show)
// chart.refresh()           — re-fetch data
```

### `useDashboardEditor`

Manages widget layout state for a dashboard — adding, removing, reordering, and updating widgets.

```tsx
import { useDashboardEditor } from '@strucura/visualizations-react';

const editor = useDashboardEditor({ dashboard });

// editor.items           — array of WidgetItem (current layout)
// editor.addWidget(widget, name, columnSpan)
// editor.removeWidget(index)
// editor.updateWidget(index, { name, column_span })
// editor.reorder(fromIndex, toIndex)
// editor.updateFilterSorts(index, filterSets, sorts)
// editor.updateColumnVisibility(index, columns)
// editor.serialize()     — returns SerializedWidget[] for saving
```

### `useFilterBuilder`

Low-level hook for managing filter set state — adding/removing filters and filter sets, updating operators and values.

```tsx
import { useFilterBuilder } from '@strucura/visualizations-react';

const builder = useFilterBuilder({
    schema,
    initialFilterSets: [],
});

// builder.filterSets
// builder.addFilterSet()
// builder.removeFilterSet(index)
// builder.addFilter(setIndex)
// builder.updateFilter(setIndex, filterIndex, changes)
// builder.removeFilter(setIndex, filterIndex)
```

### `useVisualizationData`

Base hook used internally by `useDataGrid` and `useChartData`. Handles schema fetching, data fetching with filter/sort/pagination params, and error state. You can use this directly for custom visualization types.

```tsx
import { useVisualizationData } from '@strucura/visualizations-react';
import CustomVisualization from '@/actions/App/Visualizations/CustomVisualization';

const viz = useVisualizationData({
    controller: CustomVisualization,
    initialFilterSets: [],
    initialSorts: [],
});
```

## Types

All types are exported from the package root:

### Shared

- `FilterSet`, `Filter`, `FilterSetOperator`, `FilterOperator` — filter definitions and enums
- `Sort`, `SortOperator` — sort definitions and enum
- `FloatingFilter` — quick-access filter definitions
- `VisualizationController` — base controller shape, satisfied by Wayfinder-generated controllers (`handleSchema.url()`, `handleData.url()`)
- `VisualizationState` — base state shape returned by hooks

### DataGrids

- `DataGridSchema` — full schema including columns, actions, floating filters
- `DataGridColumn` — column definition (field, header, type, sortable, filterable, etc.)
- `DataGridAction` — inline or bulk action definition
- `DataGridFloatingFilter` — floating filter definition
- `DataGridController` — Wayfinder controller shape for datagrids
- `DataGridView`, `DataGridViewColumn` — saved view definitions
- `PaginationState` — `{ current_page, last_page, total, per_page }`

### Charts

- `ChartSchema` — chart schema (label, datasets, floating filters)
- `ChartLabel` — label field definition
- `ChartDataset` — dataset definition (field, header, type: bar/line/area/pie/doughnut)
- `ChartController` — Wayfinder controller shape for charts

### Dashboards

- `Dashboard` — full dashboard with widgets
- `DashboardWidget` — widget placement (widget reference, column span, filters, sorts)
- `DashboardRevision` — revision history entry
- `DashboardShare` — share record
- `Widget` — widget definition (id, name, type, route_path)
- `WidgetItem` — runtime widget state used by the editor
- `DashboardController` — Wayfinder controller shape for dashboards

## Utilities

- `formatCellValue(value, type)` — formats a cell value based on column type
- `OPERATORS_BY_TYPE` / `getOperators(type)` — available filter operators per column type
- `defaultFilter(columns)` / `defaultFilterSet(columns)` — create empty filter/filter set
- `extractFloatingValues(filterSets, floatingFilters)` / `applyFloatingValues(...)` — convert between floating filter values and filter sets
- `buildWidgetItems(dashboard)` — convert a Dashboard's widgets into WidgetItem[]
- `serializeWidgets(items)` — convert WidgetItem[] back to a saveable format

## Usage with UI Components

This package is designed to be paired with a UI layer. The `@strucura/visualizations-shadcn` package provides shadcn/ui components that consume these hooks:

```bash
npx shadcn add ./packages/visualizations-shadcn/public/r/datagrid.json
npx shadcn add ./packages/visualizations-shadcn/public/r/dashboard.json
```

Or build your own components using the hooks directly — they're completely headless.

## Development

```bash
npm test          # run tests
npm run test:watch  # run tests in watch mode
```