@cratis/components 0.1.9 → 0.1.12

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 (258) hide show
  1. package/dist/cjs/CommandForm/CommandFormFields.js +9 -3
  2. package/dist/cjs/CommandForm/CommandFormFields.js.map +1 -1
  3. package/dist/cjs/CommandForm/ValidationMessage.js +24 -0
  4. package/dist/cjs/CommandForm/ValidationMessage.js.map +1 -0
  5. package/dist/cjs/CommandForm/asCommandFormField.js +47 -0
  6. package/dist/cjs/CommandForm/asCommandFormField.js.map +1 -0
  7. package/dist/cjs/CommandForm/fields/CheckboxField.js +13 -0
  8. package/dist/cjs/CommandForm/fields/CheckboxField.js.map +1 -0
  9. package/dist/cjs/CommandForm/fields/DropdownField.js +13 -0
  10. package/dist/cjs/CommandForm/fields/DropdownField.js.map +1 -0
  11. package/dist/cjs/CommandForm/fields/InputTextField.js +13 -0
  12. package/dist/cjs/CommandForm/fields/InputTextField.js.map +1 -0
  13. package/dist/cjs/CommandForm/fields/NumberField.js +13 -0
  14. package/dist/cjs/CommandForm/fields/NumberField.js.map +1 -0
  15. package/dist/cjs/CommandForm/fields/SliderField.js +17 -0
  16. package/dist/cjs/CommandForm/fields/SliderField.js.map +1 -0
  17. package/dist/cjs/CommandForm/fields/TextAreaField.js +13 -0
  18. package/dist/cjs/CommandForm/fields/TextAreaField.js.map +1 -0
  19. package/dist/cjs/CommandForm/index.js +15 -7
  20. package/dist/cjs/CommandForm/index.js.map +1 -1
  21. package/dist/cjs/PivotViewer/PivotViewer.css +1258 -0
  22. package/dist/cjs/PivotViewer/PivotViewer.js +14 -0
  23. package/dist/cjs/PivotViewer/PivotViewer.js.map +1 -1
  24. package/dist/cjs/PivotViewer/components/PivotCanvas.js +33 -10
  25. package/dist/cjs/PivotViewer/components/PivotCanvas.js.map +1 -1
  26. package/dist/cjs/PivotViewer/components/PivotViewerMain.js +1 -1
  27. package/dist/cjs/PivotViewer/components/PivotViewerMain.js.map +1 -1
  28. package/dist/cjs/PivotViewer/components/Spinner.css +77 -0
  29. package/dist/cjs/PivotViewer/components/pivot/sprites.js +79 -15
  30. package/dist/cjs/PivotViewer/components/pivot/sprites.js.map +1 -1
  31. package/dist/cjs/PivotViewer/components/pivot/visibility.js +36 -10
  32. package/dist/cjs/PivotViewer/components/pivot/visibility.js.map +1 -1
  33. package/dist/cjs/PivotViewer/engine/layout.js +2 -1
  34. package/dist/cjs/PivotViewer/engine/layout.js.map +1 -1
  35. package/dist/cjs/PivotViewer/hooks/usePivotEngine.js +37 -2
  36. package/dist/cjs/PivotViewer/hooks/usePivotEngine.js.map +1 -1
  37. package/dist/cjs/PivotViewer/index.js +3 -0
  38. package/dist/cjs/PivotViewer/index.js.map +1 -1
  39. package/dist/cjs/PivotViewer/types.js +22 -0
  40. package/dist/cjs/PivotViewer/types.js.map +1 -0
  41. package/dist/cjs/TimeMachine/EventsView.css +213 -0
  42. package/dist/cjs/TimeMachine/TimeMachine.css +567 -0
  43. package/dist/cjs/TimeMachine/TimeMachine.js +8 -3
  44. package/dist/cjs/TimeMachine/TimeMachine.js.map +1 -1
  45. package/dist/esm/CommandForm/CommandForm.stories.d.ts +1 -0
  46. package/dist/esm/CommandForm/CommandForm.stories.d.ts.map +1 -1
  47. package/dist/esm/CommandForm/CommandForm.stories.js +34 -1
  48. package/dist/esm/CommandForm/CommandForm.stories.js.map +1 -1
  49. package/dist/esm/CommandForm/CommandFormFields.d.ts.map +1 -1
  50. package/dist/esm/CommandForm/CommandFormFields.js +9 -3
  51. package/dist/esm/CommandForm/CommandFormFields.js.map +1 -1
  52. package/dist/esm/CommandForm/UserRegistrationCommand.d.ts +63 -0
  53. package/dist/esm/CommandForm/UserRegistrationCommand.d.ts.map +1 -0
  54. package/dist/esm/CommandForm/UserRegistrationCommand.js +143 -0
  55. package/dist/esm/CommandForm/UserRegistrationCommand.js.map +1 -0
  56. package/dist/esm/CommandForm/ValidationMessage.d.ts +8 -0
  57. package/dist/esm/CommandForm/ValidationMessage.d.ts.map +1 -0
  58. package/dist/esm/CommandForm/ValidationMessage.js +22 -0
  59. package/dist/esm/CommandForm/ValidationMessage.js.map +1 -0
  60. package/dist/esm/CommandForm/asCommandFormField.d.ts +32 -0
  61. package/dist/esm/CommandForm/asCommandFormField.d.ts.map +1 -0
  62. package/dist/esm/CommandForm/asCommandFormField.js +45 -0
  63. package/dist/esm/CommandForm/asCommandFormField.js.map +1 -0
  64. package/dist/esm/CommandForm/fields/CheckboxField.d.ts +10 -0
  65. package/dist/esm/CommandForm/fields/CheckboxField.d.ts.map +1 -0
  66. package/dist/esm/CommandForm/fields/CheckboxField.js +11 -0
  67. package/dist/esm/CommandForm/fields/CheckboxField.js.map +1 -0
  68. package/dist/esm/CommandForm/fields/DropdownField.d.ts +15 -0
  69. package/dist/esm/CommandForm/fields/DropdownField.d.ts.map +1 -0
  70. package/dist/esm/CommandForm/fields/DropdownField.js +11 -0
  71. package/dist/esm/CommandForm/fields/DropdownField.js.map +1 -0
  72. package/dist/esm/CommandForm/fields/InputTextField.d.ts +11 -0
  73. package/dist/esm/CommandForm/fields/InputTextField.d.ts.map +1 -0
  74. package/dist/esm/CommandForm/fields/InputTextField.js +11 -0
  75. package/dist/esm/CommandForm/fields/InputTextField.js.map +1 -0
  76. package/dist/esm/CommandForm/fields/NumberField.d.ts +13 -0
  77. package/dist/esm/CommandForm/fields/NumberField.d.ts.map +1 -0
  78. package/dist/esm/CommandForm/fields/NumberField.js +11 -0
  79. package/dist/esm/CommandForm/fields/NumberField.js.map +1 -0
  80. package/dist/esm/CommandForm/fields/SliderField.d.ts +12 -0
  81. package/dist/esm/CommandForm/fields/SliderField.d.ts.map +1 -0
  82. package/dist/esm/CommandForm/fields/SliderField.js +15 -0
  83. package/dist/esm/CommandForm/fields/SliderField.js.map +1 -0
  84. package/dist/esm/CommandForm/fields/TextAreaField.d.ts +12 -0
  85. package/dist/esm/CommandForm/fields/TextAreaField.d.ts.map +1 -0
  86. package/dist/esm/CommandForm/fields/TextAreaField.js +11 -0
  87. package/dist/esm/CommandForm/fields/TextAreaField.js.map +1 -0
  88. package/dist/esm/CommandForm/fields/index.d.ts +7 -0
  89. package/dist/esm/CommandForm/fields/index.d.ts.map +1 -0
  90. package/dist/esm/CommandForm/fields/index.js +7 -0
  91. package/dist/esm/CommandForm/fields/index.js.map +1 -0
  92. package/dist/esm/CommandForm/index.d.ts +3 -4
  93. package/dist/esm/CommandForm/index.d.ts.map +1 -1
  94. package/dist/esm/CommandForm/index.js +8 -4
  95. package/dist/esm/CommandForm/index.js.map +1 -1
  96. package/dist/esm/PivotViewer/PivotViewer.css +1258 -0
  97. package/dist/esm/PivotViewer/PivotViewer.d.ts.map +1 -1
  98. package/dist/esm/PivotViewer/PivotViewer.js +14 -0
  99. package/dist/esm/PivotViewer/PivotViewer.js.map +1 -1
  100. package/dist/esm/PivotViewer/PivotViewer.stories.d.ts +1 -0
  101. package/dist/esm/PivotViewer/PivotViewer.stories.d.ts.map +1 -1
  102. package/dist/esm/PivotViewer/PivotViewer.stories.js +43 -3
  103. package/dist/esm/PivotViewer/PivotViewer.stories.js.map +1 -1
  104. package/dist/esm/PivotViewer/components/PivotCanvas.d.ts.map +1 -1
  105. package/dist/esm/PivotViewer/components/PivotCanvas.js +33 -10
  106. package/dist/esm/PivotViewer/components/PivotCanvas.js.map +1 -1
  107. package/dist/esm/PivotViewer/components/PivotViewerMain.js +1 -1
  108. package/dist/esm/PivotViewer/components/PivotViewerMain.js.map +1 -1
  109. package/dist/esm/PivotViewer/components/Spinner.css +77 -0
  110. package/dist/esm/PivotViewer/components/pivot/sprites.d.ts.map +1 -1
  111. package/dist/esm/PivotViewer/components/pivot/sprites.js +79 -15
  112. package/dist/esm/PivotViewer/components/pivot/sprites.js.map +1 -1
  113. package/dist/esm/PivotViewer/components/pivot/visibility.d.ts.map +1 -1
  114. package/dist/esm/PivotViewer/components/pivot/visibility.js +36 -10
  115. package/dist/esm/PivotViewer/components/pivot/visibility.js.map +1 -1
  116. package/dist/esm/PivotViewer/engine/layout.js +2 -1
  117. package/dist/esm/PivotViewer/engine/layout.js.map +1 -1
  118. package/dist/esm/PivotViewer/engine/pivot.worker.d.ts.map +1 -1
  119. package/dist/esm/PivotViewer/engine/pivot.worker.js +22 -7
  120. package/dist/esm/PivotViewer/engine/pivot.worker.js.map +1 -1
  121. package/dist/esm/PivotViewer/hooks/useFilteredData.d.ts +2 -2
  122. package/dist/esm/PivotViewer/hooks/useFilteredData.d.ts.map +1 -1
  123. package/dist/esm/PivotViewer/hooks/useFilteredData.js +4 -2
  124. package/dist/esm/PivotViewer/hooks/useFilteredData.js.map +1 -1
  125. package/dist/esm/PivotViewer/hooks/usePivotEngine.d.ts.map +1 -1
  126. package/dist/esm/PivotViewer/hooks/usePivotEngine.js +37 -2
  127. package/dist/esm/PivotViewer/hooks/usePivotEngine.js.map +1 -1
  128. package/dist/esm/PivotViewer/index.d.ts +2 -1
  129. package/dist/esm/PivotViewer/index.d.ts.map +1 -1
  130. package/dist/esm/PivotViewer/index.js +1 -0
  131. package/dist/esm/PivotViewer/index.js.map +1 -1
  132. package/dist/esm/PivotViewer/types.d.ts +4 -1
  133. package/dist/esm/PivotViewer/types.d.ts.map +1 -1
  134. package/dist/esm/PivotViewer/types.js +19 -2
  135. package/dist/esm/PivotViewer/types.js.map +1 -1
  136. package/dist/esm/TimeMachine/EventsView.css +213 -0
  137. package/dist/esm/TimeMachine/TimeMachine.css +567 -0
  138. package/dist/esm/TimeMachine/TimeMachine.d.ts.map +1 -1
  139. package/dist/esm/TimeMachine/TimeMachine.js +8 -3
  140. package/dist/esm/TimeMachine/TimeMachine.js.map +1 -1
  141. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  142. package/package.json +31 -32
  143. package/.storybook/main.ts +0 -24
  144. package/CommandDialog/CommandDialog.stories.tsx +0 -25
  145. package/CommandDialog/CommandDialog.tsx +0 -161
  146. package/CommandDialog/index.ts +0 -4
  147. package/CommandForm/CommandForm.stories.tsx +0 -24
  148. package/CommandForm/CommandForm.tsx +0 -266
  149. package/CommandForm/CommandFormField.tsx +0 -27
  150. package/CommandForm/CommandFormFields.tsx +0 -142
  151. package/CommandForm/DatePickerField.tsx +0 -57
  152. package/CommandForm/DropdownField.tsx +0 -65
  153. package/CommandForm/InputTextField.tsx +0 -62
  154. package/CommandForm/SliderField.tsx +0 -68
  155. package/CommandForm/index.ts +0 -10
  156. package/Common/ErrorBoundary.stories.tsx +0 -10
  157. package/Common/ErrorBoundary.tsx +0 -41
  158. package/Common/FormElement.stories.tsx +0 -10
  159. package/Common/FormElement.tsx +0 -20
  160. package/Common/Page.stories.tsx +0 -10
  161. package/Common/Page.tsx +0 -21
  162. package/Common/index.ts +0 -6
  163. package/DataPage/DataPage.stories.tsx +0 -10
  164. package/DataPage/DataPage.tsx +0 -191
  165. package/DataPage/index.ts +0 -4
  166. package/DataTables/DataTableForObservableQuery.stories.tsx +0 -10
  167. package/DataTables/DataTableForObservableQuery.tsx +0 -97
  168. package/DataTables/DataTableForQuery.stories.tsx +0 -10
  169. package/DataTables/DataTableForQuery.tsx +0 -97
  170. package/DataTables/index.ts +0 -5
  171. package/Dialogs/BusyIndicatorDialog.stories.tsx +0 -26
  172. package/Dialogs/BusyIndicatorDialog.tsx +0 -26
  173. package/Dialogs/ConfirmationDialog.stories.tsx +0 -36
  174. package/Dialogs/ConfirmationDialog.tsx +0 -75
  175. package/Dialogs/index.ts +0 -5
  176. package/Dropdown/Dropdown.tsx +0 -23
  177. package/Dropdown/index.ts +0 -4
  178. package/PivotViewer/PivotViewer.stories.tsx +0 -24
  179. package/PivotViewer/PivotViewer.tsx +0 -791
  180. package/PivotViewer/components/AxisLabels.tsx +0 -69
  181. package/PivotViewer/components/DetailPanel.tsx +0 -108
  182. package/PivotViewer/components/FilterPanel.tsx +0 -189
  183. package/PivotViewer/components/FilterPanelContainer.tsx +0 -10
  184. package/PivotViewer/components/PivotCanvas.tsx +0 -660
  185. package/PivotViewer/components/PivotViewerMain.tsx +0 -229
  186. package/PivotViewer/components/RangeHistogramFilter.tsx +0 -220
  187. package/PivotViewer/components/Spinner.tsx +0 -21
  188. package/PivotViewer/components/Toolbar.tsx +0 -130
  189. package/PivotViewer/components/ToolbarContainer.tsx +0 -10
  190. package/PivotViewer/components/index.ts +0 -12
  191. package/PivotViewer/components/pivot/animation.ts +0 -108
  192. package/PivotViewer/components/pivot/buckets.ts +0 -152
  193. package/PivotViewer/components/pivot/colorResolver.ts +0 -67
  194. package/PivotViewer/components/pivot/constants.ts +0 -46
  195. package/PivotViewer/components/pivot/sprites.ts +0 -265
  196. package/PivotViewer/components/pivot/visibility.ts +0 -319
  197. package/PivotViewer/constants.ts +0 -9
  198. package/PivotViewer/engine/layout.ts +0 -149
  199. package/PivotViewer/engine/pivot.worker.ts +0 -86
  200. package/PivotViewer/engine/store.ts +0 -437
  201. package/PivotViewer/engine/types.ts +0 -255
  202. package/PivotViewer/hooks/index.ts +0 -13
  203. package/PivotViewer/hooks/useContainerDimensions.ts +0 -45
  204. package/PivotViewer/hooks/useDimensionState.ts +0 -53
  205. package/PivotViewer/hooks/useFilterOptions.ts +0 -36
  206. package/PivotViewer/hooks/useFilterPanelDrag.ts +0 -49
  207. package/PivotViewer/hooks/useFilterState.ts +0 -106
  208. package/PivotViewer/hooks/useFilteredData.ts +0 -119
  209. package/PivotViewer/hooks/usePanning.ts +0 -163
  210. package/PivotViewer/hooks/usePivotEngine.ts +0 -252
  211. package/PivotViewer/hooks/useSelectedItem.ts +0 -402
  212. package/PivotViewer/hooks/useWheelZoom.ts +0 -114
  213. package/PivotViewer/hooks/useZoomState.ts +0 -34
  214. package/PivotViewer/index.ts +0 -7
  215. package/PivotViewer/types.ts +0 -59
  216. package/PivotViewer/utils/animations.ts +0 -249
  217. package/PivotViewer/utils/constants.ts +0 -20
  218. package/PivotViewer/utils/index.ts +0 -6
  219. package/PivotViewer/utils/selection.ts +0 -292
  220. package/PivotViewer/utils/utils.ts +0 -259
  221. package/TimeMachine/EventsView.stories.tsx +0 -10
  222. package/TimeMachine/EventsView.tsx +0 -119
  223. package/TimeMachine/Properties.stories.tsx +0 -10
  224. package/TimeMachine/Properties.tsx +0 -98
  225. package/TimeMachine/ReadModelView.stories.tsx +0 -10
  226. package/TimeMachine/ReadModelView.tsx +0 -143
  227. package/TimeMachine/TimeMachine.stories.tsx +0 -10
  228. package/TimeMachine/TimeMachine.tsx +0 -244
  229. package/TimeMachine/index.ts +0 -8
  230. package/TimeMachine/types.ts +0 -23
  231. package/dist/cjs/CommandForm/DatePickerField.js +0 -31
  232. package/dist/cjs/CommandForm/DatePickerField.js.map +0 -1
  233. package/dist/cjs/CommandForm/DropdownField.js +0 -31
  234. package/dist/cjs/CommandForm/DropdownField.js.map +0 -1
  235. package/dist/cjs/CommandForm/InputTextField.js +0 -32
  236. package/dist/cjs/CommandForm/InputTextField.js.map +0 -1
  237. package/dist/cjs/CommandForm/SliderField.js +0 -34
  238. package/dist/cjs/CommandForm/SliderField.js.map +0 -1
  239. package/dist/esm/CommandForm/DatePickerField.d.ts +0 -20
  240. package/dist/esm/CommandForm/DatePickerField.d.ts.map +0 -1
  241. package/dist/esm/CommandForm/DatePickerField.js +0 -29
  242. package/dist/esm/CommandForm/DatePickerField.js.map +0 -1
  243. package/dist/esm/CommandForm/DropdownField.d.ts +0 -24
  244. package/dist/esm/CommandForm/DropdownField.d.ts.map +0 -1
  245. package/dist/esm/CommandForm/DropdownField.js +0 -29
  246. package/dist/esm/CommandForm/DropdownField.js.map +0 -1
  247. package/dist/esm/CommandForm/InputTextField.d.ts +0 -20
  248. package/dist/esm/CommandForm/InputTextField.d.ts.map +0 -1
  249. package/dist/esm/CommandForm/InputTextField.js +0 -30
  250. package/dist/esm/CommandForm/InputTextField.js.map +0 -1
  251. package/dist/esm/CommandForm/SliderField.d.ts +0 -23
  252. package/dist/esm/CommandForm/SliderField.d.ts.map +0 -1
  253. package/dist/esm/CommandForm/SliderField.js +0 -32
  254. package/dist/esm/CommandForm/SliderField.js.map +0 -1
  255. package/global.d.ts +0 -11
  256. package/index.ts +0 -22
  257. package/useOverlayZIndex.ts +0 -32
  258. package/vite.config.ts +0 -80
