@svgrid/enterprise 2.6.4 → 3.0.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.
Files changed (60) hide show
  1. package/dist/SvGridBulkEditDrawer.svelte +158 -0
  2. package/dist/SvGridBulkEditDrawer.svelte.d.ts +9 -0
  3. package/dist/SvGridSelectionBar.svelte +452 -0
  4. package/dist/SvGridSelectionBar.svelte.d.ts +6 -0
  5. package/dist/SvPivotDesigner.svelte +3 -3
  6. package/dist/SvPivotDesigner.svelte.d.ts +3 -3
  7. package/dist/bulk-edit.d.ts +64 -0
  8. package/dist/bulk-edit.js +152 -0
  9. package/dist/cdn/svgrid-enterprise.svelte-external.js +6182 -5779
  10. package/dist/designer/assets/GridMenus-Cgilexpk.js +8 -0
  11. package/dist/designer/assets/SvDateRangeInput-BV5OXYQ2.css +1 -0
  12. package/dist/designer/assets/SvDateRangeInput-CVn-yqrQ.js +1 -0
  13. package/dist/designer/assets/SvDateTimePicker-BdioTrJQ.js +1 -0
  14. package/dist/designer/assets/SvDateTimePicker-CY8TK4BT.css +1 -0
  15. package/dist/designer/assets/SvField-BsqiA5me.js +1 -0
  16. package/dist/designer/assets/SvGridCellEditor-dLY7_kk9.js +2 -0
  17. package/dist/designer/assets/SvListBox-CVYQcLX9.js +1 -0
  18. package/dist/designer/assets/{SvListBox-BMSfFJJT.css → SvListBox-DgN8kvjt.css} +1 -1
  19. package/dist/designer/assets/column-resize-C_inr5zT.js +1 -0
  20. package/dist/designer/assets/date-format-4DJvNtG2.js +1 -0
  21. package/dist/designer/assets/{SvDateTimePicker-Cygij-dr.css → date-format-Dzy4mTGh.css} +1 -1
  22. package/dist/designer/assets/dismissable-BO547MH9.js +1 -0
  23. package/dist/designer/assets/editor-registry-BjP16H0v.js +1 -0
  24. package/dist/designer/assets/index-Cp7fDJ3b.css +1 -0
  25. package/dist/designer/assets/{index-DxBZuosR.js → index-zUBix-JQ.js} +129 -129
  26. package/dist/designer/assets/{js-scroller.svelte-03aI6ovu.js → js-scroller.svelte-Bhxqb3-c.js} +2 -2
  27. package/dist/designer/assets/preload-helper-CG0n22O7.js +1 -0
  28. package/dist/designer/assets/{row-drag-touch-IuJPEt0z.js → row-drag-touch-BdknxBNL.js} +1 -1
  29. package/dist/designer/assets/row-resize-B0FWHcNr.js +1 -0
  30. package/dist/designer/assets/src-B7DNcoQK.css +1 -0
  31. package/dist/designer/assets/src-BoYyigAC.js +2896 -0
  32. package/dist/designer/assets/validate-h-aslRV9.js +1 -0
  33. package/dist/designer/index.html +18 -13
  34. package/dist/export.d.ts +4 -0
  35. package/dist/import.d.ts +7 -0
  36. package/dist/index.d.ts +3 -0
  37. package/dist/index.js +8 -0
  38. package/dist/install.d.ts +3 -0
  39. package/dist/install.js +2 -0
  40. package/dist/node/studio.js +65 -3
  41. package/dist/pivot.d.ts +11 -0
  42. package/dist/pivot.js +6 -1
  43. package/dist/selection-bar.d.ts +7 -0
  44. package/dist/selection-bar.js +42 -0
  45. package/dist/studio/emit-project.js +6 -0
  46. package/dist/studio/ui-components.generated.js +64 -2
  47. package/dist/version.d.ts +1 -1
  48. package/dist/version.js +1 -1
  49. package/package.json +8 -3
  50. package/dist/designer/assets/GridMenus-BIU7Nfbr.js +0 -7
  51. package/dist/designer/assets/SvDateTimePicker-DOBYyLeN.js +0 -1
  52. package/dist/designer/assets/SvGrid.helpers-C6wxF55r.js +0 -1
  53. package/dist/designer/assets/SvGridCellEditor-CMtmQINJ.js +0 -2
  54. package/dist/designer/assets/SvListBox-D-_I_Aff.js +0 -1
  55. package/dist/designer/assets/dismissable-2EZKoens.js +0 -1
  56. package/dist/designer/assets/editor-registry-BB1Qb5mp.js +0 -1
  57. package/dist/designer/assets/index-BfzoL904.css +0 -1
  58. package/dist/designer/assets/src-D8qr49rE.css +0 -1
  59. package/dist/designer/assets/src-Dn1Axx6T.js +0 -2896
  60. /package/dist/designer/assets/{dismissable-BF-9TJSd.css → SvField-BF-9TJSd.css} +0 -0
