@cratis/components 0.1.13 → 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.
Files changed (73) hide show
  1. package/dist/cjs/PivotViewer/PivotViewer.js +57 -378
  2. package/dist/cjs/PivotViewer/PivotViewer.js.map +1 -1
  3. package/dist/cjs/PivotViewer/hooks/useAnimationModeTracking.js +37 -0
  4. package/dist/cjs/PivotViewer/hooks/useAnimationModeTracking.js.map +1 -0
  5. package/dist/cjs/PivotViewer/hooks/useCardSelection.js +64 -0
  6. package/dist/cjs/PivotViewer/hooks/useCardSelection.js.map +1 -0
  7. package/dist/cjs/PivotViewer/hooks/useCurrentFilters.js +52 -0
  8. package/dist/cjs/PivotViewer/hooks/useCurrentFilters.js.map +1 -0
  9. package/dist/cjs/PivotViewer/hooks/useDetailPanelClose.js +63 -0
  10. package/dist/cjs/PivotViewer/hooks/useDetailPanelClose.js.map +1 -0
  11. package/dist/cjs/PivotViewer/hooks/useFieldExtractors.js +50 -0
  12. package/dist/cjs/PivotViewer/hooks/useFieldExtractors.js.map +1 -0
  13. package/dist/cjs/PivotViewer/hooks/useScrollSync.js +21 -0
  14. package/dist/cjs/PivotViewer/hooks/useScrollSync.js.map +1 -0
  15. package/dist/cjs/PivotViewer/hooks/useViewModeScrollHandling.js +42 -0
  16. package/dist/cjs/PivotViewer/hooks/useViewModeScrollHandling.js.map +1 -0
  17. package/dist/cjs/PivotViewer/utils/cardPosition.js +67 -0
  18. package/dist/cjs/PivotViewer/utils/cardPosition.js.map +1 -0
  19. package/dist/cjs/PivotViewer/utils/constants.js +4 -0
  20. package/dist/cjs/PivotViewer/utils/constants.js.map +1 -1
  21. package/dist/cjs/PivotViewer/utils/idResolution.js +34 -0
  22. package/dist/cjs/PivotViewer/utils/idResolution.js.map +1 -0
  23. package/dist/esm/PivotViewer/PivotViewer.d.ts.map +1 -1
  24. package/dist/esm/PivotViewer/PivotViewer.js +57 -378
  25. package/dist/esm/PivotViewer/PivotViewer.js.map +1 -1
  26. package/dist/esm/PivotViewer/hooks/index.d.ts +7 -0
  27. package/dist/esm/PivotViewer/hooks/index.d.ts.map +1 -1
  28. package/dist/esm/PivotViewer/hooks/index.js +7 -0
  29. package/dist/esm/PivotViewer/hooks/index.js.map +1 -1
  30. package/dist/esm/PivotViewer/hooks/useAnimationModeTracking.d.ts +2 -0
  31. package/dist/esm/PivotViewer/hooks/useAnimationModeTracking.d.ts.map +1 -0
  32. package/dist/esm/PivotViewer/hooks/useAnimationModeTracking.js +35 -0
  33. package/dist/esm/PivotViewer/hooks/useAnimationModeTracking.js.map +1 -0
  34. package/dist/esm/PivotViewer/hooks/useCardSelection.d.ts +37 -0
  35. package/dist/esm/PivotViewer/hooks/useCardSelection.d.ts.map +1 -0
  36. package/dist/esm/PivotViewer/hooks/useCardSelection.js +62 -0
  37. package/dist/esm/PivotViewer/hooks/useCardSelection.js.map +1 -0
  38. package/dist/esm/PivotViewer/hooks/useCurrentFilters.d.ts +5 -0
  39. package/dist/esm/PivotViewer/hooks/useCurrentFilters.d.ts.map +1 -0
  40. package/dist/esm/PivotViewer/hooks/useCurrentFilters.js +49 -0
  41. package/dist/esm/PivotViewer/hooks/useCurrentFilters.js.map +1 -0
  42. package/dist/esm/PivotViewer/hooks/useDetailPanelClose.d.ts +27 -0
  43. package/dist/esm/PivotViewer/hooks/useDetailPanelClose.d.ts.map +1 -0
  44. package/dist/esm/PivotViewer/hooks/useDetailPanelClose.js +61 -0
  45. package/dist/esm/PivotViewer/hooks/useDetailPanelClose.js.map +1 -0
  46. package/dist/esm/PivotViewer/hooks/useFieldExtractors.d.ts +7 -0
  47. package/dist/esm/PivotViewer/hooks/useFieldExtractors.d.ts.map +1 -0
  48. package/dist/esm/PivotViewer/hooks/useFieldExtractors.js +48 -0
  49. package/dist/esm/PivotViewer/hooks/useFieldExtractors.js.map +1 -0
  50. package/dist/esm/PivotViewer/hooks/useScrollSync.d.ts +3 -0
  51. package/dist/esm/PivotViewer/hooks/useScrollSync.d.ts.map +1 -0
  52. package/dist/esm/PivotViewer/hooks/useScrollSync.js +19 -0
  53. package/dist/esm/PivotViewer/hooks/useScrollSync.js.map +1 -0
  54. package/dist/esm/PivotViewer/hooks/useViewModeScrollHandling.d.ts +16 -0
  55. package/dist/esm/PivotViewer/hooks/useViewModeScrollHandling.d.ts.map +1 -0
  56. package/dist/esm/PivotViewer/hooks/useViewModeScrollHandling.js +40 -0
  57. package/dist/esm/PivotViewer/hooks/useViewModeScrollHandling.js.map +1 -0
  58. package/dist/esm/PivotViewer/utils/cardPosition.d.ts +18 -0
  59. package/dist/esm/PivotViewer/utils/cardPosition.d.ts.map +1 -0
  60. package/dist/esm/PivotViewer/utils/cardPosition.js +63 -0
  61. package/dist/esm/PivotViewer/utils/cardPosition.js.map +1 -0
  62. package/dist/esm/PivotViewer/utils/constants.js +3 -1
  63. package/dist/esm/PivotViewer/utils/constants.js.map +1 -1
  64. package/dist/esm/PivotViewer/utils/idResolution.d.ts +13 -0
  65. package/dist/esm/PivotViewer/utils/idResolution.d.ts.map +1 -0
  66. package/dist/esm/PivotViewer/utils/idResolution.js +31 -0
  67. package/dist/esm/PivotViewer/utils/idResolution.js.map +1 -0
  68. package/dist/esm/PivotViewer/utils/index.d.ts +2 -0
  69. package/dist/esm/PivotViewer/utils/index.d.ts.map +1 -1
  70. package/dist/esm/PivotViewer/utils/index.js +2 -0
  71. package/dist/esm/PivotViewer/utils/index.js.map +1 -1
  72. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  73. package/package.json +1 -1
