sqlly_datatable/lib.rs
1//! Configurable virtualized data grid for the [GPUI] toolkit.
2//!
3//! `sqlly-datatable` provides a self-contained `Entity<GridState>` widget that
4//! you can drop into a GPUI application. It supports:
5//!
6//! * Virtualized rendering for large datasets.
7//! * Cell, row, column and rectangular drag selection.
8//! * Sorting on column headers, with a cycle through ascending, descending,
9//! and unsorted.
10//! * Per-column filtering via a rich filter panel (operator predicates,
11//! value checklist, search) opened from the built-in context menu.
12//! * Configurable column resizing, mouse-driven scrollbars, and edge-scroll
13//! during drag selection.
14//! * Clipboard copy of any selection (with or without headers).
15//! * An optional **pivot tab** ([`SqllyDataTableBuilder::pivot`]): a
16//! cross-tabulation view with a drag-and-drop field sidebar (rows /
17//! columns / values / filters), count/sum/avg/min/max aggregation,
18//! expandable row and column groups, subtotals and grand totals, sorting
19//! on labels or values, source-value filters, and CSV export. The pivot
20//! reads a shared snapshot of the grid's rows and never mutates them;
21//! switching tabs preserves both views' state. Configure it
22//! programmatically via [`pivot::PivotConfig`] and read the live layout
23//! back from [`pivot::PivotState::config`]. Pivot row height and column
24//! width can be initialized on the builder, resized in the view, and read
25//! or updated through [`pivot::PivotState`]. Right-clicks surface to a
26//! [`pivot::PivotContextMenuProvider`] with full context (grouping paths,
27//! aggregated value, driving source rows), and double-clicking any value
28//! cell drills through: the flat grid is filtered to exactly the rows
29//! behind that cell and brought to the front.
30//!
31//! The crate is intentionally GPUI-only on the UI side; the pure formatter in
32//! [`mod@format`] is usable in any context (export pipelines, server-side preview,
33//! etc.). All formatting is configurable per column by composing the
34//! [`config::GridConfig`] defaults with [`config::ColumnOverride`] entries.
35//!
36//! # Quick start
37//!
38//! ```no_run
39//! use gpui::App;
40//! use sqlly_datatable::{
41//! CellValue, Column, ColumnKind, GridConfig, GridData, SqllyDataTable,
42//! };
43//!
44//! let data = GridData::new(
45//! vec![Column { name: "id".into(), kind: ColumnKind::Integer, width: 80.0 }],
46//! vec![vec![CellValue::Integer(1)], vec![CellValue::Integer(2)]],
47//! ).expect("rectangular data");
48//! let app = gpui::Application::new();
49//! app.run(|cx: &mut App| {
50//! let _view = SqllyDataTable::builder(data)
51//! .config(GridConfig::default())
52//! .build(cx);
53//! });
54//! ```
55//!
56//! See `crates/sqlly-datatable-sample` for a runnable demo.
57//!
58//! [GPUI]: https://github.com/zed-industries/gpui
59
60// `missing_docs` is intentionally not enabled at the crate level. The public
61// surfaces documented here are stable; private internals will get docs as the
62// `grid::` modules mature. Run clippy with
63// `#![warn(missing_docs)]` in scope when cleaning up a module.
64
65pub mod config;
66pub mod data;
67pub mod filter;
68pub mod format;
69pub mod grid;
70pub mod pivot;
71
72pub use config::{
73 BooleanFormat, ColumnOverride, DateFormat, GridConfig, KeyBinding, KeyBindings, NullFormat,
74 NumberFormat, RelativeDateFormat, RelativeUnit, ReplacementRule, ReplacementTiming,
75 ResolvedColumnFormat, StringFormat, TextAlignment, TextCase, TruncationBehavior,
76};
77pub use data::{
78 compare_cells, sample_data, CellValue, Column, ColumnKind, GridData, GridDataError,
79};
80pub use filter::{ColumnFilter, FilterPredicate, NumberOp, TextOp};
81pub use grid::{
82 BusyState, ColumnContext, ContextMenu, ContextMenuItem, ContextMenuProvider,
83 ContextMenuRequest, ContextMenuSelection, ContextMenuTarget, FilterPanel, GridState, GridTab,
84 GridTheme, HitResult, MenuAction, MenuItem, PivotSidebarPosition, RowWindow, ScrollbarAxis,
85 SelectedCellContext, SelectedRowContext, Selection, SortDirection, SqllyDataTable,
86 SqllyDataTableBuilder,
87};
88pub use pivot::{
89 AggregationFn, PivotCellContext, PivotConfig, PivotContextMenuProvider,
90 PivotContextMenuRequest, PivotGrid, PivotMenuItem, PivotMenuTarget, PivotPathComponent,
91 PivotResult, PivotSidebar, PivotSortKey, PivotState, PivotZone, DEFAULT_PIVOT_COLUMN_WIDTH,
92 DEFAULT_PIVOT_ROW_HEIGHT, MIN_PIVOT_COLUMN_WIDTH, MIN_PIVOT_ROW_HEIGHT,
93};