apex-grid 3.4.0 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +439 -0
- package/LICENSE.md +125 -0
- package/README.md +107 -14
- package/components/cell.d.ts +30 -4
- package/components/cell.js +199 -53
- package/components/cell.js.map +1 -1
- package/components/filter-row.d.ts +2 -0
- package/components/filter-row.js +82 -28
- package/components/filter-row.js.map +1 -1
- package/components/grid.d.ts +257 -20
- package/components/grid.js +463 -99
- package/components/grid.js.map +1 -1
- package/components/group-header-row.js +28 -25
- package/components/group-header-row.js.map +1 -1
- package/components/header-row.d.ts +7 -5
- package/components/header-row.js +19 -9
- package/components/header-row.js.map +1 -1
- package/components/header.js +36 -22
- package/components/header.js.map +1 -1
- package/components/row.d.ts +19 -3
- package/components/row.js +96 -22
- package/components/row.js.map +1 -1
- package/components/toolbar.js +2 -1
- package/components/toolbar.js.map +1 -1
- package/components/virtualizer.d.ts +45 -1
- package/components/virtualizer.js +184 -3
- package/components/virtualizer.js.map +1 -1
- package/controllers/dom.d.ts +4 -4
- package/controllers/dom.js +40 -22
- package/controllers/dom.js.map +1 -1
- package/controllers/editing.d.ts +104 -37
- package/controllers/editing.js +230 -78
- package/controllers/editing.js.map +1 -1
- package/controllers/expansion.d.ts +14 -5
- package/controllers/expansion.js +24 -1
- package/controllers/expansion.js.map +1 -1
- package/controllers/filter.d.ts +10 -2
- package/controllers/filter.js +62 -17
- package/controllers/filter.js.map +1 -1
- package/controllers/history.d.ts +45 -8
- package/controllers/history.js +58 -20
- package/controllers/history.js.map +1 -1
- package/controllers/navigation.d.ts +68 -13
- package/controllers/navigation.js +196 -51
- package/controllers/navigation.js.map +1 -1
- package/controllers/pagination.d.ts +6 -0
- package/controllers/pagination.js +10 -2
- package/controllers/pagination.js.map +1 -1
- package/controllers/reorder.js +42 -24
- package/controllers/reorder.js.map +1 -1
- package/controllers/resize.d.ts +17 -2
- package/controllers/resize.js +16 -6
- package/controllers/resize.js.map +1 -1
- package/controllers/row-pin.d.ts +20 -2
- package/controllers/row-pin.js +16 -9
- package/controllers/row-pin.js.map +1 -1
- package/controllers/row-reorder.d.ts +31 -11
- package/controllers/row-reorder.js +117 -37
- package/controllers/row-reorder.js.map +1 -1
- package/controllers/selection.d.ts +11 -4
- package/controllers/selection.js +26 -11
- package/controllers/selection.js.map +1 -1
- package/controllers/sort.d.ts +22 -2
- package/controllers/sort.js +29 -23
- package/controllers/sort.js.map +1 -1
- package/controllers/state.d.ts +65 -10
- package/controllers/state.js +86 -6
- package/controllers/state.js.map +1 -1
- package/controllers/tree.d.ts +15 -10
- package/controllers/tree.js +0 -0
- package/controllers/tree.js.map +1 -1
- package/custom-elements.json +3589 -452
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/highlight.css +15 -8
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/ApexGrid.html +660 -0
- package/docs/classes/ApexGridPaginator.html +36 -0
- package/docs/classes/ApexGridToolbar.html +67 -0
- package/docs/functions/localize.html +2 -2
- package/docs/functions/setup.html +1 -2
- package/docs/hierarchy.html +1 -1
- package/docs/index.html +105 -15
- package/docs/interfaces/ApexCellValidationFailedEvent.html +3 -2
- package/docs/interfaces/ApexCellValueChangedEvent.html +4 -2
- package/docs/interfaces/ApexCellValueChangingEvent.html +3 -2
- package/docs/interfaces/ApexColumnMovedEvent.html +2 -2
- package/docs/interfaces/ApexColumnMovingEvent.html +1 -1
- package/docs/interfaces/ApexDetailContext.html +2 -2
- package/docs/interfaces/ApexGridEventMap.html +9 -6
- package/docs/interfaces/ApexRowEditEndedEvent.html +2 -1
- package/docs/interfaces/ApexRowEditStartedEvent.html +2 -1
- package/docs/interfaces/ApexRowMovingEvent.html +9 -3
- package/docs/interfaces/ApexRowPinningEvent.html +1 -1
- package/docs/interfaces/ApexTreeRowExpandedEvent.html +4 -1
- package/docs/interfaces/ApexTreeRowExpandingEvent.html +4 -1
- package/docs/interfaces/BaseApexCellContext.html +1 -1
- package/docs/interfaces/BaseApexEditorContext.html +1 -1
- package/docs/interfaces/BaseColumnConfiguration.html +3 -3
- package/docs/interfaces/BaseFilterExpression.html +2 -2
- package/docs/interfaces/CSVExportOptions.html +13 -5
- package/docs/interfaces/DataPipelineConfiguration.html +2 -2
- package/docs/interfaces/EditingHistoryConfiguration.html +1 -1
- package/docs/interfaces/ExportFormat.html +2 -2
- package/docs/interfaces/ExportOptions.html +5 -3
- package/docs/interfaces/GridExpansionConfiguration.html +6 -2
- package/docs/interfaces/GridRowPinningConfiguration.html +1 -1
- package/docs/interfaces/GridRowReorderingConfiguration.html +2 -2
- package/docs/interfaces/PaginationConfiguration.html +1 -1
- package/docs/interfaces/PaginationState.html +1 -1
- package/docs/interfaces/SetStateResult.html +3 -2
- package/docs/interfaces/ValidatorContext.html +7 -2
- package/docs/media/_token-values.scss +118 -0
- package/docs/media/package.json +5 -5
- package/docs/media/state-persistence.html +0 -10
- package/docs/modules.html +1 -1
- package/docs/types/DataPipelineParams.html +2 -2
- package/docs/types/EditMode.html +2 -2
- package/docs/types/ExportSource.html +6 -4
- package/docs/types/GridLocaleText.html +1 -1
- package/docs/types/OperandKeys.html +9 -0
- package/docs/types/PaginationMode.html +1 -1
- package/docs/variables/EN_LOCALE.html +3 -3
- package/docs/variables/esLocale.html +1 -1
- package/i18n/en.d.ts +19 -0
- package/i18n/en.js +19 -0
- package/i18n/en.js.map +1 -1
- package/i18n/es.js +19 -0
- package/i18n/es.js.map +1 -1
- package/index.d.ts +2 -0
- package/index.js +2 -0
- package/index.js.map +1 -1
- package/internal/column-types.d.ts +27 -1
- package/internal/column-types.js +75 -49
- package/internal/column-types.js.map +1 -1
- package/internal/constants.d.ts +1 -2
- package/internal/constants.js +0 -4
- package/internal/constants.js.map +1 -1
- package/internal/document-styles.d.ts +30 -0
- package/internal/document-styles.js +48 -0
- package/internal/document-styles.js.map +1 -0
- package/internal/export.d.ts +39 -7
- package/internal/export.js +35 -34
- package/internal/export.js.map +1 -1
- package/internal/feature-module.d.ts +82 -3
- package/internal/feature-module.js +11 -0
- package/internal/feature-module.js.map +1 -1
- package/internal/index.d.ts +6 -4
- package/internal/index.js +5 -3
- package/internal/index.js.map +1 -1
- package/internal/normalize-case.d.ts +8 -1
- package/internal/normalize-case.js +3 -2
- package/internal/normalize-case.js.map +1 -1
- package/internal/state-snapshot.d.ts +60 -8
- package/internal/state-snapshot.js +87 -19
- package/internal/state-snapshot.js.map +1 -1
- package/internal/types.d.ts +17 -2
- package/internal/types.js.map +1 -1
- package/internal/utils.d.ts +48 -6
- package/internal/utils.js +35 -21
- package/internal/utils.js.map +1 -1
- package/internal/validators.js +1 -0
- package/internal/validators.js.map +1 -1
- package/operations/filter/operands/number.js +9 -6
- package/operations/filter/operands/number.js.map +1 -1
- package/operations/filter/operands/string.js +2 -3
- package/operations/filter/operands/string.js.map +1 -1
- package/operations/filter/types.d.ts +13 -1
- package/operations/filter/types.js.map +1 -1
- package/operations/filter.d.ts +6 -0
- package/operations/filter.js +23 -7
- package/operations/filter.js.map +1 -1
- package/operations/quick-filter.js +2 -5
- package/operations/quick-filter.js.map +1 -1
- package/operations/sort.d.ts +21 -2
- package/operations/sort.js +41 -14
- package/operations/sort.js.map +1 -1
- package/package.json +8 -4
- package/setup.d.ts +23 -11
- package/setup.js +19 -21
- package/setup.js.map +1 -1
- package/styles/_common.css.js +1 -1
- package/styles/_common.css.js.map +1 -1
- package/styles/_token-values.css.d.ts +1 -0
- package/styles/_token-values.css.js +3 -0
- package/styles/_token-values.css.js.map +1 -0
- package/styles/_tokens.css.js +1 -1
- package/styles/_tokens.css.js.map +1 -1
- package/styles/body-cell/body-cell.css.js +1 -1
- package/styles/body-cell/body-cell.css.js.map +1 -1
- package/styles/body-cell/cell-renderers.css.js +1 -1
- package/styles/body-cell/cell-renderers.css.js.map +1 -1
- package/styles/body-row/body-row.css.js +1 -1
- package/styles/body-row/body-row.css.js.map +1 -1
- package/styles/document-tokens.css.d.ts +1 -0
- package/styles/document-tokens.css.js +3 -0
- package/styles/document-tokens.css.js.map +1 -0
- package/styles/filter-row/filter-row.css.js +1 -1
- package/styles/filter-row/filter-row.css.js.map +1 -1
- package/styles/grid/_grid.base.css.js +1 -1
- package/styles/grid/_grid.base.css.js.map +1 -1
- package/styles/grid/grid.css.js +1 -1
- package/styles/grid/grid.css.js.map +1 -1
- package/styles/group-header-row/group-header-row.css.js +1 -1
- package/styles/group-header-row/group-header-row.css.js.map +1 -1
- package/styles/header-cell/header-cell.css.js +1 -1
- package/styles/header-cell/header-cell.css.js.map +1 -1
- package/styles/header-row/header-row.base.css.js +1 -1
- package/styles/header-row/header-row.base.css.js.map +1 -1
- package/styles/paginator/paginator.css.js +1 -1
- package/styles/paginator/paginator.css.js.map +1 -1
- package/styles/toolbar/toolbar.css.js +1 -1
- package/styles/toolbar/toolbar.css.js.map +1 -1
- package/tokens.css +78 -0
- package/LICENSE +0 -80
- package/docs/media/LICENSE +0 -80
- package/docs/media/_tokens.scss +0 -193
package/internal/export.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { dateFormatter, parseDate } from './column-types.js';
|
|
2
|
+
import { getDisplayColumns, isNumericColumn } from './utils.js';
|
|
2
3
|
export function resolveExportColumns(grid, opts) {
|
|
3
4
|
const all = getDisplayColumns(grid.columns).filter((column) => !column.hidden && column.exportable !== false);
|
|
4
5
|
if (!opts.columns?.length)
|
|
@@ -11,25 +12,32 @@ export function resolveExportRows(grid, source = 'view') {
|
|
|
11
12
|
case 'all':
|
|
12
13
|
return grid.data;
|
|
13
14
|
case 'page':
|
|
14
|
-
return grid.pageItems;
|
|
15
|
-
case 'selected':
|
|
16
|
-
|
|
15
|
+
return stateOf(grid)?.dataRows(grid.pageItems) ?? grid.pageItems;
|
|
16
|
+
case 'selected': {
|
|
17
|
+
const selected = new Set(grid.selectedRows);
|
|
18
|
+
const inView = viewRows(grid).filter((row) => selected.delete(row));
|
|
19
|
+
return [...inView, ...selected];
|
|
20
|
+
}
|
|
17
21
|
default:
|
|
18
|
-
return grid
|
|
22
|
+
return viewRows(grid);
|
|
19
23
|
}
|
|
20
24
|
}
|
|
25
|
+
function viewRows(grid) {
|
|
26
|
+
return stateOf(grid)?.viewRecords(grid.dataView) ?? grid.dataView;
|
|
27
|
+
}
|
|
28
|
+
function stateOf(grid) {
|
|
29
|
+
return grid.stateController;
|
|
30
|
+
}
|
|
21
31
|
export function getColumnLabel(column) {
|
|
22
32
|
return column.headerText ?? String(column.key);
|
|
23
33
|
}
|
|
24
|
-
const DATE_STYLE_MAP = {
|
|
25
|
-
short: 'short',
|
|
26
|
-
medium: 'medium',
|
|
27
|
-
long: 'long',
|
|
28
|
-
full: 'full',
|
|
29
|
-
};
|
|
30
34
|
export function defaultExportFormat(column, value) {
|
|
31
35
|
if (value === null || value === undefined)
|
|
32
36
|
return '';
|
|
37
|
+
if (isNumericColumn(column)) {
|
|
38
|
+
const n = Number(value);
|
|
39
|
+
return Number.isFinite(n) ? n : '';
|
|
40
|
+
}
|
|
33
41
|
switch (column.type) {
|
|
34
42
|
case 'select': {
|
|
35
43
|
const found = column.options?.find((option) => {
|
|
@@ -45,37 +53,29 @@ export function defaultExportFormat(column, value) {
|
|
|
45
53
|
}
|
|
46
54
|
return typeof value === 'number' || typeof value === 'boolean' ? value : String(value);
|
|
47
55
|
}
|
|
48
|
-
case 'date':
|
|
49
|
-
|
|
50
|
-
return value;
|
|
51
|
-
const parsed = new Date(value);
|
|
52
|
-
return Number.isNaN(parsed.getTime()) ? String(value) : parsed;
|
|
53
|
-
}
|
|
56
|
+
case 'date':
|
|
57
|
+
return parseDate(value) ?? (typeof value === 'object' ? '' : String(value));
|
|
54
58
|
case 'boolean':
|
|
55
|
-
return
|
|
56
|
-
case 'number':
|
|
57
|
-
case 'rating': {
|
|
58
|
-
const n = Number(value);
|
|
59
|
-
return Number.isFinite(n) ? n : '';
|
|
60
|
-
}
|
|
59
|
+
return value === true;
|
|
61
60
|
default:
|
|
62
61
|
return typeof value === 'number' || typeof value === 'boolean' ? value : String(value);
|
|
63
62
|
}
|
|
64
63
|
}
|
|
65
64
|
export function resolveExportValue(column, row, opts) {
|
|
66
65
|
const raw = row[column.key];
|
|
67
|
-
|
|
66
|
+
const value = opts.formatter
|
|
67
|
+
? opts.formatter(column, raw, row)
|
|
68
|
+
: defaultExportFormat(column, raw);
|
|
69
|
+
return value instanceof Date && Number.isNaN(value.getTime()) ? '' : value;
|
|
68
70
|
}
|
|
69
71
|
export function formatDateForCSV(column, value) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return value.toISOString();
|
|
76
|
-
}
|
|
72
|
+
return Number.isNaN(value.getTime()) ? '' : dateFormatter(column.format).format(value);
|
|
73
|
+
}
|
|
74
|
+
const FORMULA_LEADING = /^(?![+-]\d*\.?\d+$)[=+\-@\t\r]/;
|
|
75
|
+
export function escapeFormula(value) {
|
|
76
|
+
return typeof value === 'string' && FORMULA_LEADING.test(value) ? `'${value}` : value;
|
|
77
77
|
}
|
|
78
|
-
function escapeCSVCell(value, delimiter) {
|
|
78
|
+
export function escapeCSVCell(value, delimiter) {
|
|
79
79
|
if (value === null || value === undefined || value === '')
|
|
80
80
|
return '';
|
|
81
81
|
const text = value instanceof Date ? value.toISOString() : String(value);
|
|
@@ -86,11 +86,12 @@ export function buildCSV(grid, opts = {}) {
|
|
|
86
86
|
const delimiter = opts.delimiter ?? ',';
|
|
87
87
|
const newline = opts.newline ?? '\r\n';
|
|
88
88
|
const includeHeader = opts.includeHeader ?? true;
|
|
89
|
+
const cell = (value) => escapeCSVCell(opts.escapeFormulas === false ? value : escapeFormula(value), delimiter);
|
|
89
90
|
const columns = resolveExportColumns(grid, opts);
|
|
90
91
|
const rows = resolveExportRows(grid, opts.source);
|
|
91
92
|
const lines = [];
|
|
92
93
|
if (includeHeader) {
|
|
93
|
-
lines.push(columns.map((column) =>
|
|
94
|
+
lines.push(columns.map((column) => cell(getColumnLabel(column))).join(delimiter));
|
|
94
95
|
}
|
|
95
96
|
for (const row of rows) {
|
|
96
97
|
const cells = columns.map((column) => {
|
|
@@ -98,7 +99,7 @@ export function buildCSV(grid, opts = {}) {
|
|
|
98
99
|
if (value instanceof Date) {
|
|
99
100
|
value = formatDateForCSV(column, value);
|
|
100
101
|
}
|
|
101
|
-
return
|
|
102
|
+
return cell(value);
|
|
102
103
|
});
|
|
103
104
|
lines.push(cells.join(delimiter));
|
|
104
105
|
}
|
package/internal/export.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/internal/export.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AA+E/C,MAAM,UAAU,oBAAoB,CAClC,IAAiB,EACjB,IAAsB;IAEtB,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAChD,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,KAAK,KAAK,CAC1D,CAAC;IACF,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM;QAAE,OAAO,GAAG,CAAC;IACtC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,OAAoB,CAAC,CAAC;IAChD,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AACtD,CAAC;AAKD,MAAM,UAAU,iBAAiB,CAC/B,IAAiB,EACjB,SAAuB,MAAM;IAE7B,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,KAAK;YACR,OAAO,IAAI,CAAC,IAAI,CAAC;QACnB,KAAK,MAAM;YACT,OAAO,IAAI,CAAC,SAAS,CAAC;QACxB,KAAK,UAAU;YACb,OAAO,IAAI,CAAC,YAAY,CAAC;QAC3B;YACE,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;AACH,CAAC;AAKD,MAAM,UAAU,cAAc,CAAmB,MAA8B;IAC7E,OAAO,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,cAAc,GAAsE;IACxF,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;CACb,CAAC;AAOF,MAAM,UAAU,mBAAmB,CACjC,MAA8B,EAC9B,KAAc;IAEd,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACrD,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;gBAC5C,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;oBAC9D,OAAQ,MAA6B,CAAC,KAAK,KAAK,KAAK,CAAC;gBACxD,CAAC;gBACD,OAAO,MAAM,KAAK,KAAK,CAAC;YAC1B,CAAC,CAAC,CAAC;YACH,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;gBAC3D,MAAM,KAAK,GAAI,KAA6B,CAAC,KAAK,CAAC;gBACnD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;oBAAE,OAAO,KAAK,CAAC;YAClE,CAAC;YACD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACzF,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,IAAI,KAAK,YAAY,IAAI;gBAAE,OAAO,KAAK,CAAC;YACxC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,KAAwB,CAAC,CAAC;YAClD,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QACjE,CAAC;QACD,KAAK,SAAS;YACZ,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;QACxB,KAAK,QAAQ,CAAC;QACd,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YACxB,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACrC,CAAC;QACD;YACE,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3F,CAAC;AACH,CAAC;AAMD,MAAM,UAAU,kBAAkB,CAChC,MAA8B,EAC9B,GAAM,EACN,IAAsB;IAEtB,MAAM,GAAG,GAAI,GAA+B,CAAC,MAAM,CAAC,GAAa,CAAC,CAAC;IACnE,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC9F,CAAC;AAGD,MAAM,UAAU,gBAAgB,CAC9B,MAA8B,EAC9B,KAAW;IAEX,MAAM,KAAK,GAAG,cAAc,CAAC,MAAM,CAAC,MAAM,IAAI,QAAQ,CAAC,CAAC;IACxD,IAAI,CAAC;QACH,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAChF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,KAAsB,EAAE,SAAiB;IAC9D,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,EAAE,CAAC;IACrE,MAAM,IAAI,GAAG,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACzE,MAAM,YAAY,GAChB,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/F,OAAO,YAAY,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/D,CAAC;AAUD,MAAM,UAAU,QAAQ,CACtB,IAAiB,EACjB,OAA4B,EAAE;IAE9B,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,GAAG,CAAC;IACxC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC;IACvC,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC;IACjD,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAElD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,aAAa,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CACR,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAC1F,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YACnC,IAAI,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;YAClD,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;gBAC1B,KAAK,GAAG,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAC1C,CAAC;YACD,OAAO,aAAa,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACpC,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjC,OAAO,IAAI,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC;AACrD,CAAC;AAUD,MAAM,UAAU,YAAY,CAC1B,QAAgB,EAChB,OAA4B,EAC5B,QAAgB;IAEhB,IAAI,OAAO,QAAQ,KAAK,WAAW,IAAI,OAAO,GAAG,EAAE,eAAe,KAAK,UAAU;QAAE,OAAO;IAG1F,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,OAAmB,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IACjE,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IAC3C,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC;IAClB,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,MAAM,CAAC,KAAK,EAAE,CAAC;IACf,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,UAAU,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;AAChD,CAAC","sourcesContent":["import type { ApexGrid } from '../components/grid.js';\nimport type { ColumnConfiguration, ColumnDateFormat, Keys } from './types.js';\nimport { getDisplayColumns } from './utils.js';\n\n/**\n * Primitive cell values supported by the export pipeline.\n *\n * @remarks\n * Returned by the default formatter and accepted from user-supplied formatters.\n * `Date` is preserved (not stringified) so that XLSX export can write it as a\n * native date cell instead of inline text.\n */\nexport type ExportCellValue = string | number | boolean | Date | null | undefined;\n\n/**\n * Which row set should drive the export.\n *\n * - `'view'` (default) — post-filter, post-sort rows across all pages.\n * - `'all'` — the raw `data` array as supplied by the consumer.\n * - `'page'` — only the rows in the current page slice.\n * - `'selected'` — the current row selection (insertion order).\n */\nexport type ExportSource = 'view' | 'all' | 'page' | 'selected';\n\n/**\n * Options shared by all export targets.\n */\nexport interface ExportOptions<T extends object> {\n /** Output filename, without extension. Defaults to `'data'`. */\n filename?: string;\n /** Row set to export. Defaults to `'view'`. */\n source?: ExportSource;\n /**\n * Column keys to include. When omitted, every visible non-hidden column with\n * `exportable !== false` is exported, in display order.\n */\n columns?: ReadonlyArray<Keys<T>>;\n /** Whether to emit a header row. Defaults to `true`. */\n includeHeader?: boolean;\n /**\n * Per-cell value formatter. Receives the column configuration, the raw value\n * from the record, and the record itself. Return one of {@link ExportCellValue}\n * (return a `Date` to keep date typing in XLSX).\n */\n formatter?: (column: ColumnConfiguration<T>, value: unknown, row: T) => ExportCellValue;\n}\n\n/**\n * Options for {@link ApexGrid.exportToCSV}.\n */\nexport interface CSVExportOptions<T extends object> extends ExportOptions<T> {\n /** Field delimiter. Defaults to `','`. */\n delimiter?: string;\n /**\n * Prepend a UTF-8 byte-order mark so Excel auto-detects the encoding when\n * opening the file. Defaults to `true`.\n */\n bom?: boolean;\n /** Line separator. Defaults to `'\\r\\n'` (RFC 4180). */\n newline?: string;\n}\n\n/**\n * Describes an export format offered by the grid's toolbar menu.\n *\n * @remarks\n * The toolbar renders one menu item per entry returned by\n * {@link ApexGrid.exportFormats} and dispatches the chosen `id` to\n * {@link ApexGrid.exportAs}. The community grid offers `'csv'`; derived grids\n * (e.g. `apex-grid-enterprise`) extend the list (e.g. with `'xlsx'`).\n */\nexport interface ExportFormat {\n /** Stable format identifier, e.g. `'csv'`. */\n id: string;\n /** Menu item label, e.g. `'Export CSV'`. */\n label: string;\n}\n\n/**\n * Resolves the columns that should appear in the export, in display order.\n */\nexport function resolveExportColumns<T extends object>(\n grid: ApexGrid<T>,\n opts: ExportOptions<T>\n): Array<ColumnConfiguration<T>> {\n const all = getDisplayColumns(grid.columns).filter(\n (column) => !column.hidden && column.exportable !== false\n );\n if (!opts.columns?.length) return all;\n const keys = new Set(opts.columns as Keys<T>[]);\n return all.filter((column) => keys.has(column.key));\n}\n\n/**\n * Resolves the rows that should appear in the export.\n */\nexport function resolveExportRows<T extends object>(\n grid: ApexGrid<T>,\n source: ExportSource = 'view'\n): ReadonlyArray<T> {\n switch (source) {\n case 'all':\n return grid.data;\n case 'page':\n return grid.pageItems;\n case 'selected':\n return grid.selectedRows;\n default:\n return grid.dataView;\n }\n}\n\n/**\n * Returns the column's display label, used as the header cell value.\n */\nexport function getColumnLabel<T extends object>(column: ColumnConfiguration<T>): string {\n return column.headerText ?? String(column.key);\n}\n\nconst DATE_STYLE_MAP: Record<ColumnDateFormat, Intl.DateTimeFormatOptions['dateStyle']> = {\n short: 'short',\n medium: 'medium',\n long: 'long',\n full: 'full',\n};\n\n/**\n * Default cell-value formatter. Mirrors the on-screen rendering for each\n * column type while keeping primitive types primitive (so number/boolean/date\n * survive into XLSX as native cells instead of strings).\n */\nexport function defaultExportFormat<T extends object>(\n column: ColumnConfiguration<T>,\n value: unknown\n): ExportCellValue {\n if (value === null || value === undefined) return '';\n switch (column.type) {\n case 'select': {\n const found = column.options?.find((option) => {\n if (option && typeof option === 'object' && 'value' in option) {\n return (option as { value: unknown }).value === value;\n }\n return option === value;\n });\n if (found && typeof found === 'object' && 'label' in found) {\n const label = (found as { label?: unknown }).label;\n if (typeof label === 'string' && label.length > 0) return label;\n }\n return typeof value === 'number' || typeof value === 'boolean' ? value : String(value);\n }\n case 'date': {\n if (value instanceof Date) return value;\n const parsed = new Date(value as string | number);\n return Number.isNaN(parsed.getTime()) ? String(value) : parsed;\n }\n case 'boolean':\n return Boolean(value);\n case 'number':\n case 'rating': {\n const n = Number(value);\n return Number.isFinite(n) ? n : '';\n }\n default:\n return typeof value === 'number' || typeof value === 'boolean' ? value : String(value);\n }\n}\n\n/**\n * Resolves the export value for a single cell, applying the user-supplied\n * formatter when present and falling back to {@link defaultExportFormat}.\n */\nexport function resolveExportValue<T extends object>(\n column: ColumnConfiguration<T>,\n row: T,\n opts: ExportOptions<T>\n): ExportCellValue {\n const raw = (row as Record<string, unknown>)[column.key as string];\n return opts.formatter ? opts.formatter(column, raw, row) : defaultExportFormat(column, raw);\n}\n\n/** Formats a `Date` into the configured date style for CSV output. */\nexport function formatDateForCSV<T extends object>(\n column: ColumnConfiguration<T>,\n value: Date\n): string {\n const style = DATE_STYLE_MAP[column.format ?? 'medium'];\n try {\n return new Intl.DateTimeFormat(undefined, { dateStyle: style }).format(value);\n } catch {\n return value.toISOString();\n }\n}\n\nfunction escapeCSVCell(value: ExportCellValue, delimiter: string): string {\n if (value === null || value === undefined || value === '') return '';\n const text = value instanceof Date ? value.toISOString() : String(value);\n const needsQuoting =\n text.includes(delimiter) || text.includes('\"') || text.includes('\\n') || text.includes('\\r');\n return needsQuoting ? `\"${text.replace(/\"/g, '\"\"')}\"` : text;\n}\n\n/**\n * Builds the CSV string for the grid without triggering a download.\n *\n * @remarks\n * Useful when consumers want to ship the bytes through their own transport\n * (clipboard, HTTP upload). The {@link ApexGrid.exportToCSV} method calls\n * this and then triggers a browser download.\n */\nexport function buildCSV<T extends object>(\n grid: ApexGrid<T>,\n opts: CSVExportOptions<T> = {}\n): string {\n const delimiter = opts.delimiter ?? ',';\n const newline = opts.newline ?? '\\r\\n';\n const includeHeader = opts.includeHeader ?? true;\n const columns = resolveExportColumns(grid, opts);\n const rows = resolveExportRows(grid, opts.source);\n\n const lines: string[] = [];\n if (includeHeader) {\n lines.push(\n columns.map((column) => escapeCSVCell(getColumnLabel(column), delimiter)).join(delimiter)\n );\n }\n for (const row of rows) {\n const cells = columns.map((column) => {\n let value = resolveExportValue(column, row, opts);\n if (value instanceof Date) {\n value = formatDateForCSV(column, value);\n }\n return escapeCSVCell(value, delimiter);\n });\n lines.push(cells.join(delimiter));\n }\n\n const body = lines.join(newline);\n return opts.bom === false ? body : `\\uFEFF${body}`;\n}\n\n/**\n * Triggers a browser download for the given payload.\n *\n * @remarks\n * Falls back to a no-op when called outside the browser (during SSR or unit\n * tests on JSDOM without a body), so consumers can still call the public\n * export API safely.\n */\nexport function downloadBlob(\n filename: string,\n content: string | Uint8Array,\n mimeType: string\n): void {\n if (typeof document === 'undefined' || typeof URL?.createObjectURL !== 'function') return;\n // BlobPart accepts both string and Uint8Array; the cast quiets TS' strict\n // overload resolution which prefers ArrayBufferView only.\n const blob = new Blob([content as BlobPart], { type: mimeType });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = filename;\n anchor.style.display = 'none';\n document.body.appendChild(anchor);\n anchor.click();\n document.body.removeChild(anchor);\n setTimeout(() => URL.revokeObjectURL(url), 0);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/internal/export.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ApexGrid } from '../components/grid.js';\nimport type { StateController } from '../controllers/state.js';\nimport { dateFormatter, parseDate } from './column-types.js';\nimport type { ColumnConfiguration, Keys } from './types.js';\nimport { getDisplayColumns, isNumericColumn } from './utils.js';\n\n/**\n * Primitive cell values supported by the export pipeline.\n *\n * @remarks\n * Returned by the default formatter and accepted from user-supplied formatters.\n * `Date` is preserved (not stringified) so that XLSX export can write it as a\n * native date cell instead of inline text.\n */\nexport type ExportCellValue = string | number | boolean | Date | null | undefined;\n\n/**\n * Which row set should drive the export.\n *\n * - `'view'` (default): post-filter, post-sort rows across all pages.\n * - `'all'`: the raw `data` array as supplied by the consumer.\n * - `'page'`: only the rows in the current page slice.\n * - `'selected'`: the selected rows, in view order. Selected rows the\n * current view hides (filtered out or under a collapsed parent) follow,\n * in the order they were selected.\n */\nexport type ExportSource = 'view' | 'all' | 'page' | 'selected';\n\n/**\n * Options shared by all export targets.\n */\nexport interface ExportOptions<T extends object> {\n /** Output filename, without extension. Defaults to `'data'`. */\n filename?: string;\n /** Row set to export. Defaults to `'view'`. */\n source?: ExportSource;\n /**\n * Narrows the export to these column keys. The list filters the visible\n * columns with `exportable !== false`, so a hidden or non-exportable key is\n * skipped, and the output keeps display order rather than the list's order.\n * When omitted, every visible exportable column is exported.\n */\n columns?: ReadonlyArray<Keys<T>>;\n /** Whether to emit a header row. Defaults to `true`. */\n includeHeader?: boolean;\n /**\n * Per-cell value formatter. Receives the column configuration, the raw value\n * from the record, and the record itself. Return one of {@link ExportCellValue}\n * (return a `Date` to keep date typing in XLSX).\n */\n formatter?: (column: ColumnConfiguration<T>, value: unknown, row: T) => ExportCellValue;\n}\n\n/**\n * Options for {@link ApexGrid.exportToCSV}.\n */\nexport interface CSVExportOptions<T extends object> extends ExportOptions<T> {\n /** Field delimiter. Defaults to `','`. */\n delimiter?: string;\n /**\n * Prepend a UTF-8 byte-order mark so Excel auto-detects the encoding when\n * opening the file. Defaults to `true`.\n */\n bom?: boolean;\n /** Line separator. Defaults to `'\\r\\n'` (RFC 4180). */\n newline?: string;\n /**\n * Prefix an apostrophe to a text cell or header that starts with `=`, `+`,\n * `-`, `@`, a tab or a carriage return, so a spreadsheet opening the file\n * shows it as text instead of evaluating it as a formula. Numbers and text\n * that is a plain signed decimal (`-5`, `+1.5`) are written as they are.\n * Pass `false` to write such text unchanged. Defaults to `true`.\n */\n escapeFormulas?: boolean;\n}\n\n/**\n * Describes an export format offered by the grid's toolbar menu.\n *\n * @remarks\n * The toolbar renders one menu item per entry returned by\n * {@link ApexGrid.exportFormats} and dispatches the chosen `id` to\n * {@link ApexGrid.exportAs}. The community grid offers `'csv'`; derived grids\n * (e.g. `apex-grid-enterprise`) extend the list (e.g. with `'xlsx'`).\n */\nexport interface ExportFormat {\n /** Stable format identifier, e.g. `'csv'`. */\n id: string;\n /** Menu item label, e.g. `'Export CSV'`. */\n label: string;\n}\n\n/**\n * Resolves the columns that should appear in the export, in display order.\n */\nexport function resolveExportColumns<T extends object>(\n grid: ApexGrid<T>,\n opts: ExportOptions<T>\n): Array<ColumnConfiguration<T>> {\n const all = getDisplayColumns(grid.columns).filter(\n (column) => !column.hidden && column.exportable !== false\n );\n if (!opts.columns?.length) return all;\n const keys = new Set(opts.columns as Keys<T>[]);\n return all.filter((column) => keys.has(column.key));\n}\n\n/**\n * Resolves the rows that should appear in the export. The `view` and `page`\n * sources hold only data records: rows a feature module synthesized into the\n * view (group headers, a grand-total row) are dropped, see\n * {@link StateController.isDataRow}. `view` also writes the leaves of\n * collapsed groups ({@link StateController.viewRecords}); `page` writes what\n * the page shows.\n */\nexport function resolveExportRows<T extends object>(\n grid: ApexGrid<T>,\n source: ExportSource = 'view'\n): ReadonlyArray<T> {\n switch (source) {\n case 'all':\n return grid.data;\n case 'page':\n return stateOf(grid)?.dataRows(grid.pageItems) ?? grid.pageItems;\n case 'selected': {\n // Selection is a Set in the order rows were picked; write the rows the\n // way the screen lists them, then any the view hides (filtered out or\n // under a collapsed parent).\n const selected = new Set(grid.selectedRows);\n const inView = viewRows(grid).filter((row) => selected.delete(row));\n return [...inView, ...selected];\n }\n default:\n return viewRows(grid);\n }\n}\n\nfunction viewRows<T extends object>(grid: ApexGrid<T>): ReadonlyArray<T> {\n return stateOf(grid)?.viewRecords(grid.dataView) ?? grid.dataView;\n}\n\nfunction stateOf<T extends object>(grid: ApexGrid<T>): StateController<T> | undefined {\n return (grid as unknown as { stateController?: StateController<T> }).stateController;\n}\n\n/**\n * Returns the column's display label, used as the header cell value.\n */\nexport function getColumnLabel<T extends object>(column: ColumnConfiguration<T>): string {\n return column.headerText ?? String(column.key);\n}\n\n/**\n * Default cell-value formatter. Mirrors the on-screen rendering for each\n * column type while keeping primitive types primitive (so number/boolean/date\n * survive into XLSX as native cells instead of strings).\n */\nexport function defaultExportFormat<T extends object>(\n column: ColumnConfiguration<T>,\n value: unknown\n): ExportCellValue {\n if (value === null || value === undefined) return '';\n if (isNumericColumn(column)) {\n const n = Number(value);\n return Number.isFinite(n) ? n : '';\n }\n switch (column.type) {\n case 'select': {\n const found = column.options?.find((option) => {\n if (option && typeof option === 'object' && 'value' in option) {\n return (option as { value: unknown }).value === value;\n }\n return option === value;\n });\n if (found && typeof found === 'object' && 'label' in found) {\n const label = (found as { label?: unknown }).label;\n if (typeof label === 'string' && label.length > 0) return label;\n }\n return typeof value === 'number' || typeof value === 'boolean' ? value : String(value);\n }\n // The cell's own parse: a 'YYYY-MM-DD' string is the local date the cell\n // shows (not UTC midnight), and an invalid Date is empty, as on screen.\n // Text that is no date stays text.\n case 'date':\n return parseDate(value) ?? (typeof value === 'object' ? '' : String(value));\n // Checked only for `true`, like the cell's checkbox and the filter.\n case 'boolean':\n return value === true;\n default:\n return typeof value === 'number' || typeof value === 'boolean' ? value : String(value);\n }\n}\n\n/**\n * Resolves the export value for a single cell, applying the user-supplied\n * formatter when present and falling back to {@link defaultExportFormat}.\n */\nexport function resolveExportValue<T extends object>(\n column: ColumnConfiguration<T>,\n row: T,\n opts: ExportOptions<T>\n): ExportCellValue {\n const raw = (row as Record<string, unknown>)[column.key as string];\n const value = opts.formatter\n ? opts.formatter(column, raw, row)\n : defaultExportFormat(column, raw);\n // An invalid Date from a user formatter has no text or serial to write.\n return value instanceof Date && Number.isNaN(value.getTime()) ? '' : value;\n}\n\n/** Formats a `Date` into the configured date style for CSV output. */\nexport function formatDateForCSV<T extends object>(\n column: ColumnConfiguration<T>,\n value: Date\n): string {\n return Number.isNaN(value.getTime()) ? '' : dateFormatter(column.format).format(value);\n}\n\n/** Text a spreadsheet would evaluate: a formula trigger first, not a signed decimal. */\nconst FORMULA_LEADING = /^(?![+-]\\d*\\.?\\d+$)[=+\\-@\\t\\r]/;\n\n/**\n * Prefixes an apostrophe to text a spreadsheet would read as a formula (it\n * starts with `=`, `+`, `-`, `@`, a tab or a carriage return and is not a\n * plain signed decimal), the usual way to keep it text. Any other value is\n * returned as is, a boxed `String` included: an export formatter returns one\n * to mark text it means to keep raw, such as a formula source. CSV export\n * and clipboard copy share this rule.\n */\nexport function escapeFormula<V>(value: V): V | string {\n return typeof value === 'string' && FORMULA_LEADING.test(value) ? `'${value}` : value;\n}\n\n/**\n * Quotes one delimited-text field when it holds the delimiter, a double quote\n * or a line break (doubling inner quotes), the convention CSV files and\n * spreadsheet clipboards share. Blank values become an empty field.\n */\nexport function escapeCSVCell(value: ExportCellValue, delimiter: string): string {\n if (value === null || value === undefined || value === '') return '';\n const text = value instanceof Date ? value.toISOString() : String(value);\n const needsQuoting =\n text.includes(delimiter) || text.includes('\"') || text.includes('\\n') || text.includes('\\r');\n return needsQuoting ? `\"${text.replace(/\"/g, '\"\"')}\"` : text;\n}\n\n/**\n * Builds the CSV string for the grid without triggering a download.\n *\n * @remarks\n * Useful when consumers want to ship the bytes through their own transport\n * (clipboard, HTTP upload). The {@link ApexGrid.exportToCSV} method calls\n * this and then triggers a browser download.\n */\nexport function buildCSV<T extends object>(\n grid: ApexGrid<T>,\n opts: CSVExportOptions<T> = {}\n): string {\n const delimiter = opts.delimiter ?? ',';\n const newline = opts.newline ?? '\\r\\n';\n const includeHeader = opts.includeHeader ?? true;\n const cell = (value: ExportCellValue) =>\n escapeCSVCell(opts.escapeFormulas === false ? value : escapeFormula(value), delimiter);\n const columns = resolveExportColumns(grid, opts);\n const rows = resolveExportRows(grid, opts.source);\n\n const lines: string[] = [];\n if (includeHeader) {\n lines.push(columns.map((column) => cell(getColumnLabel(column))).join(delimiter));\n }\n for (const row of rows) {\n const cells = columns.map((column) => {\n let value = resolveExportValue(column, row, opts);\n if (value instanceof Date) {\n value = formatDateForCSV(column, value);\n }\n return cell(value);\n });\n lines.push(cells.join(delimiter));\n }\n\n const body = lines.join(newline);\n return opts.bom === false ? body : `\\uFEFF${body}`;\n}\n\n/**\n * Triggers a browser download for the given payload.\n *\n * @remarks\n * Falls back to a no-op when called outside the browser (during SSR or unit\n * tests on JSDOM without a body), so consumers can still call the public\n * export API safely.\n */\nexport function downloadBlob(\n filename: string,\n content: string | Uint8Array,\n mimeType: string\n): void {\n if (typeof document === 'undefined' || typeof URL?.createObjectURL !== 'function') return;\n // BlobPart accepts both string and Uint8Array; the cast quiets TS' strict\n // overload resolution which prefers ArrayBufferView only.\n const blob = new Blob([content as BlobPart], { type: mimeType });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = filename;\n anchor.style.display = 'none';\n document.body.appendChild(anchor);\n anchor.click();\n document.body.removeChild(anchor);\n setTimeout(() => URL.revokeObjectURL(url), 0);\n}\n"]}
|
|
@@ -41,11 +41,38 @@ export interface GridFeatureModule<T extends object = any> {
|
|
|
41
41
|
* Controllers that don't implement this are skipped, so the community grid
|
|
42
42
|
* (which registers no modules) is unaffected.
|
|
43
43
|
*
|
|
44
|
+
* Transforms run in a fixed order set by {@link transformOrder}, not in the
|
|
45
|
+
* order modules were registered, because they do not commute (a grand-total
|
|
46
|
+
* row appended before grouping would itself be grouped).
|
|
47
|
+
*
|
|
44
48
|
* @remarks Unstable; part of `apex-grid/internal`.
|
|
45
49
|
*/
|
|
46
50
|
export interface RowTransformer<T extends object = any> {
|
|
47
51
|
/** Return the transformed rows. Must not mutate the input array in place. */
|
|
48
52
|
processRows(rows: ReadonlyArray<T>): T[];
|
|
53
|
+
/**
|
|
54
|
+
* Position of this transform in the module chain: lower runs first, ties keep
|
|
55
|
+
* registration order, unset means `0`. First-party values: grouping `100`,
|
|
56
|
+
* pivot `200`, grand-total row `1000`. Transforms that restructure the view
|
|
57
|
+
* come first; rows that summarise the finished view come last. Leaving it
|
|
58
|
+
* unset (`0`) runs the transform before grouping.
|
|
59
|
+
*/
|
|
60
|
+
readonly transformOrder?: number;
|
|
61
|
+
/**
|
|
62
|
+
* Whether `row` is one this transform synthesized (a group header, a total
|
|
63
|
+
* row) rather than a data record. Synthesized rows are kept out of row
|
|
64
|
+
* selection and export (see {@link StateController.isDataRow}). Leave it
|
|
65
|
+
* unset when the transform's output rows are the view's records (pivot).
|
|
66
|
+
*/
|
|
67
|
+
isSyntheticRow?(row: T): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* The data records a synthesized `row` stands for that the view does not
|
|
70
|
+
* also hold, in view order: a collapsed group header's leaves. Return an
|
|
71
|
+
* empty array when they are in the view too (an expanded group) or the row
|
|
72
|
+
* stands for none (a total row). Lets Select all and a `'view'` export
|
|
73
|
+
* cover collapsed groups (see {@link StateController.viewRecords}).
|
|
74
|
+
*/
|
|
75
|
+
hiddenRecords?(row: T): ReadonlyArray<T>;
|
|
49
76
|
}
|
|
50
77
|
/** Runtime type-guard for {@link RowTransformer}. */
|
|
51
78
|
export declare function isRowTransformer<T extends object>(controller: unknown): controller is RowTransformer<T>;
|
|
@@ -69,6 +96,12 @@ export interface PresentedRow {
|
|
|
69
96
|
readonly expanded?: boolean;
|
|
70
97
|
/** Shadow part for the container element; defaults to `group-row`. */
|
|
71
98
|
readonly part?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Parts used inside {@link content} that the row should re-export, so
|
|
101
|
+
* `apex-grid::part(name)` can style them. The container {@link part} is
|
|
102
|
+
* exported without being listed here.
|
|
103
|
+
*/
|
|
104
|
+
readonly exportParts?: ReadonlyArray<string>;
|
|
72
105
|
}
|
|
73
106
|
/**
|
|
74
107
|
* Optional capability a feature module's controller may implement to render
|
|
@@ -82,11 +115,56 @@ export interface RowPresenter<T extends object = any> {
|
|
|
82
115
|
}
|
|
83
116
|
/** Runtime type-guard for {@link RowPresenter}. */
|
|
84
117
|
export declare function isRowPresenter<T extends object>(controller: unknown): controller is RowPresenter<T>;
|
|
118
|
+
/** ARIA tree/expansion semantics a module can attach to a normal (cell-rendered) row. */
|
|
119
|
+
export interface RowAria {
|
|
120
|
+
/** 1-based `aria-level` for the row element. */
|
|
121
|
+
readonly level?: number;
|
|
122
|
+
/** `aria-expanded` for the row element; omit for non-expandable rows. */
|
|
123
|
+
readonly expanded?: boolean;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Optional capability a module's controller may implement to attach ARIA
|
|
127
|
+
* tree/expansion semantics (`aria-level` / `aria-expanded`) to rows that still
|
|
128
|
+
* render as a normal cell grid — unlike {@link RowPresenter}, which replaces the
|
|
129
|
+
* cells with full-width content. Used by pivoting's expandable row groups, whose
|
|
130
|
+
* parent rows must keep showing per-column aggregate values. Returns `null` for
|
|
131
|
+
* rows the module does not own.
|
|
132
|
+
*
|
|
133
|
+
* @remarks Unstable; part of `apex-grid/internal`.
|
|
134
|
+
*/
|
|
135
|
+
export interface RowAriaProvider<T extends object = any> {
|
|
136
|
+
describeRow(row: T, ctx: RowPresenterContext<T>): RowAria | null;
|
|
137
|
+
}
|
|
138
|
+
/** Runtime type-guard for {@link RowAriaProvider}. */
|
|
139
|
+
export declare function isRowAriaProvider<T extends object>(controller: unknown): controller is RowAriaProvider<T>;
|
|
140
|
+
/**
|
|
141
|
+
* Optional capability a module's controller may implement to label the
|
|
142
|
+
* spreadsheet coordinate hints (`coordinateHints`): the row-number gutter and
|
|
143
|
+
* the column letters. A module whose references address the data rather than
|
|
144
|
+
* the view (the enterprise formula engine) answers with the coordinates a
|
|
145
|
+
* reference reads, so the hints stay true through sort, filter, paging, hidden
|
|
146
|
+
* columns and column moves. Return `null` for no label, or `undefined` to leave
|
|
147
|
+
* the default (view position) in place.
|
|
148
|
+
*
|
|
149
|
+
* @remarks Unstable; part of `apex-grid/internal`.
|
|
150
|
+
*/
|
|
151
|
+
export interface CoordinateLabeler<T extends object = any> {
|
|
152
|
+
/** The gutter label for a row. */
|
|
153
|
+
rowCoordinate(row: T): string | null | undefined;
|
|
154
|
+
/** The letter label for a column key. */
|
|
155
|
+
columnCoordinate(key: string): string | null | undefined;
|
|
156
|
+
}
|
|
157
|
+
/** Runtime type-guard for {@link CoordinateLabeler}. */
|
|
158
|
+
export declare function isCoordinateLabeler<T extends object>(controller: unknown): controller is CoordinateLabeler<T>;
|
|
85
159
|
/** Per-cell context handed to a {@link CellDecorator}. */
|
|
86
160
|
export interface CellDecoratorContext<T extends object = any> {
|
|
87
161
|
/** The row's backing data (or a synthesized row object). */
|
|
88
162
|
readonly row: T;
|
|
89
|
-
/**
|
|
163
|
+
/**
|
|
164
|
+
* Index of the row within the current page/view (matches `host.pageItems`),
|
|
165
|
+
* or `-1` for a row rendered in a pinned band, which is outside that view.
|
|
166
|
+
* Key pinned-row state by {@link row} instead.
|
|
167
|
+
*/
|
|
90
168
|
readonly rowIndex: number;
|
|
91
169
|
/** The cell's column configuration. */
|
|
92
170
|
readonly column: ColumnConfiguration<T>;
|
|
@@ -180,7 +258,8 @@ export declare function isCellInteractionHandler<T extends object>(controller: u
|
|
|
180
258
|
* / {@link StateController.restoreModuleState}, driven by `ApexGrid.getState` /
|
|
181
259
|
* `ApexGrid.setState`). The grid collects each implementer's
|
|
182
260
|
* {@link serializeState} output under the module's id and dispatches the
|
|
183
|
-
* matching value back via {@link restoreState} on restore.
|
|
261
|
+
* matching value back via {@link restoreState} on restore. Ids with no
|
|
262
|
+
* implementer are reported back by {@link StateController.restoreModuleState}.
|
|
184
263
|
*
|
|
185
264
|
* Controllers that don't implement this are skipped, so the community grid
|
|
186
265
|
* (which registers no modules) contributes nothing to a snapshot.
|
|
@@ -190,7 +269,7 @@ export declare function isCellInteractionHandler<T extends object>(controller: u
|
|
|
190
269
|
export interface SerializableModule {
|
|
191
270
|
/**
|
|
192
271
|
* Return a JSON-serializable snapshot of this module's restorable state
|
|
193
|
-
* (e.g.
|
|
272
|
+
* (e.g. the options the feature was configured with). Exclude transient/derived
|
|
194
273
|
* state and anything not JSON-safe (functions, DOM nodes).
|
|
195
274
|
*/
|
|
196
275
|
serializeState(): unknown;
|
|
@@ -8,6 +8,17 @@ export function isRowPresenter(controller) {
|
|
|
8
8
|
controller !== null &&
|
|
9
9
|
typeof controller.presentRow === 'function');
|
|
10
10
|
}
|
|
11
|
+
export function isRowAriaProvider(controller) {
|
|
12
|
+
return (typeof controller === 'object' &&
|
|
13
|
+
controller !== null &&
|
|
14
|
+
typeof controller.describeRow === 'function');
|
|
15
|
+
}
|
|
16
|
+
export function isCoordinateLabeler(controller) {
|
|
17
|
+
return (typeof controller === 'object' &&
|
|
18
|
+
controller !== null &&
|
|
19
|
+
typeof controller.rowCoordinate === 'function' &&
|
|
20
|
+
typeof controller.columnCoordinate === 'function');
|
|
21
|
+
}
|
|
11
22
|
export function isCellDecorator(controller) {
|
|
12
23
|
return (typeof controller === 'object' &&
|
|
13
24
|
controller !== null &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-module.js","sourceRoot":"","sources":["../../src/internal/feature-module.ts"],"names":[],"mappings":"AAwDA,MAAM,UAAU,gBAAgB,CAC9B,UAAmB;IAEnB,OAAO,CACL,OAAO,UAAU,KAAK,QAAQ;QAC9B,UAAU,KAAK,IAAI;QACnB,OAAQ,UAAgC,CAAC,WAAW,KAAK,UAAU,CACpE,CAAC;AACJ,CAAC;AAqCD,MAAM,UAAU,cAAc,CAC5B,UAAmB;IAEnB,OAAO,CACL,OAAO,UAAU,KAAK,QAAQ;QAC9B,UAAU,KAAK,IAAI;QACnB,OAAQ,UAA8B,CAAC,UAAU,KAAK,UAAU,CACjE,CAAC;AACJ,CAAC;AA+CD,MAAM,UAAU,eAAe,CAC7B,UAAmB;IAEnB,OAAO,CACL,OAAO,UAAU,KAAK,QAAQ;QAC9B,UAAU,KAAK,IAAI;QACnB,OAAQ,UAA+B,CAAC,YAAY,KAAK,UAAU,CACpE,CAAC;AACJ,CAAC;AAmBD,MAAM,UAAU,oBAAoB,CAAC,UAAmB;IACtD,OAAO,CACL,OAAO,UAAU,KAAK,QAAQ;QAC9B,UAAU,KAAK,IAAI;QACnB,OAAQ,UAAiC,CAAC,kBAAkB,KAAK,UAAU,CAC5E,CAAC;AACJ,CAAC;AAoCD,MAAM,UAAU,wBAAwB,CACtC,UAAmB;IAEnB,OAAO,CACL,OAAO,UAAU,KAAK,QAAQ;QAC9B,UAAU,KAAK,IAAI;QACnB,OAAQ,UAAwC,CAAC,qBAAqB,KAAK,UAAU,CACtF,CAAC;AACJ,CAAC;AA+BD,MAAM,UAAU,oBAAoB,CAAC,UAAmB;IACtD,OAAO,CACL,OAAO,UAAU,KAAK,QAAQ;QAC9B,UAAU,KAAK,IAAI;QACnB,OAAQ,UAAiC,CAAC,cAAc,KAAK,UAAU;QACvE,OAAQ,UAAiC,CAAC,YAAY,KAAK,UAAU,CACtE,CAAC;AACJ,CAAC","sourcesContent":["import type { ReactiveController, TemplateResult } from 'lit';\n// Type-only import — erased at runtime, so this does not create a runtime\n// import cycle with `controllers/state.ts` (which imports the guards below).\nimport type { StateController } from '../controllers/state.js';\nimport type { ColumnConfiguration, GridHost } from './types.js';\n\n/**\n * Extension point for layering optional features onto the grid without baking\n * them into the community build.\n *\n * A feature module contributes a {@link ReactiveController} that is constructed\n * alongside the grid's built-in controllers (see {@link StateController}). It is\n * the seam used by the first-party `@apexcharts/grid-enterprise` package; it is\n * intentionally minimal and additive so the community `<apex-grid>` element is\n * unaffected (it registers zero modules).\n *\n * @remarks This API lives under the unstable `apex-grid/internal` entry point.\n */\nexport interface GridFeatureModule<T extends object = any> {\n /**\n * Stable identifier, e.g. `'grouping'`. Used to de-duplicate modules and to\n * look the controller up later via {@link StateController.module}.\n */\n readonly id: string;\n\n /**\n * Construct the feature's controller. The controller is expected to register\n * itself with the host (typically `host.addController(this)` in its\n * constructor), exactly like the built-in controllers.\n *\n * @param host The grid host the controller drives.\n * @param state The owning {@link StateController}, passed so a module can\n * coordinate with cross-cutting grid state (e.g. request a cell-decoration\n * refresh via {@link StateController.bumpDecoration} or look up a peer\n * module). Modules that don't need it may ignore the argument.\n */\n create(host: GridHost<T>, state: StateController<T>): ReactiveController;\n}\n\n/**\n * Optional capability a feature module's controller may implement to transform\n * the row set *after* the built-in pipeline (filter → sort → tree) and *before*\n * pagination is sliced at render time. Lets a module inject or reorder rows —\n * e.g. synthesized group-header rows — in the rendered `dataView`.\n *\n * Controllers that don't implement this are skipped, so the community grid\n * (which registers no modules) is unaffected.\n *\n * @remarks Unstable; part of `apex-grid/internal`.\n */\nexport interface RowTransformer<T extends object = any> {\n /** Return the transformed rows. Must not mutate the input array in place. */\n processRows(rows: ReadonlyArray<T>): T[];\n}\n\n/** Runtime type-guard for {@link RowTransformer}. */\nexport function isRowTransformer<T extends object>(\n controller: unknown\n): controller is RowTransformer<T> {\n return (\n typeof controller === 'object' &&\n controller !== null &&\n typeof (controller as RowTransformer<T>).processRows === 'function'\n );\n}\n\n/** Per-row context handed to a {@link RowPresenter}. */\nexport interface RowPresenterContext<T extends object = any> {\n /** The grid's visible columns (post-reorder/visibility). */\n readonly columns: ReadonlyArray<ColumnConfiguration<T>>;\n /** Index of the row within the current page/view. */\n readonly rowIndex: number;\n}\n\n/**\n * A module-rendered, full-width row. Rendered inside a container that spans all\n * columns (`grid-column: 1 / -1`), mirroring the master-detail panel pattern.\n */\nexport interface PresentedRow {\n /** Template rendered inside the full-width container. */\n readonly content: TemplateResult;\n /** Optional 1-based `aria-level` applied to the row element. */\n readonly level?: number;\n /** Optional `aria-expanded` for the row element; omit for non-expandable rows. */\n readonly expanded?: boolean;\n /** Shadow part for the container element; defaults to `group-row`. */\n readonly part?: string;\n}\n\n/**\n * Optional capability a feature module's controller may implement to render\n * specific rows as full-width custom content (e.g. group headers) instead of\n * the normal cell grid. Returns `null` for rows the module does not own.\n *\n * @remarks Unstable; part of `apex-grid/internal`.\n */\nexport interface RowPresenter<T extends object = any> {\n presentRow(row: T, ctx: RowPresenterContext<T>): PresentedRow | null;\n}\n\n/** Runtime type-guard for {@link RowPresenter}. */\nexport function isRowPresenter<T extends object>(\n controller: unknown\n): controller is RowPresenter<T> {\n return (\n typeof controller === 'object' &&\n controller !== null &&\n typeof (controller as RowPresenter<T>).presentRow === 'function'\n );\n}\n\n/** Per-cell context handed to a {@link CellDecorator}. */\nexport interface CellDecoratorContext<T extends object = any> {\n /** The row's backing data (or a synthesized row object). */\n readonly row: T;\n /** Index of the row within the current page/view (matches `host.pageItems`). */\n readonly rowIndex: number;\n /** The cell's column configuration. */\n readonly column: ColumnConfiguration<T>;\n /** The cell's resolved value (`row[column.key]`). */\n readonly value: unknown;\n}\n\n/**\n * A set of host attributes a module asks the cell to reflect on itself. This is\n * the only thing a {@link CellDecorator} returns — styling is expressed by\n * keying CSS off these attributes (the cell ships an inert, variable-driven\n * `:host([data-range])` style; enterprise themes it via inheriting custom\n * properties).\n */\nexport interface CellDecoration {\n /**\n * Attributes to set on the decorated cell host. Use a `data-*` namespace\n * (e.g. `data-range`) so decoration never collides with the cell's built-in\n * reflected attributes (`active`, `editing`, `data-pinned`, …). A `null`/\n * `undefined` value removes the attribute. Attributes set on a previous\n * update that are absent here are removed automatically.\n */\n readonly attributes: Readonly<Record<string, string | null | undefined>>;\n}\n\n/**\n * Optional capability a feature module's controller may implement to decorate\n * individual cells with extra host attributes during the cell's own render\n * lifecycle — e.g. flagging the cells inside a selected range. Consulted per\n * cell via {@link StateController.decorateCell}; controllers that don't\n * implement it are skipped, so the community grid is unaffected.\n *\n * @remarks Unstable; part of `apex-grid/internal`.\n */\nexport interface CellDecorator<T extends object = any> {\n /** Return decoration for this cell, or `null` to leave it undecorated. */\n decorateCell(ctx: CellDecoratorContext<T>): CellDecoration | null;\n}\n\n/** Runtime type-guard for {@link CellDecorator}. */\nexport function isCellDecorator<T extends object>(\n controller: unknown\n): controller is CellDecorator<T> {\n return (\n typeof controller === 'object' &&\n controller !== null &&\n typeof (controller as CellDecorator<T>).decorateCell === 'function'\n );\n}\n\n/**\n * Optional capability a feature module's controller may implement to signal that\n * it provides a **column header menu** (opened from the header's kebab button).\n * The core header shows the kebab whenever a column is sortable or resizable, or\n * when a module reports `true` here, so a feature (e.g. the enterprise context\n * menu) can surface pin / hide / group / chart actions on any column. The module\n * owns the menu content itself (it opens on the `apex-grid-column-menu` event the\n * header dispatches). Inert for the community grid, which registers no modules.\n *\n * @remarks Unstable; part of `apex-grid/internal`.\n */\nexport interface ColumnMenuProvider {\n /** Whether the column-menu (kebab) button should be offered for columns. */\n providesColumnMenu(): boolean;\n}\n\n/** Runtime type-guard for {@link ColumnMenuProvider}. */\nexport function isColumnMenuProvider(controller: unknown): controller is ColumnMenuProvider {\n return (\n typeof controller === 'object' &&\n controller !== null &&\n typeof (controller as ColumnMenuProvider).providesColumnMenu === 'function'\n );\n}\n\n/** The kind of pointer interaction forwarded from a body cell. */\nexport type CellInteractionKind = 'down' | 'over' | 'up';\n\n/** A pointer interaction on a body cell, forwarded to feature modules. */\nexport interface CellInteraction<T extends object = any> {\n /** `down` on press, `over` while the pointer moves across cells, `up` on release. */\n readonly kind: CellInteractionKind;\n /** The cell's row data. */\n readonly row: T;\n /** Index of the row within the current page/view (matches `host.pageItems`). */\n readonly rowIndex: number;\n /** The cell's column configuration. */\n readonly column: ColumnConfiguration<T>;\n readonly shiftKey: boolean;\n readonly ctrlKey: boolean;\n readonly metaKey: boolean;\n /** The originating pointer event (e.g. to call `preventDefault`). */\n readonly originalEvent: PointerEvent;\n}\n\n/**\n * Optional capability a feature module's controller may implement to receive\n * pointer interactions on body cells (press / drag-over / release) — the seam a\n * range-selection feature uses to track a drag. The grid forwards interactions\n * only when at least one feature module is registered, so the community grid\n * pays nothing.\n *\n * @remarks Unstable; part of `apex-grid/internal`.\n */\nexport interface CellInteractionHandler<T extends object = any> {\n handleCellInteraction(interaction: CellInteraction<T>): void;\n}\n\n/** Runtime type-guard for {@link CellInteractionHandler}. */\nexport function isCellInteractionHandler<T extends object>(\n controller: unknown\n): controller is CellInteractionHandler<T> {\n return (\n typeof controller === 'object' &&\n controller !== null &&\n typeof (controller as CellInteractionHandler<T>).handleCellInteraction === 'function'\n );\n}\n\n/**\n * Optional capability a feature module's controller may implement so its state\n * participates in grid-state snapshots ({@link StateController.serializeModuleState}\n * / {@link StateController.restoreModuleState}, driven by `ApexGrid.getState` /\n * `ApexGrid.setState`). The grid collects each implementer's\n * {@link serializeState} output under the module's id and dispatches the\n * matching value back via {@link restoreState} on restore.\n *\n * Controllers that don't implement this are skipped, so the community grid\n * (which registers no modules) contributes nothing to a snapshot.\n *\n * @remarks Unstable; part of `apex-grid/internal`.\n */\nexport interface SerializableModule {\n /**\n * Return a JSON-serializable snapshot of this module's restorable state\n * (e.g. grouping's `groupBy` + aggregations). Exclude transient/derived\n * state and anything not JSON-safe (functions, DOM nodes).\n */\n serializeState(): unknown;\n /**\n * Restore module state from a value previously produced by\n * {@link serializeState}. Implementations should tolerate partial or\n * unexpected shapes (validate before applying) since the blob is opaque.\n */\n restoreState(data: unknown): void;\n}\n\n/** Runtime type-guard for {@link SerializableModule}. */\nexport function isSerializableModule(controller: unknown): controller is SerializableModule {\n return (\n typeof controller === 'object' &&\n controller !== null &&\n typeof (controller as SerializableModule).serializeState === 'function' &&\n typeof (controller as SerializableModule).restoreState === 'function'\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"feature-module.js","sourceRoot":"","sources":["../../src/internal/feature-module.ts"],"names":[],"mappings":"AAsFA,MAAM,UAAU,gBAAgB,CAC9B,UAAmB;IAEnB,OAAO,CACL,OAAO,UAAU,KAAK,QAAQ;QAC9B,UAAU,KAAK,IAAI;QACnB,OAAQ,UAAgC,CAAC,WAAW,KAAK,UAAU,CACpE,CAAC;AACJ,CAAC;AA2CD,MAAM,UAAU,cAAc,CAC5B,UAAmB;IAEnB,OAAO,CACL,OAAO,UAAU,KAAK,QAAQ;QAC9B,UAAU,KAAK,IAAI;QACnB,OAAQ,UAA8B,CAAC,UAAU,KAAK,UAAU,CACjE,CAAC;AACJ,CAAC;AAyBD,MAAM,UAAU,iBAAiB,CAC/B,UAAmB;IAEnB,OAAO,CACL,OAAO,UAAU,KAAK,QAAQ;QAC9B,UAAU,KAAK,IAAI;QACnB,OAAQ,UAAiC,CAAC,WAAW,KAAK,UAAU,CACrE,CAAC;AACJ,CAAC;AAqBD,MAAM,UAAU,mBAAmB,CACjC,UAAmB;IAEnB,OAAO,CACL,OAAO,UAAU,KAAK,QAAQ;QAC9B,UAAU,KAAK,IAAI;QACnB,OAAQ,UAAmC,CAAC,aAAa,KAAK,UAAU;QACxE,OAAQ,UAAmC,CAAC,gBAAgB,KAAK,UAAU,CAC5E,CAAC;AACJ,CAAC;AAmDD,MAAM,UAAU,eAAe,CAC7B,UAAmB;IAEnB,OAAO,CACL,OAAO,UAAU,KAAK,QAAQ;QAC9B,UAAU,KAAK,IAAI;QACnB,OAAQ,UAA+B,CAAC,YAAY,KAAK,UAAU,CACpE,CAAC;AACJ,CAAC;AAmBD,MAAM,UAAU,oBAAoB,CAAC,UAAmB;IACtD,OAAO,CACL,OAAO,UAAU,KAAK,QAAQ;QAC9B,UAAU,KAAK,IAAI;QACnB,OAAQ,UAAiC,CAAC,kBAAkB,KAAK,UAAU,CAC5E,CAAC;AACJ,CAAC;AAoCD,MAAM,UAAU,wBAAwB,CACtC,UAAmB;IAEnB,OAAO,CACL,OAAO,UAAU,KAAK,QAAQ;QAC9B,UAAU,KAAK,IAAI;QACnB,OAAQ,UAAwC,CAAC,qBAAqB,KAAK,UAAU,CACtF,CAAC;AACJ,CAAC;AAgCD,MAAM,UAAU,oBAAoB,CAAC,UAAmB;IACtD,OAAO,CACL,OAAO,UAAU,KAAK,QAAQ;QAC9B,UAAU,KAAK,IAAI;QACnB,OAAQ,UAAiC,CAAC,cAAc,KAAK,UAAU;QACvE,OAAQ,UAAiC,CAAC,YAAY,KAAK,UAAU,CACtE,CAAC;AACJ,CAAC","sourcesContent":["import type { ReactiveController, TemplateResult } from 'lit';\n// Type-only import — erased at runtime, so this does not create a runtime\n// import cycle with `controllers/state.ts` (which imports the guards below).\nimport type { StateController } from '../controllers/state.js';\nimport type { ColumnConfiguration, GridHost } from './types.js';\n\n/**\n * Extension point for layering optional features onto the grid without baking\n * them into the community build.\n *\n * A feature module contributes a {@link ReactiveController} that is constructed\n * alongside the grid's built-in controllers (see {@link StateController}). It is\n * the seam used by the first-party `@apexcharts/grid-enterprise` package; it is\n * intentionally minimal and additive so the community `<apex-grid>` element is\n * unaffected (it registers zero modules).\n *\n * @remarks This API lives under the unstable `apex-grid/internal` entry point.\n */\nexport interface GridFeatureModule<T extends object = any> {\n /**\n * Stable identifier, e.g. `'grouping'`. Used to de-duplicate modules and to\n * look the controller up later via {@link StateController.module}.\n */\n readonly id: string;\n\n /**\n * Construct the feature's controller. The controller is expected to register\n * itself with the host (typically `host.addController(this)` in its\n * constructor), exactly like the built-in controllers.\n *\n * @param host The grid host the controller drives.\n * @param state The owning {@link StateController}, passed so a module can\n * coordinate with cross-cutting grid state (e.g. request a cell-decoration\n * refresh via {@link StateController.bumpDecoration} or look up a peer\n * module). Modules that don't need it may ignore the argument.\n */\n create(host: GridHost<T>, state: StateController<T>): ReactiveController;\n}\n\n/**\n * Optional capability a feature module's controller may implement to transform\n * the row set *after* the built-in pipeline (filter → sort → tree) and *before*\n * pagination is sliced at render time. Lets a module inject or reorder rows —\n * e.g. synthesized group-header rows — in the rendered `dataView`.\n *\n * Controllers that don't implement this are skipped, so the community grid\n * (which registers no modules) is unaffected.\n *\n * Transforms run in a fixed order set by {@link transformOrder}, not in the\n * order modules were registered, because they do not commute (a grand-total\n * row appended before grouping would itself be grouped).\n *\n * @remarks Unstable; part of `apex-grid/internal`.\n */\nexport interface RowTransformer<T extends object = any> {\n /** Return the transformed rows. Must not mutate the input array in place. */\n processRows(rows: ReadonlyArray<T>): T[];\n\n /**\n * Position of this transform in the module chain: lower runs first, ties keep\n * registration order, unset means `0`. First-party values: grouping `100`,\n * pivot `200`, grand-total row `1000`. Transforms that restructure the view\n * come first; rows that summarise the finished view come last. Leaving it\n * unset (`0`) runs the transform before grouping.\n */\n readonly transformOrder?: number;\n\n /**\n * Whether `row` is one this transform synthesized (a group header, a total\n * row) rather than a data record. Synthesized rows are kept out of row\n * selection and export (see {@link StateController.isDataRow}). Leave it\n * unset when the transform's output rows are the view's records (pivot).\n */\n isSyntheticRow?(row: T): boolean;\n\n /**\n * The data records a synthesized `row` stands for that the view does not\n * also hold, in view order: a collapsed group header's leaves. Return an\n * empty array when they are in the view too (an expanded group) or the row\n * stands for none (a total row). Lets Select all and a `'view'` export\n * cover collapsed groups (see {@link StateController.viewRecords}).\n */\n hiddenRecords?(row: T): ReadonlyArray<T>;\n}\n\n/** Runtime type-guard for {@link RowTransformer}. */\nexport function isRowTransformer<T extends object>(\n controller: unknown\n): controller is RowTransformer<T> {\n return (\n typeof controller === 'object' &&\n controller !== null &&\n typeof (controller as RowTransformer<T>).processRows === 'function'\n );\n}\n\n/** Per-row context handed to a {@link RowPresenter}. */\nexport interface RowPresenterContext<T extends object = any> {\n /** The grid's visible columns (post-reorder/visibility). */\n readonly columns: ReadonlyArray<ColumnConfiguration<T>>;\n /** Index of the row within the current page/view. */\n readonly rowIndex: number;\n}\n\n/**\n * A module-rendered, full-width row. Rendered inside a container that spans all\n * columns (`grid-column: 1 / -1`), mirroring the master-detail panel pattern.\n */\nexport interface PresentedRow {\n /** Template rendered inside the full-width container. */\n readonly content: TemplateResult;\n /** Optional 1-based `aria-level` applied to the row element. */\n readonly level?: number;\n /** Optional `aria-expanded` for the row element; omit for non-expandable rows. */\n readonly expanded?: boolean;\n /** Shadow part for the container element; defaults to `group-row`. */\n readonly part?: string;\n /**\n * Parts used inside {@link content} that the row should re-export, so\n * `apex-grid::part(name)` can style them. The container {@link part} is\n * exported without being listed here.\n */\n readonly exportParts?: ReadonlyArray<string>;\n}\n\n/**\n * Optional capability a feature module's controller may implement to render\n * specific rows as full-width custom content (e.g. group headers) instead of\n * the normal cell grid. Returns `null` for rows the module does not own.\n *\n * @remarks Unstable; part of `apex-grid/internal`.\n */\nexport interface RowPresenter<T extends object = any> {\n presentRow(row: T, ctx: RowPresenterContext<T>): PresentedRow | null;\n}\n\n/** Runtime type-guard for {@link RowPresenter}. */\nexport function isRowPresenter<T extends object>(\n controller: unknown\n): controller is RowPresenter<T> {\n return (\n typeof controller === 'object' &&\n controller !== null &&\n typeof (controller as RowPresenter<T>).presentRow === 'function'\n );\n}\n\n/** ARIA tree/expansion semantics a module can attach to a normal (cell-rendered) row. */\nexport interface RowAria {\n /** 1-based `aria-level` for the row element. */\n readonly level?: number;\n /** `aria-expanded` for the row element; omit for non-expandable rows. */\n readonly expanded?: boolean;\n}\n\n/**\n * Optional capability a module's controller may implement to attach ARIA\n * tree/expansion semantics (`aria-level` / `aria-expanded`) to rows that still\n * render as a normal cell grid — unlike {@link RowPresenter}, which replaces the\n * cells with full-width content. Used by pivoting's expandable row groups, whose\n * parent rows must keep showing per-column aggregate values. Returns `null` for\n * rows the module does not own.\n *\n * @remarks Unstable; part of `apex-grid/internal`.\n */\nexport interface RowAriaProvider<T extends object = any> {\n describeRow(row: T, ctx: RowPresenterContext<T>): RowAria | null;\n}\n\n/** Runtime type-guard for {@link RowAriaProvider}. */\nexport function isRowAriaProvider<T extends object>(\n controller: unknown\n): controller is RowAriaProvider<T> {\n return (\n typeof controller === 'object' &&\n controller !== null &&\n typeof (controller as RowAriaProvider<T>).describeRow === 'function'\n );\n}\n\n/**\n * Optional capability a module's controller may implement to label the\n * spreadsheet coordinate hints (`coordinateHints`): the row-number gutter and\n * the column letters. A module whose references address the data rather than\n * the view (the enterprise formula engine) answers with the coordinates a\n * reference reads, so the hints stay true through sort, filter, paging, hidden\n * columns and column moves. Return `null` for no label, or `undefined` to leave\n * the default (view position) in place.\n *\n * @remarks Unstable; part of `apex-grid/internal`.\n */\nexport interface CoordinateLabeler<T extends object = any> {\n /** The gutter label for a row. */\n rowCoordinate(row: T): string | null | undefined;\n /** The letter label for a column key. */\n columnCoordinate(key: string): string | null | undefined;\n}\n\n/** Runtime type-guard for {@link CoordinateLabeler}. */\nexport function isCoordinateLabeler<T extends object>(\n controller: unknown\n): controller is CoordinateLabeler<T> {\n return (\n typeof controller === 'object' &&\n controller !== null &&\n typeof (controller as CoordinateLabeler<T>).rowCoordinate === 'function' &&\n typeof (controller as CoordinateLabeler<T>).columnCoordinate === 'function'\n );\n}\n\n/** Per-cell context handed to a {@link CellDecorator}. */\nexport interface CellDecoratorContext<T extends object = any> {\n /** The row's backing data (or a synthesized row object). */\n readonly row: T;\n /**\n * Index of the row within the current page/view (matches `host.pageItems`),\n * or `-1` for a row rendered in a pinned band, which is outside that view.\n * Key pinned-row state by {@link row} instead.\n */\n readonly rowIndex: number;\n /** The cell's column configuration. */\n readonly column: ColumnConfiguration<T>;\n /** The cell's resolved value (`row[column.key]`). */\n readonly value: unknown;\n}\n\n/**\n * A set of host attributes a module asks the cell to reflect on itself. This is\n * the only thing a {@link CellDecorator} returns — styling is expressed by\n * keying CSS off these attributes (the cell ships an inert, variable-driven\n * `:host([data-range])` style; enterprise themes it via inheriting custom\n * properties).\n */\nexport interface CellDecoration {\n /**\n * Attributes to set on the decorated cell host. Use a `data-*` namespace\n * (e.g. `data-range`) so decoration never collides with the cell's built-in\n * reflected attributes (`active`, `editing`, `data-pinned`, …). A `null`/\n * `undefined` value removes the attribute. Attributes set on a previous\n * update that are absent here are removed automatically.\n */\n readonly attributes: Readonly<Record<string, string | null | undefined>>;\n}\n\n/**\n * Optional capability a feature module's controller may implement to decorate\n * individual cells with extra host attributes during the cell's own render\n * lifecycle — e.g. flagging the cells inside a selected range. Consulted per\n * cell via {@link StateController.decorateCell}; controllers that don't\n * implement it are skipped, so the community grid is unaffected.\n *\n * @remarks Unstable; part of `apex-grid/internal`.\n */\nexport interface CellDecorator<T extends object = any> {\n /** Return decoration for this cell, or `null` to leave it undecorated. */\n decorateCell(ctx: CellDecoratorContext<T>): CellDecoration | null;\n}\n\n/** Runtime type-guard for {@link CellDecorator}. */\nexport function isCellDecorator<T extends object>(\n controller: unknown\n): controller is CellDecorator<T> {\n return (\n typeof controller === 'object' &&\n controller !== null &&\n typeof (controller as CellDecorator<T>).decorateCell === 'function'\n );\n}\n\n/**\n * Optional capability a feature module's controller may implement to signal that\n * it provides a **column header menu** (opened from the header's kebab button).\n * The core header shows the kebab whenever a column is sortable or resizable, or\n * when a module reports `true` here, so a feature (e.g. the enterprise context\n * menu) can surface pin / hide / group / chart actions on any column. The module\n * owns the menu content itself (it opens on the `apex-grid-column-menu` event the\n * header dispatches). Inert for the community grid, which registers no modules.\n *\n * @remarks Unstable; part of `apex-grid/internal`.\n */\nexport interface ColumnMenuProvider {\n /** Whether the column-menu (kebab) button should be offered for columns. */\n providesColumnMenu(): boolean;\n}\n\n/** Runtime type-guard for {@link ColumnMenuProvider}. */\nexport function isColumnMenuProvider(controller: unknown): controller is ColumnMenuProvider {\n return (\n typeof controller === 'object' &&\n controller !== null &&\n typeof (controller as ColumnMenuProvider).providesColumnMenu === 'function'\n );\n}\n\n/** The kind of pointer interaction forwarded from a body cell. */\nexport type CellInteractionKind = 'down' | 'over' | 'up';\n\n/** A pointer interaction on a body cell, forwarded to feature modules. */\nexport interface CellInteraction<T extends object = any> {\n /** `down` on press, `over` while the pointer moves across cells, `up` on release. */\n readonly kind: CellInteractionKind;\n /** The cell's row data. */\n readonly row: T;\n /** Index of the row within the current page/view (matches `host.pageItems`). */\n readonly rowIndex: number;\n /** The cell's column configuration. */\n readonly column: ColumnConfiguration<T>;\n readonly shiftKey: boolean;\n readonly ctrlKey: boolean;\n readonly metaKey: boolean;\n /** The originating pointer event (e.g. to call `preventDefault`). */\n readonly originalEvent: PointerEvent;\n}\n\n/**\n * Optional capability a feature module's controller may implement to receive\n * pointer interactions on body cells (press / drag-over / release) — the seam a\n * range-selection feature uses to track a drag. The grid forwards interactions\n * only when at least one feature module is registered, so the community grid\n * pays nothing.\n *\n * @remarks Unstable; part of `apex-grid/internal`.\n */\nexport interface CellInteractionHandler<T extends object = any> {\n handleCellInteraction(interaction: CellInteraction<T>): void;\n}\n\n/** Runtime type-guard for {@link CellInteractionHandler}. */\nexport function isCellInteractionHandler<T extends object>(\n controller: unknown\n): controller is CellInteractionHandler<T> {\n return (\n typeof controller === 'object' &&\n controller !== null &&\n typeof (controller as CellInteractionHandler<T>).handleCellInteraction === 'function'\n );\n}\n\n/**\n * Optional capability a feature module's controller may implement so its state\n * participates in grid-state snapshots ({@link StateController.serializeModuleState}\n * / {@link StateController.restoreModuleState}, driven by `ApexGrid.getState` /\n * `ApexGrid.setState`). The grid collects each implementer's\n * {@link serializeState} output under the module's id and dispatches the\n * matching value back via {@link restoreState} on restore. Ids with no\n * implementer are reported back by {@link StateController.restoreModuleState}.\n *\n * Controllers that don't implement this are skipped, so the community grid\n * (which registers no modules) contributes nothing to a snapshot.\n *\n * @remarks Unstable; part of `apex-grid/internal`.\n */\nexport interface SerializableModule {\n /**\n * Return a JSON-serializable snapshot of this module's restorable state\n * (e.g. the options the feature was configured with). Exclude transient/derived\n * state and anything not JSON-safe (functions, DOM nodes).\n */\n serializeState(): unknown;\n /**\n * Restore module state from a value previously produced by\n * {@link serializeState}. Implementations should tolerate partial or\n * unexpected shapes (validate before applying) since the blob is opaque.\n */\n restoreState(data: unknown): void;\n}\n\n/** Runtime type-guard for {@link SerializableModule}. */\nexport function isSerializableModule(controller: unknown): controller is SerializableModule {\n return (\n typeof controller === 'object' &&\n controller !== null &&\n typeof (controller as SerializableModule).serializeState === 'function' &&\n typeof (controller as SerializableModule).restoreState === 'function'\n );\n}\n"]}
|
package/internal/index.d.ts
CHANGED
|
@@ -11,14 +11,16 @@
|
|
|
11
11
|
* minor releases. Do not depend on them from third-party code.
|
|
12
12
|
*/
|
|
13
13
|
export { ApexGrid } from '../components/grid.js';
|
|
14
|
+
export { viewIndexer } from '../controllers/history.js';
|
|
14
15
|
export { gridStateContext, StateController } from '../controllers/state.js';
|
|
16
|
+
export { clampRating, commitDateInSameShape, getColumnTypeRenderer, getRatingMax, getSelectOptions, parseDate, } from './column-types.js';
|
|
15
17
|
export { PIPELINE } from './constants.js';
|
|
16
18
|
export type { ExportCellValue, ExportFormat, ExportOptions } from './export.js';
|
|
17
|
-
export { downloadBlob, getColumnLabel, resolveExportColumns, resolveExportRows, resolveExportValue, } from './export.js';
|
|
18
|
-
export type { CellDecoration, CellDecorator, CellDecoratorContext, CellInteraction, CellInteractionHandler, CellInteractionKind, ColumnMenuProvider, GridFeatureModule, PresentedRow, RowPresenter, RowPresenterContext, RowTransformer, SerializableModule, } from './feature-module.js';
|
|
19
|
-
export { isCellDecorator, isCellInteractionHandler, isColumnMenuProvider, isRowPresenter, isRowTransformer, isSerializableModule, } from './feature-module.js';
|
|
19
|
+
export { downloadBlob, escapeCSVCell, escapeFormula, getColumnLabel, resolveExportColumns, resolveExportRows, resolveExportValue, } from './export.js';
|
|
20
|
+
export type { CellDecoration, CellDecorator, CellDecoratorContext, CellInteraction, CellInteractionHandler, CellInteractionKind, ColumnMenuProvider, CoordinateLabeler, GridFeatureModule, PresentedRow, RowAria, RowAriaProvider, RowPresenter, RowPresenterContext, RowTransformer, SerializableModule, } from './feature-module.js';
|
|
21
|
+
export { isCellDecorator, isCellInteractionHandler, isColumnMenuProvider, isCoordinateLabeler, isRowAriaProvider, isRowPresenter, isRowTransformer, isSerializableModule, } from './feature-module.js';
|
|
20
22
|
export { registerComponent } from './register.js';
|
|
21
23
|
export type { ColumnLayoutState, FilterStateSnapshot, GetStateOptions, GridState, RowRef, SetStateOptions, SortStateSnapshot, } from './state-snapshot.js';
|
|
22
|
-
export { applyColumnLayout, deserializeFilter, resolveRowRefs, serializeColumnLayout, serializeFilter, serializeRowRefs, serializeSort, } from './state-snapshot.js';
|
|
24
|
+
export { applyColumnLayout, deserializeFilter, mergeColumnLayout, registerFilterOperand, resolveFilterOperand, resolveRowRefs, serializeColumnLayout, serializeFilter, serializeRowRefs, serializeSort, } from './state-snapshot.js';
|
|
23
25
|
export type { ActiveNode, ColumnConfiguration, GridHost, Keys, ToolbarAction } from './types.js';
|
|
24
26
|
export { getDisplayColumns } from './utils.js';
|
package/internal/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
export { ApexGrid } from '../components/grid.js';
|
|
2
|
+
export { viewIndexer } from '../controllers/history.js';
|
|
2
3
|
export { gridStateContext, StateController } from '../controllers/state.js';
|
|
4
|
+
export { clampRating, commitDateInSameShape, getColumnTypeRenderer, getRatingMax, getSelectOptions, parseDate, } from './column-types.js';
|
|
3
5
|
export { PIPELINE } from './constants.js';
|
|
4
|
-
export { downloadBlob, getColumnLabel, resolveExportColumns, resolveExportRows, resolveExportValue, } from './export.js';
|
|
5
|
-
export { isCellDecorator, isCellInteractionHandler, isColumnMenuProvider, isRowPresenter, isRowTransformer, isSerializableModule, } from './feature-module.js';
|
|
6
|
+
export { downloadBlob, escapeCSVCell, escapeFormula, getColumnLabel, resolveExportColumns, resolveExportRows, resolveExportValue, } from './export.js';
|
|
7
|
+
export { isCellDecorator, isCellInteractionHandler, isColumnMenuProvider, isCoordinateLabeler, isRowAriaProvider, isRowPresenter, isRowTransformer, isSerializableModule, } from './feature-module.js';
|
|
6
8
|
export { registerComponent } from './register.js';
|
|
7
|
-
export { applyColumnLayout, deserializeFilter, resolveRowRefs, serializeColumnLayout, serializeFilter, serializeRowRefs, serializeSort, } from './state-snapshot.js';
|
|
9
|
+
export { applyColumnLayout, deserializeFilter, mergeColumnLayout, registerFilterOperand, resolveFilterOperand, resolveRowRefs, serializeColumnLayout, serializeFilter, serializeRowRefs, serializeSort, } from './state-snapshot.js';
|
|
8
10
|
export { getDisplayColumns } from './utils.js';
|
|
9
11
|
//# sourceMappingURL=index.js.map
|
package/internal/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/internal/index.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EACL,YAAY,EACZ,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/internal/index.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EACL,WAAW,EACX,qBAAqB,EACrB,qBAAqB,EACrB,YAAY,EACZ,gBAAgB,EAChB,SAAS,GACV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EACL,YAAY,EACZ,aAAa,EACb,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAmBrB,OAAO,EACL,eAAe,EACf,wBAAwB,EACxB,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAUlD,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,cAAc,EACd,qBAAqB,EACrB,eAAe,EACf,gBAAgB,EAChB,aAAa,GACd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC","sourcesContent":["/**\n * Unstable, first-party extension surface for `apex-grid`.\n *\n * This entry point (`apex-grid/internal`) exposes the internals that the\n * first-party `@apexcharts/grid-enterprise` package builds on: the grid class,\n * its state controller, the component registration helper, and the feature\n * module contract. It is intentionally separate from the public `.` barrel.\n *\n * @remarks\n * No semver guarantees are made for these exports. They may change between\n * minor releases. Do not depend on them from third-party code.\n */\nexport { ApexGrid } from '../components/grid.js';\nexport { viewIndexer } from '../controllers/history.js';\nexport { gridStateContext, StateController } from '../controllers/state.js';\nexport {\n clampRating,\n commitDateInSameShape,\n getColumnTypeRenderer,\n getRatingMax,\n getSelectOptions,\n parseDate,\n} from './column-types.js';\nexport { PIPELINE } from './constants.js';\nexport type { ExportCellValue, ExportFormat, ExportOptions } from './export.js';\nexport {\n downloadBlob,\n escapeCSVCell,\n escapeFormula,\n getColumnLabel,\n resolveExportColumns,\n resolveExportRows,\n resolveExportValue,\n} from './export.js';\nexport type {\n CellDecoration,\n CellDecorator,\n CellDecoratorContext,\n CellInteraction,\n CellInteractionHandler,\n CellInteractionKind,\n ColumnMenuProvider,\n CoordinateLabeler,\n GridFeatureModule,\n PresentedRow,\n RowAria,\n RowAriaProvider,\n RowPresenter,\n RowPresenterContext,\n RowTransformer,\n SerializableModule,\n} from './feature-module.js';\nexport {\n isCellDecorator,\n isCellInteractionHandler,\n isColumnMenuProvider,\n isCoordinateLabeler,\n isRowAriaProvider,\n isRowPresenter,\n isRowTransformer,\n isSerializableModule,\n} from './feature-module.js';\nexport { registerComponent } from './register.js';\nexport type {\n ColumnLayoutState,\n FilterStateSnapshot,\n GetStateOptions,\n GridState,\n RowRef,\n SetStateOptions,\n SortStateSnapshot,\n} from './state-snapshot.js';\nexport {\n applyColumnLayout,\n deserializeFilter,\n mergeColumnLayout,\n registerFilterOperand,\n resolveFilterOperand,\n resolveRowRefs,\n serializeColumnLayout,\n serializeFilter,\n serializeRowRefs,\n serializeSort,\n} from './state-snapshot.js';\nexport type { ActiveNode, ColumnConfiguration, GridHost, Keys, ToolbarAction } from './types.js';\nexport { getDisplayColumns } from './utils.js';\n"]}
|
|
@@ -1 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* The text a string filter operand compares: strings as they are, `null` and
|
|
3
|
+
* `undefined` as `''`, any other value (number, Date, array) through `String`,
|
|
4
|
+
* case-folded unless `caseSensitive`. Total, so a cell of any type can be
|
|
5
|
+
* matched by a string condition without throwing. A string cell allocates
|
|
6
|
+
* nothing beyond the case fold.
|
|
7
|
+
*/
|
|
8
|
+
export declare function normalizeCase(value: unknown, caseSensitive?: boolean): string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export function normalizeCase(
|
|
2
|
-
|
|
1
|
+
export function normalizeCase(value, caseSensitive) {
|
|
2
|
+
const text = typeof value === 'string' ? value : value == null ? '' : String(value);
|
|
3
|
+
return caseSensitive ? text : text.toLowerCase();
|
|
3
4
|
}
|
|
4
5
|
//# sourceMappingURL=normalize-case.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize-case.js","sourceRoot":"","sources":["../../src/internal/normalize-case.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"normalize-case.js","sourceRoot":"","sources":["../../src/internal/normalize-case.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,aAAa,CAAC,KAAc,EAAE,aAAuB;IACnE,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpF,OAAO,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;AACnD,CAAC","sourcesContent":["/**\n * The text a string filter operand compares: strings as they are, `null` and\n * `undefined` as `''`, any other value (number, Date, array) through `String`,\n * case-folded unless `caseSensitive`. Total, so a cell of any type can be\n * matched by a string condition without throwing. A string cell allocates\n * nothing beyond the case fold.\n */\nexport function normalizeCase(value: unknown, caseSensitive?: boolean): string {\n const text = typeof value === 'string' ? value : value == null ? '' : String(value);\n return caseSensitive ? text : text.toLowerCase();\n}\n"]}
|