@cratis/components 0.1.15 → 0.1.17

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 (103) hide show
  1. package/dist/cjs/PivotViewer/PivotViewer.css +32 -19
  2. package/dist/cjs/PivotViewer/PivotViewer.js +44 -8
  3. package/dist/cjs/PivotViewer/PivotViewer.js.map +1 -1
  4. package/dist/cjs/PivotViewer/components/PivotCanvas.js +32 -51
  5. package/dist/cjs/PivotViewer/components/PivotCanvas.js.map +1 -1
  6. package/dist/cjs/PivotViewer/components/PivotViewerMain.js +4 -2
  7. package/dist/cjs/PivotViewer/components/PivotViewerMain.js.map +1 -1
  8. package/dist/cjs/PivotViewer/components/Toolbar.js +1 -1
  9. package/dist/cjs/PivotViewer/components/Toolbar.js.map +1 -1
  10. package/dist/cjs/PivotViewer/components/pivot/animation.js +4 -3
  11. package/dist/cjs/PivotViewer/components/pivot/animation.js.map +1 -1
  12. package/dist/cjs/PivotViewer/components/pivot/groups.js +151 -0
  13. package/dist/cjs/PivotViewer/components/pivot/groups.js.map +1 -0
  14. package/dist/cjs/PivotViewer/components/pivot/sprites.js +1 -15
  15. package/dist/cjs/PivotViewer/components/pivot/sprites.js.map +1 -1
  16. package/dist/cjs/PivotViewer/components/pivot/visibility.js +50 -27
  17. package/dist/cjs/PivotViewer/components/pivot/visibility.js.map +1 -1
  18. package/dist/cjs/PivotViewer/engine/layout.js +11 -7
  19. package/dist/cjs/PivotViewer/engine/layout.js.map +1 -1
  20. package/dist/cjs/PivotViewer/hooks/useCurrentFilters.js.map +1 -1
  21. package/dist/cjs/PivotViewer/hooks/usePanning.js +8 -4
  22. package/dist/cjs/PivotViewer/hooks/usePanning.js.map +1 -1
  23. package/dist/cjs/PivotViewer/hooks/usePivotEngine.js +1 -31
  24. package/dist/cjs/PivotViewer/hooks/usePivotEngine.js.map +1 -1
  25. package/dist/cjs/PivotViewer/hooks/useViewModeScrollHandling.js +4 -3
  26. package/dist/cjs/PivotViewer/hooks/useViewModeScrollHandling.js.map +1 -1
  27. package/dist/cjs/PivotViewer/types.js.map +1 -1
  28. package/dist/cjs/PivotViewer/utils/animations.js +11 -19
  29. package/dist/cjs/PivotViewer/utils/animations.js.map +1 -1
  30. package/dist/cjs/PivotViewer/utils/cardPosition.js +0 -3
  31. package/dist/cjs/PivotViewer/utils/cardPosition.js.map +1 -1
  32. package/dist/cjs/PivotViewer/utils/constants.js +2 -2
  33. package/dist/cjs/PivotViewer/utils/constants.js.map +1 -1
  34. package/dist/esm/PivotViewer/PivotViewer.css +32 -19
  35. package/dist/esm/PivotViewer/PivotViewer.d.ts +1 -1
  36. package/dist/esm/PivotViewer/PivotViewer.d.ts.map +1 -1
  37. package/dist/esm/PivotViewer/PivotViewer.js +45 -9
  38. package/dist/esm/PivotViewer/PivotViewer.js.map +1 -1
  39. package/dist/esm/PivotViewer/PivotViewer.stories.d.ts.map +1 -1
  40. package/dist/esm/PivotViewer/PivotViewer.stories.js +5 -2
  41. package/dist/esm/PivotViewer/PivotViewer.stories.js.map +1 -1
  42. package/dist/esm/PivotViewer/components/PivotCanvas.d.ts.map +1 -1
  43. package/dist/esm/PivotViewer/components/PivotCanvas.js +33 -52
  44. package/dist/esm/PivotViewer/components/PivotCanvas.js.map +1 -1
  45. package/dist/esm/PivotViewer/components/PivotViewerMain.d.ts +2 -1
  46. package/dist/esm/PivotViewer/components/PivotViewerMain.d.ts.map +1 -1
  47. package/dist/esm/PivotViewer/components/PivotViewerMain.js +4 -2
  48. package/dist/esm/PivotViewer/components/PivotViewerMain.js.map +1 -1
  49. package/dist/esm/PivotViewer/components/Toolbar.js +1 -1
  50. package/dist/esm/PivotViewer/components/Toolbar.js.map +1 -1
  51. package/dist/esm/PivotViewer/components/pivot/animation.d.ts.map +1 -1
  52. package/dist/esm/PivotViewer/components/pivot/animation.js +4 -3
  53. package/dist/esm/PivotViewer/components/pivot/animation.js.map +1 -1
  54. package/dist/esm/PivotViewer/components/pivot/groups.d.ts +6 -0
  55. package/dist/esm/PivotViewer/components/pivot/groups.d.ts.map +1 -0
  56. package/dist/esm/PivotViewer/components/pivot/groups.js +129 -0
  57. package/dist/esm/PivotViewer/components/pivot/groups.js.map +1 -0
  58. package/dist/esm/PivotViewer/components/pivot/sprites.d.ts.map +1 -1
  59. package/dist/esm/PivotViewer/components/pivot/sprites.js +2 -15
  60. package/dist/esm/PivotViewer/components/pivot/sprites.js.map +1 -1
  61. package/dist/esm/PivotViewer/components/pivot/visibility.d.ts +4 -0
  62. package/dist/esm/PivotViewer/components/pivot/visibility.d.ts.map +1 -1
  63. package/dist/esm/PivotViewer/components/pivot/visibility.js +50 -27
  64. package/dist/esm/PivotViewer/components/pivot/visibility.js.map +1 -1
  65. package/dist/esm/PivotViewer/engine/layout.js +11 -7
  66. package/dist/esm/PivotViewer/engine/layout.js.map +1 -1
  67. package/dist/esm/PivotViewer/engine/pivot.worker.d.ts.map +1 -1
  68. package/dist/esm/PivotViewer/engine/pivot.worker.js +0 -8
  69. package/dist/esm/PivotViewer/engine/pivot.worker.js.map +1 -1
  70. package/dist/esm/PivotViewer/engine/types.d.ts +1 -0
  71. package/dist/esm/PivotViewer/engine/types.d.ts.map +1 -1
  72. package/dist/esm/PivotViewer/hooks/useCurrentFilters.js.map +1 -1
  73. package/dist/esm/PivotViewer/hooks/useFilteredData.d.ts +1 -1
  74. package/dist/esm/PivotViewer/hooks/useFilteredData.js +4 -4
  75. package/dist/esm/PivotViewer/hooks/useFilteredData.js.map +1 -1
  76. package/dist/esm/PivotViewer/hooks/usePanning.d.ts.map +1 -1
  77. package/dist/esm/PivotViewer/hooks/usePanning.js +8 -4
  78. package/dist/esm/PivotViewer/hooks/usePanning.js.map +1 -1
  79. package/dist/esm/PivotViewer/hooks/usePivotEngine.d.ts.map +1 -1
  80. package/dist/esm/PivotViewer/hooks/usePivotEngine.js +1 -31
  81. package/dist/esm/PivotViewer/hooks/usePivotEngine.js.map +1 -1
  82. package/dist/esm/PivotViewer/hooks/useViewModeScrollHandling.d.ts.map +1 -1
  83. package/dist/esm/PivotViewer/hooks/useViewModeScrollHandling.js +4 -3
  84. package/dist/esm/PivotViewer/hooks/useViewModeScrollHandling.js.map +1 -1
  85. package/dist/esm/PivotViewer/types.d.ts +16 -0
  86. package/dist/esm/PivotViewer/types.d.ts.map +1 -1
  87. package/dist/esm/PivotViewer/types.js.map +1 -1
  88. package/dist/esm/PivotViewer/utils/animations.js +11 -19
  89. package/dist/esm/PivotViewer/utils/animations.js.map +1 -1
  90. package/dist/esm/PivotViewer/utils/cardPosition.js +1 -4
  91. package/dist/esm/PivotViewer/utils/cardPosition.js.map +1 -1
  92. package/dist/esm/PivotViewer/utils/constants.d.ts +4 -4
  93. package/dist/esm/PivotViewer/utils/constants.d.ts.map +1 -1
  94. package/dist/esm/PivotViewer/utils/constants.js +2 -2
  95. package/dist/esm/PivotViewer/utils/constants.js.map +1 -1
  96. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  97. package/package.json +1 -1
  98. package/dist/cjs/PivotViewer/components/pivot/buckets.js +0 -124
  99. package/dist/cjs/PivotViewer/components/pivot/buckets.js.map +0 -1
  100. package/dist/esm/PivotViewer/components/pivot/buckets.d.ts +0 -6
  101. package/dist/esm/PivotViewer/components/pivot/buckets.d.ts.map +0 -1
  102. package/dist/esm/PivotViewer/components/pivot/buckets.js +0 -102
  103. package/dist/esm/PivotViewer/components/pivot/buckets.js.map +0 -1
