@svgrid/grid 2.6.20 → 2.6.22

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.
Files changed (110) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/README.md +22 -0
  3. package/dist/GridMenus.svelte +17 -12
  4. package/dist/SvGrid.controller.svelte.d.ts +14 -8
  5. package/dist/SvGrid.controller.svelte.js +214 -74
  6. package/dist/SvGrid.css +1 -1
  7. package/dist/SvGrid.svelte +112 -57
  8. package/dist/SvGrid.types.d.ts +191 -1
  9. package/dist/ai.d.ts +28 -0
  10. package/dist/ai.js +6 -0
  11. package/dist/cdn/{GridMenus-B0F9iBrG.js → GridMenus-BuoBPqxx.js} +137 -132
  12. package/dist/cdn/GridMenus-n4llxoOI.js +494 -0
  13. package/dist/cdn/column-resize-DsfNXMom.js +102 -0
  14. package/dist/cdn/row-resize-BRcimkUT.js +95 -0
  15. package/dist/cdn/{src-Cd0tearp.js → src-C9Hihx1W.js} +3497 -3487
  16. package/dist/cdn/{src-B1TdiyS8.js → src-D1lXwq1l.js} +8258 -8248
  17. package/dist/cdn/svgrid.js +10 -8
  18. package/dist/cdn/svgrid.svelte-external.js +10 -8
  19. package/dist/cdn/validate-_CDJzgIo.js +75 -0
  20. package/dist/cell-formatting.d.ts +2 -0
  21. package/dist/cell-formatting.js +2 -0
  22. package/dist/chart-export.d.ts +1 -0
  23. package/dist/chart.d.ts +31 -5
  24. package/dist/chart.js +9 -3
  25. package/dist/column-groups.js +1 -1
  26. package/dist/column-resize.d.ts +46 -0
  27. package/dist/column-resize.js +205 -0
  28. package/dist/columns.d.ts +0 -3
  29. package/dist/columns.js +0 -57
  30. package/dist/core.d.ts +216 -4
  31. package/dist/core.js +532 -119
  32. package/dist/createTree.svelte.d.ts +3 -0
  33. package/dist/createTree.svelte.js +1 -0
  34. package/dist/datetime/date-core.d.ts +2 -0
  35. package/dist/datetime/date-restrict.d.ts +1 -0
  36. package/dist/datetime/timezone.d.ts +1 -0
  37. package/dist/dock-manager-model.d.ts +3 -0
  38. package/dist/dock-manager-model.js +1 -0
  39. package/dist/dock-model.d.ts +6 -0
  40. package/dist/dock-model.js +3 -0
  41. package/dist/editor-contract.d.ts +1 -0
  42. package/dist/filtering/excel-filters.js +28 -0
  43. package/dist/group-display.d.ts +1 -1
  44. package/dist/index.d.ts +2 -1
  45. package/dist/index.js +6 -0
  46. package/dist/list-option.d.ts +1 -0
  47. package/dist/menus.js +1 -1
  48. package/dist/positioning.d.ts +2 -0
  49. package/dist/row-resize.d.ts +11 -0
  50. package/dist/row-resize.js +7 -1
  51. package/dist/scheduler-ical.d.ts +1 -0
  52. package/dist/scheduler-model.d.ts +1 -0
  53. package/dist/selection.js +9 -0
  54. package/dist/spreadsheet.d.ts +1 -1
  55. package/dist/spreadsheet.js +1 -1
  56. package/dist/summaries.js +22 -0
  57. package/dist/svgrid-wrapper.types.d.ts +5 -0
  58. package/dist/toast-store.svelte.d.ts +4 -0
  59. package/dist/validate.d.ts +50 -0
  60. package/dist/validate.js +187 -0
  61. package/package.json +4 -1
  62. package/src/GridMenus.svelte +17 -12
  63. package/src/SvGrid.controller.svelte.ts +223 -76
  64. package/src/SvGrid.css +1 -1
  65. package/src/SvGrid.svelte +112 -57
  66. package/src/SvGrid.types.ts +191 -1
  67. package/src/ai.ts +28 -0
  68. package/src/cell-formatting.ts +2 -0
  69. package/src/chart-export.ts +1 -0
  70. package/src/chart.ts +31 -5
  71. package/src/column-groups.ts +1 -1
  72. package/src/column-resize.test.ts +381 -0
  73. package/src/column-resize.ts +227 -0
  74. package/src/columns.test.ts +0 -103
  75. package/src/columns.ts +0 -58
  76. package/src/core.aggregate.test.ts +134 -0
  77. package/src/core.filter.test.ts +156 -0
  78. package/src/core.grouping.test.ts +146 -0
  79. package/src/core.row-shape.test.ts +119 -0
  80. package/src/core.rowmodel-cache.test.ts +121 -0
  81. package/src/core.sort.test.ts +293 -0
  82. package/src/core.ts +723 -119
  83. package/src/createTree.svelte.ts +3 -0
  84. package/src/datetime/date-core.ts +2 -0
  85. package/src/datetime/date-restrict.ts +1 -0
  86. package/src/datetime/timezone.ts +1 -0
  87. package/src/dock-manager-model.ts +3 -0
  88. package/src/dock-model.ts +6 -0
  89. package/src/editor-contract.ts +1 -0
  90. package/src/filtering/excel-filters.ts +30 -0
  91. package/src/filtering/normalize-fast-path.test.ts +104 -0
  92. package/src/group-display.ts +1 -1
  93. package/src/index.ts +12 -1
  94. package/src/list-option.ts +1 -0
  95. package/src/menus.ts +1 -1
  96. package/src/positioning.ts +2 -0
  97. package/src/resize-props.test.ts +361 -0
  98. package/src/row-resize.test.ts +31 -0
  99. package/src/row-resize.ts +21 -3
  100. package/src/scheduler-ical.ts +1 -0
  101. package/src/scheduler-model.ts +1 -0
  102. package/src/selection.ts +9 -0
  103. package/src/spreadsheet.ts +1 -1
  104. package/src/summaries.ts +21 -0
  105. package/src/svgrid-wrapper.types.ts +5 -0
  106. package/src/svgrid.summaries.test.ts +217 -0
  107. package/src/toast-store.svelte.ts +4 -0
  108. package/src/validate.test.ts +207 -0
  109. package/src/validate.ts +269 -0
  110. package/dist/cdn/GridMenus-IHK_l7m6.js +0 -489