@@ -0,0 +1 @@
1
+ var e=`https://svgrid.com/docs/getting-started/3-data-and-columns/`;function t(e,n=[]){for(let r of e)r.columns?.length?t(r.columns,n):n.push(r);return n}function n(n){let i=[],a=t(n.columns??[]),o=(n.data??[]).slice(0,10);if(o.length){let t=new Set;for(let e of o)if(e&&typeof e==`object`)for(let n of Object.keys(e))t.add(n);for(let n of a){let a=n.field;if(!a||n.fieldFn||t.has(a))continue;let o=r(a,[...t]);i.push(`[svgrid] Column field "${a}" does not exist on your row data, so that column renders empty.${o?` Did you mean "${o}"?`:``} Available keys: ${[...t].slice(0,12).join(`, `)}. See ${e}`)}}let s=new Map;for(let e of a){let t=e.id??e.field;t&&s.set(t,(s.get(t)??0)+1)}for(let[t,n]of s)n>1&&i.push(`[svgrid] ${n} columns share the id "${t}". Column state (sorting, filtering, pinning, width) is keyed by id, so they will act as one. Give each an explicit \`id\`. See ${e}`);let c=n.pageable===void 0&&n.showPagination===void 0;n.pageSize!==void 0&&c&&i.push("[svgrid] `pageSize` is set but pagination was never turned on, so it has no effect and every row renders. Add `pageable` to switch the pager on."),!(n.sortable===!0||n.features?.rowSortingFeature)&&a.some(e=>e.sortable===!0)&&i.push("[svgrid] A column sets `sortable: true`, but sorting is not enabled on the grid, so its header does nothing. Add `sortable` to <SvGrid> (it registers the sorting feature for you).");let l=new Set;for(let e of a){let t=e.id??e.field;t&&l.add(t)}for(let e of n.groupBy??[]){if(l.has(e))continue;let t=r(e,[...l]);i.push(`[svgrid] \`groupBy\` refers to column "${e}", which does not exist, so that grouping level is ignored.${t?` Did you mean "${t}"?`:``} Column ids: ${[...l].slice(0,12).join(`, `)}`)}let u=n.treeData?.column;if(u&&!l.has(u)&&i.push(`[svgrid] \`treeData.column\` refers to column "${u}", which does not exist, so the expander falls back to the first visible column.`),o.length&&n.treeData){let e=new Set;for(let t of o)if(t&&typeof t==`object`)for(let n of Object.keys(t))e.add(n);let t=n.treeData.parentField;if(t&&!e.has(t)){let n=r(t,[...e]);i.push(`[svgrid] \`treeData.parentField\` is "${t}", which is not on your row data, so every row becomes a root and no hierarchy appears.${n?` Did you mean "${n}"?`:``}`)}let a=n.treeData.idField;a&&!e.has(a)&&i.push(`[svgrid] \`treeData.idField\` is "${a}", which is not on your row data, so parent lookups cannot match and the tree stays flat.`)}return(n.initialColumnPinning?.left?.length??0)+(n.initialColumnPinning?.right?.length??0)>0&&n.columnVirtualization!==!1&&i.push("[svgrid] `initialColumnPinning` is set while column virtualization is on (its default), so the pinned columns will not stick - the virtualizer recycles column nodes. Add `columnVirtualization={false}`."),n.externalPagination===!0&&n.rowCount===void 0&&i.push("[svgrid] `externalPagination` is on but `rowCount` is not set, so the pager cannot know how many pages exist. Pass the server total as `rowCount`."),n.externalSort===!0&&!n.onSortingChange&&i.push("[svgrid] `externalSort` is on but there is no `onSortingChange` handler, so clicking a header changes nothing - the grid stopped sorting and nobody is listening. Add `onSortingChange` and re-fetch in your handler."),n.externalFilter===!0&&!n.onFiltersChange&&i.push("[svgrid] `externalFilter` is on but there is no `onFiltersChange` handler, so filtering the grid changes nothing. Add `onFiltersChange` and re-fetch in your handler."),i}function r(e,t){let n,r=1/0;for(let a of t){let t=i(e.toLowerCase(),a.toLowerCase());t<r&&(r=t,n=a)}let a=Math.min(3,Math.floor(e.length/3)+1);return r<=a?n:void 0}function i(e,t){if(e===t)return 0;let n=Array(t.length+1);for(let e=0;e<=t.length;e++)n[e]=e;for(let r=1;r<=e.length;r++){let i=n[0];n[0]=r;for(let a=1;a<=t.length;a++){let o=Math.min(n[a]+1,n[a-1]+1,i+(e[r-1]===t[a-1]?0:1));i=n[a],n[a]=o}}return n[t.length]}export{n as validateGridConfig};
@@ -4,29 +4,34 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>SvGrid Studio - Designer</title>
7
- <script type="module" crossorigin src="./assets/index-DxBZuosR.js"></script>
7
+ <script type="module" crossorigin src="./assets/index-zUBix-JQ.js"></script>
8
8
  <link rel="modulepreload" crossorigin href="./assets/rolldown-runtime-Dd_uD5pT.js">
9
9
  <link rel="modulepreload" crossorigin href="./assets/disclose-version-CIm4S9xS.js">
10
10
  <link rel="modulepreload" crossorigin href="./assets/export-format-DwjuTfrQ.js">
11
- <link rel="modulepreload" crossorigin href="./assets/js-scroller.svelte-03aI6ovu.js">
12
- <link rel="modulepreload" crossorigin href="./assets/SvGrid.helpers-C6wxF55r.js">
13
- <link rel="modulepreload" crossorigin href="./assets/editor-registry-BB1Qb5mp.js">
14
- <link rel="modulepreload" crossorigin href="./assets/dismissable-2EZKoens.js">
11
+ <link rel="modulepreload" crossorigin href="./assets/js-scroller.svelte-Bhxqb3-c.js">
12
+ <link rel="modulepreload" crossorigin href="./assets/preload-helper-CG0n22O7.js">
13
+ <link rel="modulepreload" crossorigin href="./assets/SvField-BsqiA5me.js">
14
+ <link rel="modulepreload" crossorigin href="./assets/date-format-4DJvNtG2.js">
15
15
  <link rel="modulepreload" crossorigin href="./assets/popover-CUkLsvRX.js">
16
- <link rel="modulepreload" crossorigin href="./assets/SvDateTimePicker-DOBYyLeN.js">
17
16
  <link rel="modulepreload" crossorigin href="./assets/SvGridDropdown-CAYG7Y-O.js">
17
+ <link rel="modulepreload" crossorigin href="./assets/dismissable-BO547MH9.js">
18
+ <link rel="modulepreload" crossorigin href="./assets/SvDateTimePicker-BdioTrJQ.js">
19
+ <link rel="modulepreload" crossorigin href="./assets/editor-registry-BjP16H0v.js">
18
20
  <link rel="modulepreload" crossorigin href="./assets/easing-zaypKrr0.js">
19
21
  <link rel="modulepreload" crossorigin href="./assets/chart-DHEgt4lN.js">
20
22
  <link rel="modulepreload" crossorigin href="./assets/SvGridChart-BEDNTdc5.js">
21
- <link rel="modulepreload" crossorigin href="./assets/src-Dn1Axx6T.js">
22
- <link rel="modulepreload" crossorigin href="./assets/SvListBox-D-_I_Aff.js">
23
- <link rel="stylesheet" crossorigin href="./assets/dismissable-BF-9TJSd.css">
24
- <link rel="stylesheet" crossorigin href="./assets/SvDateTimePicker-Cygij-dr.css">
23
+ <link rel="modulepreload" crossorigin href="./assets/src-BoYyigAC.js">
24
+ <link rel="modulepreload" crossorigin href="./assets/SvDateRangeInput-CVn-yqrQ.js">
25
+ <link rel="modulepreload" crossorigin href="./assets/SvListBox-CVYQcLX9.js">
26
+ <link rel="stylesheet" crossorigin href="./assets/SvField-BF-9TJSd.css">
27
+ <link rel="stylesheet" crossorigin href="./assets/date-format-Dzy4mTGh.css">
25
28
  <link rel="stylesheet" crossorigin href="./assets/SvGridDropdown-Crwb2P3Q.css">
