@cratis/components 4.26.3 → 4.27.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/compat-manifest.json +11 -11
- package/dist/esm/Common/CratisComponentsProvider.d.ts +4 -0
- package/dist/esm/Common/CratisComponentsProvider.d.ts.map +1 -1
- package/dist/esm/Common/CratisComponentsProvider.js +1 -0
- package/dist/esm/Common/CratisComponentsProvider.js.map +1 -1
- package/dist/esm/DataPage/DataPage.d.ts +2 -0
- package/dist/esm/DataPage/DataPage.d.ts.map +1 -1
- package/dist/esm/DataPage/DataPage.js.map +1 -1
- package/dist/esm/DataTables/DataTableForObservableQuery.d.ts +2 -0
- package/dist/esm/DataTables/DataTableForObservableQuery.d.ts.map +1 -1
- package/dist/esm/DataTables/DataTableForObservableQuery.js +1 -1
- package/dist/esm/DataTables/DataTableForObservableQuery.js.map +1 -1
- package/dist/esm/DataTables/DataTableForQuery.d.ts +2 -0
- package/dist/esm/DataTables/DataTableForQuery.d.ts.map +1 -1
- package/dist/esm/DataTables/DataTableForQuery.js +1 -1
- package/dist/esm/DataTables/DataTableForQuery.js.map +1 -1
- package/dist/esm/DataTables/PaginatorPageItem.d.ts +13 -0
- package/dist/esm/DataTables/PaginatorPageItem.d.ts.map +1 -0
- package/dist/esm/DataTables/PaginatorPageItem.js +4 -0
- package/dist/esm/DataTables/PaginatorPageItem.js.map +1 -0
- package/dist/esm/DataTables/TablePaginator.d.ts +22 -2
- package/dist/esm/DataTables/TablePaginator.d.ts.map +1 -1
- package/dist/esm/DataTables/TablePaginator.js.map +1 -1
- package/dist/esm/DataTables/TablePaginatorImplementation.d.ts +1 -1
- package/dist/esm/DataTables/TablePaginatorImplementation.d.ts.map +1 -1
- package/dist/esm/DataTables/TablePaginatorImplementation.js +8 -3
- package/dist/esm/DataTables/TablePaginatorImplementation.js.map +1 -1
- package/dist/esm/DataTables/TablePaginatorPages.d.ts +9 -0
- package/dist/esm/DataTables/TablePaginatorPages.d.ts.map +1 -0
- package/dist/esm/DataTables/TablePaginatorPages.js +20 -0
- package/dist/esm/DataTables/TablePaginatorPages.js.map +1 -0
- package/dist/esm/DataTables/index.d.ts +2 -0
- package/dist/esm/DataTables/index.d.ts.map +1 -1
- package/dist/esm/DataTables/index.js +1 -0
- package/dist/esm/DataTables/index.js.map +1 -1
- package/dist/esm/DataTables/paginatorPages.d.ts +15 -0
- package/dist/esm/DataTables/paginatorPages.d.ts.map +1 -0
- package/dist/esm/DataTables/paginatorPages.js +40 -0
- package/dist/esm/DataTables/paginatorPages.js.map +1 -0
- package/dist/esm/Filter/FilterGroup.d.ts +23 -0
- package/dist/esm/Filter/FilterGroup.d.ts.map +1 -0
- package/dist/esm/Filter/FilterGroup.js +51 -0
- package/dist/esm/Filter/FilterGroup.js.map +1 -0
- package/dist/esm/Filter/FilterPanel.d.ts.map +1 -1
- package/dist/esm/Filter/FilterPanel.js +24 -257
- package/dist/esm/Filter/FilterPanel.js.map +1 -1
- package/dist/esm/Filter/FilterSearchBox.d.ts +10 -0
- package/dist/esm/Filter/FilterSearchBox.d.ts.map +1 -0
- package/dist/esm/Filter/FilterSearchBox.js +10 -0
- package/dist/esm/Filter/FilterSearchBox.js.map +1 -0
- package/dist/esm/Filter/measurePanelPlacement.d.ts +31 -0
- package/dist/esm/Filter/measurePanelPlacement.d.ts.map +1 -0
- package/dist/esm/Filter/measurePanelPlacement.js +132 -0
- package/dist/esm/Filter/measurePanelPlacement.js.map +1 -0
- package/dist/esm/Filter/usePanelDismissal.d.ts +32 -0
- package/dist/esm/Filter/usePanelDismissal.d.ts.map +1 -0
- package/dist/esm/Filter/usePanelDismissal.js +63 -0
- package/dist/esm/Filter/usePanelDismissal.js.map +1 -0
- package/dist/esm/Filter/usePanelPosition.d.ts +24 -0
- package/dist/esm/Filter/usePanelPosition.d.ts.map +1 -0
- package/dist/esm/Filter/usePanelPosition.js +85 -0
- package/dist/esm/Filter/usePanelPosition.js.map +1 -0
- package/dist/esm/Filter/useResolvedAnchor.d.ts +17 -0
- package/dist/esm/Filter/useResolvedAnchor.d.ts.map +1 -0
- package/dist/esm/Filter/useResolvedAnchor.js +16 -0
- package/dist/esm/Filter/useResolvedAnchor.js.map +1 -0
- package/dist/esm/PivotViewer/PivotViewer.d.ts.map +1 -1
- package/dist/esm/PivotViewer/PivotViewer.js +47 -207
- package/dist/esm/PivotViewer/PivotViewer.js.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/sprites.js +1 -1
- package/dist/esm/PivotViewer/components/pivot/syncScrollSprites.d.ts +2 -2
- package/dist/esm/PivotViewer/components/pivot/syncScrollSprites.d.ts.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/syncScrollSprites.js +1 -1
- package/dist/esm/PivotViewer/components/pivot/syncScrollSprites.js.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/usePivotScrollSync.d.ts.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/usePivotScrollSync.js +8 -2
- package/dist/esm/PivotViewer/components/pivot/usePivotScrollSync.js.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/usePivotSpriteSync.d.ts.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/usePivotSpriteSync.js +49 -28
- package/dist/esm/PivotViewer/components/pivot/usePivotSpriteSync.js.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/visibility.d.ts +12 -2
- package/dist/esm/PivotViewer/components/pivot/visibility.d.ts.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/visibility.js +34 -194
- package/dist/esm/PivotViewer/components/pivot/visibility.js.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/visibilityHelpers.d.ts +114 -0
- package/dist/esm/PivotViewer/components/pivot/visibilityHelpers.d.ts.map +1 -0
- package/dist/esm/PivotViewer/components/pivot/visibilityHelpers.js +306 -0
- package/dist/esm/PivotViewer/components/pivot/visibilityHelpers.js.map +1 -0
- package/dist/esm/PivotViewer/hooks/useColorCssVariables.d.ts +9 -0
- package/dist/esm/PivotViewer/hooks/useColorCssVariables.d.ts.map +1 -0
- package/dist/esm/PivotViewer/hooks/useColorCssVariables.js +32 -0
- package/dist/esm/PivotViewer/hooks/useColorCssVariables.js.map +1 -0
- package/dist/esm/PivotViewer/hooks/usePivotViewerGrouping.d.ts +27 -0
- package/dist/esm/PivotViewer/hooks/usePivotViewerGrouping.d.ts.map +1 -0
- package/dist/esm/PivotViewer/hooks/usePivotViewerGrouping.js +40 -0
- package/dist/esm/PivotViewer/hooks/usePivotViewerGrouping.js.map +1 -0
- package/dist/esm/PivotViewer/hooks/usePivotViewerInteractions.d.ts +27 -0
- package/dist/esm/PivotViewer/hooks/usePivotViewerInteractions.d.ts.map +1 -0
- package/dist/esm/PivotViewer/hooks/usePivotViewerInteractions.js +46 -0
- package/dist/esm/PivotViewer/hooks/usePivotViewerInteractions.js.map +1 -0
- package/dist/esm/PivotViewer/hooks/useRawGrouping.d.ts +22 -0
- package/dist/esm/PivotViewer/hooks/useRawGrouping.d.ts.map +1 -0
- package/dist/esm/PivotViewer/hooks/useRawGrouping.js +56 -0
- package/dist/esm/PivotViewer/hooks/useRawGrouping.js.map +1 -0
- package/dist/esm/PivotViewer/hooks/useScrollPositionTracking.d.ts +12 -0
- package/dist/esm/PivotViewer/hooks/useScrollPositionTracking.d.ts.map +1 -0
- package/dist/esm/PivotViewer/hooks/useScrollPositionTracking.js +20 -0
- package/dist/esm/PivotViewer/hooks/useScrollPositionTracking.js.map +1 -0
- package/dist/esm/PivotViewer/hooks/useViewerLayout.d.ts +16 -0
- package/dist/esm/PivotViewer/hooks/useViewerLayout.d.ts.map +1 -0
- package/dist/esm/PivotViewer/hooks/useViewerLayout.js +29 -0
- package/dist/esm/PivotViewer/hooks/useViewerLayout.js.map +1 -0
- package/dist/esm/PivotViewer/hooks/useVisibleIds.d.ts +21 -0
- package/dist/esm/PivotViewer/hooks/useVisibleIds.d.ts.map +1 -0
- package/dist/esm/PivotViewer/hooks/useVisibleIds.js +34 -0
- package/dist/esm/PivotViewer/hooks/useVisibleIds.js.map +1 -0
- package/dist/esm/configuration/CratisComponentsDefaults.d.ts.map +1 -1
- package/dist/esm/configuration/CratisComponentsDefaults.js +2 -0
- package/dist/esm/configuration/CratisComponentsDefaults.js.map +1 -1
- package/dist/esm/styles.DataPage.css +51 -6
- package/dist/esm/styles.DataTables.css +51 -6
- package/dist/esm/styles.SchemaEditor.css +51 -6
- package/dist/esm/styles.css +51 -6
- package/dist/esm/styles.renderer.builtin.css +51 -6
- package/dist/esm/types/parts.d.ts +4 -1
- package/dist/esm/types/parts.d.ts.map +1 -1
- package/dist/esm/types/parts.js +4 -1
- package/dist/esm/types/parts.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { useRef, useState, useEffect
|
|
3
|
-
import { usePivotEngine } from './hooks/usePivotEngine.js';
|
|
4
|
-
import { computeLayout } from './engine/layout.js';
|
|
2
|
+
import { useRef, useState, useEffect } from 'react';
|
|
5
3
|
import { useFilterState } from './hooks/useFilterState.js';
|
|
6
4
|
import { useDimensionState } from './hooks/useDimensionState.js';
|
|
7
5
|
import { useZoomState } from './hooks/useZoomState.js';
|
|
8
|
-
import { BASE_CARD_HEIGHT, BASE_CARD_WIDTH
|
|
6
|
+
import { BASE_CARD_HEIGHT, BASE_CARD_WIDTH } from './constants.js';
|
|
9
7
|
import { PivotViewerMain } from './components/PivotViewerMain.js';
|
|
10
8
|
import { FilterPanelContainer } from './components/FilterPanelContainer.js';
|
|
11
9
|
import { ToolbarContainer } from './components/ToolbarContainer.js';
|
|
@@ -14,18 +12,32 @@ import { usePanning } from './hooks/usePanning.js';
|
|
|
14
12
|
import { useWheelZoom } from './hooks/useWheelZoom.js';
|
|
15
13
|
import { useZoomScrollAnchor } from './hooks/useZoomScrollAnchor.js';
|
|
16
14
|
import 'react-dom';
|
|
17
|
-
import { useFieldExtractors } from './hooks/useFieldExtractors.js';
|
|
18
|
-
import { useCurrentFilters, useCurrentGroupBy } from './hooks/useCurrentFilters.js';
|
|
19
|
-
import { useCardSelection } from './hooks/useCardSelection.js';
|
|
20
|
-
import { useDetailPanelClose } from './hooks/useDetailPanelClose.js';
|
|
21
|
-
import { useScrollSync } from './hooks/useScrollSync.js';
|
|
22
|
-
import { useAnimationModeTracking } from './hooks/useAnimationModeTracking.js';
|
|
23
|
-
import { useViewModeScrollHandling } from './hooks/useViewModeScrollHandling.js';
|
|
24
15
|
import { useContainerDimensions } from './hooks/useContainerDimensions.js';
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
16
|
+
import { useColorCssVariables } from './hooks/useColorCssVariables.js';
|
|
17
|
+
import { useViewerLayout } from './hooks/useViewerLayout.js';
|
|
18
|
+
import { useScrollPositionTracking } from './hooks/useScrollPositionTracking.js';
|
|
19
|
+
import { usePivotViewerGrouping } from './hooks/usePivotViewerGrouping.js';
|
|
20
|
+
import { usePivotViewerInteractions } from './hooks/usePivotViewerInteractions.js';
|
|
28
21
|
|
|
22
|
+
function countActiveFilters(filterState, rangeFilterState) {
|
|
23
|
+
const selectionCount = Object.values(filterState).reduce((sum, vals) => sum + vals.size, 0);
|
|
24
|
+
return selectionCount + Object.values(rangeFilterState).filter((r) => r !== null).length;
|
|
25
|
+
}
|
|
26
|
+
function filtersClassName(hasFilters, filtersOpen) {
|
|
27
|
+
if (!hasFilters)
|
|
28
|
+
return 'no-filters';
|
|
29
|
+
return filtersOpen ? 'filters-open' : 'filters-closed';
|
|
30
|
+
}
|
|
31
|
+
function buildViewerClassName(className, hasFilters, filtersOpen, viewMode) {
|
|
32
|
+
return [
|
|
33
|
+
'pivot-viewer',
|
|
34
|
+
className,
|
|
35
|
+
filtersClassName(hasFilters, filtersOpen),
|
|
36
|
+
viewMode === 'grouped' ? 'grouped-mode' : 'collection-mode',
|
|
37
|
+
]
|
|
38
|
+
.filter(Boolean)
|
|
39
|
+
.join(' ');
|
|
40
|
+
}
|
|
29
41
|
function PivotViewer({ data, dimensions, filters, defaultDimensionKey, cardRenderer, detailRenderer, getItemId, searchFields, title, className, emptyContent, isLoading = false, loadingLabel, labels, colors, }) {
|
|
30
42
|
const containerRef = useRef(null);
|
|
31
43
|
const filterButtonRef = useRef(null);
|
|
@@ -36,8 +48,6 @@ function PivotViewer({ data, dimensions, filters, defaultDimensionKey, cardRende
|
|
|
36
48
|
const [filtersOpen, setFiltersOpen] = useState(false);
|
|
37
49
|
const [selectedItem, setSelectedItem] = useState(null);
|
|
38
50
|
const [isZooming, setIsZooming] = useState(false);
|
|
39
|
-
const [visibleIds, setVisibleIds] = useState(new Uint32Array(0));
|
|
40
|
-
const [rawGrouping, setRawGrouping] = useState({ groups: [] });
|
|
41
51
|
const [hoveredGroupIndex, setHoveredGroupIndex] = useState(null);
|
|
42
52
|
const [preSelectionState, setPreSelectionState] = useState(null);
|
|
43
53
|
const [, setAnimationMode] = useState('layout');
|
|
@@ -49,143 +59,22 @@ function PivotViewer({ data, dimensions, filters, defaultDimensionKey, cardRende
|
|
|
49
59
|
useWheelZoom(containerRef, zoomLevel, setZoomLevel);
|
|
50
60
|
useZoomScrollAnchor(containerRef, spacerRef, viewMode);
|
|
51
61
|
const containerDimensions = useContainerDimensions(containerRef, isLoading);
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (!container)
|
|
55
|
-
return;
|
|
56
|
-
const handleScroll = () => {
|
|
57
|
-
setScrollPosition({
|
|
58
|
-
x: container.scrollLeft,
|
|
59
|
-
y: container.scrollTop,
|
|
60
|
-
});
|
|
61
|
-
};
|
|
62
|
-
container.addEventListener('scroll', handleScroll);
|
|
63
|
-
return () => container.removeEventListener('scroll', handleScroll);
|
|
64
|
-
}, []);
|
|
65
|
-
const { fieldExtractors, indexFields } = useFieldExtractors(dimensions, filters);
|
|
66
|
-
const { ready, applyFilters: engineApplyFilters, computeGrouping, sortIds, } = usePivotEngine({
|
|
62
|
+
useScrollPositionTracking(containerRef, setScrollPosition);
|
|
63
|
+
const { ready, visibleIds, grouping } = usePivotViewerGrouping({
|
|
67
64
|
data,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if (!ready)
|
|
75
|
-
return;
|
|
76
|
-
let cancelled = false;
|
|
77
|
-
void engineApplyFilters(currentFilters).then((result) => {
|
|
78
|
-
if (cancelled)
|
|
79
|
-
return;
|
|
80
|
-
let ids = result.visibleIds;
|
|
81
|
-
if (ids.length === 0 && currentFilters.length === 0 && data.length > 0) {
|
|
82
|
-
const fallbackIds = new Uint32Array(data.length);
|
|
83
|
-
for (let i = 0; i < data.length; i++) {
|
|
84
|
-
fallbackIds[i] = i;
|
|
85
|
-
}
|
|
86
|
-
ids = fallbackIds;
|
|
87
|
-
}
|
|
88
|
-
setVisibleIds(filterVisibleIdsBySearch(data, ids, search, searchFields));
|
|
89
|
-
});
|
|
90
|
-
return () => {
|
|
91
|
-
cancelled = true;
|
|
92
|
-
};
|
|
93
|
-
}, [ready, currentFilters, engineApplyFilters, data, search, searchFields]);
|
|
94
|
-
useEffect(() => {
|
|
95
|
-
if (!ready || visibleIds.length === 0) {
|
|
96
|
-
setRawGrouping({ groups: [] });
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
let cancelled = false;
|
|
100
|
-
if (viewMode === 'collection') {
|
|
101
|
-
if (activeDimensionKey) {
|
|
102
|
-
void sortIds(visibleIds, activeDimensionKey).then((sortedIds) => {
|
|
103
|
-
if (cancelled)
|
|
104
|
-
return;
|
|
105
|
-
setRawGrouping({
|
|
106
|
-
groups: [
|
|
107
|
-
{
|
|
108
|
-
key: 'all',
|
|
109
|
-
label: 'All Items',
|
|
110
|
-
value: 'all',
|
|
111
|
-
ids: sortedIds,
|
|
112
|
-
count: sortedIds.length,
|
|
113
|
-
},
|
|
114
|
-
],
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
else {
|
|
119
|
-
setRawGrouping({
|
|
120
|
-
groups: [
|
|
121
|
-
{
|
|
122
|
-
key: 'all',
|
|
123
|
-
label: 'All Items',
|
|
124
|
-
value: 'all',
|
|
125
|
-
ids: visibleIds,
|
|
126
|
-
count: visibleIds.length,
|
|
127
|
-
},
|
|
128
|
-
],
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
else {
|
|
133
|
-
void computeGrouping(visibleIds, currentGroupBy).then((result) => {
|
|
134
|
-
if (!cancelled)
|
|
135
|
-
setRawGrouping(result);
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
return () => {
|
|
139
|
-
cancelled = true;
|
|
140
|
-
};
|
|
141
|
-
}, [
|
|
142
|
-
ready,
|
|
143
|
-
visibleIds,
|
|
144
|
-
currentGroupBy,
|
|
145
|
-
viewMode,
|
|
146
|
-
computeGrouping,
|
|
147
|
-
sortIds,
|
|
65
|
+
dimensions,
|
|
66
|
+
filters,
|
|
67
|
+
filterState,
|
|
68
|
+
rangeFilterState,
|
|
69
|
+
dimensionFilter,
|
|
70
|
+
activeDimension,
|
|
148
71
|
activeDimensionKey,
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
const layout = useMemo(() => {
|
|
152
|
-
const cardWidth = BASE_CARD_WIDTH;
|
|
153
|
-
const cardHeight = BASE_CARD_HEIGHT;
|
|
154
|
-
const containerWidth = containerDimensions.width / zoomLevel;
|
|
155
|
-
const containerHeight = viewMode === 'collection'
|
|
156
|
-
? containerDimensions.height / zoomLevel
|
|
157
|
-
: containerDimensions.height;
|
|
158
|
-
const result = computeLayout(grouping, {
|
|
159
|
-
viewMode,
|
|
160
|
-
cardWidth,
|
|
161
|
-
cardHeight,
|
|
162
|
-
cardsPerColumn: CARDS_PER_COLUMN,
|
|
163
|
-
containerWidth,
|
|
164
|
-
containerHeight,
|
|
165
|
-
});
|
|
166
|
-
return result;
|
|
167
|
-
}, [
|
|
168
|
-
grouping,
|
|
169
|
-
viewMode,
|
|
170
|
-
zoomLevel,
|
|
171
|
-
containerDimensions.width,
|
|
172
|
-
containerDimensions.height,
|
|
173
|
-
]);
|
|
174
|
-
const resolveId = useCallback((item) => resolveInternalItemIndex(data, item, getItemId), [data, getItemId]);
|
|
175
|
-
useAnimationModeTracking(filterState, rangeFilterState, search, activeDimensionKey, viewMode, setAnimationMode);
|
|
176
|
-
useScrollSync(containerRef, axisLabelsRef, viewMode);
|
|
177
|
-
useViewModeScrollHandling({
|
|
178
|
-
containerRef,
|
|
72
|
+
searchFields,
|
|
73
|
+
search,
|
|
179
74
|
viewMode,
|
|
180
|
-
grouping,
|
|
181
|
-
layout,
|
|
182
|
-
selectedItem,
|
|
183
|
-
zoomLevel,
|
|
184
|
-
resolveId,
|
|
185
|
-
data,
|
|
186
|
-
setPreSelectionState,
|
|
187
75
|
});
|
|
188
|
-
const
|
|
76
|
+
const layout = useViewerLayout(grouping, viewMode, zoomLevel, containerDimensions);
|
|
77
|
+
const { resolveId, handleCardClick, closeDetail } = usePivotViewerInteractions({
|
|
189
78
|
data,
|
|
190
79
|
isPanning,
|
|
191
80
|
selectedItem,
|
|
@@ -193,29 +82,18 @@ function PivotViewer({ data, dimensions, filters, defaultDimensionKey, cardRende
|
|
|
193
82
|
viewMode,
|
|
194
83
|
layout,
|
|
195
84
|
containerRef,
|
|
85
|
+
axisLabelsRef,
|
|
196
86
|
spacerRef,
|
|
197
87
|
containerDimensions,
|
|
198
88
|
scrollPosition,
|
|
199
89
|
preSelectionState,
|
|
200
90
|
grouping,
|
|
201
91
|
getItemId,
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
});
|
|
208
|
-
const closeDetail = useDetailPanelClose({
|
|
209
|
-
selectedItem,
|
|
210
|
-
preSelectionState,
|
|
211
|
-
zoomLevel,
|
|
212
|
-
viewMode,
|
|
213
|
-
layout,
|
|
214
|
-
containerRef,
|
|
215
|
-
containerDimensions,
|
|
216
|
-
grouping,
|
|
217
|
-
data,
|
|
218
|
-
resolveId,
|
|
92
|
+
filterState,
|
|
93
|
+
rangeFilterState,
|
|
94
|
+
search,
|
|
95
|
+
activeDimensionKey,
|
|
96
|
+
setAnimationMode,
|
|
219
97
|
setZoomLevel,
|
|
220
98
|
setIsZooming,
|
|
221
99
|
setSelectedItem,
|
|
@@ -225,50 +103,12 @@ function PivotViewer({ data, dimensions, filters, defaultDimensionKey, cardRende
|
|
|
225
103
|
const cardHeight = BASE_CARD_HEIGHT;
|
|
226
104
|
const filterOptions = useFilterOptions(data, filters, filterState, rangeFilterState);
|
|
227
105
|
const hasFilters = Boolean(filters && filters.length > 0);
|
|
228
|
-
const activeFilterCount =
|
|
229
|
-
const viewerClassName =
|
|
230
|
-
'pivot-viewer',
|
|
231
|
-
className,
|
|
232
|
-
hasFilters ? (filtersOpen ? 'filters-open' : 'filters-closed') : 'no-filters',
|
|
233
|
-
viewMode === 'grouped' ? 'grouped-mode' : 'collection-mode',
|
|
234
|
-
]
|
|
235
|
-
.filter(Boolean)
|
|
236
|
-
.join(' ');
|
|
106
|
+
const activeFilterCount = countActiveFilters(filterState, rangeFilterState);
|
|
107
|
+
const viewerClassName = buildViewerClassName(className, hasFilters, filtersOpen, viewMode);
|
|
237
108
|
useEffect(() => {
|
|
238
109
|
setSelectedItem(null);
|
|
239
110
|
}, [viewMode]);
|
|
240
|
-
const cssVariables =
|
|
241
|
-
const vars = {};
|
|
242
|
-
if (!colors)
|
|
243
|
-
return vars;
|
|
244
|
-
if (colors.primaryColor)
|
|
245
|
-
vars['--cratis-primary-color'] = colors.primaryColor;
|
|
246
|
-
if (colors.primaryColorText)
|
|
247
|
-
vars['--cratis-primary-color-text'] = colors.primaryColorText;
|
|
248
|
-
if (colors.primary500)
|
|
249
|
-
vars['--cratis-primary-500'] = colors.primary500;
|
|
250
|
-
if (colors.surfaceGround)
|
|
251
|
-
vars['--cratis-surface-ground'] = colors.surfaceGround;
|
|
252
|
-
if (colors.surfaceCard)
|
|
253
|
-
vars['--cratis-surface-card'] = colors.surfaceCard;
|
|
254
|
-
if (colors.surfaceSection)
|
|
255
|
-
vars['--cratis-surface-section'] = colors.surfaceSection;
|
|
256
|
-
if (colors.surfaceOverlay)
|
|
257
|
-
vars['--cratis-surface-overlay'] = colors.surfaceOverlay;
|
|
258
|
-
if (colors.surfaceBorder)
|
|
259
|
-
vars['--cratis-surface-border'] = colors.surfaceBorder;
|
|
260
|
-
if (colors.textColor)
|
|
261
|
-
vars['--cratis-text-color'] = colors.textColor;
|
|
262
|
-
if (colors.textColorSecondary)
|
|
263
|
-
vars['--cratis-text-color-secondary'] = colors.textColorSecondary;
|
|
264
|
-
if (colors.highlightBg)
|
|
265
|
-
vars['--cratis-highlight-bg'] = colors.highlightBg;
|
|
266
|
-
if (colors.maskbg)
|
|
267
|
-
vars['--cratis-maskbg'] = colors.maskbg;
|
|
268
|
-
if (colors.focusRing)
|
|
269
|
-
vars['--cratis-focus-ring'] = colors.focusRing;
|
|
270
|
-
return vars;
|
|
271
|
-
}, [colors]);
|
|
111
|
+
const cssVariables = useColorCssVariables(colors);
|
|
272
112
|
return (jsxs("div", { className: viewerClassName, style: cssVariables, children: [jsx(FilterPanelContainer, { isOpen: filtersOpen && hasFilters, filterLabel: labels?.filters, searchPlaceholder: labels?.search, searchGroup: labels?.searchGroup, search: search, filterState: filterState, rangeFilterState: rangeFilterState, expandedFilterKey: expandedFilterKey, filterOptions: filterOptions, anchorRef: filterButtonRef, onClose: () => setFiltersOpen(false), onSearchChange: setSearch, onFilterToggle: handleToggleFilter, onFilterClear: handleClearFilter, onRangeChange: handleRangeChange, onExpandedFilterChange: setExpandedFilterKey }), jsxs("main", { className: 'pv-main', children: [jsx(ToolbarContainer, { hasFilters: hasFilters, filtersOpen: filtersOpen, filteredCount: visibleIds.length, viewMode: viewMode, zoomLevel: zoomLevel, activeDimensionKey: activeDimensionKey, dimensions: dimensions, activeFilterCount: activeFilterCount, title: title, labels: labels, onFiltersToggle: () => setFiltersOpen((prev) => !prev), onViewModeChange: setViewMode, onZoomIn: handleZoomIn, onZoomOut: handleZoomOut, onZoomSlider: handleZoomSlider, onZoomReset: handleZoomReset, onZoomChange: handleZoomChange, onDimensionChange: setActiveDimensionKey, filterButtonRef: filterButtonRef }), jsx(PivotViewerMain, { data: data, ready: ready, isLoading: isLoading, loadingLabel: loadingLabel ?? labels?.loading ?? 'Loading…', viewportLabel: labels?.viewport ?? 'Card area', visibleIds: visibleIds, grouping: grouping, layout: layout, cardWidth: cardWidth, cardHeight: cardHeight, zoomLevel: zoomLevel, scrollPosition: scrollPosition, containerDimensions: containerDimensions, selectedItem: selectedItem, hoveredGroupIndex: hoveredGroupIndex, isZooming: isZooming, viewMode: viewMode, cardRenderer: cardRenderer, colorOverrides: colors, detailRenderer: detailRenderer, resolveId: resolveId, emptyContent: emptyContent, dimensionFilter: dimensionFilter, onCardClick: handleCardClick, onPanStart: handlePanStart, onPanMove: handlePanMove, onPanEnd: handlePanEnd, onGroupHover: setHoveredGroupIndex, onAxisLabelClick: handleAxisLabelClick, onCloseDetail: closeDetail, containerRef: containerRef, axisLabelsRef: axisLabelsRef, spacerRef: spacerRef })] })] }));
|
|
273
113
|
}
|
|
274
114
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PivotViewer.js","sources":["../../../PivotViewer/PivotViewer.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { PivotViewerProps } from './types';\nimport type { GroupingResult } from './engine/types';\nimport { usePivotEngine } from './hooks/usePivotEngine';\nimport { computeLayout } from './engine/layout';\nimport { useFilterState } from './hooks/useFilterState';\nimport { useDimensionState } from './hooks/useDimensionState';\nimport { useZoomState } from './hooks/useZoomState';\nimport {\n BASE_CARD_WIDTH,\n BASE_CARD_HEIGHT,\n CARDS_PER_COLUMN,\n GROUP_SPACING,\n} from './constants';\nimport { PivotViewerMain } from './components/PivotViewerMain';\nimport { FilterPanelContainer } from './components/FilterPanelContainer';\nimport { ToolbarContainer } from './components/ToolbarContainer';\nimport { usePanning, useWheelZoom, useZoomScrollAnchor, useFilterOptions } from './hooks';\nimport { useContainerDimensions } from './hooks/useContainerDimensions';\nimport type { ViewMode } from './components/Toolbar';\nimport { useFieldExtractors } from './hooks/useFieldExtractors';\nimport { presentGrouping } from './utils/presentGrouping';\nimport { useCurrentFilters, useCurrentGroupBy } from './hooks/useCurrentFilters';\nimport { filterVisibleIdsBySearch } from './utils/search';\nimport { resolveInternalItemIndex } from './utils/idResolution';\nimport { useCardSelection } from './hooks/useCardSelection';\nimport { useDetailPanelClose } from './hooks/useDetailPanelClose';\nimport { useScrollSync } from './hooks/useScrollSync';\nimport { useAnimationModeTracking } from './hooks/useAnimationModeTracking';\nimport { useViewModeScrollHandling } from './hooks/useViewModeScrollHandling';\n\n/**\n * A faceted, zoomable card-grid visualization inspired by Microsoft's PivotViewer.\n * Renders a large set of items as cards that can be grouped by any of a set of\n * declared dimensions, filtered through faceted panels, searched by text, and\n * zoomed/panned around freely. A detail pane shows the selected card's full\n * information.\n *\n * Backed by PIXI.js for high-performance rendering, so it gracefully handles\n * thousands of items. Consumers supply their own `cardRenderer` and\n * `detailRenderer` to control card and detail content; the component handles\n * grouping, filtering, panning, zooming, and selection internally.\n *\n * Use this for exploratory data analysis UIs over large collections (catalogs,\n * inventories, telemetry samples). For tabular display, use {@link DataPage}\n * or {@link DataTableForQuery}.\n *\n * @typeParam TItem - The item type contained in {@link PivotViewerProps.data}.\n * @param props - {@link PivotViewerProps}.\n */\nexport function PivotViewer<TItem extends object>({\n data,\n dimensions,\n filters,\n defaultDimensionKey,\n cardRenderer,\n detailRenderer,\n getItemId,\n searchFields,\n title,\n className,\n emptyContent,\n isLoading = false,\n loadingLabel,\n labels,\n colors,\n}: PivotViewerProps<TItem>) {\n // Refs\n const containerRef = useRef<HTMLDivElement>(null!);\n const filterButtonRef = useRef<HTMLButtonElement>(null!);\n const axisLabelsRef = useRef<HTMLDivElement>(null!);\n const spacerRef = useRef<HTMLDivElement>(null!);\n\n // State\n const [search, setSearch] = useState('');\n const [viewMode, setViewMode] = useState<ViewMode>('collection');\n const [filtersOpen, setFiltersOpen] = useState(false);\n const [selectedItem, setSelectedItem] = useState<TItem | null>(null);\n const [isZooming, setIsZooming] = useState(false);\n const [visibleIds, setVisibleIds] = useState<Uint32Array>(new Uint32Array(0));\n const [rawGrouping, setRawGrouping] = useState<GroupingResult>({ groups: [] });\n const [hoveredGroupIndex, setHoveredGroupIndex] = useState<number | null>(null);\n const [preSelectionState, setPreSelectionState] = useState<{\n zoom: number;\n scrollLeft: number;\n scrollTop: number;\n } | null>(null);\n const [, setAnimationMode] = useState<'layout' | 'filter'>('layout');\n const [scrollPosition, setScrollPosition] = useState({ x: 0, y: 0 });\n\n // Filter hooks\n const {\n filterState,\n rangeFilterState,\n expandedFilterKey,\n setExpandedFilterKey,\n handleToggleFilter,\n handleClearFilter,\n handleRangeChange,\n } = useFilterState(filters);\n\n // Dimension hooks\n const {\n activeDimensionKey,\n setActiveDimensionKey,\n activeDimension,\n dimensionFilter,\n handleAxisLabelClick,\n } = useDimensionState(dimensions, defaultDimensionKey);\n\n // Zoom and pan hooks\n const {\n zoomLevel,\n setZoomLevel,\n handleZoomIn,\n handleZoomOut,\n handleZoomSlider,\n handleZoomReset,\n handleZoomChange,\n } = useZoomState(1);\n\n const { isPanning, handlePanStart, handlePanMove, handlePanEnd } = usePanning(\n containerRef,\n undefined,\n setScrollPosition,\n );\n\n useWheelZoom(containerRef, zoomLevel, setZoomLevel);\n useZoomScrollAnchor(containerRef, spacerRef, viewMode);\n\n // Track container dimensions for responsive layout\n const containerDimensions = useContainerDimensions(containerRef, isLoading);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handleScroll = () => {\n setScrollPosition({\n x: container.scrollLeft,\n y: container.scrollTop,\n });\n };\n\n container.addEventListener('scroll', handleScroll);\n return () => container.removeEventListener('scroll', handleScroll);\n }, []);\n\n // Build field extractors for the columnar store\n const { fieldExtractors, indexFields } = useFieldExtractors(dimensions, filters);\n\n // Initialize the Web Worker engine\n const {\n ready,\n applyFilters: engineApplyFilters,\n computeGrouping,\n sortIds,\n } = usePivotEngine({\n data,\n fieldExtractors,\n indexFields,\n });\n\n // Build filter specs from UI state\n const currentFilters = useCurrentFilters(\n filters,\n filterState,\n rangeFilterState,\n dimensionFilter,\n activeDimension,\n );\n\n const currentGroupBy = useCurrentGroupBy(activeDimensionKey, dimensions);\n\n // Apply filters, then narrow the result by search - a post-filter step over the visible\n // Uint32 ids so it applies identically whether the engine result came from the worker or\n // its synchronous fallback.\n useEffect(() => {\n if (!ready) return;\n\n let cancelled = false;\n void engineApplyFilters(currentFilters).then((result) => {\n if (cancelled) return;\n let ids = result.visibleIds;\n\n // If the engine failed to return any IDs while no filters are active,\n // fall back to showing the full dataset so the canvas never renders empty.\n if (ids.length === 0 && currentFilters.length === 0 && data.length > 0) {\n const fallbackIds = new Uint32Array(data.length);\n for (let i = 0; i < data.length; i++) {\n fallbackIds[i] = i;\n }\n ids = fallbackIds;\n }\n\n setVisibleIds(filterVisibleIdsBySearch(data, ids, search, searchFields));\n });\n return () => {\n cancelled = true;\n };\n }, [ready, currentFilters, engineApplyFilters, data, search, searchFields]);\n\n // Compute grouping. Every async branch ignores a result after its dependencies change, so an\n // older worker response can never overwrite a newer filter/search/view selection.\n useEffect(() => {\n if (!ready || visibleIds.length === 0) {\n setRawGrouping({ groups: [] });\n return;\n }\n\n let cancelled = false;\n if (viewMode === 'collection') {\n // In collection mode, create a single group with all items.\n if (activeDimensionKey) {\n void sortIds(visibleIds, activeDimensionKey).then((sortedIds) => {\n if (cancelled) return;\n setRawGrouping({\n groups: [\n {\n key: 'all',\n label: 'All Items',\n value: 'all',\n ids: sortedIds,\n count: sortedIds.length,\n },\n ],\n });\n });\n } else {\n setRawGrouping({\n groups: [\n {\n key: 'all',\n label: 'All Items',\n value: 'all',\n ids: visibleIds,\n count: visibleIds.length,\n },\n ],\n });\n }\n } else {\n void computeGrouping(visibleIds, currentGroupBy).then((result) => {\n if (!cancelled) setRawGrouping(result);\n });\n }\n\n return () => {\n cancelled = true;\n };\n }, [\n ready,\n visibleIds,\n currentGroupBy,\n viewMode,\n computeGrouping,\n sortIds,\n activeDimensionKey,\n ]);\n\n const grouping = useMemo(\n () => viewMode === 'grouped' ? presentGrouping(rawGrouping, activeDimension, data) : rawGrouping,\n [viewMode, rawGrouping, activeDimension, data],\n );\n\n // Compute layout\n const layout = useMemo(() => {\n // Calculate layout at base dimensions (zoom is applied as transform)\n const cardWidth = BASE_CARD_WIDTH;\n const cardHeight = BASE_CARD_HEIGHT;\n const containerWidth = containerDimensions.width / zoomLevel;\n // For grouped mode, use fixed container height to ensure stable layout during zoom\n const containerHeight =\n viewMode === 'collection'\n ? containerDimensions.height / zoomLevel\n : containerDimensions.height;\n\n const result = computeLayout(grouping, {\n viewMode,\n cardWidth,\n cardHeight,\n cardsPerColumn: CARDS_PER_COLUMN,\n groupSpacing: GROUP_SPACING,\n containerWidth,\n containerHeight,\n });\n\n return result;\n }, [\n grouping,\n viewMode,\n zoomLevel,\n containerDimensions.width,\n containerDimensions.height,\n ]);\n\n const resolveId = useCallback(\n (item: TItem) => resolveInternalItemIndex(data, item, getItemId),\n [data, getItemId],\n );\n\n // Track animation mode changes\n useAnimationModeTracking(\n filterState,\n rangeFilterState,\n search,\n activeDimensionKey,\n viewMode,\n setAnimationMode,\n );\n\n // Sync axis labels scroll with container scroll\n useScrollSync(containerRef, axisLabelsRef, viewMode);\n\n // Handle scroll positioning when switching view modes or grouping changes\n useViewModeScrollHandling({\n containerRef,\n viewMode,\n grouping,\n layout,\n selectedItem,\n zoomLevel,\n resolveId,\n data,\n setPreSelectionState,\n });\n\n // Handle card selection (click)\n const handleCardClick = useCardSelection({\n data,\n isPanning,\n selectedItem,\n zoomLevel,\n viewMode,\n layout,\n containerRef,\n spacerRef,\n containerDimensions,\n scrollPosition,\n preSelectionState,\n grouping,\n getItemId,\n resolveId,\n setZoomLevel,\n setIsZooming,\n setSelectedItem,\n setPreSelectionState,\n });\n\n // Handle detail panel close\n const closeDetail = useDetailPanelClose({\n selectedItem,\n preSelectionState,\n zoomLevel,\n viewMode,\n layout,\n containerRef,\n containerDimensions,\n grouping,\n data,\n resolveId,\n setZoomLevel,\n setIsZooming,\n setSelectedItem,\n setPreSelectionState,\n });\n\n // Use base card dimensions - zoom is applied as transform in canvas\n const cardWidth = BASE_CARD_WIDTH;\n const cardHeight = BASE_CARD_HEIGHT;\n\n // Calculate filter options\n const filterOptions = useFilterOptions(data, filters, filterState, rangeFilterState);\n\n const hasFilters = Boolean(filters && filters.length > 0);\n const activeFilterCount =\n Object.values(filterState).reduce(\n (sum: number, vals) => sum + (vals as Set<string>).size,\n 0,\n ) + Object.values(rangeFilterState).filter((r) => r !== null).length;\n\n const viewerClassName = [\n 'pivot-viewer',\n className,\n hasFilters ? (filtersOpen ? 'filters-open' : 'filters-closed') : 'no-filters',\n viewMode === 'grouped' ? 'grouped-mode' : 'collection-mode',\n ]\n .filter(Boolean)\n .join(' ');\n\n // Deselect any selected card when switching between view modes\n useEffect(() => {\n setSelectedItem(null);\n }, [viewMode]);\n\n // Map provided color overrides to CSS variables understood by the component.\n const cssVariables = useMemo(() => {\n const vars: Record<string, string> = {};\n if (!colors) return vars;\n if (colors.primaryColor) vars['--cratis-primary-color'] = colors.primaryColor;\n if (colors.primaryColorText)\n vars['--cratis-primary-color-text'] = colors.primaryColorText;\n if (colors.primary500) vars['--cratis-primary-500'] = colors.primary500;\n if (colors.surfaceGround) vars['--cratis-surface-ground'] = colors.surfaceGround;\n if (colors.surfaceCard) vars['--cratis-surface-card'] = colors.surfaceCard;\n if (colors.surfaceSection)\n vars['--cratis-surface-section'] = colors.surfaceSection;\n if (colors.surfaceOverlay)\n vars['--cratis-surface-overlay'] = colors.surfaceOverlay;\n if (colors.surfaceBorder) vars['--cratis-surface-border'] = colors.surfaceBorder;\n if (colors.textColor) vars['--cratis-text-color'] = colors.textColor;\n if (colors.textColorSecondary)\n vars['--cratis-text-color-secondary'] = colors.textColorSecondary;\n if (colors.highlightBg) vars['--cratis-highlight-bg'] = colors.highlightBg;\n if (colors.maskbg) vars['--cratis-maskbg'] = colors.maskbg;\n if (colors.focusRing) vars['--cratis-focus-ring'] = colors.focusRing;\n return vars;\n }, [colors]);\n\n return (\n <div className={viewerClassName} style={cssVariables as React.CSSProperties}>\n <FilterPanelContainer\n isOpen={filtersOpen && hasFilters}\n filterLabel={labels?.filters}\n searchPlaceholder={labels?.search}\n searchGroup={labels?.searchGroup}\n search={search}\n filterState={filterState}\n rangeFilterState={rangeFilterState}\n expandedFilterKey={expandedFilterKey}\n filterOptions={filterOptions}\n anchorRef={filterButtonRef}\n onClose={() => setFiltersOpen(false)}\n onSearchChange={setSearch}\n onFilterToggle={handleToggleFilter}\n onFilterClear={handleClearFilter}\n onRangeChange={handleRangeChange}\n onExpandedFilterChange={setExpandedFilterKey}\n />\n\n <main className='pv-main'>\n <ToolbarContainer\n hasFilters={hasFilters}\n filtersOpen={filtersOpen}\n filteredCount={visibleIds.length}\n viewMode={viewMode}\n zoomLevel={zoomLevel}\n activeDimensionKey={activeDimensionKey}\n dimensions={dimensions}\n activeFilterCount={activeFilterCount}\n title={title}\n labels={labels}\n onFiltersToggle={() => setFiltersOpen((prev) => !prev)}\n onViewModeChange={setViewMode}\n onZoomIn={handleZoomIn}\n onZoomOut={handleZoomOut}\n onZoomSlider={handleZoomSlider}\n onZoomReset={handleZoomReset}\n onZoomChange={handleZoomChange}\n onDimensionChange={setActiveDimensionKey}\n filterButtonRef={filterButtonRef}\n />\n\n <PivotViewerMain\n data={data}\n ready={ready}\n isLoading={isLoading}\n loadingLabel={loadingLabel ?? labels?.loading ?? 'Loading…'}\n viewportLabel={labels?.viewport ?? 'Card area'}\n visibleIds={visibleIds}\n grouping={grouping}\n layout={layout}\n cardWidth={cardWidth}\n cardHeight={cardHeight}\n zoomLevel={zoomLevel}\n scrollPosition={scrollPosition}\n containerDimensions={containerDimensions}\n selectedItem={selectedItem}\n hoveredGroupIndex={hoveredGroupIndex}\n isZooming={isZooming}\n viewMode={viewMode}\n cardRenderer={cardRenderer}\n colorOverrides={colors}\n detailRenderer={detailRenderer}\n resolveId={resolveId}\n emptyContent={emptyContent}\n dimensionFilter={dimensionFilter}\n onCardClick={handleCardClick}\n onPanStart={handlePanStart as (e: React.MouseEvent) => void}\n onPanMove={handlePanMove as (e: React.MouseEvent) => void}\n onPanEnd={handlePanEnd}\n onGroupHover={setHoveredGroupIndex}\n onAxisLabelClick={handleAxisLabelClick}\n onCloseDetail={closeDetail}\n containerRef={containerRef}\n axisLabelsRef={axisLabelsRef}\n spacerRef={spacerRef}\n />\n </main>\n </div>\n );\n}\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PivotViewer.js","sources":["../../../PivotViewer/PivotViewer.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { useEffect, useRef, useState } from 'react';\nimport type { PivotViewerProps } from './types';\nimport { useFilterState } from './hooks/useFilterState';\nimport { useDimensionState } from './hooks/useDimensionState';\nimport { useZoomState } from './hooks/useZoomState';\nimport { BASE_CARD_WIDTH, BASE_CARD_HEIGHT } from './constants';\nimport { PivotViewerMain } from './components/PivotViewerMain';\nimport { FilterPanelContainer } from './components/FilterPanelContainer';\nimport { ToolbarContainer } from './components/ToolbarContainer';\nimport { usePanning, useWheelZoom, useZoomScrollAnchor, useFilterOptions } from './hooks';\nimport { useContainerDimensions } from './hooks/useContainerDimensions';\nimport type { ViewMode } from './components/Toolbar';\nimport { useColorCssVariables } from './hooks/useColorCssVariables';\nimport { useViewerLayout } from './hooks/useViewerLayout';\nimport { useScrollPositionTracking } from './hooks/useScrollPositionTracking';\nimport { usePivotViewerGrouping } from './hooks/usePivotViewerGrouping';\nimport { usePivotViewerInteractions } from './hooks/usePivotViewerInteractions';\n\nfunction countActiveFilters(\n filterState: Record<string, unknown>,\n rangeFilterState: Record<string, unknown>,\n): number {\n const selectionCount = Object.values(filterState).reduce(\n (sum: number, vals) => sum + (vals as Set<string>).size,\n 0,\n );\n return selectionCount + Object.values(rangeFilterState).filter((r) => r !== null).length;\n}\n\nfunction filtersClassName(hasFilters: boolean, filtersOpen: boolean): string {\n if (!hasFilters) return 'no-filters';\n return filtersOpen ? 'filters-open' : 'filters-closed';\n}\n\nfunction buildViewerClassName(\n className: string | undefined,\n hasFilters: boolean,\n filtersOpen: boolean,\n viewMode: ViewMode,\n): string {\n return [\n 'pivot-viewer',\n className,\n filtersClassName(hasFilters, filtersOpen),\n viewMode === 'grouped' ? 'grouped-mode' : 'collection-mode',\n ]\n .filter(Boolean)\n .join(' ');\n}\n\n/**\n * A faceted, zoomable card-grid visualization inspired by Microsoft's PivotViewer.\n * Renders a large set of items as cards that can be grouped by any of a set of\n * declared dimensions, filtered through faceted panels, searched by text, and\n * zoomed/panned around freely. A detail pane shows the selected card's full\n * information.\n *\n * Backed by PIXI.js for high-performance rendering, so it gracefully handles\n * thousands of items. Consumers supply their own `cardRenderer` and\n * `detailRenderer` to control card and detail content; the component handles\n * grouping, filtering, panning, zooming, and selection internally.\n *\n * Use this for exploratory data analysis UIs over large collections (catalogs,\n * inventories, telemetry samples). For tabular display, use {@link DataPage}\n * or {@link DataTableForQuery}.\n *\n * @typeParam TItem - The item type contained in {@link PivotViewerProps.data}.\n * @param props - {@link PivotViewerProps}.\n */\nexport function PivotViewer<TItem extends object>({\n data,\n dimensions,\n filters,\n defaultDimensionKey,\n cardRenderer,\n detailRenderer,\n getItemId,\n searchFields,\n title,\n className,\n emptyContent,\n isLoading = false,\n loadingLabel,\n labels,\n colors,\n}: PivotViewerProps<TItem>) {\n // Refs\n const containerRef = useRef<HTMLDivElement>(null!);\n const filterButtonRef = useRef<HTMLButtonElement>(null!);\n const axisLabelsRef = useRef<HTMLDivElement>(null!);\n const spacerRef = useRef<HTMLDivElement>(null!);\n\n // State\n const [search, setSearch] = useState('');\n const [viewMode, setViewMode] = useState<ViewMode>('collection');\n const [filtersOpen, setFiltersOpen] = useState(false);\n const [selectedItem, setSelectedItem] = useState<TItem | null>(null);\n const [isZooming, setIsZooming] = useState(false);\n const [hoveredGroupIndex, setHoveredGroupIndex] = useState<number | null>(null);\n const [preSelectionState, setPreSelectionState] = useState<{\n zoom: number;\n scrollLeft: number;\n scrollTop: number;\n } | null>(null);\n const [, setAnimationMode] = useState<'layout' | 'filter'>('layout');\n const [scrollPosition, setScrollPosition] = useState({ x: 0, y: 0 });\n\n // Filter hooks\n const {\n filterState,\n rangeFilterState,\n expandedFilterKey,\n setExpandedFilterKey,\n handleToggleFilter,\n handleClearFilter,\n handleRangeChange,\n } = useFilterState(filters);\n\n // Dimension hooks\n const {\n activeDimensionKey,\n setActiveDimensionKey,\n activeDimension,\n dimensionFilter,\n handleAxisLabelClick,\n } = useDimensionState(dimensions, defaultDimensionKey);\n\n // Zoom and pan hooks\n const {\n zoomLevel,\n setZoomLevel,\n handleZoomIn,\n handleZoomOut,\n handleZoomSlider,\n handleZoomReset,\n handleZoomChange,\n } = useZoomState(1);\n\n const { isPanning, handlePanStart, handlePanMove, handlePanEnd } = usePanning(\n containerRef,\n undefined,\n setScrollPosition,\n );\n\n useWheelZoom(containerRef, zoomLevel, setZoomLevel);\n useZoomScrollAnchor(containerRef, spacerRef, viewMode);\n\n // Track container dimensions for responsive layout\n const containerDimensions = useContainerDimensions(containerRef, isLoading);\n\n useScrollPositionTracking(containerRef, setScrollPosition);\n\n const { ready, visibleIds, grouping } = usePivotViewerGrouping({\n data,\n dimensions,\n filters,\n filterState,\n rangeFilterState,\n dimensionFilter,\n activeDimension,\n activeDimensionKey,\n searchFields,\n search,\n viewMode,\n });\n\n const layout = useViewerLayout(grouping, viewMode, zoomLevel, containerDimensions);\n\n const { resolveId, handleCardClick, closeDetail } = usePivotViewerInteractions({\n data,\n isPanning,\n selectedItem,\n zoomLevel,\n viewMode,\n layout,\n containerRef,\n axisLabelsRef,\n spacerRef,\n containerDimensions,\n scrollPosition,\n preSelectionState,\n grouping,\n getItemId,\n filterState,\n rangeFilterState,\n search,\n activeDimensionKey,\n setAnimationMode,\n setZoomLevel,\n setIsZooming,\n setSelectedItem,\n setPreSelectionState,\n });\n\n // Use base card dimensions - zoom is applied as transform in canvas\n const cardWidth = BASE_CARD_WIDTH;\n const cardHeight = BASE_CARD_HEIGHT;\n\n // Calculate filter options\n const filterOptions = useFilterOptions(data, filters, filterState, rangeFilterState);\n\n const hasFilters = Boolean(filters && filters.length > 0);\n const activeFilterCount = countActiveFilters(filterState, rangeFilterState);\n const viewerClassName = buildViewerClassName(className, hasFilters, filtersOpen, viewMode);\n\n // Deselect any selected card when switching between view modes\n useEffect(() => {\n setSelectedItem(null);\n }, [viewMode]);\n\n const cssVariables = useColorCssVariables(colors);\n\n return (\n <div className={viewerClassName} style={cssVariables as React.CSSProperties}>\n <FilterPanelContainer\n isOpen={filtersOpen && hasFilters}\n filterLabel={labels?.filters}\n searchPlaceholder={labels?.search}\n searchGroup={labels?.searchGroup}\n search={search}\n filterState={filterState}\n rangeFilterState={rangeFilterState}\n expandedFilterKey={expandedFilterKey}\n filterOptions={filterOptions}\n anchorRef={filterButtonRef}\n onClose={() => setFiltersOpen(false)}\n onSearchChange={setSearch}\n onFilterToggle={handleToggleFilter}\n onFilterClear={handleClearFilter}\n onRangeChange={handleRangeChange}\n onExpandedFilterChange={setExpandedFilterKey}\n />\n\n <main className='pv-main'>\n <ToolbarContainer\n hasFilters={hasFilters}\n filtersOpen={filtersOpen}\n filteredCount={visibleIds.length}\n viewMode={viewMode}\n zoomLevel={zoomLevel}\n activeDimensionKey={activeDimensionKey}\n dimensions={dimensions}\n activeFilterCount={activeFilterCount}\n title={title}\n labels={labels}\n onFiltersToggle={() => setFiltersOpen((prev) => !prev)}\n onViewModeChange={setViewMode}\n onZoomIn={handleZoomIn}\n onZoomOut={handleZoomOut}\n onZoomSlider={handleZoomSlider}\n onZoomReset={handleZoomReset}\n onZoomChange={handleZoomChange}\n onDimensionChange={setActiveDimensionKey}\n filterButtonRef={filterButtonRef}\n />\n\n <PivotViewerMain\n data={data}\n ready={ready}\n isLoading={isLoading}\n loadingLabel={loadingLabel ?? labels?.loading ?? 'Loading…'}\n viewportLabel={labels?.viewport ?? 'Card area'}\n visibleIds={visibleIds}\n grouping={grouping}\n layout={layout}\n cardWidth={cardWidth}\n cardHeight={cardHeight}\n zoomLevel={zoomLevel}\n scrollPosition={scrollPosition}\n containerDimensions={containerDimensions}\n selectedItem={selectedItem}\n hoveredGroupIndex={hoveredGroupIndex}\n isZooming={isZooming}\n viewMode={viewMode}\n cardRenderer={cardRenderer}\n colorOverrides={colors}\n detailRenderer={detailRenderer}\n resolveId={resolveId}\n emptyContent={emptyContent}\n dimensionFilter={dimensionFilter}\n onCardClick={handleCardClick}\n onPanStart={handlePanStart as (e: React.MouseEvent) => void}\n onPanMove={handlePanMove as (e: React.MouseEvent) => void}\n onPanEnd={handlePanEnd}\n onGroupHover={setHoveredGroupIndex}\n onAxisLabelClick={handleAxisLabelClick}\n onCloseDetail={closeDetail}\n containerRef={containerRef}\n axisLabelsRef={axisLabelsRef}\n spacerRef={spacerRef}\n />\n </main>\n </div>\n );\n}\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as PIXI from 'pixi.js';
|
|
2
|
-
import { CARD_RADIUS,
|
|
2
|
+
import { CARD_RADIUS, CARD_PADDING, CARD_GAP } from './constants.js';
|
|
3
3
|
import { ellipsizeLine, ellipsizeBlock } from './ellipsize.js';
|
|
4
4
|
|
|
5
5
|
const VALUES_INSET = 65;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { LayoutResult } from '../../engine/types.js';
|
|
2
|
-
import { type SyncParams } from './visibility.js';
|
|
2
|
+
import { type SyncParams, type SyncResult } from './visibility.js';
|
|
3
3
|
/** Keep the scroll path's transition layout in sync with the normal render path. */
|
|
4
|
-
export declare function syncScrollSprites<TItem>(params: Omit<SyncParams<TItem>, 'prevLayout'>, previousLayout: LayoutResult | null):
|
|
4
|
+
export declare function syncScrollSprites<TItem>(params: Omit<SyncParams<TItem>, 'prevLayout'>, previousLayout: LayoutResult | null): SyncResult;
|
|
5
5
|
//# sourceMappingURL=syncScrollSprites.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syncScrollSprites.d.ts","sourceRoot":"","sources":["../../../../../PivotViewer/components/pivot/syncScrollSprites.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAoB,CAAC;AACvD,OAAO,EAAyB,KAAK,UAAU,EAAE,MAAM,iBAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"syncScrollSprites.d.ts","sourceRoot":"","sources":["../../../../../PivotViewer/components/pivot/syncScrollSprites.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAoB,CAAC;AACvD,OAAO,EAAyB,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAc,CAAC;AAEvF,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC,EAAE,cAAc,EAAE,YAAY,GAAG,IAAI,GAAG,UAAU,CAEvI"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { syncSpritesToViewport } from './visibility.js';
|
|
2
2
|
|
|
3
3
|
function syncScrollSprites(params, previousLayout) {
|
|
4
|
-
syncSpritesToViewport({ ...params, prevLayout: previousLayout });
|
|
4
|
+
return syncSpritesToViewport({ ...params, prevLayout: previousLayout });
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
export { syncScrollSprites };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syncScrollSprites.js","sources":["../../../../../PivotViewer/components/pivot/syncScrollSprites.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport type { LayoutResult } from '../../engine/types';\nimport { syncSpritesToViewport, type SyncParams } from './visibility';\n\n/** Keep the scroll path's transition layout in sync with the normal render path. */\nexport function syncScrollSprites<TItem>(params: Omit<SyncParams<TItem>, 'prevLayout'>, previousLayout: LayoutResult | null) {\n syncSpritesToViewport({ ...params, prevLayout: previousLayout });\n}\n"],"names":[],"mappings":";;AAOM,SAAU,iBAAiB,CAAQ,MAA6C,EAAE,cAAmC,EAAA;IACvH,qBAAqB,CAAC,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"syncScrollSprites.js","sources":["../../../../../PivotViewer/components/pivot/syncScrollSprites.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport type { LayoutResult } from '../../engine/types';\nimport { syncSpritesToViewport, type SyncParams, type SyncResult } from './visibility';\n\n/** Keep the scroll path's transition layout in sync with the normal render path. */\nexport function syncScrollSprites<TItem>(params: Omit<SyncParams<TItem>, 'prevLayout'>, previousLayout: LayoutResult | null): SyncResult {\n return syncSpritesToViewport({ ...params, prevLayout: previousLayout });\n}\n"],"names":[],"mappings":";;AAOM,SAAU,iBAAiB,CAAQ,MAA6C,EAAE,cAAmC,EAAA;IACvH,OAAO,qBAAqB,CAAC,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,CAAC;AAC3E;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePivotScrollSync.d.ts","sourceRoot":"","sources":["../../../../../PivotViewer/components/pivot/usePivotScrollSync.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAsB,CAAC;AAE/D;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,KAAK,SAAS,MAAM,+EAOpD,kBAAkB,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"usePivotScrollSync.d.ts","sourceRoot":"","sources":["../../../../../PivotViewer/components/pivot/usePivotScrollSync.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAsB,CAAC;AAE/D;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,KAAK,SAAS,MAAM,+EAOpD,kBAAkB,CAAC,KAAK,CAAC,SA6K3B,CAAC"}
|
|
@@ -17,10 +17,11 @@ const usePivotScrollSync = ({ props, stage, transition, cardColorsRef, onCardCli
|
|
|
17
17
|
const container = parentContainerRef.current;
|
|
18
18
|
const app = appRef.current;
|
|
19
19
|
const pendingRef = { scheduled: false };
|
|
20
|
+
let frameHandle = 0;
|
|
20
21
|
const processScroll = () => {
|
|
21
22
|
pendingRef.scheduled = false;
|
|
22
23
|
try {
|
|
23
|
-
syncScrollSprites({
|
|
24
|
+
const { pending } = syncScrollSprites({
|
|
24
25
|
root: rootRef.current,
|
|
25
26
|
groupsContainer: groupsContainerRef.current,
|
|
26
27
|
container: parentContainerRef.current,
|
|
@@ -47,6 +48,10 @@ const usePivotScrollSync = ({ props, stage, transition, cardColorsRef, onCardCli
|
|
|
47
48
|
prevScrollLeftRef.current = container.scrollLeft || 0;
|
|
48
49
|
needsRenderRef.current = true;
|
|
49
50
|
app.renderer?.render(app.stage);
|
|
51
|
+
if (pending) {
|
|
52
|
+
pendingRef.scheduled = true;
|
|
53
|
+
frameHandle = requestAnimationFrame(processScroll);
|
|
54
|
+
}
|
|
50
55
|
}
|
|
51
56
|
catch (e) {
|
|
52
57
|
console.error('[PivotCanvas] processScroll error', e);
|
|
@@ -55,12 +60,13 @@ const usePivotScrollSync = ({ props, stage, transition, cardColorsRef, onCardCli
|
|
|
55
60
|
const onScroll = () => {
|
|
56
61
|
if (!pendingRef.scheduled) {
|
|
57
62
|
pendingRef.scheduled = true;
|
|
58
|
-
requestAnimationFrame(processScroll);
|
|
63
|
+
frameHandle = requestAnimationFrame(processScroll);
|
|
59
64
|
}
|
|
60
65
|
};
|
|
61
66
|
container.addEventListener('scroll', onScroll, { passive: true });
|
|
62
67
|
return () => {
|
|
63
68
|
container.removeEventListener('scroll', onScroll);
|
|
69
|
+
cancelAnimationFrame(frameHandle);
|
|
64
70
|
};
|
|
65
71
|
}, [
|
|
66
72
|
pixiReady,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePivotScrollSync.js","sources":["../../../../../PivotViewer/components/pivot/usePivotScrollSync.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { useEffect } from 'react';\nimport { asReactMouseEvent } from './asReactMouseEvent';\nimport type { CardSprite } from './constants';\nimport {\n createCardSprite as createCardSpriteExternal,\n updateCardContent as updateCardContentExternal,\n} from './sprites';\nimport { syncScrollSprites } from './syncScrollSprites';\nimport type { PivotRenderContext } from './PivotRenderContext';\n\n/**\n * Syncs the card sprites once per animation frame while the viewport scrolls, natively or\n * programmatically.\n * @param context The props, stage, transition state and colors.\n */\nexport const usePivotScrollSync = <TItem extends object>({\n props,\n stage,\n transition,\n cardColorsRef,\n onCardClickRef,\n onPanStartRef,\n}: PivotRenderContext<TItem>) => {\n const {\n items,\n layout,\n grouping,\n visibleIds,\n cardWidth,\n cardHeight,\n zoomLevel,\n panX,\n panY,\n viewportWidth,\n viewportHeight,\n selectedId,\n viewMode,\n cardRenderer,\n resolveId,\n onPanStart,\n onCardClick,\n containerRef: parentContainerRef,\n } = props;\n const { rootRef, groupsContainerRef, spritesRef, appRef, needsRenderRef, pixiReady } =\n stage;\n const {\n isViewTransitionRef,\n transitionLayoutRef,\n transitionSeenIdsRef,\n prevScrollTopRef,\n prevScrollLeftRef,\n } = transition;\n\n // Listen to native scroll events on the parent container so we update the\n // Pixi world immediately when the user scrolls (native scrollbar or\n // programmatic). This ensures `syncSpritesToViewport` runs on scroll and\n // creates/destroys sprites as the viewport moves.\n useEffect(() => {\n if (\n !pixiReady ||\n !parentContainerRef ||\n !parentContainerRef.current ||\n !appRef.current ||\n !rootRef.current\n )\n return;\n\n const container = parentContainerRef.current;\n const app = appRef.current;\n\n // rAF-batched scroll handling: process scroll once per animation frame to avoid heavy synchronous work inside\n // the scroll event which causes jank and de-synchronisation between the\n // compositor and Pixi render updates.\n const pendingRef = { scheduled: false } as { scheduled: boolean };\n\n const processScroll = () => {\n pendingRef.scheduled = false;\n try {\n // Note: We delegate root/groups container positioning to syncSpritesToViewport\n // because it encapsulates the logic for conditional vertical alignment (offsetY)\n // in different view modes. Manually setting position here would overwrite that logic.\n\n syncScrollSprites(\n {\n root: rootRef.current,\n groupsContainer: groupsContainerRef.current,\n container: parentContainerRef.current,\n sprites: spritesRef.current,\n layout,\n visibleIds,\n items,\n cardWidth,\n cardHeight,\n panX,\n panY,\n zoomLevel,\n viewportWidth,\n viewportHeight,\n createCardSprite: (id: string | number, x: number, y: number) =>\n createCardSpriteExternal(\n id,\n x,\n y,\n items as TItem[],\n (item, e, id) => onCardClickRef.current(item, e, id),\n (e) => onPanStartRef.current(asReactMouseEvent(e)),\n cardWidth,\n cardHeight,\n cardColorsRef.current,\n cardRenderer,\n resolveId,\n ),\n updateCardContent: (sprite: CardSprite, item: TItem) =>\n updateCardContentExternal(\n sprite,\n item,\n selectedId,\n cardWidth,\n cardHeight,\n cardColorsRef.current,\n cardRenderer,\n ),\n isViewTransition: isViewTransitionRef.current,\n viewMode,\n transitionSeenIds: transitionSeenIdsRef.current,\n prevScrollTop: prevScrollTopRef.current,\n prevScrollLeft: prevScrollLeftRef.current,\n },\n transitionLayoutRef.current,\n );\n\n // Update previous scroll position for next frame\n prevScrollTopRef.current = container.scrollTop || 0;\n prevScrollLeftRef.current = container.scrollLeft || 0;\n needsRenderRef.current = true;\n app.renderer?.render(app.stage);\n } catch (e) {\n console.error('[PivotCanvas] processScroll error', e);\n }\n };\n\n const onScroll = () => {\n // schedule the work for the next animation frame\n if (!pendingRef.scheduled) {\n pendingRef.scheduled = true;\n requestAnimationFrame(processScroll);\n }\n };\n\n container.addEventListener('scroll', onScroll, { passive: true });\n\n return () => {\n container.removeEventListener('scroll', onScroll);\n };\n }, [\n pixiReady,\n layout,\n visibleIds,\n items,\n cardWidth,\n cardHeight,\n zoomLevel,\n viewportWidth,\n viewportHeight,\n panX,\n panY,\n grouping,\n viewMode,\n selectedId,\n onCardClick,\n onPanStart,\n appRef,\n cardColorsRef,\n groupsContainerRef,\n isViewTransitionRef,\n needsRenderRef,\n onCardClickRef,\n onPanStartRef,\n parentContainerRef,\n prevScrollLeftRef,\n prevScrollTopRef,\n rootRef,\n spritesRef,\n transitionLayoutRef,\n transitionSeenIdsRef,\n ]);\n};\n"],"names":["createCardSpriteExternal","updateCardContentExternal"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"usePivotScrollSync.js","sources":["../../../../../PivotViewer/components/pivot/usePivotScrollSync.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { useEffect } from 'react';\nimport { asReactMouseEvent } from './asReactMouseEvent';\nimport type { CardSprite } from './constants';\nimport {\n createCardSprite as createCardSpriteExternal,\n updateCardContent as updateCardContentExternal,\n} from './sprites';\nimport { syncScrollSprites } from './syncScrollSprites';\nimport type { PivotRenderContext } from './PivotRenderContext';\n\n/**\n * Syncs the card sprites once per animation frame while the viewport scrolls, natively or\n * programmatically.\n * @param context The props, stage, transition state and colors.\n */\nexport const usePivotScrollSync = <TItem extends object>({\n props,\n stage,\n transition,\n cardColorsRef,\n onCardClickRef,\n onPanStartRef,\n}: PivotRenderContext<TItem>) => {\n const {\n items,\n layout,\n grouping,\n visibleIds,\n cardWidth,\n cardHeight,\n zoomLevel,\n panX,\n panY,\n viewportWidth,\n viewportHeight,\n selectedId,\n viewMode,\n cardRenderer,\n resolveId,\n onPanStart,\n onCardClick,\n containerRef: parentContainerRef,\n } = props;\n const { rootRef, groupsContainerRef, spritesRef, appRef, needsRenderRef, pixiReady } =\n stage;\n const {\n isViewTransitionRef,\n transitionLayoutRef,\n transitionSeenIdsRef,\n prevScrollTopRef,\n prevScrollLeftRef,\n } = transition;\n\n // Listen to native scroll events on the parent container so we update the\n // Pixi world immediately when the user scrolls (native scrollbar or\n // programmatic). This ensures `syncSpritesToViewport` runs on scroll and\n // creates/destroys sprites as the viewport moves.\n useEffect(() => {\n if (\n !pixiReady ||\n !parentContainerRef ||\n !parentContainerRef.current ||\n !appRef.current ||\n !rootRef.current\n )\n return;\n\n const container = parentContainerRef.current;\n const app = appRef.current;\n\n // rAF-batched scroll handling: process scroll once per animation frame to avoid heavy synchronous work inside\n // the scroll event which causes jank and de-synchronisation between the\n // compositor and Pixi render updates.\n const pendingRef = { scheduled: false } as { scheduled: boolean };\n let frameHandle = 0;\n\n const processScroll = () => {\n pendingRef.scheduled = false;\n try {\n // Note: We delegate root/groups container positioning to syncSpritesToViewport\n // because it encapsulates the logic for conditional vertical alignment (offsetY)\n // in different view modes. Manually setting position here would overwrite that logic.\n\n const { pending } = syncScrollSprites(\n {\n root: rootRef.current,\n groupsContainer: groupsContainerRef.current,\n container: parentContainerRef.current,\n sprites: spritesRef.current,\n layout,\n visibleIds,\n items,\n cardWidth,\n cardHeight,\n panX,\n panY,\n zoomLevel,\n viewportWidth,\n viewportHeight,\n createCardSprite: (id: string | number, x: number, y: number) =>\n createCardSpriteExternal(\n id,\n x,\n y,\n items as TItem[],\n (item, e, id) => onCardClickRef.current(item, e, id),\n (e) => onPanStartRef.current(asReactMouseEvent(e)),\n cardWidth,\n cardHeight,\n cardColorsRef.current,\n cardRenderer,\n resolveId,\n ),\n updateCardContent: (sprite: CardSprite, item: TItem) =>\n updateCardContentExternal(\n sprite,\n item,\n selectedId,\n cardWidth,\n cardHeight,\n cardColorsRef.current,\n cardRenderer,\n ),\n isViewTransition: isViewTransitionRef.current,\n viewMode,\n transitionSeenIds: transitionSeenIdsRef.current,\n prevScrollTop: prevScrollTopRef.current,\n prevScrollLeft: prevScrollLeftRef.current,\n },\n transitionLayoutRef.current,\n );\n\n // Update previous scroll position for next frame\n prevScrollTopRef.current = container.scrollTop || 0;\n prevScrollLeftRef.current = container.scrollLeft || 0;\n needsRenderRef.current = true;\n app.renderer?.render(app.stage);\n\n // Creation was deferred by the per-frame budget: continue on the next frame\n // until the buffer is filled.\n if (pending) {\n pendingRef.scheduled = true;\n frameHandle = requestAnimationFrame(processScroll);\n }\n } catch (e) {\n console.error('[PivotCanvas] processScroll error', e);\n }\n };\n\n const onScroll = () => {\n // schedule the work for the next animation frame\n if (!pendingRef.scheduled) {\n pendingRef.scheduled = true;\n frameHandle = requestAnimationFrame(processScroll);\n }\n };\n\n container.addEventListener('scroll', onScroll, { passive: true });\n\n return () => {\n container.removeEventListener('scroll', onScroll);\n cancelAnimationFrame(frameHandle);\n };\n }, [\n pixiReady,\n layout,\n visibleIds,\n items,\n cardWidth,\n cardHeight,\n zoomLevel,\n viewportWidth,\n viewportHeight,\n panX,\n panY,\n grouping,\n viewMode,\n selectedId,\n onCardClick,\n onPanStart,\n appRef,\n cardColorsRef,\n groupsContainerRef,\n isViewTransitionRef,\n needsRenderRef,\n onCardClickRef,\n onPanStartRef,\n parentContainerRef,\n prevScrollLeftRef,\n prevScrollTopRef,\n rootRef,\n spritesRef,\n transitionLayoutRef,\n transitionSeenIdsRef,\n ]);\n};\n"],"names":["createCardSpriteExternal","updateCardContentExternal"],"mappings":";;;;;AAkBO,MAAM,kBAAkB,GAAG,CAAuB,EACrD,KAAK,EACL,KAAK,EACL,UAAU,EACV,aAAa,EACb,cAAc,EACd,aAAa,GACW,KAAI;AAC5B,IAAA,MAAM,EACF,KAAK,EACL,MAAM,EACN,QAAQ,EACR,UAAU,EACV,SAAS,EACT,UAAU,EACV,SAAS,EACT,IAAI,EACJ,IAAI,EACJ,aAAa,EACb,cAAc,EACd,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,UAAU,EACV,WAAW,EACX,YAAY,EAAE,kBAAkB,GACnC,GAAG,KAAK;AACT,IAAA,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,GAChF,KAAK;AACT,IAAA,MAAM,EACF,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,GACpB,GAAG,UAAU;IAMd,SAAS,CAAC,MAAK;AACX,QAAA,IACI,CAAC,SAAS;AACV,YAAA,CAAC,kBAAkB;YACnB,CAAC,kBAAkB,CAAC,OAAO;YAC3B,CAAC,MAAM,CAAC,OAAO;YACf,CAAC,OAAO,CAAC,OAAO;YAEhB;AAEJ,QAAA,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO;AAC5C,QAAA,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO;AAK1B,QAAA,MAAM,UAAU,GAAG,EAAE,SAAS,EAAE,KAAK,EAA4B;QACjE,IAAI,WAAW,GAAG,CAAC;QAEnB,MAAM,aAAa,GAAG,MAAK;AACvB,YAAA,UAAU,CAAC,SAAS,GAAG,KAAK;AAC5B,YAAA,IAAI;AAKA,gBAAA,MAAM,EAAE,OAAO,EAAE,GAAG,iBAAiB,CACjC;oBACI,IAAI,EAAE,OAAO,CAAC,OAAO;oBACrB,eAAe,EAAE,kBAAkB,CAAC,OAAO;oBAC3C,SAAS,EAAE,kBAAkB,CAAC,OAAO;oBACrC,OAAO,EAAE,UAAU,CAAC,OAAO;oBAC3B,MAAM;oBACN,UAAU;oBACV,KAAK;oBACL,SAAS;oBACT,UAAU;oBACV,IAAI;oBACJ,IAAI;oBACJ,SAAS;oBACT,aAAa;oBACb,cAAc;AACd,oBAAA,gBAAgB,EAAE,CAAC,EAAmB,EAAE,CAAS,EAAE,CAAS,KACxDA,gBAAwB,CACpB,EAAE,EACF,CAAC,EACD,CAAC,EACD,KAAgB,EAChB,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,KAAK,cAAc,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,EACpD,CAAC,CAAC,KAAK,aAAa,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAClD,SAAS,EACT,UAAU,EACV,aAAa,CAAC,OAAO,EACrB,YAAY,EACZ,SAAS,CACZ;oBACL,iBAAiB,EAAE,CAAC,MAAkB,EAAE,IAAW,KAC/CC,iBAAyB,CACrB,MAAM,EACN,IAAI,EACJ,UAAU,EACV,SAAS,EACT,UAAU,EACV,aAAa,CAAC,OAAO,EACrB,YAAY,CACf;oBACL,gBAAgB,EAAE,mBAAmB,CAAC,OAAO;oBAC7C,QAAQ;oBACR,iBAAiB,EAAE,oBAAoB,CAAC,OAAO;oBAC/C,aAAa,EAAE,gBAAgB,CAAC,OAAO;oBACvC,cAAc,EAAE,iBAAiB,CAAC,OAAO;AAC5C,iBAAA,EACD,mBAAmB,CAAC,OAAO,CAC9B;gBAGD,gBAAgB,CAAC,OAAO,GAAG,SAAS,CAAC,SAAS,IAAI,CAAC;gBACnD,iBAAiB,CAAC,OAAO,GAAG,SAAS,CAAC,UAAU,IAAI,CAAC;AACrD,gBAAA,cAAc,CAAC,OAAO,GAAG,IAAI;gBAC7B,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;gBAI/B,IAAI,OAAO,EAAE;AACT,oBAAA,UAAU,CAAC,SAAS,GAAG,IAAI;AAC3B,oBAAA,WAAW,GAAG,qBAAqB,CAAC,aAAa,CAAC;gBACtD;YACJ;YAAE,OAAO,CAAC,EAAE;AACR,gBAAA,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,CAAC,CAAC;YACzD;AACJ,QAAA,CAAC;QAED,MAAM,QAAQ,GAAG,MAAK;AAElB,YAAA,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE;AACvB,gBAAA,UAAU,CAAC,SAAS,GAAG,IAAI;AAC3B,gBAAA,WAAW,GAAG,qBAAqB,CAAC,aAAa,CAAC;YACtD;AACJ,QAAA,CAAC;AAED,QAAA,SAAS,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAEjE,QAAA,OAAO,MAAK;AACR,YAAA,SAAS,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC;YACjD,oBAAoB,CAAC,WAAW,CAAC;AACrC,QAAA,CAAC;AACL,IAAA,CAAC,EAAE;QACC,SAAS;QACT,MAAM;QACN,UAAU;QACV,KAAK;QACL,SAAS;QACT,UAAU;QACV,SAAS;QACT,aAAa;QACb,cAAc;QACd,IAAI;QACJ,IAAI;QACJ,QAAQ;QACR,QAAQ;QACR,UAAU;QACV,WAAW;QACX,UAAU;QACV,MAAM;QACN,aAAa;QACb,kBAAkB;QAClB,mBAAmB;QACnB,cAAc;QACd,cAAc;QACd,aAAa;QACb,kBAAkB;QAClB,iBAAiB;QACjB,gBAAgB;QAChB,OAAO;QACP,UAAU;QACV,mBAAmB;QACnB,oBAAoB;AACvB,KAAA,CAAC;AACN;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePivotSpriteSync.d.ts","sourceRoot":"","sources":["../../../../../PivotViewer/components/pivot/usePivotSpriteSync.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAsB,CAAC;AAE/D;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,KAAK,SAAS,MAAM,+EAOpD,kBAAkB,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"usePivotSpriteSync.d.ts","sourceRoot":"","sources":["../../../../../PivotViewer/components/pivot/usePivotSpriteSync.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAsB,CAAC;AAE/D;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,KAAK,SAAS,MAAM,+EAOpD,kBAAkB,CAAC,KAAK,CAAC,SAkO3B,CAAC"}
|