@cratis/components 0.1.12 → 0.1.14
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/cjs/CommandDialog/CommandDialog.js.map +1 -1
- package/dist/cjs/CommandForm/CommandForm.js +6 -2
- package/dist/cjs/CommandForm/CommandForm.js.map +1 -1
- package/dist/cjs/CommandForm/CommandFormFields.js.map +1 -1
- package/dist/cjs/DataTables/DataTableForObservableQuery.js.map +1 -1
- package/dist/cjs/DataTables/DataTableForQuery.js.map +1 -1
- package/dist/cjs/PivotViewer/PivotViewer.js +57 -378
- package/dist/cjs/PivotViewer/PivotViewer.js.map +1 -1
- package/dist/cjs/PivotViewer/components/PivotCanvas.js +3 -3
- package/dist/cjs/PivotViewer/components/PivotCanvas.js.map +1 -1
- package/dist/cjs/PivotViewer/components/PivotViewerMain.js.map +1 -1
- package/dist/cjs/PivotViewer/components/RangeHistogramFilter.js.map +1 -1
- package/dist/cjs/PivotViewer/components/pivot/buckets.js.map +1 -1
- package/dist/cjs/PivotViewer/components/pivot/sprites.js +1 -1
- package/dist/cjs/PivotViewer/components/pivot/sprites.js.map +1 -1
- package/dist/cjs/PivotViewer/components/pivot/visibility.js.map +1 -1
- package/dist/cjs/PivotViewer/hooks/useAnimationModeTracking.js +37 -0
- package/dist/cjs/PivotViewer/hooks/useAnimationModeTracking.js.map +1 -0
- package/dist/cjs/PivotViewer/hooks/useCardSelection.js +64 -0
- package/dist/cjs/PivotViewer/hooks/useCardSelection.js.map +1 -0
- package/dist/cjs/PivotViewer/hooks/useCurrentFilters.js +52 -0
- package/dist/cjs/PivotViewer/hooks/useCurrentFilters.js.map +1 -0
- package/dist/cjs/PivotViewer/hooks/useDetailPanelClose.js +63 -0
- package/dist/cjs/PivotViewer/hooks/useDetailPanelClose.js.map +1 -0
- package/dist/cjs/PivotViewer/hooks/useFieldExtractors.js +50 -0
- package/dist/cjs/PivotViewer/hooks/useFieldExtractors.js.map +1 -0
- package/dist/cjs/PivotViewer/hooks/usePanning.js.map +1 -1
- package/dist/cjs/PivotViewer/hooks/usePivotEngine.js.map +1 -1
- package/dist/cjs/PivotViewer/hooks/useScrollSync.js +21 -0
- package/dist/cjs/PivotViewer/hooks/useScrollSync.js.map +1 -0
- package/dist/cjs/PivotViewer/hooks/useViewModeScrollHandling.js +42 -0
- package/dist/cjs/PivotViewer/hooks/useViewModeScrollHandling.js.map +1 -0
- package/dist/cjs/PivotViewer/types.js.map +1 -1
- package/dist/cjs/PivotViewer/utils/cardPosition.js +67 -0
- package/dist/cjs/PivotViewer/utils/cardPosition.js.map +1 -0
- package/dist/cjs/PivotViewer/utils/constants.js +4 -0
- package/dist/cjs/PivotViewer/utils/constants.js.map +1 -1
- package/dist/cjs/PivotViewer/utils/idResolution.js +34 -0
- package/dist/cjs/PivotViewer/utils/idResolution.js.map +1 -0
- package/dist/esm/CommandDialog/CommandDialog.d.ts +2 -2
- package/dist/esm/CommandDialog/CommandDialog.d.ts.map +1 -1
- package/dist/esm/CommandDialog/CommandDialog.js.map +1 -1
- package/dist/esm/CommandForm/CommandForm.d.ts +2 -2
- package/dist/esm/CommandForm/CommandForm.d.ts.map +1 -1
- package/dist/esm/CommandForm/CommandForm.js +6 -2
- package/dist/esm/CommandForm/CommandForm.js.map +1 -1
- package/dist/esm/CommandForm/CommandFormFields.d.ts +2 -2
- package/dist/esm/CommandForm/CommandFormFields.d.ts.map +1 -1
- package/dist/esm/CommandForm/CommandFormFields.js.map +1 -1
- package/dist/esm/Common/ErrorBoundary.stories.d.ts +1 -1
- package/dist/esm/Common/ErrorBoundary.stories.js.map +1 -1
- package/dist/esm/Common/FormElement.stories.d.ts +1 -1
- package/dist/esm/Common/FormElement.stories.js.map +1 -1
- package/dist/esm/Common/Page.stories.d.ts +1 -1
- package/dist/esm/Common/Page.stories.js.map +1 -1
- package/dist/esm/DataPage/DataPage.stories.d.ts +1 -1
- package/dist/esm/DataPage/DataPage.stories.js.map +1 -1
- package/dist/esm/DataTables/DataTableForObservableQuery.d.ts +4 -4
- package/dist/esm/DataTables/DataTableForObservableQuery.d.ts.map +1 -1
- package/dist/esm/DataTables/DataTableForObservableQuery.js.map +1 -1
- package/dist/esm/DataTables/DataTableForObservableQuery.stories.d.ts +1 -1
- package/dist/esm/DataTables/DataTableForObservableQuery.stories.js.map +1 -1
- package/dist/esm/DataTables/DataTableForQuery.d.ts +4 -4
- package/dist/esm/DataTables/DataTableForQuery.d.ts.map +1 -1
- package/dist/esm/DataTables/DataTableForQuery.js.map +1 -1
- package/dist/esm/DataTables/DataTableForQuery.stories.d.ts +1 -1
- package/dist/esm/DataTables/DataTableForQuery.stories.js.map +1 -1
- package/dist/esm/Dialogs/ConfirmationDialog.stories.js.map +1 -1
- package/dist/esm/PivotViewer/PivotViewer.d.ts.map +1 -1
- package/dist/esm/PivotViewer/PivotViewer.js +57 -378
- package/dist/esm/PivotViewer/PivotViewer.js.map +1 -1
- package/dist/esm/PivotViewer/components/PivotCanvas.d.ts +2 -2
- package/dist/esm/PivotViewer/components/PivotCanvas.d.ts.map +1 -1
- package/dist/esm/PivotViewer/components/PivotCanvas.js +3 -3
- package/dist/esm/PivotViewer/components/PivotCanvas.js.map +1 -1
- package/dist/esm/PivotViewer/components/PivotViewerMain.js.map +1 -1
- package/dist/esm/PivotViewer/components/RangeHistogramFilter.js.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/buckets.js.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/sprites.js +1 -1
- package/dist/esm/PivotViewer/components/pivot/sprites.js.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/visibility.js.map +1 -1
- package/dist/esm/PivotViewer/engine/pivot.worker.d.ts.map +1 -1
- package/dist/esm/PivotViewer/engine/pivot.worker.js.map +1 -1
- package/dist/esm/PivotViewer/hooks/index.d.ts +7 -0
- package/dist/esm/PivotViewer/hooks/index.d.ts.map +1 -1
- package/dist/esm/PivotViewer/hooks/index.js +7 -0
- package/dist/esm/PivotViewer/hooks/index.js.map +1 -1
- package/dist/esm/PivotViewer/hooks/useAnimationModeTracking.d.ts +2 -0
- package/dist/esm/PivotViewer/hooks/useAnimationModeTracking.d.ts.map +1 -0
- package/dist/esm/PivotViewer/hooks/useAnimationModeTracking.js +35 -0
- package/dist/esm/PivotViewer/hooks/useAnimationModeTracking.js.map +1 -0
- package/dist/esm/PivotViewer/hooks/useCardSelection.d.ts +37 -0
- package/dist/esm/PivotViewer/hooks/useCardSelection.d.ts.map +1 -0
- package/dist/esm/PivotViewer/hooks/useCardSelection.js +62 -0
- package/dist/esm/PivotViewer/hooks/useCardSelection.js.map +1 -0
- package/dist/esm/PivotViewer/hooks/useCurrentFilters.d.ts +5 -0
- package/dist/esm/PivotViewer/hooks/useCurrentFilters.d.ts.map +1 -0
- package/dist/esm/PivotViewer/hooks/useCurrentFilters.js +49 -0
- package/dist/esm/PivotViewer/hooks/useCurrentFilters.js.map +1 -0
- package/dist/esm/PivotViewer/hooks/useDetailPanelClose.d.ts +27 -0
- package/dist/esm/PivotViewer/hooks/useDetailPanelClose.d.ts.map +1 -0
- package/dist/esm/PivotViewer/hooks/useDetailPanelClose.js +61 -0
- package/dist/esm/PivotViewer/hooks/useDetailPanelClose.js.map +1 -0
- package/dist/esm/PivotViewer/hooks/useFieldExtractors.d.ts +7 -0
- package/dist/esm/PivotViewer/hooks/useFieldExtractors.d.ts.map +1 -0
- package/dist/esm/PivotViewer/hooks/useFieldExtractors.js +48 -0
- package/dist/esm/PivotViewer/hooks/useFieldExtractors.js.map +1 -0
- package/dist/esm/PivotViewer/hooks/useFilterPanelDrag.js.map +1 -1
- package/dist/esm/PivotViewer/hooks/usePanning.js.map +1 -1
- package/dist/esm/PivotViewer/hooks/usePivotEngine.js.map +1 -1
- package/dist/esm/PivotViewer/hooks/useScrollSync.d.ts +3 -0
- package/dist/esm/PivotViewer/hooks/useScrollSync.d.ts.map +1 -0
- package/dist/esm/PivotViewer/hooks/useScrollSync.js +19 -0
- package/dist/esm/PivotViewer/hooks/useScrollSync.js.map +1 -0
- package/dist/esm/PivotViewer/hooks/useViewModeScrollHandling.d.ts +16 -0
- package/dist/esm/PivotViewer/hooks/useViewModeScrollHandling.d.ts.map +1 -0
- package/dist/esm/PivotViewer/hooks/useViewModeScrollHandling.js +40 -0
- package/dist/esm/PivotViewer/hooks/useViewModeScrollHandling.js.map +1 -0
- package/dist/esm/PivotViewer/types.js.map +1 -1
- package/dist/esm/PivotViewer/utils/cardPosition.d.ts +18 -0
- package/dist/esm/PivotViewer/utils/cardPosition.d.ts.map +1 -0
- package/dist/esm/PivotViewer/utils/cardPosition.js +63 -0
- package/dist/esm/PivotViewer/utils/cardPosition.js.map +1 -0
- package/dist/esm/PivotViewer/utils/constants.js +3 -1
- package/dist/esm/PivotViewer/utils/constants.js.map +1 -1
- package/dist/esm/PivotViewer/utils/idResolution.d.ts +13 -0
- package/dist/esm/PivotViewer/utils/idResolution.d.ts.map +1 -0
- package/dist/esm/PivotViewer/utils/idResolution.js +31 -0
- package/dist/esm/PivotViewer/utils/idResolution.js.map +1 -0
- package/dist/esm/PivotViewer/utils/index.d.ts +2 -0
- package/dist/esm/PivotViewer/utils/index.d.ts.map +1 -1
- package/dist/esm/PivotViewer/utils/index.js +2 -0
- package/dist/esm/PivotViewer/utils/index.js.map +1 -1
- package/dist/esm/TimeMachine/EventsView.stories.d.ts +1 -1
- package/dist/esm/TimeMachine/EventsView.stories.js.map +1 -1
- package/dist/esm/TimeMachine/Properties.stories.d.ts +1 -1
- package/dist/esm/TimeMachine/Properties.stories.js.map +1 -1
- package/dist/esm/TimeMachine/ReadModelView.stories.d.ts +1 -1
- package/dist/esm/TimeMachine/ReadModelView.stories.js.map +1 -1
- package/dist/esm/TimeMachine/TimeMachine.stories.d.ts +1 -1
- package/dist/esm/TimeMachine/TimeMachine.stories.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/vite.config.js.map +1 -1
- package/dist/esm/vitest.setup.d.ts +2 -0
- package/dist/esm/vitest.setup.d.ts.map +1 -0
- package/dist/esm/vitest.setup.js +8 -0
- package/dist/esm/vitest.setup.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Layout } from '../utils/cardPosition';
|
|
2
|
+
import type { ViewMode } from '../components/Toolbar';
|
|
3
|
+
interface UseDetailPanelCloseParams<TItem extends object> {
|
|
4
|
+
selectedItem: TItem | null;
|
|
5
|
+
preSelectionState: {
|
|
6
|
+
zoom: number;
|
|
7
|
+
scrollLeft: number;
|
|
8
|
+
scrollTop: number;
|
|
9
|
+
} | null;
|
|
10
|
+
zoomLevel: number;
|
|
11
|
+
viewMode: ViewMode;
|
|
12
|
+
layout: Layout;
|
|
13
|
+
containerDimensions: {
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
};
|
|
17
|
+
grouping: unknown;
|
|
18
|
+
data: TItem[];
|
|
19
|
+
resolveId: (item: TItem, index: number) => string | number;
|
|
20
|
+
setZoomLevel: (level: number) => void;
|
|
21
|
+
setIsZooming: (zooming: boolean) => void;
|
|
22
|
+
setSelectedItem: (item: TItem | null) => void;
|
|
23
|
+
setPreSelectionState: (state: null) => void;
|
|
24
|
+
}
|
|
25
|
+
export declare function useDetailPanelClose<TItem extends object>({ selectedItem, preSelectionState, zoomLevel, viewMode, layout, containerDimensions, grouping, data, resolveId, setZoomLevel, setIsZooming, setSelectedItem, setPreSelectionState, }: UseDetailPanelCloseParams<TItem>): () => void;
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=useDetailPanelClose.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDetailPanelClose.d.ts","sourceRoot":"","sources":["../../../../PivotViewer/hooks/useDetailPanelClose.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAQtD,UAAU,yBAAyB,CAAC,KAAK,SAAS,MAAM;IACpD,YAAY,EAAE,KAAK,GAAG,IAAI,CAAC;IAC3B,iBAAiB,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAClF,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,mBAAmB,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACvD,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,KAAK,EAAE,CAAC;IACd,SAAS,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAAC;IAC3D,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,YAAY,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,eAAe,EAAE,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,oBAAoB,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,IAAI,CAAC;CAC/C;AAED,wBAAgB,mBAAmB,CAAC,KAAK,SAAS,MAAM,EAAE,EACtD,YAAY,EACZ,iBAAiB,EACjB,SAAS,EACT,QAAQ,EACR,MAAM,EACN,mBAAmB,EACnB,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,oBAAoB,GACvB,EAAE,yBAAyB,CAAC,KAAK,CAAC,cA2ElC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { smoothScrollTo, animateZoomAndScroll } from '../utils/animations.js';
|
|
3
|
+
import { normalizeIdToLayoutKey, getCardPositionFromLayout } from '../utils/idResolution.js';
|
|
4
|
+
import { createCardPositionCallbacks } from '../utils/cardPosition.js';
|
|
5
|
+
import { BASE_CARD_HEIGHT, BASE_CARD_WIDTH } from '../utils/constants.js';
|
|
6
|
+
|
|
7
|
+
function useDetailPanelClose({ selectedItem, preSelectionState, zoomLevel, viewMode, layout, containerDimensions, grouping, data, resolveId, setZoomLevel, setIsZooming, setSelectedItem, setPreSelectionState, }) {
|
|
8
|
+
return useCallback(() => {
|
|
9
|
+
const container = document.querySelector('.pv-main')?.parentElement;
|
|
10
|
+
if (!container || !selectedItem) {
|
|
11
|
+
setSelectedItem(null);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const index = data.indexOf(selectedItem);
|
|
15
|
+
let itemId = index !== -1 ? index : resolveId(selectedItem, 0);
|
|
16
|
+
itemId = normalizeIdToLayoutKey(itemId, layout);
|
|
17
|
+
const cardPosition = getCardPositionFromLayout(itemId, layout, BASE_CARD_WIDTH, BASE_CARD_HEIGHT);
|
|
18
|
+
if (!preSelectionState) {
|
|
19
|
+
setSelectedItem(null);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (viewMode === 'collection') {
|
|
23
|
+
setSelectedItem(null);
|
|
24
|
+
smoothScrollTo(container, preSelectionState.scrollLeft, preSelectionState.scrollTop, true);
|
|
25
|
+
setPreSelectionState(null);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const zoomChanged = Math.abs(preSelectionState.zoom - zoomLevel) > 0.001;
|
|
29
|
+
if (!zoomChanged || !cardPosition) {
|
|
30
|
+
setSelectedItem(null);
|
|
31
|
+
smoothScrollTo(container, preSelectionState.scrollLeft, preSelectionState.scrollTop, true);
|
|
32
|
+
setPreSelectionState(null);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const targetZoom = preSelectionState.zoom;
|
|
36
|
+
const targetContainerWidth = containerDimensions.width / targetZoom;
|
|
37
|
+
const targetContainerHeight = containerDimensions.height;
|
|
38
|
+
const callbacks = createCardPositionCallbacks(itemId, grouping, viewMode, targetContainerWidth, targetContainerHeight);
|
|
39
|
+
const targetCardPosition = callbacks.getCardPositionAtZoom(targetZoom);
|
|
40
|
+
setIsZooming(true);
|
|
41
|
+
animateZoomAndScroll({
|
|
42
|
+
container,
|
|
43
|
+
cardPosition,
|
|
44
|
+
targetCardPosition,
|
|
45
|
+
getCardPositionAtZoom: callbacks.getCardPositionAtZoom,
|
|
46
|
+
startZoom: zoomLevel,
|
|
47
|
+
targetZoom,
|
|
48
|
+
targetScrollLeft: preSelectionState.scrollLeft,
|
|
49
|
+
targetScrollTop: preSelectionState.scrollTop,
|
|
50
|
+
onUpdate: setZoomLevel,
|
|
51
|
+
onComplete: () => {
|
|
52
|
+
setIsZooming(false);
|
|
53
|
+
setSelectedItem(null);
|
|
54
|
+
setPreSelectionState(null);
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
}, [preSelectionState, selectedItem, zoomLevel, viewMode, resolveId, setZoomLevel, layout, grouping, containerDimensions, data, setSelectedItem, setPreSelectionState, setIsZooming]);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export { useDetailPanelClose };
|
|
61
|
+
//# sourceMappingURL=useDetailPanelClose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDetailPanelClose.js","sources":["../../../../PivotViewer/hooks/useDetailPanelClose.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 { useCallback } from 'react';\nimport { animateZoomAndScroll, smoothScrollTo } from '../utils/animations';\nimport type { Layout } from '../utils/cardPosition';\nimport type { ViewMode } from '../components/Toolbar';\nimport {\n getCardPositionFromLayout,\n normalizeIdToLayoutKey,\n} from '../utils/idResolution';\nimport { createCardPositionCallbacks } from '../utils/cardPosition';\nimport { BASE_CARD_WIDTH, BASE_CARD_HEIGHT } from '../utils/constants';\n\ninterface UseDetailPanelCloseParams<TItem extends object> {\n selectedItem: TItem | null;\n preSelectionState: { zoom: number; scrollLeft: number; scrollTop: number } | null;\n zoomLevel: number;\n viewMode: ViewMode;\n layout: Layout;\n containerDimensions: { width: number; height: number };\n grouping: unknown;\n data: TItem[];\n resolveId: (item: TItem, index: number) => string | number;\n setZoomLevel: (level: number) => void;\n setIsZooming: (zooming: boolean) => void;\n setSelectedItem: (item: TItem | null) => void;\n setPreSelectionState: (state: null) => void;\n}\n\nexport function useDetailPanelClose<TItem extends object>({\n selectedItem,\n preSelectionState,\n zoomLevel,\n viewMode,\n layout,\n containerDimensions,\n grouping,\n data,\n resolveId,\n setZoomLevel,\n setIsZooming,\n setSelectedItem,\n setPreSelectionState,\n}: UseDetailPanelCloseParams<TItem>) {\n return useCallback(() => {\n // Get container element\n const container = document.querySelector('.pv-main')?.parentElement as HTMLDivElement | null;\n if (!container || !selectedItem) {\n setSelectedItem(null);\n return;\n }\n\n // Resolve item ID\n const index = data.indexOf(selectedItem);\n let itemId: string | number = index !== -1 ? index : resolveId(selectedItem, 0);\n itemId = normalizeIdToLayoutKey(itemId, layout);\n\n // Get card position from layout\n const cardPosition = getCardPositionFromLayout(itemId, layout, BASE_CARD_WIDTH, BASE_CARD_HEIGHT);\n\n if (!preSelectionState) {\n setSelectedItem(null);\n return;\n }\n\n // Collection mode: just scroll back\n if (viewMode === 'collection') {\n setSelectedItem(null);\n smoothScrollTo(container, preSelectionState.scrollLeft, preSelectionState.scrollTop, true);\n setPreSelectionState(null);\n return;\n }\n\n // Grouped mode: check if zoom changed\n const zoomChanged = Math.abs(preSelectionState.zoom - zoomLevel) > 0.001;\n\n if (!zoomChanged || !cardPosition) {\n setSelectedItem(null);\n smoothScrollTo(container, preSelectionState.scrollLeft, preSelectionState.scrollTop, true);\n setPreSelectionState(null);\n return;\n }\n\n // Calculate target position for animation (zooming out)\n const targetZoom = preSelectionState.zoom;\n const targetContainerWidth = containerDimensions.width / targetZoom;\n const targetContainerHeight = containerDimensions.height;\n\n const callbacks = createCardPositionCallbacks(\n itemId,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n grouping as unknown as any,\n viewMode,\n targetContainerWidth,\n targetContainerHeight,\n );\n\n const targetCardPosition = callbacks.getCardPositionAtZoom(targetZoom);\n\n setIsZooming(true);\n\n animateZoomAndScroll({\n container,\n cardPosition,\n targetCardPosition,\n getCardPositionAtZoom: callbacks.getCardPositionAtZoom,\n startZoom: zoomLevel,\n targetZoom,\n targetScrollLeft: preSelectionState.scrollLeft,\n targetScrollTop: preSelectionState.scrollTop,\n onUpdate: setZoomLevel,\n onComplete: () => {\n setIsZooming(false);\n setSelectedItem(null);\n setPreSelectionState(null);\n },\n });\n }, [preSelectionState, selectedItem, zoomLevel, viewMode, resolveId, setZoomLevel, layout, grouping, containerDimensions, data, setSelectedItem, setPreSelectionState, setIsZooming]);\n}\n"],"names":[],"mappings":";;;;;;AA8BM,SAAU,mBAAmB,CAAuB,EACtD,YAAY,EACZ,iBAAiB,EACjB,SAAS,EACT,QAAQ,EACR,MAAM,EACN,mBAAmB,EACnB,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,oBAAoB,GACW,EAAA;IAC/B,OAAO,WAAW,CAAC,MAAK;QAEpB,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,aAAsC;AAC5F,QAAA,IAAI,CAAC,SAAS,IAAI,CAAC,YAAY,EAAE;YAC7B,eAAe,CAAC,IAAI,CAAC;YACrB;QACJ;QAGA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC;AACxC,QAAA,IAAI,MAAM,GAAoB,KAAK,KAAK,EAAE,GAAG,KAAK,GAAG,SAAS,CAAC,YAAY,EAAE,CAAC,CAAC;AAC/E,QAAA,MAAM,GAAG,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC;AAG/C,QAAA,MAAM,YAAY,GAAG,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,gBAAgB,CAAC;QAEjG,IAAI,CAAC,iBAAiB,EAAE;YACpB,eAAe,CAAC,IAAI,CAAC;YACrB;QACJ;AAGA,QAAA,IAAI,QAAQ,KAAK,YAAY,EAAE;YAC3B,eAAe,CAAC,IAAI,CAAC;AACrB,YAAA,cAAc,CAAC,SAAS,EAAE,iBAAiB,CAAC,UAAU,EAAE,iBAAiB,CAAC,SAAS,EAAE,IAAI,CAAC;YAC1F,oBAAoB,CAAC,IAAI,CAAC;YAC1B;QACJ;AAGA,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,GAAG,SAAS,CAAC,GAAG,KAAK;AAExE,QAAA,IAAI,CAAC,WAAW,IAAI,CAAC,YAAY,EAAE;YAC/B,eAAe,CAAC,IAAI,CAAC;AACrB,YAAA,cAAc,CAAC,SAAS,EAAE,iBAAiB,CAAC,UAAU,EAAE,iBAAiB,CAAC,SAAS,EAAE,IAAI,CAAC;YAC1F,oBAAoB,CAAC,IAAI,CAAC;YAC1B;QACJ;AAGA,QAAA,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI;AACzC,QAAA,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,KAAK,GAAG,UAAU;AACnE,QAAA,MAAM,qBAAqB,GAAG,mBAAmB,CAAC,MAAM;AAExD,QAAA,MAAM,SAAS,GAAG,2BAA2B,CACzC,MAAM,EAEN,QAA0B,EAC1B,QAAQ,EACR,oBAAoB,EACpB,qBAAqB,CACxB;QAED,MAAM,kBAAkB,GAAG,SAAS,CAAC,qBAAqB,CAAC,UAAU,CAAC;QAEtE,YAAY,CAAC,IAAI,CAAC;AAElB,QAAA,oBAAoB,CAAC;YACjB,SAAS;YACT,YAAY;YACZ,kBAAkB;YAClB,qBAAqB,EAAE,SAAS,CAAC,qBAAqB;AACtD,YAAA,SAAS,EAAE,SAAS;YACpB,UAAU;YACV,gBAAgB,EAAE,iBAAiB,CAAC,UAAU;YAC9C,eAAe,EAAE,iBAAiB,CAAC,SAAS;AAC5C,YAAA,QAAQ,EAAE,YAAY;YACtB,UAAU,EAAE,MAAK;gBACb,YAAY,CAAC,KAAK,CAAC;gBACnB,eAAe,CAAC,IAAI,CAAC;gBACrB,oBAAoB,CAAC,IAAI,CAAC;YAC9B,CAAC;AACJ,SAAA,CAAC;AACN,IAAA,CAAC,EAAE,CAAC,iBAAiB,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,mBAAmB,EAAE,IAAI,EAAE,eAAe,EAAE,oBAAoB,EAAE,YAAY,CAAC,CAAC;AACzL;;;;"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FieldValue } from '../engine/types';
|
|
2
|
+
import type { PivotDimension, PivotFilter } from '../types';
|
|
3
|
+
export declare function useFieldExtractors<TItem extends object>(dimensions: PivotDimension<TItem>[], filters?: PivotFilter<TItem>[]): {
|
|
4
|
+
fieldExtractors: Map<string, (item: TItem) => FieldValue>;
|
|
5
|
+
indexFields: string[];
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=useFieldExtractors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFieldExtractors.d.ts","sourceRoot":"","sources":["../../../../PivotViewer/hooks/useFieldExtractors.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5D,wBAAgB,kBAAkB,CAAC,KAAK,SAAS,MAAM,EACnD,UAAU,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,EACnC,OAAO,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE;wCAGgB,KAAK,KAAK,UAAU;;EA8CrE"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
|
|
3
|
+
function useFieldExtractors(dimensions, filters) {
|
|
4
|
+
const fieldExtractors = useMemo(() => {
|
|
5
|
+
const extractors = new Map();
|
|
6
|
+
for (const dim of dimensions) {
|
|
7
|
+
extractors.set(dim.key, (item) => {
|
|
8
|
+
const val = dim.getValue(item);
|
|
9
|
+
if (val instanceof Date)
|
|
10
|
+
return val.getTime();
|
|
11
|
+
if (typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean' || val === null) {
|
|
12
|
+
return val;
|
|
13
|
+
}
|
|
14
|
+
return String(val);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
if (filters) {
|
|
18
|
+
for (const filter of filters) {
|
|
19
|
+
extractors.set(filter.key, (item) => {
|
|
20
|
+
const val = filter.getValue(item);
|
|
21
|
+
if (val instanceof Date)
|
|
22
|
+
return val.getTime();
|
|
23
|
+
if (typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean' || val === null) {
|
|
24
|
+
return val;
|
|
25
|
+
}
|
|
26
|
+
return String(val);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return extractors;
|
|
31
|
+
}, [dimensions, filters]);
|
|
32
|
+
const indexFields = useMemo(() => {
|
|
33
|
+
const fields = new Set();
|
|
34
|
+
for (const dim of dimensions) {
|
|
35
|
+
fields.add(dim.key);
|
|
36
|
+
}
|
|
37
|
+
if (filters) {
|
|
38
|
+
for (const filter of filters) {
|
|
39
|
+
fields.add(filter.key);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return Array.from(fields);
|
|
43
|
+
}, [dimensions, filters]);
|
|
44
|
+
return { fieldExtractors, indexFields };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export { useFieldExtractors };
|
|
48
|
+
//# sourceMappingURL=useFieldExtractors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFieldExtractors.js","sources":["../../../../PivotViewer/hooks/useFieldExtractors.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 { useMemo } from 'react';\nimport type { FieldValue } from '../engine/types';\nimport type { PivotDimension, PivotFilter } from '../types';\n\nexport function useFieldExtractors<TItem extends object>(\n dimensions: PivotDimension<TItem>[],\n filters?: PivotFilter<TItem>[],\n) {\n const fieldExtractors = useMemo(() => {\n const extractors = new Map<string, (item: TItem) => FieldValue>();\n\n for (const dim of dimensions) {\n extractors.set(dim.key, (item) => {\n const val = dim.getValue(item);\n if (val instanceof Date) return val.getTime();\n if (typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean' || val === null) {\n return val;\n }\n return String(val);\n });\n }\n\n if (filters) {\n for (const filter of filters) {\n extractors.set(filter.key, (item) => {\n const val = filter.getValue(item);\n if (val instanceof Date) return val.getTime();\n if (typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean' || val === null) {\n return val;\n }\n return String(val);\n });\n }\n }\n\n return extractors;\n }, [dimensions, filters]);\n\n const indexFields = useMemo(() => {\n const fields = new Set<string>();\n\n for (const dim of dimensions) {\n fields.add(dim.key);\n }\n\n if (filters) {\n for (const filter of filters) {\n fields.add(filter.key);\n }\n }\n\n return Array.from(fields);\n }, [dimensions, filters]);\n\n return { fieldExtractors, indexFields };\n}\n"],"names":[],"mappings":";;AAOM,SAAU,kBAAkB,CAC9B,UAAmC,EACnC,OAA8B,EAAA;AAE9B,IAAA,MAAM,eAAe,GAAG,OAAO,CAAC,MAAK;AACjC,QAAA,MAAM,UAAU,GAAG,IAAI,GAAG,EAAuC;AAEjE,QAAA,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE;YAC1B,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,KAAI;gBAC7B,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAC9B,IAAI,GAAG,YAAY,IAAI;AAAE,oBAAA,OAAO,GAAG,CAAC,OAAO,EAAE;AAC7C,gBAAA,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,EAAE;AAChG,oBAAA,OAAO,GAAG;gBACd;AACA,gBAAA,OAAO,MAAM,CAAC,GAAG,CAAC;AACtB,YAAA,CAAC,CAAC;QACN;QAEA,IAAI,OAAO,EAAE;AACT,YAAA,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;gBAC1B,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,KAAI;oBAChC,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;oBACjC,IAAI,GAAG,YAAY,IAAI;AAAE,wBAAA,OAAO,GAAG,CAAC,OAAO,EAAE;AAC7C,oBAAA,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,EAAE;AAChG,wBAAA,OAAO,GAAG;oBACd;AACA,oBAAA,OAAO,MAAM,CAAC,GAAG,CAAC;AACtB,gBAAA,CAAC,CAAC;YACN;QACJ;AAEA,QAAA,OAAO,UAAU;AACrB,IAAA,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AAEzB,IAAA,MAAM,WAAW,GAAG,OAAO,CAAC,MAAK;AAC7B,QAAA,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU;AAEhC,QAAA,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE;AAC1B,YAAA,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;QACvB;QAEA,IAAI,OAAO,EAAE;AACT,YAAA,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;AAC1B,gBAAA,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC;YAC1B;QACJ;AAEA,QAAA,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AAC7B,IAAA,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AAEzB,IAAA,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE;AAC3C;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFilterPanelDrag.js","sourceRoot":"","sources":["../../../../PivotViewer/hooks/useFilterPanelDrag.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzD,MAAM,UAAU,kBAAkB;IAChC,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACvE,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9D,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAE7D,MAAM,0BAA0B,GAAG,WAAW,CAAC,CAAC,CAAmB,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"useFilterPanelDrag.js","sourceRoot":"","sources":["../../../../PivotViewer/hooks/useFilterPanelDrag.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzD,MAAM,UAAU,kBAAkB;IAChC,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACvE,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9D,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAE7D,MAAM,0BAA0B,GAAG,WAAW,CAAC,CAAC,CAAmB,EAAE,EAAE;QACrE,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC;QACrB,kBAAkB,CAAC,IAAI,CAAC,CAAC;QACzB,aAAa,CAAC;YACZ,CAAC,EAAE,CAAC,CAAC,OAAO,GAAG,cAAc,CAAC,CAAC;YAC/B,CAAC,EAAE,CAAC,CAAC,OAAO,GAAG,cAAc,CAAC,CAAC;SAChC,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;IAErB,MAAM,qBAAqB,GAAG,WAAW,CAAC,CAAC,CAAa,EAAE,EAAE;QAC1D,IAAI,CAAC,eAAe;YAAE,OAAO;QAC7B,iBAAiB,CAAC;YAChB,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC;YACxC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC;SAC1C,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC,CAAC;IAElC,MAAM,wBAAwB,GAAG,WAAW,CAAC,GAAG,EAAE;QAChD,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,eAAe,EAAE,CAAC;YACpB,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,qBAAqB,CAAC,CAAC;YAC9D,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,wBAAwB,CAAC,CAAC;YAC/D,OAAO,GAAG,EAAE;gBACV,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,qBAAqB,CAAC,CAAC;gBACjE,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,wBAAwB,CAAC,CAAC;YACpE,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC,EAAE,CAAC,eAAe,EAAE,qBAAqB,EAAE,wBAAwB,CAAC,CAAC,CAAC;IAEvE,OAAO;QACL,cAAc;QACd,eAAe;QACf,0BAA0B;KAC3B,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePanning.js","sources":["../../../../PivotViewer/hooks/usePanning.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 { useState, useRef, useCallback } from 'react';\n\nexport function usePanning(\n containerRef: React.RefObject<HTMLDivElement | null>,\n onBackgroundClick?: () => void,\n onScrollChange?: (scroll: { x: number; y: number }) => void\n) {\n const [isPanning, setIsPanning] = useState(false);\n const panStartRef = useRef<{ x: number; y: number; scrollLeft: number; scrollTop: number } | null>(null);\n const velocityRef = useRef({ x: 0, y: 0 });\n const lastMouseRef = useRef<{ x: number; y: number; time: number } | null>(null);\n const inertiaAnimationRef = useRef<number | null>(null);\n const didDragRef = useRef(false);\n const clickedOnBackgroundRef = useRef(false);\n\n const stopInertia = useCallback(() => {\n if (inertiaAnimationRef.current) {\n cancelAnimationFrame(inertiaAnimationRef.current);\n inertiaAnimationRef.current = null;\n }\n }, []);\n\n const handlePanStart = useCallback((e: React.MouseEvent | MouseEvent, isExplicitlyOnCard?: boolean) => {\n const container = containerRef.current;\n if (!container) return;\n\n stopInertia();\n\n const target = e.target as HTMLElement;\n // Check if explicitly on card (from Pixi) or via DOM (fallback)\n const isOnCard = isExplicitlyOnCard ?? !!target.closest('.pv-card');\n\n clickedOnBackgroundRef.current = !isOnCard;\n didDragRef.current = false;\n velocityRef.current = { x: 0, y: 0 };\n\n if (e.button === 1 || (e.button === 0 && (e.altKey || !isOnCard))) {\n if (!isOnCard) {\n
|
|
1
|
+
{"version":3,"file":"usePanning.js","sources":["../../../../PivotViewer/hooks/usePanning.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 { useState, useRef, useCallback } from 'react';\n\nexport function usePanning(\n containerRef: React.RefObject<HTMLDivElement | null>,\n onBackgroundClick?: () => void,\n onScrollChange?: (scroll: { x: number; y: number }) => void\n) {\n const [isPanning, setIsPanning] = useState(false);\n const panStartRef = useRef<{ x: number; y: number; scrollLeft: number; scrollTop: number } | null>(null);\n const velocityRef = useRef({ x: 0, y: 0 });\n const lastMouseRef = useRef<{ x: number; y: number; time: number } | null>(null);\n const inertiaAnimationRef = useRef<number | null>(null);\n const didDragRef = useRef(false);\n const clickedOnBackgroundRef = useRef(false);\n\n const stopInertia = useCallback(() => {\n if (inertiaAnimationRef.current) {\n cancelAnimationFrame(inertiaAnimationRef.current);\n inertiaAnimationRef.current = null;\n }\n }, []);\n\n const handlePanStart = useCallback((e: React.MouseEvent | MouseEvent, isExplicitlyOnCard?: boolean) => {\n const container = containerRef.current;\n if (!container) return;\n\n stopInertia();\n\n const target = e.target as HTMLElement;\n // Check if explicitly on card (from Pixi) or via DOM (fallback)\n const isOnCard = isExplicitlyOnCard ?? !!target.closest('.pv-card');\n\n clickedOnBackgroundRef.current = !isOnCard;\n didDragRef.current = false;\n velocityRef.current = { x: 0, y: 0 };\n\n if (e.button === 1 || (e.button === 0 && (e.altKey || !isOnCard))) {\n if (!isOnCard) {\n e.preventDefault?.();\n }\n setIsPanning(true);\n panStartRef.current = {\n x: e.clientX,\n y: e.clientY,\n scrollLeft: container.scrollLeft,\n scrollTop: container.scrollTop,\n };\n lastMouseRef.current = { x: e.clientX, y: e.clientY, time: performance.now() };\n }\n }, [containerRef, stopInertia]);\n\n const handlePanMove = useCallback((e: React.MouseEvent | MouseEvent) => {\n const panStart = panStartRef.current;\n if (!isPanning || !panStart) return;\n\n const dx = e.clientX - panStart.x;\n const dy = e.clientY - panStart.y;\n\n // Mark as dragged if moved more than 3 pixels\n if (Math.abs(dx) > 3 || Math.abs(dy) > 3) {\n didDragRef.current = true;\n }\n\n // Camera moves opposite to drag direction\n const newCameraX = panStart.scrollLeft - dx;\n const newCameraY = panStart.scrollTop - dy;\n\n // Update camera position\n // Update container scroll directly so the visual camera follows the drag\n const container = containerRef.current;\n if (container) {\n container.scrollLeft = Math.max(0, Math.round(newCameraX));\n container.scrollTop = Math.max(0, Math.round(newCameraY));\n }\n\n // Also notify parent about scroll change (keeps external state in sync)\n if (onScrollChange) {\n onScrollChange({ x: container ? container.scrollLeft : newCameraX, y: container ? container.scrollTop : newCameraY });\n }\n\n // Track velocity for inertia\n const now = performance.now();\n const last = lastMouseRef.current;\n if (last) {\n const dt = now - last.time;\n if (dt > 0 && dt < 50) {\n const instantVx = (last.x - e.clientX) / dt;\n const instantVy = (last.y - e.clientY) / dt;\n velocityRef.current = {\n x: velocityRef.current.x * 0.5 + instantVx * 0.5,\n y: velocityRef.current.y * 0.5 + instantVy * 0.5,\n };\n }\n }\n lastMouseRef.current = { x: e.clientX, y: e.clientY, time: now };\n }, [isPanning, containerRef, onScrollChange]);\n\n const handlePanEnd = useCallback(() => {\n const wasPanning = isPanning;\n const velocity = { ...velocityRef.current };\n\n setIsPanning(false);\n panStartRef.current = null;\n\n // If clicked on background and didn't drag, trigger deselect\n if (clickedOnBackgroundRef.current && !didDragRef.current && onBackgroundClick) {\n onBackgroundClick();\n }\n\n if (!wasPanning) {\n return;\n }\n\n const container = containerRef.current;\n if (!container) {\n lastMouseRef.current = null;\n return;\n }\n\n const speed = Math.sqrt(velocity.x * velocity.x + velocity.y * velocity.y);\n\n // Start inertia if moving fast enough\n if (speed > 0.3) {\n let vx = velocity.x * 16;\n let vy = velocity.y * 16;\n\n const animate = () => {\n const currentSpeed = Math.sqrt(vx * vx + vy * vy);\n\n if (currentSpeed < 0.5) {\n inertiaAnimationRef.current = null;\n return;\n }\n\n container.scrollLeft += vx;\n container.scrollTop += vy;\n\n // Decay\n vx *= 0.95;\n vy *= 0.95;\n\n inertiaAnimationRef.current = requestAnimationFrame(animate);\n };\n\n inertiaAnimationRef.current = requestAnimationFrame(animate);\n }\n\n lastMouseRef.current = null;\n }, [isPanning, containerRef, onBackgroundClick]);\n\n return {\n isPanning,\n handlePanStart,\n handlePanMove,\n handlePanEnd,\n };\n}\n\n\n\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePivotEngine.js","sources":["../../../../PivotViewer/hooks/usePivotEngine.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, useRef, useState, useCallback } from 'react';\nimport type {\n PivotStore,\n PivotIndexes,\n FilterSpec,\n FilterResult,\n GroupSpec,\n GroupingResult,\n WorkerInMessage,\n WorkerOutMessage,\n FieldValue,\n} from '../engine/types';\nimport { buildStore, buildIndexes, applyFilters, computeGrouping, sortIds } from '../engine/store';\n\nexport interface UsePivotEngineOptions<TItem extends object> {\n data: TItem[];\n fieldExtractors: Map<string, (item: TItem) => FieldValue>;\n indexFields: string[];\n}\n\nexport interface UsePivotEngineResult {\n ready: boolean;\n applyFilters: (filters: FilterSpec[]) => Promise<FilterResult>;\n computeGrouping: (visibleIds: Uint32Array, groupBy: GroupSpec) => Promise<GroupingResult>;\n sortIds: (visibleIds: Uint32Array, sortBy: string) => Promise<Uint32Array>;\n}\n\nexport function usePivotEngine<TItem extends object>({\n data,\n fieldExtractors,\n indexFields,\n}: UsePivotEngineOptions<TItem>): UsePivotEngineResult {\n const [ready, setReady] = useState(false);\n const workerRef = useRef<Worker | null>(null);\n const indexesRef = useRef<PivotIndexes | null>(null);\n const fallbackRef = useRef(false);\n const storeRef = useRef<PivotStore | null>(null);\n const pendingCallbacksRef = useRef<Map<string, (result: unknown) => void>>(new Map());\n\n useEffect(() => {\n console.log('[PivotEngine] Creating worker');\n const worker = new Worker(\n new URL('../engine/pivot.worker.ts', import.meta.url),\n { type: 'module' }\n );\n\n workerRef.current = worker;\n console.log('[PivotEngine] Worker created, setting up message handlers');\n\n worker.onmessage = (e: MessageEvent<WorkerOutMessage>) => {\n const message = e.data;\n console.log('[PivotEngine] Received message from worker:', message.type);\n\n switch (message.type) {\n case 'indexesReady':\n console.log('[PivotEngine] Indexes ready');\n setReady(true);\n break;\n\n case 'filterResult': {\n const callback = pendingCallbacksRef.current.get('filter');\n if (callback) {\n console.log('[PivotEngine] Calling filter callback and deleting');\n callback(message.result);\n pendingCallbacksRef.current.delete('filter');\n } else {\n console.warn('[PivotEngine] No callback registered for filter result - ignoring duplicate message');\n }\n break;\n }\n\n case 'groupingResult': {\n console.log('[PivotEngine] Received groupingResult:', message.result);\n const callback = pendingCallbacksRef.current.get('grouping');\n if (callback) {\n console.log('[PivotEngine] Calling grouping callback and deleting');\n callback(message.result);\n pendingCallbacksRef.current.delete('grouping');\n } else {\n console.warn('[PivotEngine] No callback registered for grouping result - ignoring duplicate message');\n }\n break;\n }\n\n case 'sortResult': {\n const callback = pendingCallbacksRef.current.get('sort');\n if (callback) {\n console.log('[PivotEngine] Calling sort callback and deleting');\n callback(message.result);\n pendingCallbacksRef.current.delete('sort');\n } else {\n console.warn('[PivotEngine] No callback registered for sort result - ignoring duplicate message');\n }\n break;\n }\n }\n };\n\n worker.onerror = (error) => {\n console.error('[PivotEngine] Worker error:', error);\n // enable synchronous fallback so UI can still function without worker\n fallbackRef.current = true;\n workerRef.current = null;\n // if we already built store/indexes, mark ready so UI can use fallback\n if (storeRef.current) {\n try {\n indexesRef.current = buildIndexes(storeRef.current, indexFields);\n } catch (e) {\n console.error('[PivotEngine] Failed to build indexes in fallback:', e);\n indexesRef.current = null;\n }\n setReady(true);\n }\n };\n\n return () => {\n worker.terminate();\n };\n }, []);\n\n useEffect(() => {\n if (!workerRef.current) {\n console.warn('[PivotEngine] Worker not available in data effect');\n return;\n }\n\n console.log('[PivotEngine] Building indexes for', data.length, 'items');\n setReady(false);\n\n const store = buildStore(data, fieldExtractors);\n storeRef.current = store;\n console.log('[PivotEngine] Store built with', store.items.length, 'items and', store.fields.size, 'fields');\n\n // compute indexes locally for immediate fallback and cache\n try {\n indexesRef.current = buildIndexes(store, indexFields);\n } catch (e) {\n console.error('[PivotEngine] buildIndexes failed:', e);\n indexesRef.current = null;\n }\n\n if (workerRef.current) {\n // Convert Map to array for serialization\n const fieldsArray = Array.from(store.fields.entries());\n const serializableStore = {\n ...store,\n fields: fieldsArray,\n };\n\n const message: WorkerInMessage = {\n type: 'buildIndexes',\n store: serializableStore as any,\n fields: indexFields,\n };\n\n console.log('[PivotEngine] Posting buildIndexes with', fieldsArray.length, 'fields');\n workerRef.current.postMessage(message);\n } else {\n // no worker available, mark ready to allow fallback synchronous usage\n setReady(true);\n }\n }, [data, fieldExtractors, indexFields]);\n\n const applyFiltersCallback = useCallback(\n (filters: FilterSpec[]): Promise<FilterResult> => {\n return new Promise((resolve) => {\n // If worker is not available, use synchronous fallback using local indexes\n if (!workerRef.current || fallbackRef.current) {\n try {\n const store = storeRef.current;\n const indexes = indexesRef.current;\n if (store && indexes) {\n const result = applyFilters(store, indexes, filters);\n resolve(result);\n return;\n }\n } catch (e) {\n console.error('[PivotEngine] fallback applyFilters error:', e);\n }\n\n // if fallback not possible, return empty result\n resolve({ visibleIds: new Uint32Array(0), count: 0 });\n return;\n }\n\n pendingCallbacksRef.current.set('filter', resolve as (result: unknown) => void);\n\n const message: WorkerInMessage = {\n type: 'applyFilters',\n filters,\n };\n\n workerRef.current.postMessage(message);\n });\n },\n [ready]\n );\n\n const computeGroupingCallback = useCallback(\n (visibleIds: Uint32Array, groupBy: GroupSpec): Promise<GroupingResult> => {\n console.log('[PivotEngine] computeGroupingCallback called with', visibleIds.length, 'visibleIds');\n \n // Check if there's already a pending grouping request\n if (pendingCallbacksRef.current.has('grouping')) {\n console.warn('[PivotEngine] Grouping already in progress, ignoring duplicate request');\n return Promise.resolve({ groups: [] });\n }\n \n return new Promise((resolve) => {\n // synchronous fallback if worker unavailable\n if (!workerRef.current || fallbackRef.current) {\n console.log('[PivotEngine] Using synchronous fallback for grouping');\n try {\n const store = storeRef.current;\n const indexes = indexesRef.current;\n if (store && indexes) {\n const result = computeGrouping(store, indexes, visibleIds, groupBy);\n console.log('[PivotEngine] Fallback grouping result:', result);\n resolve(result);\n return;\n }\n } catch (e) {\n console.error('[PivotEngine] fallback computeGrouping error:', e);\n }\n\n console.warn('[PivotEngine] No store/indexes for fallback, returning empty');\n resolve({ groups: [] });\n return;\n }\n\n console.log('[PivotEngine] Setting grouping callback and posting to worker');\n pendingCallbacksRef.current.set('grouping', resolve as (result: unknown) => void);\n\n const message: WorkerInMessage = {\n type: 'computeGrouping',\n visibleIds,\n groupBy,\n };\n\n workerRef.current.postMessage(message);\n console.log('[PivotEngine] Message posted to worker');\n });\n },\n [ready]\n );\n\n const sortIdsCallback = useCallback(\n (visibleIds: Uint32Array, sortBy: string): Promise<Uint32Array> => {\n return new Promise((resolve) => {\n // synchronous fallback if worker unavailable\n if (!workerRef.current || fallbackRef.current) {\n try {\n const store = storeRef.current;\n if (store) {\n const result = sortIds(store, visibleIds, sortBy);\n resolve(result);\n return;\n }\n } catch (e) {\n console.error('[PivotEngine] fallback sortIds error:', e);\n }\n\n resolve(visibleIds);\n return;\n }\n\n pendingCallbacksRef.current.set('sort', resolve as (result: unknown) => void);\n\n const message: WorkerInMessage = {\n type: 'sort',\n ids: visibleIds,\n sortBy,\n };\n\n workerRef.current.postMessage(message);\n });\n },\n [ready]\n );\n\n return {\n ready,\n applyFilters: applyFiltersCallback,\n computeGrouping: computeGroupingCallback,\n sortIds: sortIdsCallback,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"usePivotEngine.js","sources":["../../../../PivotViewer/hooks/usePivotEngine.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, useRef, useState, useCallback } from 'react';\nimport type {\n PivotStore,\n PivotIndexes,\n FilterSpec,\n FilterResult,\n GroupSpec,\n GroupingResult,\n WorkerInMessage,\n WorkerOutMessage,\n FieldValue,\n} from '../engine/types';\nimport { buildStore, buildIndexes, applyFilters, computeGrouping, sortIds } from '../engine/store';\n\nexport interface UsePivotEngineOptions<TItem extends object> {\n data: TItem[];\n fieldExtractors: Map<string, (item: TItem) => FieldValue>;\n indexFields: string[];\n}\n\nexport interface UsePivotEngineResult {\n ready: boolean;\n applyFilters: (filters: FilterSpec[]) => Promise<FilterResult>;\n computeGrouping: (visibleIds: Uint32Array, groupBy: GroupSpec) => Promise<GroupingResult>;\n sortIds: (visibleIds: Uint32Array, sortBy: string) => Promise<Uint32Array>;\n}\n\nexport function usePivotEngine<TItem extends object>({\n data,\n fieldExtractors,\n indexFields,\n}: UsePivotEngineOptions<TItem>): UsePivotEngineResult {\n const [ready, setReady] = useState(false);\n const workerRef = useRef<Worker | null>(null);\n const indexesRef = useRef<PivotIndexes | null>(null);\n const fallbackRef = useRef(false);\n const storeRef = useRef<PivotStore | null>(null);\n const pendingCallbacksRef = useRef<Map<string, (result: unknown) => void>>(new Map());\n\n useEffect(() => {\n console.log('[PivotEngine] Creating worker');\n const worker = new Worker(\n new URL('../engine/pivot.worker.ts', import.meta.url),\n { type: 'module' }\n );\n\n workerRef.current = worker;\n console.log('[PivotEngine] Worker created, setting up message handlers');\n\n worker.onmessage = (e: MessageEvent<WorkerOutMessage>) => {\n const message = e.data;\n console.log('[PivotEngine] Received message from worker:', message.type);\n\n switch (message.type) {\n case 'indexesReady':\n console.log('[PivotEngine] Indexes ready');\n setReady(true);\n break;\n\n case 'filterResult': {\n const callback = pendingCallbacksRef.current.get('filter');\n if (callback) {\n console.log('[PivotEngine] Calling filter callback and deleting');\n callback(message.result);\n pendingCallbacksRef.current.delete('filter');\n } else {\n console.warn('[PivotEngine] No callback registered for filter result - ignoring duplicate message');\n }\n break;\n }\n\n case 'groupingResult': {\n console.log('[PivotEngine] Received groupingResult:', message.result);\n const callback = pendingCallbacksRef.current.get('grouping');\n if (callback) {\n console.log('[PivotEngine] Calling grouping callback and deleting');\n callback(message.result);\n pendingCallbacksRef.current.delete('grouping');\n } else {\n console.warn('[PivotEngine] No callback registered for grouping result - ignoring duplicate message');\n }\n break;\n }\n\n case 'sortResult': {\n const callback = pendingCallbacksRef.current.get('sort');\n if (callback) {\n console.log('[PivotEngine] Calling sort callback and deleting');\n callback(message.result);\n pendingCallbacksRef.current.delete('sort');\n } else {\n console.warn('[PivotEngine] No callback registered for sort result - ignoring duplicate message');\n }\n break;\n }\n }\n };\n\n worker.onerror = (error) => {\n console.error('[PivotEngine] Worker error:', error);\n // enable synchronous fallback so UI can still function without worker\n fallbackRef.current = true;\n workerRef.current = null;\n // if we already built store/indexes, mark ready so UI can use fallback\n if (storeRef.current) {\n try {\n indexesRef.current = buildIndexes(storeRef.current, indexFields);\n } catch (e) {\n console.error('[PivotEngine] Failed to build indexes in fallback:', e);\n indexesRef.current = null;\n }\n setReady(true);\n }\n };\n\n return () => {\n worker.terminate();\n };\n }, []);\n\n useEffect(() => {\n if (!workerRef.current) {\n console.warn('[PivotEngine] Worker not available in data effect');\n return;\n }\n\n console.log('[PivotEngine] Building indexes for', data.length, 'items');\n setReady(false);\n\n const store = buildStore(data, fieldExtractors);\n storeRef.current = store;\n console.log('[PivotEngine] Store built with', store.items.length, 'items and', store.fields.size, 'fields');\n\n // compute indexes locally for immediate fallback and cache\n try {\n indexesRef.current = buildIndexes(store, indexFields);\n } catch (e) {\n console.error('[PivotEngine] buildIndexes failed:', e);\n indexesRef.current = null;\n }\n\n if (workerRef.current) {\n // Convert Map to array for serialization\n const fieldsArray = Array.from(store.fields.entries());\n const serializableStore = {\n ...store,\n fields: fieldsArray,\n };\n\n const message: WorkerInMessage = {\n type: 'buildIndexes',\n store: serializableStore as unknown as PivotStore,\n fields: indexFields,\n };\n\n console.log('[PivotEngine] Posting buildIndexes with', fieldsArray.length, 'fields');\n workerRef.current.postMessage(message);\n } else {\n // no worker available, mark ready to allow fallback synchronous usage\n setReady(true);\n }\n }, [data, fieldExtractors, indexFields]);\n\n const applyFiltersCallback = useCallback(\n (filters: FilterSpec[]): Promise<FilterResult> => {\n return new Promise((resolve) => {\n // If worker is not available, use synchronous fallback using local indexes\n if (!workerRef.current || fallbackRef.current) {\n try {\n const store = storeRef.current;\n const indexes = indexesRef.current;\n if (store && indexes) {\n const result = applyFilters(store, indexes, filters);\n resolve(result);\n return;\n }\n } catch (e) {\n console.error('[PivotEngine] fallback applyFilters error:', e);\n }\n\n // if fallback not possible, return empty result\n resolve({ visibleIds: new Uint32Array(0), count: 0 });\n return;\n }\n\n pendingCallbacksRef.current.set('filter', resolve as (result: unknown) => void);\n\n const message: WorkerInMessage = {\n type: 'applyFilters',\n filters,\n };\n\n workerRef.current.postMessage(message);\n });\n },\n [ready]\n );\n\n const computeGroupingCallback = useCallback(\n (visibleIds: Uint32Array, groupBy: GroupSpec): Promise<GroupingResult> => {\n console.log('[PivotEngine] computeGroupingCallback called with', visibleIds.length, 'visibleIds');\n \n // Check if there's already a pending grouping request\n if (pendingCallbacksRef.current.has('grouping')) {\n console.warn('[PivotEngine] Grouping already in progress, ignoring duplicate request');\n return Promise.resolve({ groups: [] });\n }\n \n return new Promise((resolve) => {\n // synchronous fallback if worker unavailable\n if (!workerRef.current || fallbackRef.current) {\n console.log('[PivotEngine] Using synchronous fallback for grouping');\n try {\n const store = storeRef.current;\n const indexes = indexesRef.current;\n if (store && indexes) {\n const result = computeGrouping(store, indexes, visibleIds, groupBy);\n console.log('[PivotEngine] Fallback grouping result:', result);\n resolve(result);\n return;\n }\n } catch (e) {\n console.error('[PivotEngine] fallback computeGrouping error:', e);\n }\n\n console.warn('[PivotEngine] No store/indexes for fallback, returning empty');\n resolve({ groups: [] });\n return;\n }\n\n console.log('[PivotEngine] Setting grouping callback and posting to worker');\n pendingCallbacksRef.current.set('grouping', resolve as (result: unknown) => void);\n\n const message: WorkerInMessage = {\n type: 'computeGrouping',\n visibleIds,\n groupBy,\n };\n\n workerRef.current.postMessage(message);\n console.log('[PivotEngine] Message posted to worker');\n });\n },\n [ready]\n );\n\n const sortIdsCallback = useCallback(\n (visibleIds: Uint32Array, sortBy: string): Promise<Uint32Array> => {\n return new Promise((resolve) => {\n // synchronous fallback if worker unavailable\n if (!workerRef.current || fallbackRef.current) {\n try {\n const store = storeRef.current;\n if (store) {\n const result = sortIds(store, visibleIds, sortBy);\n resolve(result);\n return;\n }\n } catch (e) {\n console.error('[PivotEngine] fallback sortIds error:', e);\n }\n\n resolve(visibleIds);\n return;\n }\n\n pendingCallbacksRef.current.set('sort', resolve as (result: unknown) => void);\n\n const message: WorkerInMessage = {\n type: 'sort',\n ids: visibleIds,\n sortBy,\n };\n\n workerRef.current.postMessage(message);\n });\n },\n [ready]\n );\n\n return {\n ready,\n applyFilters: applyFiltersCallback,\n computeGrouping: computeGroupingCallback,\n sortIds: sortIdsCallback,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useScrollSync.d.ts","sourceRoot":"","sources":["../../../../PivotViewer/hooks/useScrollSync.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAKtD,wBAAgB,aAAa,CACzB,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,EAC7C,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,EAC9C,QAAQ,EAAE,QAAQ,QAkBrB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
function useScrollSync(containerRef, axisLabelsRef, viewMode) {
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
const container = containerRef.current;
|
|
6
|
+
const axisLabels = axisLabelsRef.current;
|
|
7
|
+
if (!container || !axisLabels || viewMode !== 'grouped')
|
|
8
|
+
return;
|
|
9
|
+
const handleScroll = () => {
|
|
10
|
+
axisLabels.scrollLeft = container.scrollLeft;
|
|
11
|
+
};
|
|
12
|
+
handleScroll();
|
|
13
|
+
container.addEventListener('scroll', handleScroll);
|
|
14
|
+
return () => container.removeEventListener('scroll', handleScroll);
|
|
15
|
+
}, [viewMode, containerRef, axisLabelsRef]);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { useScrollSync };
|
|
19
|
+
//# sourceMappingURL=useScrollSync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useScrollSync.js","sources":["../../../../PivotViewer/hooks/useScrollSync.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 type { ViewMode } from '../components/Toolbar';\n\n/**\n * Synchronizes axis labels scroll with container scroll\n */\nexport function useScrollSync(\n containerRef: React.RefObject<HTMLDivElement>,\n axisLabelsRef: React.RefObject<HTMLDivElement>,\n viewMode: ViewMode,\n) {\n useEffect(() => {\n const container = containerRef.current;\n const axisLabels = axisLabelsRef.current;\n\n if (!container || !axisLabels || viewMode !== 'grouped') return;\n\n const handleScroll = () => {\n axisLabels.scrollLeft = container.scrollLeft;\n };\n\n // Sync immediately\n handleScroll();\n\n container.addEventListener('scroll', handleScroll);\n return () => container.removeEventListener('scroll', handleScroll);\n }, [viewMode, containerRef, axisLabelsRef]);\n}\n"],"names":[],"mappings":";;SASgB,aAAa,CACzB,YAA6C,EAC7C,aAA8C,EAC9C,QAAkB,EAAA;IAElB,SAAS,CAAC,MAAK;AACX,QAAA,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO;AACtC,QAAA,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO;QAExC,IAAI,CAAC,SAAS,IAAI,CAAC,UAAU,IAAI,QAAQ,KAAK,SAAS;YAAE;QAEzD,MAAM,YAAY,GAAG,MAAK;AACtB,YAAA,UAAU,CAAC,UAAU,GAAG,SAAS,CAAC,UAAU;AAChD,QAAA,CAAC;AAGD,QAAA,YAAY,EAAE;AAEd,QAAA,SAAS,CAAC,gBAAgB,CAAC,QAAQ,EAAE,YAAY,CAAC;QAClD,OAAO,MAAM,SAAS,CAAC,mBAAmB,CAAC,QAAQ,EAAE,YAAY,CAAC;IACtE,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;AAC/C;;;;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Layout } from '../utils/cardPosition';
|
|
2
|
+
import type { ViewMode } from '../components/Toolbar';
|
|
3
|
+
interface UseViewModeScrollHandlingParams<TItem extends object> {
|
|
4
|
+
containerRef: React.RefObject<HTMLDivElement>;
|
|
5
|
+
viewMode: ViewMode;
|
|
6
|
+
grouping: unknown;
|
|
7
|
+
layout: Layout;
|
|
8
|
+
selectedItem: TItem | null;
|
|
9
|
+
zoomLevel: number;
|
|
10
|
+
resolveId: (item: TItem, index: number) => string | number;
|
|
11
|
+
data: TItem[];
|
|
12
|
+
setPreSelectionState: (state: null) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare function useViewModeScrollHandling<TItem extends object>({ containerRef, viewMode, grouping, layout, selectedItem, zoomLevel, resolveId, data, setPreSelectionState, }: UseViewModeScrollHandlingParams<TItem>): void;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=useViewModeScrollHandling.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useViewModeScrollHandling.d.ts","sourceRoot":"","sources":["../../../../PivotViewer/hooks/useViewModeScrollHandling.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAOtD,UAAU,+BAA+B,CAAC,KAAK,SAAS,MAAM;IAC1D,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC9C,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,KAAK,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAAC;IAC3D,IAAI,EAAE,KAAK,EAAE,CAAC;IACd,oBAAoB,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,IAAI,CAAC;CAC/C;AAKD,wBAAgB,yBAAyB,CAAC,KAAK,SAAS,MAAM,EAAE,EAC5D,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,YAAY,EACZ,SAAS,EACT,SAAS,EACT,IAAI,EACJ,oBAAoB,GACvB,EAAE,+BAA+B,CAAC,KAAK,CAAC,QA6CxC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useRef, useEffect } from 'react';
|
|
2
|
+
import { calculateCenterScrollPosition } from '../utils/animations.js';
|
|
3
|
+
import { BASE_CARD_HEIGHT, BASE_CARD_WIDTH, DETAIL_PANEL_WIDTH } from '../utils/constants.js';
|
|
4
|
+
import { normalizeIdToLayoutKey, getCardPositionFromLayout } from '../utils/idResolution.js';
|
|
5
|
+
|
|
6
|
+
function useViewModeScrollHandling({ containerRef, viewMode, grouping, layout, selectedItem, zoomLevel, resolveId, data, setPreSelectionState, }) {
|
|
7
|
+
const lastProcessedViewMode = useRef(viewMode);
|
|
8
|
+
const lastProcessedGrouping = useRef(grouping);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
const viewModeChanged = lastProcessedViewMode.current !== viewMode;
|
|
11
|
+
const groupingChanged = lastProcessedGrouping.current !== grouping;
|
|
12
|
+
if (!viewModeChanged && !groupingChanged)
|
|
13
|
+
return;
|
|
14
|
+
lastProcessedViewMode.current = viewMode;
|
|
15
|
+
lastProcessedGrouping.current = grouping;
|
|
16
|
+
const container = containerRef.current;
|
|
17
|
+
if (!container)
|
|
18
|
+
return;
|
|
19
|
+
if (selectedItem) {
|
|
20
|
+
const index = data.indexOf(selectedItem);
|
|
21
|
+
let itemId = index !== -1 ? index : resolveId(selectedItem, 0);
|
|
22
|
+
itemId = normalizeIdToLayoutKey(itemId, layout);
|
|
23
|
+
const cardPosition = getCardPositionFromLayout(itemId, layout, BASE_CARD_WIDTH, BASE_CARD_HEIGHT);
|
|
24
|
+
if (cardPosition) {
|
|
25
|
+
const detailWidth = viewMode === 'collection' ? 0 : DETAIL_PANEL_WIDTH;
|
|
26
|
+
const { scrollLeft, scrollTop } = calculateCenterScrollPosition(container, cardPosition, zoomLevel, detailWidth, layout.totalHeight);
|
|
27
|
+
container.scrollTo({ left: scrollLeft, top: scrollTop });
|
|
28
|
+
setPreSelectionState(null);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
else if (viewMode === 'grouped') {
|
|
32
|
+
setTimeout(() => {
|
|
33
|
+
container.scrollTop = container.scrollHeight;
|
|
34
|
+
}, 0);
|
|
35
|
+
}
|
|
36
|
+
}, [viewMode, grouping, layout, selectedItem, resolveId, zoomLevel, containerRef, data, setPreSelectionState]);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export { useViewModeScrollHandling };
|
|
40
|
+
//# sourceMappingURL=useViewModeScrollHandling.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useViewModeScrollHandling.js","sources":["../../../../PivotViewer/hooks/useViewModeScrollHandling.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, useRef } from 'react';\nimport { calculateCenterScrollPosition } from '../utils/animations';\nimport type { Layout } from '../utils/cardPosition';\nimport type { ViewMode } from '../components/Toolbar';\nimport { BASE_CARD_WIDTH, BASE_CARD_HEIGHT, DETAIL_PANEL_WIDTH } from '../utils/constants';\nimport {\n getCardPositionFromLayout,\n normalizeIdToLayoutKey,\n} from '../utils/idResolution';\n\ninterface UseViewModeScrollHandlingParams<TItem extends object> {\n containerRef: React.RefObject<HTMLDivElement>;\n viewMode: ViewMode;\n grouping: unknown;\n layout: Layout;\n selectedItem: TItem | null;\n zoomLevel: number;\n resolveId: (item: TItem, index: number) => string | number;\n data: TItem[];\n setPreSelectionState: (state: null) => void;\n}\n\n/**\n * Handles scroll positioning when switching view modes or grouping changes\n */\nexport function useViewModeScrollHandling<TItem extends object>({\n containerRef,\n viewMode,\n grouping,\n layout,\n selectedItem,\n zoomLevel,\n resolveId,\n data,\n setPreSelectionState,\n}: UseViewModeScrollHandlingParams<TItem>) {\n const lastProcessedViewMode = useRef(viewMode);\n const lastProcessedGrouping = useRef(grouping);\n\n useEffect(() => {\n const viewModeChanged = lastProcessedViewMode.current !== viewMode;\n const groupingChanged = lastProcessedGrouping.current !== grouping;\n\n if (!viewModeChanged && !groupingChanged) return;\n\n lastProcessedViewMode.current = viewMode;\n lastProcessedGrouping.current = grouping;\n\n const container = containerRef.current;\n if (!container) return;\n\n // If we have a selected item, keep it centered in the new layout\n if (selectedItem) {\n const index = data.indexOf(selectedItem);\n let itemId: string | number = index !== -1 ? index : resolveId(selectedItem, 0);\n itemId = normalizeIdToLayoutKey(itemId, layout);\n\n const cardPosition = getCardPositionFromLayout(itemId, layout, BASE_CARD_WIDTH, BASE_CARD_HEIGHT);\n\n if (cardPosition) {\n const detailWidth = viewMode === 'collection' ? 0 : DETAIL_PANEL_WIDTH;\n\n const { scrollLeft, scrollTop } = calculateCenterScrollPosition(\n container,\n cardPosition,\n zoomLevel,\n detailWidth,\n layout.totalHeight,\n );\n\n container.scrollTo({ left: scrollLeft, top: scrollTop });\n setPreSelectionState(null);\n }\n } else if (viewMode === 'grouped') {\n // Default behavior for grouped view: scroll to bottom\n setTimeout(() => {\n container.scrollTop = container.scrollHeight;\n }, 0);\n }\n }, [viewMode, grouping, layout, selectedItem, resolveId, zoomLevel, containerRef, data, setPreSelectionState]);\n}\n"],"names":[],"mappings":";;;;;AA4BM,SAAU,yBAAyB,CAAuB,EAC5D,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,YAAY,EACZ,SAAS,EACT,SAAS,EACT,IAAI,EACJ,oBAAoB,GACiB,EAAA;AACrC,IAAA,MAAM,qBAAqB,GAAG,MAAM,CAAC,QAAQ,CAAC;AAC9C,IAAA,MAAM,qBAAqB,GAAG,MAAM,CAAC,QAAQ,CAAC;IAE9C,SAAS,CAAC,MAAK;AACX,QAAA,MAAM,eAAe,GAAG,qBAAqB,CAAC,OAAO,KAAK,QAAQ;AAClE,QAAA,MAAM,eAAe,GAAG,qBAAqB,CAAC,OAAO,KAAK,QAAQ;AAElE,QAAA,IAAI,CAAC,eAAe,IAAI,CAAC,eAAe;YAAE;AAE1C,QAAA,qBAAqB,CAAC,OAAO,GAAG,QAAQ;AACxC,QAAA,qBAAqB,CAAC,OAAO,GAAG,QAAQ;AAExC,QAAA,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO;AACtC,QAAA,IAAI,CAAC,SAAS;YAAE;QAGhB,IAAI,YAAY,EAAE;YACd,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC;AACxC,YAAA,IAAI,MAAM,GAAoB,KAAK,KAAK,EAAE,GAAG,KAAK,GAAG,SAAS,CAAC,YAAY,EAAE,CAAC,CAAC;AAC/E,YAAA,MAAM,GAAG,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC;AAE/C,YAAA,MAAM,YAAY,GAAG,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,gBAAgB,CAAC;YAEjG,IAAI,YAAY,EAAE;AACd,gBAAA,MAAM,WAAW,GAAG,QAAQ,KAAK,YAAY,GAAG,CAAC,GAAG,kBAAkB;gBAEtE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,6BAA6B,CAC3D,SAAS,EACT,YAAY,EACZ,SAAS,EACT,WAAW,EACX,MAAM,CAAC,WAAW,CACrB;AAED,gBAAA,SAAS,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;gBACxD,oBAAoB,CAAC,IAAI,CAAC;YAC9B;QACJ;AAAO,aAAA,IAAI,QAAQ,KAAK,SAAS,EAAE;YAE/B,UAAU,CAAC,MAAK;AACZ,gBAAA,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC,YAAY;YAChD,CAAC,EAAE,CAAC,CAAC;QACT;IACJ,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE,oBAAoB,CAAC,CAAC;AAClH;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sources":["../../../PivotViewer/types.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 { ReactNode } from 'react';\n\nexport type PivotPrimitive = string | number | boolean | Date | null | undefined;\n\n/**\n * Type-safe property accessor for accessing properties, including nested ones\n */\nexport type PropertyAccessor<TItem> = (item: TItem) => unknown;\n\n/**\n * Extract property path from a property accessor function\n * Supports nested properties like item => item.address.city\n */\nexport function getPropertyPath<TItem>(accessor: PropertyAccessor<TItem>): string {\n const fnStr = accessor.toString();\n // Match patterns like: item => item.prop or item => item.prop.nested or (item) => item.prop\n const match = fnStr.match(/(?:=>|return)\\s*[a-zA-Z_$][a-zA-Z0-9_$]*\\.([a-zA-Z_$][a-zA-Z0-9_$.]*)/)
|
|
1
|
+
{"version":3,"file":"types.js","sources":["../../../PivotViewer/types.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 { ReactNode } from 'react';\n\nexport type PivotPrimitive = string | number | boolean | Date | null | undefined;\n\n/**\n * Type-safe property accessor for accessing properties, including nested ones\n */\nexport type PropertyAccessor<TItem> = (item: TItem) => unknown;\n\n/**\n * Extract property path from a property accessor function\n * Supports nested properties like item => item.address.city\n */\nexport function getPropertyPath<TItem>(accessor: PropertyAccessor<TItem>): string {\n const fnStr = accessor.toString();\n // Match patterns like: item => item.prop or item => item.prop.nested or (item) => item.prop\n const match = fnStr.match(/(?:=>|return)\\s*[a-zA-Z_$][a-zA-Z0-9_$]*\\.([a-zA-Z_$][a-zA-Z0-9_$.]*)/);\n return match ? match[1] : '';\n}\n\n/**\n * Get the value from an item using a property path string\n * Supports nested properties like \"address.city\"\n */\nexport function getValueByPath<TItem>(item: TItem, path: string): unknown {\n const parts = path.split('.');\n let value: unknown = item;\n for (const part of parts) {\n if (value === null || value === undefined) {\n return undefined;\n }\n value = value[part];\n }\n return value;\n}\n\nexport interface PivotGroup<TItem extends object> {\n key: string;\n label: string;\n value: PivotPrimitive;\n items: TItem[];\n count?: number;\n}\n\nexport interface PivotDimension<TItem extends object> {\n key: string;\n label: string;\n getValue: (item: TItem) => PivotPrimitive;\n formatValue?: (value: PivotPrimitive) => string;\n sort?: (a: PivotGroup<TItem>, b: PivotGroup<TItem>) => number;\n}\n\nexport interface PivotFilterOption {\n key: string;\n label: string;\n value: PivotPrimitive;\n count: number;\n}\n\nexport interface PivotFilter<TItem extends object> {\n key: string;\n label: string;\n getValue: (item: TItem) => PivotPrimitive;\n multi?: boolean;\n options?: PivotFilterOption[];\n sort?: (a: PivotFilterOption, b: PivotFilterOption) => number;\n /** For numeric filters, enables range picker with histogram */\n type?: 'string' | 'number' | 'date';\n /** Number of buckets for the histogram in range filters */\n buckets?: number;\n}\n\nexport interface PivotViewerProps<TItem extends object> {\n data: TItem[];\n dimensions: PivotDimension<TItem>[];\n filters?: PivotFilter<TItem>[];\n defaultDimensionKey?: string;\n cardRenderer?: (item: TItem) => ReactNode;\n getItemId?: (item: TItem, index: number) => string | number;\n searchFields?: PropertyAccessor<TItem>[];\n className?: string;\n emptyContent?: ReactNode;\n isLoading?: boolean;\n}\n\nexport type FilterState = Record<string, Set<string>>;\n\nexport type RangeFilterState = Record<string, [number, number] | null>;\n"],"names":[],"mappings":"AAgBM,SAAU,eAAe,CAAQ,QAAiC,EAAA;AACpE,IAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,EAAE;IAEjC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,uEAAuE,CAAC;AAClG,IAAA,OAAO,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE;AAChC;AAMM,SAAU,cAAc,CAAQ,IAAW,EAAE,IAAY,EAAA;IAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;IAC7B,IAAI,KAAK,GAAY,IAAI;AACzB,IAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;QACtB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE;AACvC,YAAA,OAAO,SAAS;QACpB;AACA,QAAA,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC;IACvB;AACA,IAAA,OAAO,KAAK;AAChB;;;;"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { GroupingResult } from '../engine/types';
|
|
2
|
+
import type { ViewMode } from '../components/Toolbar';
|
|
3
|
+
import type { LayoutResult } from '../engine/types';
|
|
4
|
+
import type { CardPosition } from './idResolution';
|
|
5
|
+
export type Layout = LayoutResult;
|
|
6
|
+
export declare function getCardPositionAtZoom(zoom: number, itemId: string | number, grouping: GroupingResult, viewMode: ViewMode, containerWidth: number, containerHeight: number): CardPosition | null;
|
|
7
|
+
export declare function getLayoutSizeAtZoom(zoom: number, grouping: GroupingResult, viewMode: ViewMode, containerWidth: number, containerHeight: number): {
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
};
|
|
11
|
+
export declare function createCardPositionCallbacks(itemId: string | number, grouping: GroupingResult, viewMode: ViewMode, containerWidth: number, containerHeight: number): {
|
|
12
|
+
getCardPositionAtZoom: (zoom: number) => CardPosition | null;
|
|
13
|
+
getLayoutSizeAtZoom: (zoom: number) => {
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=cardPosition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cardPosition.d.ts","sourceRoot":"","sources":["../../../../PivotViewer/utils/cardPosition.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAQtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,MAAM,MAAM,GAAG,YAAY,CAAC;AAKlC,wBAAgB,qBAAqB,CACjC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,MAAM,GACxB,YAAY,GAAG,IAAI,CA6BrB;AAKD,wBAAgB,mBAAmB,CAC/B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,MAAM,GACxB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAgCnC;AAMD,wBAAgB,2BAA2B,CACvC,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,MAAM;kCAGW,MAAM;gCAGR,MAAM;eAjD9B,MAAM;gBAAU,MAAM;;EAoDjC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { computeLayout } from '../engine/layout.js';
|
|
2
|
+
import { BASE_CARD_HEIGHT, BASE_CARD_WIDTH, GROUP_SPACING, CARDS_PER_COLUMN } from '../constants.js';
|
|
3
|
+
|
|
4
|
+
function getCardPositionAtZoom(zoom, itemId, grouping, viewMode, containerWidth, containerHeight) {
|
|
5
|
+
const scaledContainerWidth = containerWidth / zoom;
|
|
6
|
+
const scaledContainerHeight = viewMode === 'collection'
|
|
7
|
+
? containerHeight / zoom
|
|
8
|
+
: containerHeight;
|
|
9
|
+
const layout = computeLayout(grouping, {
|
|
10
|
+
viewMode,
|
|
11
|
+
cardWidth: BASE_CARD_WIDTH,
|
|
12
|
+
cardHeight: BASE_CARD_HEIGHT,
|
|
13
|
+
cardsPerColumn: CARDS_PER_COLUMN,
|
|
14
|
+
groupSpacing: GROUP_SPACING,
|
|
15
|
+
containerWidth: scaledContainerWidth,
|
|
16
|
+
containerHeight: scaledContainerHeight,
|
|
17
|
+
});
|
|
18
|
+
const position = layout.positions.get(itemId);
|
|
19
|
+
if (!position) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
x: position.x,
|
|
24
|
+
y: position.y,
|
|
25
|
+
width: BASE_CARD_WIDTH,
|
|
26
|
+
height: BASE_CARD_HEIGHT,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function getLayoutSizeAtZoom(zoom, grouping, viewMode, containerWidth, containerHeight) {
|
|
30
|
+
if (viewMode === 'collection') {
|
|
31
|
+
const layout = computeLayout(grouping, {
|
|
32
|
+
viewMode,
|
|
33
|
+
cardWidth: BASE_CARD_WIDTH,
|
|
34
|
+
cardHeight: BASE_CARD_HEIGHT,
|
|
35
|
+
cardsPerColumn: CARDS_PER_COLUMN,
|
|
36
|
+
groupSpacing: GROUP_SPACING,
|
|
37
|
+
containerWidth,
|
|
38
|
+
containerHeight,
|
|
39
|
+
});
|
|
40
|
+
return { width: layout.totalWidth, height: layout.totalHeight };
|
|
41
|
+
}
|
|
42
|
+
const scaledContainerWidth = containerWidth / zoom;
|
|
43
|
+
const scaledContainerHeight = containerHeight;
|
|
44
|
+
const layout = computeLayout(grouping, {
|
|
45
|
+
viewMode,
|
|
46
|
+
cardWidth: BASE_CARD_WIDTH,
|
|
47
|
+
cardHeight: BASE_CARD_HEIGHT,
|
|
48
|
+
cardsPerColumn: CARDS_PER_COLUMN,
|
|
49
|
+
groupSpacing: GROUP_SPACING,
|
|
50
|
+
containerWidth: scaledContainerWidth,
|
|
51
|
+
containerHeight: scaledContainerHeight,
|
|
52
|
+
});
|
|
53
|
+
return { width: layout.totalWidth, height: layout.totalHeight };
|
|
54
|
+
}
|
|
55
|
+
function createCardPositionCallbacks(itemId, grouping, viewMode, containerWidth, containerHeight) {
|
|
56
|
+
return {
|
|
57
|
+
getCardPositionAtZoom: (zoom) => getCardPositionAtZoom(zoom, itemId, grouping, viewMode, containerWidth, containerHeight),
|
|
58
|
+
getLayoutSizeAtZoom: (zoom) => getLayoutSizeAtZoom(zoom, grouping, viewMode, containerWidth, containerHeight),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export { createCardPositionCallbacks, getCardPositionAtZoom, getLayoutSizeAtZoom };
|
|
63
|
+
//# sourceMappingURL=cardPosition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cardPosition.js","sources":["../../../../PivotViewer/utils/cardPosition.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 { GroupingResult } from '../engine/types';\nimport { computeLayout } from '../engine/layout';\nimport {\n BASE_CARD_WIDTH,\n BASE_CARD_HEIGHT,\n CARDS_PER_COLUMN,\n GROUP_SPACING,\n} from '../constants';\nimport type { ViewMode } from '../components/Toolbar';\nimport type { LayoutResult } from '../engine/types';\nimport type { CardPosition } from './idResolution';\n\nexport type Layout = LayoutResult;\n\n/**\n * Computes the card position at a specific zoom level\n */\nexport function getCardPositionAtZoom(\n zoom: number,\n itemId: string | number,\n grouping: GroupingResult,\n viewMode: ViewMode,\n containerWidth: number,\n containerHeight: number,\n): CardPosition | null {\n const scaledContainerWidth = containerWidth / zoom;\n const scaledContainerHeight = viewMode === 'collection'\n ? containerHeight / zoom\n : containerHeight;\n\n const layout = computeLayout(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n grouping as unknown as any, {\n viewMode,\n cardWidth: BASE_CARD_WIDTH,\n cardHeight: BASE_CARD_HEIGHT,\n cardsPerColumn: CARDS_PER_COLUMN,\n groupSpacing: GROUP_SPACING,\n containerWidth: scaledContainerWidth,\n containerHeight: scaledContainerHeight,\n });\n\n const position = layout.positions.get(itemId);\n if (!position) {\n return null;\n }\n\n return {\n x: position.x,\n y: position.y,\n width: BASE_CARD_WIDTH,\n height: BASE_CARD_HEIGHT,\n };\n}\n\n/**\n * Computes layout size at a specific zoom level\n */\nexport function getLayoutSizeAtZoom(\n zoom: number,\n grouping: GroupingResult,\n viewMode: ViewMode,\n containerWidth: number,\n containerHeight: number,\n): { width: number; height: number } {\n if (viewMode === 'collection') {\n const layout = computeLayout(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n grouping as unknown as any, {\n viewMode,\n cardWidth: BASE_CARD_WIDTH,\n cardHeight: BASE_CARD_HEIGHT,\n cardsPerColumn: CARDS_PER_COLUMN,\n groupSpacing: GROUP_SPACING,\n containerWidth,\n containerHeight,\n });\n return { width: layout.totalWidth, height: layout.totalHeight };\n }\n\n const scaledContainerWidth = containerWidth / zoom;\n const scaledContainerHeight = containerHeight;\n\n const layout = computeLayout(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n grouping as unknown as any, {\n viewMode,\n cardWidth: BASE_CARD_WIDTH,\n cardHeight: BASE_CARD_HEIGHT,\n cardsPerColumn: CARDS_PER_COLUMN,\n groupSpacing: GROUP_SPACING,\n containerWidth: scaledContainerWidth,\n containerHeight: scaledContainerHeight,\n });\n\n return { width: layout.totalWidth, height: layout.totalHeight };\n}\n\n/**\n * Creates callback functions for card position calculations at various zoom levels\n * Used for smooth animations during zoom and pan operations\n */\nexport function createCardPositionCallbacks(\n itemId: string | number,\n grouping: GroupingResult,\n viewMode: ViewMode,\n containerWidth: number,\n containerHeight: number,\n) {\n return {\n getCardPositionAtZoom: (zoom: number) =>\n getCardPositionAtZoom(zoom, itemId, grouping, viewMode, containerWidth, containerHeight),\n \n getLayoutSizeAtZoom: (zoom: number) =>\n getLayoutSizeAtZoom(zoom, grouping, viewMode, containerWidth, containerHeight),\n };\n}\n"],"names":[],"mappings":";;;AAoBM,SAAU,qBAAqB,CACjC,IAAY,EACZ,MAAuB,EACvB,QAAwB,EACxB,QAAkB,EAClB,cAAsB,EACtB,eAAuB,EAAA;AAEvB,IAAA,MAAM,oBAAoB,GAAG,cAAc,GAAG,IAAI;AAClD,IAAA,MAAM,qBAAqB,GAAG,QAAQ,KAAK;UACrC,eAAe,GAAG;UAClB,eAAe;AAErB,IAAA,MAAM,MAAM,GAAG,aAAa,CAExB,QAA0B,EAAE;QAC5B,QAAQ;AACR,QAAA,SAAS,EAAE,eAAe;AAC1B,QAAA,UAAU,EAAE,gBAAgB;AAC5B,QAAA,cAAc,EAAE,gBAAgB;AAChC,QAAA,YAAY,EAAE,aAAa;AAC3B,QAAA,cAAc,EAAE,oBAAoB;AACpC,QAAA,eAAe,EAAE,qBAAqB;AACzC,KAAA,CAAC;IAEF,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC;IAC7C,IAAI,CAAC,QAAQ,EAAE;AACX,QAAA,OAAO,IAAI;IACf;IAEA,OAAO;QACH,CAAC,EAAE,QAAQ,CAAC,CAAC;QACb,CAAC,EAAE,QAAQ,CAAC,CAAC;AACb,QAAA,KAAK,EAAE,eAAe;AACtB,QAAA,MAAM,EAAE,gBAAgB;KAC3B;AACL;AAKM,SAAU,mBAAmB,CAC/B,IAAY,EACZ,QAAwB,EACxB,QAAkB,EAClB,cAAsB,EACtB,eAAuB,EAAA;AAEvB,IAAA,IAAI,QAAQ,KAAK,YAAY,EAAE;AAC3B,QAAA,MAAM,MAAM,GAAG,aAAa,CAExB,QAA0B,EAAE;YAC5B,QAAQ;AACR,YAAA,SAAS,EAAE,eAAe;AAC1B,YAAA,UAAU,EAAE,gBAAgB;AAC5B,YAAA,cAAc,EAAE,gBAAgB;AAChC,YAAA,YAAY,EAAE,aAAa;YAC3B,cAAc;YACd,eAAe;AAClB,SAAA,CAAC;AACF,QAAA,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE;IACnE;AAEA,IAAA,MAAM,oBAAoB,GAAG,cAAc,GAAG,IAAI;IAClD,MAAM,qBAAqB,GAAG,eAAe;AAE7C,IAAA,MAAM,MAAM,GAAG,aAAa,CAExB,QAA0B,EAAE;QAC5B,QAAQ;AACR,QAAA,SAAS,EAAE,eAAe;AAC1B,QAAA,UAAU,EAAE,gBAAgB;AAC5B,QAAA,cAAc,EAAE,gBAAgB;AAChC,QAAA,YAAY,EAAE,aAAa;AAC3B,QAAA,cAAc,EAAE,oBAAoB;AACpC,QAAA,eAAe,EAAE,qBAAqB;AACzC,KAAA,CAAC;AAEF,IAAA,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE;AACnE;AAMM,SAAU,2BAA2B,CACvC,MAAuB,EACvB,QAAwB,EACxB,QAAkB,EAClB,cAAsB,EACtB,eAAuB,EAAA;IAEvB,OAAO;AACH,QAAA,qBAAqB,EAAE,CAAC,IAAY,KAChC,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,eAAe,CAAC;AAE5F,QAAA,mBAAmB,EAAE,CAAC,IAAY,KAC9B,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,eAAe,CAAC;KACrF;AACL;;;;"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
const ZOOM_MAX = 3;
|
|
2
|
+
const BASE_CARD_WIDTH = 180;
|
|
3
|
+
const BASE_CARD_HEIGHT = 140;
|
|
2
4
|
const DETAIL_PANEL_WIDTH = 380;
|
|
3
5
|
const ZOOM_MULTIPLIER = 1.15;
|
|
4
6
|
const MIN_ZOOM_ON_SELECT = 1.2;
|
|
5
7
|
|
|
6
|
-
export { DETAIL_PANEL_WIDTH, MIN_ZOOM_ON_SELECT, ZOOM_MAX, ZOOM_MULTIPLIER };
|
|
8
|
+
export { BASE_CARD_HEIGHT, BASE_CARD_WIDTH, DETAIL_PANEL_WIDTH, MIN_ZOOM_ON_SELECT, ZOOM_MAX, ZOOM_MULTIPLIER };
|
|
7
9
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sources":["../../../../PivotViewer/utils/constants.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\n// Zoom constants\nexport const ZOOM_MIN = 0.1;\nexport const ZOOM_MAX = 3;\nexport const ZOOM_STEP = 0.05;\n\n// Layout constants\nexport const GROUP_SPACING = 40;\nexport const CARD_GAP = 8;\nexport const CARDS_PER_COLUMN = 5;\nexport const BASE_CARD_WIDTH = 180;\nexport const BASE_CARD_HEIGHT = 140;\nexport const DETAIL_PANEL_WIDTH = 380;\n\n// Animation constants\nexport const ZOOM_ANIMATION_DURATION = 300;\nexport const ZOOM_MULTIPLIER = 1.15;\nexport const MIN_ZOOM_ON_SELECT = 1.2;\n"],"names":[],"mappings":"AAKO,MAAM,QAAQ,GAAG;
|
|
1
|
+
{"version":3,"file":"constants.js","sources":["../../../../PivotViewer/utils/constants.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\n// Zoom constants\nexport const ZOOM_MIN = 0.1;\nexport const ZOOM_MAX = 3;\nexport const ZOOM_STEP = 0.05;\n\n// Layout constants\nexport const GROUP_SPACING = 40;\nexport const CARD_GAP = 8;\nexport const CARDS_PER_COLUMN = 5;\nexport const BASE_CARD_WIDTH = 180;\nexport const BASE_CARD_HEIGHT = 140;\nexport const DETAIL_PANEL_WIDTH = 380;\n\n// Animation constants\nexport const ZOOM_ANIMATION_DURATION = 300;\nexport const ZOOM_MULTIPLIER = 1.15;\nexport const MIN_ZOOM_ON_SELECT = 1.2;\n"],"names":[],"mappings":"AAKO,MAAM,QAAQ,GAAG;AAOjB,MAAM,eAAe,GAAG;AACxB,MAAM,gBAAgB,GAAG;AACzB,MAAM,kBAAkB,GAAG;AAI3B,MAAM,eAAe,GAAG;AACxB,MAAM,kBAAkB,GAAG;;;;"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { LayoutResult } from '../engine/types';
|
|
2
|
+
type Layout = LayoutResult;
|
|
3
|
+
export interface CardPosition {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function resolveItemId<TItem extends object>(item: TItem, index: number, getItemId?: (item: TItem, index: number) => string | number): string | number;
|
|
10
|
+
export declare function normalizeIdToLayoutKey(itemId: string | number, layout: Layout): string | number;
|
|
11
|
+
export declare function getCardPositionFromLayout(itemId: string | number, layout: Layout, cardWidth: number, cardHeight: number): CardPosition | null;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=idResolution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idResolution.d.ts","sourceRoot":"","sources":["../../../../PivotViewer/utils/idResolution.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD,KAAK,MAAM,GAAG,YAAY,CAAC;AAE3B,MAAM,WAAW,YAAY;IACzB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAClB;AAKD,wBAAgB,aAAa,CAAC,KAAK,SAAS,MAAM,EAC9C,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,GAC5D,MAAM,GAAG,MAAM,CAOjB;AAMD,wBAAgB,sBAAsB,CAClC,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,MAAM,EAAE,MAAM,GACf,MAAM,GAAG,MAAM,CAqBjB;AAKD,wBAAgB,yBAAyB,CACrC,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACnB,YAAY,GAAG,IAAI,CAcrB"}
|