@toclocoinc/lattice-grid 1.14.0 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lattice-grid.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Lattice Grid 1.14.0, type declarations
2
+ * Lattice Grid 1.16.0, type declarations
3
3
  * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
4
  * https://latticegrid.dev
5
5
  */
@@ -341,6 +341,22 @@ export interface LookupSpec {
341
341
  export type DecorationName = 'plain' | 'fill' | 'pill' | 'dot' | 'bar' | 'heat' | 'icon';
342
342
  export type VariantName = 'neutral' | 'info' | 'success' | 'warning' | 'danger' | 'accent' | 'none' | (string & {});
343
343
 
344
+ /** A built-in threshold icon set, mapping value bands to built-in glyphs. */
345
+ export type IconSetName = 'trafficLights' | 'arrows' | 'trafficArrows' | 'ratings' | (string & {});
346
+
347
+ /**
348
+ * One band of a threshold icon set. A value clears a band when it is at least
349
+ * `min`; the highest band it clears wins. Omit `min` on the last band to make
350
+ * it the catch-all. `label` is what assistive technology announces for the
351
+ * glyph, so a screen-reader user hears the band's meaning, not only the value.
352
+ */
353
+ export interface IconBand {
354
+ min?: number;
355
+ icon: string;
356
+ label?: string;
357
+ variant?: VariantName;
358
+ }
359
+
344
360
  export interface DecorationSpec {
345
361
  type: DecorationName;
346
362
  size?: 'sm' | 'md' | 'lg';
@@ -349,6 +365,10 @@ export interface DecorationSpec {
349
365
  edge?: boolean;
350
366
  position?: 'start' | 'end';
351
367
  name?: string | Record<string, string>;
368
+ /** icon only: a built-in threshold icon set, expanded to `bands`. */
369
+ iconSet?: IconSetName;
370
+ /** icon only: value bands mapped to glyphs, first match by descending `min`. */
371
+ bands?: IconBand[];
352
372
  min?: number;
353
373
  max?: number;
354
374
  origin?: number;
@@ -738,6 +758,59 @@ export interface Source {
738
758
 
739
759
  export interface MemorySourceConfig { mode: 'memory'; columnarBelow?: number }
740
760
 
761
+ /**
762
+ * How rows are ingested into the column store.
763
+ */
764
+ export interface IngestConfig {
765
+ /**
766
+ * Retain the caller's row objects by reference so identity round-trips.
767
+ * Default `true`, the historical behaviour: `rows.data()` returns the exact
768
+ * objects you supplied, `row === sourceObject` holds, and a custom renderer
769
+ * reading `row.sourceObject` works.
770
+ *
771
+ * Set `false` to keep only the packed columns and reconstruct a plain row
772
+ * object from them on demand. This drops roughly half the resident footprint,
773
+ * but changes three behaviours: `rows.data()` returns freshly reconstructed
774
+ * objects (new object each call, so `row === sourceObject` no longer holds),
775
+ * a custom renderer that reaches for `row.sourceObject` gets a reconstruction
776
+ * rather than the original, and equality against a row becomes value-based.
777
+ * The stored values are unchanged, so `get()`, `byKey()`, `value()` and
778
+ * `values()` are unaffected.
779
+ */
780
+ retainSource?: boolean;
781
+
782
+ /**
783
+ * Columnize `stream`-source ingest on a Worker so a large load does not block
784
+ * the main thread. Default `false`. When on, an arriving chunk that clears
785
+ * {@link IngestConfig.workerThreshold} is packed into typed column buffers on
786
+ * the Worker; the main thread merges the finished buffers into the store and
787
+ * renders, without running the per-field extraction pass that otherwise
788
+ * dominates ingest.
789
+ *
790
+ * This makes **stream** ingest non-blocking (remote sources already are).
791
+ * Memory and paged sources cannot be made non-blocking this way — the main
792
+ * thread must read the caller's own row objects — and are unaffected. The
793
+ * effect composes with `retainSource: false`: with it off the source keeps no
794
+ * caller-object array on the main thread at all, so the load is both
795
+ * non-blocking and lighter on memory.
796
+ *
797
+ * A column that reads through a closure — a `date` column's storage
798
+ * conversion, or a computed column — cannot cross the Worker boundary, so a
799
+ * grid with any such column columnizes on the main thread and says so once.
800
+ * Falls back silently to the main thread wherever a Worker cannot be created.
801
+ */
802
+ useWorker?: boolean;
803
+
804
+ /**
805
+ * Row count in a single stream chunk at or above which columnization is
806
+ * offloaded to the Worker when {@link IngestConfig.useWorker} is on. Default
807
+ * `10000`. A smaller first chunk is packed on the main thread, where the
808
+ * cost is trivial and the postMessage round trip would only add latency to
809
+ * time-to-first-row.
810
+ */
811
+ workerThreshold?: number;
812
+ }
813
+
741
814
  export interface PagedSourceConfig {
742
815
  mode: 'paged';
743
816
  pageSize?: number;
@@ -968,6 +1041,15 @@ export interface EditConfig {
968
1041
  commit?: (write: PendingWrite) => unknown;
969
1042
  confirm?: 'auto' | 'manual';
970
1043
  pendingTimeout?: number;
1044
+ /**
1045
+ * Show a preview of what a bulk paste will change before it commits (§12),
1046
+ * with confirm/cancel. Off by default: a paste commits straight away, exactly
1047
+ * as it always has. When on, a paste into more than one cell first opens a
1048
+ * dialog listing every cell that changes (old → new) and every cell that would
1049
+ * be rejected (permission, data-type, read-only); confirm commits precisely
1050
+ * that set through the ordinary edit path, cancel commits nothing.
1051
+ */
1052
+ pastePreview?: boolean;
971
1053
  }
972
1054
 
973
1055
  export interface PendingWrite {
@@ -1010,6 +1092,8 @@ export interface GridConfig {
1010
1092
  rowKey?: string | ((row: unknown) => string);
1011
1093
  /** Where rows come from: memory, paged, remote, stream or derived. */
1012
1094
  source?: SourceConfig;
1095
+ /** How rows are ingested into the column store. */
1096
+ ingest?: IngestConfig;
1013
1097
  /** Applied to every column before its own settings. */
1014
1098
  columnDefaults?: Column;
1015
1099
  /** Named bundles of column settings, referenced by a column's `preset`. */
@@ -1374,6 +1458,14 @@ export interface GridConfig {
1374
1458
  totalOnlyChangedColumns?: boolean;
1375
1459
  /** Put the total in the header rather than a footer row. */
1376
1460
  showTotalInHeader?: boolean;
1461
+ /**
1462
+ * Let the user pick a column's reduction from the column menu. On, the
1463
+ * totalling entry becomes an "Aggregate" submenu offering the aggregates the
1464
+ * column's type says are meaningful (§9.4); off, the menu keeps its plain
1465
+ * "Total this column" toggle. Off by default, so an existing grid is
1466
+ * unchanged.
1467
+ */
1468
+ aggregateChooser?: boolean;
1377
1469
  /** Render only the visible columns once there are more than this many. */
1378
1470
  columnVirtualisationAbove?: number;
1379
1471
  /** The bar beneath the grid, and which panels it carries. */
@@ -1391,6 +1483,23 @@ export interface GridConfig {
1391
1483
  */
1392
1484
  columnMenu?: boolean | ((p: ColumnMenuParams, defaults: MenuItem[]) => MenuItem[] | void);
1393
1485
 
1486
+ /**
1487
+ * Chart a selected cell range — the spreadsheet "chart this selection"
1488
+ * gesture. Off by default, so a grid opts in.
1489
+ *
1490
+ * The DOM layer draws no charts itself — the charts module is optional and
1491
+ * loaded by the host — so this is where the host wires the two together: a
1492
+ * function, or an object carrying `onChart`, is called with the grid and the
1493
+ * selected range when the reader chooses "Chart selection" from the cell
1494
+ * menu. The handler typically calls `chartRange` from
1495
+ * `lattice-grid/modules/charts`. `true` offers the item and emits nothing
1496
+ * extra; supply a handler to have it actually draw.
1497
+ */
1498
+ rangeChart?:
1499
+ | boolean
1500
+ | ((grid: Grid, range: CellRange) => void)
1501
+ | { onChart?: (grid: Grid, range: CellRange) => void };
1502
+
1394
1503
  /**
1395
1504
  * The `?` keyboard shortcut overlay. `false` suppresses it, for a host
1396
1505
  * that wants `?` for itself. Default true.
@@ -1503,6 +1612,22 @@ export interface GridConfig {
1503
1612
  /** File name for the export action, without the extension. */
1504
1613
  exportName?: string;
1505
1614
  };
1615
+ /**
1616
+ * A drag-and-drop group-by strip above the column header — the pattern AG
1617
+ * Grid calls the row-group panel. Drag a column heading into it to group by
1618
+ * that column; the active groups show as removable, reorderable chips, and
1619
+ * reordering the chips changes the nesting order. It is keyboard-operable
1620
+ * (arrows navigate, Shift+arrow reorders, Delete ungroups, and an add control
1621
+ * groups any column), and every change is announced through the live region,
1622
+ * which is why it also addresses the drag-only complaint of BACKLOG-0000429.
1623
+ *
1624
+ * Off by default and non-breaking, matching `toolPanel`. It drives the same
1625
+ * grouping model as `grid.columns.group()`; it reimplements nothing.
1626
+ */
1627
+ groupPanel?: boolean | {
1628
+ /** Placeholder shown while nothing is grouped. */
1629
+ hint?: string;
1630
+ };
1506
1631
  /** The quick filter's initial text. */
1507
1632
  quickFilterText?: string;
1508
1633
  /**
@@ -1592,6 +1717,14 @@ export type PermissionPolicy =
1592
1717
 
1593
1718
  export interface MenuItem {
1594
1719
  name?: string;
1720
+ /**
1721
+ * An icon shown in the slot before the label. Three forms, told apart without
1722
+ * a second option so existing definitions keep working: a registered sprite
1723
+ * name (`'download'`), a single character or emoji (`'↑'`), or author-trusted
1724
+ * element markup (`'<i class="fa-light fa-download"></i>'`), which is rendered
1725
+ * as an element rather than shown as text. Markup is inserted into the icon
1726
+ * slot only — never the label — at the same trust as `action`.
1727
+ */
1595
1728
  icon?: string;
1596
1729
  shortcut?: string;
1597
1730
  action?: () => void;
@@ -2156,6 +2289,11 @@ export interface RowsApi {
2156
2289
  export interface ColumnsApi {
2157
2290
  /** Set or clear a column's totals-row reduction. */
2158
2291
  setTotal(id: string, fn: TotalName | TotalFn | null): void;
2292
+ /**
2293
+ * The aggregate names meaningful for a column, honouring its type's
2294
+ * `totals.supported` declaration (§9.4). What the aggregate chooser offers.
2295
+ */
2296
+ aggregates(id: string): TotalName[];
2159
2297
  /** Every distinct value in a column, from the dictionary where there is one. */
2160
2298
  distinct(id: string): unknown[];
2161
2299
  get(id: string): ResolvedColumn | undefined;
@@ -2178,6 +2316,13 @@ export interface ColumnsApi {
2178
2316
  move(id: string, to: number): void;
2179
2317
  pin(id: string, side: 'start' | 'end' | null): void;
2180
2318
  resize(id: string, px: number): void;
2319
+ /**
2320
+ * Set, change or clear a column's decoration at runtime (§8.7). Pass `null` to
2321
+ * clear it back to plain text. Presentation config: it is not on the undo
2322
+ * timeline and is not carried in a saved view — use `grid.formatting` for
2323
+ * durable, view-persisted conditional styling.
2324
+ */
2325
+ decorate(id: string, decoration: DecorationName | DecorationSpec | null, opts?: { variant?: VariantSpec }): void;
2181
2326
  autoSize(ids?: string | string[]): void;
2182
2327
  fit(): void;
2183
2328
  group(ids: string | string[]): void;
@@ -2261,6 +2406,18 @@ export interface EditApi {
2261
2406
  redo(): void;
2262
2407
  setCells(writes: { key: string; colId: string; value: unknown }[], type?: 'cell' | 'fill' | 'paste'): number;
2263
2408
  pasteInto(anchor: { key: string; colId: string }, text: string, extent?: { rows?: number; columns?: number }): number;
2409
+ /** Whether a bulk paste is previewed before it commits (`edit.pastePreview`, §12). */
2410
+ readonly pastePreview: boolean;
2411
+ /**
2412
+ * Compute what a paste would change, without committing (§12). The engine
2413
+ * behind `edit.pastePreview`: `changes` are the accepted writes with their old
2414
+ * and new values (and whether each actually differs), `rejected` are the cells
2415
+ * a commit would refuse, each with a reason.
2416
+ */
2417
+ previewPaste(anchor: { key: string; colId: string }, text: string, extent?: { rows?: number; columns?: number }): {
2418
+ changes: { key: string; colId: string; oldValue: unknown; newValue: unknown; changed: boolean }[];
2419
+ rejected: { key: string; colId: string; value: unknown; reason: 'permission' | 'readOnly' | 'validation' | 'locked' | 'missing' }[];
2420
+ };
2264
2421
  settle(id: string, ok: boolean, reason?: string): boolean;
2265
2422
  pending(): OpenWrite[];
2266
2423
  status(key: string, colId: string): 'pending' | null;
@@ -3193,6 +3350,15 @@ export interface StatConfig extends StatValueSpec {
3193
3350
  /** An element, or a CSS selector resolved against the grid's document. */
3194
3351
  container: HTMLElement | string;
3195
3352
  title?: string;
3353
+ /**
3354
+ * An optional leading icon beside the title and value, using the same value
3355
+ * contract as a menu item: a registered sprite name, a single character or
3356
+ * emoji, or author-trusted element markup (`'<i class="fa-light fa-bolt">
3357
+ * </i>'`, an `<img>`). It lays out to the side without disturbing the change
3358
+ * indicator, threshold bands or confidence interval; omit it for the plain
3359
+ * tile layout.
3360
+ */
3361
+ icon?: string;
3196
3362
  /** A literal value, a spec to reduce, or a function of the grid. */
3197
3363
  value?: unknown | StatValueSpec | ((grid: Grid) => unknown);
3198
3364
  /** Text under the value, or a function of it. */
@@ -3606,6 +3772,12 @@ export interface ChartSpec {
3606
3772
  y?: string;
3607
3773
  /** Splits the measure into one series per distinct value. */
3608
3774
  series?: string;
3775
+ /**
3776
+ * The exact rows to chart, overriding the grid's own walk — an array, or a
3777
+ * function returning one at draw time. `chartRange` uses it to bind a chart
3778
+ * to the band of rows a selected range covers rather than the whole grid.
3779
+ */
3780
+ rows?: object[] | ((grid: Grid) => object[]);
3609
3781
  /** Several measures at once, for combo and candlestick. */
3610
3782
  measures?: ChartMeasure[];
3611
3783
  /** Endpoints, for sankey, chord and network. */
@@ -3736,6 +3908,39 @@ declare module 'lattice-grid/modules/charts' {
3736
3908
  export const SCHEMES: Readonly<Record<string, readonly string[]>>;
3737
3909
  export const PALETTE: readonly string[];
3738
3910
  export function createChart(spec: ChartSpec): Chart;
3911
+ /**
3912
+ * Chart a selected cell range. Derives the chart from the range's shape — a
3913
+ * leading text column becomes the categories, the numeric columns become the
3914
+ * measures — and returns the live chart, or null when the range has nothing
3915
+ * to measure. Respects hidden and unreadable columns. The type is a sensible
3916
+ * default the caller can change with `chart.update({ type })`.
3917
+ */
3918
+ export function chartRange(
3919
+ grid: Grid,
3920
+ opts: {
3921
+ container: Element | string;
3922
+ range?: CellRange;
3923
+ type?: ChartType;
3924
+ } & Partial<ChartSpec>,
3925
+ ): Chart | null;
3926
+ /** Would {@link chartRange} draw something for the grid's current selection? */
3927
+ export function canChartRange(grid: Grid, opts?: { range?: CellRange }): boolean;
3928
+ /**
3929
+ * Decide what a chart of a range should be, without drawing it: the type, the
3930
+ * category column, the measure columns, and a `spec` ready for `createChart`
3931
+ * — or a `reason` naming why the range cannot be charted.
3932
+ */
3933
+ export function deriveRangeSpec(
3934
+ grid: Grid,
3935
+ opts?: { range?: CellRange; type?: ChartType },
3936
+ ): {
3937
+ spec: ChartSpec | null;
3938
+ type: ChartType | null;
3939
+ x: string | null;
3940
+ measures: string[];
3941
+ columns: string[];
3942
+ reason: string | null;
3943
+ };
3739
3944
  export function registerScheme(name: string, colours: readonly string[]): void;
3740
3945
  export function resolveScheme(spec?: object): object;
3741
3946
  export function schemeNames(): string[];
@@ -3824,7 +4029,16 @@ declare module 'lattice-grid/modules/htmx' {
3824
4029
  }
3825
4030
 
3826
4031
  declare module 'lattice-grid/modules/dhtmlx-compat' {
3827
- /** A dhtmlx Grid-shaped API over Lattice, for migrating a piece at a time. */
4032
+ /**
4033
+ * A dhtmlx Grid-shaped API over Lattice, for migrating a piece at a time.
4034
+ *
4035
+ * The module shares the page's one core rather than bundling its own: the
4036
+ * grid it builds comes from the `lattice-grid` package the app already loads
4037
+ * (or the `LatticeGrid` global a script tag publishes), so a licence set on
4038
+ * that core applies to these grids too. Load the core alongside this module —
4039
+ * a bundler wires the peer import for you; a `<script src>` page loads the
4040
+ * global build first.
4041
+ */
3828
4042
  export class Grid {
3829
4043
  constructor(container: Element | string, config?: object);
3830
4044
  }