package/src/ai.ts CHANGED
@@ -48,6 +48,7 @@ type ExportFormat = 'xlsx' | 'xls' | 'pdf' | 'csv' | 'tsv' | 'html' | 'json' | '
48
48
  */
49
49
  export type AIProvider = (request: AIRequest) => Promise<string>
50
50
 
51
+ /** One call out to the model, as the grid builds it. Providers receive this. */
51
52
  export type AIRequest = {
52
53
  /** Full prompt the grid built for the model. Already includes column
53
54
  * schema and any sampled rows where applicable. */
@@ -66,6 +67,7 @@ export type AIRequest = {
66
67
  maxOutputTokens?: number
67
68
  }
68
69
 
70
+ /** Which helper produced a request - carried on {@link AIRequest} for routing and telemetry. */
69
71
  export type AITask = 'filter' | 'smart-fill' | 'summarize' | 'classify' | 'export' | 'anomaly' | 'chart'
70
72
 
71
73
  let provider: AIProvider | null = null
@@ -79,10 +81,12 @@ export function setAIProvider(p: AIProvider | null): void {
79
81
  provider = p
80
82
  }
81
83
 
84
+ /** The provider registered with `setAIProvider`, or null when none is. */
82
85
  export function getAIProvider(): AIProvider | null {
83
86
  return provider
84
87
  }
85
88
 
89
+ /** Whether an AI provider is registered. Gate AI affordances on this so the UI stays honest. */
86
90
  export function hasAIProvider(): boolean {
87
91
  return provider != null
88
92
  }
@@ -198,13 +202,16 @@ function schemaToPromptBlock(schema: ColumnSchemaEntry[]): string {
198
202
  // 1. Natural-language filter / sort
199
203
  // ---------------------------------------------------------------------------
200
204
 
205
+ /** One condition in a filter plan: a column, a comparison, and the value to match. */
201
206
  export type AIFilterClause = {
202
207
  field: string
203
208
  operator: 'contains' | 'equals' | 'startsWith' | 'greaterThan' | 'lessThan' | 'isBlank'
204
209
  value?: string
205
210
  }
211
+ /** One ordering clause in a filter plan. */
206
212
  export type AISortClause = { field: string; desc: boolean }
207
213
 
214
+ /** A natural-language query turned into filters and sorting, plus the model's reasoning. */
208
215
  export type AIFilterResult = {
209
216
  filters: AIFilterClause[]
210
217
  sort: AISortClause[]
@@ -213,6 +220,7 @@ export type AIFilterResult = {
213
220
  rationale: string
214
221
  }
215
222
 
223
+ /** Options for `aiFilter` - preview the plan, or apply it straight to the grid. */
216
224
  export type AIFilterOptions = {
217
225
  /**
218
226
  * When true, the helper not only RETURNS the plan but also applies it
@@ -284,14 +292,17 @@ export async function aiFilter<
284
292
  // 2. Smart fill
285
293
  // ---------------------------------------------------------------------------
286
294
 
295
+ /** One worked example teaching smart-fill what to produce for a row. */
287
296
  export type AISmartFillExample = { input: Record<string, unknown>; output: unknown }
288
297
 
298
+ /** Proposed values for the blank cells of one column, each with a confidence score. */
289
299
  export type AISmartFillResult<TValue = unknown> = {
290
300
  field: string
291
301
  predictions: Array<{ rowIndex: number; value: TValue; confidence: number }>
292
302
  rationale: string
293
303
  }
294
304
 
305
+ /** Options for `aiSmartFill` - which column to fill, which rows, and the examples to learn from. */
295
306
  export type AISmartFillOptions = {
296
307
  /** Target column - the one whose values we want filled. */
297
308
  field: string
@@ -379,12 +390,14 @@ export async function aiSmartFill<
379
390
  // 3. Summarise
380
391
  // ---------------------------------------------------------------------------
381
392
 
393
+ /** What to summarise: one row, the selection, a group, or the whole set. */
382
394
  export type AISummarizeTarget =
383
395
  | { kind: 'row'; rowIndex: number }
384
396
  | { kind: 'all' }
385
397
  | { kind: 'selection'; rowIndices: number[] }
386
398
  | { kind: 'group'; field: string; value: unknown }
387
399
 
400
+ /** A generated summary: prose, bullets, and the columns the model leaned on. */
388
401
  export type AISummary = {
389
402
  text: string
390
403
  bullets: string[]
@@ -393,6 +406,7 @@ export type AISummary = {
393
406
  highlightedFields: string[]
394
407
  }
395
408
 
409
+ /** Options for `aiSummarize` - the target, and optionally the question to answer. */
396
410
  export type AISummarizeOptions = {
397
411
  target: AISummarizeTarget
398
412
  /** Optional question the user is trying to answer. Helps the model
@@ -468,6 +482,7 @@ export async function aiSummarize<
468
482
  // 4. Classify (free-text -> bucketed value)
469
483
  // ---------------------------------------------------------------------------
470
484
 
485
+ /** Options for `aiClassify` - the column to label and the categories to choose from. */
471
486
  export type AIClassifyOptions = {
472
487
  /** Column whose free-text we're classifying. */
473
488
  inputField: string
@@ -482,6 +497,7 @@ export type AIClassifyOptions = {
482
497
  signal?: AbortSignal
483
498
  }
484
499
 
500
+ /** Proposed category labels per row, with the model's reasoning. */
485
501
  export type AIClassifyResult = {
486
502
  inputField: string
487
503
  outputField: string
@@ -545,6 +561,7 @@ export async function aiClassify<
545
561
 
546
562
  const EXPORT_FORMATS: ExportFormat[] = ['xlsx', 'xls', 'pdf', 'csv', 'tsv', 'html', 'json', 'xml', 'md']
547
563
 
564
+ /** An export the model derived from a request: format, columns, and scope. */
548
565
  export type AIExportPlan = {
549
566
  format: ExportFormat
550
567
  filters: AIFilterClause[]
@@ -554,6 +571,7 @@ export type AIExportPlan = {
554
571
  rationale: string
555
572
  }
556
573
 
574
+ /** Options for `aiExport` - preview the plan, or run the export it describes. */
557
575
  export type AIExportOptions = {
558
576
  /**
559
577
  * Also apply the filter / sort / grouping to the grid (mutating the view) so
@@ -719,6 +737,7 @@ function applyPlanToRows<TData extends RowData>(
719
737
  // 6. Find anomalies
720
738
  // ---------------------------------------------------------------------------
721
739
 
740
+ /** One flagged value, with why it stands out and how strongly. */
722
741
  export type AIAnomaly = {
723
742
  /** Index into the SCANNED rows (target order), when the model pins one row. */
724
743
  rowIndex?: number
@@ -728,11 +747,13 @@ export type AIAnomaly = {
728
747
  severity: 'low' | 'medium' | 'high'
729
748
  }
730
749
 
750
+ /** Everything an anomaly scan flagged across the rows it looked at. */
731
751
  export type AIAnomalyResult = {
732
752
  anomalies: AIAnomaly[]
733
753
  summary: string
734
754
  }
735
755
 
756
+ /** Options for `aiFindAnomalies` - which rows and columns to scan. */
736
757
  export type AIAnomalyOptions = {
737
758
  /** Which rows to scan. Defaults to the whole dataset. */
738
759
  target?: AISummarizeTarget
@@ -814,8 +835,10 @@ export async function aiFindAnomalies<
814
835
  // 7. Natural-language chart ("chart this")
815
836
  // ---------------------------------------------------------------------------
816
837
 
838
+ /** Chart shapes the model may choose from when planning a visualisation. */
817
839
  export type AIChartType = 'bar' | 'line' | 'area' | 'pie'
818
840
 
841
+ /** A chart the model proposed: its type, and the fields to plot. */
819
842
  export type AIChartPlan = {
820
843
  type: AIChartType
821
844
  /** Group-by (category-axis) column field, or null. */
@@ -832,6 +855,7 @@ export type AIChartPlan = {
832
855
  rationale: string
833
856
  }
834
857
 
858
+ /** Options for `aiChart` - preview the plan, or render it into the grid. */
835
859
  export type AIChartOptions = {
836
860
  /** Apply the plan to the grid's chart panel (open + configure). Default false. */
837
861
  apply?: boolean
@@ -951,6 +975,10 @@ export function enableAiCharting<
951
975
  })
952
976
  }
953
977
 
978
+ /**
979
+ * Remove the natural-language chart handler, hiding the AI button in the chart
980
+ * panel. The inverse of `enableAiCharting`; safe to call when none was set.
981
+ */
954
982
  export function disableAiCharting<
955
983
  TFeatures extends TableFeatures,
956
984
  TData extends RowData,
@@ -106,6 +106,8 @@ function getNumberFormatter(
106
106
 
107
107
  /** Cache of `Intl.DateTimeFormat` by `(locale, options)` signature. */
108
108
  const dateFormatterCache = new Map<string, Intl.DateTimeFormat>()
109
+ /** A cached `Intl.DateTimeFormat` for the locale and options given. Cached because
110
+ * constructing one per cell is the dominant cost when formatting a date column. */
109
111
  export function getDateFormatter(
110
112
  locales: string | readonly string[] | undefined,
111
113
  options: Intl.DateTimeFormatOptions,
@@ -21,6 +21,7 @@ function cssVar(el: Element, name: string, fallback: string): string {
21
21
  return v || fallback
22
22
  }
23
23
 
24
+ /** Options for exporting a chart: the filename, and the background to paint behind it. */
24
25
  export type ChartExportOptions = {
25
26
  /** Background color of the exported image. Default: the grid background. */
26
27
  background?: string
package/src/chart.ts CHANGED
@@ -36,9 +36,8 @@ export type SeriesOverlay = 'linear' | `sma:${number}` | `ema:${number}`
36
36
  /** A texture fill applied in addition to (and on top of) the series color.
37
37
  * Helps colorblind readers distinguish series at a glance. */
38
38
  export type SeriesPattern = 'solid' | 'stripe' | 'crosshatch' | 'dots' | 'diagonal'
39
- /** Cycle used when `ChartSpec.patternFallback` is true and a series has no
40
- * explicit `pattern` set. Skips `'solid'` so every series gets a texture. */
41
39
 
40
+ /** One plotted series: its label, its values (one per category), and how to draw it. */
42
41
  export type ChartSeries = {
43
42
  label: string
44
43
  values: number[]
@@ -95,6 +94,12 @@ export type ChartReferenceLine = {
95
94
  dashed?: boolean
96
95
  }
97
96
 
97
+ /**
98
+ * What to plot - the input you build and hand to a chart. Categories are the
99
+ * x-axis labels and every series supplies one value per category.
100
+ *
101
+ * {@link buildChart} turns this into a {@link ChartGeometry} for rendering.
102
+ */
98
103
  export type ChartSpec = {
99
104
  /** Default type for series that don't set their own `type`. */
100
105
  type: ChartType
@@ -326,6 +331,7 @@ export type ChartHeatmapCell = {
326
331
  colLabel: string
327
332
  }
328
333
 
334
+ /** A computed bar rectangle in SVG coordinates. Output of {@link buildChart}, not an input. */
329
335
  export type ChartBar = {
330
336
  x: number
331
337
  y: number
@@ -338,6 +344,7 @@ export type ChartBar = {
338
344
  series: string
339
345
  value: number
340
346
  }
347
+ /** One computed point on a line, with whether the series has a value there. */
341
348
  export type ChartLinePoint = {
342
349
  x: number
343
350
  y: number
@@ -346,6 +353,7 @@ export type ChartLinePoint = {
346
353
  /** False for null / NaN values - the line breaks (gap), no dot is drawn. */
347
354
  defined: boolean
348
355
  }
356
+ /** A computed line series: its points and the path drawn through them. */
349
357
  export type ChartLine = {
350
358
  path: string
351
359
  areaPath: string
@@ -356,6 +364,7 @@ export type ChartLine = {
356
364
  * series, when both arrays are supplied. Empty otherwise. */
357
365
  bandPath?: string
358
366
  }
367
+ /** A computed pie slice, as an SVG arc plus its label placement. */
359
368
  export type ChartPieSlice = {
360
369
  path: string
361
370
  color: string
@@ -366,12 +375,17 @@ export type ChartPieSlice = {
366
375
  cx: number
367
376
  cy: number
368
377
  }
378
+ /** A value-axis tick: the number, where it sits vertically, and its label. */
369
379
  export type ChartAxisTick = { value: number; y: number; label: string }
380
+ /** A category-axis tick: the label and its horizontal position. */
370
381
  export type ChartCategoryTick = { label: string; x: number }
382
+ /** One legend entry, paired with the series colour it stands for. */
371
383
  export type ChartLegendItem = { label: string; color: string }
384
+ /** A computed reference line (target, average, threshold) at its plotted height. */
372
385
  export type ChartRefLineGeo = { y: number; label: string; color: string; dashed: boolean }
373
386
  /** A vertical reference line (horizontal bar charts) positioned by `x`. */
374
387
  export type ChartRefLineGeoV = { x: number; label: string; color: string; dashed: boolean }
388
+ /** A computed scatter point in SVG coordinates. */
375
389
  export type ChartScatterDot = {
376
390
  cx: number
377
391
  cy: number
@@ -383,6 +397,11 @@ export type ChartScatterDot = {
383
397
  y: number
384
398
  }
385
399
 
400
+ /**
401
+ * Everything needed to render a chart: the plot rectangle plus every mark
402
+ * already positioned in SVG coordinates. Produced by {@link buildChart} from a
403
+ * {@link ChartSpec}, so a renderer does no maths of its own.
404
+ */
386
405
  export type ChartGeometry = {
387
406
  type: ChartType
388
407
  width: number
@@ -455,6 +474,7 @@ export type ChartGeometry = {
455
474
  sankeyLinks: ChartSankeyLink[]
456
475
  }
457
476
 
477
+ /** Series colours used when a {@link ChartSeries} sets none, in order. */
458
478
  export const DEFAULT_PALETTE = [
459
479
  '#2563eb',
460
480
  '#16a34a',
@@ -480,6 +500,7 @@ function niceNum(range: number, roundIt: boolean): number {
480
500
  return nf * Math.pow(10, exp)
481
501
  }
482
502
 
503
+ /** An axis range rounded to human-friendly bounds and tick spacing. */
483
504
  export type NiceScale = { min: number; max: number; step: number; ticks: number[] }
484
505
 
485
506
  // ---- Color helpers for heatmap / pattern fills ----------------------
@@ -574,9 +595,6 @@ function project(value: number, min: number, max: number, isLog: boolean): numbe
574
595
 
575
596
  // ---- Overlay math: trendline + moving averages -----------------------
576
597
 
577
- /** Ordinary least-squares regression on (i, values[i]) pairs (i = x index).
578
- * Returns the fitted value at each x index, or NaN where the source value
579
- * was non-finite. */
580
598
  /** Build an SVG path from a list of (x,y) pairs, optionally smoothed via
581
599
  * monotone cubic interpolation (preserves local extrema - no overshoots).
582
600
  * Breaks the path at `defined === false` gaps. */
@@ -655,6 +673,9 @@ function monotoneCubicPath(pts: Array<{ x: number; y: number }>): string {
655
673
  return path
656
674
  }
657
675
 
676
+ /** Ordinary least-squares regression on (i, values[i]) pairs (i = x index).
677
+ * Returns the fitted value at each x index, or NaN where the source value
678
+ * was non-finite. */
658
679
  export function linearTrend(values: number[]): number[] {
659
680
  let n = 0, sumX = 0, sumY = 0, sumXX = 0, sumXY = 0
660
681
  for (let i = 0; i < values.length; i += 1) {
@@ -835,6 +856,11 @@ function axisDomain(
835
856
  return isLog ? niceLogScale(dMin, dMax) : niceScale(dMin, dMax)
836
857
  }
837
858
 
859
+ /**
860
+ * Lay out a {@link ChartSpec} into renderable {@link ChartGeometry} - scales,
861
+ * ticks, and the position of every bar, line, slice and dot. Pure: no DOM, so
862
+ * it runs during SSR and can be unit-tested directly.
863
+ */
838
864
  export function buildChart(spec: ChartSpec, theme: 'light' | 'dark' = 'light'): ChartGeometry {
839
865
  const width = spec.width ?? 520
840
866
  const height = spec.height ?? 300
@@ -1,4 +1,4 @@
1
- // Collapsible column groups (AG-Grid `columnGroupShow`). A column group can
1
+ // Collapsible column groups (a per-column `columnGroupShow` flag). A column group can
2
2
  // carry a collapse toggle: its child columns tagged `columnGroupShow: 'open'`
3
3
  // show only when the group is expanded, `'closed'` show only when collapsed,
4
4
  // and untagged children always show.