@toolbox-web/grid 1.30.2 → 1.31.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/README.md +1 -1
- package/all.js +2 -2
- package/all.js.map +1 -1
- package/index.js +1 -1
- package/index.js.map +1 -1
- package/lib/core/internal/dom-builder.d.ts +3 -3
- package/lib/core/plugin/base-plugin.d.ts +31 -8
- package/lib/core/plugin/plugin-manager.d.ts +2 -2
- package/lib/core/types.d.ts +16 -1
- package/lib/plugins/clipboard/index.js +1 -1
- package/lib/plugins/clipboard/index.js.map +1 -1
- package/lib/plugins/column-virtualization/index.js +1 -1
- package/lib/plugins/column-virtualization/index.js.map +1 -1
- package/lib/plugins/context-menu/index.js +1 -1
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/editing/index.js +1 -1
- package/lib/plugins/editing/index.js.map +1 -1
- package/lib/plugins/export/index.js +1 -1
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/filtering/index.js +1 -1
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/index.js +1 -1
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-rows/index.js +2 -2
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/master-detail/index.js +1 -1
- package/lib/plugins/master-detail/index.js.map +1 -1
- package/lib/plugins/multi-sort/MultiSortPlugin.d.ts +8 -1
- package/lib/plugins/multi-sort/index.js +1 -1
- package/lib/plugins/multi-sort/index.js.map +1 -1
- package/lib/plugins/pinned-columns/index.js +1 -1
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-rows/index.js +1 -1
- package/lib/plugins/pinned-rows/index.js.map +1 -1
- package/lib/plugins/pivot/PivotPlugin.d.ts +43 -1
- package/lib/plugins/pivot/index.d.ts +1 -1
- package/lib/plugins/pivot/index.js +1 -1
- package/lib/plugins/pivot/index.js.map +1 -1
- package/lib/plugins/pivot/pivot-engine.d.ts +21 -2
- package/lib/plugins/pivot/pivot-model.d.ts +6 -3
- package/lib/plugins/pivot/pivot-panel.d.ts +8 -3
- package/lib/plugins/pivot/pivot-rows.d.ts +3 -3
- package/lib/plugins/pivot/types.d.ts +121 -8
- package/lib/plugins/print/index.js +1 -1
- package/lib/plugins/print/index.js.map +1 -1
- package/lib/plugins/reorder-columns/index.js +1 -1
- package/lib/plugins/reorder-columns/index.js.map +1 -1
- package/lib/plugins/reorder-rows/index.js +1 -1
- package/lib/plugins/reorder-rows/index.js.map +1 -1
- package/lib/plugins/responsive/index.js +1 -1
- package/lib/plugins/responsive/index.js.map +1 -1
- package/lib/plugins/selection/index.js +1 -1
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/server-side/index.js +1 -1
- package/lib/plugins/server-side/index.js.map +1 -1
- package/lib/plugins/tooltip/index.js +1 -1
- package/lib/plugins/tooltip/index.js.map +1 -1
- package/lib/plugins/tree/index.js +1 -1
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/undo-redo/index.js +1 -1
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/visibility/index.js +1 -1
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +1 -1
- package/themes/dg-theme-bootstrap.css +8 -1
- package/themes/dg-theme-large.css +3 -1
- package/themes/dg-theme-material.css +3 -1
- package/themes/dg-theme-standard.css +5 -0
- package/themes/dg-theme-vibrant.css +5 -0
- package/umd/grid.all.umd.js +1 -1
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +1 -1
- package/umd/grid.umd.js.map +1 -1
- package/umd/plugins/context-menu.umd.js +1 -1
- package/umd/plugins/context-menu.umd.js.map +1 -1
- package/umd/plugins/editing.umd.js +1 -1
- package/umd/plugins/editing.umd.js.map +1 -1
- package/umd/plugins/filtering.umd.js +1 -1
- package/umd/plugins/filtering.umd.js.map +1 -1
- package/umd/plugins/grouping-rows.umd.js +1 -1
- package/umd/plugins/grouping-rows.umd.js.map +1 -1
- package/umd/plugins/master-detail.umd.js +1 -1
- package/umd/plugins/master-detail.umd.js.map +1 -1
- package/umd/plugins/multi-sort.umd.js +1 -1
- package/umd/plugins/multi-sort.umd.js.map +1 -1
- package/umd/plugins/pivot.umd.js +1 -1
- package/umd/plugins/pivot.umd.js.map +1 -1
- package/umd/plugins/print.umd.js +1 -1
- package/umd/plugins/print.umd.js.map +1 -1
- package/umd/plugins/reorder-rows.umd.js +1 -1
- package/umd/plugins/reorder-rows.umd.js.map +1 -1
- package/umd/plugins/tree.umd.js +1 -1
- package/umd/plugins/tree.umd.js.map +1 -1
- package/umd/plugins/visibility.umd.js +1 -1
- package/umd/plugins/visibility.umd.js.map +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PivotConfig, PivotResult, PivotRow, PivotValueField } from './types';
|
|
1
|
+
import { PivotConfig, PivotResult, PivotRow, PivotSortConfig, PivotSortDir, PivotValueField } from './types';
|
|
2
2
|
export type PivotDataRow = Record<string, unknown>;
|
|
3
3
|
/**
|
|
4
4
|
* Build a hierarchical pivot result from flat data.
|
|
@@ -8,7 +8,7 @@ export declare function buildPivot(rows: PivotDataRow[], config: PivotConfig): P
|
|
|
8
8
|
/**
|
|
9
9
|
* Get unique column key combinations from the data.
|
|
10
10
|
*/
|
|
11
|
-
export declare function getUniqueColumnKeys(rows: PivotDataRow[], columnFields: string[]): string[];
|
|
11
|
+
export declare function getUniqueColumnKeys(rows: PivotDataRow[], columnFields: string[], sortDir?: PivotSortDir): string[];
|
|
12
12
|
/**
|
|
13
13
|
* Group rows by a single field.
|
|
14
14
|
*/
|
|
@@ -47,3 +47,22 @@ export declare function flattenPivotRows(rows: PivotRow[], expandedKeys?: Set<st
|
|
|
47
47
|
* Get all group keys from pivot rows (for expand all / collapse all).
|
|
48
48
|
*/
|
|
49
49
|
export declare function getAllGroupKeys(rows: PivotRow[]): string[];
|
|
50
|
+
/**
|
|
51
|
+
* Recursively sort pivot rows at each level.
|
|
52
|
+
*/
|
|
53
|
+
export declare function sortPivotRows(rows: PivotRow[], sortConfig: PivotSortConfig, valueFields: PivotValueField[]): void;
|
|
54
|
+
/**
|
|
55
|
+
* Sort pivot rows by multiple criteria (from MultiSort's sort model).
|
|
56
|
+
* Each criterion is a PivotSortConfig; earlier entries take precedence.
|
|
57
|
+
* Maintains hierarchy by sorting children recursively at each level.
|
|
58
|
+
*/
|
|
59
|
+
export declare function sortPivotMulti(rows: PivotRow[], configs: PivotSortConfig[], valueFields: PivotValueField[]): void;
|
|
60
|
+
/**
|
|
61
|
+
* Resolve `defaultExpanded` config to a set of keys, similar to grouping-rows.
|
|
62
|
+
*/
|
|
63
|
+
export declare function resolveDefaultExpanded(value: boolean | number | string | string[] | undefined, allGroupKeys: string[]): Set<string>;
|
|
64
|
+
/**
|
|
65
|
+
* Calculate column totals (sum of all leaf row values per column key).
|
|
66
|
+
* Used for percentage-of-column calculations.
|
|
67
|
+
*/
|
|
68
|
+
export declare function getColumnTotals(rows: PivotRow[], columnKeys: string[], valueFields: PivotValueField[]): Record<string, number>;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { AggFunc, PivotConfig } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Resolve an AggFunc to an executable function.
|
|
4
|
+
* Supports both built-in string names and custom functions.
|
|
5
|
+
*/
|
|
6
|
+
export declare function getPivotAggregator(aggFunc: AggFunc): (values: number[]) => number;
|
|
4
7
|
export declare function validatePivotConfig(config: PivotConfig): string[];
|
|
5
8
|
export declare function createValueKey(columnValues: string[], valueField: string): string;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { AggFunc, PivotConfig } from './types';
|
|
2
|
-
/**
|
|
3
|
-
|
|
1
|
+
import { AggFunc, CustomAggFunc, PivotConfig } from './types';
|
|
2
|
+
/** Built-in aggregation function names (excludes custom functions) */
|
|
3
|
+
type BuiltInAggFunc = Exclude<AggFunc, CustomAggFunc>;
|
|
4
|
+
/** All available built-in aggregation functions for the panel UI */
|
|
5
|
+
export declare const AGG_FUNCS: BuiltInAggFunc[];
|
|
4
6
|
/** Field info for available fields */
|
|
5
7
|
export interface FieldInfo {
|
|
6
8
|
field: string;
|
|
@@ -11,6 +13,8 @@ export interface PanelCallbacks {
|
|
|
11
13
|
onTogglePivot: (enabled: boolean) => void;
|
|
12
14
|
onAddFieldToZone: (field: string, zone: 'rowGroups' | 'columnGroups') => void;
|
|
13
15
|
onRemoveFieldFromZone: (field: string, zone: 'rowGroups' | 'columnGroups') => void;
|
|
16
|
+
onReorderFieldInZone: (field: string, zone: 'rowGroups' | 'columnGroups', newIndex: number) => void;
|
|
17
|
+
onMoveFieldBetweenZones: (field: string, fromZone: 'rowGroups' | 'columnGroups', toZone: 'rowGroups' | 'columnGroups') => void;
|
|
14
18
|
onAddValueField: (field: string, aggFunc: AggFunc) => void;
|
|
15
19
|
onRemoveValueField: (field: string) => void;
|
|
16
20
|
onUpdateValueAggFunc: (field: string, aggFunc: AggFunc) => void;
|
|
@@ -22,3 +26,4 @@ export interface PanelCallbacks {
|
|
|
22
26
|
* Returns a cleanup function that removes all event listeners and DOM elements.
|
|
23
27
|
*/
|
|
24
28
|
export declare function renderPivotPanel(container: HTMLElement, config: PivotConfig, isActive: boolean, callbacks: PanelCallbacks): () => void;
|
|
29
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ColumnConfig,
|
|
1
|
+
import { ColumnConfig, GridIcons } from '../../core/types';
|
|
2
2
|
/** Row data with pivot metadata */
|
|
3
3
|
export interface PivotRowData {
|
|
4
4
|
__pivotRowKey?: string;
|
|
@@ -16,8 +16,7 @@ export interface RowRenderContext {
|
|
|
16
16
|
columns: ColumnConfig[];
|
|
17
17
|
rowIndex: number;
|
|
18
18
|
onToggle: (key: string) => void;
|
|
19
|
-
|
|
20
|
-
setIcon: (element: HTMLElement, icon: IconValue) => void;
|
|
19
|
+
setIcon: (element: HTMLElement, iconKey: keyof GridIcons) => void;
|
|
21
20
|
}
|
|
22
21
|
/**
|
|
23
22
|
* Render a pivot group row (has children, can expand/collapse).
|
|
@@ -29,5 +28,6 @@ export declare function renderPivotGroupRow(row: PivotRowData, rowEl: HTMLElemen
|
|
|
29
28
|
export declare function renderPivotLeafRow(row: PivotRowData, rowEl: HTMLElement, columns: ColumnConfig[], rowIndex: number): boolean;
|
|
30
29
|
/**
|
|
31
30
|
* Render the grand total row.
|
|
31
|
+
* Used both for the sticky footer and for in-row-model rendering.
|
|
32
32
|
*/
|
|
33
33
|
export declare function renderPivotGrandTotalRow(row: PivotRowData, rowEl: HTMLElement, columns: ColumnConfig[]): boolean;
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import { ExpandCollapseAnimation } from '../../core/types';
|
|
2
2
|
export type { ExpandCollapseAnimation } from '../../core/types';
|
|
3
|
+
/**
|
|
4
|
+
* Custom aggregation function that receives an array of numeric values
|
|
5
|
+
* and returns a single aggregated result.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const weightedAvg: CustomAggFunc = (values) => {
|
|
10
|
+
* const total = values.reduce((a, b) => a + b, 0);
|
|
11
|
+
* return total / values.length;
|
|
12
|
+
* };
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export type CustomAggFunc = (values: number[]) => number;
|
|
3
16
|
/**
|
|
4
17
|
* Built-in aggregation functions for pivot value fields.
|
|
5
18
|
*
|
|
@@ -15,16 +28,43 @@ export type { ExpandCollapseAnimation } from '../../core/types';
|
|
|
15
28
|
* | `'first'` | Value from the first row in the group | May be `undefined` if group is empty |
|
|
16
29
|
* | `'last'` | Value from the last row in the group | May be `undefined` if group is empty |
|
|
17
30
|
*
|
|
18
|
-
*
|
|
31
|
+
* You can also provide a custom function:
|
|
19
32
|
* ```typescript
|
|
20
33
|
* const valueFields: PivotValueField[] = [
|
|
21
34
|
* { field: 'revenue', aggFunc: 'sum', header: 'Total Revenue' },
|
|
22
|
-
* { field: '
|
|
23
|
-
* { field: 'orders', aggFunc: 'count', header: '# Orders' },
|
|
35
|
+
* { field: 'margin', aggFunc: (values) => values.reduce((a, b) => a + b, 0) / values.length },
|
|
24
36
|
* ];
|
|
25
37
|
* ```
|
|
26
38
|
*/
|
|
27
|
-
export type AggFunc = 'sum' | 'avg' | 'count' | 'min' | 'max' | 'first' | 'last';
|
|
39
|
+
export type AggFunc = 'sum' | 'avg' | 'count' | 'min' | 'max' | 'first' | 'last' | CustomAggFunc;
|
|
40
|
+
/** Sort direction for pivot rows or columns. */
|
|
41
|
+
export type PivotSortDir = 'asc' | 'desc';
|
|
42
|
+
/** Configuration for sorting pivot row groups. */
|
|
43
|
+
export interface PivotSortConfig {
|
|
44
|
+
/** Sort by `'label'` (group name) or `'value'` (aggregate value). Default: `'label'` */
|
|
45
|
+
by?: 'label' | 'value';
|
|
46
|
+
/** Sort direction. Default: `'asc'` */
|
|
47
|
+
direction?: PivotSortDir;
|
|
48
|
+
/** When `by: 'value'`, which value field to sort by (defaults to first value field). */
|
|
49
|
+
valueField?: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Value display mode for pivot cells.
|
|
53
|
+
* - `'raw'` — Show raw aggregated value (default)
|
|
54
|
+
* - `'percentOfRow'` — Show as percentage of row total
|
|
55
|
+
* - `'percentOfColumn'` — Show as percentage of column total
|
|
56
|
+
* - `'percentOfGrandTotal'` — Show as percentage of grand total
|
|
57
|
+
*/
|
|
58
|
+
export type PivotValueDisplayMode = 'raw' | 'percentOfRow' | 'percentOfColumn' | 'percentOfGrandTotal';
|
|
59
|
+
/**
|
|
60
|
+
* Value that determines which groups are expanded by default.
|
|
61
|
+
* - `true` — Expand all groups
|
|
62
|
+
* - `false` — Collapse all groups
|
|
63
|
+
* - `number` — Expand group at this index
|
|
64
|
+
* - `string` — Expand group with this key
|
|
65
|
+
* - `string[]` — Expand groups matching these keys
|
|
66
|
+
*/
|
|
67
|
+
export type PivotDefaultExpandedValue = boolean | number | string | string[];
|
|
28
68
|
/**
|
|
29
69
|
* Configuration for the pivot plugin.
|
|
30
70
|
*
|
|
@@ -55,8 +95,15 @@ export interface PivotConfig {
|
|
|
55
95
|
valueFields?: PivotValueField[];
|
|
56
96
|
showTotals?: boolean;
|
|
57
97
|
showGrandTotal?: boolean;
|
|
58
|
-
/**
|
|
59
|
-
|
|
98
|
+
/**
|
|
99
|
+
* Which groups are expanded by default.
|
|
100
|
+
* - `true` — expand all (default)
|
|
101
|
+
* - `false` — collapse all
|
|
102
|
+
* - `number` — expand group at index
|
|
103
|
+
* - `string` — expand group with key
|
|
104
|
+
* - `string[]` — expand groups matching keys
|
|
105
|
+
*/
|
|
106
|
+
defaultExpanded?: PivotDefaultExpandedValue;
|
|
60
107
|
/** Indent width per depth level in pixels (default: 20) */
|
|
61
108
|
indentWidth?: number;
|
|
62
109
|
/** Whether to show the pivot configuration tool panel (default: true) */
|
|
@@ -69,6 +116,32 @@ export interface PivotConfig {
|
|
|
69
116
|
* @default 'slide'
|
|
70
117
|
*/
|
|
71
118
|
animation?: ExpandCollapseAnimation;
|
|
119
|
+
/**
|
|
120
|
+
* Sort configuration for row groups.
|
|
121
|
+
* When set, groups at each level are sorted by label or aggregate value.
|
|
122
|
+
*/
|
|
123
|
+
sortRows?: PivotSortConfig;
|
|
124
|
+
/**
|
|
125
|
+
* Sort direction for column keys. Default: `'asc'` (alphabetical).
|
|
126
|
+
* Set to `'desc'` for reverse order.
|
|
127
|
+
*/
|
|
128
|
+
sortColumns?: PivotSortDir;
|
|
129
|
+
/**
|
|
130
|
+
* Include the grand total row in the row model (so it's included in exports/copy).
|
|
131
|
+
* When `false` (default), grand total is rendered as a separate sticky footer.
|
|
132
|
+
* @default false
|
|
133
|
+
*/
|
|
134
|
+
grandTotalInRowModel?: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Display mode for aggregated values.
|
|
137
|
+
* @default 'raw'
|
|
138
|
+
*/
|
|
139
|
+
valueDisplayMode?: PivotValueDisplayMode;
|
|
140
|
+
/**
|
|
141
|
+
* Whether to show subtotal rows at each group level in multi-level grouping.
|
|
142
|
+
* @default false
|
|
143
|
+
*/
|
|
144
|
+
showSubtotals?: boolean;
|
|
72
145
|
}
|
|
73
146
|
/**
|
|
74
147
|
* Defines a value field in the pivot table — which data field to aggregate
|
|
@@ -80,10 +153,20 @@ export interface PivotConfig {
|
|
|
80
153
|
export interface PivotValueField {
|
|
81
154
|
/** The row data field to aggregate (must exist on the source row objects). */
|
|
82
155
|
field: string;
|
|
83
|
-
/** Aggregation function
|
|
156
|
+
/** Aggregation function — a built-in name or a custom function. */
|
|
84
157
|
aggFunc: AggFunc;
|
|
85
158
|
/** Custom column header label. Defaults to `"field (aggFunc)"` if omitted. */
|
|
86
159
|
header?: string;
|
|
160
|
+
/**
|
|
161
|
+
* Format function for display values. Receives the aggregated number and returns a string.
|
|
162
|
+
* When omitted, the original column's `format` is used if available, otherwise raw `String(value)`.
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```typescript
|
|
166
|
+
* { field: 'revenue', aggFunc: 'sum', format: (v) => `$${v.toLocaleString()}` }
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
format?: (value: number) => string;
|
|
87
170
|
}
|
|
88
171
|
export interface PivotState {
|
|
89
172
|
isActive: boolean;
|
|
@@ -117,13 +200,43 @@ export interface PivotRow {
|
|
|
117
200
|
values: Record<string, number | null>;
|
|
118
201
|
/** Row total across all columns */
|
|
119
202
|
total?: number;
|
|
120
|
-
/**
|
|
203
|
+
/**
|
|
204
|
+
* Whether this row has sub-groups (i.e. `remainingFields.length > 0` in the engine).
|
|
205
|
+
* NOTE: With a single `rowGroupFields`, grouped rows have `isGroup: false` because
|
|
206
|
+
* there are no further levels to expand. Use multi-level grouping when testing
|
|
207
|
+
* group-related logic like `getAllGroupKeys()`.
|
|
208
|
+
*/
|
|
121
209
|
isGroup: boolean;
|
|
122
210
|
/** Child rows (for hierarchical grouping) */
|
|
123
211
|
children?: PivotRow[];
|
|
124
212
|
/** Number of data rows in this group */
|
|
125
213
|
rowCount?: number;
|
|
126
214
|
}
|
|
215
|
+
/** Detail for `pivot-toggle` event. Fired when a group is expanded/collapsed. */
|
|
216
|
+
export interface PivotToggleDetail {
|
|
217
|
+
/** The pivot row key that was toggled. */
|
|
218
|
+
key: string;
|
|
219
|
+
/** Whether the group is now expanded. */
|
|
220
|
+
expanded: boolean;
|
|
221
|
+
/** The display label of the group. */
|
|
222
|
+
label: string;
|
|
223
|
+
/** The depth level of the group. */
|
|
224
|
+
depth: number;
|
|
225
|
+
}
|
|
226
|
+
/** Detail for `pivot-state-change` event. Fired when pivot is enabled or disabled. */
|
|
227
|
+
export interface PivotStateChangeDetail {
|
|
228
|
+
/** Whether pivot is now active. */
|
|
229
|
+
active: boolean;
|
|
230
|
+
}
|
|
231
|
+
/** Detail for `pivot-config-change` event. Fired when pivot configuration changes via the panel. */
|
|
232
|
+
export interface PivotConfigChangeDetail {
|
|
233
|
+
/** The configuration property that changed. */
|
|
234
|
+
property: string;
|
|
235
|
+
/** The field that was affected (if applicable). */
|
|
236
|
+
field?: string;
|
|
237
|
+
/** The zone that was affected (if applicable). */
|
|
238
|
+
zone?: 'rowGroups' | 'columnGroups' | 'values';
|
|
239
|
+
}
|
|
127
240
|
declare module '../../core/types' {
|
|
128
241
|
interface PluginNameMap {
|
|
129
242
|
pivot: import('./PivotPlugin').PivotPlugin;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function t(t,e){return`[tbw-grid${t?`#${t}`:""}${e?`:${e}`:""}]`}function e(e,i,n,r){return`${t(n,r)} ${e}: ${i}\n\n → More info: ${function(t){return`https://toolboxjs.com/grid/errors#${t.toLowerCase()}`}(e)}`}const i="tbw-print-isolation-style";async function n(t,n={}){const{orientation:r="landscape"}=n,o=t.id;document.querySelectorAll(`#${CSS.escape(o)}`).length>1&&function(t,i,n,r){console.warn(e(t,i,n,r))}("TBW093",`Multiple elements found with id="${o}". Print isolation may not work correctly. Ensure each grid has a unique ID.`,o,"print"),document.getElementById(i)?.remove();const s=function(t,e){const n=document.createElement("style");return n.id=i,n.textContent=`\n /* Print isolation: hide everything except the target grid */\n @media print {\n /* Hide all body children by default */\n body > *:not(#${t}) {\n display: none !important;\n }\n\n /* But show the grid and ensure it's not hidden by ancestor rules */\n #${t} {\n display: block !important;\n position: static !important;\n visibility: visible !important;\n opacity: 1 !important;\n overflow: visible !important;\n height: auto !important;\n width: 100% !important;\n max-height: none !important;\n margin: 0 !important;\n padding: 0 !important;\n transform: none !important;\n }\n\n /* If grid is nested, we need to show its ancestors too */\n #${t},\n #${t} * {\n visibility: visible !important;\n }\n\n /* Walk up the DOM and show all ancestors of the grid */\n body *:has(> #${t}),\n body *:has(#${t}) {\n display: block !important;\n visibility: visible !important;\n opacity: 1 !important;\n overflow: visible !important;\n height: auto !important;\n position: static !important;\n transform: none !important;\n background: transparent !important;\n border: none !important;\n padding: 0 !important;\n margin: 0 !important;\n }\n\n /* Hide siblings of ancestors (everything that's not in the path to the grid) */\n body *:has(#${t}) > *:not(:has(#${t})):not(#${t}) {\n display: none !important;\n }\n\n /* Page settings */\n @page {\n size: ${e};\n margin: 1cm;\n }\n\n /* Ensure proper print styling */\n body {\n margin: 0 !important;\n padding: 0 !important;\n background: white !important;\n color-scheme: light !important;\n }\n }\n\n /* Screen: also apply isolation for print preview */\n @media screen {\n /* When this stylesheet is active, we're about to print */\n /* No screen-specific rules needed - isolation only applies to print */\n }\n `,n}(o,r);return document.head.appendChild(s),new Promise(t=>{const e=()=>{window.removeEventListener("afterprint",e),document.getElementById(i)?.remove(),t()};window.addEventListener("afterprint",e),window.print(),setTimeout(()=>{window.removeEventListener("afterprint",e),document.getElementById(i)?.remove(),t()},5e3)})}const r=/* @__PURE__ */new Set(["script","iframe","object","embed","form","input","button","textarea","select","link","meta","base","style","template","slot","portal","frame","frameset","applet","noscript","noembed","plaintext","xmp","listing"]),o=/^on\w+$/i,s=/* @__PURE__ */new Set(["href","src","action","formaction","data","srcdoc","xlink:href","poster","srcset"]),a=/^\s*(javascript|vbscript|data|blob):/i;function d(t){if(!t||"string"!=typeof t)return"";if(-1===t.indexOf("<"))return t;const e=document.createElement("template");return e.innerHTML=t,function(t){const e=[],i=t.querySelectorAll("*");for(const n of i){const t=n.tagName.toLowerCase();if(r.has(t)){e.push(n);continue}if("svg"===t||"http://www.w3.org/2000/svg"===n.namespaceURI){if(Array.from(n.attributes).some(t=>o.test(t.name)||"href"===t.name||"xlink:href"===t.name)){e.push(n);continue}}const i=[];for(const e of n.attributes){const t=e.name.toLowerCase();o.test(t)?i.push(e.name):(s.has(t)&&a.test(e.value)||"style"===t&&/expression\s*\(|javascript:|behavior\s*:/i.test(e.value))&&i.push(e.name)}i.forEach(t=>n.removeAttribute(t))}e.forEach(t=>t.remove())}(e.content),e.innerHTML}const l='<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentColor" d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/></svg>',p={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:l,filterActive:l,print:"🖨️"};class h{static dependencies;static manifest;aliases;version="undefined"!=typeof __GRID_VERSION__?__GRID_VERSION__:"dev";styles;cellRenderers;headerRenderers;cellEditors;grid;config;userConfig;#t;get defaultConfig(){return{}}constructor(t={}){this.userConfig=t}attach(t){this.#t?.abort(),this.#t=new AbortController,this.grid=t,this.config={...this.defaultConfig,...this.userConfig}}detach(){this.#t?.abort(),this.#t=void 0}getPlugin(t){return this.grid?.getPlugin(t)}emit(t,e){this.grid?.dispatchEvent?.(new CustomEvent(t,{detail:e,bubbles:!0}))}emitCancelable(t,e){const i=new CustomEvent(t,{detail:e,bubbles:!0,cancelable:!0});return this.grid?.dispatchEvent?.(i),i.defaultPrevented}on(t,e){this.grid?._pluginManager?.subscribe(this,t,e)}off(t){this.grid?._pluginManager?.unsubscribe(this,t)}emitPluginEvent(t,e){this.grid?._pluginManager?.emitPluginEvent(t,e)}requestRender(){this.grid?.requestRender?.()}requestColumnsRender(){this.grid?.requestColumnsRender?.()}requestRenderWithFocus(){this.grid?.requestRenderWithFocus?.()}requestAfterRender(){this.grid?.requestAfterRender?.()}requestVirtualRefresh(){this.grid?.requestVirtualRefresh?.()}get rows(){return this.grid?.rows??[]}get sourceRows(){return this.grid?.sourceRows??[]}get columns(){return this.grid?.columns??[]}get visibleColumns(){return this.grid?._visibleColumns??[]}get gridElement(){return this.grid?._hostElement}get disconnectSignal(){return this.#t?.signal??this.grid?.disconnectSignal}get gridIcons(){const t=this.grid?.gridConfig?.icons??{};return{...p,...t}}get isAnimationEnabled(){const t=this.grid?.effectiveConfig?.animation?.mode??"reduced-motion";if(!1===t||"off"===t)return!1;if(!0===t||"on"===t)return!0;const e=this.gridElement;if(e){return"0"!==getComputedStyle(e).getPropertyValue("--tbw-animation-enabled").trim()}return!0}get animationDuration(){const t=this.gridElement;if(t){const e=getComputedStyle(t).getPropertyValue("--tbw-animation-duration").trim(),i=parseInt(e,10);if(!isNaN(i))return i}return 200}resolveIcon(t,e){return void 0!==e?e:this.gridIcons[t]}setIcon(t,e){"string"==typeof e?t.innerHTML=d(e):e instanceof HTMLElement&&(t.innerHTML="",t.appendChild(e.cloneNode(!0)))}warn(i,n){void 0!==n?console.warn(e(i,n,this.gridElement.id,this.name)):console.warn(`${t(this.gridElement.id,this.name)} ${i}`)}throwDiagnostic(t,i){throw new Error(e(t,i,this.gridElement.id,this.name))}}const m={button:!1,orientation:"landscape",warnThreshold:500,maxRows:0,includeTitle:!0,includeTimestamp:!0,title:"",isolate:!1};class c extends h{name="print";version="1.0.0";styles=".tbw-print-header,.tbw-print-footer{display:none}@media print{tbw-grid{overflow:visible!important;height:auto!important;border:none!important;border-radius:0!important;color-scheme:light only;-webkit-print-color-adjust:exact;print-color-adjust:exact}tbw-grid .tbw-grid-content{overflow:visible!important;height:auto!important;max-height:none!important}tbw-grid .tbw-scroll-area{overflow:visible!important;height:auto!important;max-height:none!important}tbw-grid .rows-body{overflow:visible!important;height:auto!important;max-height:none!important}tbw-grid .rows-container,tbw-grid .rows-viewport,tbw-grid .rows{overflow:visible!important;height:auto!important;max-height:none!important;transform:none!important}tbw-grid .rows-viewport .rows{position:static!important}tbw-grid .resize-handle,tbw-grid [part=sort-indicator],tbw-grid .tbw-filter-btn,tbw-grid .tool-panel,tbw-grid .tool-panel-content,tbw-grid .tbw-shell-header,tbw-grid .shell-toolbar,tbw-grid .tool-panel-toggle,tbw-grid [data-print-hide],tbw-grid .expander-cell,tbw-grid .tree-toggle,tbw-grid .context-menu,tbw-grid .faux-vscroll{display:none!important}tbw-grid .tbw-print-header{display:flex;justify-content:space-between;align-items:baseline;padding:var(--tbw-spacing-md, .5em) 0;margin-bottom:var(--tbw-spacing-md, .5em);border-bottom:2px solid var(--tbw-print-border, var(--tbw-color-border-strong));font-family:inherit}.tbw-print-header-title{font-size:1.25em;font-weight:700}.tbw-print-header-timestamp{font-size:var(--tbw-font-size-sm, .875em);color:var(--tbw-print-muted, var(--tbw-color-fg-muted))}tbw-grid .tbw-print-footer{display:block;margin-top:var(--tbw-spacing-md, .5em);padding-top:var(--tbw-spacing-md, .5em);border-top:1px solid var(--tbw-print-border, var(--tbw-color-border));font-size:var(--tbw-font-size-xs, .75em);color:var(--tbw-print-muted, var(--tbw-color-fg-muted));text-align:end}tbw-grid .data-grid-row{break-inside:avoid;page-break-inside:avoid}tbw-grid .cell{border:1px solid var(--tbw-print-cell-border, var(--tbw-color-border))!important}tbw-grid .header-row,tbw-grid .data-grid-row{padding-inline-end:1px}tbw-grid .data-grid-row:hover,tbw-grid .cell:hover{background:inherit!important}@page{margin:1cm}@page{tbw-grid.print-landscape{size:landscape}}@page{tbw-grid.print-portrait{size:portrait}}}";#e=!1;#i=null;#n=null;#r=null;#o=null;#s=null;#a=null;get#d(){return this.grid}isPrinting(){return this.#e}async print(t){if(this.#e)return void this.warn("TBW090","Print already in progress");const i=this.gridElement;if(!i)return void this.warn("TBW091","Grid not available");const n={...m,...this.config,...t},r=this.rows.length;let o=r,s=!1;if(n.warnThreshold>0&&r>n.warnThreshold){const t=n.maxRows>0?`\n\nNote: Output will be limited to ${n.maxRows.toLocaleString()} rows.`:"";if(!confirm(`This grid has ${r.toLocaleString()} rows. Printing large datasets may cause performance issues or browser slowdowns.${t}\n\nClick OK to continue, or Cancel to abort.`))return}n.maxRows>0&&r>n.maxRows&&(o=n.maxRows,s=!0),this.#e=!0;const a=performance.now();this.emit("print-start",{rowCount:o,limitApplied:s,originalRowCount:r});try{const t=this.#d;this.#n={bypassThreshold:t._virtualization?.bypassThreshold??24},this.#l(),s&&(this.#r=this.sourceRows,this.grid.rows=this.sourceRows.slice(0,o),await new Promise(t=>setTimeout(t,50))),(n.includeTitle||n.includeTimestamp)&&this.#p(n),await this.#h(),await new Promise(t=>requestAnimationFrame(t)),await new Promise(t=>requestAnimationFrame(t)),i.classList.add(`print-${n.orientation}`),await new Promise(t=>requestAnimationFrame(t)),await new Promise(t=>requestAnimationFrame(t)),n.isolate?await this.#m(n):await this.#c(),this.emit("print-complete",{success:!0,rowCount:o,duration:Math.round(performance.now()-a)})}catch(c){d="TBW092",l=`Print failed: ${c}`,p=this.gridElement?.id,h=this.name,console.error(e(d,l,p,h)),this.emit("print-complete",{success:!1,rowCount:0,duration:Math.round(performance.now()-a)})}finally{this.#u(),this.#e=!1}var d,l,p,h}#p(t){const e=this.gridElement;if(e){if(this.#o=document.createElement("div"),this.#o.className="tbw-print-header",t.includeTitle){const e=t.title||this.grid.effectiveConfig?.shell?.header?.title||"Grid Data",i=document.createElement("div");i.className="tbw-print-header-title",i.textContent=e,this.#o.appendChild(i)}if(t.includeTimestamp){const t=document.createElement("div");t.className="tbw-print-header-timestamp",t.textContent=`Printed: ${/* @__PURE__ */(new Date).toLocaleString()}`,this.#o.appendChild(t)}e.insertBefore(this.#o,e.firstChild),this.#s=document.createElement("div"),this.#s.className="tbw-print-footer",this.#s.textContent=`Page generated from ${window.location.hostname}`,e.appendChild(this.#s)}}async#h(){const t=this.#d;if(!t._virtualization)return;const e=this.rows.length;t._virtualization.bypassThreshold=e+100,t.refreshVirtualWindow(!0),await new Promise(t=>setTimeout(t,100))}async#c(){return new Promise(t=>{const e=()=>{window.removeEventListener("afterprint",e),t()};window.addEventListener("afterprint",e),window.print(),setTimeout(()=>{"undefined"!=typeof window&&window.removeEventListener("afterprint",e),t()},1e3)})}async#m(t){const e=this.gridElement;e&&await n(e,{orientation:t.orientation})}#l(){const t=this.columns;if(t){this.#i=/* @__PURE__ */new Map;for(const e of t)e.printHidden&&e.field&&(this.#i.set(e.field,!e.hidden),this.grid.setColumnVisible(e.field,!1))}}#g(){if(this.#i){for(const[t,e]of this.#i)this.grid.setColumnVisible(t,e);this.#i=null}}#u(){const t=this.gridElement;if(!t)return;this.#g(),t.classList.remove("print-portrait","print-landscape"),null!==this.#a&&(t.style.transform="",t.style.transformOrigin="",t.style.width="",this.#a=null),this.#o&&(this.#o.remove(),this.#o=null),this.#s&&(this.#s.remove(),this.#s=null);const e=this.#d;this.#n&&e._virtualization&&(e._virtualization.bypassThreshold=this.#n.bypassThreshold,e.refreshVirtualWindow(!0),this.#n=null),null!==this.#r&&(this.grid.rows=this.#r,this.#r=null)}afterRender(){this.config?.button&&!this.#w&&(this.#b(),this.#w=!0)}#w=!1;#b(){const t=this.#d;t.registerToolbarContent?.({id:"print-button",order:900,render:t=>{const e=document.createElement("button");e.className="tbw-toolbar-btn tbw-print-btn",e.title="Print grid",e.type="button";const i=this.resolveIcon("print")||"🖨️";this.setIcon(e,i),e.addEventListener("click",()=>{this.print()},{signal:this.disconnectSignal}),t.appendChild(e)}})}}export{c as PrintPlugin,n as printGridIsolated};
|
|
1
|
+
function t(t,e){return`[tbw-grid${t?`#${t}`:""}${e?`:${e}`:""}]`}function e(e,i,n,r){return`${t(n,r)} ${e}: ${i}\n\n → More info: ${function(t){return`https://toolboxjs.com/grid/errors#${t.toLowerCase()}`}(e)}`}const i="tbw-print-isolation-style";async function n(t,n={}){const{orientation:r="landscape"}=n,o=t.id;document.querySelectorAll(`#${CSS.escape(o)}`).length>1&&function(t,i,n,r){console.warn(e(t,i,n,r))}("TBW093",`Multiple elements found with id="${o}". Print isolation may not work correctly. Ensure each grid has a unique ID.`,o,"print"),document.getElementById(i)?.remove();const s=function(t,e){const n=document.createElement("style");return n.id=i,n.textContent=`\n /* Print isolation: hide everything except the target grid */\n @media print {\n /* Hide all body children by default */\n body > *:not(#${t}) {\n display: none !important;\n }\n\n /* But show the grid and ensure it's not hidden by ancestor rules */\n #${t} {\n display: block !important;\n position: static !important;\n visibility: visible !important;\n opacity: 1 !important;\n overflow: visible !important;\n height: auto !important;\n width: 100% !important;\n max-height: none !important;\n margin: 0 !important;\n padding: 0 !important;\n transform: none !important;\n }\n\n /* If grid is nested, we need to show its ancestors too */\n #${t},\n #${t} * {\n visibility: visible !important;\n }\n\n /* Walk up the DOM and show all ancestors of the grid */\n body *:has(> #${t}),\n body *:has(#${t}) {\n display: block !important;\n visibility: visible !important;\n opacity: 1 !important;\n overflow: visible !important;\n height: auto !important;\n position: static !important;\n transform: none !important;\n background: transparent !important;\n border: none !important;\n padding: 0 !important;\n margin: 0 !important;\n }\n\n /* Hide siblings of ancestors (everything that's not in the path to the grid) */\n body *:has(#${t}) > *:not(:has(#${t})):not(#${t}) {\n display: none !important;\n }\n\n /* Page settings */\n @page {\n size: ${e};\n margin: 1cm;\n }\n\n /* Ensure proper print styling */\n body {\n margin: 0 !important;\n padding: 0 !important;\n background: white !important;\n color-scheme: light !important;\n }\n }\n\n /* Screen: also apply isolation for print preview */\n @media screen {\n /* When this stylesheet is active, we're about to print */\n /* No screen-specific rules needed - isolation only applies to print */\n }\n `,n}(o,r);return document.head.appendChild(s),new Promise(t=>{const e=()=>{window.removeEventListener("afterprint",e),document.getElementById(i)?.remove(),t()};window.addEventListener("afterprint",e),window.print(),setTimeout(()=>{window.removeEventListener("afterprint",e),document.getElementById(i)?.remove(),t()},5e3)})}["__otorp__","__retteGenifed__","__retteSenifed__","rotcurtsnoc","wodniw","sihTlabolg","labolg","ssecorp","noitcnuF","tropmi","lave","tcelfeR","yxorP","rorrE","stnemugra","tnemucod","noitacol","eikooc","egarotSlacol","egarotSnoisses","BDdexedni","hctef","tseuqeRpttHLMX","tekcoSbeW","rekroW","rekroWderahS","rekroWecivreS","renepo","tnerap","pot","semarf","fles"].map(t=>t.split("").reverse().join(""));const r=/* @__PURE__ */new Set(["script","iframe","object","embed","form","input","button","textarea","select","link","meta","base","style","template","slot","portal","frame","frameset","applet","noscript","noembed","plaintext","xmp","listing"]),o=/^on\w+$/i,s=/* @__PURE__ */new Set(["href","src","action","formaction","data","srcdoc","xlink:href","poster","srcset"]),a=/^\s*(javascript|vbscript|data|blob):/i;function d(t){if(!t||"string"!=typeof t)return"";if(-1===t.indexOf("<"))return t;const e=document.createElement("template");return e.innerHTML=t,function(t){const e=[],i=t.querySelectorAll("*");for(const n of i){const t=n.tagName.toLowerCase();if(r.has(t)){e.push(n);continue}if("svg"===t||"http://www.w3.org/2000/svg"===n.namespaceURI){if(Array.from(n.attributes).some(t=>o.test(t.name)||"href"===t.name||"xlink:href"===t.name)){e.push(n);continue}}const i=[];for(const e of n.attributes){const t=e.name.toLowerCase();o.test(t)?i.push(e.name):(s.has(t)&&a.test(e.value)||"style"===t&&/expression\s*\(|javascript:|behavior\s*:/i.test(e.value))&&i.push(e.name)}i.forEach(t=>n.removeAttribute(t))}e.forEach(t=>t.remove())}(e.content),e.innerHTML}const l='<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentColor" d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/></svg>',c={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:l,filterActive:l,print:"🖨️"};class p{static dependencies;static manifest;aliases;version="undefined"!=typeof __GRID_VERSION__?__GRID_VERSION__:"dev";styles;cellRenderers;headerRenderers;cellEditors;grid;config;userConfig;#t;get defaultConfig(){return{}}constructor(t={}){this.userConfig=t}attach(t){this.#t?.abort(),this.#t=new AbortController,this.grid=t,this.config={...this.defaultConfig,...this.userConfig}}detach(){this.#t?.abort(),this.#t=void 0}getPlugin(t){return this.grid?.getPlugin(t)}emit(t,e){this.grid?.dispatchEvent?.(new CustomEvent(t,{detail:e,bubbles:!0}))}emitCancelable(t,e){const i=new CustomEvent(t,{detail:e,bubbles:!0,cancelable:!0});return this.grid?.dispatchEvent?.(i),i.defaultPrevented}on(t,e){this.grid?._pluginManager?.subscribe(this,t,e)}off(t){this.grid?._pluginManager?.unsubscribe(this,t)}emitPluginEvent(t,e){this.grid?._pluginManager?.emitPluginEvent(t,e)}requestRender(){this.grid?.requestRender?.()}requestColumnsRender(){this.grid?.requestColumnsRender?.()}requestRenderWithFocus(){this.grid?.requestRenderWithFocus?.()}requestAfterRender(){this.grid?.requestAfterRender?.()}requestVirtualRefresh(){this.grid?.requestVirtualRefresh?.()}get rows(){return this.grid?.rows??[]}get sourceRows(){return this.grid?.sourceRows??[]}get columns(){return this.grid?.columns??[]}get visibleColumns(){return this.grid?._visibleColumns??[]}get gridElement(){return this.grid?._hostElement}get disconnectSignal(){return this.#t?.signal??this.grid?.disconnectSignal}get gridIcons(){const t=this.grid?.gridConfig?.icons??{};return{...c,...t}}get isAnimationEnabled(){const t=this.grid?.effectiveConfig?.animation?.mode??"reduced-motion";if(!1===t||"off"===t)return!1;if(!0===t||"on"===t)return!0;const e=this.gridElement;if(e){return"0"!==getComputedStyle(e).getPropertyValue("--tbw-animation-enabled").trim()}return!0}get animationDuration(){const t=this.gridElement;if(t){const e=getComputedStyle(t).getPropertyValue("--tbw-animation-duration").trim(),i=parseInt(e,10);if(!isNaN(i))return i}return 200}resolveIcon(t,e){return void 0!==e?e:this.gridIcons[t]}setIcon(t,e,i){t.dataset.icon=e.replace(/([A-Z])/g,"-$1").toLowerCase(),"collapse"===e?t.dataset.expanded="":"expand"===e&&delete t.dataset.expanded;const n=this.#e(e,i);void 0!==n?"string"==typeof n?t.innerHTML=d(n):n instanceof HTMLElement&&(t.innerHTML="",t.appendChild(n.cloneNode(!0))):t.innerHTML=""}#e(t,e){return void 0!==e?e:this.grid?.gridConfig?.icons?.[t]}updateSortIndicator(t,e){t.querySelector('[part~="sort-indicator"], .sort-indicator')?.remove();const i=document.createElement("span");i.setAttribute("part","sort-indicator"),i.className="sort-indicator",e?(t.setAttribute("aria-sort","asc"===e?"ascending":"descending"),t.setAttribute("data-sort",e),this.setIcon(i,"asc"===e?"sortAsc":"sortDesc")):(t.setAttribute("aria-sort","none"),t.removeAttribute("data-sort"),this.setIcon(i,"sortNone"));const n=t.querySelector(".tbw-filter-btn")??t.querySelector(".resize-handle");return n?t.insertBefore(i,n):t.appendChild(i),i}warn(i,n){void 0!==n?console.warn(e(i,n,this.gridElement.id,this.name)):console.warn(`${t(this.gridElement.id,this.name)} ${i}`)}throwDiagnostic(t,i){throw new Error(e(t,i,this.gridElement.id,this.name))}}const m={button:!1,orientation:"landscape",warnThreshold:500,maxRows:0,includeTitle:!0,includeTimestamp:!0,title:"",isolate:!1};class h extends p{name="print";version="1.0.0";styles=".tbw-print-header,.tbw-print-footer{display:none}@media print{tbw-grid{overflow:visible!important;height:auto!important;border:none!important;border-radius:0!important;color-scheme:light only;-webkit-print-color-adjust:exact;print-color-adjust:exact}tbw-grid .tbw-grid-content{overflow:visible!important;height:auto!important;max-height:none!important}tbw-grid .tbw-scroll-area{overflow:visible!important;height:auto!important;max-height:none!important}tbw-grid .rows-body{overflow:visible!important;height:auto!important;max-height:none!important}tbw-grid .rows-container,tbw-grid .rows-viewport,tbw-grid .rows{overflow:visible!important;height:auto!important;max-height:none!important;transform:none!important}tbw-grid .rows-viewport .rows{position:static!important}tbw-grid .resize-handle,tbw-grid [part=sort-indicator],tbw-grid .tbw-filter-btn,tbw-grid .tool-panel,tbw-grid .tool-panel-content,tbw-grid .tbw-shell-header,tbw-grid .shell-toolbar,tbw-grid .tool-panel-toggle,tbw-grid [data-print-hide],tbw-grid .expander-cell,tbw-grid .tree-toggle,tbw-grid .context-menu,tbw-grid .faux-vscroll{display:none!important}tbw-grid .tbw-print-header{display:flex;justify-content:space-between;align-items:baseline;padding:var(--tbw-spacing-md, .5em) 0;margin-bottom:var(--tbw-spacing-md, .5em);border-bottom:2px solid var(--tbw-print-border, var(--tbw-color-border-strong));font-family:inherit}.tbw-print-header-title{font-size:1.25em;font-weight:700}.tbw-print-header-timestamp{font-size:var(--tbw-font-size-sm, .875em);color:var(--tbw-print-muted, var(--tbw-color-fg-muted))}tbw-grid .tbw-print-footer{display:block;margin-top:var(--tbw-spacing-md, .5em);padding-top:var(--tbw-spacing-md, .5em);border-top:1px solid var(--tbw-print-border, var(--tbw-color-border));font-size:var(--tbw-font-size-xs, .75em);color:var(--tbw-print-muted, var(--tbw-color-fg-muted));text-align:end}tbw-grid .data-grid-row{break-inside:avoid;page-break-inside:avoid}tbw-grid .cell{border:1px solid var(--tbw-print-cell-border, var(--tbw-color-border))!important}tbw-grid .header-row,tbw-grid .data-grid-row{padding-inline-end:1px}tbw-grid .data-grid-row:hover,tbw-grid .cell:hover{background:inherit!important}@page{margin:1cm}@page{tbw-grid.print-landscape{size:landscape}}@page{tbw-grid.print-portrait{size:portrait}}}";#i=!1;#n=null;#r=null;#o=null;#s=null;#a=null;#d=null;get#l(){return this.grid}isPrinting(){return this.#i}async print(t){if(this.#i)return void this.warn("TBW090","Print already in progress");const i=this.gridElement;if(!i)return void this.warn("TBW091","Grid not available");const n={...m,...this.config,...t},r=this.rows.length;let o=r,s=!1;if(n.warnThreshold>0&&r>n.warnThreshold){const t=n.maxRows>0?`\n\nNote: Output will be limited to ${n.maxRows.toLocaleString()} rows.`:"";if(!confirm(`This grid has ${r.toLocaleString()} rows. Printing large datasets may cause performance issues or browser slowdowns.${t}\n\nClick OK to continue, or Cancel to abort.`))return}n.maxRows>0&&r>n.maxRows&&(o=n.maxRows,s=!0),this.#i=!0;const a=performance.now();this.emit("print-start",{rowCount:o,limitApplied:s,originalRowCount:r});try{const t=this.#l;this.#r={bypassThreshold:t._virtualization?.bypassThreshold??24},this.#c(),s&&(this.#o=this.sourceRows,this.grid.rows=this.sourceRows.slice(0,o),await new Promise(t=>setTimeout(t,50))),(n.includeTitle||n.includeTimestamp)&&this.#p(n),await this.#m(),await new Promise(t=>requestAnimationFrame(t)),await new Promise(t=>requestAnimationFrame(t)),i.classList.add(`print-${n.orientation}`),await new Promise(t=>requestAnimationFrame(t)),await new Promise(t=>requestAnimationFrame(t)),n.isolate?await this.#h(n):await this.#u(),this.emit("print-complete",{success:!0,rowCount:o,duration:Math.round(performance.now()-a)})}catch(h){d="TBW092",l=`Print failed: ${h}`,c=this.gridElement?.id,p=this.name,console.error(e(d,l,c,p)),this.emit("print-complete",{success:!1,rowCount:0,duration:Math.round(performance.now()-a)})}finally{this.#g(),this.#i=!1}var d,l,c,p}#p(t){const e=this.gridElement;if(e){if(this.#s=document.createElement("div"),this.#s.className="tbw-print-header",t.includeTitle){const e=t.title||this.grid.effectiveConfig?.shell?.header?.title||"Grid Data",i=document.createElement("div");i.className="tbw-print-header-title",i.textContent=e,this.#s.appendChild(i)}if(t.includeTimestamp){const t=document.createElement("div");t.className="tbw-print-header-timestamp",t.textContent=`Printed: ${/* @__PURE__ */(new Date).toLocaleString()}`,this.#s.appendChild(t)}e.insertBefore(this.#s,e.firstChild),this.#a=document.createElement("div"),this.#a.className="tbw-print-footer",this.#a.textContent=`Page generated from ${window.location.hostname}`,e.appendChild(this.#a)}}async#m(){const t=this.#l;if(!t._virtualization)return;const e=this.rows.length;t._virtualization.bypassThreshold=e+100,t.refreshVirtualWindow(!0),await new Promise(t=>setTimeout(t,100))}async#u(){return new Promise(t=>{const e=()=>{window.removeEventListener("afterprint",e),t()};window.addEventListener("afterprint",e),window.print(),setTimeout(()=>{"undefined"!=typeof window&&window.removeEventListener("afterprint",e),t()},1e3)})}async#h(t){const e=this.gridElement;e&&await n(e,{orientation:t.orientation})}#c(){const t=this.columns;if(t){this.#n=/* @__PURE__ */new Map;for(const e of t)e.printHidden&&e.field&&(this.#n.set(e.field,!e.hidden),this.grid.setColumnVisible(e.field,!1))}}#w(){if(this.#n){for(const[t,e]of this.#n)this.grid.setColumnVisible(t,e);this.#n=null}}#g(){const t=this.gridElement;if(!t)return;this.#w(),t.classList.remove("print-portrait","print-landscape"),null!==this.#d&&(t.style.transform="",t.style.transformOrigin="",t.style.width="",this.#d=null),this.#s&&(this.#s.remove(),this.#s=null),this.#a&&(this.#a.remove(),this.#a=null);const e=this.#l;this.#r&&e._virtualization&&(e._virtualization.bypassThreshold=this.#r.bypassThreshold,e.refreshVirtualWindow(!0),this.#r=null),null!==this.#o&&(this.grid.rows=this.#o,this.#o=null)}afterRender(){this.config?.button&&!this.#b&&(this.#f(),this.#b=!0)}#b=!1;#f(){const t=this.#l;t.registerToolbarContent?.({id:"print-button",order:900,render:t=>{const e=document.createElement("button");e.className="tbw-toolbar-btn tbw-print-btn",e.title="Print grid",e.type="button",this.setIcon(e,"print"),e.addEventListener("click",()=>{this.print()},{signal:this.disconnectSignal}),t.appendChild(e)}})}}export{h as PrintPlugin,n as printGridIsolated};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|