@@ -1,45 +0,0 @@
1
- // Copyright (c) Cratis. All rights reserved.
2
- // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
-
4
- import { useEffect, useState } from 'react';
5
-
6
- /**
7
- * Hook to track container dimensions using ResizeObserver.
8
- *
9
- * @param containerRef - Ref to the container element.
10
- * @param dependency - Optional dependency to trigger updates.
11
- * @returns Dimensions of the container.
12
- */
13
- export function useContainerDimensions(
14
- containerRef: React.RefObject<HTMLDivElement>,
15
- dependency?: unknown
16
- ) {
17
- const [dimensions, setDimensions] = useState({ width: 1200, height: 600 });
18
-
19
- useEffect(() => {
20
- const container = containerRef.current;
21
- if (!container) return;
22
-
23
- const updateDimensions = () => {
24
- setDimensions({
25
- width: container.clientWidth,
26
- height: container.clientHeight,
27
- });
28
- };
29
-
30
- // Initial dimensions
31
- updateDimensions();
32
-
33
- // Observe for resize changes
34
- const resizeObserver = new ResizeObserver(() => {
35
- updateDimensions();
36
- });
37
- resizeObserver.observe(container);
38
-
39
- return () => {
40
- resizeObserver.disconnect();
41
- };
42
- }, [containerRef, dependency]);
43
-
44
- return dimensions;
45
- }
@@ -1,53 +0,0 @@
1
- // Copyright (c) Cratis. All rights reserved.
2
- // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
-
4
- import { useMemo, useState, useEffect, useCallback } from 'react';
5
- import type { PivotDimension } from '../types';
6
-
7
- export type PivotDimensionFilter = string | null;
8
-
9
- export function useDimensionState<TItem extends object>(
10
- dimensions: PivotDimension<TItem>[],
11
- defaultDimensionKey?: string
12
- ) {
13
- const dimensionMap = useMemo(() => {
14
- const map = new Map<string, PivotDimension<TItem>>();
15
- dimensions.forEach((dimension) => map.set(dimension.key, dimension));
16
- return map;
17
- }, [dimensions]);
18
-
19
- const initialDimension = useMemo(() => {
20
- if (defaultDimensionKey && dimensionMap.has(defaultDimensionKey)) {
21
- return defaultDimensionKey;
22
- }
23
- return dimensions[0]?.key ?? '';
24
- }, [defaultDimensionKey, dimensionMap, dimensions]);
25
-
26
- const [activeDimensionKey, setActiveDimensionKey] = useState(initialDimension);
27
- const [dimensionFilter, setDimensionFilter] = useState<string | null>(null);
28
-
29
- useEffect(() => {
30
- setActiveDimensionKey((previous) => {
31
- if (previous && dimensionMap.has(previous)) {
32
- return previous;
33
- }
34
- return initialDimension;
35
- });
36
- setDimensionFilter(null);
37
- }, [dimensionMap, initialDimension]);
38
-
39
- const activeDimension = dimensionMap.get(activeDimensionKey) ?? dimensions[0];
40
-
41
- const handleAxisLabelClick = useCallback((groupKey: string) => {
42
- setDimensionFilter((prev) => (prev === groupKey ? null : groupKey));
43
- }, []);
44
-
45
- return {
46
- dimensionMap,
47
- activeDimensionKey,
48
- setActiveDimensionKey,
49
- activeDimension,
50
- dimensionFilter,
51
- handleAxisLabelClick,
52
- };
53
- }
@@ -1,36 +0,0 @@
1
- // Copyright (c) Cratis. All rights reserved.
2
- // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
-
4
- import { useMemo } from 'react';
5
- import type { PivotFilter, PivotFilterOption, PivotPrimitive } from '../types';
6
- import { applyFilters, computeFilterOptions, computeNumericRange } from '../utils/utils';
7
- import type { FilterState, RangeFilterState } from '../types';
8
-
9
- export function useFilterOptions<TItem extends object>(
10
- data: TItem[],
11
- filters: PivotFilter<TItem>[] | undefined,
12
- filterState: FilterState,
13
- rangeFilterState: RangeFilterState
14
- ) {
15
- return useMemo(() => {
16
- if (!filters?.length) {
17
- return [] as {
18
- filter: PivotFilter<TItem>;
19
- options: PivotFilterOption[];
20
- numericRange?: { min: number; max: number; values: PivotPrimitive[] };
21
- }[];
22
- }
23
-
24
- return filters.map((filter) => {
25
- const baseData = applyFilters(data, filters, filterState, rangeFilterState, filter.key);
26
-
27
- if (filter.type === 'number') {
28
- const numericRange = computeNumericRange(baseData, filter);
29
- return { filter, options: [], numericRange };
30
- }
31
-
32
- const options = computeFilterOptions(baseData, filter);
33
- return { filter, options };
34
- });
35
- }, [data, filters, filterState, rangeFilterState]);
36
- }
@@ -1,49 +0,0 @@
1
- // Copyright (c) Cratis. All rights reserved.
2
- // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
-
4
- import { useState, useCallback, useEffect } from 'react';
5
-
6
- export function useFilterPanelDrag() {
7
- const [filterPanelPos, setFilterPanelPos] = useState({ x: 16, y: 88 });
8
- const [isDraggingPanel, setIsDraggingPanel] = useState(false);
9
- const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });
10
-
11
- const handleFilterPanelDragStart = useCallback((e: React.MouseEvent) => {
12
- (e as any).preventDefault?.();
13
- setIsDraggingPanel(true);
14
- setDragOffset({
15
- x: e.clientX - filterPanelPos.x,
16
- y: e.clientY - filterPanelPos.y,
17
- });
18
- }, [filterPanelPos]);
19
-
20
- const handleFilterPanelDrag = useCallback((e: MouseEvent) => {
21
- if (!isDraggingPanel) return;
22
- setFilterPanelPos({
23
- x: Math.max(0, e.clientX - dragOffset.x),
24
- y: Math.max(60, e.clientY - dragOffset.y),
25
- });
26
- }, [isDraggingPanel, dragOffset]);
27
-
28
- const handleFilterPanelDragEnd = useCallback(() => {
29
- setIsDraggingPanel(false);
30
- }, []);
31
-
32
- useEffect(() => {
33
- if (isDraggingPanel) {
34
- document.addEventListener('mousemove', handleFilterPanelDrag);
35
- document.addEventListener('mouseup', handleFilterPanelDragEnd);
36
- return () => {
37
- document.removeEventListener('mousemove', handleFilterPanelDrag);
38
- document.removeEventListener('mouseup', handleFilterPanelDragEnd);
39
- };
40
- }
41
- return undefined;
42
- }, [isDraggingPanel, handleFilterPanelDrag, handleFilterPanelDragEnd]);
43
-
44
- return {
45
- filterPanelPos,
46
- isDraggingPanel,
47
- handleFilterPanelDragStart,
48
- };
49
- }
@@ -1,106 +0,0 @@
1
- // Copyright (c) Cratis. All rights reserved.
2
- // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
-
4
- import { useState, useEffect, useCallback } from 'react';
5
- import { buildFilterState, buildRangeFilterState } from '../utils/utils';
6
- import { FilterState, RangeFilterState, PivotFilter } from '../types';
7
-
8
- /**
9
- * Hook to manage filter state.
10
- */
11
- export function useFilterState<TItem extends object>(
12
- filters: PivotFilter<TItem>[] | undefined
13
- ) {
14
- const [filterState, setFilterState] = useState<FilterState>(() => buildFilterState(filters));
15
- const [rangeFilterState, setRangeFilterState] = useState<RangeFilterState>(() => buildRangeFilterState(filters));
16
- const [expandedFilterKey, setExpandedFilterKey] = useState<string | null>(filters?.[0]?.key ?? null);
17
-
18
- useEffect(() => {
19
- setFilterState((prev) => {
20
- const next = buildFilterState(filters);
21
- if (!filters) return next;
22
-
23
- filters.forEach((filter) => {
24
- if (prev[filter.key]) {
25
- next[filter.key] = new Set(prev[filter.key]);
26
- }
27
- });
28
-
29
- return next;
30
- });
31
- setRangeFilterState((prev) => {
32
- const next = buildRangeFilterState(filters);
33
- if (!filters) return next;
34
- filters.forEach((filter) => {
35
- if (filter.type === 'number' && filter.key in prev) {
36
- next[filter.key] = prev[filter.key];
37
- }
38
- });
39
- return next;
40
- });
41
- }, [filters]);
42
-
43
- useEffect(() => {
44
- if (!filters?.length) {
45
- setExpandedFilterKey(null);
46
- return;
47
- }
48
-
49
- setExpandedFilterKey((current) => {
50
- if (current && filters.some((filter) => filter.key === current)) {
51
- return current;
52
- }
53
- return filters[0]?.key ?? null;
54
- });
55
- }, [filters]);
56
-
57
- const handleToggleFilter = useCallback((filterKey: string, optionKey: string, multi: boolean | undefined) => {
58
- setFilterState((prev) => {
59
- const next: FilterState = { ...prev };
60
- const current = new Set(prev[filterKey] ?? []);
61
-
62
- if (multi) {
63
- if (current.has(optionKey)) {
64
- current.delete(optionKey);
65
- } else {
66
- current.add(optionKey);
67
- }
68
- } else {
69
- if (current.has(optionKey)) {
70
- current.clear();
71
- } else {
72
- current.clear();
73
- current.add(optionKey);
74
- }
75
- }
76
-
77
- next[filterKey] = current;
78
- return next;
79
- });
80
- }, []);
81
-
82
- const handleClearFilter = useCallback((filterKey: string) => {
83
- setFilterState((prev) => {
84
- const next: FilterState = { ...prev };
85
- next[filterKey] = new Set();
86
- return next;
87
- });
88
- }, []);
89
-
90
- const handleRangeChange = useCallback((filterKey: string, range: [number, number] | null) => {
91
- setRangeFilterState((prev) => ({
92
- ...prev,
93
- [filterKey]: range,
94
- }));
95
- }, []);
96
-
97
- return {
98
- filterState,
99
- rangeFilterState,
100
- expandedFilterKey,
101
- setExpandedFilterKey,
102
- handleToggleFilter,
103
- handleClearFilter,
104
- handleRangeChange,
105
- };
106
- }
@@ -1,119 +0,0 @@
1
- // Copyright (c) Cratis. All rights reserved.
2
- // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
-
4
- import { useMemo } from 'react';
5
- import type { PivotDimension, PivotFilter, PivotGroup } from '../types';
6
- import { applyFilters, groupData, toKey } from '../utils/utils';
7
- import type { FilterState, RangeFilterState } from '../utils/utils';
8
-
9
- export function useFilteredData<TItem extends object>(
10
- data: TItem[],
11
- filters: PivotFilter<TItem>[] | undefined,
12
- filterState: FilterState,
13
- rangeFilterState: RangeFilterState,
14
- activeDimension: PivotDimension<TItem> | undefined,
15
- dimensionFilter: string | null,
16
- searchTerm: string,
17
- searchFields?: (keyof TItem)[]
18
- ) {
19
- const filteredData = useMemo(() => {
20
- let dataWithFilters = applyFilters(data, filters, filterState, rangeFilterState);
21
-
22
- if (dimensionFilter && activeDimension) {
23
- dataWithFilters = dataWithFilters.filter((item) => {
24
- const value = activeDimension.getValue(item);
25
- const key = toKey(value);
26
- return key === dimensionFilter;
27
- });
28
- }
29
-
30
- if (!searchTerm) {
31
- return dataWithFilters;
32
- }
33
-
34
- // Optimize search by using indexOf instead of includes for better performance
35
- return dataWithFilters.filter((item) => {
36
- if (searchFields && searchFields.length) {
37
- for (const field of searchFields) {
38
- const value = item[field];
39
- if (value !== undefined && String(value).toLowerCase().indexOf(searchTerm) !== -1) {
40
- return true;
41
- }
42
- }
43
- return false;
44
- }
45
-
46
- // Fallback to JSON stringify - less efficient but comprehensive
47
- return JSON.stringify(item).toLowerCase().indexOf(searchTerm) !== -1;
48
- });
49
- }, [data, filters, filterState, rangeFilterState, dimensionFilter, activeDimension, searchFields, searchTerm]);
50
-
51
- const allGroupsForBuckets = useMemo(() => {
52
- if (!activeDimension) {
53
- return [] as PivotGroup<TItem>[];
54
- }
55
- const dataWithoutDimensionFilter = applyFilters(data, filters, filterState, rangeFilterState);
56
- return groupData(dataWithoutDimensionFilter, activeDimension);
57
- }, [data, filters, filterState, rangeFilterState, activeDimension]);
58
-
59
- const groupedGroups = useMemo(() => {
60
- if (!activeDimension) {
61
- return [] as PivotGroup<TItem>[];
62
- }
63
-
64
- if (dimensionFilter) {
65
- const filteredGroup = allGroupsForBuckets.find((group) => group.key === dimensionFilter);
66
- return filteredGroup ? [filteredGroup] : [];
67
- }
68
-
69
- return groupData(filteredData, activeDimension);
70
- }, [filteredData, activeDimension, dimensionFilter, allGroupsForBuckets]);
71
-
72
- const collectionGroup = useMemo(() => {
73
- if (filteredData.length === 0) {
74
- return [] as PivotGroup<TItem>[];
75
- }
76
-
77
- // Sort by active dimension when in collection mode
78
- const sortedData = activeDimension
79
- ? [...filteredData].sort((a, b) => {
80
- const valueA = activeDimension.getValue(a);
81
- const valueB = activeDimension.getValue(b);
82
-
83
- // Handle null/undefined
84
- if (valueA == null && valueB == null) return 0;
85
- if (valueA == null) return 1;
86
- if (valueB == null) return -1;
87
-
88
- // Handle dates
89
- if (valueA instanceof Date && valueB instanceof Date) {
90
- return valueA.getTime() - valueB.getTime();
91
- }
92
-
93
- // Handle numbers
94
- if (typeof valueA === 'number' && typeof valueB === 'number') {
95
- return valueA - valueB;
96
- }
97
-
98
- // Handle strings
99
- return String(valueA).localeCompare(String(valueB));
100
- })
101
- : filteredData;
102
-
103
- return [
104
- {
105
- key: 'collection-all',
106
- label: 'All Events',
107
- value: null,
108
- items: sortedData,
109
- } as PivotGroup<TItem>,
110
- ];
111
- }, [filteredData, activeDimension]);
112
-
113
- return {
114
- filteredData,
115
- allGroupsForBuckets,
116
- groupedGroups,
117
- collectionGroup,
118
- };
119
- }
@@ -1,163 +0,0 @@
1
- // Copyright (c) Cratis. All rights reserved.
2
- // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
-
4
- import { useState, useRef, useCallback } from 'react';
5
-
6
- export function usePanning(
7
- containerRef: React.RefObject<HTMLDivElement | null>,
8
- onBackgroundClick?: () => void,
9
- onScrollChange?: (scroll: { x: number; y: number }) => void
10
- ) {
11
- const [isPanning, setIsPanning] = useState(false);
12
- const panStartRef = useRef<{ x: number; y: number; scrollLeft: number; scrollTop: number } | null>(null);
13
- const velocityRef = useRef({ x: 0, y: 0 });
14
- const lastMouseRef = useRef<{ x: number; y: number; time: number } | null>(null);
15
- const inertiaAnimationRef = useRef<number | null>(null);
16
- const didDragRef = useRef(false);
17
- const clickedOnBackgroundRef = useRef(false);
18
-
19
- const stopInertia = useCallback(() => {
20
- if (inertiaAnimationRef.current) {
21
- cancelAnimationFrame(inertiaAnimationRef.current);
22
- inertiaAnimationRef.current = null;
23
- }
24
- }, []);
25
-
26
- const handlePanStart = useCallback((e: React.MouseEvent | MouseEvent, isExplicitlyOnCard?: boolean) => {
27
- const container = containerRef.current;
28
- if (!container) return;
29
-
30
- stopInertia();
31
-
32
- const target = e.target as HTMLElement;
33
- // Check if explicitly on card (from Pixi) or via DOM (fallback)
34
- const isOnCard = isExplicitlyOnCard ?? !!target.closest('.pv-card');
35
-
36
- clickedOnBackgroundRef.current = !isOnCard;
37
- didDragRef.current = false;
38
- velocityRef.current = { x: 0, y: 0 };
39
-
40
- if (e.button === 1 || (e.button === 0 && (e.altKey || !isOnCard))) {
41
- if (!isOnCard) {
42
- (e as any).preventDefault?.();
43
- }
44
- setIsPanning(true);
45
- panStartRef.current = {
46
- x: e.clientX,
47
- y: e.clientY,
48
- scrollLeft: container.scrollLeft,
49
- scrollTop: container.scrollTop,
50
- };
51
- lastMouseRef.current = { x: e.clientX, y: e.clientY, time: performance.now() };
52
- }
53
- }, [containerRef, stopInertia]);
54
-
55
- const handlePanMove = useCallback((e: React.MouseEvent | MouseEvent) => {
56
- const panStart = panStartRef.current;
57
- if (!isPanning || !panStart) return;
58
-
59
- const dx = e.clientX - panStart.x;
60
- const dy = e.clientY - panStart.y;
61
-
62
- // Mark as dragged if moved more than 3 pixels
63
- if (Math.abs(dx) > 3 || Math.abs(dy) > 3) {
64
- didDragRef.current = true;
65
- }
66
-
67
- // Camera moves opposite to drag direction
68
- const newCameraX = panStart.scrollLeft - dx;
69
- const newCameraY = panStart.scrollTop - dy;
70
-
71
- // Update camera position
72
- // Update container scroll directly so the visual camera follows the drag
73
- const container = containerRef.current;
74
- if (container) {
75
- container.scrollLeft = Math.max(0, Math.round(newCameraX));
76
- container.scrollTop = Math.max(0, Math.round(newCameraY));
77
- }
78
-
79
- // Also notify parent about scroll change (keeps external state in sync)
80
- if (onScrollChange) {
81
- onScrollChange({ x: container ? container.scrollLeft : newCameraX, y: container ? container.scrollTop : newCameraY });
82
- }
83
-
84
- // Track velocity for inertia
85
- const now = performance.now();
86
- const last = lastMouseRef.current;
87
- if (last) {
88
- const dt = now - last.time;
89
- if (dt > 0 && dt < 50) {
90
- const instantVx = (last.x - e.clientX) / dt;
91
- const instantVy = (last.y - e.clientY) / dt;
92
- velocityRef.current = {
93
- x: velocityRef.current.x * 0.5 + instantVx * 0.5,
94
- y: velocityRef.current.y * 0.5 + instantVy * 0.5,
95
- };
96
- }
97
- }
98
- lastMouseRef.current = { x: e.clientX, y: e.clientY, time: now };
99
- }, [isPanning, containerRef, onScrollChange]);
100
-
101
- const handlePanEnd = useCallback(() => {
102
- const wasPanning = isPanning;
103
- const velocity = { ...velocityRef.current };
104
-
105
- setIsPanning(false);
106
- panStartRef.current = null;
107
-
108
- // If clicked on background and didn't drag, trigger deselect
109
- if (clickedOnBackgroundRef.current && !didDragRef.current && onBackgroundClick) {
110
- onBackgroundClick();
111
- }
112
-
113
- if (!wasPanning) {
114
- return;
115
- }
116
-
117
- const container = containerRef.current;
118
- if (!container) {
119
- lastMouseRef.current = null;
120
- return;
121
- }
122
-
123
- const speed = Math.sqrt(velocity.x * velocity.x + velocity.y * velocity.y);
124
-
125
- // Start inertia if moving fast enough
126
- if (speed > 0.3) {
127
- let vx = velocity.x * 16;
128
- let vy = velocity.y * 16;
129
-
130
- const animate = () => {
131
- const currentSpeed = Math.sqrt(vx * vx + vy * vy);
132
-
133
- if (currentSpeed < 0.5) {
134
- inertiaAnimationRef.current = null;
135
- return;
136
- }
137
-
138
- container.scrollLeft += vx;
139
- container.scrollTop += vy;
140
-
141
- // Decay
142
- vx *= 0.95;
143
- vy *= 0.95;
144
-
145
- inertiaAnimationRef.current = requestAnimationFrame(animate);
146
- };
147
-
148
- inertiaAnimationRef.current = requestAnimationFrame(animate);
149
- }
150
-
151
- lastMouseRef.current = null;
152
- }, [isPanning, containerRef, onBackgroundClick]);
153
-
154
- return {
155
- isPanning,
156
- handlePanStart,
157
- handlePanMove,
158
- handlePanEnd,
159
- };
160
- }
161
-
162
-
163
-