@archbase/components 4.0.23 → 4.0.25
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/dist/archbase-components-4.0.25.tgz +0 -0
- package/dist/datagrid/ag-grid/archbase-data-grid-ag-types.d.ts +2 -0
- package/dist/index.js +3807 -3764
- package/package.json +4 -4
- package/src/datagrid/ag-grid/archbase-data-grid-ag-types.tsx +2 -0
- package/src/datagrid/ag-grid/archbase-data-grid-ag.tsx +123 -10
- package/src/datagrid/main/archbase-data-grid.tsx +1 -1
- package/dist/archbase-components-4.0.23.tgz +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@archbase/components",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.25",
|
|
4
4
|
"description": "UI Components for Archbase React v3 - Form editors, data visualization, and business components",
|
|
5
5
|
"author": "Edson Martins <edsonmartins2005@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -118,9 +118,9 @@
|
|
|
118
118
|
"vis-timeline": "^7.7.3",
|
|
119
119
|
"xlsx": "^0.18.5",
|
|
120
120
|
"yet-another-react-lightbox": "^3.21.0",
|
|
121
|
-
"@archbase/core": "4.0.
|
|
122
|
-
"@archbase/data": "4.0.
|
|
123
|
-
"@archbase/layout": "4.0.
|
|
121
|
+
"@archbase/core": "4.0.25",
|
|
122
|
+
"@archbase/data": "4.0.25",
|
|
123
|
+
"@archbase/layout": "4.0.25"
|
|
124
124
|
},
|
|
125
125
|
"devDependencies": {
|
|
126
126
|
"@types/d3": "^7.4.3",
|
|
@@ -90,6 +90,8 @@ export interface ArchbaseDataGridAGColumnProps<T = any> {
|
|
|
90
90
|
maxSize?: number;
|
|
91
91
|
/** Custom cell renderer */
|
|
92
92
|
render?: (data: any) => ReactNode;
|
|
93
|
+
/** Truncate long content with ellipsis (and show a native tooltip with the full value) */
|
|
94
|
+
truncate?: boolean;
|
|
93
95
|
/** Column visibility */
|
|
94
96
|
visible: boolean;
|
|
95
97
|
/** Column width */
|
|
@@ -13,8 +13,81 @@ import React, {
|
|
|
13
13
|
useCallback,
|
|
14
14
|
Children,
|
|
15
15
|
isValidElement,
|
|
16
|
+
type ReactNode,
|
|
17
|
+
type ReactElement,
|
|
16
18
|
} from 'react';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Returns a stable reference to `children` as long as the structural shape
|
|
22
|
+
* (number of valid elements, their `type` and `key`) does not change.
|
|
23
|
+
*
|
|
24
|
+
* JSX like `<Comp>{a}{b}</Comp>` creates a NEW children array on every render,
|
|
25
|
+
* even when `a` and `b` are stable references. That makes useMemo deps that
|
|
26
|
+
* include `children` recompute on every parent render. For consumers like
|
|
27
|
+
* AG-Grid where rebuilding column defs invalidates virtualization, this is
|
|
28
|
+
* expensive. This hook lets the consumer skip recomputation when the
|
|
29
|
+
* children only "look the same".
|
|
30
|
+
*/
|
|
31
|
+
function useStableChildren(children: ReactNode): ReactNode {
|
|
32
|
+
const ref = useRef<ReactNode>(children);
|
|
33
|
+
const prevSignature = useRef<string>('');
|
|
34
|
+
|
|
35
|
+
const currentElements = Children.toArray(children).filter(isValidElement) as ReactElement[];
|
|
36
|
+
const currentSignature = currentElements
|
|
37
|
+
.map((el) => `${String((el.type as any)?.displayName || (el.type as any)?.name || el.type)}::${String(el.key ?? '')}`)
|
|
38
|
+
.join('|');
|
|
39
|
+
|
|
40
|
+
if (currentSignature !== prevSignature.current) {
|
|
41
|
+
prevSignature.current = currentSignature;
|
|
42
|
+
ref.current = children;
|
|
43
|
+
}
|
|
44
|
+
return ref.current;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Class applied to AG cells when the user opts into `truncate` on a column.
|
|
49
|
+
* The companion CSS (injected once per document below) makes the React
|
|
50
|
+
* container shrink in the cell's flex layout and clips overflow with an
|
|
51
|
+
* ellipsis. Native `title` attribute on the rendered span shows the full
|
|
52
|
+
* value on hover.
|
|
53
|
+
*/
|
|
54
|
+
const ARCHBASE_TRUNCATE_CELL_CLASS = 'archbase-ag-truncate-cell';
|
|
55
|
+
const ARCHBASE_TRUNCATE_TEXT_CLASS = 'archbase-ag-truncate-text';
|
|
56
|
+
const ARCHBASE_TRUNCATE_STYLE_ID = 'archbase-ag-truncate-style';
|
|
57
|
+
|
|
58
|
+
function ensureTruncateStyleInjected(): void {
|
|
59
|
+
if (typeof document === 'undefined') return;
|
|
60
|
+
if (document.getElementById(ARCHBASE_TRUNCATE_STYLE_ID)) return;
|
|
61
|
+
const style = document.createElement('style');
|
|
62
|
+
style.id = ARCHBASE_TRUNCATE_STYLE_ID;
|
|
63
|
+
style.textContent = `
|
|
64
|
+
.ag-cell.${ARCHBASE_TRUNCATE_CELL_CLASS} {
|
|
65
|
+
overflow: hidden !important;
|
|
66
|
+
}
|
|
67
|
+
.ag-cell.${ARCHBASE_TRUNCATE_CELL_CLASS} .ag-react-container,
|
|
68
|
+
.ag-cell.${ARCHBASE_TRUNCATE_CELL_CLASS} > * {
|
|
69
|
+
flex: 1 1 0 !important;
|
|
70
|
+
min-width: 0 !important;
|
|
71
|
+
max-width: 100% !important;
|
|
72
|
+
overflow: hidden !important;
|
|
73
|
+
}
|
|
74
|
+
.${ARCHBASE_TRUNCATE_TEXT_CLASS} {
|
|
75
|
+
display: block;
|
|
76
|
+
width: 100%;
|
|
77
|
+
max-width: 100%;
|
|
78
|
+
overflow: hidden;
|
|
79
|
+
text-overflow: ellipsis;
|
|
80
|
+
white-space: nowrap;
|
|
81
|
+
}
|
|
82
|
+
`;
|
|
83
|
+
document.head.appendChild(style);
|
|
84
|
+
}
|
|
17
85
|
import { AgGridReact } from 'ag-grid-react';
|
|
86
|
+
|
|
87
|
+
// Memoize AgGridReact — recommended by AG-Grid's official performance demo. This
|
|
88
|
+
// is by far the biggest scroll-perf win: it skips the full AG-Grid re-render when
|
|
89
|
+
// the parent re-renders but every prop reference is the same.
|
|
90
|
+
const AgGridReactMemo = React.memo(AgGridReact);
|
|
18
91
|
import {
|
|
19
92
|
AllCommunityModule,
|
|
20
93
|
ModuleRegistry,
|
|
@@ -175,7 +248,7 @@ function ArchbaseDataGridAG<T extends object = any, ID = any>(
|
|
|
175
248
|
csvOptions,
|
|
176
249
|
toolbarAlignment = 'right',
|
|
177
250
|
positionActionsColumn = 'first',
|
|
178
|
-
actionsColumnWidth =
|
|
251
|
+
actionsColumnWidth = 120,
|
|
179
252
|
toolbarLeftContent,
|
|
180
253
|
bottomToolbarMinHeight,
|
|
181
254
|
paginationLabels,
|
|
@@ -199,6 +272,11 @@ function ArchbaseDataGridAG<T extends object = any, ID = any>(
|
|
|
199
272
|
const gridApiRef = useRef<GridApi | null>(null);
|
|
200
273
|
const gridContainerRef = useRef<HTMLDivElement>(null);
|
|
201
274
|
|
|
275
|
+
// Reference-stable children: only changes when the structural shape changes.
|
|
276
|
+
// Prevents columnDefs useMemo from invalidating on every parent render and
|
|
277
|
+
// forcing AG-Grid to rebuild all columns (which destroys virtualization perf).
|
|
278
|
+
const stableChildren = useStableChildren(children);
|
|
279
|
+
|
|
202
280
|
// Detect DataSource version
|
|
203
281
|
const isV2 = isDataSourceV2(dataSource);
|
|
204
282
|
|
|
@@ -348,8 +426,9 @@ function ArchbaseDataGridAG<T extends object = any, ID = any>(
|
|
|
348
426
|
}
|
|
349
427
|
}
|
|
350
428
|
|
|
351
|
-
// Extract column definitions from children
|
|
352
|
-
|
|
429
|
+
// Extract column definitions from children (using the structurally-stable
|
|
430
|
+
// reference so this useMemo doesn't recompute on every parent render).
|
|
431
|
+
Children.forEach(stableChildren, (child) => {
|
|
353
432
|
if (isValidElement(child) && child.type === Columns) {
|
|
354
433
|
Children.forEach((child.props as any).children, (column) => {
|
|
355
434
|
if (isValidElement(column)) {
|
|
@@ -361,7 +440,7 @@ function ArchbaseDataGridAG<T extends object = any, ID = any>(
|
|
|
361
440
|
const alignment = getAlignmentByDataType(dataType, columnProps.align);
|
|
362
441
|
|
|
363
442
|
// Get cell renderer
|
|
364
|
-
const
|
|
443
|
+
const baseCellRenderer = getCellRendererByDataType(
|
|
365
444
|
dataType,
|
|
366
445
|
columnProps.render
|
|
367
446
|
? (params) =>
|
|
@@ -380,6 +459,24 @@ function ArchbaseDataGridAG<T extends object = any, ID = any>(
|
|
|
380
459
|
}
|
|
381
460
|
);
|
|
382
461
|
|
|
462
|
+
// Quando truncate=true, envolve o conteúdo num span que ativa o
|
|
463
|
+
// ellipsis (cssClass adicionada à cell faz o flex item interno
|
|
464
|
+
// encolher — ver ensureTruncateStyleInjected).
|
|
465
|
+
const cellRenderer = columnProps.truncate
|
|
466
|
+
? (params: any) => {
|
|
467
|
+
const titleValue = params.value == null ? '' : String(params.value);
|
|
468
|
+
return (
|
|
469
|
+
<span title={titleValue} className={ARCHBASE_TRUNCATE_TEXT_CLASS}>
|
|
470
|
+
{baseCellRenderer(params)}
|
|
471
|
+
</span>
|
|
472
|
+
);
|
|
473
|
+
}
|
|
474
|
+
: baseCellRenderer;
|
|
475
|
+
|
|
476
|
+
if (columnProps.truncate) {
|
|
477
|
+
ensureTruncateStyleInjected();
|
|
478
|
+
}
|
|
479
|
+
|
|
383
480
|
// Create value getter for nested fields
|
|
384
481
|
const valueGetter = columnProps.dataField.includes('.')
|
|
385
482
|
? (params: any) => {
|
|
@@ -427,7 +524,9 @@ function ArchbaseDataGridAG<T extends object = any, ID = any>(
|
|
|
427
524
|
: alignment === 'right'
|
|
428
525
|
? 'flex-end'
|
|
429
526
|
: 'center',
|
|
527
|
+
...(columnProps.truncate ? { overflow: 'hidden' } : {}),
|
|
430
528
|
},
|
|
529
|
+
cellClass: columnProps.truncate ? ARCHBASE_TRUNCATE_CELL_CLASS : undefined,
|
|
431
530
|
// Custom properties
|
|
432
531
|
enableGlobalFilter: columnProps.enableGlobalFilter,
|
|
433
532
|
dataType: columnProps.dataType,
|
|
@@ -441,7 +540,7 @@ function ArchbaseDataGridAG<T extends object = any, ID = any>(
|
|
|
441
540
|
|
|
442
541
|
return cols;
|
|
443
542
|
}, [
|
|
444
|
-
|
|
543
|
+
stableChildren,
|
|
445
544
|
enableRowActions,
|
|
446
545
|
renderRowActions,
|
|
447
546
|
actionsColumnWidth,
|
|
@@ -494,6 +593,18 @@ function ArchbaseDataGridAG<T extends object = any, ID = any>(
|
|
|
494
593
|
};
|
|
495
594
|
}, [enableRowSelection]);
|
|
496
595
|
|
|
596
|
+
// Estabiliza a referência do getRowId — recomendação da AG-Grid: prop
|
|
597
|
+
// instável invalida o mapeamento interno de linhas e quebra o React.memo do
|
|
598
|
+
// AgGridReactMemo. Junto com columnDefs estável (via useStableChildren),
|
|
599
|
+
// garante que o memo realmente faça o seu trabalho.
|
|
600
|
+
const stableGetRowIdAG = useCallback(
|
|
601
|
+
(params: GetRowIdParams<T>) => {
|
|
602
|
+
const id = safeGetRowId(params.data, getRowId);
|
|
603
|
+
return id !== undefined ? String(id) : '';
|
|
604
|
+
},
|
|
605
|
+
[getRowId]
|
|
606
|
+
);
|
|
607
|
+
|
|
497
608
|
// Grid ready handler
|
|
498
609
|
const onGridReady = useCallback((event: GridReadyEvent) => {
|
|
499
610
|
gridApiRef.current = event.api;
|
|
@@ -1164,7 +1275,7 @@ function ArchbaseDataGridAG<T extends object = any, ID = any>(
|
|
|
1164
1275
|
|
|
1165
1276
|
{/* AG Grid */}
|
|
1166
1277
|
<Box style={{ flex: 1, overflow: 'hidden', position: 'relative', minHeight: 0, ...cssVars }}>
|
|
1167
|
-
<
|
|
1278
|
+
<AgGridReactMemo
|
|
1168
1279
|
theme={agGridTheme}
|
|
1169
1280
|
rowData={rows}
|
|
1170
1281
|
columnDefs={columnDefs}
|
|
@@ -1175,10 +1286,7 @@ function ArchbaseDataGridAG<T extends object = any, ID = any>(
|
|
|
1175
1286
|
onCellDoubleClicked={onCellDoubleClicked}
|
|
1176
1287
|
onSortChanged={onSortChanged}
|
|
1177
1288
|
onFilterChanged={onFilterChanged}
|
|
1178
|
-
getRowId={
|
|
1179
|
-
const id = safeGetRowId(params.data, getRowId);
|
|
1180
|
-
return id !== undefined ? String(id) : '';
|
|
1181
|
-
}}
|
|
1289
|
+
getRowId={stableGetRowIdAG}
|
|
1182
1290
|
rowHeight={rowHeight}
|
|
1183
1291
|
headerHeight={40}
|
|
1184
1292
|
loading={isLoadingInternal || isLoading}
|
|
@@ -1190,6 +1298,11 @@ function ArchbaseDataGridAG<T extends object = any, ID = any>(
|
|
|
1190
1298
|
suppressScrollOnNewData={true}
|
|
1191
1299
|
enableCellTextSelection={true}
|
|
1192
1300
|
ensureDomOrder={true}
|
|
1301
|
+
// Perf — recomendações da doc oficial AG-Grid (scrolling-performance):
|
|
1302
|
+
// mantém apenas N linhas extra renderizadas fora do viewport.
|
|
1303
|
+
rowBuffer={10}
|
|
1304
|
+
// Desliga o highlight de hover quando o usuário pediu (perf win).
|
|
1305
|
+
suppressRowHoverHighlight={!highlightOnHover}
|
|
1193
1306
|
/>
|
|
1194
1307
|
</Box>
|
|
1195
1308
|
|
|
@@ -156,7 +156,7 @@ function ArchbaseDataGrid<T extends object = any, ID = any>(props: ArchbaseDataG
|
|
|
156
156
|
csvOptions,
|
|
157
157
|
toolbarAlignment = 'right',
|
|
158
158
|
positionActionsColumn = 'first',
|
|
159
|
-
actionsColumnWidth =
|
|
159
|
+
actionsColumnWidth = 120,
|
|
160
160
|
toolbarLeftContent,
|
|
161
161
|
columnAutoWidth = false,
|
|
162
162
|
rowHeight = 52,
|
|
Binary file
|