29
+ <link rel="stylesheet" crossorigin href="./assets/SvDateTimePicker-CY8TK4BT.css">
26
30
  <link rel="stylesheet" crossorigin href="./assets/SvGridChart-Vu4Nvjiv.css">
27
- <link rel="stylesheet" crossorigin href="./assets/src-D8qr49rE.css">
28
- <link rel="stylesheet" crossorigin href="./assets/SvListBox-BMSfFJJT.css">
29
- <link rel="stylesheet" crossorigin href="./assets/index-BfzoL904.css">
31
+ <link rel="stylesheet" crossorigin href="./assets/src-B7DNcoQK.css">
32
+ <link rel="stylesheet" crossorigin href="./assets/SvDateRangeInput-BV5OXYQ2.css">
33
+ <link rel="stylesheet" crossorigin href="./assets/SvListBox-DgN8kvjt.css">
34
+ <link rel="stylesheet" crossorigin href="./assets/index-Cp7fDJ3b.css">
30
35
  </head>
31
36
  <body>
32
37
  <div id="app"></div>
package/dist/export.d.ts CHANGED
@@ -11,6 +11,7 @@ import type { ConditionalFormat } from '@svgrid/grid/format';
11
11
  * - `csv` / `tsv` / `html` / `json` / `xml` / `md` native, no peer deps.
12
12
  */
13
13
  export type ExportFormat = 'xlsx' | 'xls' | 'pdf' | 'csv' | 'tsv' | 'html' | 'json' | 'xml' | 'md';
