@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.
- package/dist/cjs/CommandForm/CommandFormFields.js +9 -3
- package/dist/cjs/CommandForm/CommandFormFields.js.map +1 -1
- package/dist/cjs/CommandForm/ValidationMessage.js +24 -0
- package/dist/cjs/CommandForm/ValidationMessage.js.map +1 -0
- package/dist/cjs/CommandForm/asCommandFormField.js +47 -0
- package/dist/cjs/CommandForm/asCommandFormField.js.map +1 -0
- package/dist/cjs/CommandForm/fields/CheckboxField.js +13 -0
- package/dist/cjs/CommandForm/fields/CheckboxField.js.map +1 -0
- package/dist/cjs/CommandForm/fields/DropdownField.js +13 -0
- package/dist/cjs/CommandForm/fields/DropdownField.js.map +1 -0
- package/dist/cjs/CommandForm/fields/InputTextField.js +13 -0
- package/dist/cjs/CommandForm/fields/InputTextField.js.map +1 -0
- package/dist/cjs/CommandForm/fields/NumberField.js +13 -0
- package/dist/cjs/CommandForm/fields/NumberField.js.map +1 -0
- package/dist/cjs/CommandForm/fields/SliderField.js +17 -0
- package/dist/cjs/CommandForm/fields/SliderField.js.map +1 -0
- package/dist/cjs/CommandForm/fields/TextAreaField.js +13 -0
- package/dist/cjs/CommandForm/fields/TextAreaField.js.map +1 -0
- package/dist/cjs/CommandForm/index.js +15 -7
- package/dist/cjs/CommandForm/index.js.map +1 -1
- package/dist/cjs/PivotViewer/PivotViewer.css +1258 -0
- package/dist/cjs/PivotViewer/PivotViewer.js +14 -0
- package/dist/cjs/PivotViewer/PivotViewer.js.map +1 -1
- package/dist/cjs/PivotViewer/components/PivotCanvas.js +33 -10
- package/dist/cjs/PivotViewer/components/PivotCanvas.js.map +1 -1
- package/dist/cjs/PivotViewer/components/PivotViewerMain.js +1 -1
- package/dist/cjs/PivotViewer/components/PivotViewerMain.js.map +1 -1
- package/dist/cjs/PivotViewer/components/Spinner.css +77 -0
- package/dist/cjs/PivotViewer/components/pivot/sprites.js +79 -15
- package/dist/cjs/PivotViewer/components/pivot/sprites.js.map +1 -1
- package/dist/cjs/PivotViewer/components/pivot/visibility.js +36 -10
- package/dist/cjs/PivotViewer/components/pivot/visibility.js.map +1 -1
- package/dist/cjs/PivotViewer/engine/layout.js +2 -1
- package/dist/cjs/PivotViewer/engine/layout.js.map +1 -1
- package/dist/cjs/PivotViewer/hooks/usePivotEngine.js +37 -2
- package/dist/cjs/PivotViewer/hooks/usePivotEngine.js.map +1 -1
- package/dist/cjs/PivotViewer/index.js +3 -0
- package/dist/cjs/PivotViewer/index.js.map +1 -1
- package/dist/cjs/PivotViewer/types.js +22 -0
- package/dist/cjs/PivotViewer/types.js.map +1 -0
- package/dist/cjs/TimeMachine/EventsView.css +213 -0
- package/dist/cjs/TimeMachine/TimeMachine.css +567 -0
- package/dist/cjs/TimeMachine/TimeMachine.js +8 -3
- package/dist/cjs/TimeMachine/TimeMachine.js.map +1 -1
- package/dist/esm/CommandForm/CommandForm.stories.d.ts +1 -0
- package/dist/esm/CommandForm/CommandForm.stories.d.ts.map +1 -1
- package/dist/esm/CommandForm/CommandForm.stories.js +34 -1
- package/dist/esm/CommandForm/CommandForm.stories.js.map +1 -1
- package/dist/esm/CommandForm/CommandFormFields.d.ts.map +1 -1
- package/dist/esm/CommandForm/CommandFormFields.js +9 -3
- package/dist/esm/CommandForm/CommandFormFields.js.map +1 -1
- package/dist/esm/CommandForm/UserRegistrationCommand.d.ts +63 -0
- package/dist/esm/CommandForm/UserRegistrationCommand.d.ts.map +1 -0
- package/dist/esm/CommandForm/UserRegistrationCommand.js +143 -0
- package/dist/esm/CommandForm/UserRegistrationCommand.js.map +1 -0
- package/dist/esm/CommandForm/ValidationMessage.d.ts +8 -0
- package/dist/esm/CommandForm/ValidationMessage.d.ts.map +1 -0
- package/dist/esm/CommandForm/ValidationMessage.js +22 -0
- package/dist/esm/CommandForm/ValidationMessage.js.map +1 -0
- package/dist/esm/CommandForm/asCommandFormField.d.ts +32 -0
- package/dist/esm/CommandForm/asCommandFormField.d.ts.map +1 -0
- package/dist/esm/CommandForm/asCommandFormField.js +45 -0
- package/dist/esm/CommandForm/asCommandFormField.js.map +1 -0
- package/dist/esm/CommandForm/fields/CheckboxField.d.ts +10 -0
- package/dist/esm/CommandForm/fields/CheckboxField.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/CheckboxField.js +11 -0
- package/dist/esm/CommandForm/fields/CheckboxField.js.map +1 -0
- package/dist/esm/CommandForm/fields/DropdownField.d.ts +15 -0
- package/dist/esm/CommandForm/fields/DropdownField.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/DropdownField.js +11 -0
- package/dist/esm/CommandForm/fields/DropdownField.js.map +1 -0
- package/dist/esm/CommandForm/fields/InputTextField.d.ts +11 -0
- package/dist/esm/CommandForm/fields/InputTextField.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/InputTextField.js +11 -0
- package/dist/esm/CommandForm/fields/InputTextField.js.map +1 -0
- package/dist/esm/CommandForm/fields/NumberField.d.ts +13 -0
- package/dist/esm/CommandForm/fields/NumberField.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/NumberField.js +11 -0
- package/dist/esm/CommandForm/fields/NumberField.js.map +1 -0
- package/dist/esm/CommandForm/fields/SliderField.d.ts +12 -0
- package/dist/esm/CommandForm/fields/SliderField.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/SliderField.js +15 -0
- package/dist/esm/CommandForm/fields/SliderField.js.map +1 -0
- package/dist/esm/CommandForm/fields/TextAreaField.d.ts +12 -0
- package/dist/esm/CommandForm/fields/TextAreaField.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/TextAreaField.js +11 -0
- package/dist/esm/CommandForm/fields/TextAreaField.js.map +1 -0
- package/dist/esm/CommandForm/fields/index.d.ts +7 -0
- package/dist/esm/CommandForm/fields/index.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/index.js +7 -0
- package/dist/esm/CommandForm/fields/index.js.map +1 -0
- package/dist/esm/CommandForm/index.d.ts +3 -4
- package/dist/esm/CommandForm/index.d.ts.map +1 -1
- package/dist/esm/CommandForm/index.js +8 -4
- package/dist/esm/CommandForm/index.js.map +1 -1
- package/dist/esm/PivotViewer/PivotViewer.css +1258 -0
- package/dist/esm/PivotViewer/PivotViewer.d.ts.map +1 -1
- package/dist/esm/PivotViewer/PivotViewer.js +14 -0
- package/dist/esm/PivotViewer/PivotViewer.js.map +1 -1
- package/dist/esm/PivotViewer/PivotViewer.stories.d.ts +1 -0
- package/dist/esm/PivotViewer/PivotViewer.stories.d.ts.map +1 -1
- package/dist/esm/PivotViewer/PivotViewer.stories.js +43 -3
- package/dist/esm/PivotViewer/PivotViewer.stories.js.map +1 -1
- package/dist/esm/PivotViewer/components/PivotCanvas.d.ts.map +1 -1
- package/dist/esm/PivotViewer/components/PivotCanvas.js +33 -10
- package/dist/esm/PivotViewer/components/PivotCanvas.js.map +1 -1
- package/dist/esm/PivotViewer/components/PivotViewerMain.js +1 -1
- package/dist/esm/PivotViewer/components/PivotViewerMain.js.map +1 -1
- package/dist/esm/PivotViewer/components/Spinner.css +77 -0
- package/dist/esm/PivotViewer/components/pivot/sprites.d.ts.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/sprites.js +79 -15
- package/dist/esm/PivotViewer/components/pivot/sprites.js.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/visibility.d.ts.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/visibility.js +36 -10
- package/dist/esm/PivotViewer/components/pivot/visibility.js.map +1 -1
- package/dist/esm/PivotViewer/engine/layout.js +2 -1
- package/dist/esm/PivotViewer/engine/layout.js.map +1 -1
- package/dist/esm/PivotViewer/engine/pivot.worker.d.ts.map +1 -1
- package/dist/esm/PivotViewer/engine/pivot.worker.js +22 -7
- package/dist/esm/PivotViewer/engine/pivot.worker.js.map +1 -1
- package/dist/esm/PivotViewer/hooks/useFilteredData.d.ts +2 -2
- package/dist/esm/PivotViewer/hooks/useFilteredData.d.ts.map +1 -1
- package/dist/esm/PivotViewer/hooks/useFilteredData.js +4 -2
- package/dist/esm/PivotViewer/hooks/useFilteredData.js.map +1 -1
- package/dist/esm/PivotViewer/hooks/usePivotEngine.d.ts.map +1 -1
- package/dist/esm/PivotViewer/hooks/usePivotEngine.js +37 -2
- package/dist/esm/PivotViewer/hooks/usePivotEngine.js.map +1 -1
- package/dist/esm/PivotViewer/index.d.ts +2 -1
- package/dist/esm/PivotViewer/index.d.ts.map +1 -1
- package/dist/esm/PivotViewer/index.js +1 -0
- package/dist/esm/PivotViewer/index.js.map +1 -1
- package/dist/esm/PivotViewer/types.d.ts +4 -1
- package/dist/esm/PivotViewer/types.d.ts.map +1 -1
- package/dist/esm/PivotViewer/types.js +19 -2
- package/dist/esm/PivotViewer/types.js.map +1 -1
- package/dist/esm/TimeMachine/EventsView.css +213 -0
- package/dist/esm/TimeMachine/TimeMachine.css +567 -0
- package/dist/esm/TimeMachine/TimeMachine.d.ts.map +1 -1
- package/dist/esm/TimeMachine/TimeMachine.js +8 -3
- package/dist/esm/TimeMachine/TimeMachine.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +31 -32
- package/.storybook/main.ts +0 -24
- package/CommandDialog/CommandDialog.stories.tsx +0 -25
- package/CommandDialog/CommandDialog.tsx +0 -161
- package/CommandDialog/index.ts +0 -4
- package/CommandForm/CommandForm.stories.tsx +0 -24
- package/CommandForm/CommandForm.tsx +0 -266
- package/CommandForm/CommandFormField.tsx +0 -27
- package/CommandForm/CommandFormFields.tsx +0 -142
- package/CommandForm/DatePickerField.tsx +0 -57
- package/CommandForm/DropdownField.tsx +0 -65
- package/CommandForm/InputTextField.tsx +0 -62
- package/CommandForm/SliderField.tsx +0 -68
- package/CommandForm/index.ts +0 -10
- package/Common/ErrorBoundary.stories.tsx +0 -10
- package/Common/ErrorBoundary.tsx +0 -41
- package/Common/FormElement.stories.tsx +0 -10
- package/Common/FormElement.tsx +0 -20
- package/Common/Page.stories.tsx +0 -10
- package/Common/Page.tsx +0 -21
- package/Common/index.ts +0 -6
- package/DataPage/DataPage.stories.tsx +0 -10
- package/DataPage/DataPage.tsx +0 -191
- package/DataPage/index.ts +0 -4
- package/DataTables/DataTableForObservableQuery.stories.tsx +0 -10
- package/DataTables/DataTableForObservableQuery.tsx +0 -97
- package/DataTables/DataTableForQuery.stories.tsx +0 -10
- package/DataTables/DataTableForQuery.tsx +0 -97
- package/DataTables/index.ts +0 -5
- package/Dialogs/BusyIndicatorDialog.stories.tsx +0 -26
- package/Dialogs/BusyIndicatorDialog.tsx +0 -26
- package/Dialogs/ConfirmationDialog.stories.tsx +0 -36
- package/Dialogs/ConfirmationDialog.tsx +0 -75
- package/Dialogs/index.ts +0 -5
- package/Dropdown/Dropdown.tsx +0 -23
- package/Dropdown/index.ts +0 -4
- package/PivotViewer/PivotViewer.stories.tsx +0 -24
- package/PivotViewer/PivotViewer.tsx +0 -791
- package/PivotViewer/components/AxisLabels.tsx +0 -69
- package/PivotViewer/components/DetailPanel.tsx +0 -108
- package/PivotViewer/components/FilterPanel.tsx +0 -189
- package/PivotViewer/components/FilterPanelContainer.tsx +0 -10
- package/PivotViewer/components/PivotCanvas.tsx +0 -660
- package/PivotViewer/components/PivotViewerMain.tsx +0 -229
- package/PivotViewer/components/RangeHistogramFilter.tsx +0 -220
- package/PivotViewer/components/Spinner.tsx +0 -21
- package/PivotViewer/components/Toolbar.tsx +0 -130
- package/PivotViewer/components/ToolbarContainer.tsx +0 -10
- package/PivotViewer/components/index.ts +0 -12
- package/PivotViewer/components/pivot/animation.ts +0 -108
- package/PivotViewer/components/pivot/buckets.ts +0 -152
- package/PivotViewer/components/pivot/colorResolver.ts +0 -67
- package/PivotViewer/components/pivot/constants.ts +0 -46
- package/PivotViewer/components/pivot/sprites.ts +0 -265
- package/PivotViewer/components/pivot/visibility.ts +0 -319
- package/PivotViewer/constants.ts +0 -9
- package/PivotViewer/engine/layout.ts +0 -149
- package/PivotViewer/engine/pivot.worker.ts +0 -86
- package/PivotViewer/engine/store.ts +0 -437
- package/PivotViewer/engine/types.ts +0 -255
- package/PivotViewer/hooks/index.ts +0 -13
- package/PivotViewer/hooks/useContainerDimensions.ts +0 -45
- package/PivotViewer/hooks/useDimensionState.ts +0 -53
- package/PivotViewer/hooks/useFilterOptions.ts +0 -36
- package/PivotViewer/hooks/useFilterPanelDrag.ts +0 -49
- package/PivotViewer/hooks/useFilterState.ts +0 -106
- package/PivotViewer/hooks/useFilteredData.ts +0 -119
- package/PivotViewer/hooks/usePanning.ts +0 -163
- package/PivotViewer/hooks/usePivotEngine.ts +0 -252
- package/PivotViewer/hooks/useSelectedItem.ts +0 -402
- package/PivotViewer/hooks/useWheelZoom.ts +0 -114
- package/PivotViewer/hooks/useZoomState.ts +0 -34
- package/PivotViewer/index.ts +0 -7
- package/PivotViewer/types.ts +0 -59
- package/PivotViewer/utils/animations.ts +0 -249
- package/PivotViewer/utils/constants.ts +0 -20
- package/PivotViewer/utils/index.ts +0 -6
- package/PivotViewer/utils/selection.ts +0 -292
- package/PivotViewer/utils/utils.ts +0 -259
- package/TimeMachine/EventsView.stories.tsx +0 -10
- package/TimeMachine/EventsView.tsx +0 -119
- package/TimeMachine/Properties.stories.tsx +0 -10
- package/TimeMachine/Properties.tsx +0 -98
- package/TimeMachine/ReadModelView.stories.tsx +0 -10
- package/TimeMachine/ReadModelView.tsx +0 -143
- package/TimeMachine/TimeMachine.stories.tsx +0 -10
- package/TimeMachine/TimeMachine.tsx +0 -244
- package/TimeMachine/index.ts +0 -8
- package/TimeMachine/types.ts +0 -23
- package/dist/cjs/CommandForm/DatePickerField.js +0 -31
- package/dist/cjs/CommandForm/DatePickerField.js.map +0 -1
- package/dist/cjs/CommandForm/DropdownField.js +0 -31
- package/dist/cjs/CommandForm/DropdownField.js.map +0 -1
- package/dist/cjs/CommandForm/InputTextField.js +0 -32
- package/dist/cjs/CommandForm/InputTextField.js.map +0 -1
- package/dist/cjs/CommandForm/SliderField.js +0 -34
- package/dist/cjs/CommandForm/SliderField.js.map +0 -1
- package/dist/esm/CommandForm/DatePickerField.d.ts +0 -20
- package/dist/esm/CommandForm/DatePickerField.d.ts.map +0 -1
- package/dist/esm/CommandForm/DatePickerField.js +0 -29
- package/dist/esm/CommandForm/DatePickerField.js.map +0 -1
- package/dist/esm/CommandForm/DropdownField.d.ts +0 -24
- package/dist/esm/CommandForm/DropdownField.d.ts.map +0 -1
- package/dist/esm/CommandForm/DropdownField.js +0 -29
- package/dist/esm/CommandForm/DropdownField.js.map +0 -1
- package/dist/esm/CommandForm/InputTextField.d.ts +0 -20
- package/dist/esm/CommandForm/InputTextField.d.ts.map +0 -1
- package/dist/esm/CommandForm/InputTextField.js +0 -30
- package/dist/esm/CommandForm/InputTextField.js.map +0 -1
- package/dist/esm/CommandForm/SliderField.d.ts +0 -23
- package/dist/esm/CommandForm/SliderField.d.ts.map +0 -1
- package/dist/esm/CommandForm/SliderField.js +0 -32
- package/dist/esm/CommandForm/SliderField.js.map +0 -1
- package/global.d.ts +0 -11
- package/index.ts +0 -22
- package/useOverlayZIndex.ts +0 -32
- package/vite.config.ts +0 -80
|
@@ -1,114 +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 { useCallback, useEffect } from 'react';
|
|
5
|
-
import { ZOOM_MIN, ZOOM_MAX } from '../utils/utils';
|
|
6
|
-
|
|
7
|
-
export function useWheelZoom(
|
|
8
|
-
containerRef: React.RefObject<HTMLDivElement | null>,
|
|
9
|
-
zoomLevel: number,
|
|
10
|
-
setZoomLevel: (zoom: number) => void
|
|
11
|
-
) {
|
|
12
|
-
const handleWheel = useCallback((e: WheelEvent) => {
|
|
13
|
-
if (e.ctrlKey || e.metaKey) {
|
|
14
|
-
e.preventDefault();
|
|
15
|
-
|
|
16
|
-
const container = containerRef.current;
|
|
17
|
-
if (!container) return;
|
|
18
|
-
|
|
19
|
-
container.style.scrollBehavior = 'auto';
|
|
20
|
-
|
|
21
|
-
const rect = container.getBoundingClientRect();
|
|
22
|
-
const cursorX = e.clientX - rect.left;
|
|
23
|
-
const cursorY = e.clientY - rect.top;
|
|
24
|
-
const scrollX = container.scrollLeft;
|
|
25
|
-
const scrollY = container.scrollTop;
|
|
26
|
-
|
|
27
|
-
const delta = -e.deltaY * 0.01;
|
|
28
|
-
const newZoom = Math.max(ZOOM_MIN, Math.min(ZOOM_MAX, zoomLevel + delta));
|
|
29
|
-
const zoomRatio = newZoom / zoomLevel;
|
|
30
|
-
|
|
31
|
-
const newScrollLeft = (scrollX + cursorX) * zoomRatio - cursorX;
|
|
32
|
-
const newScrollTop = (scrollY + cursorY) * zoomRatio - cursorY;
|
|
33
|
-
|
|
34
|
-
setZoomLevel(newZoom);
|
|
35
|
-
|
|
36
|
-
setTimeout(() => {
|
|
37
|
-
container.scrollLeft = Math.max(0, newScrollLeft);
|
|
38
|
-
container.scrollTop = Math.max(0, newScrollTop);
|
|
39
|
-
setTimeout(() => {
|
|
40
|
-
container.style.scrollBehavior = '';
|
|
41
|
-
}, 50);
|
|
42
|
-
}, 0);
|
|
43
|
-
}
|
|
44
|
-
}, [zoomLevel, setZoomLevel, containerRef]);
|
|
45
|
-
|
|
46
|
-
useEffect(() => {
|
|
47
|
-
const container = containerRef.current;
|
|
48
|
-
if (!container) return;
|
|
49
|
-
|
|
50
|
-
container.addEventListener('wheel', handleWheel, { passive: false });
|
|
51
|
-
|
|
52
|
-
let lastTouchDistance = 0;
|
|
53
|
-
let currentZoom = zoomLevel;
|
|
54
|
-
|
|
55
|
-
const handleTouchStart = (e: TouchEvent) => {
|
|
56
|
-
if (e.touches.length === 2) {
|
|
57
|
-
const dx = e.touches[0].clientX - e.touches[1].clientX;
|
|
58
|
-
const dy = e.touches[0].clientY - e.touches[1].clientY;
|
|
59
|
-
lastTouchDistance = Math.sqrt(dx * dx + dy * dy);
|
|
60
|
-
currentZoom = zoomLevel;
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
const handleTouchMove = (e: TouchEvent) => {
|
|
65
|
-
if (e.touches.length === 2) {
|
|
66
|
-
e.preventDefault();
|
|
67
|
-
const dx = e.touches[0].clientX - e.touches[1].clientX;
|
|
68
|
-
const dy = e.touches[0].clientY - e.touches[1].clientY;
|
|
69
|
-
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
70
|
-
|
|
71
|
-
const centerX = (e.touches[0].clientX + e.touches[1].clientX) / 2;
|
|
72
|
-
const centerY = (e.touches[0].clientY + e.touches[1].clientY) / 2;
|
|
73
|
-
const rect = container.getBoundingClientRect();
|
|
74
|
-
const cursorX = centerX - rect.left;
|
|
75
|
-
const cursorY = centerY - rect.top;
|
|
76
|
-
|
|
77
|
-
if (lastTouchDistance > 0) {
|
|
78
|
-
const scale = distance / lastTouchDistance;
|
|
79
|
-
const newZoom = Math.max(ZOOM_MIN, Math.min(ZOOM_MAX, currentZoom * scale));
|
|
80
|
-
const zoomRatio = newZoom / zoomLevel;
|
|
81
|
-
|
|
82
|
-
const contentX = container.scrollLeft + cursorX;
|
|
83
|
-
const contentY = container.scrollTop + cursorY;
|
|
84
|
-
|
|
85
|
-
const newScrollLeft = contentX * zoomRatio - cursorX;
|
|
86
|
-
const newScrollTop = contentY * zoomRatio - cursorY;
|
|
87
|
-
|
|
88
|
-
setZoomLevel(newZoom);
|
|
89
|
-
|
|
90
|
-
requestAnimationFrame(() => {
|
|
91
|
-
container.scrollLeft = Math.max(0, newScrollLeft);
|
|
92
|
-
container.scrollTop = Math.max(0, newScrollTop);
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
lastTouchDistance = distance;
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
const handleTouchEnd = () => {
|
|
100
|
-
lastTouchDistance = 0;
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
container.addEventListener('touchstart', handleTouchStart, { passive: true });
|
|
104
|
-
container.addEventListener('touchmove', handleTouchMove, { passive: false });
|
|
105
|
-
container.addEventListener('touchend', handleTouchEnd, { passive: true });
|
|
106
|
-
|
|
107
|
-
return () => {
|
|
108
|
-
container.removeEventListener('wheel', handleWheel);
|
|
109
|
-
container.removeEventListener('touchstart', handleTouchStart);
|
|
110
|
-
container.removeEventListener('touchmove', handleTouchMove);
|
|
111
|
-
container.removeEventListener('touchend', handleTouchEnd);
|
|
112
|
-
};
|
|
113
|
-
}, [handleWheel, zoomLevel, setZoomLevel, containerRef]);
|
|
114
|
-
}
|
|
@@ -1,34 +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 } from 'react';
|
|
5
|
-
import { ZOOM_MIN, ZOOM_MAX } from '../utils/utils';
|
|
6
|
-
|
|
7
|
-
export function useZoomState(initialZoom = 1) {
|
|
8
|
-
const [zoomLevel, setZoomLevel] = useState(initialZoom);
|
|
9
|
-
|
|
10
|
-
const handleZoomChange = useCallback((newZoom: number) => {
|
|
11
|
-
setZoomLevel(Math.max(ZOOM_MIN, Math.min(ZOOM_MAX, newZoom)));
|
|
12
|
-
}, []);
|
|
13
|
-
|
|
14
|
-
const handleZoomIn = useCallback(() => {
|
|
15
|
-
handleZoomChange(zoomLevel + 0.2);
|
|
16
|
-
}, [zoomLevel, handleZoomChange]);
|
|
17
|
-
|
|
18
|
-
const handleZoomOut = useCallback(() => {
|
|
19
|
-
handleZoomChange(zoomLevel - 0.2);
|
|
20
|
-
}, [zoomLevel, handleZoomChange]);
|
|
21
|
-
|
|
22
|
-
const handleZoomSlider = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
|
23
|
-
handleZoomChange(parseFloat(e.target.value));
|
|
24
|
-
}, [handleZoomChange]);
|
|
25
|
-
|
|
26
|
-
return {
|
|
27
|
-
zoomLevel,
|
|
28
|
-
setZoomLevel,
|
|
29
|
-
handleZoomChange,
|
|
30
|
-
handleZoomIn,
|
|
31
|
-
handleZoomOut,
|
|
32
|
-
handleZoomSlider,
|
|
33
|
-
};
|
|
34
|
-
}
|
package/PivotViewer/index.ts
DELETED
|
@@ -1,7 +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 { PivotViewer } from './PivotViewer';
|
|
5
|
-
|
|
6
|
-
export { PivotViewer, PivotViewer as PivotViewerOptimized };
|
|
7
|
-
export type { PivotViewerProps, PivotDimension, PivotFilter, PivotFilterOption, PivotGroup, PivotPrimitive } from './types';
|
package/PivotViewer/types.ts
DELETED
|
@@ -1,59 +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 type { ReactNode } from 'react';
|
|
5
|
-
|
|
6
|
-
export type PivotPrimitive = string | number | boolean | Date | null | undefined;
|
|
7
|
-
|
|
8
|
-
export interface PivotGroup<TItem extends object> {
|
|
9
|
-
key: string;
|
|
10
|
-
label: string;
|
|
11
|
-
value: PivotPrimitive;
|
|
12
|
-
items: TItem[];
|
|
13
|
-
count?: number;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface PivotDimension<TItem extends object> {
|
|
17
|
-
key: string;
|
|
18
|
-
label: string;
|
|
19
|
-
getValue: (item: TItem) => PivotPrimitive;
|
|
20
|
-
formatValue?: (value: PivotPrimitive) => string;
|
|
21
|
-
sort?: (a: PivotGroup<TItem>, b: PivotGroup<TItem>) => number;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface PivotFilterOption {
|
|
25
|
-
key: string;
|
|
26
|
-
label: string;
|
|
27
|
-
value: PivotPrimitive;
|
|
28
|
-
count: number;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface PivotFilter<TItem extends object> {
|
|
32
|
-
key: string;
|
|
33
|
-
label: string;
|
|
34
|
-
getValue: (item: TItem) => PivotPrimitive;
|
|
35
|
-
multi?: boolean;
|
|
36
|
-
options?: PivotFilterOption[];
|
|
37
|
-
sort?: (a: PivotFilterOption, b: PivotFilterOption) => number;
|
|
38
|
-
/** For numeric filters, enables range picker with histogram */
|
|
39
|
-
type?: 'string' | 'number' | 'date';
|
|
40
|
-
/** Number of buckets for the histogram in range filters */
|
|
41
|
-
buckets?: number;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export interface PivotViewerProps<TItem extends object> {
|
|
45
|
-
data: TItem[];
|
|
46
|
-
dimensions: PivotDimension<TItem>[];
|
|
47
|
-
filters?: PivotFilter<TItem>[];
|
|
48
|
-
defaultDimensionKey?: string;
|
|
49
|
-
cardRenderer?: (item: TItem) => ReactNode;
|
|
50
|
-
getItemId?: (item: TItem, index: number) => string | number;
|
|
51
|
-
searchFields?: (keyof TItem)[];
|
|
52
|
-
className?: string;
|
|
53
|
-
emptyContent?: ReactNode;
|
|
54
|
-
isLoading?: boolean;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export type FilterState = Record<string, Set<string>>;
|
|
58
|
-
|
|
59
|
-
export type RangeFilterState = Record<string, [number, number] | null>;
|
|
@@ -1,249 +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
|
-
export type EasingFunction = (t: number) => number;
|
|
5
|
-
|
|
6
|
-
export const easeOutCubic: EasingFunction = (t: number) => 1 - Math.pow(1 - t, 3);
|
|
7
|
-
|
|
8
|
-
export interface ZoomAnimationParams {
|
|
9
|
-
startZoom: number;
|
|
10
|
-
targetZoom: number;
|
|
11
|
-
duration?: number;
|
|
12
|
-
easing?: EasingFunction;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface ScrollAnimationParams {
|
|
16
|
-
targetScrollLeft: number;
|
|
17
|
-
targetScrollTop: number;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface ZoomScrollAnimationParams extends ZoomAnimationParams, ScrollAnimationParams {
|
|
21
|
-
container: HTMLElement;
|
|
22
|
-
cardPosition?: { x: number; y: number; width: number; height: number } | null;
|
|
23
|
-
targetCardPosition?: { x: number; y: number; width: number; height: number } | null;
|
|
24
|
-
getCardPositionAtZoom?: (zoom: number) => { x: number; y: number; width: number; height: number } | null;
|
|
25
|
-
getLayoutSizeAtZoom?: (zoom: number) => { width: number; height: number };
|
|
26
|
-
spacer?: HTMLElement | null;
|
|
27
|
-
onUpdate: (zoom: number) => void;
|
|
28
|
-
onComplete?: () => void;
|
|
29
|
-
startScrollLeft?: number; // Optional explicit start scroll
|
|
30
|
-
startScrollTop?: number; // Optional explicit start scroll
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Animate zoom and scroll together, keeping a specific element centered
|
|
35
|
-
*/
|
|
36
|
-
export function animateZoomAndScroll({
|
|
37
|
-
container,
|
|
38
|
-
cardPosition,
|
|
39
|
-
targetCardPosition,
|
|
40
|
-
getCardPositionAtZoom,
|
|
41
|
-
getLayoutSizeAtZoom,
|
|
42
|
-
spacer,
|
|
43
|
-
startZoom,
|
|
44
|
-
targetZoom,
|
|
45
|
-
targetScrollLeft,
|
|
46
|
-
targetScrollTop,
|
|
47
|
-
duration = 300,
|
|
48
|
-
easing = easeOutCubic,
|
|
49
|
-
onUpdate,
|
|
50
|
-
onComplete,
|
|
51
|
-
startScrollLeft,
|
|
52
|
-
startScrollTop,
|
|
53
|
-
}: ZoomScrollAnimationParams): () => void {
|
|
54
|
-
container.style.scrollBehavior = 'auto';
|
|
55
|
-
|
|
56
|
-
let startTime: number | null = null;
|
|
57
|
-
let rafId: number | null = null;
|
|
58
|
-
|
|
59
|
-
// Capture start scroll if not provided
|
|
60
|
-
const initialScrollLeft = startScrollLeft ?? container.scrollLeft;
|
|
61
|
-
const initialScrollTop = startScrollTop ?? container.scrollTop;
|
|
62
|
-
|
|
63
|
-
// Calculate initial center point relative to viewport
|
|
64
|
-
const startCardCenterX = cardPosition ? (cardPosition.x * startZoom + (cardPosition.width * startZoom) / 2) : 0;
|
|
65
|
-
const startCardCenterY = cardPosition ? (cardPosition.y * startZoom + (cardPosition.height * startZoom) / 2) : 0;
|
|
66
|
-
|
|
67
|
-
const startCardScreenX = startCardCenterX - initialScrollLeft;
|
|
68
|
-
const startCardScreenY = startCardCenterY - initialScrollTop;
|
|
69
|
-
|
|
70
|
-
const animate = (timestamp: number) => {
|
|
71
|
-
if (startTime === null) {
|
|
72
|
-
startTime = timestamp;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const elapsed = timestamp - startTime;
|
|
76
|
-
const progress = Math.min(1, elapsed / duration);
|
|
77
|
-
const easedProgress = easing(progress);
|
|
78
|
-
|
|
79
|
-
const currentZoom = startZoom + (targetZoom - startZoom) * easedProgress;
|
|
80
|
-
|
|
81
|
-
// Update spacer size synchronously if possible
|
|
82
|
-
if (spacer && getLayoutSizeAtZoom) {
|
|
83
|
-
const size = getLayoutSizeAtZoom(currentZoom);
|
|
84
|
-
if (size) {
|
|
85
|
-
spacer.style.width = `${size.width * currentZoom}px`;
|
|
86
|
-
spacer.style.height = `${size.height * currentZoom}px`;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
onUpdate(currentZoom);
|
|
91
|
-
|
|
92
|
-
if (cardPosition) {
|
|
93
|
-
let currentCardX: number;
|
|
94
|
-
let currentCardY: number;
|
|
95
|
-
|
|
96
|
-
if (getCardPositionAtZoom) {
|
|
97
|
-
const pos = getCardPositionAtZoom(currentZoom);
|
|
98
|
-
if (pos) {
|
|
99
|
-
currentCardX = pos.x;
|
|
100
|
-
currentCardY = pos.y;
|
|
101
|
-
} else {
|
|
102
|
-
currentCardX = cardPosition.x;
|
|
103
|
-
currentCardY = cardPosition.y;
|
|
104
|
-
}
|
|
105
|
-
} else {
|
|
106
|
-
// Interpolate card position if target is provided (for layouts that change with zoom)
|
|
107
|
-
currentCardX = targetCardPosition
|
|
108
|
-
? cardPosition.x + (targetCardPosition.x - cardPosition.x) * easedProgress
|
|
109
|
-
: cardPosition.x;
|
|
110
|
-
currentCardY = targetCardPosition
|
|
111
|
-
? cardPosition.y + (targetCardPosition.y - cardPosition.y) * easedProgress
|
|
112
|
-
: cardPosition.y;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Calculate where the card center is at current zoom
|
|
116
|
-
const currentCardCenterX = currentCardX * currentZoom + (cardPosition.width * currentZoom) / 2;
|
|
117
|
-
const currentCardCenterY = currentCardY * currentZoom + (cardPosition.height * currentZoom) / 2;
|
|
118
|
-
|
|
119
|
-
// Calculate where the card center will be at the end of animation (relative to viewport)
|
|
120
|
-
// Target scroll position is where we want to end up
|
|
121
|
-
const endCardX = targetCardPosition ? targetCardPosition.x : cardPosition.x;
|
|
122
|
-
const endCardY = targetCardPosition ? targetCardPosition.y : cardPosition.y;
|
|
123
|
-
|
|
124
|
-
const endCardCenterX = endCardX * targetZoom + (cardPosition.width * targetZoom) / 2;
|
|
125
|
-
const endCardCenterY = endCardY * targetZoom + (cardPosition.height * targetZoom) / 2;
|
|
126
|
-
|
|
127
|
-
const endCardScreenX = endCardCenterX - targetScrollLeft;
|
|
128
|
-
const endCardScreenY = endCardCenterY - targetScrollTop;
|
|
129
|
-
|
|
130
|
-
// Interpolate the desired screen position
|
|
131
|
-
const desiredScreenX = startCardScreenX + (endCardScreenX - startCardScreenX) * easedProgress;
|
|
132
|
-
const desiredScreenY = startCardScreenY + (endCardScreenY - startCardScreenY) * easedProgress;
|
|
133
|
-
|
|
134
|
-
// Calculate needed scroll position to put card at desired screen position
|
|
135
|
-
const neededScrollLeft = currentCardCenterX - desiredScreenX;
|
|
136
|
-
const neededScrollTop = currentCardCenterY - desiredScreenY;
|
|
137
|
-
|
|
138
|
-
let maxScrollLeft = container.scrollWidth - container.clientWidth;
|
|
139
|
-
let maxScrollTop = container.scrollHeight - container.clientHeight;
|
|
140
|
-
|
|
141
|
-
// If we have explicit layout size, use it for clamping to avoid DOM sync issues
|
|
142
|
-
if (getLayoutSizeAtZoom) {
|
|
143
|
-
const size = getLayoutSizeAtZoom(currentZoom);
|
|
144
|
-
if (size) {
|
|
145
|
-
maxScrollLeft = Math.max(0, size.width * currentZoom - container.clientWidth);
|
|
146
|
-
maxScrollTop = Math.max(0, size.height * currentZoom - container.clientHeight);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// We can't clamp strictly during animation because the scrollWidth/Height might not have updated yet
|
|
151
|
-
// if the spacer hasn't resized. But usually spacer resizes immediately on zoom update.
|
|
152
|
-
// For safety, we just set it.
|
|
153
|
-
container.scrollLeft = Math.min(Math.max(0, neededScrollLeft), maxScrollLeft);
|
|
154
|
-
container.scrollTop = Math.min(Math.max(0, neededScrollTop), maxScrollTop);
|
|
155
|
-
} else {
|
|
156
|
-
// If no card position, just interpolate scroll position
|
|
157
|
-
// Use captured initial scroll positions for linear interpolation
|
|
158
|
-
const currentScrollLeft = initialScrollLeft + (targetScrollLeft - initialScrollLeft) * easedProgress;
|
|
159
|
-
const currentScrollTop = initialScrollTop + (targetScrollTop - initialScrollTop) * easedProgress;
|
|
160
|
-
|
|
161
|
-
container.scrollLeft = currentScrollLeft;
|
|
162
|
-
container.scrollTop = currentScrollTop;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (progress < 1) {
|
|
166
|
-
rafId = requestAnimationFrame(animate);
|
|
167
|
-
} else {
|
|
168
|
-
container.style.scrollBehavior = '';
|
|
169
|
-
container.scrollLeft = targetScrollLeft;
|
|
170
|
-
container.scrollTop = targetScrollTop;
|
|
171
|
-
onComplete?.();
|
|
172
|
-
}
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
rafId = requestAnimationFrame(animate);
|
|
176
|
-
|
|
177
|
-
return () => {
|
|
178
|
-
if (rafId !== null) {
|
|
179
|
-
cancelAnimationFrame(rafId);
|
|
180
|
-
container.style.scrollBehavior = '';
|
|
181
|
-
}
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Calculate scroll position to center a card in viewport, accounting for detail panel
|
|
187
|
-
*/
|
|
188
|
-
export function calculateCenterScrollPosition(
|
|
189
|
-
container: HTMLElement,
|
|
190
|
-
cardPosition: { x: number; y: number; width: number; height: number },
|
|
191
|
-
zoomLevel: number,
|
|
192
|
-
detailPanelWidth: number = 0,
|
|
193
|
-
totalHeight?: number
|
|
194
|
-
): { scrollLeft: number; scrollTop: number } {
|
|
195
|
-
const cardCenterX = cardPosition.x * zoomLevel + (cardPosition.width * zoomLevel) / 2;
|
|
196
|
-
const cardCenterY = cardPosition.y * zoomLevel + (cardPosition.height * zoomLevel) / 2;
|
|
197
|
-
|
|
198
|
-
const availableWidth = container.clientWidth - detailPanelWidth;
|
|
199
|
-
const targetX = availableWidth / 2;
|
|
200
|
-
const targetY = container.clientHeight / 2;
|
|
201
|
-
|
|
202
|
-
const scrollLeft = Math.max(0, cardCenterX - targetX);
|
|
203
|
-
let scrollTop = Math.max(0, cardCenterY - targetY);
|
|
204
|
-
|
|
205
|
-
console.log('[Animation] calculateCenterScrollPosition', {
|
|
206
|
-
cardY: cardPosition.y,
|
|
207
|
-
zoomLevel,
|
|
208
|
-
cardCenterY,
|
|
209
|
-
targetY,
|
|
210
|
-
initialScrollTop: scrollTop,
|
|
211
|
-
totalHeight,
|
|
212
|
-
containerHeight: container.clientHeight
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
// If totalHeight is provided, clamp to valid scroll range
|
|
216
|
-
if (totalHeight) {
|
|
217
|
-
const contentHeight = totalHeight * zoomLevel;
|
|
218
|
-
const viewportHeight = container.clientHeight;
|
|
219
|
-
const maxScrollTop = Math.max(0, contentHeight - viewportHeight);
|
|
220
|
-
|
|
221
|
-
console.log('[Animation] Clamping', {
|
|
222
|
-
contentHeight,
|
|
223
|
-
viewportHeight,
|
|
224
|
-
maxScrollTop,
|
|
225
|
-
currentScrollTop: scrollTop,
|
|
226
|
-
clamped: Math.min(scrollTop, maxScrollTop)
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
scrollTop = Math.min(scrollTop, maxScrollTop);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
return { scrollLeft, scrollTop };
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Smooth scroll to position
|
|
237
|
-
*/
|
|
238
|
-
export function smoothScrollTo(
|
|
239
|
-
container: HTMLElement,
|
|
240
|
-
scrollLeft: number,
|
|
241
|
-
scrollTop: number,
|
|
242
|
-
smooth: boolean = true
|
|
243
|
-
): void {
|
|
244
|
-
container.scrollTo({
|
|
245
|
-
left: scrollLeft,
|
|
246
|
-
top: scrollTop,
|
|
247
|
-
behavior: smooth ? 'smooth' : 'auto',
|
|
248
|
-
});
|
|
249
|
-
}
|
|
@@ -1,20 +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
|
-
// Zoom constants
|
|
5
|
-
export const ZOOM_MIN = 0.1;
|
|
6
|
-
export const ZOOM_MAX = 3;
|
|
7
|
-
export const ZOOM_STEP = 0.05;
|
|
8
|
-
|
|
9
|
-
// Layout constants
|
|
10
|
-
export const GROUP_SPACING = 40;
|
|
11
|
-
export const CARD_GAP = 8;
|
|
12
|
-
export const CARDS_PER_COLUMN = 5;
|
|
13
|
-
export const BASE_CARD_WIDTH = 180;
|
|
14
|
-
export const BASE_CARD_HEIGHT = 140;
|
|
15
|
-
export const DETAIL_PANEL_WIDTH = 380;
|
|
16
|
-
|
|
17
|
-
// Animation constants
|
|
18
|
-
export const ZOOM_ANIMATION_DURATION = 300;
|
|
19
|
-
export const ZOOM_MULTIPLIER = 1.15;
|
|
20
|
-
export const MIN_ZOOM_ON_SELECT = 1.2;
|