@@ -3,25 +3,20 @@ let store = null;
3
3
  let indexes = null;
4
4
  self.onmessage = (e) => {
5
5
  const message = e.data;
6
- console.log('[Worker] Received message:', message.type);
7
6
  switch (message.type) {
8
7
  case 'buildIndexes': {
9
- console.log('[Worker] Building indexes for', message.store.items.length, 'items');
10
8
  const fieldsArray = message.store.fields;
11
9
  const fieldsMap = new Map(fieldsArray);
12
10
  store = {
13
11
  ...message.store,
14
12
  fields: fieldsMap,
15
13
  };
16
- console.log('[Worker] Store converted, fields:', Array.from(fieldsMap.keys()));
17
14
  if (store) {
18
15
  indexes = buildIndexes(store, message.fields);
19
- console.log('[Worker] Indexes built');
20
16
  const response = {
21
17
  type: 'indexesReady',
22
18
  indexes,
23
19
  };
24
- console.log('[Worker] Posting indexesReady');
25
20
  self.postMessage(response);
26
21
  }
27
22
  break;
@@ -44,14 +39,11 @@ self.onmessage = (e) => {
44
39
  console.error('[Worker] Store or indexes not initialized');
45
40
  return;
46
41
  }
47
- console.log('[Worker] Computing grouping for', message.visibleIds.length, 'items, groupBy:', message.groupBy);
48
42
  const result = computeGrouping(store, indexes, message.visibleIds, message.groupBy);
49
- console.log('[Worker] Grouping computed:', result.groups.length, 'groups');
50
43
  const response = {
51
44
  type: 'groupingResult',
52
45
  result,
53
46
  };
54
- console.log('[Worker] Posting groupingResult');
55
47
  self.postMessage(response);
56
48
  break;
57
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"pivot.worker.js","sourceRoot":"","sources":["../../../../PivotViewer/engine/pivot.worker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pivot.worker.js","sourceRoot":"","sources":["../../../../PivotViewer/engine/pivot.worker.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAE/E,IAAI,KAAK,GAAsB,IAAI,CAAC;AACpC,IAAI,OAAO,GAAwB,IAAI,CAAC;AAExC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAgC,EAAE,EAAE;IACpD,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC;IAEvB,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,cAAc,CAAC,CAAC,CAAC;YAEpB,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,MAAsC,CAAC;YACzE,MAAM,SAAS,GAAG,IAAI,GAAG,CAAgB,WAAW,CAAC,CAAC;YAEtD,KAAK,GAAG;gBACN,GAAG,OAAO,CAAC,KAAK;gBAChB,MAAM,EAAE,SAAS;aAClB,CAAC;YACF,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,GAAG,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;gBAE9C,MAAM,QAAQ,GAAqB;oBACjC,IAAI,EAAE,cAAc;oBACpB,OAAO;iBACR,CAAC;gBACF,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;YAC7B,CAAC;YACD,MAAM;QACR,CAAC;QAED,KAAK,cAAc,CAAC,CAAC,CAAC;YACpB,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;gBACvB,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;gBAClD,OAAO;YACT,CAAC;YAED,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;YAE7D,MAAM,QAAQ,GAAqB;gBACjC,IAAI,EAAE,cAAc;gBACpB,MAAM;aACP,CAAC;YACF,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;YAC3B,MAAM;QACR,CAAC;QAED,KAAK,iBAAiB,CAAC,CAAC,CAAC;YACvB,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;gBACvB,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;gBAC3D,OAAO;YACT,CAAC;YAED,MAAM,MAAM,GAAG,eAAe,CAC5B,KAAK,EACL,OAAO,EACP,OAAO,CAAC,UAAU,EAClB,OAAO,CAAC,OAAO,CAChB,CAAC;YAEF,MAAM,QAAQ,GAAqB;gBACjC,IAAI,EAAE,gBAAgB;gBACtB,MAAM;aACP,CAAC;YACF,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;YAC3B,MAAM;QACR,CAAC;QAED,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;gBACvC,OAAO;YACT,CAAC;YAED,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;YAE3D,MAAM,QAAQ,GAAqB;gBACjC,IAAI,EAAE,YAAY;gBAClB,MAAM;aACP,CAAC;YACF,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;YAC3B,MAAM;QACR,CAAC;IACH,CAAC;AACH,CAAC,CAAC"}
@@ -84,6 +84,7 @@ export interface LayoutResult {
84
84
  totalWidth: number;
85
85
  totalHeight: number;
86
86
  bucketWidths?: number[];
87
+ groupXs?: number[];
87
88
  }
88
89
  export interface BuildIndexesMessage {
89
90
  type: 'buildIndexes';
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../PivotViewer/engine/types.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAErC,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAE1D,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;CACvC;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,MAAM,MAAM,KAAK,GAAG,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC;AAK7D,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,WAAW,CAAC;IACjB,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAG3B,KAAK,EAAE,OAAO,EAAE,CAAC;CAClB;AAKD,MAAM,WAAW,gBAAgB;IAE/B,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAGrC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAKD,MAAM,WAAW,YAAY;IAE3B,MAAM,EAAE,YAAY,CAAC;IAGrB,GAAG,EAAE,WAAW,CAAC;IAGjB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAKD,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC3C,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACpC;AAKD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,aAAa,GAAG,SAAS,CAAC;IAGhC,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAGrB,KAAK,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACtC;AAKD,MAAM,WAAW,YAAY;IAE3B,UAAU,EAAE,WAAW,CAAC;IAGxB,KAAK,EAAE,MAAM,CAAC;CACf;AAKD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IAGd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAKD,MAAM,WAAW,WAAW;IAE1B,GAAG,EAAE,MAAM,CAAC;IAGZ,KAAK,EAAE,MAAM,CAAC;IAGd,KAAK,EAAE,UAAU,CAAC;IAGlB,GAAG,EAAE,WAAW,CAAC;IAGjB,KAAK,EAAE,MAAM,CAAC;CACf;AAKD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE,WAAW,CAAC;CACzB;AAKD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,YAAY,GAAG,SAAS,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAKD,MAAM,WAAW,YAAY;IAC3B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,UAAU,EAAE,MAAM,CAAC;CACpB;AAKD,MAAM,WAAW,YAAY;IAE3B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAGrC,UAAU,EAAE,MAAM,CAAC;IAGnB,WAAW,EAAE,MAAM,CAAC;IAGpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAKD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,UAAU,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAKD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,YAAY,CAAC;CACvB;AAKD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAKD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;CACtB;AAKD,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,iBAAiB,CAAC;IACxB,UAAU,EAAE,WAAW,CAAC;IACxB,OAAO,EAAE,SAAS,CAAC;CACpB;AAKD,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,MAAM,eAAe,GACvB,mBAAmB,GACnB,mBAAmB,GACnB,sBAAsB,GACtB,WAAW,CAAC;AAEhB,MAAM,MAAM,gBAAgB,GACxB,mBAAmB,GACnB,mBAAmB,GACnB,qBAAqB,GACrB,iBAAiB,CAAC;AAKtB,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,WAAW,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAKD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;CACrB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../PivotViewer/engine/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useCurrentFilters.js","sources":["../../../../PivotViewer/hooks/useCurrentFilters.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 { FilterSpec, GroupSpec } from '../engine/types';\nimport type { PivotDimension, PivotFilter } from '../types';\n\nexport function useCurrentFilters<TItem extends object>(\n filters: PivotFilter<TItem>[] | undefined,\n filterState: Record<string, Set<string>>,\n rangeFilterState: Record<string, [number | null, number | null] | null>,\n search: string,\n searchFields: unknown[] | undefined,\n dimensionFilter: string | null,\n activeDimension: PivotDimension<TItem> | undefined,\n): FilterSpec[] {\n return useMemo((): FilterSpec[] => {\n const specs: FilterSpec[] = [];\n\n // Search filter\n const searchTerm = search.trim().toLowerCase();\n if (searchTerm && searchFields && searchFields.length > 0) {\n // TODO: Implement search in worker\n // For now, search will be handled client-side after worker filtering\n }\n\n // Categorical filters\n for (const [key, values] of Object.entries(filterState)) {\n const valueSet = values as Set<string>;\n if (valueSet.size > 0) {\n specs.push({\n field: key,\n type: 'categorical',\n values: valueSet,\n });\n }\n }\n\n // Range filters\n for (const [key, range] of Object.entries(rangeFilterState)) {\n if (range && (range[0] !== null || range[1] !== null)) {\n const min = range[0] ?? -Infinity;\n const max = range[1] ?? Infinity;\n specs.push({\n field: key,\n type: 'numeric',\n range: { min, max },\n });\n }\n }\n\n // Dimension filter (bucket filter)\n if (dimensionFilter && activeDimension) {\n specs.push({\n field: activeDimension.key,\n type: 'categorical',\n values: new Set([dimensionFilter]),\n });\n }\n\n return specs;\n }, [filterState, rangeFilterState, search, searchFields, dimensionFilter, activeDimension]);\n}\n\nexport function useCurrentGroupBy<TItem extends object>(\n activeDimensionKey: string | null,\n dimensions: PivotDimension<TItem>[],\n): GroupSpec {\n return useMemo((): GroupSpec => {\n return {\n field: activeDimensionKey || dimensions[0]?.key || '',\n buckets: 10,\n };\n }, [activeDimensionKey, dimensions]);\n}\n"],"names":[],"mappings":";;AAOM,SAAU,iBAAiB,CAC7B,OAAyC,EACzC,WAAwC,EACxC,gBAAuE,EACvE,MAAc,EACd,YAAmC,EACnC,eAA8B,EAC9B,eAAkD,EAAA;IAElD,OAAO,OAAO,CAAC,MAAmB;QAC9B,MAAM,KAAK,GAAiB,EAAE;QAG9B,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE;QAC9C,IAAI,UAAU,IAAI,YAAY,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE;AAM3D,QAAA,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;YACrD,MAAM,QAAQ,GAAG,MAAqB;AACtC,YAAA,IAAI,QAAQ,CAAC,IAAI,GAAG,CAAC,EAAE;gBACnB,KAAK,CAAC,IAAI,CAAC;AACP,oBAAA,KAAK,EAAE,GAAG;AACV,oBAAA,IAAI,EAAE,aAAa;AACnB,oBAAA,MAAM,EAAE,QAAQ;AACnB,iBAAA,CAAC;YACN;QACJ;AAGA,QAAA,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE;AACzD,YAAA,IAAI,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE;gBACnD,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ;gBACjC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,QAAQ;gBAChC,KAAK,CAAC,IAAI,CAAC;AACP,oBAAA,KAAK,EAAE,GAAG;AACV,oBAAA,IAAI,EAAE,SAAS;AACf,oBAAA,KAAK,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE;AACtB,iBAAA,CAAC;YACN;QACJ;AAGA,QAAA,IAAI,eAAe,IAAI,eAAe,EAAE;YACpC,KAAK,CAAC,IAAI,CAAC;gBACP,KAAK,EAAE,eAAe,CAAC,GAAG;AAC1B,gBAAA,IAAI,EAAE,aAAa;AACnB,gBAAA,MAAM,EAAE,IAAI,GAAG,CAAC,CAAC,eAAe,CAAC,CAAC;AACrC,aAAA,CAAC;QACN;AAEA,QAAA,OAAO,KAAK;AAChB,IAAA,CAAC,EAAE,CAAC,WAAW,EAAE,gBAAgB,EAAE,MAAM,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,CAAC,CAAC;AAC/F;AAEM,SAAU,iBAAiB,CAC7B,kBAAiC,EACjC,UAAmC,EAAA;IAEnC,OAAO,OAAO,CAAC,MAAgB;QAC3B,OAAO;YACH,KAAK,EAAE,kBAAkB,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE;AACrD,YAAA,OAAO,EAAE,EAAE;SACd;AACL,IAAA,CAAC,EAAE,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAAC;AACxC;;;;"}
1
+ {"version":3,"file":"useCurrentFilters.js","sources":["../../../../PivotViewer/hooks/useCurrentFilters.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 { FilterSpec, GroupSpec } from '../engine/types';\nimport type { PivotDimension, PivotFilter } from '../types';\n\nexport function useCurrentFilters<TItem extends object>(\n filters: PivotFilter<TItem>[] | undefined,\n filterState: Record<string, Set<string>>,\n rangeFilterState: Record<string, [number | null, number | null] | null>,\n search: string,\n searchFields: unknown[] | undefined,\n dimensionFilter: string | null,\n activeDimension: PivotDimension<TItem> | undefined,\n): FilterSpec[] {\n return useMemo((): FilterSpec[] => {\n const specs: FilterSpec[] = [];\n\n // Search filter\n const searchTerm = search.trim().toLowerCase();\n if (searchTerm && searchFields && searchFields.length > 0) {\n // TODO: Implement search in worker\n // For now, search will be handled client-side after worker filtering\n }\n\n // Categorical filters\n for (const [key, values] of Object.entries(filterState)) {\n const valueSet = values as Set<string>;\n if (valueSet.size > 0) {\n specs.push({\n field: key,\n type: 'categorical',\n values: valueSet,\n });\n }\n }\n\n // Range filters\n for (const [key, range] of Object.entries(rangeFilterState)) {\n if (range && (range[0] !== null || range[1] !== null)) {\n const min = range[0] ?? -Infinity;\n const max = range[1] ?? Infinity;\n specs.push({\n field: key,\n type: 'numeric',\n range: { min, max },\n });\n }\n }\n\n // Dimension filter (grouped filter)\n if (dimensionFilter && activeDimension) {\n specs.push({\n field: activeDimension.key,\n type: 'categorical',\n values: new Set([dimensionFilter]),\n });\n }\n\n return specs;\n }, [filterState, rangeFilterState, search, searchFields, dimensionFilter, activeDimension]);\n}\n\nexport function useCurrentGroupBy<TItem extends object>(\n activeDimensionKey: string | null,\n dimensions: PivotDimension<TItem>[],\n): GroupSpec {\n return useMemo((): GroupSpec => {\n return {\n field: activeDimensionKey || dimensions[0]?.key || '',\n buckets: 10,\n };\n }, [activeDimensionKey, dimensions]);\n}\n"],"names":[],"mappings":";;AAOM,SAAU,iBAAiB,CAC7B,OAAyC,EACzC,WAAwC,EACxC,gBAAuE,EACvE,MAAc,EACd,YAAmC,EACnC,eAA8B,EAC9B,eAAkD,EAAA;IAElD,OAAO,OAAO,CAAC,MAAmB;QAC9B,MAAM,KAAK,GAAiB,EAAE;QAG9B,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE;QAC9C,IAAI,UAAU,IAAI,YAAY,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE;AAM3D,QAAA,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;YACrD,MAAM,QAAQ,GAAG,MAAqB;AACtC,YAAA,IAAI,QAAQ,CAAC,IAAI,GAAG,CAAC,EAAE;gBACnB,KAAK,CAAC,IAAI,CAAC;AACP,oBAAA,KAAK,EAAE,GAAG;AACV,oBAAA,IAAI,EAAE,aAAa;AACnB,oBAAA,MAAM,EAAE,QAAQ;AACnB,iBAAA,CAAC;YACN;QACJ;AAGA,QAAA,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE;AACzD,YAAA,IAAI,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE;gBACnD,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ;gBACjC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,QAAQ;gBAChC,KAAK,CAAC,IAAI,CAAC;AACP,oBAAA,KAAK,EAAE,GAAG;AACV,oBAAA,IAAI,EAAE,SAAS;AACf,oBAAA,KAAK,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE;AACtB,iBAAA,CAAC;YACN;QACJ;AAGA,QAAA,IAAI,eAAe,IAAI,eAAe,EAAE;YACpC,KAAK,CAAC,IAAI,CAAC;gBACP,KAAK,EAAE,eAAe,CAAC,GAAG;AAC1B,gBAAA,IAAI,EAAE,aAAa;AACnB,gBAAA,MAAM,EAAE,IAAI,GAAG,CAAC,CAAC,eAAe,CAAC,CAAC;AACrC,aAAA,CAAC;QACN;AAEA,QAAA,OAAO,KAAK;AAChB,IAAA,CAAC,EAAE,CAAC,WAAW,EAAE,gBAAgB,EAAE,MAAM,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,CAAC,CAAC;AAC/F;AAEM,SAAU,iBAAiB,CAC7B,kBAAiC,EACjC,UAAmC,EAAA;IAEnC,OAAO,OAAO,CAAC,MAAgB;QAC3B,OAAO;YACH,KAAK,EAAE,kBAAkB,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE;AACrD,YAAA,OAAO,EAAE,EAAE;SACd;AACL,IAAA,CAAC,EAAE,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAAC;AACxC;;;;"}
@@ -2,7 +2,7 @@ import type { PivotDimension, PivotFilter, PivotGroup, PropertyAccessor } from '
2
2
  import type { FilterState, RangeFilterState } from '../utils/utils';
3
3
  export declare function useFilteredData<TItem extends object>(data: TItem[], filters: PivotFilter<TItem>[] | undefined, filterState: FilterState, rangeFilterState: RangeFilterState, activeDimension: PivotDimension<TItem> | undefined, dimensionFilter: string | null, searchTerm: string, searchFields?: PropertyAccessor<TItem>[]): {
4
4
  filteredData: TItem[];
5
- allGroupsForBuckets: PivotGroup<TItem>[];
5
+ allGroupsForGroupedMode: PivotGroup<TItem>[];
6
6
  groupedGroups: PivotGroup<TItem>[];
7
7
  collectionGroup: PivotGroup<TItem>[];
8
8
  };
@@ -28,7 +28,7 @@ export function useFilteredData(data, filters, filterState, rangeFilterState, ac
28
28
  return JSON.stringify(item).toLowerCase().indexOf(searchTerm) !== -1;
29
29
  });
30
30
  }, [data, filters, filterState, rangeFilterState, dimensionFilter, activeDimension, searchFields, searchTerm]);
31
- const allGroupsForBuckets = useMemo(() => {
31
+ const allGroupsForGroupedMode = useMemo(() => {
32
32
  if (!activeDimension) {
33
33
  return [];
34
34
  }
@@ -40,11 +40,11 @@ export function useFilteredData(data, filters, filterState, rangeFilterState, ac
40
40
  return [];
41
41
  }
42
42
  if (dimensionFilter) {
43
- const filteredGroup = allGroupsForBuckets.find((group) => group.key === dimensionFilter);
43
+ const filteredGroup = allGroupsForGroupedMode.find((group) => group.key === dimensionFilter);
44
44
  return filteredGroup ? [filteredGroup] : [];
45
45
  }
46
46
  return groupData(filteredData, activeDimension);
47
- }, [filteredData, activeDimension, dimensionFilter, allGroupsForBuckets]);
47
+ }, [filteredData, activeDimension, dimensionFilter, allGroupsForGroupedMode]);
48
48
  const collectionGroup = useMemo(() => {
49
49
  if (filteredData.length === 0) {
50
50
  return [];
@@ -79,7 +79,7 @@ export function useFilteredData(data, filters, filterState, rangeFilterState, ac
79
79
  }, [filteredData, activeDimension]);
80
80
  return {
81
81
  filteredData,
82
- allGroupsForBuckets,
82
+ allGroupsForGroupedMode,
83
83
  groupedGroups,
84
84
  collectionGroup,
85
85
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useFilteredData.js","sourceRoot":"","sources":["../../../../PivotViewer/hooks/useFilteredData.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useFilteredData.js","sourceRoot":"","sources":["../../../../PivotViewer/hooks/useFilteredData.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"usePanning.d.ts","sourceRoot":"","sources":["../../../../PivotViewer/hooks/usePanning.ts"],"names":[],"mappings":"AAKA,wBAAgB,UAAU,CACxB,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,EACpD,iBAAiB,CAAC,EAAE,MAAM,IAAI,EAC9B,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI;;wBAiBpB,KAAK,CAAC,UAAU,GAAG,UAAU,uBAAuB,OAAO;uBA6B5D,KAAK,CAAC,UAAU,GAAG,UAAU;;EAyGpE"}
1
+ {"version":3,"file":"usePanning.d.ts","sourceRoot":"","sources":["../../../../PivotViewer/hooks/usePanning.ts"],"names":[],"mappings":"AAKA,wBAAgB,UAAU,CACxB,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,EACpD,iBAAiB,CAAC,EAAE,MAAM,IAAI,EAC9B,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI;;wBAiBpB,KAAK,CAAC,UAAU,GAAG,UAAU,uBAAuB,OAAO;uBA6B5D,KAAK,CAAC,UAAU,GAAG,UAAU;;EAiHpE"}
@@ -51,8 +51,10 @@ function usePanning(containerRef, onBackgroundClick, onScrollChange) {
51
51
  const newCameraY = panStart.scrollTop - dy;
52
52
  const container = containerRef.current;
53
53
  if (container) {
54
- container.scrollLeft = Math.max(0, Math.round(newCameraX));
55
- container.scrollTop = Math.max(0, Math.round(newCameraY));
54
+ const maxScrollLeft = Math.max(0, container.scrollWidth - container.clientWidth);
55
+ const maxScrollTop = Math.max(0, container.scrollHeight - container.clientHeight);
56
+ container.scrollLeft = Math.max(0, Math.min(maxScrollLeft, Math.round(newCameraX)));
57
+ container.scrollTop = Math.max(0, Math.min(maxScrollTop, Math.round(newCameraY)));
56
58
  }
57
59
  if (onScrollChange) {
58
60
  onScrollChange({ x: container ? container.scrollLeft : newCameraX, y: container ? container.scrollTop : newCameraY });
@@ -96,8 +98,10 @@ function usePanning(containerRef, onBackgroundClick, onScrollChange) {
96
98
  inertiaAnimationRef.current = null;
97
99
  return;
98
100
  }
99
- container.scrollLeft += vx;
100
- container.scrollTop += vy;
101
+ const maxScrollLeft = Math.max(0, container.scrollWidth - container.clientWidth);
102
+ const maxScrollTop = Math.max(0, container.scrollHeight - container.clientHeight);
103
+ container.scrollLeft = Math.max(0, Math.min(maxScrollLeft, container.scrollLeft + vx));
104
+ container.scrollTop = Math.max(0, Math.min(maxScrollTop, container.scrollTop + vy));
101
105
  vx *= 0.95;
102
106
  vy *= 0.95;
103
107
  inertiaAnimationRef.current = requestAnimationFrame(animate);
@@ -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 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
+ {"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 // Constrain scroll position to prevent viewing beyond content bounds\n const maxScrollLeft = Math.max(0, container.scrollWidth - container.clientWidth);\n const maxScrollTop = Math.max(0, container.scrollHeight - container.clientHeight);\n \n container.scrollLeft = Math.max(0, Math.min(maxScrollLeft, Math.round(newCameraX)));\n container.scrollTop = Math.max(0, Math.min(maxScrollTop, 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 // Constrain scroll position to prevent viewing beyond content bounds\n const maxScrollLeft = Math.max(0, container.scrollWidth - container.clientWidth);\n const maxScrollTop = Math.max(0, container.scrollHeight - container.clientHeight);\n \n container.scrollLeft = Math.max(0, Math.min(maxScrollLeft, container.scrollLeft + vx));\n container.scrollTop = Math.max(0, Math.min(maxScrollTop, 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.d.ts","sourceRoot":"","sources":["../../../../PivotViewer/hooks/usePivotEngine.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAGV,UAAU,EACV,YAAY,EACZ,SAAS,EACT,cAAc,EAGd,UAAU,EACX,MAAM,iBAAiB,CAAC;AAGzB,MAAM,WAAW,qBAAqB,CAAC,KAAK,SAAS,MAAM;IACzD,IAAI,EAAE,KAAK,EAAE,CAAC;IACd,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,UAAU,CAAC,CAAC;IAC1D,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/D,eAAe,EAAE,CAAC,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IAC1F,OAAO,EAAE,CAAC,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;CAC5E;AAED,wBAAgB,cAAc,CAAC,KAAK,SAAS,MAAM,EAAE,EACnD,IAAI,EACJ,eAAe,EACf,WAAW,GACZ,EAAE,qBAAqB,CAAC,KAAK,CAAC,GAAG,oBAAoB,CA8RrD"}
1
+ {"version":3,"file":"usePivotEngine.d.ts","sourceRoot":"","sources":["../../../../PivotViewer/hooks/usePivotEngine.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAGV,UAAU,EACV,YAAY,EACZ,SAAS,EACT,cAAc,EAGd,UAAU,EACX,MAAM,iBAAiB,CAAC;AAGzB,MAAM,WAAW,qBAAqB,CAAC,KAAK,SAAS,MAAM;IACzD,IAAI,EAAE,KAAK,EAAE,CAAC;IACd,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,UAAU,CAAC,CAAC;IAC1D,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/D,eAAe,EAAE,CAAC,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IAC1F,OAAO,EAAE,CAAC,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;CAC5E;AAED,wBAAgB,cAAc,CAAC,KAAK,SAAS,MAAM,EAAE,EACnD,IAAI,EACJ,eAAe,EACf,WAAW,GACZ,EAAE,qBAAqB,CAAC,KAAK,CAAC,GAAG,oBAAoB,CAiQrD"}
@@ -11,7 +11,6 @@ function usePivotEngine({ data, fieldExtractors, indexFields, }) {
11
11
  const pendingCallbacksRef = useRef(new Map());
12
12
  useEffect(() => {
13
13
  if (typeof window === 'undefined' || typeof Worker === 'undefined') {
14
- console.warn('[PivotEngine] Worker not supported in this environment, using main thread');
15
14
  fallbackRef.current = true;
16
15
  setWorkerAvailable(false);
17
16
  return;
@@ -29,68 +28,49 @@ function usePivotEngine({ data, fieldExtractors, indexFields, }) {
29
28
  const response = await fetch(workerUrl, { method: 'HEAD' });
30
29
  const contentType = response.headers.get('content-type') ?? '';
31
30
  if (!response.ok || !contentType.includes('javascript')) {
32
- console.warn('[PivotEngine] Worker asset not reachable, using main thread');
33
31
  enableFallback();
34
32
  return;
35
33
  }
36
34
  }
37
35
  }
38
- catch (error) {
39
- console.warn('[PivotEngine] Worker preflight failed, using main thread', error);
36
+ catch {
40
37
  enableFallback();
41
38
  return;
42
39
  }
43
40
  if (disposed) {
44
41
  return;
45
42
  }
46
- console.log('[PivotEngine] Creating worker');
47
43
  const worker = new Worker(workerUrl, { type: 'module' });
48
44
  workerRef.current = worker;
49
45
  setWorkerAvailable(true);
50
- console.log('[PivotEngine] Worker created, setting up message handlers');
51
46
  worker.onmessage = (e) => {
52
47
  const message = e.data;
53
- console.log('[PivotEngine] Received message from worker:', message.type);
54
48
  switch (message.type) {
55
49
  case 'indexesReady':
56
- console.log('[PivotEngine] Indexes ready');
57
50
  setReady(true);
58
51
  break;
59
52
  case 'filterResult': {
60
53
  const callback = pendingCallbacksRef.current.get('filter');
61
54
  if (callback) {
62
- console.log('[PivotEngine] Calling filter callback and deleting');
63
55
  callback(message.result);
64
56
  pendingCallbacksRef.current.delete('filter');
65
57
  }
66
- else {
67
- console.warn('[PivotEngine] No callback registered for filter result - ignoring duplicate message');
68
- }
69
58
  break;
70
59
  }
71
60
  case 'groupingResult': {
72
- console.log('[PivotEngine] Received groupingResult:', message.result);
73
61
  const callback = pendingCallbacksRef.current.get('grouping');
74
62
  if (callback) {
75
- console.log('[PivotEngine] Calling grouping callback and deleting');
76
63
  callback(message.result);
77
64
  pendingCallbacksRef.current.delete('grouping');
78
65
  }
79
- else {
80
- console.warn('[PivotEngine] No callback registered for grouping result - ignoring duplicate message');
81
- }
82
66
  break;
83
67
  }
84
68
  case 'sortResult': {
85
69
  const callback = pendingCallbacksRef.current.get('sort');
86
70
  if (callback) {
87
- console.log('[PivotEngine] Calling sort callback and deleting');
88
71
  callback(message.result);
89
72
  pendingCallbacksRef.current.delete('sort');
90
73
  }
91
- else {
92
- console.warn('[PivotEngine] No callback registered for sort result - ignoring duplicate message');
93
- }
94
74
  break;
95
75
  }
96
76
  }
@@ -118,11 +98,9 @@ function usePivotEngine({ data, fieldExtractors, indexFields, }) {
118
98
  };
119
99
  }, [indexFields]);
120
100
  useEffect(() => {
121
- console.log('[PivotEngine] Building indexes for', data.length, 'items');
122
101
  setReady(false);
123
102
  const store = buildStore(data, fieldExtractors);
124
103
  storeRef.current = store;
125
- console.log('[PivotEngine] Store built with', store.items.length, 'items and', store.fields.size, 'fields');
126
104
  try {
127
105
  indexesRef.current = buildIndexes(store, indexFields);
128
106
  }
@@ -141,7 +119,6 @@ function usePivotEngine({ data, fieldExtractors, indexFields, }) {
141
119
  store: serializableStore,
142
120
  fields: indexFields,
143
121
  };
144
- console.log('[PivotEngine] Posting buildIndexes with', fieldsArray.length, 'fields');
145
122
  workerRef.current.postMessage(message);
146
123
  }
147
124
  else {
@@ -175,20 +152,16 @@ function usePivotEngine({ data, fieldExtractors, indexFields, }) {
175
152
  });
176
153
  }, [ready]);
177
154
  const computeGroupingCallback = useCallback((visibleIds, groupBy) => {
178
- console.log('[PivotEngine] computeGroupingCallback called with', visibleIds.length, 'visibleIds');
179
155
  if (pendingCallbacksRef.current.has('grouping')) {
180
- console.warn('[PivotEngine] Grouping already in progress, ignoring duplicate request');
181
156
  return Promise.resolve({ groups: [] });
182
157
  }
183
158
  return new Promise((resolve) => {
184
159
  if (!workerRef.current || fallbackRef.current) {
185
- console.log('[PivotEngine] Using synchronous fallback for grouping');
186
160
  try {
187
161
  const store = storeRef.current;
188
162
  const indexes = indexesRef.current;
189
163
  if (store && indexes) {
190
164
  const result = computeGrouping(store, indexes, visibleIds, groupBy);
191
- console.log('[PivotEngine] Fallback grouping result:', result);
192
165
  resolve(result);
193
166
  return;
194
167
  }
@@ -196,11 +169,9 @@ function usePivotEngine({ data, fieldExtractors, indexFields, }) {
196
169
  catch (e) {
197
170
  console.error('[PivotEngine] fallback computeGrouping error:', e);
198
171
  }
199
- console.warn('[PivotEngine] No store/indexes for fallback, returning empty');
200
172
  resolve({ groups: [] });
201
173
  return;
202
174
  }
203
- console.log('[PivotEngine] Setting grouping callback and posting to worker');
204
175
  pendingCallbacksRef.current.set('grouping', resolve);
205
176
  const message = {
206
177
  type: 'computeGrouping',
@@ -208,7 +179,6 @@ function usePivotEngine({ data, fieldExtractors, indexFields, }) {
208
179
  groupBy,
209
180
  };
210
181
  workerRef.current.postMessage(message);
211
- console.log('[PivotEngine] Message posted to worker');
212
182
  });
213
183
  }, [ready]);
214
184
  const sortIdsCallback = useCallback((visibleIds, sortBy) => {
@@ -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 [workerAvailable, setWorkerAvailable] = 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 if (typeof window === 'undefined' || typeof Worker === 'undefined') {\n console.warn('[PivotEngine] Worker not supported in this environment, using main thread');\n fallbackRef.current = true;\n setWorkerAvailable(false);\n return;\n }\n\n const workerUrl = new URL('../engine/pivot.worker.js', import.meta.url);\n let disposed = false;\n\n const enableFallback = () => {\n fallbackRef.current = true;\n workerRef.current = null;\n setWorkerAvailable(false);\n };\n\n const setupWorker = async () => {\n try {\n if (typeof fetch === 'function') {\n const response = await fetch(workerUrl, { method: 'HEAD' });\n const contentType = response.headers.get('content-type') ?? '';\n\n if (!response.ok || !contentType.includes('javascript')) {\n console.warn('[PivotEngine] Worker asset not reachable, using main thread');\n enableFallback();\n return;\n }\n }\n } catch (error) {\n console.warn('[PivotEngine] Worker preflight failed, using main thread', error);\n enableFallback();\n return;\n }\n\n if (disposed) {\n return;\n }\n\n console.log('[PivotEngine] Creating worker');\n const worker = new Worker(workerUrl, { type: 'module' });\n\n workerRef.current = worker;\n setWorkerAvailable(true);\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 enableFallback();\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\n void setupWorker();\n\n return () => {\n disposed = true;\n workerRef.current?.terminate();\n workerRef.current = null;\n };\n }, [indexFields]);\n\n useEffect(() => {\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 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 && !fallbackRef.current) {\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 setReady(true);\n }\n }, [data, fieldExtractors, indexFields, workerAvailable]);\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 [workerAvailable, setWorkerAvailable] = 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 if (typeof window === 'undefined' || typeof Worker === 'undefined') {\n fallbackRef.current = true;\n setWorkerAvailable(false);\n return;\n }\n\n const workerUrl = new URL('../engine/pivot.worker.js', import.meta.url);\n let disposed = false;\n\n const enableFallback = () => {\n fallbackRef.current = true;\n workerRef.current = null;\n setWorkerAvailable(false);\n };\n\n const setupWorker = async () => {\n try {\n if (typeof fetch === 'function') {\n const response = await fetch(workerUrl, { method: 'HEAD' });\n const contentType = response.headers.get('content-type') ?? '';\n\n if (!response.ok || !contentType.includes('javascript')) {\n enableFallback();\n return;\n }\n }\n } catch {\n enableFallback();\n return;\n }\n\n if (disposed) {\n return;\n }\n\n const worker = new Worker(workerUrl, { type: 'module' });\n\n workerRef.current = worker;\n setWorkerAvailable(true);\n\n worker.onmessage = (e: MessageEvent<WorkerOutMessage>) => {\n const message = e.data;\n\n switch (message.type) {\n case 'indexesReady':\n setReady(true);\n break;\n\n case 'filterResult': {\n const callback = pendingCallbacksRef.current.get('filter');\n if (callback) {\n callback(message.result);\n pendingCallbacksRef.current.delete('filter');\n }\n break;\n }\n\n case 'groupingResult': {\n const callback = pendingCallbacksRef.current.get('grouping');\n if (callback) {\n callback(message.result);\n pendingCallbacksRef.current.delete('grouping');\n }\n break;\n }\n\n case 'sortResult': {\n const callback = pendingCallbacksRef.current.get('sort');\n if (callback) {\n callback(message.result);\n pendingCallbacksRef.current.delete('sort');\n }\n break;\n }\n }\n };\n\n worker.onerror = (error) => {\n console.error('[PivotEngine] Worker error:', error);\n enableFallback();\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\n void setupWorker();\n\n return () => {\n disposed = true;\n workerRef.current?.terminate();\n workerRef.current = null;\n };\n }, [indexFields]);\n\n useEffect(() => {\n setReady(false);\n\n const store = buildStore(data, fieldExtractors);\n storeRef.current = store;\n\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 && !fallbackRef.current) {\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 workerRef.current.postMessage(message);\n } else {\n setReady(true);\n }\n }, [data, fieldExtractors, indexFields, workerAvailable]);\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 // Check if there's already a pending grouping request\n if (pendingCallbacksRef.current.has('grouping')) {\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 try {\n const store = storeRef.current;\n const indexes = indexesRef.current;\n if (store && indexes) {\n const result = computeGrouping(store, indexes, visibleIds, groupBy);\n resolve(result);\n return;\n }\n } catch (e) {\n console.error('[PivotEngine] fallback computeGrouping error:', e);\n }\n\n resolve({ groups: [] });\n return;\n }\n\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 });\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 +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"}
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,QAgDxC"}
@@ -29,9 +29,10 @@ function useViewModeScrollHandling({ containerRef, viewMode, grouping, layout, s
29
29
  }
30
30
  }
31
31
  else if (viewMode === 'grouped') {
32
- setTimeout(() => {
33
- container.scrollTop = container.scrollHeight;
34
- }, 0);
32
+ const scrollToHeight = layout.totalHeight * zoomLevel - container.clientHeight;
33
+ const targetScrollTop = Math.max(0, scrollToHeight);
34
+ container.scrollTop = targetScrollTop;
35
+ container.scrollLeft = 0;
35
36
  }
36
37
  }, [viewMode, grouping, layout, selectedItem, resolveId, zoomLevel, containerRef, data, setPreSelectionState]);
37
38
  }
@@ -1 +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
+ {"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 to see the cards\n // which are laid out from bottom-to-top. Use layout.totalHeight which is\n // the authoritative height in world units, converted back to pixels.\n const scrollToHeight = layout.totalHeight * zoomLevel - container.clientHeight;\n const targetScrollTop = Math.max(0, scrollToHeight);\n container.scrollTop = targetScrollTop;\n container.scrollLeft = 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;QACA;AAAO,aAAA,IAAI,QAAQ,KAAK,SAAS,EAAE;YAI/B,MAAM,cAAc,GAAG,MAAM,CAAC,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC,YAAY;YAC9E,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC;AACnD,YAAA,SAAS,CAAC,SAAS,GAAG,eAAe;AACrC,YAAA,SAAS,CAAC,UAAU,GAAG,CAAC;QAChC;IACJ,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE,oBAAoB,CAAC,CAAC;AAClH;;;;"}
@@ -39,11 +39,27 @@ export interface PivotViewerProps<TItem extends object> {
39
39
  filters?: PivotFilter<TItem>[];
40
40
  defaultDimensionKey?: string;
41
41
  cardRenderer?: (item: TItem) => ReactNode;
42
+ detailRenderer?: (item: TItem, onClose: () => void) => ReactNode;
42
43
  getItemId?: (item: TItem, index: number) => string | number;
43
44
  searchFields?: PropertyAccessor<TItem>[];
44
45
  className?: string;
45
46
  emptyContent?: ReactNode;
46
47
  isLoading?: boolean;
48
+ colors?: Partial<{
49
+ primaryColor: string;
50
+ primaryColorText: string;
51
+ primary500: string;
52
+ surfaceGround: string;
53
+ surfaceCard: string;
54
+ surfaceSection: string;
55
+ surfaceOverlay: string;
56
+ surfaceBorder: string;
57
+ textColor: string;
58
+ textColorSecondary: string;
59
+ highlightBg: string;
60
+ maskbg: string;
61
+ focusRing: string;
62
+ }>;
47
63
  }
48
64
  export type FilterState = Record<string, Set<string>>;
49
65
  export type RangeFilterState = Record<string, [number, number] | null>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../PivotViewer/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../PivotViewer/types.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;AAKjF,MAAM,MAAM,gBAAgB,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC;AAM/D,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,EAAE,gBAAgB,CAAC,KAAK,CAAC,GAAG,MAAM,CAKhF;AAMD,wBAAgB,cAAc,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAUxE;AAED,MAAM,WAAW,UAAU,CAAC,KAAK,SAAS,MAAM;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,EAAE,KAAK,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc,CAAC,KAAK,SAAS,MAAM;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,cAAc,CAAC;IAC1C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,MAAM,CAAC;IAChD,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC;CAC/D;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW,CAAC,KAAK,SAAS,MAAM;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,cAAc,CAAC;IAC1C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC9B,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,iBAAiB,KAAK,MAAM,CAAC;IAE9D,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IAEpC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB,CAAC,KAAK,SAAS,MAAM;IACpD,IAAI,EAAE,KAAK,EAAE,CAAC;IACd,UAAU,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;IACpC,OAAO,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;IAC/B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,SAAS,CAAC;IAE1C,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK,SAAS,CAAC;IACjE,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAAC;IAC5D,YAAY,CAAC,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,SAAS,CAAC,EAAE,OAAO,CAAC;IAKpB,MAAM,CAAC,EAAE,OAAO,CAAC;QACf,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;QAClB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;CACJ;AAED,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAEtD,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC"}
@@ -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_$.]*)/);\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;;;;"}
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 /** Optional renderer for the slide-in detail panel when a card is selected */\n detailRenderer?: (item: TItem, onClose: () => void) => ReactNode;\n getItemId?: (item: TItem, index: number) => string | number;\n searchFields?: PropertyAccessor<TItem>[];\n className?: string;\n emptyContent?: ReactNode;\n isLoading?: boolean;\n /**\n * Optional color overrides mapped to PrimeReact-like CSS variables.\n * If omitted, values are taken from the global theme (PrimeReact defaults).\n */\n colors?: Partial<{\n primaryColor: string;\n primaryColorText: string;\n primary500: string;\n surfaceGround: string;\n surfaceCard: string;\n surfaceSection: string;\n surfaceOverlay: string;\n surfaceBorder: string;\n textColor: string;\n textColorSecondary: string;\n highlightBg: string;\n maskbg: string;\n focusRing: string;\n }>;\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;;;;"}