14
+ /** One column in an export: which field to read, and how to label and format it. */
14
15
  export type ExportColumn<TData = RowData> = {
15
16
  /** Data field name on the row object. */
16
17
  field: string;
@@ -111,6 +112,7 @@ export type ExportHeaderFooterLine = {
111
112
  center?: string;
112
113
  right?: string;
113
114
  };
115
+ /** One tab of a multi-sheet workbook. Only formats with sheets (xlsx, xls) use these. */
114
116
  export type ExportSheet<TData> = {
115
117
  /** Sheet/tab label. Required. */
116
118
  label: string;
@@ -129,6 +131,7 @@ export type ExportSheet<TData> = {
129
131
  * an explicit array - export exactly these.
130
132
  */
131
133
  export type ExportRowSource<TData> = ReadonlyArray<TData> | 'displayed' | 'selected' | 'all';
134
+ /** Everything `exportGrid` accepts: the format, the filename, which rows and columns, and per-format tuning. */
132
135
  export type ExportOptions<TData> = {
133
136
  format: ExportFormat;
134
137
  /** Base filename (extension is appended if missing). Defaults to "grid". */
@@ -304,6 +307,7 @@ export declare function buildGroupedPdfBody<TData extends RowData>(cols: Readonl
304
307
  export declare function exportGrid<TFeatures extends TableFeatures, TData extends RowData>(api: SvGridApi<TFeatures, TData>, opts: ExportOptions<TData>): Promise<ExportResult | undefined>;
305
308
  /** Native formats that can be placed on the clipboard. */
306
309
  export type ClipboardFormat = 'csv' | 'tsv' | 'html' | 'json' | 'xml' | 'md';
310
+ /** Options for copying a range to the clipboard, as opposed to writing a file. */
307
311
  export type ClipboardExportOptions<TData> = {
308
312
  /** Clipboard payload format. Default 'tsv' (pastes cleanly into Excel / Sheets). */
309
313
  format?: ClipboardFormat;
package/dist/import.d.ts CHANGED
@@ -24,7 +24,9 @@
24
24
  * `print`, so unlicensed evaluation works but emits a one-time nudge.
25
25
  */
26
26
  import type { RowData, SvGridApi, TableFeatures } from '@svgrid/grid';
27
+ /** Source formats `importGrid` reads. `'auto'` picks one from the file extension. */
27
28
  export type ImportFormat = 'xlsx' | 'csv' | 'tsv' | 'json' | 'auto';
29
+ /** Maps a source header to the row field it populates, for files whose columns do not match your data. */
28
30
  export type ImportColumnMap = Record<string, string>;
29
31
  /**
30
32
  * Declared data type per target field. When `columnTypes` is set on
@@ -33,6 +35,7 @@ export type ImportColumnMap = Record<string, string>;
33
35
  * stricter than the ad-hoc "looks like a number" fallback.
34
36
  */
35
37
  export type ImportFieldType = 'string' | 'number' | 'integer' | 'boolean' | 'date' | 'datetime' | 'json';
38
+ /** Per-field coercion, so a column of `"42"` strings arrives as numbers. */
36
39
  export type ImportColumnTypes = Record<string, ImportFieldType>;
37
40
  /**
38
41
  * The slice of a grid column the auto-mapper needs: its target `field`,
@@ -58,6 +61,7 @@ export type ImportProgress = {
58
61
  /** Total rows this phase will process (0 when unknown, e.g. mid-parse). */
59
62
  total: number;
60
63
  };
64
+ /** One row that failed validation, with the reason and where it came from. */
61
65
  export type ImportRowError = {
62
66
  /** 0-based row index in the SOURCE file (excluding the header). */
63
67
  rowIndex: number;
@@ -65,10 +69,12 @@ export type ImportRowError = {
65
69
  field: string;
66
70
  message: string;
67
71
  };
72
+ /** Per-row check run during import. Return an error message to reject the row, or nothing to accept it. */
68
73
  export type ImportValidator<TData> = (row: TData, rowIndex: number) => Array<{
69
74
  field: string;
70
75
  message: string;
71
76
  }>;
77
+ /** Everything `importGrid` accepts: the format, the column mapping and types, and the validator. */
72
78
  export type ImportOptions<TData> = {
73
79
  /** The file to read. A `File`/`Blob` works for xlsx; a string is treated as
74
80
  * inline CSV/TSV/JSON text. */
@@ -140,6 +146,7 @@ export type ImportOptions<TData> = {
140
146
  /** Progress callback for large files (parse + map phases). */
141
147
  onProgress?: (progress: ImportProgress) => void;
142
148
  };
149
+ /** The outcome of an import: the rows that parsed, and the ones that did not with their errors. */
143
150
  export type ImportResult<TData> = {
144
151
  /** Source headers as found in the file, in their original order. */
145
152
  headers: string[];
package/dist/index.d.ts CHANGED
@@ -9,6 +9,9 @@ export { default as SvImportDialog } from './SvImportDialog.svelte';
9
9
  export { installEnterprise, type EnterpriseGridApi, type EnterpriseAIApi, type EnterprisePivotApi } from './install';
10
10
  export { enableSchedulerView, SvGridScheduler } from './scheduler';
11
11
  export { enableBoardView, SvGridBoard } from './board';
12
+ export { enableSelectionBar, SvGridSelectionBar } from './selection-bar';
13
+ export { applyBulkEdit, bulkEditableFields, bulkEditInitialValues, coerceBulkValue, type BulkEditField, type BulkEditResult } from './bulk-edit';
14
+ export { default as SvGridBulkEditDrawer } from './SvGridBulkEditDrawer.svelte';
12
15
  export { enablePivot } from './pivot-enable';
13
16
  export { enableAdvancedFilter } from './advanced-filter-enable';
14
17
  export { default as SvAdvancedFilter } from './SvAdvancedFilter.svelte';
package/dist/index.js CHANGED
@@ -17,6 +17,14 @@ export { enableSchedulerView, SvGridScheduler } from './scheduler';
17
17
  // Kanban board view (Pro). `enableBoardView()` registers the renderer so
18
18
  // `<SvGrid board={...}>` shows lanes of cards. Config types live in @svgrid/grid.
19
19
  export { enableBoardView, SvGridBoard } from './board';
20
+ // Bulk-action bar over the row selection (Pro). `enableSelectionBar()` registers
21
+ // the renderer so `<SvGrid selectionBar={...}>` floats a bar over the grid while
22
+ // rows are selected. The prop + its config types live in @svgrid/grid.
23
+ export { enableSelectionBar, SvGridSelectionBar } from './selection-bar';
24
+ // Bulk edit engine behind the bar's `editFields` button - exported so an app
25
+ // can drive the same write from its own UI.
26
+ export { applyBulkEdit, bulkEditableFields, bulkEditInitialValues, coerceBulkValue } from './bulk-edit';
27
+ export { default as SvGridBulkEditDrawer } from './SvGridBulkEditDrawer.svelte';
20
28
  // In-grid pivot mode (Pro). `enablePivot()` registers the pivot engine so
21
29
  // `<SvGrid pivot={...}>` renders a pivot table in place of the flat table.
22
30
  export { enablePivot } from './pivot-enable';
package/dist/install.d.ts CHANGED
@@ -4,6 +4,7 @@ import { type PrintOptions } from './print';
4
4
  import { type ImportOptions, type ImportResult } from './import';
5
5
  import { type AIChartOptions, type AIChartPlan, type AIFilterOptions, type AIFilterResult, type AISmartFillOptions, type AISmartFillResult, type AISummarizeOptions, type AISummary, type AIClassifyOptions, type AIClassifyResult, type AIExportOptions, type AIExportPlan, type AIAnomalyOptions, type AIAnomalyResult } from '@svgrid/grid';
6
6
  import { type PivotConfig, type PivotResult } from './pivot';
7
+ /** The `api.ai.*` namespace added by the enterprise install. */
7
8
  export type EnterpriseAIApi<TData extends RowData> = {
8
9
  /** Natural-language -> filter + sort plan (and optionally apply it). */
9
10
  filter(query: string, opts?: AIFilterOptions): Promise<AIFilterResult>;
@@ -21,6 +22,7 @@ export type EnterpriseAIApi<TData extends RowData> = {
21
22
  chart(query: string, opts?: AIChartOptions): Promise<AIChartPlan>;
22
23
  readonly _rowType?: TData;
23
24
  };
25
+ /** The `api.pivot.*` namespace added by the enterprise install. */
24
26
  export type EnterprisePivotApi<TFeatures extends TableFeatures, TData extends RowData> = {
25
27
  /**
26
28
  * Build a pivot row/column model from the grid's current data. Returns
@@ -36,6 +38,7 @@ export type EnterprisePivotApi<TFeatures extends TableFeatures, TData extends Ro
36
38
  */
37
39
  buildFrom<TIn extends RowData>(data: ReadonlyArray<TIn>, config: PivotConfig<TIn>): PivotResult<TFeatures>;
38
40
  };
41
+ /** The grid API plus everything enterprise adds - what `installEnterprise` hands back. */
39
42
  export type EnterpriseGridApi<TFeatures extends TableFeatures, TData extends RowData> = SvGridApi<TFeatures, TData> & {
40
43
  /** Export the current visible rows to the chosen format. Returns the built
41
44
  * file ({@link ExportResult}) for the dependency-free paths (undefined for
package/dist/install.js CHANGED
@@ -9,6 +9,7 @@ import { aiFilter, aiSmartFill, aiSummarize, aiClassify, aiExport, aiFindAnomali
9
9
  import { createPivotModel, } from './pivot';
10
10
  import { enableSchedulerView } from './scheduler';
11
11
  import { enableBoardView } from './board';
12
+ import { enableSelectionBar } from './selection-bar';
12
13
  import { enableAdvancedFilter } from './advanced-filter-enable';
13
14
  import { enablePivot } from './pivot-enable';
14
15
  /**
@@ -42,6 +43,7 @@ export function installEnterprise(api) {
42
43
  enableSchedulerView();
43
44
  // Register the Kanban board view (no-op without the `board` prop).
44
45
  enableBoardView();
46
+ enableSelectionBar();
45
47
  // Register the export engine so built-in AI exports (aiExport) can write the
46
48
  // enterprise formats (xlsx / pdf / ...); free grids without it get the plan only.
47
49
  registerExportProvider(exportGrid);
@@ -3169,6 +3169,7 @@ var GENERATED_UI_SURFACE = {
3169
3169
  "key": "block",
3170
3170
  "label": "Block",
3171
3171
  "type": "boolean",
3172
+ "default": false,
3172
3173
  "description": "Fill the container instead of the control's own default width. A default width is right for a control sitting on its own; in a form grid a row of inputs each stopping at a different width reads as broken.",
3173
3174
  "group": "appearance"
3174
3175
  },
@@ -6138,6 +6139,7 @@ var GENERATED_UI_SURFACE = {
6138
6139
  "key": "block",
6139
6140
  "label": "Block",
6140
6141
  "type": "boolean",
6142
+ "default": false,
6141
6143
  "description": "Fill the container instead of the control's own default width. A default width is right for a control sitting on its own; in a form grid a row of inputs each stopping at a different width reads as broken.",
6142
6144
  "group": "appearance"
6143
6145
  },
@@ -6326,6 +6328,7 @@ var GENERATED_UI_SURFACE = {
6326
6328
  "key": "block",
6327
6329
  "label": "Block",
6328
6330
  "type": "boolean",
6331
+ "default": false,
6329
6332
  "description": "Fill the container instead of the control's own default width. A default width is right for a control sitting on its own; in a form grid a row of inputs each stopping at a different width reads as broken.",
6330
6333
  "group": "appearance"
6331
6334
  },
@@ -6520,6 +6523,7 @@ var GENERATED_UI_SURFACE = {
6520
6523
  "key": "block",
6521
6524
  "label": "Block",
6522
6525
  "type": "boolean",
6526
+ "default": false,
6523
6527
  "description": "Fill the container instead of the control's own default width. A default width is right for a control sitting on its own; in a form grid a row of inputs each stopping at a different width reads as broken.",
6524
6528
  "group": "appearance"
6525
6529
  },
@@ -8179,6 +8183,7 @@ var GENERATED_UI_SURFACE = {
8179
8183
  "key": "block",
8180
8184
  "label": "Block",
8181
8185
  "type": "boolean",
8186
+ "default": false,
8182
8187
  "description": "Fill the container instead of the control's own default width. A default width is right for a control sitting on its own; in a form grid a row of inputs each stopping at a different width reads as broken.",
8183
8188
  "group": "appearance"
8184
8189
  },
@@ -8663,6 +8668,13 @@ var GENERATED_UI_SURFACE = {
8663
8668
  "description": "Right-click context menu. `true` shows the default item set (copy, cut, paste, clear, insert row above/below, remove row, remove column). Pass an array to customize: strings are built-in keys, `\"separator\"` is a divider, and objects are custom items. Omitted/`false` disables the menu (native browser menu shows instead).",
8664
8669
  "group": "common"
8665
8670
  },
8671
+ {
8672
+ "key": "selectionBar",
8673
+ "label": "Selection Bar",
8674
+ "type": "boolean",
8675
+ "description": "Floating bar that appears over the grid while rows are selected, showing the count and the actions that apply to the whole selection - the pattern an issue tracker uses for bulk edit. `true` gives the count and a Clear button. An array is the shorthand for `{ actions }`. Pass to also set `position` (`'bottom'` default, or `'top'`), `maxVisible` and `hideClear`. Omitted / `false` is off. Default **off**. This is chrome that floats over your content, not a gesture: it overlaps a row, and what belongs on it is specific to the app. **The prop and its types are free; the bar itself is an Enterprise feature.** Install `@svgrid/enterprise` and call `enableSelectionBar()` (or `installEnterprise`, which does it for you) to render it - without that the grid shows a short upsell note in its place, the same way the scheduler and board views do.",
8676
+ "group": "common"
8677
+ },
8666
8678
  {
8667
8679
  "key": "features",
8668
8680
  "label": "Features",
@@ -8681,12 +8693,14 @@ var GENERATED_UI_SURFACE = {
8681
8693
  "key": "filterable",
8682
8694
  "label": "Filterable",
8683
8695
  "type": "boolean",
8696
+ "description": "Click a header to filter that column. Injects `columnFilteringFeature`, so you do not import it yourself. Which filter surface appears is a separate question - see `filterMode` (default `'menu'`). <SvGrid {data} {columns} filterable />",
8684
8697
  "group": "common"
8685
8698
  },
8686
8699
  {
8687
8700
  "key": "editable",
8688
8701
  "label": "Editable",
8689
8702
  "type": "boolean",
8703
+ "description": "Inline cell editing. Alias of `enableInlineEditing`, and wins over it when both are set. A column also needs an `editorType` to be editable; without one it falls back to a text editor. <SvGrid {data} {columns} editable />",
8690
8704
  "group": "common"
8691
8705
  },
8692
8706
  {
@@ -8707,6 +8721,7 @@ var GENERATED_UI_SURFACE = {
8707
8721
  "key": "groupable",
8708
8722
  "label": "Groupable",
8709
8723
  "type": "boolean",
8724
+ "description": "Show the grouping controls: \"Group by this column\" in the column menu, and the group panel when `showGroupPanel` is on. Alias of `showGroupingControls`, and also injects `columnGroupingFeature`. This turns on the UI for grouping. To group without asking the user, set `groupBy` instead. <SvGrid {data} {columns} groupable />",
8710
8725
  "group": "common"
8711
8726
  },
8712
8727
  {
@@ -8762,12 +8777,14 @@ var GENERATED_UI_SURFACE = {
8762
8777
  "key": "pageable",
8763
8778
  "label": "Pageable",
8764
8779
  "type": "boolean",
8780
+ "description": "Show the pagination footer. Alias of `showPagination`, and wins over it when both are set. Page size starts at `pageSize` (default 10). <SvGrid {data} {columns} pageable pageSize={25} />",
8765
8781
  "group": "common"
8766
8782
  },
8767
8783
  {
8768
8784
  "key": "loading",
8769
8785
  "label": "Loading",
8770
8786
  "type": "boolean",
8787
+ "description": "Show the loading state instead of the rows. By default this replaces the grid body with \"Loading...\"; set `loadingOverlay` to keep the current rows visible under a dimmed overlay instead, which is what you usually want for a server-paged grid.",
8771
8788
  "group": "behavior"
8772
8789
  },
8773
8790
  {
@@ -8788,12 +8805,14 @@ var GENERATED_UI_SURFACE = {
8788
8805
  "key": "error",
8789
8806
  "label": "Error",
8790
8807
  "type": "string",
8808
+ "description": "Render an error message in place of the rows. `null` or omitted means no error. Takes precedence over `loading` and over the empty state.",
8791
8809
  "group": "common"
8792
8810
  },
8793
8811
  {
8794
8812
  "key": "emptyMessage",
8795
8813
  "label": "Empty Message",
8796
8814
  "type": "string",
8815
+ "description": "Text shown when there are no rows to display - either the data is empty or a filter matched nothing. Defaults to the localized `noRows` string, so prefer `localization.text.noRows` when you are translating the whole grid.",
8797
8816
  "group": "common"
8798
8817
  },
8799
8818
  {
@@ -8807,12 +8826,14 @@ var GENERATED_UI_SURFACE = {
8807
8826
  "key": "showGlobalFilter",
8808
8827
  "label": "Show Global Filter",
8809
8828
  "type": "boolean",
8829
+ "description": "Show the single search box that filters across every column. Explicitly setting this wins over `filterMode`; leaving it unset means it appears only when `filterMode` is `'global'`.",
8810
8830
  "group": "common"
8811
8831
  },
8812
8832
  {
8813
8833
  "key": "showColumnFilters",
8814
8834
  "label": "Show Column Filters",
8815
8835
  "type": "boolean",
8836
+ "description": "Show the filter section inside each column's menu. Explicitly setting this wins over `filterMode`; unset, it follows `filterMode` (default `'menu'`, so this is normally on). Setting it `true` also adds the inline \"floating filter\" input under each header - that surface requires the explicit opt-in, since it otherwise duplicates the menu's own filter popover.",
8816
8837
  "group": "common"
8817
8838
  },
8818
8839
  {
@@ -8832,18 +8853,21 @@ var GENERATED_UI_SURFACE = {
8832
8853
  "key": "showGroupingControls",
8833
8854
  "label": "Show Grouping Controls",
8834
8855
  "type": "boolean",
8856
+ "description": "Show the grouping affordances (the column menu's \"Group by this column\", and the group panel). The `groupable` shortcut sets this and registers the grouping feature in one go; prefer that unless you have already registered `columnGroupingFeature` yourself.",
8835
8857
  "group": "common"
8836
8858
  },
8837
8859
  {
8838
8860
  "key": "showRowSelection",
8839
8861
  "label": "Show Row Selection",
8840
8862
  "type": "boolean",
8863
+ "description": "Show the row-selection checkbox column, including the select-all checkbox in the header. Unset, it follows `selectionMode` (default `'both'`, so row selection is on).",
8841
8864
  "group": "common"
8842
8865
  },
8843
8866
  {
8844
8867
  "key": "showPagination",
8845
8868
  "label": "Show Pagination",
8846
8869
  "type": "boolean",
8870
+ "description": "Show the pagination footer. Off by default. `pageable` is the shortcut alias and wins when both are set.",
8847
8871
  "group": "common"
8848
8872
  },
8849
8873
  {
@@ -8897,6 +8921,7 @@ var GENERATED_UI_SURFACE = {
8897
8921
  "key": "virtualization",
8898
8922
  "label": "Virtualization",
8899
8923
  "type": "boolean",
8924
+ "description": "Render only the rows in view instead of all of them. **On by default** - this is what keeps a 100,000-row grid responsive. Turn it off when a row's height cannot be known up front and must not be clipped, such as a variable-height master-detail panel. Expect the DOM to hold every row when you do.",
8900
8925
  "group": "common"
8901
8926
  },
8902
8927
  {
@@ -8913,6 +8938,13 @@ var GENERATED_UI_SURFACE = {
8913
8938
  "description": "Size each row to its own content instead of a fixed height: cell text wraps and the row grows to fit the tallest cell. Rows are measured after they render, so this works with virtualization - `rowHeight` (or 30) is the estimate used before a row has been measured, which keeps the scrollbar stable while you scroll into new rows. Costs a measurement pass per row, so prefer a fixed `rowHeight` when your content is uniform. Ignored when `rowHeight` is a function (you are already supplying per-row heights).",
8914
8939
  "group": "common"
8915
8940
  },
8941
+ {
8942
+ "key": "rowResize",
8943
+ "label": "Row Resize",
8944
+ "type": "boolean",
8945
+ "description": "Let the user drag a row's bottom edge to change its height. **Off by default**, because a resizable row needs somewhere to grab and most grids do not want a drag target on every row. The grid remembers the heights itself, so this works as a bare boolean - no `rowHeight` function required. Drag, or focus the grip and use Up/Down (Shift for 1px steps). Turning this on also turns on the **row header column** (* showRowNumbers), because that is where the grip lives and where a spreadsheet puts it - a drag target on the edge of a data cell works but reads as an accident. An explicit `showRowNumbers={false}` still wins; the grip then falls back to the row's first cell, and a column of your own carrying `cellClass: 'sv-row-gutter'` is used ahead of either. Ignored under `autoRowHeight`, where the content decides the height and a manual one would immediately be overwritten. For full control of the heights - persisting them, sharing them between grids - pass a function-valued and use the `rowResize` action directly.",
8946
+ "group": "common"
8947
+ },
8916
8948
  {
8917
8949
  "key": "headerHeight",
8918
8950
  "label": "Header Height",
@@ -8924,6 +8956,7 @@ var GENERATED_UI_SURFACE = {
8924
8956
  "key": "overscan",
8925
8957
  "label": "Overscan",
8926
8958
  "type": "number",
8959
+ "description": "Extra rows rendered above and below the viewport, so fast scrolling does not reach empty space before the next batch renders. Defaults to 8. Raise it for very tall rows, lower it to trim DOM work.",
8927
8960
  "group": "common"
8928
8961
  },
8929
8962
  {
@@ -8937,18 +8970,21 @@ var GENERATED_UI_SURFACE = {
8937
8970
  "key": "columnVirtualization",
8938
8971
  "label": "Column Virtualization",
8939
8972
  "type": "boolean",
8973
+ "description": "Render only the columns in view, the horizontal counterpart of `virtualization`. **On by default**, which is what makes a 100-column grid scroll smoothly. It recycles column DOM nodes, so it cannot coexist with sticky pinned columns - turn it off if you need pinning to survive horizontal scrolling.",
8940
8974
  "group": "common"
8941
8975
  },
8942
8976
  {
8943
8977
  "key": "columnOverscan",
8944
8978
  "label": "Column Overscan",
8945
8979
  "type": "number",
8980
+ "description": "Extra columns rendered either side of the viewport when `columnVirtualization` is on. Defaults to 3.",
8946
8981
  "group": "common"
8947
8982
  },
8948
8983
  {
8949
8984
  "key": "columnWidth",
8950
8985
  "label": "Column Width",
8951
8986
  "type": "number",
8987
+ "description": "Fallback width in pixels for columns whose `ColumnDef` sets no `width`. Defaults to 140.",
8952
8988
  "group": "common"
8953
8989
  },
8954
8990
  {
@@ -8965,6 +9001,13 @@ var GENERATED_UI_SURFACE = {
8965
9001
  "description": "When `true`, columns are scaled proportionally so their total width fills the viewport (no empty space on the right). Disabled by default - explicit `width` values are used as-is. User resizes still win once they happen.",
8966
9002
  "group": "common"
8967
9003
  },
9004
+ {
9005
+ "key": "columnResize",
9006
+ "label": "Column Resize",
9007
+ "type": "boolean",
9008
+ "description": "Let the user drag a column's edge to change its width. **Off by default**, so `width` means the width you asked for until you say otherwise. Turn it on for grids the reader is meant to arrange - a spreadsheet, a dense report, anything with columns whose content varies in length. Leave it off for layouts you control, and for columns that must keep their size: a row-number gutter, a checkbox column, an icon column. It is grid-wide rather than per-column: there is no `resizable: false` on a single column definition. `api.autosizeColumn()`, `fitColumns` and programmatic width changes work either way - this only governs the drag handle. The handles come from the `columnResize` action, loaded on demand: a grid that leaves this off never fetches that code.",
9009
+ "group": "common"
9010
+ },
8968
9011
  {
8969
9012
  "key": "responsive",
8970
9013
  "label": "Responsive",
@@ -8982,12 +9025,21 @@ var GENERATED_UI_SURFACE = {
8982
9025
  "key": "showFilterRow",
8983
9026
  "label": "Show Filter Row",
8984
9027
  "type": "boolean",
9028
+ "description": "Show the always-visible filter row under the header. Explicitly setting this wins over `filterMode`; unset, it appears only when `filterMode` is `'row'`.",
8985
9029
  "group": "common"
8986
9030
  },
8987
9031
  {
8988
9032
  "key": "enableCellSelection",
8989
9033
  "label": "Enable Cell Selection",
8990
9034
  "type": "boolean",
9035
+ "description": "Cell selection - click to select, drag or shift-click to extend to a range, which is what clipboard copy and the range fill handle operate on. Unset, it follows `selectionMode` (default `'both'`, so this is on). `selectable` is the shortcut alias and wins over it.",
9036
+ "group": "common"
9037
+ },
9038
+ {
9039
+ "key": "moveCells",
9040
+ "label": "Move Cells",
9041
+ "type": "boolean",
9042
+ "description": "Excel-style drag-and-drop of a selected cell range: grab the range's border and drag it somewhere else to MOVE the values there, or hold Ctrl (Cmd on macOS) to COPY them instead. The modifier is read at drop time, so it can be pressed or released mid-drag. On by default whenever cell selection is on, matching the fill handle. Set `false` to keep a border pointerdown starting a fresh selection, which is what it did before this existed. The grab strip is the outer 4px of the range border, so a pointerdown anywhere further inside still starts a new selection. A drop is refused outright - nothing changes - when the destination would fall outside the grid, or when any source or destination cell is read-only. It does not move the part that fits and silently drop the rest.",
8991
9043
  "group": "common"
8992
9044
  },
8993
9045
  {
@@ -9016,6 +9068,7 @@ var GENERATED_UI_SURFACE = {
9016
9068
  "key": "enableInlineEditing",
9017
9069
  "label": "Enable Inline Editing",
9018
9070
  "type": "boolean",
9071
+ "description": "Inline cell editing: F2 or double-click opens an editor in the active cell, Enter commits, Esc cancels. Off by default. A column still needs an `editorType` to pick its editor (text, number, date, checkbox, list, ...); without one it gets a plain text editor. `editable` is the shortcut alias and wins over this.",
9019
9072
  "group": "common"
9020
9073
  },
9021
9074
  {
@@ -9029,6 +9082,14 @@ var GENERATED_UI_SURFACE = {
9029
9082
  "key": "enableRowSummaries",
9030
9083
  "label": "Enable Row Summaries",
9031
9084
  "type": "boolean",
9085
+ "description": "Append a sticky footer row aggregating every filtered row: the sum of a numeric column, `Count: N` otherwise. Choose a different aggregate per column with that column's own `summary` option, or set it to `false` there to leave the cell blank. Off by default. `summary` is the shortcut alias and wins when both are set. <SvGrid {data} {columns} summary />",
9086
+ "group": "common"
9087
+ },
9088
+ {
9089
+ "key": "summary",
9090
+ "label": "Summary",
9091
+ "type": "boolean",
9092
+ "description": "Shortcut alias for . Wins over it when both are set, the same precedence `selectable` has over `enableCellSelection`.",
9032
9093
  "group": "common"
9033
9094
  },
9034
9095
  {
@@ -9056,7 +9117,7 @@ var GENERATED_UI_SURFACE = {
9056
9117
  "key": "columnMenuTabs",
9057
9118
  "label": "Column Menu Tabs",
9058
9119
  "type": "boolean",
9059
- "description": "Render the header column menu (⋮) as a tabbed popover - **General**, **Filter**, and **Columns** tabs (the AG-Grid layout). Defaults to `false`, which keeps the flat menu (actions list + \"Choose columns\" submenu).",
9120
+ "description": "Render the header column menu (⋮) as a tabbed popover - **General**, **Filter**, and **Columns** tabs (the tabbed layout). Defaults to `false`, which keeps the flat menu (actions list + \"Choose columns\" submenu).",
9060
9121
  "group": "common"
9061
9122
  },
9062
9123
  {
@@ -9336,7 +9397,8 @@ var GENERATED_UI_SURFACE = {
9336
9397
  {
9337
9398
  "key": "cellValueChange",
9338
9399
  "label": "Cell Value Change",
9339
- "prop": "onCellValueChange"
9400
+ "prop": "onCellValueChange",
9401
+ "description": "Fires after an inline edit commits, with the cell's old and new value and the row it belongs to. This is where you persist the change. The grid has already applied the edit to its own state by the time this runs, so it is a notification, not a veto - reject a value with the column's `valueParser` or a validation rule instead."
9340
9402
  },
9341
9403
  {
9342
9404
  "key": "activeCellChange",
@@ -15818,7 +15880,7 @@ function hasFieldConditions(schema) {
15818
15880
  *
15819
15881
  * `version.test.ts` asserts this matches `package.json`, so the two cannot drift.
15820
15882
  */
15821
- var SVGRID_VERSION = "2.6.4";
15883
+ var SVGRID_VERSION = "3.0.0";
15822
15884
  //#endregion
15823
15885
  //#region src/studio/emit-project.ts
15824
15886
  var has = (blocks, kind) => blocks.some((b) => b.config.kind === kind);
package/dist/pivot.d.ts CHANGED
@@ -30,8 +30,11 @@
30
30
  * ```
31
31
  */
32
32
  import type { ColumnDef, CellFormatConfig, RowData, TableFeatures } from '@svgrid/grid';
33
+ /** Built-in pivot measures, named in {@link PivotValueConfig}. */
33
34
  export type PivotAggregatorId = 'sum' | 'avg' | 'min' | 'max' | 'count' | 'countDistinct' | 'first' | 'last';
35
+ /** A custom measure: reduce the values under one cell to the number to display. */
34
36
  export type PivotAggregator = (values: ReadonlyArray<unknown>) => unknown;
37
+ /** One measure: the field to aggregate and how to aggregate it. */
35
38
  export type PivotValueConfig<TData> = {
36
39
  /** Row field whose values get aggregated. */
37
40
  field: keyof TData & string;
@@ -42,6 +45,7 @@ export type PivotValueConfig<TData> = {
42
45
  /** Optional cell formatter. */
43
46
  format?: CellFormatConfig;
44
47
  };
48
+ /** A pivot definition: the row axis, the column axis, and the measures at their intersections. */
45
49
  export type PivotConfig<TData> = {
46
50
  /** Outer-most first. Each entry becomes one level of row grouping. */
47
51
  rows: ReadonlyArray<keyof TData & string>;
@@ -60,6 +64,7 @@ export type PivotConfig<TData> = {
60
64
  /** Optional sort for row-axis values per dim level (defaults to alpha). */
61
65
  rowSort?: (a: unknown, b: unknown, level: number) => number;
62
66
  };
67
+ /** What a pivot row represents - a group header, a subtotal, a leaf, or the grand total. */
63
68
  export type PivotRowKind = 'group' | 'subtotal' | 'leaf' | 'grandTotal';
64
69
  /**
65
70
  * Shape of one entry in `result.rows`. The first-column label lives at
@@ -87,10 +92,16 @@ export type PivotRow = {
87
92
  /** Aggregated value cells - keyed by leaf column id. */
88
93
  [columnId: string]: unknown;
89
94
  };
95
+ /** A built pivot: the rows to display, and the generated column definitions for its column axis. */
90
96
  export type PivotResult<TFeatures extends TableFeatures> = {
91
97
  rows: PivotRow[];
92
98
  columns: Array<ColumnDef<TFeatures, PivotRow>>;
93
99
  };
100
+ /**
101
+ * Build a pivot table from flat rows: cross the row axis with the column axis,
102
+ * aggregate each intersection, and return rows plus generated columns ready to
103
+ * hand to `<SvGrid>`.
104
+ */
94
105
  export declare function createPivotModel<TFeatures extends TableFeatures, TData extends RowData>(data: ReadonlyArray<TData>, config: PivotConfig<TData>): PivotResult<TFeatures>;
95
106
  /**
96
107
  * Public registry of built-in aggregators. Useful for surfacing the
package/dist/pivot.js CHANGED
@@ -233,7 +233,7 @@ parentId) {
233
233
  // regardless of `rowSubtotals` so the grouping hierarchy and the
234
234
  // expand/collapse parent chain stay intact; the flag only controls whether
235
235
  // the header carries its aggregate (subtotal) values or renders as a
236
- // label-only row. This matches Excel / AG Grid, where hiding subtotals never
236
+ // label-only row. This matches Excel, where hiding subtotals never
237
237
  // removes a grouping level from the row axis.
238
238
  const isRealGroup = node.level > 0 && node.level < rowFields.length;
239
239
  let nextParentId = parentId;
@@ -259,6 +259,11 @@ parentId) {
259
259
  }
260
260
  }
261
261
  // ------------------------------------------------------------ public API
262
+ /**
263
+ * Build a pivot table from flat rows: cross the row axis with the column axis,
264
+ * aggregate each intersection, and return rows plus generated columns ready to
265
+ * hand to `<SvGrid>`.
266
+ */
262
267
  export function createPivotModel(data, config) {
263
268
  if (config.values.length === 0) {
264
269
  throw new Error('pivot: at least one value config is required');
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Register the Enterprise selection bar. Idempotent - safe to call from every
3
+ * component that uses `selectionBar`, or once at app start. Also invoked by
4
+ * {@link installEnterprise} so wiring the Pro API turns the bar on too.
5
+ */
6
+ export declare function enableSelectionBar(): void;
7
+ export { default as SvGridSelectionBar } from './SvGridSelectionBar.svelte';
@@ -0,0 +1,42 @@
1
+ /**
2
+ * selection bar - registers the Enterprise bulk-action bar with the grid, so
3
+ * `<SvGrid selectionBar={...}>` floats a bar over the rows while any are
4
+ * selected: the count, the actions that apply to the whole selection, an
5
+ * overflow menu once there are more than a handful, and a clear button.
6
+ *
7
+ * The grid ships the `selectionBar` prop and its config types for free; the
8
+ * *renderer* (SvGridSelectionBar) is Pro and plugs in through the grid's
9
+ * `registerSelectionBarView` seam. Without it the grid shows a short upsell
10
+ * note where the bar would be.
11
+ *
12
+ * Soft-gated like the rest of Enterprise: it works without a license key but
13
+ * the grid shows the "unlicensed" watermark + a one-time console nudge.
14
+ *
15
+ * ```ts
16
+ * import { setLicenseKey, enableSelectionBar } from '@svgrid/enterprise'
17
+ * setLicenseKey('YOUR-KEY')
18
+ * enableSelectionBar()
19
+ * // then:
20
+ * // <SvGrid {data} {columns} showRowSelection
21
+ * // selectionBar={{ position: 'bottom', actions: [...] }} />
22
+ * ```
23
+ */
24
+ import { registerSelectionBarView } from '@svgrid/grid';
25
+ import { isLicenseKeySet } from './license';
26
+ import { emitUnlicensedNudge } from './watermark';
27
+ import SvGridSelectionBar from './SvGridSelectionBar.svelte';
28
+ let enabled = false;
29
+ /**
30
+ * Register the Enterprise selection bar. Idempotent - safe to call from every
31
+ * component that uses `selectionBar`, or once at app start. Also invoked by
32
+ * {@link installEnterprise} so wiring the Pro API turns the bar on too.
33
+ */
34
+ export function enableSelectionBar() {
35
+ if (enabled)
36
+ return;
37
+ enabled = true;
38
+ registerSelectionBarView(SvGridSelectionBar);
39
+ if (!isLicenseKeySet())
40
+ emitUnlicensedNudge();
41
+ }
42
+ export { default as SvGridSelectionBar } from './SvGridSelectionBar.svelte';
@@ -195,6 +195,12 @@ function blockMarkup(entity, schemaVar, typeName, block, resolve, ctx = { hasRec
195
195
  return fire ? `(${param}) => { ${base}${fire} }` : `(${param}) => ${base}`;
196
196
  };
197
197
  const lines = [`data={${dataExpr}}`, `columns={${colVar}}`, `loading={${tree || grouped ? '!allRowsReady' : 'view.loading'}}`, `loadingOverlay`, `emptyMessage=${JSON.stringify(emptyMsg)}`, `fitColumns`];
198
+ // Emitted explicitly in BOTH directions on purpose. The grid now defaults
199
+ // this off and takes `summary` as a shortcut, but generated apps install
200
+ // the PUBLISHED @svgrid/grid, where the default is still on and `summary`
201
+ // does not exist yet. Switching to `summary` (or dropping the `false`)
202
+ // before that release would silently give every generated screen the
203
+ // wrong footer. Revisit once the grid carrying the flip is published.
198
204
  lines.push(`enableRowSummaries={${cfg.rowSummaries ? 'true' : 'false'}}`);
199
205
  if (cfg.striped)
200
206
  lines.push(`zebraRows`);