apex-grid 3.5.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 +338 -0
- package/LICENSE.md +125 -0
- package/README.md +64 -10
- 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 +146 -36
- package/components/grid.js +442 -103
- 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 +11 -9
- package/components/header-row.js.map +1 -1
- package/components/header.js +32 -20
- package/components/header.js.map +1 -1
- package/components/row.d.ts +19 -3
- package/components/row.js +69 -23
- 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 +40 -0
- package/components/virtualizer.js +116 -5
- 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 +67 -13
- package/controllers/navigation.js +191 -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 +38 -22
- 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 +56 -7
- package/controllers/state.js +76 -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 +3156 -277
- 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 +155 -81
- package/docs/classes/ApexGridPaginator.html +1 -1
- package/docs/classes/ApexGridToolbar.html +3 -3
- package/docs/functions/localize.html +2 -2
- package/docs/hierarchy.html +1 -1
- package/docs/index.html +74 -11
- package/docs/interfaces/ApexCellValidationFailedEvent.html +3 -2
- package/docs/interfaces/ApexCellValueChangedEvent.html +4 -2
- package/docs/interfaces/ApexCellValueChangingEvent.html +3 -2
- package/docs/interfaces/ApexGridEventMap.html +5 -2
- 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/BaseFilterExpression.html +2 -2
- package/docs/interfaces/CSVExportOptions.html +12 -4
- package/docs/interfaces/DataPipelineConfiguration.html +1 -1
- package/docs/interfaces/ExportOptions.html +5 -3
- package/docs/interfaces/GridExpansionConfiguration.html +6 -2
- package/docs/interfaces/GridRowReorderingConfiguration.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 +3 -2
- package/docs/modules.html +1 -1
- package/docs/types/ExportSource.html +6 -4
- package/docs/types/OperandKeys.html +9 -0
- package/docs/variables/EN_LOCALE.html +2 -2
- package/i18n/en.d.ts +5 -0
- package/i18n/en.js +5 -0
- package/i18n/en.js.map +1 -1
- package/i18n/es.js +5 -0
- package/i18n/es.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 +60 -3
- package/internal/feature-module.js +6 -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 +34 -6
- package/internal/utils.js +30 -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 -3
- package/setup.d.ts +11 -0
- package/setup.js +9 -19
- package/setup.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 -214
|
@@ -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
|
|
@@ -104,11 +137,34 @@ export interface RowAriaProvider<T extends object = any> {
|
|
|
104
137
|
}
|
|
105
138
|
/** Runtime type-guard for {@link RowAriaProvider}. */
|
|
106
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>;
|
|
107
159
|
/** Per-cell context handed to a {@link CellDecorator}. */
|
|
108
160
|
export interface CellDecoratorContext<T extends object = any> {
|
|
109
161
|
/** The row's backing data (or a synthesized row object). */
|
|
110
162
|
readonly row: T;
|
|
111
|
-
/**
|
|
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
|
+
*/
|
|
112
168
|
readonly rowIndex: number;
|
|
113
169
|
/** The cell's column configuration. */
|
|
114
170
|
readonly column: ColumnConfiguration<T>;
|
|
@@ -202,7 +258,8 @@ export declare function isCellInteractionHandler<T extends object>(controller: u
|
|
|
202
258
|
* / {@link StateController.restoreModuleState}, driven by `ApexGrid.getState` /
|
|
203
259
|
* `ApexGrid.setState`). The grid collects each implementer's
|
|
204
260
|
* {@link serializeState} output under the module's id and dispatches the
|
|
205
|
-
* 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}.
|
|
206
263
|
*
|
|
207
264
|
* Controllers that don't implement this are skipped, so the community grid
|
|
208
265
|
* (which registers no modules) contributes nothing to a snapshot.
|
|
@@ -212,7 +269,7 @@ export declare function isCellInteractionHandler<T extends object>(controller: u
|
|
|
212
269
|
export interface SerializableModule {
|
|
213
270
|
/**
|
|
214
271
|
* Return a JSON-serializable snapshot of this module's restorable state
|
|
215
|
-
* (e.g.
|
|
272
|
+
* (e.g. the options the feature was configured with). Exclude transient/derived
|
|
216
273
|
* state and anything not JSON-safe (functions, DOM nodes).
|
|
217
274
|
*/
|
|
218
275
|
serializeState(): unknown;
|
|
@@ -13,6 +13,12 @@ export function isRowAriaProvider(controller) {
|
|
|
13
13
|
controller !== null &&
|
|
14
14
|
typeof controller.describeRow === 'function');
|
|
15
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
|
+
}
|
|
16
22
|
export function isCellDecorator(controller) {
|
|
17
23
|
return (typeof controller === 'object' &&
|
|
18
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;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;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/** 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/** 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, RowAria, RowAriaProvider, RowPresenter, RowPresenterContext, RowTransformer, SerializableModule, } from './feature-module.js';
|
|
19
|
-
export { isCellDecorator, isCellInteractionHandler, isColumnMenuProvider, isRowAriaProvider, 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, isRowAriaProvider, 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"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FilterCriteria, FilterExpression } from '../operations/filter/types.js';
|
|
1
|
+
import type { FilterCriteria, FilterExpression, FilterOperation } from '../operations/filter/types.js';
|
|
2
2
|
import type { SortExpression, SortingDirection } from '../operations/sort/types.js';
|
|
3
3
|
import type { ColumnConfiguration, PinPosition } from './types.js';
|
|
4
4
|
/**
|
|
@@ -105,6 +105,27 @@ export interface SetStateOptions<T extends object> {
|
|
|
105
105
|
*/
|
|
106
106
|
strict?: boolean;
|
|
107
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* The `setState` slices in the order `setState` applies them, each mapped to
|
|
110
|
+
* the {@link GridState} keys it restores (`tree` restores both tree keys).
|
|
111
|
+
*/
|
|
112
|
+
export declare const SET_STATE_SLICE_KEYS: {
|
|
113
|
+
readonly columns: readonly ["columns"];
|
|
114
|
+
readonly sort: readonly ["sort"];
|
|
115
|
+
readonly filter: readonly ["filter"];
|
|
116
|
+
readonly quickFilter: readonly ["quickFilter"];
|
|
117
|
+
readonly modules: readonly ["modules"];
|
|
118
|
+
readonly rowOrder: readonly ["rowOrder"];
|
|
119
|
+
readonly tree: readonly ["treeExpanded", "treeExpandedKeys"];
|
|
120
|
+
readonly expansion: readonly ["expansion"];
|
|
121
|
+
readonly rowPinning: readonly ["rowPinning"];
|
|
122
|
+
readonly selection: readonly ["selection"];
|
|
123
|
+
readonly pagination: readonly ["pagination"];
|
|
124
|
+
};
|
|
125
|
+
/** A `setState` slice name, as reported in {@link SetStateResult}. */
|
|
126
|
+
export type SetStateSlice = keyof typeof SET_STATE_SLICE_KEYS;
|
|
127
|
+
/** Every slice name, in apply order. */
|
|
128
|
+
export declare const SET_STATE_SLICES: SetStateSlice[];
|
|
108
129
|
/**
|
|
109
130
|
* The outcome of an {@link SetStateOptions} apply. `setState` never throws on
|
|
110
131
|
* malformed input (unless `strict`): it applies recognized slices, skips the
|
|
@@ -112,9 +133,12 @@ export interface SetStateOptions<T extends object> {
|
|
|
112
133
|
* clamped, or unresolved.
|
|
113
134
|
*/
|
|
114
135
|
export interface SetStateResult {
|
|
115
|
-
/**
|
|
136
|
+
/**
|
|
137
|
+
* Slice names that were present and applied (e.g. `'sort'`, `'columns'`); see
|
|
138
|
+
* {@link SET_STATE_SLICE_KEYS} for the {@link GridState} keys of each.
|
|
139
|
+
*/
|
|
116
140
|
applied: string[];
|
|
117
|
-
/** Known slice names that were absent
|
|
141
|
+
/** Known slice names ({@link SetStateSlice}) that were absent or not applied. */
|
|
118
142
|
skipped: string[];
|
|
119
143
|
/** What was dropped / clamped / unresolved, one message each. */
|
|
120
144
|
warnings: string[];
|
|
@@ -125,28 +149,56 @@ export declare function serializeColumnLayout<T extends object>(columns: Readonl
|
|
|
125
149
|
* Return a new columns array reordered to match `layout`, with width / pinning /
|
|
126
150
|
* visibility applied. Column objects are shallow-cloned so non-layout
|
|
127
151
|
* properties (templates, comparers, type config) are preserved. Columns absent
|
|
128
|
-
* from `layout` are appended unchanged; layout entries with no matching column
|
|
129
|
-
* are ignored.
|
|
152
|
+
* from `layout` are appended unchanged; layout entries with no matching column,
|
|
153
|
+
* a repeated key, or no string `key` are ignored. This is the full-layout
|
|
154
|
+
* restorer: to change a few fields in place, overlay them with
|
|
155
|
+
* {@link mergeColumnLayout} first.
|
|
130
156
|
*/
|
|
131
157
|
export declare function applyColumnLayout<T extends object>(columns: ReadonlyArray<ColumnConfiguration<T>>, layout: ReadonlyArray<ColumnLayoutState>): ColumnConfiguration<T>[];
|
|
158
|
+
/**
|
|
159
|
+
* Overlay a partial layout onto `current` (a full {@link serializeColumnLayout}
|
|
160
|
+
* result): each `partial` entry changes only the fields it defines on the
|
|
161
|
+
* column with the same key, and the order of `current` is kept. `null` clears
|
|
162
|
+
* a field (e.g. `pinned: null` unpins). Entries for unknown keys are ignored.
|
|
163
|
+
* Returns a new full layout to hand to `setState({ columns })`.
|
|
164
|
+
*/
|
|
165
|
+
export declare function mergeColumnLayout(current: ReadonlyArray<ColumnLayoutState>, partial: ReadonlyArray<Partial<Record<keyof ColumnLayoutState, unknown>>>): ColumnLayoutState[];
|
|
132
166
|
export declare function serializeSort<T extends object>(expressions: ReadonlyArray<SortExpression<T>>): SortStateSnapshot[];
|
|
133
167
|
export declare function serializeFilter<T extends object>(expressions: ReadonlyArray<FilterExpression<T>>): FilterStateSnapshot[];
|
|
168
|
+
/**
|
|
169
|
+
* Make `operation` resolvable by its `name` on every column, after the
|
|
170
|
+
* column type's own operands. For first-party filter UIs (the enterprise set
|
|
171
|
+
* filter) whose expressions must survive `setState(getState())`. The
|
|
172
|
+
* operation must be stateless: everything it needs travels in `searchTerm`.
|
|
173
|
+
*/
|
|
174
|
+
export declare function registerFilterOperand(operation: FilterOperation<unknown>): void;
|
|
175
|
+
/**
|
|
176
|
+
* Resolve a filter operand name (e.g. `'contains'`) to the live
|
|
177
|
+
* {@link FilterOperation} of `column`'s type, else to one registered with
|
|
178
|
+
* {@link registerFilterOperand}. Only the tables' own names resolve, so
|
|
179
|
+
* `'toString'` or `'constructor'` never pass as operands.
|
|
180
|
+
*/
|
|
181
|
+
export declare function resolveFilterOperand<T extends object>(column: ColumnConfiguration<T>, name: unknown): FilterOperation<unknown> | undefined;
|
|
134
182
|
/**
|
|
135
183
|
* Rebuild filter expressions from a snapshot, resolving each operand name back
|
|
136
184
|
* to a live {@link FilterOperation} via the target column's operand set.
|
|
137
|
-
* Entries whose column or operand can't be
|
|
138
|
-
*
|
|
185
|
+
* Entries that are not keyed objects, whose column or operand can't be
|
|
186
|
+
* resolved, or whose binary operand has no `searchTerm` are dropped; `onDrop`
|
|
187
|
+
* (when given) is called with the dropped entry and a reason.
|
|
139
188
|
*/
|
|
140
189
|
export declare function deserializeFilter<T extends object>(snapshots: ReadonlyArray<FilterStateSnapshot>, getColumn: (key: string) => ColumnConfiguration<T> | undefined, onDrop?: (snapshot: FilterStateSnapshot, reason: string) => void): FilterExpression<T>[];
|
|
141
190
|
/**
|
|
142
191
|
* Serialize a set of rows to {@link RowRef}s. With a `rowId` resolver each row
|
|
143
192
|
* is captured by id; otherwise by its positional index in `universe`
|
|
144
193
|
* (`ApexGrid.data`). Rows not found in `universe` (index mode) are skipped.
|
|
194
|
+
* Index mode builds one position map per call, so it is linear in the sizes
|
|
195
|
+
* of `rows` and `universe` rather than their product.
|
|
145
196
|
*/
|
|
146
197
|
export declare function serializeRowRefs<T extends object>(rows: ReadonlyArray<T>, universe: ReadonlyArray<T>, rowId?: (row: T) => string | number): RowRef[];
|
|
147
198
|
/**
|
|
148
199
|
* Resolve {@link RowRef}s back to rows in `universe`. `id` refs require a
|
|
149
200
|
* `rowId` resolver (otherwise they're skipped); `index` refs resolve
|
|
150
|
-
* positionally.
|
|
201
|
+
* positionally and must be non-negative integers. Refs that are not objects,
|
|
202
|
+
* and unresolvable refs, are dropped.
|
|
151
203
|
*/
|
|
152
204
|
export declare function resolveRowRefs<T extends object>(refs: ReadonlyArray<RowRef>, universe: ReadonlyArray<T>, rowId?: (row: T) => string | number): T[];
|
|
@@ -1,4 +1,23 @@
|
|
|
1
1
|
import { getFilterOperandsFor } from './utils.js';
|
|
2
|
+
export const SET_STATE_SLICE_KEYS = {
|
|
3
|
+
columns: ['columns'],
|
|
4
|
+
sort: ['sort'],
|
|
5
|
+
filter: ['filter'],
|
|
6
|
+
quickFilter: ['quickFilter'],
|
|
7
|
+
modules: ['modules'],
|
|
8
|
+
rowOrder: ['rowOrder'],
|
|
9
|
+
tree: ['treeExpanded', 'treeExpandedKeys'],
|
|
10
|
+
expansion: ['expansion'],
|
|
11
|
+
rowPinning: ['rowPinning'],
|
|
12
|
+
selection: ['selection'],
|
|
13
|
+
pagination: ['pagination'],
|
|
14
|
+
};
|
|
15
|
+
export const SET_STATE_SLICES = Object.keys(SET_STATE_SLICE_KEYS);
|
|
16
|
+
const _everyKeyHasASlice = true;
|
|
17
|
+
void _everyKeyHasASlice;
|
|
18
|
+
function isKeyed(value) {
|
|
19
|
+
return typeof value === 'object' && value !== null && typeof value.key === 'string';
|
|
20
|
+
}
|
|
2
21
|
export function serializeColumnLayout(columns) {
|
|
3
22
|
return columns.map((column) => ({
|
|
4
23
|
key: String(column.key),
|
|
@@ -14,6 +33,8 @@ export function applyColumnLayout(columns, layout) {
|
|
|
14
33
|
const used = new Set();
|
|
15
34
|
const ordered = [];
|
|
16
35
|
for (const entry of layout) {
|
|
36
|
+
if (!isKeyed(entry) || used.has(entry.key))
|
|
37
|
+
continue;
|
|
17
38
|
const column = byKey.get(entry.key);
|
|
18
39
|
if (!column)
|
|
19
40
|
continue;
|
|
@@ -31,6 +52,24 @@ export function applyColumnLayout(columns, layout) {
|
|
|
31
52
|
}
|
|
32
53
|
return ordered;
|
|
33
54
|
}
|
|
55
|
+
export function mergeColumnLayout(current, partial) {
|
|
56
|
+
const patches = new Map();
|
|
57
|
+
for (const entry of partial) {
|
|
58
|
+
if (isKeyed(entry))
|
|
59
|
+
patches.set(entry.key, entry);
|
|
60
|
+
}
|
|
61
|
+
return current.map((column) => {
|
|
62
|
+
const next = { ...column };
|
|
63
|
+
const patch = patches.get(column.key);
|
|
64
|
+
if (patch) {
|
|
65
|
+
for (const field of ['width', 'pinned', 'hidden']) {
|
|
66
|
+
if (patch[field] !== undefined)
|
|
67
|
+
next[field] = patch[field] ?? undefined;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return next;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
34
73
|
export function serializeSort(expressions) {
|
|
35
74
|
return expressions.map((expression) => ({
|
|
36
75
|
key: String(expression.key),
|
|
@@ -38,53 +77,80 @@ export function serializeSort(expressions) {
|
|
|
38
77
|
caseSensitive: expression.caseSensitive,
|
|
39
78
|
}));
|
|
40
79
|
}
|
|
80
|
+
function copyTerm(term) {
|
|
81
|
+
return Array.isArray(term) ? [...term] : term;
|
|
82
|
+
}
|
|
41
83
|
export function serializeFilter(expressions) {
|
|
42
84
|
return expressions.map((expression) => {
|
|
43
85
|
const condition = expression.condition;
|
|
44
86
|
return {
|
|
45
87
|
key: String(expression.key),
|
|
46
88
|
operand: typeof condition === 'string' ? condition : condition.name,
|
|
47
|
-
searchTerm: expression.searchTerm,
|
|
89
|
+
searchTerm: copyTerm(expression.searchTerm),
|
|
48
90
|
criteria: expression.criteria,
|
|
49
91
|
caseSensitive: expression.caseSensitive,
|
|
50
92
|
};
|
|
51
93
|
});
|
|
52
94
|
}
|
|
95
|
+
const registeredOperands = new Map();
|
|
96
|
+
export function registerFilterOperand(operation) {
|
|
97
|
+
registeredOperands.set(operation.name, operation);
|
|
98
|
+
}
|
|
99
|
+
export function resolveFilterOperand(column, name) {
|
|
100
|
+
if (typeof name !== 'string')
|
|
101
|
+
return undefined;
|
|
102
|
+
const operands = getFilterOperandsFor(column);
|
|
103
|
+
return Object.hasOwn(operands, name) ? operands[name] : registeredOperands.get(name);
|
|
104
|
+
}
|
|
53
105
|
export function deserializeFilter(snapshots, getColumn, onDrop) {
|
|
54
106
|
const expressions = [];
|
|
55
107
|
for (const snapshot of snapshots) {
|
|
108
|
+
if (!isKeyed(snapshot)) {
|
|
109
|
+
onDrop?.({ key: String(snapshot) }, 'not a filter entry');
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
56
112
|
const column = getColumn(snapshot.key);
|
|
57
113
|
if (!column) {
|
|
58
114
|
onDrop?.(snapshot, 'unknown column');
|
|
59
115
|
continue;
|
|
60
116
|
}
|
|
61
|
-
const
|
|
62
|
-
const condition = operands[snapshot.operand];
|
|
117
|
+
const condition = resolveFilterOperand(column, snapshot.operand);
|
|
63
118
|
if (!condition) {
|
|
64
119
|
onDrop?.(snapshot, `unknown operand "${snapshot.operand}"`);
|
|
65
120
|
continue;
|
|
66
121
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
122
|
+
if (!condition.unary && (snapshot.searchTerm === undefined || snapshot.searchTerm === null)) {
|
|
123
|
+
onDrop?.(snapshot, `operand "${snapshot.operand}" needs a searchTerm`);
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const expression = { key: snapshot.key, condition };
|
|
127
|
+
if (snapshot.searchTerm !== undefined)
|
|
128
|
+
expression.searchTerm = copyTerm(snapshot.searchTerm);
|
|
129
|
+
if (snapshot.criteria !== undefined)
|
|
130
|
+
expression.criteria = snapshot.criteria;
|
|
131
|
+
if (snapshot.caseSensitive !== undefined)
|
|
132
|
+
expression.caseSensitive = snapshot.caseSensitive;
|
|
133
|
+
expressions.push(expression);
|
|
74
134
|
}
|
|
75
135
|
return expressions;
|
|
76
136
|
}
|
|
77
137
|
export function serializeRowRefs(rows, universe, rowId) {
|
|
138
|
+
if (rowId)
|
|
139
|
+
return rows.map((row) => ({ id: rowId(row) }));
|
|
140
|
+
if (rows.length < 2) {
|
|
141
|
+
const index = rows.length ? universe.indexOf(rows[0]) : -1;
|
|
142
|
+
return index === -1 ? [] : [{ index }];
|
|
143
|
+
}
|
|
144
|
+
const positions = new Map();
|
|
145
|
+
universe.forEach((row, index) => {
|
|
146
|
+
if (!positions.has(row))
|
|
147
|
+
positions.set(row, index);
|
|
148
|
+
});
|
|
78
149
|
const refs = [];
|
|
79
150
|
for (const row of rows) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
else {
|
|
84
|
-
const index = universe.indexOf(row);
|
|
85
|
-
if (index !== -1)
|
|
86
|
-
refs.push({ index });
|
|
87
|
-
}
|
|
151
|
+
const index = positions.get(row);
|
|
152
|
+
if (index !== undefined)
|
|
153
|
+
refs.push({ index });
|
|
88
154
|
}
|
|
89
155
|
return refs;
|
|
90
156
|
}
|
|
@@ -92,6 +158,8 @@ export function resolveRowRefs(refs, universe, rowId) {
|
|
|
92
158
|
const out = [];
|
|
93
159
|
let byId = null;
|
|
94
160
|
for (const ref of refs) {
|
|
161
|
+
if (typeof ref !== 'object' || ref === null)
|
|
162
|
+
continue;
|
|
95
163
|
if ('id' in ref) {
|
|
96
164
|
if (!rowId)
|
|
97
165
|
continue;
|
|
@@ -104,7 +172,7 @@ export function resolveRowRefs(refs, universe, rowId) {
|
|
|
104
172
|
if (row)
|
|
105
173
|
out.push(row);
|
|
106
174
|
}
|
|
107
|
-
else {
|
|
175
|
+
else if (Number.isInteger(ref.index) && ref.index >= 0) {
|
|
108
176
|
const row = universe[ref.index];
|
|
109
177
|
if (row)
|
|
110
178
|
out.push(row);
|