@evotecit/canopyx 0.3.16 → 0.3.20

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 (150) hide show
  1. package/CanopyX.Html/Assets/canopyx-board.css +50 -0
  2. package/CanopyX.Html/Assets/canopyx-board.js +39 -0
  3. package/CanopyX.Html/Assets/canopyx-buckets.js +15 -0
  4. package/CanopyX.Html/Assets/canopyx-calculations.css +7 -0
  5. package/CanopyX.Html/Assets/canopyx-calculations.js +52 -0
  6. package/CanopyX.Html/Assets/canopyx-calendar-edit.js +3 -3
  7. package/CanopyX.Html/Assets/canopyx-calendar.css +74 -80
  8. package/CanopyX.Html/Assets/canopyx-calendar.js +26 -31
  9. package/CanopyX.Html/Assets/canopyx-cell-range.css +4 -4
  10. package/CanopyX.Html/Assets/canopyx-cell-range.js +16 -14
  11. package/CanopyX.Html/Assets/canopyx-changes.css +61 -79
  12. package/CanopyX.Html/Assets/canopyx-changes.js +18 -15
  13. package/CanopyX.Html/Assets/canopyx-column-groups.css +5 -1
  14. package/CanopyX.Html/Assets/canopyx-column-groups.js +15 -9
  15. package/CanopyX.Html/Assets/canopyx-compare.css +37 -0
  16. package/CanopyX.Html/Assets/canopyx-compare.js +12 -0
  17. package/CanopyX.Html/Assets/canopyx-data.js +3 -3
  18. package/CanopyX.Html/Assets/canopyx-detail-rows.css +4 -4
  19. package/CanopyX.Html/Assets/canopyx-detail-rows.js +1 -1
  20. package/CanopyX.Html/Assets/canopyx-editing.css +5 -5
  21. package/CanopyX.Html/Assets/canopyx-editing.js +2 -2
  22. package/CanopyX.Html/Assets/canopyx-enhance.js +5 -5
  23. package/CanopyX.Html/Assets/canopyx-export.js +54 -13
  24. package/CanopyX.Html/Assets/canopyx-facets.css +32 -22
  25. package/CanopyX.Html/Assets/canopyx-facets.js +19 -15
  26. package/CanopyX.Html/Assets/canopyx-filter-editor.css +75 -89
  27. package/CanopyX.Html/Assets/canopyx-filter-editor.js +20 -16
  28. package/CanopyX.Html/Assets/canopyx-flow-checks.css +3 -3
  29. package/CanopyX.Html/Assets/canopyx-flow-checks.js +1 -1
  30. package/CanopyX.Html/Assets/canopyx-flow-command.css +3 -3
  31. package/CanopyX.Html/Assets/canopyx-flow-command.js +1 -1
  32. package/CanopyX.Html/Assets/canopyx-flow-dialog.css +4 -4
  33. package/CanopyX.Html/Assets/canopyx-flow-dialog.js +1 -1
  34. package/CanopyX.Html/Assets/canopyx-flow-drafts.css +2 -2
  35. package/CanopyX.Html/Assets/canopyx-flow-drafts.js +1 -1
  36. package/CanopyX.Html/Assets/canopyx-flow-entry.css +142 -17
  37. package/CanopyX.Html/Assets/canopyx-flow-entry.js +5 -5
  38. package/CanopyX.Html/Assets/canopyx-flow-host.css +2 -2
  39. package/CanopyX.Html/Assets/canopyx-flow-host.js +1 -1
  40. package/CanopyX.Html/Assets/canopyx-flow-module.mjs +5 -5
  41. package/CanopyX.Html/Assets/canopyx-flow-pick.css +4 -4
  42. package/CanopyX.Html/Assets/canopyx-flow-pick.js +1 -1
  43. package/CanopyX.Html/Assets/canopyx-flow-preview.css +1 -1
  44. package/CanopyX.Html/Assets/canopyx-flow-preview.js +1 -1
  45. package/CanopyX.Html/Assets/canopyx-flow-records.css +2 -2
  46. package/CanopyX.Html/Assets/canopyx-flow-records.js +1 -1
  47. package/CanopyX.Html/Assets/canopyx-flow-tasks.css +4 -4
  48. package/CanopyX.Html/Assets/canopyx-flow-tasks.js +1 -1
  49. package/CanopyX.Html/Assets/canopyx-flow.css +41 -41
  50. package/CanopyX.Html/Assets/canopyx-flow.js +1 -1
  51. package/CanopyX.Html/Assets/canopyx-format-editor.css +9 -9
  52. package/CanopyX.Html/Assets/canopyx-format-editor.js +2 -2
  53. package/CanopyX.Html/Assets/canopyx-formatting.css +13 -13
  54. package/CanopyX.Html/Assets/canopyx-formatting.js +12 -11
  55. package/CanopyX.Html/Assets/canopyx-forms.css +3 -3
  56. package/CanopyX.Html/Assets/canopyx-forms.js +1 -1
  57. package/CanopyX.Html/Assets/canopyx-grid-module.mjs +220 -155
  58. package/CanopyX.Html/Assets/canopyx-grid-options.css +8 -8
  59. package/CanopyX.Html/Assets/canopyx-grid-options.js +9 -2
  60. package/CanopyX.Html/Assets/canopyx-grid.css +285 -150
  61. package/CanopyX.Html/Assets/canopyx-grid.js +220 -155
  62. package/CanopyX.Html/Assets/canopyx-grouping.css +23 -16
  63. package/CanopyX.Html/Assets/canopyx-grouping.js +24 -17
  64. package/CanopyX.Html/Assets/canopyx-highlight.css +10 -10
  65. package/CanopyX.Html/Assets/canopyx-highlight.js +1 -1
  66. package/CanopyX.Html/Assets/canopyx-interactive.css +215 -91
  67. package/CanopyX.Html/Assets/canopyx-interactive.js +47 -52
  68. package/CanopyX.Html/Assets/canopyx-labels-de.js +177 -9
  69. package/CanopyX.Html/Assets/canopyx-labels-es.js +177 -9
  70. package/CanopyX.Html/Assets/canopyx-labels-fr.js +176 -8
  71. package/CanopyX.Html/Assets/canopyx-labels-it.js +176 -8
  72. package/CanopyX.Html/Assets/canopyx-labels-pl.js +176 -8
  73. package/CanopyX.Html/Assets/canopyx-layouts.css +49 -21
  74. package/CanopyX.Html/Assets/canopyx-layouts.js +36 -14
  75. package/CanopyX.Html/Assets/canopyx-link.css +3 -3
  76. package/CanopyX.Html/Assets/canopyx-link.js +4 -4
  77. package/CanopyX.Html/Assets/canopyx-links.js +2 -2
  78. package/CanopyX.Html/Assets/canopyx-live.css +3 -5
  79. package/CanopyX.Html/Assets/canopyx-live.js +3 -3
  80. package/CanopyX.Html/Assets/canopyx-matrix.css +32 -39
  81. package/CanopyX.Html/Assets/canopyx-matrix.js +11 -11
  82. package/CanopyX.Html/Assets/canopyx-module.mjs +47 -52
  83. package/CanopyX.Html/Assets/canopyx-office-export.js +2936 -0
  84. package/CanopyX.Html/Assets/canopyx-pager.css +1 -1
  85. package/CanopyX.Html/Assets/canopyx-pager.js +1 -1
  86. package/CanopyX.Html/Assets/canopyx-path.css +45 -0
  87. package/CanopyX.Html/Assets/canopyx-path.js +28 -0
  88. package/CanopyX.Html/Assets/canopyx-pivot.css +75 -0
  89. package/CanopyX.Html/Assets/canopyx-pivot.js +72 -0
  90. package/CanopyX.Html/Assets/canopyx-plan.css +63 -0
  91. package/CanopyX.Html/Assets/canopyx-plan.js +71 -0
  92. package/CanopyX.Html/Assets/canopyx-presenters.js +2 -2
  93. package/CanopyX.Html/Assets/canopyx-record-panel.css +51 -45
  94. package/CanopyX.Html/Assets/canopyx-record-panel.js +30 -22
  95. package/CanopyX.Html/Assets/canopyx-reporting-module.mjs +262 -197
  96. package/CanopyX.Html/Assets/canopyx-reporting.css +300 -164
  97. package/CanopyX.Html/Assets/canopyx-reporting.js +262 -197
  98. package/CanopyX.Html/Assets/canopyx-stack.css +35 -0
  99. package/CanopyX.Html/Assets/canopyx-stack.js +24 -0
  100. package/CanopyX.Html/Assets/canopyx-time-slider.css +18 -0
  101. package/CanopyX.Html/Assets/canopyx-time-slider.js +27 -0
  102. package/CanopyX.Html/Assets/canopyx-timeline.css +19 -19
  103. package/CanopyX.Html/Assets/canopyx-timeline.js +6 -5
  104. package/CanopyX.Html/Assets/canopyx-tree-tools.css +47 -46
  105. package/CanopyX.Html/Assets/canopyx-tree-tools.js +15 -12
  106. package/CanopyX.Html/Assets/canopyx-ui-menu.css +41 -0
  107. package/CanopyX.Html/Assets/canopyx-ui-menu.js +64 -0
  108. package/CanopyX.Html/Assets/canopyx-ui-navigation.css +73 -0
  109. package/CanopyX.Html/Assets/canopyx-ui-navigation.js +39 -0
  110. package/CanopyX.Html/Assets/canopyx-ui-overlays.css +79 -0
  111. package/CanopyX.Html/Assets/canopyx-ui-overlays.js +45 -0
  112. package/CanopyX.Html/Assets/canopyx-ui-picker.css +12 -0
  113. package/CanopyX.Html/Assets/canopyx-ui-picker.js +6 -0
  114. package/CanopyX.Html/Assets/canopyx-ui-stepper.css +174 -0
  115. package/CanopyX.Html/Assets/canopyx-ui-stepper.js +48 -0
  116. package/CanopyX.Html/Assets/canopyx-ui-tabs.css +153 -0
  117. package/CanopyX.Html/Assets/canopyx-ui-tabs.js +47 -0
  118. package/CanopyX.Html/Assets/canopyx-values.css +5 -0
  119. package/CanopyX.Html/Assets/canopyx-values.js +13 -0
  120. package/CanopyX.Html/Assets/canopyx-view-intents.css +12 -0
  121. package/CanopyX.Html/Assets/canopyx-view-intents.js +56 -0
  122. package/CanopyX.Html/Assets/canopyx.css +212 -85
  123. package/CanopyX.Html/Assets/canopyx.js +38 -26
  124. package/JavaScript/board.d.ts +30 -0
  125. package/JavaScript/changes.d.ts +4 -1
  126. package/JavaScript/column-groups.d.ts +24 -4
  127. package/JavaScript/facets.d.ts +5 -3
  128. package/JavaScript/grid.d.ts +161 -17
  129. package/JavaScript/hosts.d.ts +16 -1
  130. package/JavaScript/index.d.ts +4 -2
  131. package/JavaScript/locales/de.mjs +177 -9
  132. package/JavaScript/locales/es.mjs +177 -9
  133. package/JavaScript/locales/fr.mjs +176 -8
  134. package/JavaScript/locales/it.mjs +176 -8
  135. package/JavaScript/locales/pl.mjs +176 -8
  136. package/JavaScript/matrix.d.ts +4 -1
  137. package/JavaScript/path.d.ts +33 -0
  138. package/JavaScript/pivot.d.ts +135 -0
  139. package/JavaScript/plan.d.ts +23 -0
  140. package/JavaScript/protocol.d.ts +18 -3
  141. package/JavaScript/records.d.ts +4 -0
  142. package/JavaScript/stack.d.ts +28 -0
  143. package/JavaScript/time-slider.d.ts +58 -0
  144. package/JavaScript/ui.d.ts +261 -0
  145. package/JavaScript/view-intents.d.ts +45 -0
  146. package/README.md +76 -187
  147. package/README.nuget.md +63 -87
  148. package/ThirdParty/OfficeIMO/LICENSE +21 -0
  149. package/ThirdParty/OfficeIMO/README.md +13 -0
  150. package/package.json +76 -3
