react-native-metrify 0.1.0-alpha.1 → 0.1.0-alpha.2
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/package.json +1 -2
- package/src/core/animation/index.ts +0 -113
- package/src/core/animation/index.web.ts +0 -112
- package/src/core/hooks/index.ts +0 -66
- package/src/core/index.ts +0 -26
- package/src/core/layout/index.ts +0 -101
- package/src/core/math/index.ts +0 -72
- package/src/core/package.json +0 -13
- package/src/core/theme/ThemeProvider.tsx +0 -36
- package/src/core/theme/index.ts +0 -5
- package/src/core/theme/themes.ts +0 -132
- package/src/core/types/index.ts +0 -164
- package/src/core/utils/responsive.ts +0 -203
- package/src/core/utils/time.ts +0 -100
- package/src/index.ts +0 -13
- package/src/renderer-svg/adapters/index.ts +0 -84
- package/src/renderer-svg/index.ts +0 -8
- package/src/renderer-svg/package.json +0 -17
- package/src/renderer-svg/paths/arc.ts +0 -93
- package/src/renderer-svg/paths/index.ts +0 -6
- package/src/renderer-svg/paths/line.ts +0 -83
- package/src/renderer-svg/paths/rect.ts +0 -80
- package/src/renderer-svg/primitives/AnimatedCircle.tsx +0 -48
- package/src/renderer-svg/primitives/AnimatedPath.tsx +0 -48
- package/src/renderer-svg/primitives/Text.tsx +0 -73
- package/src/renderer-svg/primitives/index.ts +0 -6
- package/src/widgets/AreaChart/AreaChart.tsx +0 -213
- package/src/widgets/AreaChart/index.ts +0 -2
- package/src/widgets/AreaChart/types.ts +0 -34
- package/src/widgets/BarChart/BarChart.tsx +0 -249
- package/src/widgets/BarChart/index.ts +0 -10
- package/src/widgets/BarChart/types.ts +0 -27
- package/src/widgets/BoxPlot/BoxPlot.tsx +0 -252
- package/src/widgets/BoxPlot/index.ts +0 -2
- package/src/widgets/BoxPlot/types.ts +0 -27
- package/src/widgets/BubbleChart/BubbleChart.tsx +0 -175
- package/src/widgets/BubbleChart/index.ts +0 -2
- package/src/widgets/BubbleChart/types.ts +0 -33
- package/src/widgets/CandlestickChart/CandlestickChart.tsx +0 -204
- package/src/widgets/CandlestickChart/index.ts +0 -2
- package/src/widgets/CandlestickChart/types.ts +0 -29
- package/src/widgets/FunnelChart/FunnelChart.tsx +0 -172
- package/src/widgets/FunnelChart/index.ts +0 -2
- package/src/widgets/FunnelChart/types.ts +0 -22
- package/src/widgets/Gauge/Gauge.tsx +0 -235
- package/src/widgets/Gauge/index.ts +0 -5
- package/src/widgets/Gauge/types.ts +0 -19
- package/src/widgets/GroupedBarChart/GroupedBarChart.tsx +0 -190
- package/src/widgets/GroupedBarChart/index.ts +0 -2
- package/src/widgets/GroupedBarChart/types.ts +0 -30
- package/src/widgets/Heatmap/Heatmap.tsx +0 -216
- package/src/widgets/Heatmap/index.ts +0 -2
- package/src/widgets/Heatmap/types.ts +0 -27
- package/src/widgets/Histogram/Histogram.tsx +0 -173
- package/src/widgets/Histogram/index.ts +0 -2
- package/src/widgets/Histogram/types.ts +0 -18
- package/src/widgets/HorizontalBarChart/HorizontalBarChart.tsx +0 -125
- package/src/widgets/HorizontalBarChart/index.ts +0 -2
- package/src/widgets/HorizontalBarChart/types.ts +0 -23
- package/src/widgets/KPI/KPI.tsx +0 -222
- package/src/widgets/KPI/index.ts +0 -5
- package/src/widgets/KPI/types.ts +0 -19
- package/src/widgets/LineChart/LineChart.tsx +0 -364
- package/src/widgets/LineChart/index.ts +0 -10
- package/src/widgets/LineChart/types.ts +0 -34
- package/src/widgets/MultiLineSparkline/MultiLineSparkline.tsx +0 -234
- package/src/widgets/MultiLineSparkline/index.ts +0 -10
- package/src/widgets/MultiLineSparkline/types.ts +0 -25
- package/src/widgets/PieChart/PieChart.tsx +0 -275
- package/src/widgets/PieChart/index.ts +0 -10
- package/src/widgets/PieChart/types.ts +0 -26
- package/src/widgets/Progress/Progress.tsx +0 -201
- package/src/widgets/Progress/index.ts +0 -5
- package/src/widgets/Progress/types.ts +0 -19
- package/src/widgets/RadarChart/RadarChart.tsx +0 -213
- package/src/widgets/RadarChart/index.ts +0 -2
- package/src/widgets/RadarChart/types.ts +0 -29
- package/src/widgets/SankeyDiagram/SankeyDiagram.tsx +0 -272
- package/src/widgets/SankeyDiagram/index.ts +0 -2
- package/src/widgets/SankeyDiagram/types.ts +0 -29
- package/src/widgets/ScatterPlot/ScatterPlot.tsx +0 -167
- package/src/widgets/ScatterPlot/index.ts +0 -2
- package/src/widgets/ScatterPlot/types.ts +0 -32
- package/src/widgets/Sparkline/Sparkline.tsx +0 -203
- package/src/widgets/Sparkline/index.ts +0 -5
- package/src/widgets/Sparkline/types.ts +0 -18
- package/src/widgets/StackedBarChart/StackedBarChart.tsx +0 -181
- package/src/widgets/StackedBarChart/index.ts +0 -2
- package/src/widgets/StackedBarChart/types.ts +0 -29
- package/src/widgets/SunburstChart/SunburstChart.tsx +0 -176
- package/src/widgets/SunburstChart/index.ts +0 -2
- package/src/widgets/SunburstChart/types.ts +0 -22
- package/src/widgets/Treemap/Treemap.tsx +0 -191
- package/src/widgets/Treemap/index.ts +0 -2
- package/src/widgets/Treemap/types.ts +0 -23
- package/src/widgets/WaterfallChart/WaterfallChart.tsx +0 -226
- package/src/widgets/WaterfallChart/index.ts +0 -2
- package/src/widgets/WaterfallChart/types.ts +0 -26
- package/src/widgets/index.ts +0 -40
- package/src/widgets/package.json +0 -18
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-metrify",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.2",
|
|
4
4
|
"description": "Mobile-first SVG chart library for React Native, Expo, and React Native Web",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
16
|
"dist",
|
|
17
|
-
"src",
|
|
18
17
|
"README.md",
|
|
19
18
|
"LICENSE",
|
|
20
19
|
"CHANGELOG.md"
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Animation helpers - Simple version without reanimated
|
|
3
|
-
* For full animation support, use react-native-reanimated separately
|
|
4
|
-
*/
|
|
5
|
-
import { useEffect } from 'react';
|
|
6
|
-
import { AnimationConfig } from '../types';
|
|
7
|
-
|
|
8
|
-
// Type for shared value (compatible with reanimated)
|
|
9
|
-
export type SharedValue<T = number> = { value: T };
|
|
10
|
-
|
|
11
|
-
// Simple implementations (no animations, just values)
|
|
12
|
-
export const useSharedValue = <T = number>(initialValue: T): SharedValue<T> => {
|
|
13
|
-
return { value: initialValue };
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export const withTiming = (value: any, config?: any) => value;
|
|
17
|
-
export const withSpring = (value: any, config?: any) => value;
|
|
18
|
-
|
|
19
|
-
export const Easing = {
|
|
20
|
-
linear: (t: number) => t,
|
|
21
|
-
ease: (t: number) => t,
|
|
22
|
-
quad: (t: number) => t * t,
|
|
23
|
-
cubic: (t: number) => t * t * t,
|
|
24
|
-
bezier: (x1: number, y1: number, x2: number, y2: number) => (t: number) => t,
|
|
25
|
-
in: (easing: (t: number) => number) => easing,
|
|
26
|
-
out: (easing: (t: number) => number) => (t: number) => 1 - easing(1 - t),
|
|
27
|
-
inOut: (easing: (t: number) => number) => (t: number) =>
|
|
28
|
-
t < 0.5 ? easing(t * 2) / 2 : 1 - easing((1 - t) * 2) / 2,
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Default timing configuration
|
|
33
|
-
*/
|
|
34
|
-
export const DEFAULT_TIMING_CONFIG = {
|
|
35
|
-
duration: 300,
|
|
36
|
-
easing: Easing.out(Easing.cubic),
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Default spring configuration
|
|
41
|
-
*/
|
|
42
|
-
export const DEFAULT_SPRING_CONFIG = {
|
|
43
|
-
damping: 15,
|
|
44
|
-
stiffness: 150,
|
|
45
|
-
mass: 1,
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Hook that creates an animated value that transitions to a target
|
|
50
|
-
* @param target - Target value to animate to
|
|
51
|
-
* @param config - Animation configuration
|
|
52
|
-
*/
|
|
53
|
-
export function useAnimatedValue(
|
|
54
|
-
target: number,
|
|
55
|
-
config: AnimationConfig = {}
|
|
56
|
-
): SharedValue<number> {
|
|
57
|
-
const animatedValue = useSharedValue(target);
|
|
58
|
-
|
|
59
|
-
useEffect(() => {
|
|
60
|
-
animatedValue.value = withTiming(target, {
|
|
61
|
-
duration: config.duration ?? DEFAULT_TIMING_CONFIG.duration,
|
|
62
|
-
easing: DEFAULT_TIMING_CONFIG.easing,
|
|
63
|
-
});
|
|
64
|
-
}, [target, config.duration, animatedValue]);
|
|
65
|
-
|
|
66
|
-
return animatedValue;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Hook that creates an animated progress value (0 to normalized)
|
|
71
|
-
* @param value - Current value
|
|
72
|
-
* @param max - Maximum value
|
|
73
|
-
* @param config - Animation configuration
|
|
74
|
-
*/
|
|
75
|
-
export function useAnimatedProgress(
|
|
76
|
-
value: number,
|
|
77
|
-
max: number,
|
|
78
|
-
config: AnimationConfig = {}
|
|
79
|
-
): SharedValue<number> {
|
|
80
|
-
const normalized = max > 0 ? Math.min(value / max, 1) : 0;
|
|
81
|
-
return useAnimatedValue(normalized, config);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Hook that creates a spring-animated value
|
|
86
|
-
* @param target - Target value to animate to
|
|
87
|
-
*/
|
|
88
|
-
export function useSpringValue(target: number): SharedValue<number> {
|
|
89
|
-
const animatedValue = useSharedValue(target);
|
|
90
|
-
|
|
91
|
-
useEffect(() => {
|
|
92
|
-
animatedValue.value = withSpring(target, DEFAULT_SPRING_CONFIG);
|
|
93
|
-
}, [target, animatedValue]);
|
|
94
|
-
|
|
95
|
-
return animatedValue;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Creates timing config for manual animations
|
|
100
|
-
*/
|
|
101
|
-
export function useTimingConfig(config: AnimationConfig = {}) {
|
|
102
|
-
return {
|
|
103
|
-
duration: config.duration ?? DEFAULT_TIMING_CONFIG.duration,
|
|
104
|
-
easing: DEFAULT_TIMING_CONFIG.easing,
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Creates spring config for manual animations
|
|
110
|
-
*/
|
|
111
|
-
export function useSpringConfig() {
|
|
112
|
-
return DEFAULT_SPRING_CONFIG;
|
|
113
|
-
}
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Animation helpers for widgets (Web version - no reanimated)
|
|
3
|
-
* Uses basic React state for web compatibility
|
|
4
|
-
*/
|
|
5
|
-
import { useEffect } from 'react';
|
|
6
|
-
import { AnimationConfig } from '../types';
|
|
7
|
-
|
|
8
|
-
// Type for shared value (web compatible)
|
|
9
|
-
export type SharedValue<T> = { value: T };
|
|
10
|
-
|
|
11
|
-
// Web-compatible stubs for reanimated functions
|
|
12
|
-
export const useSharedValue = <T,>(initialValue: T): SharedValue<T> => {
|
|
13
|
-
return { value: initialValue };
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export const withTiming = (value: number, config?: any) => {
|
|
17
|
-
return value;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export const withSpring = (value: number, config?: any) => {
|
|
21
|
-
return value;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export const withDelay = (delay: number, animation: any) => {
|
|
25
|
-
return animation;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export const withSequence = (...animations: any[]) => {
|
|
29
|
-
return animations[animations.length - 1];
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export const withRepeat = (animation: any, numberOfReps?: number, reverse?: boolean) => {
|
|
33
|
-
return animation;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export const Easing = {
|
|
37
|
-
linear: (t: number) => t,
|
|
38
|
-
ease: (t: number) => t,
|
|
39
|
-
quad: (t: number) => t * t,
|
|
40
|
-
cubic: (t: number) => t * t * t,
|
|
41
|
-
bezier: (x1: number, y1: number, x2: number, y2: number) => (t: number) => t,
|
|
42
|
-
in: (easing: (t: number) => number) => easing,
|
|
43
|
-
out: (easing: (t: number) => number) => (t: number) => 1 - easing(1 - t),
|
|
44
|
-
inOut: (easing: (t: number) => number) => (t: number) =>
|
|
45
|
-
t < 0.5 ? easing(t * 2) / 2 : 1 - easing((1 - t) * 2) / 2,
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Default timing configuration
|
|
50
|
-
*/
|
|
51
|
-
export const DEFAULT_TIMING_CONFIG = {
|
|
52
|
-
duration: 300,
|
|
53
|
-
easing: Easing.linear,
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Default spring configuration
|
|
58
|
-
*/
|
|
59
|
-
export const DEFAULT_SPRING_CONFIG = {
|
|
60
|
-
damping: 15,
|
|
61
|
-
stiffness: 150,
|
|
62
|
-
mass: 1,
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Hook to animate value changes (web version)
|
|
67
|
-
*/
|
|
68
|
-
export function useAnimatedValue(
|
|
69
|
-
target: number,
|
|
70
|
-
config: AnimationConfig = {}
|
|
71
|
-
): SharedValue<number> {
|
|
72
|
-
// On web, just return the value directly
|
|
73
|
-
// Full animation support requires additional setup
|
|
74
|
-
return useSharedValue(target);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Hook that creates an animated progress value (0 to normalized)
|
|
79
|
-
*/
|
|
80
|
-
export function useAnimatedProgress(
|
|
81
|
-
value: number,
|
|
82
|
-
max: number,
|
|
83
|
-
config: AnimationConfig = {}
|
|
84
|
-
): SharedValue<number> {
|
|
85
|
-
const normalized = max > 0 ? Math.min(value / max, 1) : 0;
|
|
86
|
-
return useAnimatedValue(normalized, config);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Hook that creates a spring-animated value
|
|
91
|
-
*/
|
|
92
|
-
export function useSpringValue(target: number): SharedValue<number> {
|
|
93
|
-
return useSharedValue(target);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Creates timing config for manual animations
|
|
98
|
-
*/
|
|
99
|
-
export function useTimingConfig(config: AnimationConfig = {}) {
|
|
100
|
-
return {
|
|
101
|
-
duration: config.duration ?? DEFAULT_TIMING_CONFIG.duration,
|
|
102
|
-
easing: DEFAULT_TIMING_CONFIG.easing,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Creates spring config for manual animations
|
|
108
|
-
*/
|
|
109
|
-
export function useSpringConfig() {
|
|
110
|
-
return DEFAULT_SPRING_CONFIG;
|
|
111
|
-
}
|
|
112
|
-
|
package/src/core/hooks/index.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Reusable hooks for widgets
|
|
3
|
-
*/
|
|
4
|
-
import { useMemo } from 'react';
|
|
5
|
-
import { Theme } from '../types';
|
|
6
|
-
import { useTheme } from '../theme';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Hook to get widget dimensions with defaults
|
|
10
|
-
*/
|
|
11
|
-
export function useWidgetDimensions(
|
|
12
|
-
width?: number,
|
|
13
|
-
height?: number,
|
|
14
|
-
defaultWidth: number = 300,
|
|
15
|
-
defaultHeight: number = 200
|
|
16
|
-
) {
|
|
17
|
-
return useMemo(
|
|
18
|
-
() => ({
|
|
19
|
-
width: width ?? defaultWidth,
|
|
20
|
-
height: height ?? defaultHeight,
|
|
21
|
-
}),
|
|
22
|
-
[width, height, defaultWidth, defaultHeight]
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Hook to merge theme overrides
|
|
28
|
-
*/
|
|
29
|
-
export function useWidgetTheme(themeOverride?: Theme): Theme {
|
|
30
|
-
const contextTheme = useTheme();
|
|
31
|
-
return themeOverride ?? contextTheme;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Hook for widget padding calculations
|
|
36
|
-
*/
|
|
37
|
-
export function useWidgetPadding(theme: Theme) {
|
|
38
|
-
return useMemo(
|
|
39
|
-
() => ({
|
|
40
|
-
top: theme.spacing.md,
|
|
41
|
-
right: theme.spacing.md,
|
|
42
|
-
bottom: theme.spacing.md,
|
|
43
|
-
left: theme.spacing.md,
|
|
44
|
-
horizontal: theme.spacing.md * 2,
|
|
45
|
-
vertical: theme.spacing.md * 2,
|
|
46
|
-
}),
|
|
47
|
-
[theme.spacing.md]
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Hook to calculate inner dimensions after padding
|
|
53
|
-
*/
|
|
54
|
-
export function useInnerDimensions(
|
|
55
|
-
width: number,
|
|
56
|
-
height: number,
|
|
57
|
-
padding: { horizontal: number; vertical: number }
|
|
58
|
-
) {
|
|
59
|
-
return useMemo(
|
|
60
|
-
() => ({
|
|
61
|
-
width: Math.max(0, width - padding.horizontal),
|
|
62
|
-
height: Math.max(0, height - padding.vertical),
|
|
63
|
-
}),
|
|
64
|
-
[width, height, padding.horizontal, padding.vertical]
|
|
65
|
-
);
|
|
66
|
-
}
|
package/src/core/index.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Core package - Foundation for all widgets
|
|
3
|
-
* NO SVG dependencies allowed here
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// Math utilities
|
|
7
|
-
export * from './math';
|
|
8
|
-
|
|
9
|
-
// Layout utilities
|
|
10
|
-
export * from './layout';
|
|
11
|
-
|
|
12
|
-
// Theme system
|
|
13
|
-
export * from './theme';
|
|
14
|
-
|
|
15
|
-
// Animation helpers
|
|
16
|
-
export * from './animation';
|
|
17
|
-
|
|
18
|
-
// Hooks
|
|
19
|
-
export * from './hooks';
|
|
20
|
-
|
|
21
|
-
// Types
|
|
22
|
-
export * from './types';
|
|
23
|
-
|
|
24
|
-
// Utils
|
|
25
|
-
export * from './utils/time';
|
|
26
|
-
export * from './utils/responsive';
|
package/src/core/layout/index.ts
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Layout utilities for widget positioning and sizing
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export interface Box {
|
|
6
|
-
x: number;
|
|
7
|
-
y: number;
|
|
8
|
-
width: number;
|
|
9
|
-
height: number;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface Point {
|
|
13
|
-
x: number;
|
|
14
|
-
y: number;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Calculate center point of a box
|
|
19
|
-
*/
|
|
20
|
-
export function getCenter(box: Box): Point {
|
|
21
|
-
return {
|
|
22
|
-
x: box.x + box.width / 2,
|
|
23
|
-
y: box.y + box.height / 2,
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Calculate bounding box for a set of points
|
|
29
|
-
*/
|
|
30
|
-
export function getBoundingBox(points: Point[]): Box {
|
|
31
|
-
if (points.length === 0) {
|
|
32
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const xs = points.map(p => p.x);
|
|
36
|
-
const ys = points.map(p => p.y);
|
|
37
|
-
|
|
38
|
-
const minX = Math.min(...xs);
|
|
39
|
-
const maxX = Math.max(...xs);
|
|
40
|
-
const minY = Math.min(...ys);
|
|
41
|
-
const maxY = Math.max(...ys);
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
x: minX,
|
|
45
|
-
y: minY,
|
|
46
|
-
width: maxX - minX,
|
|
47
|
-
height: maxY - minY,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Apply padding to a box
|
|
53
|
-
*/
|
|
54
|
-
export function applyPadding(
|
|
55
|
-
box: Box,
|
|
56
|
-
padding: { top: number; right: number; bottom: number; left: number }
|
|
57
|
-
): Box {
|
|
58
|
-
return {
|
|
59
|
-
x: box.x + padding.left,
|
|
60
|
-
y: box.y + padding.top,
|
|
61
|
-
width: Math.max(0, box.width - padding.left - padding.right),
|
|
62
|
-
height: Math.max(0, box.height - padding.top - padding.bottom),
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Calculate aspect ratio
|
|
68
|
-
*/
|
|
69
|
-
export function getAspectRatio(width: number, height: number): number {
|
|
70
|
-
return height > 0 ? width / height : 1;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Scale box to fit within constraints while maintaining aspect ratio
|
|
75
|
-
*/
|
|
76
|
-
export function fitBox(
|
|
77
|
-
box: Box,
|
|
78
|
-
maxWidth: number,
|
|
79
|
-
maxHeight: number
|
|
80
|
-
): Box {
|
|
81
|
-
const aspectRatio = getAspectRatio(box.width, box.height);
|
|
82
|
-
const maxAspectRatio = getAspectRatio(maxWidth, maxHeight);
|
|
83
|
-
|
|
84
|
-
let width = maxWidth;
|
|
85
|
-
let height = maxHeight;
|
|
86
|
-
|
|
87
|
-
if (aspectRatio > maxAspectRatio) {
|
|
88
|
-
// Box is wider than container
|
|
89
|
-
height = width / aspectRatio;
|
|
90
|
-
} else {
|
|
91
|
-
// Box is taller than container
|
|
92
|
-
width = height * aspectRatio;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
x: box.x,
|
|
97
|
-
y: box.y,
|
|
98
|
-
width,
|
|
99
|
-
height,
|
|
100
|
-
};
|
|
101
|
-
}
|
package/src/core/math/index.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Core math utilities for dashboard widgets
|
|
3
|
-
* Pure functions only - no side effects, no dependencies
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Clamps a value between min and max
|
|
8
|
-
*/
|
|
9
|
-
export function clamp(value: number, min: number, max: number): number {
|
|
10
|
-
return Math.min(Math.max(value, min), max);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Normalizes a value from [min, max] to [0, 1]
|
|
15
|
-
*/
|
|
16
|
-
export function normalize(value: number, min: number, max: number): number {
|
|
17
|
-
if (max === min) return 0;
|
|
18
|
-
return clamp((value - min) / (max - min), 0, 1);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Interpolates a value from one range to another
|
|
23
|
-
* @example interpolate(5, [0, 10], [0, 100]) // 50
|
|
24
|
-
*/
|
|
25
|
-
export function interpolate(
|
|
26
|
-
value: number,
|
|
27
|
-
inRange: [number, number],
|
|
28
|
-
outRange: [number, number]
|
|
29
|
-
): number {
|
|
30
|
-
const normalized = normalize(value, inRange[0], inRange[1]);
|
|
31
|
-
return outRange[0] + normalized * (outRange[1] - outRange[0]);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Converts polar coordinates to cartesian
|
|
36
|
-
* @param cx - Center X
|
|
37
|
-
* @param cy - Center Y
|
|
38
|
-
* @param r - Radius
|
|
39
|
-
* @param angle - Angle in degrees
|
|
40
|
-
*/
|
|
41
|
-
export function polarToCartesian(
|
|
42
|
-
cx: number,
|
|
43
|
-
cy: number,
|
|
44
|
-
r: number,
|
|
45
|
-
angle: number
|
|
46
|
-
): { x: number; y: number } {
|
|
47
|
-
const angleInRadians = ((angle - 90) * Math.PI) / 180;
|
|
48
|
-
return {
|
|
49
|
-
x: cx + r * Math.cos(angleInRadians),
|
|
50
|
-
y: cy + r * Math.sin(angleInRadians),
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Rounds a number to a specified number of decimal places
|
|
56
|
-
*/
|
|
57
|
-
export function roundTo(value: number, decimals: number = 2): number {
|
|
58
|
-
const multiplier = Math.pow(10, decimals);
|
|
59
|
-
return Math.round(value * multiplier) / multiplier;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Calculates the distance between two points
|
|
64
|
-
*/
|
|
65
|
-
export function distance(
|
|
66
|
-
x1: number,
|
|
67
|
-
y1: number,
|
|
68
|
-
x2: number,
|
|
69
|
-
y2: number
|
|
70
|
-
): number {
|
|
71
|
-
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
|
|
72
|
-
}
|
package/src/core/package.json
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@dashboard-widgets/core",
|
|
3
|
-
"version": "0.1.0",
|
|
4
|
-
"description": "Core utilities for dashboard widgets - math, theme, animation, layout",
|
|
5
|
-
"main": "index.ts",
|
|
6
|
-
"types": "index.ts",
|
|
7
|
-
"private": true,
|
|
8
|
-
"peerDependencies": {
|
|
9
|
-
"react": ">=18.0.0",
|
|
10
|
-
"react-native": ">=0.70.0",
|
|
11
|
-
"react-native-reanimated": ">=3.0.0"
|
|
12
|
-
}
|
|
13
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Theme provider and context
|
|
3
|
-
*/
|
|
4
|
-
import React, { createContext, useContext, ReactNode } from 'react';
|
|
5
|
-
import { Theme } from '../types';
|
|
6
|
-
import { DefaultTheme } from './themes';
|
|
7
|
-
|
|
8
|
-
const ThemeContext = createContext<Theme>(DefaultTheme);
|
|
9
|
-
|
|
10
|
-
export interface ThemeProviderProps {
|
|
11
|
-
theme?: Theme;
|
|
12
|
-
children: ReactNode;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Theme provider component
|
|
17
|
-
* Wraps the app and provides theme to all widgets
|
|
18
|
-
*/
|
|
19
|
-
export function ThemeProvider({ theme = DefaultTheme, children }: ThemeProviderProps) {
|
|
20
|
-
return (
|
|
21
|
-
<ThemeContext.Provider value={theme}>
|
|
22
|
-
{children}
|
|
23
|
-
</ThemeContext.Provider>
|
|
24
|
-
);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Hook to access the current theme
|
|
29
|
-
*/
|
|
30
|
-
export function useTheme(): Theme {
|
|
31
|
-
const theme = useContext(ThemeContext);
|
|
32
|
-
if (!theme) {
|
|
33
|
-
throw new Error('useTheme must be used within a ThemeProvider');
|
|
34
|
-
}
|
|
35
|
-
return theme;
|
|
36
|
-
}
|
package/src/core/theme/index.ts
DELETED
package/src/core/theme/themes.ts
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Default theme definitions
|
|
3
|
-
*/
|
|
4
|
-
import { Theme } from '../types';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Default light theme
|
|
8
|
-
*/
|
|
9
|
-
export const DefaultTheme: Theme = {
|
|
10
|
-
colors: {
|
|
11
|
-
// Primary colors
|
|
12
|
-
primary: '#3B82F6',
|
|
13
|
-
secondary: '#8B5CF6',
|
|
14
|
-
accent: '#EC4899',
|
|
15
|
-
|
|
16
|
-
// Semantic colors
|
|
17
|
-
success: '#10B981',
|
|
18
|
-
warning: '#F59E0B',
|
|
19
|
-
error: '#EF4444',
|
|
20
|
-
info: '#3B82F6',
|
|
21
|
-
|
|
22
|
-
// Background colors
|
|
23
|
-
background: '#FFFFFF',
|
|
24
|
-
surface: '#F9FAFB',
|
|
25
|
-
overlay: 'rgba(0, 0, 0, 0.5)',
|
|
26
|
-
|
|
27
|
-
// Text colors
|
|
28
|
-
text: '#111827',
|
|
29
|
-
textSecondary: '#6B7280',
|
|
30
|
-
textDisabled: '#D1D5DB',
|
|
31
|
-
|
|
32
|
-
// Border colors
|
|
33
|
-
border: '#E5E7EB',
|
|
34
|
-
borderLight: '#F3F4F6',
|
|
35
|
-
|
|
36
|
-
// Chart colors
|
|
37
|
-
chartPrimary: '#3B82F6',
|
|
38
|
-
chartSecondary: '#8B5CF6',
|
|
39
|
-
chartTertiary: '#EC4899',
|
|
40
|
-
chartQuaternary: '#F59E0B',
|
|
41
|
-
chartPositive: '#10B981',
|
|
42
|
-
chartNegative: '#EF4444',
|
|
43
|
-
chartNeutral: '#6B7280',
|
|
44
|
-
},
|
|
45
|
-
spacing: {
|
|
46
|
-
xs: 4,
|
|
47
|
-
sm: 8,
|
|
48
|
-
md: 16,
|
|
49
|
-
lg: 24,
|
|
50
|
-
xl: 32,
|
|
51
|
-
xxl: 48,
|
|
52
|
-
},
|
|
53
|
-
radius: {
|
|
54
|
-
none: 0,
|
|
55
|
-
sm: 4,
|
|
56
|
-
md: 8,
|
|
57
|
-
lg: 12,
|
|
58
|
-
full: 9999,
|
|
59
|
-
},
|
|
60
|
-
fontScale: {
|
|
61
|
-
xs: 10,
|
|
62
|
-
sm: 12,
|
|
63
|
-
md: 14,
|
|
64
|
-
lg: 18,
|
|
65
|
-
xl: 24,
|
|
66
|
-
xxl: 32,
|
|
67
|
-
},
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Dark theme
|
|
72
|
-
*/
|
|
73
|
-
export const DarkTheme: Theme = {
|
|
74
|
-
colors: {
|
|
75
|
-
// Primary colors
|
|
76
|
-
primary: '#60A5FA',
|
|
77
|
-
secondary: '#A78BFA',
|
|
78
|
-
accent: '#F472B6',
|
|
79
|
-
|
|
80
|
-
// Semantic colors
|
|
81
|
-
success: '#34D399',
|
|
82
|
-
warning: '#FBBF24',
|
|
83
|
-
error: '#F87171',
|
|
84
|
-
info: '#60A5FA',
|
|
85
|
-
|
|
86
|
-
// Background colors
|
|
87
|
-
background: '#111827',
|
|
88
|
-
surface: '#1F2937',
|
|
89
|
-
overlay: 'rgba(0, 0, 0, 0.7)',
|
|
90
|
-
|
|
91
|
-
// Text colors
|
|
92
|
-
text: '#F9FAFB',
|
|
93
|
-
textSecondary: '#D1D5DB',
|
|
94
|
-
textDisabled: '#6B7280',
|
|
95
|
-
|
|
96
|
-
// Border colors
|
|
97
|
-
border: '#374151',
|
|
98
|
-
borderLight: '#4B5563',
|
|
99
|
-
|
|
100
|
-
// Chart colors
|
|
101
|
-
chartPrimary: '#60A5FA',
|
|
102
|
-
chartSecondary: '#A78BFA',
|
|
103
|
-
chartTertiary: '#F472B6',
|
|
104
|
-
chartQuaternary: '#FBBF24',
|
|
105
|
-
chartPositive: '#34D399',
|
|
106
|
-
chartNegative: '#F87171',
|
|
107
|
-
chartNeutral: '#9CA3AF',
|
|
108
|
-
},
|
|
109
|
-
spacing: {
|
|
110
|
-
xs: 4,
|
|
111
|
-
sm: 8,
|
|
112
|
-
md: 16,
|
|
113
|
-
lg: 24,
|
|
114
|
-
xl: 32,
|
|
115
|
-
xxl: 48,
|
|
116
|
-
},
|
|
117
|
-
radius: {
|
|
118
|
-
none: 0,
|
|
119
|
-
sm: 4,
|
|
120
|
-
md: 8,
|
|
121
|
-
lg: 12,
|
|
122
|
-
full: 9999,
|
|
123
|
-
},
|
|
124
|
-
fontScale: {
|
|
125
|
-
xs: 10,
|
|
126
|
-
sm: 12,
|
|
127
|
-
md: 14,
|
|
128
|
-
lg: 18,
|
|
129
|
-
xl: 24,
|
|
130
|
-
xxl: 32,
|
|
131
|
-
},
|
|
132
|
-
};
|