@@ -0,0 +1,67 @@
1
+ 'use strict';
2
+
3
+ var layout = require('../engine/layout.js');
4
+ var constants = require('../constants.js');
5
+
6
+ function getCardPositionAtZoom(zoom, itemId, grouping, viewMode, containerWidth, containerHeight) {
7
+ const scaledContainerWidth = containerWidth / zoom;
8
+ const scaledContainerHeight = viewMode === 'collection'
9
+ ? containerHeight / zoom
10
+ : containerHeight;
11
+ const layout$1 = layout.computeLayout(grouping, {
12
+ viewMode,
13
+ cardWidth: constants.BASE_CARD_WIDTH,
14
+ cardHeight: constants.BASE_CARD_HEIGHT,
15
+ cardsPerColumn: constants.CARDS_PER_COLUMN,
16
+ groupSpacing: constants.GROUP_SPACING,
17
+ containerWidth: scaledContainerWidth,
18
+ containerHeight: scaledContainerHeight,
19
+ });
20
+ const position = layout$1.positions.get(itemId);
21
+ if (!position) {
22
+ return null;
23
+ }
24
+ return {
25
+ x: position.x,
26
+ y: position.y,
27
+ width: constants.BASE_CARD_WIDTH,
28
+ height: constants.BASE_CARD_HEIGHT,
29
+ };
30
+ }
31
+ function getLayoutSizeAtZoom(zoom, grouping, viewMode, containerWidth, containerHeight) {
32
+ if (viewMode === 'collection') {
33
+ const layout$1 = layout.computeLayout(grouping, {
34
+ viewMode,
35
+ cardWidth: constants.BASE_CARD_WIDTH,
36
+ cardHeight: constants.BASE_CARD_HEIGHT,
37
+ cardsPerColumn: constants.CARDS_PER_COLUMN,
38
+ groupSpacing: constants.GROUP_SPACING,
39
+ containerWidth,
40
+ containerHeight,
41
+ });
42
+ return { width: layout$1.totalWidth, height: layout$1.totalHeight };
43
+ }
44
+ const scaledContainerWidth = containerWidth / zoom;
45
+ const scaledContainerHeight = containerHeight;
46
+ const layout$1 = layout.computeLayout(grouping, {
47
+ viewMode,
48
+ cardWidth: constants.BASE_CARD_WIDTH,
49
+ cardHeight: constants.BASE_CARD_HEIGHT,
50
+ cardsPerColumn: constants.CARDS_PER_COLUMN,
51
+ groupSpacing: constants.GROUP_SPACING,
52
+ containerWidth: scaledContainerWidth,
53
+ containerHeight: scaledContainerHeight,
54
+ });
55
+ return { width: layout$1.totalWidth, height: layout$1.totalHeight };
56
+ }
57
+ function createCardPositionCallbacks(itemId, grouping, viewMode, containerWidth, containerHeight) {
58
+ return {
59
+ getCardPositionAtZoom: (zoom) => getCardPositionAtZoom(zoom, itemId, grouping, viewMode, containerWidth, containerHeight),
60
+ getLayoutSizeAtZoom: (zoom) => getLayoutSizeAtZoom(zoom, grouping, viewMode, containerWidth, containerHeight),
61
+ };
62
+ }
63
+
64
+ exports.createCardPositionCallbacks = createCardPositionCallbacks;
65
+ exports.getCardPositionAtZoom = getCardPositionAtZoom;
66
+ exports.getLayoutSizeAtZoom = getLayoutSizeAtZoom;
67
+ //# 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":["layout","computeLayout","BASE_CARD_WIDTH","BASE_CARD_HEIGHT","CARDS_PER_COLUMN","GROUP_SPACING"],"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,MAAMA,QAAM,GAAGC,oBAAa,CAExB,QAA0B,EAAE;QAC5B,QAAQ;AACR,QAAA,SAAS,EAAEC,yBAAe;AAC1B,QAAA,UAAU,EAAEC,0BAAgB;AAC5B,QAAA,cAAc,EAAEC,0BAAgB;AAChC,QAAA,YAAY,EAAEC,uBAAa;AAC3B,QAAA,cAAc,EAAE,oBAAoB;AACpC,QAAA,eAAe,EAAE,qBAAqB;AACzC,KAAA,CAAC;IAEF,MAAM,QAAQ,GAAGL,QAAM,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,EAAEE,yBAAe;AACtB,QAAA,MAAM,EAAEC,0BAAgB;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,MAAMH,QAAM,GAAGC,oBAAa,CAExB,QAA0B,EAAE;YAC5B,QAAQ;AACR,YAAA,SAAS,EAAEC,yBAAe;AAC1B,YAAA,UAAU,EAAEC,0BAAgB;AAC5B,YAAA,cAAc,EAAEC,0BAAgB;AAChC,YAAA,YAAY,EAAEC,uBAAa;YAC3B,cAAc;YACd,eAAe;AAClB,SAAA,CAAC;AACF,QAAA,OAAO,EAAE,KAAK,EAAEL,QAAM,CAAC,UAAU,EAAE,MAAM,EAAEA,QAAM,CAAC,WAAW,EAAE;IACnE;AAEA,IAAA,MAAM,oBAAoB,GAAG,cAAc,GAAG,IAAI;IAClD,MAAM,qBAAqB,GAAG,eAAe;AAE7C,IAAA,MAAMA,QAAM,GAAGC,oBAAa,CAExB,QAA0B,EAAE;QAC5B,QAAQ;AACR,QAAA,SAAS,EAAEC,yBAAe;AAC1B,QAAA,UAAU,EAAEC,0BAAgB;AAC5B,QAAA,cAAc,EAAEC,0BAAgB;AAChC,QAAA,YAAY,EAAEC,uBAAa;AAC3B,QAAA,cAAc,EAAE,oBAAoB;AACpC,QAAA,eAAe,EAAE,qBAAqB;AACzC,KAAA,CAAC;AAEF,IAAA,OAAO,EAAE,KAAK,EAAEL,QAAM,CAAC,UAAU,EAAE,MAAM,EAAEA,QAAM,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,10 +1,14 @@
1
1
  'use strict';