@@ -1,4 +1,15 @@
1
+ import type { GridPathDefinition } from "./path.js";
2
+ export * from "./path.js";
3
+ import type { GridStackDefinition } from "./stack.js";
4
+ export * from "./stack.js";
5
+ export * from "./time-slider.js";
1
6
  import CanopyX from "./index.js";
7
+ import type { GridBoardDefinition, GridBoardMove, GridBoardState } from "./board.js";
8
+ export * from "./board.js";
9
+ import type { GridPlanDefinition, GridPlanOptions, GridPlanChangeProposal } from "./plan.js";
10
+ export * from "./plan.js";
11
+ import type { GridViewIntentApi } from "./view-intents.js";
12
+ export type { GridViewIntent, GridViewIntentPreview, GridViewIntentApi } from "./view-intents.js";
2
13
  import type { TreeGrid } from "./index.js";
3
14
  import type { CanopyColumn, CanopyLabels, Cell, CellValue, SortDirection, TimeZone, SearchHighlightOptions, LayoutOptions, LayoutState, ViewModeMethods } from "./protocol.js";
4
15
  import type { HostOptions, ExportFormat, ExportFormatOptions, ExportFormatResult, ExportMenuOptions, LinkedView } from "./hosts.js";
@@ -8,12 +19,13 @@ import type { GridEditorDefinition, GridValidation, GridEditingSettings, GridEdi
8
19
  import type { RecordPanelDefinition, RecordPanelOptions, RecordLoader, RecordSectionRenderer, RecordAction, RecordOpenAll, OpenRecordOptions } from "./records.js";
9
20
  export * from "./records.js";
10
21
  export * from "./index.js";
22
+ export * from "./ui.js";
11
23
  export * from "./enhance.js";
12
24
  import type { enhance, grid } from "./enhance.js";
13
25
  export * from "./editing.js";
14
26
  import type { GridExportFormat, GridFormatOptions, GridFormatRule } from "./formatting.js";
15
27
  export * from "./formatting.js";
16
- import type { GridColumnGroup, GridColumnGroupApi } from "./column-groups.js";
28
+ import type { GridColumnGroup, GridColumnBandDefinition, GridColumnGroupApi } from "./column-groups.js";
17
29
  import type { GridRangeSelection, GridClipboardSettings, GridCellRange, GridPasteEvent, GridCellRangeApi } from "./cell-ranges.js";
18
30
  export * from "./column-groups.js";
19
31
  export * from "./cell-ranges.js";
@@ -23,6 +35,8 @@ import type { GridCalendarDefinition, GridCalendarOptions, GridCalendarApi, Grid
23
35
  export * from "./facets.js";
24
36
  export * from "./calendar.js";
25
37
  export * from "./live.js";
38
+ import type { GridPivotApi, GridPivotDefinition, GridPivotState, GridPivotQuery, GridPivotAcceptedResult, GridPivotExportAxisPresentation, GridPivotExportDescriptor } from "./pivot.js";
39
+ export * from "./pivot.js";
26
40
 
27
41
  /** A stable record identity and typed cells. Flat records have no tree fields. */
28
42
  export interface GridRow { id: string; cells: Record<string, Cell>; tone?: string; className?: string;
@@ -44,6 +58,9 @@ export type GridHighlightRule = GridBuiltinFilter & { target?: "row" | "cell" }
44
58
  export interface GridExportCell {
45
59
  readonly value: CellValue;
46
60
  readonly text: string;
61
+ /** Pivot-table captures retain numeric display modes and native number formats. */
62
+ readonly mode?: GridShowAs;
63
+ readonly numberFormat?: string;
47
64
  readonly tone?: string;
48
65
  readonly link?: { readonly target: string; readonly tooltip?: string };
49
66
  /** The cell's conditional formatting, present when the grid has rules that format it. CSV reads only value and text. */
@@ -52,7 +69,7 @@ export interface GridExportCell {
52
69
  readonly diagnostics?: readonly string[];
53
70
  }
54
71
  /** An immutable record projected onto the declared export columns. Group headings and summaries are not records. */
55
- export interface GridExportRow {
72
+ export interface GridExportRow extends Partial<GridPivotExportAxisPresentation> {
56
73
  readonly id: string; readonly cells: Readonly<Record<string, GridExportCell>>;
57
74
  readonly tone?: string; readonly diagnostics?: readonly string[];
58
75
  /** The record's row formatting, present when a row rule matched it. */
@@ -61,11 +78,15 @@ export interface GridExportRow {
61
78
  readonly detail?: Extract<GridRowDetail, { type: "table" | "properties" | "html" }>;
62
79
  }
63
80
  /** Captured column intent. Hosts map semantic tones and CSS pixel widths into their output format. */
64
- export interface GridExportColumn {
81
+ export interface GridExportColumn extends Partial<GridPivotExportAxisPresentation> {
65
82
  readonly id: string; readonly title: string; readonly kind: "text" | "number" | "datetime";
83
+ /** Present on numeric pivot-table columns. */
84
+ readonly aggregate?: string;
66
85
  /** Reporting runtime only. */
67
86
  readonly width?: { readonly unit: "css-px"; readonly preferred: number; readonly minimum: number; readonly maximum?: number };
68
87
  readonly wrap?: boolean; readonly alignment?: "left" | "right";
88
+ /** The effective pin in the captured layout; null when the column is unpinned. */
89
+ readonly pinned?: "left" | "right" | null;
69
90
  readonly presenter?: GridPresenter;
70
91
  /** The column number format that produced the display text. */
71
92
  readonly format?: GridNumberFormat;
@@ -135,7 +156,19 @@ export type GridColumn<Row extends GridRow = GridRow> = Omit<CanopyColumn, "id"
135
156
  alwaysVisible?: boolean;
136
157
  /** Hover tooltip: "auto" shows a cell's full value while it is cut off; a declared column id shows that column's text. */
137
158
  tooltip?: string;
138
- };
159
+ } & (
160
+ | { readonly calculation?: never }
161
+ /** A bounded expression over raw row values. Calculated cells are read-only; hosted values come from the server. */
162
+ | { readonly calculation: string; editable?: false }
163
+ );
164
+ /** One reader-editable calculation definition; all authored calculation IDs must remain in the submitted set. */
165
+ export interface GridCalculatedColumnDefinition {
166
+ readonly id: string;
167
+ readonly title: string;
168
+ readonly kind: "text" | "number" | "datetime";
169
+ /** One to 2048 UTF-16 code units, parsed as the bounded calculation grammar. */
170
+ readonly expression: string;
171
+ }
139
172
  export type GridColumnPriority = "essential" | "normal" | "optional" | number;
140
173
  export interface GridSort { readonly column: string; readonly direction: SortDirection; }
141
174
  /** Code-unit collation; natural digit runs never convert to floating-point numbers. */
@@ -154,6 +187,7 @@ export type GridPresenter =
154
187
  | { readonly kind: "longText"; readonly mono?: boolean }
155
188
  | { readonly kind: "enum" | "state"; readonly tones?: Readonly<Record<string,string>>; /** Tones shown as plain text instead of a chip or dot. */ readonly quietTones?: readonly string[]; /** Quiet values muted (default) or in the normal text colour. */ readonly quietStyle?: "muted" | "plain" }
156
189
  | { readonly kind: "change"; readonly deltaColumn: string; readonly higherIsGood?: boolean }
190
+ | { readonly kind: "change"; readonly beforeAfter: true }
157
191
  | { readonly kind: "statusStrip" | "missing" }
158
192
  | ({ readonly kind: "sparklineBars" | "sparklineLine" } & GridHistoryPresentation)
159
193
  | { readonly kind: "identifier"; readonly secondaryColumn?: string; readonly mono?: boolean }
@@ -186,6 +220,10 @@ export interface GridPager {
186
220
  }
187
221
  /** Include the reporting entry point when this optional capability set is present. */
188
222
  export interface GridReporting {
223
+ /** Initial full-query pivot; requires offset navigation and declared aggregates. */
224
+ readonly pivot?: GridPivotDefinition;
225
+ /** Readers can configure pivots over declared sortable/filterable fields and aggregates. */
226
+ readonly pivotable?: boolean;
189
227
  /** Fixed first ordering key. Group headings and collapse never change record paging/counts/exports. */
190
228
  readonly grouping?: GridSort & { readonly headerTemplate?: string };
191
229
  /** Initial runtime grouping levels, outermost first (at most four). Not combined with grouping. */
@@ -271,14 +309,14 @@ export type GridAction<Q extends AcceptedGridQuery = GridQuery> =
271
309
  /** render fills container on the entry's first open (and again after a render that threw); close() closes the menu and
272
310
  * focuses its button; signal aborts when the grid is destroyed. */
273
311
  | { label: string; render: (container: HTMLElement, context: { close(): void; signal: AbortSignal }) => void; run?: never };
274
- export type GridBuiltinFilter = {
312
+ export type GridBuiltinFilter = ({
275
313
  readonly column: string;
276
314
  readonly operator: "eq" | "ne" | "contains" | "startsWith" | "in" | "gt" | "ge" | "lt" | "le";
277
315
  readonly values: readonly Exclude<CellValue, null>[];
278
- } | { readonly column: string; readonly operator: "isNull" | "isNotNull"; readonly values: readonly []; };
316
+ } | { readonly column: string; readonly operator: "isNull" | "isNotNull"; readonly values: readonly []; }) & { readonly bucket?: GridBucket };
279
317
 
280
318
  /** A registered custom operator uses one typed, non-null operand. */
281
- export type GridFilter = GridBuiltinFilter | { readonly column: string; readonly operator: string & {}; readonly values: readonly Exclude<CellValue, null>[] };
319
+ export type GridFilter = GridBuiltinFilter | { readonly column: string; readonly operator: string & {}; readonly values: readonly Exclude<CellValue, null>[]; readonly bucket?: never };
282
320
 
283
321
  /** A nonempty nested expression: at most eight levels, 64 groups and 64 total predicates including flat filters. */
284
322
  export interface GridFilterGroup {
@@ -287,6 +325,16 @@ export interface GridFilterGroup {
287
325
  readonly groups: readonly GridFilterGroup[];
288
326
  }
289
327
 
328
+ /** A raw or bucketed field in an exact correlated tuple. */
329
+ export interface GridTupleColumn { readonly column: string; readonly bucket?: GridBucket; }
330
+ /** One to six fields and one to 200 equally wide tuples. Strings are exact; null is an explicit missing value. */
331
+ export interface GridTupleFilter {
332
+ readonly columns: readonly GridTupleColumn[];
333
+ readonly values: readonly (readonly CellValue[])[];
334
+ /** Complements membership, including rows containing null. Defaults to false. */
335
+ readonly exclude?: boolean;
336
+ }
337
+
290
338
  /** A frozen accepted query. Sorting/filtering cover the entire source before the requested window. */
291
339
  export interface GridQuery {
292
340
  readonly protocol: "canopyx/2";
@@ -297,11 +345,13 @@ export interface GridQuery {
297
345
  readonly limit: number;
298
346
  readonly search: string;
299
347
  /** Absent preserves substring matching; words matches all words/quoted phrases across searchable cells. */
300
- readonly searchMode?: "substring" | "words";
348
+ readonly searchMode?: "substring" | "words" | "regex";
301
349
  readonly sort: readonly GridSort[];
302
350
  readonly filters: readonly GridFilter[];
303
351
  /** Combined with search and flat filters using AND. */
304
352
  readonly filterGroup?: GridFilterGroup;
353
+ /** At most eight atomic predicates, AND-combined with the other query criteria. Empty input is omitted. */
354
+ readonly tupleFilters?: readonly GridTupleFilter[];
305
355
  /** Runtime grouping levels (reporting groupBy/groupable definitions); omitted input uses the declared levels, [] ungroups. */
306
356
  readonly groupBy?: readonly GridGroupLevel[];
307
357
  }
@@ -314,7 +364,21 @@ export type AcceptedGridQuery = GridQuery | GridCursorQuery;
314
364
  export type GridQueryInput<Q extends AcceptedGridQuery = GridQuery> = Partial<Q>;
315
365
  type GridCount<Q extends AcceptedGridQuery> = Q extends GridCursorQuery ? number | null : number;
316
366
 
367
+ /** Complete summary counts remain stable when the displayed comparison is filtered. */
368
+ export interface DatasetCompare {
369
+ readonly statusColumn: string;
370
+ readonly counts: Readonly<{ added: number; removed: number; changed: number; unchanged: number }>;
371
+ /** Changed matched-cell counts by declared column, excluding added and removed rows. */
372
+ readonly columns: Readonly<Record<string, number>>;
373
+ readonly onlyChanges: boolean;
374
+ }
317
375
  interface GridDefinition<Q extends AcceptedGridQuery = GridQuery, Row extends GridRow = GridRow> {
376
+ /** Enables the calculated-column editor and saved definitions. Only built-in inline sources support it. */
377
+ calculatedColumnsEditable?: boolean;
378
+ /** Complete keyed comparison metadata; loads the optional comparison controls. */
379
+ compare?: DatasetCompare;
380
+ /** Carry the optional validated view-intent preview part. No model or transport is provided. */
381
+ viewIntents?: boolean;
318
382
  protocol: "canopyx/2";
319
383
  type: "grid";
320
384
  id: string;
@@ -346,12 +410,20 @@ interface GridDefinition<Q extends AcceptedGridQuery = GridQuery, Row extends Gr
346
410
  rowAction?: "none" | "details" | "link";
347
411
  /** Draw a row tone as a bar at the row start (default false). */
348
412
  rowAccents?: boolean;
413
+ /** True opens the record drawer as a full-height sheet over a scrim at every width (default false: a side panel on wide screens, a sheet on narrow ones). */
414
+ recordDrawerModal?: boolean;
349
415
  /** How editable columns edit; the host's editing option overrides these. */
350
416
  editing?: GridEditingSettings;
351
417
  /** Marks search and column-filter matches in cells and the drawer, with a match count and next/previous (docs/search-highlight.md). */
352
418
  searchHighlight?: boolean | SearchHighlightOptions;
353
419
  /** The Layout menu: fit, scroll and cards, and the density (docs/layout-modes.md); layout.density starts the grid at that density. */
354
420
  layout?: LayoutOptions;
421
+ /** Literal templates keyed by card column slot. {columnId} inserts formatted text; markup is never parsed. */
422
+ cardTemplate?: Readonly<Record<string, string>>;
423
+ /** Follow page scrolling only when an auto-height grid fits all rows. Default false. */
424
+ stickyHeader?: boolean;
425
+ /** Permit searchMode: "regex" with the bounded condition grammar. Default false. */
426
+ allowRegexSearch?: boolean;
355
427
  /** Wire documents retain numeric rowHeight and enable measurement with this optional flag. */
356
428
  autoRowHeight?: boolean;
357
429
  /** Minimum and estimate for the rowHeight: "auto" API shorthand (20..64, default 28). */
@@ -369,6 +441,8 @@ interface GridDefinition<Q extends AcceptedGridQuery = GridQuery, Row extends Gr
369
441
  /** Pager settings of a paged view, read by the pager part (canopyx-pager.js); absent keeps the built-in pager. */
370
442
  pager?: GridPager;
371
443
  selection: "none" | "single" | "multiple";
444
+ /** Select rows on click instead of running the row action. Ctrl/Command toggles; Shift extends. Default false. */
445
+ selectOnClick?: boolean;
372
446
  /** Ordinal IDs are source positions in one snapshot; saved selection replay and keyed live updates are unavailable. Default stableKey. */
373
447
  rowIdentity?: "stableKey" | "ordinal";
374
448
  search: boolean;
@@ -379,6 +453,8 @@ interface GridDefinition<Q extends AcceptedGridQuery = GridQuery, Row extends Gr
379
453
  reporting?: GridReporting;
380
454
  /** Header rows above the columns, up to three levels (docs/column-groups.md). */
381
455
  columnGroups?: readonly GridColumnGroup[];
456
+ /** Presentation labels follow displayed contiguous members and pins without governing layout. Mutually exclusive with columnGroups. */
457
+ columnBands?: readonly GridColumnBandDefinition[];
382
458
  /** Cell ranges by mouse, keyboard and touch, the cell menu and the clipboard keys (docs/cell-ranges.md). */
383
459
  rangeSelection?: GridRangeSelection;
384
460
  /** How cell ranges copy and paste. */
@@ -391,6 +467,12 @@ interface GridDefinition<Q extends AcceptedGridQuery = GridQuery, Row extends Gr
391
467
  facets?: GridFacetPanelDefinition<Row>;
392
468
  /** Shows the records as a calendar: month, week, day, N days, agenda, year and the resource timeline (calendar.d.ts). */
393
469
  calendar?: GridCalendarDefinition<Row>;
470
+ /** Lane cards with the grid's search, facets, saved views and record panel; loaded as an optional part. */
471
+ path?: GridPathDefinition;
472
+ stack?: GridStackDefinition;
473
+ board?: GridBoardDefinition;
474
+ /** Dependencies, baseline and governed proposals on the calendar's resource timeline. */
475
+ plan?: GridPlanDefinition;
394
476
  /** Rows can be dragged out (or picked up with F2) onto a calendar that accepts drops. */
395
477
  dragRows?: boolean;
396
478
  stateKey?: string;
@@ -430,8 +512,9 @@ export interface GridRowData {
430
512
  }
431
513
  /** An inline grid whose rows the data part decodes from compact row data, chunk by chunk, after the first paint. */
432
514
  export interface CompactGridView<Row extends GridRow = GridRow> extends GridDefinition<GridQuery, Row> { source: { kind: "inline"; navigation?: "offset" }; rowData: GridRowData; rows?: never; }
433
- export interface HostGridView<Row extends GridRow = GridRow> extends GridDefinition<GridQuery, Row> { source: { kind: "host"; navigation?: "offset" }; rows?: never; }
515
+ export interface HostGridView<Row extends GridRow = GridRow> extends GridDefinition<GridQuery, Row> { calculatedColumnsEditable?: false; source: { kind: "host"; navigation?: "offset" }; rows?: never; }
434
516
  export interface CursorGridView<Row extends GridRow = GridRow> extends GridDefinition<GridCursorQuery, Row> {
517
+ calculatedColumnsEditable?: false;
435
518
  source: { kind: "host"; navigation: "cursor" };
436
519
  presentation: "paged";
437
520
  rows?: never;
@@ -452,13 +535,15 @@ export interface GridPage<Row extends GridRow = GridRow> {
452
535
  items: Row[];
453
536
  }
454
537
  /** Hosts own data access, authorization and query execution; cancellation does not grant write authority. */
455
- export interface GridFacetOptions { readonly search?: string; readonly limit?: number; readonly includeCurrentFilter?: boolean; readonly signal?: AbortSignal; }
538
+ export interface GridFacetOptions { readonly search?: string; readonly limit?: number; readonly includeCurrentFilter?: boolean; readonly signal?: AbortSignal; readonly bucket?: GridBucket; }
456
539
  /** Facet values/counts ignore the query window and sort; excluding the current column replaces its predicates by true. */
457
540
  export interface GridFacetQuery<Q extends AcceptedGridQuery = AcceptedGridQuery> {
541
+ readonly bucket?: GridBucket;
458
542
  readonly protocol: "canopyx/2"; readonly type: "gridFacetQuery"; readonly query: Q & { readonly revision: string };
459
543
  readonly column: string; readonly search: string; readonly limit: number; readonly includeCurrentFilter: boolean;
460
544
  }
461
545
  export interface GridFacetPage {
546
+ readonly bucket?: GridBucket;
462
547
  readonly protocol: "canopyx/2"; readonly type: "gridFacetPage"; readonly view: string; readonly revision: string;
463
548
  readonly column: string; readonly search: string; readonly includeCurrentFilter: boolean;
464
549
  readonly matched: number; readonly totalValues: number; readonly truncated: boolean;
@@ -472,6 +557,8 @@ export interface GridSource<Row extends GridRow = GridRow> extends GridFacetSour
472
557
  query(query: GridQuery, options: { signal: AbortSignal }): GridPage<Row> | PromiseLike<GridPage<Row>>;
473
558
  /** Complete-query metadata, echoing the normalized accepted request, revision and matched count. */
474
559
  summary?(query: GridQuery & { readonly revision: string }, options: { signal: AbortSignal }): GridSummary | PromiseLike<GridSummary>;
560
+ /** Computes the full accepted query, echoing its query/revision; requires an explicit endpoint capability. */
561
+ pivot?(request: GridPivotQuery, options: { signal: AbortSignal }): GridPivotAcceptedResult | PromiseLike<GridPivotAcceptedResult>;
475
562
  /** Saves changed rows (a remote source posts the gridCommit document to its commit endpoint) and answers per row. */
476
563
  commit?(batch: GridCommit, options: { signal: AbortSignal }): GridCommitResult | PromiseLike<GridCommitResult>;
477
564
  /** A record's details when its drawer opens (a gridRecordQuery answered with a gridRecord), as a remote protocol client sends it. */
@@ -488,6 +575,8 @@ export interface GridFooter {
488
575
  readonly aggregates: readonly GridAggregate[];
489
576
  }
490
577
  export interface GridAggregate {
578
+ /** A display transformation; raw aggregates remain unchanged. */
579
+ readonly showAs?: GridShowAs;
491
580
  /** The label is shown beside the value in group headings and the query totals row. */
492
581
  readonly id: string; readonly column: string; readonly label: string;
493
582
  readonly operation: GridAggregateOperation;
@@ -495,7 +584,14 @@ export interface GridAggregate {
495
584
  readonly format?: GridNumberFormat;
496
585
  }
497
586
  /** One runtime grouping level: groups order by value, or by a declared aggregate (nulls last, ties by value). */
587
+ /** Numeric keys partition calendar instants or half-open numeric intervals. Monday and UTC are the calendar defaults. */
588
+ export type GridBucket =
589
+ | { readonly kind: "day" | "week" | "month" | "quarter" | "year" | "hour" | "weekday"; readonly timeZone?: string; readonly firstWeekday?: 0 | 1 | 2 | 3 | 4 | 5 | 6 }
590
+ | { readonly kind: "width"; readonly width: number; readonly origin?: number }
591
+ | { readonly kind: "edges"; readonly edges: readonly number[] };
592
+
498
593
  export interface GridGroupLevel {
594
+ readonly bucket?: GridBucket;
499
595
  readonly column: string; readonly direction: "asc" | "desc"; readonly aggregate?: string;
500
596
  }
501
597
  /** Declared detail rows: one content source (a page template, a plugin detail renderer or a nested view), else record payloads. */
@@ -546,6 +642,14 @@ export interface GridSummary {
546
642
  readonly query: GridQuery & { readonly revision: string }; readonly matched: number;
547
643
  readonly groups: readonly GridGroup[]; readonly aggregates: Readonly<Record<string, number | null>>;
548
644
  }
645
+
646
+ /** Percent modes return fractions; rank uses descending competition order. Null/zero denominators produce null. */
647
+ export type GridShowAs = "value" | "percentGrandTotal" | "percentParent" | "percentColumn" | "percentRow" | "runningTotal" | "rank" | "difference" | "percentChange";
648
+ export interface GridAggregateDisplayValue { readonly value: number | null; readonly mode: GridShowAs; readonly numberFormat: string; }
649
+ export interface GridSummaryDisplay {
650
+ readonly totals: Readonly<Record<string, GridAggregateDisplayValue>>;
651
+ readonly groups: Readonly<Record<string, Readonly<Record<string, GridAggregateDisplayValue>>>>;
652
+ }
549
653
  /** One complete visible page. Null counts remain unknown; ordinal positions do not grant random access. */
550
654
  export interface GridCursorPage<Row extends GridRow = GridRow> extends Omit<GridPage<Row>, "type" | "total" | "matched"> {
551
655
  type: "gridCursorPage";
@@ -586,6 +690,10 @@ export interface GridQuerySelection<Q extends AcceptedGridQuery = GridQuery> {
586
690
  }
587
691
  /** Exports retain the accepted revision, query ordering, columns and selected IDs at invocation. */
588
692
  export interface GridExportRequest<Q extends AcceptedGridQuery = GridQuery> {
693
+ /** Reporting captures preserve the declared native rules for document writers; resolved cell formats stay on rows. */
694
+ readonly formatRules?: readonly GridFormatRule[];
695
+ /** UTC instant captured at invocation, for export metadata. */
696
+ readonly generatedAt?: string;
589
697
  /** Ordinary grids capture text only; the reporting runtime resolves semantic presentation and diagnostics. */
590
698
  readonly presentation: "text" | "semantic";
591
699
  readonly scope: "filtered" | "selected" | "all";
@@ -609,6 +717,8 @@ export interface GridExportRequest<Q extends AcceptedGridQuery = GridQuery> {
609
717
  readonly totals: Readonly<Record<string, number | null>>; readonly groups: readonly (GridGroup & { readonly text: string })[] };
610
718
  /** Records carry their detail payloads. */
611
719
  readonly details?: true;
720
+ /** Explicit full-query pivot table. Rows are enumerated once through the ordinary capture; they are not duplicated here. */
721
+ readonly pivot?: GridPivotExportDescriptor;
612
722
  }
613
723
  /** Record counts refer to the complete captured export scope, including selected-query exclusions. */
614
724
  export interface GridExportProgress {
@@ -636,11 +746,16 @@ export interface GridRowActivation<Row extends GridRow = GridRow> {
636
746
  }
637
747
  export interface GridExportOptions {
638
748
  scope: GridExportRequest["scope"];
749
+ /** Include declared detail payloads; false omits them. Defaults to the detail definition's print policy. */
750
+ includeDetails?: boolean;
751
+ /** Reporting bridge only: capture the active complete pivot table. Requires filtered scope; defaults to record capture.
752
+ * Available for capture, print and host delivery; pivot XLSX/PDF exportAs is not supported yet. */
753
+ pivot?: boolean;
639
754
  /** Defaults to visible exportable columns in their current order. Explicit non-exportable columns are rejected. */
640
755
  columns?: string[];
641
756
  values?: GridExportRequest["values"];
642
757
  signal?: AbortSignal;
643
- /** Client CSV defaults to 50000; clipboard to 10000. Larger results use a host hook. */
758
+ /** Client CSV defaults to 50000; clipboard to 10000; print to 1000 (maximum 10000). Larger results use a host hook. */
644
759
  maxRows?: number;
645
760
  /** Reporting runtime only. A safe basename up to 100 UTF-16 units; hosts append their format extension. */
646
761
  fileName?: string;
@@ -648,7 +763,7 @@ export interface GridExportOptions {
648
763
  locale?: string;
649
764
  /** Reporting runtime only. Overrides the captured display zone without changing the view. */
650
765
  timeZone?: TimeZone;
651
- /** Reporting runtime only. Observational synchronous progress; a throwing callback aborts the operation. */
766
+ /** Observational synchronous progress for print and reporting exports; a throwing callback aborts the operation. */
652
767
  onProgress?: (progress: GridExportProgress) => void;
653
768
  }
654
769
  /** A complete bounded snapshot for a host renderer: at most 10000 records and 4 Mi UTF-16 units. */
@@ -679,6 +794,7 @@ export interface GridState<Q extends AcceptedGridQuery = GridQuery> {
679
794
  scrollTop: number;
680
795
  /** Reporting grouping only. At most 10000 bounded stable keys; omitted from shareable state. */
681
796
  collapsedGroups?: string[];
797
+ aggregateShowAs?: Record<string, GridShowAs>;
682
798
  /** Optional for compatibility with existing continuous snapshots; restored offsets clamp to current results. */
683
799
  paging?: { pageLength: number; offset: number; allRows?: boolean };
684
800
  /** Formatting rules edited at run time, when they differ from the view's; restored with the view. */
@@ -691,6 +807,12 @@ export interface GridState<Q extends AcceptedGridQuery = GridQuery> {
691
807
  facets?: { open: boolean };
692
808
  /** The calendar's view, date, zoom and collapsed resources, in a grid with a calendar. */
693
809
  calendar?: GridCalendarSavedState;
810
+ /** Selected phone lane of an optional board. */
811
+ board?: GridBoardState;
812
+ /** Pivot definition, active mode, collapsed prefixes and compact-screen column choice. */
813
+ pivot?: GridPivotState;
814
+ /** Up to 32 definitions, allowed only when the current view enables calculatedColumnsEditable. */
815
+ calculatedColumns?: readonly GridCalculatedColumnDefinition[];
694
816
  }
695
817
  /** Versioned, bounded preference envelope. Revisions/cursors belong to data, never durable settings. */
696
818
  export type GridPreferenceQuery<Q extends AcceptedGridQuery = GridQuery> = Readonly<Omit<Q, "revision" | "cursor">> & {
@@ -724,6 +846,8 @@ interface GridHostBehavior<Q extends AcceptedGridQuery = GridQuery, Row extends
724
846
  source?: Q extends GridCursorQuery ? GridCursorSource<Row> : GridSource<Row>;
725
847
  /** Space-separated host styling classes copied onto body-appended record, text and column overlays when opened. */
726
848
  overlayClass?: string;
849
+ /** True opens the record drawer as a full-height sheet over a scrim at every width (default false: a side panel on wide screens, a sheet on narrow ones). */
850
+ recordDrawerModal?: boolean;
727
851
  labels?: Partial<CanopyLabels>;
728
852
  renderers?: Record<string, (row: Row, element: HTMLElement, context: GridCellContext) => boolean | void>;
729
853
  cachePageLimit?: number;
@@ -746,12 +870,11 @@ interface GridHostBehavior<Q extends AcceptedGridQuery = GridQuery, Row extends
746
870
  onExport?: (event: { format: string; request: GridExportRequest<Q>; capture: GridExport<Q>; signal: AbortSignal;
747
871
  /** Reporting runtime only. Monotonic record counts and phases; late calls after cancellation are ignored. */
748
872
  reportProgress?: (phase: GridExportProgress["phase"], completed: number) => void }) => void | PromiseLike<void>;
749
- /** Reporting runtime only. Render the complete snapshot through a host-owned renderer; honor cancellation before delivery. */
750
873
  /** After a layout or density switch; the canopyx:layout event carries the same detail. */
751
874
  onLayout?: (detail: LayoutState) => void | boolean;
752
875
  /** After each finished match count and each move between matches; the canopyx:matches event carries the same detail. */
753
876
  onMatches?: (detail: { total: number; current: number; complete: boolean }) => void | boolean;
754
- /** layout asks for stacked records from a grid in the card layout and a table otherwise; print never scrolls. */
877
+ /** Overrides the script-free print renderer. layout is stacked for cards and table otherwise; honor cancellation before delivery. */
755
878
  onPrint?: (event: { snapshot: GridExportSnapshot<Q>; signal: AbortSignal; layout: "table" | "stacked" }) => void | PromiseLike<void>;
756
879
  /** Hosts compose a drawer or details view and restore returnFocus when it closes. */
757
880
  onDetails?: (event: { row: Readonly<Row>; query: Q; signal: AbortSignal; returnFocus: Element | null }) => void | PromiseLike<void>;
@@ -789,6 +912,11 @@ interface GridHostBehavior<Q extends AcceptedGridQuery = GridQuery, Row extends
789
912
  editing?: GridEditingOptions<Q>;
790
913
  /** Before a value changes; returning false (or cancelling canopyx:cellValueChanging) keeps the old value. */
791
914
  onCellValueChanging?: (event: GridCellValueChange) => boolean | void;
915
+ /** Accept a board lane proposal with true, reject with false, or let the configured editing writer decide. */
916
+ onBoardMove?: (event: GridBoardMove) => boolean | void | PromiseLike<boolean>;
917
+ plan?: GridPlanOptions;
918
+ /** Cancel a plan proposal before the host callback runs; event return values never change actual dates. */
919
+ onPlanChangeProposal?: (event: GridPlanChangeProposal) => boolean | void;
792
920
  /** After a value changed. */
793
921
  onCellValueChanged?: (event: GridCellValueChange) => void;
794
922
  /** A row whose edits are complete and valid. Return a result (or true, or a promise) to save it, false to keep editing, nothing to leave it in the batch. */
@@ -837,12 +965,22 @@ export type GridOptions<Row extends GridRow = GridRow> = GridHostOptions<GridQue
837
965
  export type CursorGridOptions<Row extends GridRow = GridRow> = GridHostOptions<GridCursorQuery, Row> & { view: CursorGridView<Row>; source: GridCursorSource<Row> };
838
966
 
839
967
  /** Presentation controller. Selection uses stable IDs independently of cached or visible rows. Row (default GridRow) types its view, column methods and live API. */
840
- export interface DataGrid<Q extends AcceptedGridQuery = GridQuery, Row extends GridRow = GridRow> extends GridEditingApi, LinkedView, ViewModeMethods, GridColumnGroupApi, GridCellRangeApi, GridLiveApi<Row, Q>, GridFacetPanelApi, GridCalendarApi {
968
+ export interface DataGrid<Q extends AcceptedGridQuery = GridQuery, Row extends GridRow = GridRow> extends GridPivotApi, GridEditingApi, LinkedView, ViewModeMethods, GridColumnGroupApi, GridCellRangeApi, GridLiveApi<Row, Q>, GridFacetPanelApi, GridCalendarApi, GridViewIntentApi<Q> {
841
969
  readonly element: HTMLElement;
842
970
  readonly view: GridView<Row>;
843
971
  readonly ready: Promise<Q>;
844
972
  getQuery(): Q | null;
973
+ /** Whether the comparison's unchanged rows are excluded by the accepted query. */
974
+ getOnlyChanges(): boolean;
975
+ /** Change the comparison scope through its ordinary status-column filter. */
976
+ setOnlyChanges(enabled: boolean): Promise<Q>;
845
977
  setQuery(query: GridQueryInput<Q>): Promise<Q>;
978
+ /** Immutable definitions of the declared calculated columns; [] when none are configured. */
979
+ getCalculatedColumns(): readonly GridCalculatedColumnDefinition[];
980
+ /** Replaces the complete definition set after validation. Requires calculatedColumnsEditable and built-in inline data. */
981
+ setCalculatedColumns(definitions: readonly GridCalculatedColumnDefinition[]): Promise<readonly GridCalculatedColumnDefinition[]>;
982
+ /** Opens the inline calculated-column editor, optionally anchored to a host element. */
983
+ openCalculatedColumn(anchor?: HTMLElement): Promise<void>;
846
984
  sort(sorts: readonly GridSort[]): Promise<Q>;
847
985
  getPaging(): GridPaging<Q>;
848
986
  /** Offset sources only. Cursor sources reject random page access. */
@@ -891,6 +1029,10 @@ export interface DataGrid<Q extends AcceptedGridQuery = GridQuery, Row extends G
891
1029
  getSelectionDescriptor?(): GridSelection<Q>;
892
1030
  /** Reporting summary capability only; null before acceptance. */
893
1031
  getSummary?(): GridSummary | null;
1032
+ /** Changes only presentation, then updates saved/share state. */
1033
+ setAggregateShowAs?(aggregate: string, mode: GridShowAs): Promise<void>;
1034
+ /** Loads the optional values part and returns numeric values paired with export number formats. */
1035
+ getDisplaySummary?(): Promise<GridSummaryDisplay | null>;
894
1036
  /** Grouped reporting grids (fixed or runtime). Keys name groups of any level. Collapse affects display; record query/selection/export scope remain intact. */
895
1037
  setGroupCollapsed?(key: string, collapsed: boolean): void;
896
1038
  getCollapsedGroups?(): string[];
@@ -917,6 +1059,8 @@ export interface DataGrid<Q extends AcceptedGridQuery = GridQuery, Row extends G
917
1059
  setTimeZone(zone: TimeZone): void;
918
1060
  getTimeZone(): TimeZone;
919
1061
  /** Explicit identities only. Throws in query-selection mode; use getSelectionDescriptor instead. */
1062
+ /** Mutable pointer-selection opt-in, initially taken from the view. Does not add checkboxes. */
1063
+ selectOnClick: boolean;
920
1064
  getSelection(): string[];
921
1065
  setSelection(ids: string[]): void;
922
1066
  clearSelection(): void;
@@ -931,8 +1075,8 @@ export interface DataGrid<Q extends AcceptedGridQuery = GridQuery, Row extends G
931
1075
  exportAs(format: string, options: Omit<GridExportOptions, "onProgress" | "maxRows"> & ExportFormatOptions): Promise<ExportFormatResult>;
932
1076
  /** Reporting runtime only. Complete bounded record snapshot; default maxRows is 1000, never silently truncates. */
933
1077
  materializeExport?(options: GridExportOptions): Promise<GridExportSnapshot<Q>>;
934
- /** Reporting runtime only. Passes the same bounded snapshot to onPrint; never prints viewport DOM. */
935
- print?(options: GridExportOptions): Promise<void>;
1078
+ /** Prints a bounded complete static snapshot, or passes it to onPrint. Default maxRows is 1000; never prints viewport DOM. */
1079
+ print(options: GridExportOptions): Promise<void>;
936
1080
  /** Details are opened for loaded records, by toolbar, double click or Ctrl/Command+Enter. */
937
1081
  openDetails(id: string): Promise<void>;
938
1082
  /** The current formatting rules: the view's, or the ones set since. */
@@ -13,6 +13,8 @@ export interface ExportMenuOptions {
13
13
  csv?: boolean;
14
14
  /** Offers the clipboard action. Defaults to true. */
15
15
  copy?: boolean;
16
+ /** Offers a grid's default static print action. Defaults to true for declared XLSX/PDF formats; hosts can override printing. */
17
+ print?: boolean;
16
18
  /** Values captured by native menu actions. Defaults to display. */
17
19
  values?: "raw" | "display";
18
20
  }
@@ -98,6 +100,10 @@ export interface ExportFormatContext {
98
100
  readonly fileName: string;
99
101
  /** The format's id. */
100
102
  readonly format: string;
103
+ /** True requests a captured metadata section when the writer supports it. Default false. */
104
+ readonly includeMetadata: boolean;
105
+ /** Reports a bounded, structured limitation without changing captured values. */
106
+ diagnostic(value: ExportDiagnostic): void;
101
107
  /** Reports written records (a nonnegative integer; other values are ignored); the Export menu shows them as progress. */
102
108
  progress(completed: number): void;
103
109
  }
@@ -113,19 +119,26 @@ export interface ExportFormat<C extends ExportCapture = ExportCapture> {
113
119
  readonly mime?: string;
114
120
  /** False omits this writer from the Export menu; exportAs still runs it. Default true. */
115
121
  readonly showInMenu?: boolean;
122
+ /** Default capture values for this format, used only when the caller does not choose raw/display explicitly. */
123
+ readonly values?: "raw" | "display";
116
124
  /** Returns the file: a Blob (a File names the download itself), or bytes typed with mime. */
117
125
  write(capture: C, context: ExportFormatContext): Blob | ArrayBuffer | ArrayBufferView | PromiseLike<Blob | ArrayBuffer | ArrayBufferView>;
118
126
  }
119
127
  export interface ExportProgress { readonly phase: "reading" | "generating" | "ready"; readonly completed: number; readonly total: number | null; }
128
+ /** A document writer's limitation, with optional stable source identities. */
129
+ export interface ExportDiagnostic { readonly code: string; readonly columnId?: string; readonly rowId?: string; }
120
130
  export interface ExportFormatOptions {
121
131
  signal?: AbortSignal;
122
132
  onProgress?: (progress: ExportProgress) => void;
133
+ onDiagnostic?: (diagnostic: ExportDiagnostic) => void;
134
+ /** Requests captured metadata; the built-in XLSX writer adds an About worksheet. Default false. */
135
+ includeMetadata?: boolean;
123
136
  /** Safety timeout for the writer, 1..2147483647 ms; overrides the grid's exportTimeoutMs (default 600000). */
124
137
  timeoutMs?: number;
125
138
  /** False returns the file without starting a browser download. Default true. */
126
139
  download?: boolean;
127
140
  }
128
- export interface ExportFormatResult { readonly blob: Blob; readonly fileName: string; readonly format: string; }
141
+ export interface ExportFormatResult { readonly blob: Blob; readonly fileName: string; readonly format: string; readonly diagnostics: readonly ExportDiagnostic[]; }
129
142
  export interface TreeExportOptions {
130
143
  /** "visible" (default): the rows the reader can see, in order. "selected": the loaded selected nodes in tree order, including collapsed ones.
131
144
  * "all": every node in the current sort order, the whole tree of an inline source and the loaded nodes of a lazy one. */
@@ -152,6 +165,8 @@ export interface TreeExport extends ExportCapture {
152
165
  export type HostTrustedHTML = typeof globalThis extends { TrustedHTML: { prototype: infer T } } ? T : never;
153
166
  /** Hooks stay with the host. Acceptance never makes the grid perform a write. */
154
167
  interface HostOptionsBase extends RecordPanelOptions {
168
+ /** Overrides the view: true opens a modal record sheet at every width; false keeps the responsive side panel/sheet. */
169
+ recordDrawerModal?: boolean;
155
170
  source?: DataSource;
156
171
  labels?: CanopyLabels;
157
172
  requestTimeoutMs?: number;
@@ -4,9 +4,11 @@ import type {
4
4
  } from "./protocol.js";
5
5
  import type {
6
6
  TreeGridOptions, HostOptions, Sources, ExpandPathOptions, NodeFilter, FilterOptions,
7
- InteractionOptions, DropPlacement, ExportFormat, ExportFormatOptions, ExportFormatResult, TreeExport, TreeExportOptions, LinkedView
7
+ InteractionOptions, DropPlacement, ExportFormat, ExportFormatContext, ExportDiagnostic, ExportFormatOptions, ExportFormatResult, TreeExport, TreeExportOptions, LinkedView
8
8
  } from "./hosts.js";
9
9
  import type { CanopyPlugin, CanopyPartDefinition } from "./plugins.js";
10
+ import type { UiApi } from "./ui.js";
11
+ export * from "./ui.js";
10
12
  export * from "./protocol.js";
11
13
  export * from "./hosts.js";
12
14
  export * from "./plugins.js";
@@ -117,7 +119,7 @@ export function registerPart(name: string, part: CanopyPartDefinition): void;
117
119
  */
118
120
  export function setNonce(nonce: string): void;
119
121
 
120
- declare const CanopyX: Readonly<{
122
+ declare const CanopyX: Readonly<UiApi & {
121
123
  protocol: typeof protocol;
122
124
  createTreeGrid: typeof createTreeGrid;
123
125
  configure: typeof configure;