2
2
 
3
3
  const ZOOM_MAX = 3;
4
+ const BASE_CARD_WIDTH = 180;
5
+ const BASE_CARD_HEIGHT = 140;
4
6
  const DETAIL_PANEL_WIDTH = 380;
5
7
  const ZOOM_MULTIPLIER = 1.15;
6
8
  const MIN_ZOOM_ON_SELECT = 1.2;
7
9
 
10
+ exports.BASE_CARD_HEIGHT = BASE_CARD_HEIGHT;
11
+ exports.BASE_CARD_WIDTH = BASE_CARD_WIDTH;
8
12
  exports.DETAIL_PANEL_WIDTH = DETAIL_PANEL_WIDTH;
9
13
  exports.MIN_ZOOM_ON_SELECT = MIN_ZOOM_ON_SELECT;
10
14
  exports.ZOOM_MAX = ZOOM_MAX;
@@ -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;AASjB,MAAM,kBAAkB,GAAG;AAI3B,MAAM,eAAe,GAAG;AACxB,MAAM,kBAAkB,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,34 @@
1
+ 'use strict';
2
+
3
+ function normalizeIdToLayoutKey(itemId, layout) {
4
+ if (layout.positions.has(itemId)) {
5
+ return itemId;
6
+ }
7
+ if (typeof itemId === 'number' && layout.positions.has(String(itemId))) {
8
+ return String(itemId);
9
+ }
10
+ if (typeof itemId === 'string') {
11
+ const numId = Number(itemId);
12
+ if (!isNaN(numId) && layout.positions.has(numId)) {
13
+ return numId;
14
+ }
15
+ }
16
+ return itemId;
17
+ }
18
+ function getCardPositionFromLayout(itemId, layout, cardWidth, cardHeight) {
19
+ const normalizedId = normalizeIdToLayoutKey(itemId, layout);
20
+ const position = layout.positions.get(normalizedId);
21
+ if (!position) {
22
+ return null;
23
+ }
24
+ return {
25
+ x: position.x,
26
+ y: position.y,
27
+ width: cardWidth,
28
+ height: cardHeight,
29
+ };
30
+ }
31
+
32
+ exports.getCardPositionFromLayout = getCardPositionFromLayout;
33
+ exports.normalizeIdToLayoutKey = normalizeIdToLayoutKey;
34
+ //# sourceMappingURL=idResolution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idResolution.js","sources":["../../../../PivotViewer/utils/idResolution.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';\n\ntype Layout = LayoutResult;\n\nexport interface CardPosition {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * Resolves the ID for an item, handling type conversions and consistency with layout keys\n */\nexport function resolveItemId<TItem extends object>(\n item: TItem,\n index: number,\n getItemId?: (item: TItem, index: number) => string | number,\n): string | number {\n if (getItemId) {\n const id = getItemId(item, index);\n return typeof id === 'number' ? id : id;\n }\n const id = (item as Record<string, unknown>)['id'];\n return typeof id === 'number' ? id : index;\n}\n\n/**\n * Ensures the item ID matches the layout's key type (number vs string)\n * by attempting type conversion if needed\n */\nexport function normalizeIdToLayoutKey(\n itemId: string | number,\n layout: Layout,\n): string | number {\n // If already in layout, return as-is\n if (layout.positions.has(itemId)) {\n return itemId;\n }\n\n // Try converting number to string\n if (typeof itemId === 'number' && layout.positions.has(String(itemId))) {\n return String(itemId);\n }\n\n // Try converting string to number\n if (typeof itemId === 'string') {\n const numId = Number(itemId);\n if (!isNaN(numId) && layout.positions.has(numId)) {\n return numId;\n }\n }\n\n // Return original if no match found (will likely result in null position)\n return itemId;\n}\n\n/**\n * Gets the card position from the layout, handling ID type mismatches\n */\nexport function getCardPositionFromLayout(\n itemId: string | number,\n layout: Layout,\n cardWidth: number,\n cardHeight: number,\n): CardPosition | null {\n const normalizedId = normalizeIdToLayoutKey(itemId, layout);\n const position = layout.positions.get(normalizedId);\n\n if (!position) {\n return null;\n }\n\n return {\n x: position.x,\n y: position.y,\n width: cardWidth,\n height: cardHeight,\n };\n}\n"],"names":[],"mappings":";;AAkCM,SAAU,sBAAsB,CAClC,MAAuB,EACvB,MAAc,EAAA;IAGd,IAAI,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;AAC9B,QAAA,OAAO,MAAM;IACjB;AAGA,IAAA,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE;AACpE,QAAA,OAAO,MAAM,CAAC,MAAM,CAAC;IACzB;AAGA,IAAA,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;AAC5B,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;AAC5B,QAAA,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;AAC9C,YAAA,OAAO,KAAK;QAChB;IACJ;AAGA,IAAA,OAAO,MAAM;AACjB;AAKM,SAAU,yBAAyB,CACrC,MAAuB,EACvB,MAAc,EACd,SAAiB,EACjB,UAAkB,EAAA;IAElB,MAAM,YAAY,GAAG,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC;IAC3D,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC;IAEnD,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,SAAS;AAChB,QAAA,MAAM,EAAE,UAAU;KACrB;AACL;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"PivotViewer.d.ts","sourceRoot":"","sources":["../../../PivotViewer/PivotViewer.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAiBhD,OAAO,mBAAmB,CAAC;AAQ3B,wBAAgB,WAAW,CAAC,KAAK,SAAS,MAAM,EAAE,EAC9C,IAAI,EACJ,UAAU,EACV,OAAO,EACP,mBAAmB,EACnB,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,SAAiB,GACpB,EAAE,gBAAgB,CAAC,KAAK,CAAC,2CAgwBzB"}
1
+ {"version":3,"file":"PivotViewer.d.ts","sourceRoot":"","sources":["../../../PivotViewer/PivotViewer.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAQhD,OAAO,mBAAmB,CAAC;AAe3B,wBAAgB,WAAW,CAAC,KAAK,SAAS,MAAM,EAAE,EAC9C,IAAI,EACJ,UAAU,EACV,OAAO,EACP,mBAAmB,EACnB,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,SAAiB,GACpB,EAAE,gBAAgB,CAAC,KAAK,CAAC,2CA6VzB"}
@@ -5,10 +5,7 @@ import { computeLayout } from './engine/layout.js';
5
5
  import { useFilterState } from './hooks/useFilterState.js';
6
6
  import { useDimensionState } from './hooks/useDimensionState.js';
7
7
  import { useZoomState } from './hooks/useZoomState.js';
8
- import { handleCardSelection } from './utils/selection.js';
9
- import { calculateCenterScrollPosition, smoothScrollTo, animateZoomAndScroll } from './utils/animations.js';
10
8
  import { BASE_CARD_HEIGHT, BASE_CARD_WIDTH, GROUP_SPACING, CARDS_PER_COLUMN } from './constants.js';
11
- import { DETAIL_PANEL_WIDTH, ZOOM_MAX, MIN_ZOOM_ON_SELECT, ZOOM_MULTIPLIER } from './utils/constants.js';
12
9
  import './PivotViewer.css';
13
10
  import { PivotViewerMain } from './components/PivotViewerMain.js';
14
11
  import { FilterPanelContainer } from './components/FilterPanelContainer.js';
@@ -17,6 +14,13 @@ import { useFilterOptions } from './hooks/useFilterOptions.js';
17
14
  import { usePanning } from './hooks/usePanning.js';
18
15
  import { useWheelZoom } from './hooks/useWheelZoom.js';
19
16
  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';
20
24
  import { useContainerDimensions } from './hooks/useContainerDimensions.js';
21
25
 
22
26
  function PivotViewer({ data, dimensions, filters, defaultDimensionKey, cardRenderer, getItemId, searchFields, className, emptyContent, isLoading = false, }) {
@@ -37,12 +41,6 @@ function PivotViewer({ data, dimensions, filters, defaultDimensionKey, cardRende
37
41
  const [scrollPosition, setScrollPosition] = useState({ x: 0, y: 0 });
38
42
  const { filterState, rangeFilterState, expandedFilterKey, setExpandedFilterKey, handleToggleFilter, handleClearFilter, handleRangeChange, } = useFilterState(filters);
39
43
  const { activeDimensionKey, setActiveDimensionKey, activeDimension, dimensionFilter, handleAxisLabelClick, } = useDimensionState(dimensions, defaultDimensionKey);
40
- const prevFilterStateRef = useRef(filterState);
41
- const prevRangeFilterStateRef = useRef(rangeFilterState);
42
- const prevSearchRef = useRef(search);
43
- const prevDimensionRef = useRef(activeDimensionKey);
44
- const prevViewModeRef = useRef(viewMode);
45
- const isFirstRenderRef = useRef(true);
46
44
  const { zoomLevel, setZoomLevel, handleZoomIn, handleZoomOut, handleZoomSlider, } = useZoomState(1);
47
45
  const { isPanning, handlePanStart, handlePanMove, handlePanEnd, } = usePanning(containerRef, undefined, setScrollPosition);
48
46
  useWheelZoom(containerRef, zoomLevel, setZoomLevel);
@@ -60,125 +58,14 @@ function PivotViewer({ data, dimensions, filters, defaultDimensionKey, cardRende
60
58
  container.addEventListener('scroll', handleScroll);
61
59
  return () => container.removeEventListener('scroll', handleScroll);
62
60
  }, []);
63
- useEffect(() => {
64
- if (isFirstRenderRef.current) {
65
- isFirstRenderRef.current = false;
66
- return;
67
- }
68
- const filterChanged = prevFilterStateRef.current !== filterState;
69
- const rangeChanged = prevRangeFilterStateRef.current !== rangeFilterState;
70
- const searchChanged = prevSearchRef.current !== search;
71
- const dimensionChanged = prevDimensionRef.current !== activeDimensionKey;
72
- const viewModeChanged = prevViewModeRef.current !== viewMode;
73
- if (filterChanged || rangeChanged || searchChanged) {
74
- setAnimationMode('filter');
75
- }
76
- else if (dimensionChanged || viewModeChanged) {
77
- setAnimationMode('layout');
78
- }
79
- prevFilterStateRef.current = filterState;
80
- prevRangeFilterStateRef.current = rangeFilterState;
81
- prevSearchRef.current = search;
82
- prevDimensionRef.current = activeDimensionKey;
83
- prevViewModeRef.current = viewMode;
84
- }, [filterState, rangeFilterState, search, activeDimensionKey, viewMode]);
85
- useEffect(() => {
86
- const container = containerRef.current;
87
- const axisLabels = axisLabelsRef.current;
88
- if (!container || !axisLabels || viewMode !== 'grouped')
89
- return;
90
- const handleScroll = () => {
91
- axisLabels.scrollLeft = container.scrollLeft;
92
- };
93
- handleScroll();
94
- container.addEventListener('scroll', handleScroll);
95
- return () => container.removeEventListener('scroll', handleScroll);
96
- }, [viewMode]);
97
- const fieldExtractors = useMemo(() => {
98
- const extractors = new Map();
99
- for (const dim of dimensions) {
100
- extractors.set(dim.key, (item) => {
101
- const val = dim.getValue(item);
102
- if (val instanceof Date)
103
- return val.getTime();
104
- if (typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean' || val === null) {
105
- return val;
106
- }
107
- return String(val);
108
- });
109
- }
110
- if (filters) {
111
- for (const filter of filters) {
112
- extractors.set(filter.key, (item) => {
113
- const val = filter.getValue(item);
114
- if (val instanceof Date)
115
- return val.getTime();
116
- if (typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean' || val === null) {
117
- return val;
118
- }
119
- return String(val);
120
- });
121
- }
122
- }
123
- return extractors;
124
- }, [dimensions, filters]);
125
- const indexFields = useMemo(() => {
126
- const fields = new Set();
127
- for (const dim of dimensions) {
128
- fields.add(dim.key);
129
- }
130
- if (filters) {
131
- for (const filter of filters) {
132
- fields.add(filter.key);
133
- }
134
- }
135
- return Array.from(fields);
136
- }, [dimensions, filters]);
61
+ const { fieldExtractors, indexFields } = useFieldExtractors(dimensions, filters);
137
62
  const { ready, applyFilters: engineApplyFilters, computeGrouping, sortIds } = usePivotEngine({
138
63
  data,
139
64
  fieldExtractors,
140
65
  indexFields,
141
66
  });
142
- const currentFilters = useMemo(() => {
143
- const specs = [];
144
- const searchTerm = search.trim().toLowerCase();
145
- if (searchTerm && searchFields && searchFields.length > 0) ;
146
- for (const [key, values] of Object.entries(filterState)) {
147
- const valueSet = values;
148
- if (valueSet.size > 0) {
149
- specs.push({
150
- field: key,
151
- type: 'categorical',
152
- values: valueSet,
153
- });
154
- }
155
- }
156
- for (const [key, range] of Object.entries(rangeFilterState)) {
157
- if (range && (range[0] !== null || range[1] !== null)) {
158
- const min = range[0] ?? -Infinity;
159
- const max = range[1] ?? Infinity;
160
- specs.push({
161
- field: key,
162
- type: 'numeric',
163
- range: { min, max },
164
- });
165
- }
166
- }
167
- if (dimensionFilter && activeDimension) {
168
- specs.push({
169
- field: activeDimension.key,
170
- type: 'categorical',
171
- values: new Set([dimensionFilter]),
172
- });
173
- }
174
- return specs;
175
- }, [filterState, rangeFilterState, search, searchFields, dimensionFilter, activeDimension]);
176
- const currentGroupBy = useMemo(() => {
177
- return {
178
- field: activeDimensionKey || dimensions[0]?.key || '',
179
- buckets: 10,
180
- };
181
- }, [activeDimensionKey, dimensions]);
67
+ const currentFilters = useCurrentFilters(filters, filterState, rangeFilterState, search, searchFields, dimensionFilter, activeDimension);
68
+ const currentGroupBy = useCurrentGroupBy(activeDimensionKey, dimensions);
182
69
  useEffect(() => {
183
70
  if (!ready)
184
71
  return;
@@ -224,7 +111,7 @@ function PivotViewer({ data, dimensions, filters, defaultDimensionKey, cardRende
224
111
  const lastRequest = lastGroupingRequest.current;
225
112
  if (lastRequest &&
226
113
  lastRequest.viewMode === viewMode &&
227
- lastRequest.groupBy.field === currentGroupBy.field &&
114
+ lastRequest.groupBy?.field === currentGroupBy.field &&
228
115
  lastRequest.visibleIds === visibleIds) {
229
116
  console.log('[PivotViewer] Skipping duplicate grouping request');
230
117
  return;
@@ -262,260 +149,52 @@ function PivotViewer({ data, dimensions, filters, defaultDimensionKey, cardRende
262
149
  const id = item['id'];
263
150
  return typeof id === 'number' ? id : index;
264
151
  }, [getItemId]);
265
- const lastProcessedViewMode = useRef(viewMode);
266
- const lastProcessedGrouping = useRef(grouping);
267
- useEffect(() => {
268
- const viewModeChanged = lastProcessedViewMode.current !== viewMode;
269
- const groupingChanged = lastProcessedGrouping.current !== grouping;
270
- if (!viewModeChanged && !groupingChanged)
271
- return;
272
- lastProcessedViewMode.current = viewMode;
273
- lastProcessedGrouping.current = grouping;
274
- const container = containerRef.current;
275
- if (!container)
276
- return;
277
- if (selectedItem) {
278
- let itemId = resolveId(selectedItem, 0);
279
- if (typeof itemId === 'string' && !layout.positions.has(itemId)) {
280
- const numId = Number(itemId);
281
- if (!isNaN(numId) && layout.positions.has(numId))
282
- itemId = numId;
283
- }
284
- else if (typeof itemId === 'number' && !layout.positions.has(itemId)) {
285
- const strId = String(itemId);
286
- if (layout.positions.has(strId))
287
- itemId = strId;
288
- }
289
- const position = layout.positions.get(itemId);
290
- if (position) {
291
- const cardPosition = {
292
- x: position.x,
293
- y: position.y,
294
- width: BASE_CARD_WIDTH,
295
- height: BASE_CARD_HEIGHT
296
- };
297
- const detailWidth = viewMode === 'collection' ? 0 : DETAIL_PANEL_WIDTH;
298
- const { scrollLeft, scrollTop } = calculateCenterScrollPosition(container, cardPosition, zoomLevel, detailWidth, layout.totalHeight);
299
- container.scrollTo({ left: scrollLeft, top: scrollTop });
300
- setPreSelectionState(null);
301
- }
302
- }
303
- else if (viewMode === 'grouped') {
304
- setTimeout(() => {
305
- container.scrollTop = container.scrollHeight;
306
- setScrollPosition({ x: container.scrollLeft, y: container.scrollTop });
307
- }, 0);
308
- }
309
- }, [viewMode, grouping, layout, selectedItem, resolveId, zoomLevel]);
310
- const handleCardClick = useCallback((item, e, id) => {
311
- if (isPanning)
312
- return;
313
- const container = containerRef.current;
314
- if (!container)
315
- return;
316
- let itemId = (id !== undefined && id !== null) ? id : resolveId(item, 0);
317
- if (typeof itemId === 'string' && !layout.positions.has(itemId)) {
318
- const numId = Number(itemId);
319
- if (!isNaN(numId) && layout.positions.has(numId)) {
320
- itemId = numId;
321
- }
322
- }
323
- else if (typeof itemId === 'number' && !layout.positions.has(itemId)) {
324
- const strId = String(itemId);
325
- if (layout.positions.has(strId)) {
326
- itemId = strId;
327
- }
328
- }
329
- const selectedId = selectedItem ? (data.indexOf(selectedItem) !== -1 ? data.indexOf(selectedItem) : resolveId(selectedItem, 0)) : null;
330
- const position = layout.positions.get(itemId);
331
- const cardPosition = position ? {
332
- x: position.x,
333
- y: position.y,
334
- width: BASE_CARD_WIDTH,
335
- height: BASE_CARD_HEIGHT
336
- } : null;
337
- let targetCardPosition = null;
338
- let getCardPositionAtZoom = undefined;
339
- let targetTotalHeight = layout.totalHeight;
340
- if (viewMode === 'grouped' && cardPosition) {
341
- const targetZoom = Math.min(ZOOM_MAX, Math.max(MIN_ZOOM_ON_SELECT, zoomLevel * ZOOM_MULTIPLIER));
342
- const targetContainerWidth = containerDimensions.width / targetZoom;
343
- const targetContainerHeight = containerDimensions.height;
344
- const targetLayout = computeLayout(grouping, {
345
- viewMode,
346
- cardWidth: BASE_CARD_WIDTH,
347
- cardHeight: BASE_CARD_HEIGHT,
348
- cardsPerColumn: CARDS_PER_COLUMN,
349
- groupSpacing: GROUP_SPACING,
350
- containerWidth: targetContainerWidth,
351
- containerHeight: targetContainerHeight,
352
- });
353
- targetTotalHeight = targetLayout.totalHeight;
354
- const targetPos = targetLayout.positions.get(itemId);
355
- if (targetPos) {
356
- targetCardPosition = {
357
- x: targetPos.x,
358
- y: targetPos.y,
359
- width: BASE_CARD_WIDTH,
360
- height: BASE_CARD_HEIGHT
361
- };
362
- }
363
- getCardPositionAtZoom = (zoom) => {
364
- const currentContainerWidth = containerDimensions.width / zoom;
365
- const currentContainerHeight = containerDimensions.height;
366
- const currentLayout = computeLayout(grouping, {
367
- viewMode,
368
- cardWidth: BASE_CARD_WIDTH,
369
- cardHeight: BASE_CARD_HEIGHT,
370
- cardsPerColumn: CARDS_PER_COLUMN,
371
- groupSpacing: GROUP_SPACING,
372
- containerWidth: currentContainerWidth,
373
- containerHeight: currentContainerHeight,
374
- });
375
- const pos = currentLayout.positions.get(itemId);
376
- return pos ? { x: pos.x, y: pos.y, width: BASE_CARD_WIDTH, height: BASE_CARD_HEIGHT } : null;
377
- };
378
- }
379
- const getLayoutSizeAtZoom = (zoom) => {
380
- if (viewMode === 'collection') {
381
- return { width: layout.totalWidth, height: layout.totalHeight };
382
- }
383
- const currentContainerWidth = containerDimensions.width / zoom;
384
- const currentContainerHeight = containerDimensions.height;
385
- const currentLayout = computeLayout(grouping, {
386
- viewMode,
387
- cardWidth: BASE_CARD_WIDTH,
388
- cardHeight: BASE_CARD_HEIGHT,
389
- cardsPerColumn: CARDS_PER_COLUMN,
390
- groupSpacing: GROUP_SPACING,
391
- containerWidth: currentContainerWidth,
392
- containerHeight: currentContainerHeight,
393
- });
394
- return { width: currentLayout.totalWidth, height: currentLayout.totalHeight };
395
- };
396
- handleCardSelection({
397
- item,
398
- itemId,
399
- selectedItemId: selectedId,
400
- container,
401
- cardPosition,
402
- targetCardPosition,
403
- getCardPositionAtZoom,
404
- getLayoutSizeAtZoom,
405
- spacer: spacerRef.current,
406
- preSelectionState,
407
- startScrollPosition: { x: scrollPosition.x, y: scrollPosition.y },
408
- setZoomLevel,
409
- setIsZooming,
410
- setSelectedItem,
411
- setPreSelectionState,
412
- viewMode,
413
- zoomLevel,
414
- totalHeight: targetTotalHeight,
415
- });
416
- }, [isPanning, selectedItem, zoomLevel, preSelectionState, viewMode, resolveId, setZoomLevel, layout, grouping, containerDimensions, scrollPosition]);
417
- const closeDetail = useCallback(() => {
418
- const container = containerRef.current;
419
- if (!container || !selectedItem) {
420
- setSelectedItem(null);
421
- return;
422
- }
423
- const index = data.indexOf(selectedItem);
424
- let itemId = index !== -1 ? index : resolveId(selectedItem, 0);
425
- if (typeof itemId === 'string' && !layout.positions.has(itemId)) {
426
- const numId = Number(itemId);
427
- if (!isNaN(numId) && layout.positions.has(numId)) {
428
- itemId = numId;
429
- }
430
- }
431
- else if (typeof itemId === 'number' && !layout.positions.has(itemId)) {
432
- const strId = String(itemId);
433
- if (layout.positions.has(strId)) {
434
- itemId = strId;
435
- }
436
- }
437
- const position = layout.positions.get(itemId);
438
- const cardPosition = position ? {
439
- x: position.x,
440
- y: position.y,
441
- width: BASE_CARD_WIDTH,
442
- height: BASE_CARD_HEIGHT
443
- } : null;
444
- if (!preSelectionState) {
445
- setSelectedItem(null);
446
- return;
447
- }
448
- if (viewMode === 'collection') {
449
- setSelectedItem(null);
450
- smoothScrollTo(container, preSelectionState.scrollLeft, preSelectionState.scrollTop, true);
451
- setPreSelectionState(null);
452
- return;
453
- }
454
- const zoomChanged = Math.abs(preSelectionState.zoom - zoomLevel) > 0.001;
455
- if (!zoomChanged || !cardPosition) {
456
- setSelectedItem(null);
457
- smoothScrollTo(container, preSelectionState.scrollLeft, preSelectionState.scrollTop, true);
458
- setPreSelectionState(null);
459
- return;
460
- }
461
- let targetCardPosition = null;
462
- let getCardPositionAtZoom = undefined;
463
- if (viewMode === 'grouped') {
464
- const targetZoom = preSelectionState.zoom;
465
- const targetContainerWidth = containerDimensions.width / targetZoom;
466
- const targetContainerHeight = containerDimensions.height;
467
- const targetLayout = computeLayout(grouping, {
468
- viewMode,
469
- cardWidth: BASE_CARD_WIDTH,
470
- cardHeight: BASE_CARD_HEIGHT,
471
- cardsPerColumn: CARDS_PER_COLUMN,
472
- groupSpacing: GROUP_SPACING,
473
- containerWidth: targetContainerWidth,
474
- containerHeight: targetContainerHeight,
475
- });
476
- const targetPos = targetLayout.positions.get(itemId);
477
- if (targetPos) {
478
- targetCardPosition = {
479
- x: targetPos.x,
480
- y: targetPos.y,
481
- width: BASE_CARD_WIDTH,
482
- height: BASE_CARD_HEIGHT
483
- };
484
- }
485
- getCardPositionAtZoom = (zoom) => {
486
- const currentContainerWidth = containerDimensions.width / zoom;
487
- const currentContainerHeight = containerDimensions.height;
488
- const currentLayout = computeLayout(grouping, {
489
- viewMode,
490
- cardWidth: BASE_CARD_WIDTH,
491
- cardHeight: BASE_CARD_HEIGHT,
492
- cardsPerColumn: CARDS_PER_COLUMN,
493
- groupSpacing: GROUP_SPACING,
494
- containerWidth: currentContainerWidth,
495
- containerHeight: currentContainerHeight,
496
- });
497
- const pos = currentLayout.positions.get(itemId);
498
- return pos ? { x: pos.x, y: pos.y, width: BASE_CARD_WIDTH, height: BASE_CARD_HEIGHT } : null;
499
- };
500
- }
501
- setIsZooming(true);
502
- animateZoomAndScroll({
503
- container,
504
- cardPosition,
505
- targetCardPosition,
506
- getCardPositionAtZoom,
507
- startZoom: zoomLevel,
508
- targetZoom: preSelectionState.zoom,
509
- targetScrollLeft: preSelectionState.scrollLeft,
510
- targetScrollTop: preSelectionState.scrollTop,
511
- onUpdate: setZoomLevel,
512
- onComplete: () => {
513
- setIsZooming(false);
514
- setSelectedItem(null);
515
- setPreSelectionState(null);
516
- },
517
- });
518
- }, [preSelectionState, selectedItem, zoomLevel, viewMode, resolveId, setZoomLevel, layout, grouping, containerDimensions]);
152
+ useAnimationModeTracking(filterState, rangeFilterState, search, activeDimensionKey, viewMode, setAnimationMode);
153
+ useScrollSync(containerRef, axisLabelsRef, viewMode);
154
+ useViewModeScrollHandling({
155
+ containerRef,
156
+ viewMode,
157
+ grouping,
158
+ layout,
159
+ selectedItem,
160
+ zoomLevel,
161
+ resolveId,
162
+ data,
163
+ setPreSelectionState,
164
+ });
165
+ const handleCardClick = useCardSelection({
166
+ data,
167
+ isPanning,
168
+ selectedItem,
169
+ zoomLevel,
170
+ viewMode,
171
+ layout,
172
+ containerDimensions,
173
+ scrollPosition,
174
+ preSelectionState,
175
+ grouping,
176
+ getItemId,
177
+ resolveId,
178
+ setZoomLevel,
179
+ setIsZooming,
180
+ setSelectedItem,
181
+ setPreSelectionState,
182
+ });
183
+ const closeDetail = useDetailPanelClose({
184
+ selectedItem,
185
+ preSelectionState,
186
+ zoomLevel,
187
+ viewMode,
188
+ layout,
189
+ containerDimensions,
190
+ grouping,
191
+ data,
192
+ resolveId,
193
+ setZoomLevel,
194
+ setIsZooming,
195
+ setSelectedItem,
196
+ setPreSelectionState,
197
+ });
519
198
  const cardWidth = BASE_CARD_WIDTH;
520
199
  const cardHeight = BASE_CARD_HEIGHT;
521
200
  const filterOptions = useFilterOptions(data, filters, filterState, rangeFilterState);