@hero-design/rn 8.99.4 → 8.100.0
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/.turbo/turbo-build.log +8 -3
- package/CHANGELOG.md +17 -0
- package/es/index.js +5621 -690
- package/jest.config.js +1 -1
- package/lib/index.js +5545 -613
- package/package.json +4 -2
- package/src/components/Avatar/AvatarStack/utils.ts +6 -4
- package/src/components/Badge/Status.tsx +1 -1
- package/src/components/Badge/__tests__/Status.spec.tsx +20 -0
- package/src/components/Badge/__tests__/__snapshots__/Status.spec.tsx.snap +2 -0
- package/src/components/Chart/ChartSelect/StyledChartSelect.tsx +9 -0
- package/src/components/Chart/ChartSelect/__tests__/StyledChartSelect.spec.tsx +15 -0
- package/src/components/Chart/ChartSelect/__tests__/__snapshots__/StyledChartSelect.spec.tsx.snap +20 -0
- package/src/components/Chart/ChartSelect/__tests__/index.spec.tsx +111 -0
- package/src/components/Chart/ChartSelect/index.tsx +137 -0
- package/src/components/Chart/ColumnChart/ColumnChartContent.tsx +84 -0
- package/src/components/Chart/ColumnChart/Segment.tsx +66 -0
- package/src/components/Chart/ColumnChart/StackedSegment.tsx +99 -0
- package/src/components/Chart/ColumnChart/StyledColumnChart.tsx +9 -0
- package/src/components/Chart/ColumnChart/__tests__/ColumnChartContent.spec.tsx +68 -0
- package/src/components/Chart/ColumnChart/__tests__/Segment.spec.tsx +99 -0
- package/src/components/Chart/ColumnChart/__tests__/StackedSegment.spec.tsx +115 -0
- package/src/components/Chart/ColumnChart/__tests__/__snapshots__/StackedSegment.spec.tsx.snap +120 -0
- package/src/components/Chart/ColumnChart/__tests__/__snapshots__/index.spec.tsx.snap +1405 -0
- package/src/components/Chart/ColumnChart/__tests__/index.spec.tsx +134 -0
- package/src/components/Chart/ColumnChart/index.tsx +216 -0
- package/src/components/Chart/Line/Line.tsx +81 -0
- package/src/components/Chart/Line/__tests__/Line.spec.tsx +148 -0
- package/src/components/Chart/Line/__tests__/__snapshots__/Line.spec.tsx.snap +56 -0
- package/src/components/Chart/Line/__tests__/__snapshots__/index.spec.tsx.snap +1461 -0
- package/src/components/Chart/Line/__tests__/index.spec.tsx +112 -0
- package/src/components/Chart/Line/index.tsx +143 -0
- package/src/components/Chart/StyledChart.tsx +16 -0
- package/src/components/Chart/index.tsx +13 -0
- package/src/components/Chart/shared/AxisLabel.tsx +25 -0
- package/src/components/Chart/shared/ChartFrame.tsx +131 -0
- package/src/components/Chart/shared/ChartHeader.tsx +19 -0
- package/src/components/Chart/shared/EmptyState.tsx +83 -0
- package/src/components/Chart/shared/XAxis.tsx +69 -0
- package/src/components/Chart/shared/XAxisGrid.tsx +42 -0
- package/src/components/Chart/shared/YAxis.tsx +104 -0
- package/src/components/Chart/shared/YAxisGrid.tsx +58 -0
- package/src/components/Chart/shared/__tests__/ChartFrame.spec.tsx +125 -0
- package/src/components/Chart/shared/__tests__/ChartHeader.spec.tsx +22 -0
- package/src/components/Chart/shared/__tests__/EmptyState.spec.tsx +29 -0
- package/src/components/Chart/shared/__tests__/XAXisGrid.spec.tsx +30 -0
- package/src/components/Chart/shared/__tests__/XAxis.spec.tsx +42 -0
- package/src/components/Chart/shared/__tests__/YAxis.spec.tsx +72 -0
- package/src/components/Chart/shared/__tests__/YAxisGrid.spec.tsx +35 -0
- package/src/components/Chart/shared/__tests__/__snapshots__/ChartFrame.spec.tsx.snap +3058 -0
- package/src/components/Chart/shared/__tests__/__snapshots__/ChartHeader.spec.tsx.snap +160 -0
- package/src/components/Chart/shared/__tests__/__snapshots__/EmptyState.spec.tsx.snap +155 -0
- package/src/components/Chart/shared/__tests__/__snapshots__/XAXisGrid.spec.tsx.snap +197 -0
- package/src/components/Chart/shared/__tests__/__snapshots__/XAxis.spec.tsx.snap +369 -0
- package/src/components/Chart/shared/__tests__/__snapshots__/YAxis.spec.tsx.snap +1013 -0
- package/src/components/Chart/shared/__tests__/__snapshots__/YAxisGrid.spec.tsx.snap +228 -0
- package/src/components/Chart/shared/__tests__/niceNumbers.spec.tsx +127 -0
- package/src/components/Chart/shared/constants.ts +2 -0
- package/src/components/Chart/shared/hooks/useColorScale.ts +25 -0
- package/src/components/Chart/shared/hooks/useGenerateTicks.ts +27 -0
- package/src/components/Chart/shared/hooks/useScaleBandX.ts +17 -0
- package/src/components/Chart/shared/hooks/useScaleLinearY.ts +30 -0
- package/src/components/Chart/shared/niceNumbers.ts +68 -0
- package/src/components/Chart/types.ts +100 -0
- package/src/components/Select/MultiSelect/OptionList.tsx +1 -1
- package/src/components/Select/MultiSelect/index.tsx +2 -6
- package/src/components/Select/MultiSelect/utils.ts +1 -1
- package/src/components/Select/SingleSelect/OptionList.tsx +1 -1
- package/src/components/Select/SingleSelect/index.tsx +2 -7
- package/src/components/Select/__tests__/helpers.spec.tsx +0 -36
- package/src/components/Select/helpers.tsx +0 -75
- package/src/components/Switch/SelectorSwitch/__tests__/__snapshots__/Option.spec.tsx.snap +3 -0
- package/src/components/Switch/SelectorSwitch/__tests__/__snapshots__/index.spec.tsx.snap +1 -0
- package/src/components/Tabs/__tests__/__snapshots__/ScrollableTabs.spec.tsx.snap +3 -0
- package/src/components/Tabs/__tests__/__snapshots__/ScrollableTabsHeader.spec.tsx.snap +2 -0
- package/src/components/Tabs/__tests__/__snapshots__/TabWithBadge.spec.tsx.snap +1 -0
- package/src/components/Tabs/__tests__/__snapshots__/index.spec.tsx.snap +3 -0
- package/src/index.ts +2 -0
- package/src/theme/__tests__/__snapshots__/index.spec.ts.snap +28 -0
- package/src/theme/components/chart.ts +28 -0
- package/src/theme/components/columnChart.ts +15 -0
- package/src/theme/getTheme.ts +6 -0
- package/src/types.ts +4 -0
- package/src/utils/__tests__/helpers.spec.ts +36 -1
- package/src/utils/helpers.ts +76 -1
- package/stats/8.100.0/rn-stats.html +4842 -0
- package/stats/8.99.4/rn-stats.html +1 -1
- package/types/components/Badge/Status.d.ts +0 -1
- package/types/components/Chart/ChartSelect/StyledChartSelect.d.ts +8 -0
- package/types/components/Chart/ChartSelect/index.d.ts +63 -0
- package/types/components/Chart/ColumnChart/ColumnChartContent.d.ts +25 -0
- package/types/components/Chart/ColumnChart/Segment.d.ts +14 -0
- package/types/components/Chart/ColumnChart/StackedSegment.d.ts +28 -0
- package/types/components/Chart/ColumnChart/StyledColumnChart.d.ts +8 -0
- package/types/components/Chart/ColumnChart/index.d.ts +80 -0
- package/types/components/Chart/Line/Line.d.ts +21 -0
- package/types/components/Chart/Line/index.d.ts +35 -0
- package/types/components/Chart/StyledChart.d.ts +9 -0
- package/types/components/Chart/index.d.ts +9 -0
- package/types/components/Chart/shared/AxisLabel.d.ts +7 -0
- package/types/components/Chart/shared/ChartFrame.d.ts +30 -0
- package/types/components/Chart/shared/ChartHeader.d.ts +8 -0
- package/types/components/Chart/shared/EmptyState.d.ts +8 -0
- package/types/components/Chart/shared/XAxis.d.ts +8 -0
- package/types/components/Chart/shared/XAxisGrid.d.ts +8 -0
- package/types/components/Chart/shared/YAxis.d.ts +10 -0
- package/types/components/Chart/shared/YAxisGrid.d.ts +10 -0
- package/types/components/Chart/shared/constants.d.ts +2 -0
- package/types/components/Chart/shared/hooks/useColorScale.d.ts +7 -0
- package/types/components/Chart/shared/hooks/useGenerateTicks.d.ts +6 -0
- package/types/components/Chart/shared/hooks/useScaleBandX.d.ts +8 -0
- package/types/components/Chart/shared/hooks/useScaleLinearY.d.ts +9 -0
- package/types/components/Chart/shared/niceNumbers.d.ts +12 -0
- package/types/components/Chart/types.d.ts +84 -0
- package/types/components/Select/helpers.d.ts +0 -5
- package/types/index.d.ts +2 -1
- package/types/theme/components/chart.d.ts +22 -0
- package/types/theme/components/columnChart.d.ts +10 -0
- package/types/theme/getTheme.d.ts +4 -0
- package/types/types.d.ts +3 -1
- package/types/utils/helpers.d.ts +5 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
deepCompareValue,
|
|
3
2
|
getScrollParams,
|
|
4
3
|
isSections,
|
|
5
4
|
toFlatOptions,
|
|
@@ -73,38 +72,3 @@ describe('getScrollParams', () => {
|
|
|
73
72
|
});
|
|
74
73
|
});
|
|
75
74
|
});
|
|
76
|
-
|
|
77
|
-
describe('deepCompareValue', () => {
|
|
78
|
-
it.each`
|
|
79
|
-
a | b | expected
|
|
80
|
-
${1} | ${1} | ${true}
|
|
81
|
-
${'test'} | ${'test'} | ${true}
|
|
82
|
-
${true} | ${true} | ${true}
|
|
83
|
-
${null} | ${null} | ${true}
|
|
84
|
-
${undefined} | ${undefined} | ${true}
|
|
85
|
-
${1} | ${2} | ${false}
|
|
86
|
-
${'test'} | ${'other'} | ${false}
|
|
87
|
-
${true} | ${false} | ${false}
|
|
88
|
-
${null} | ${undefined} | ${false}
|
|
89
|
-
${NaN} | ${NaN} | ${false}
|
|
90
|
-
${1} | ${NaN} | ${false}
|
|
91
|
-
${[1, 2, 3]} | ${[1, 2, 3]} | ${true}
|
|
92
|
-
${['a', 'b']} | ${['a', 'b']} | ${true}
|
|
93
|
-
${[]} | ${[]} | ${true}
|
|
94
|
-
${[1, 2]} | ${[1, 2, 3]} | ${false}
|
|
95
|
-
${[1, 2]} | ${[2, 1]} | ${false}
|
|
96
|
-
${[1, [2, 3]]} | ${[1, [2, 3]]} | ${true}
|
|
97
|
-
${[1, [2, 3]]} | ${[1, [2, 4]]} | ${false}
|
|
98
|
-
${{ a: 1, b: 2 }} | ${{ a: 1, b: 2 }} | ${true}
|
|
99
|
-
${{}} | ${{}} | ${true}
|
|
100
|
-
${{ a: 1 }} | ${{ a: 2 }} | ${false}
|
|
101
|
-
${{ a: 1 }} | ${{ b: 1 }} | ${false}
|
|
102
|
-
${{ a: 1 }} | ${{ a: 1, b: 2 }} | ${false}
|
|
103
|
-
${{ a: { b: 1 } }} | ${{ a: { b: 1 } }} | ${true}
|
|
104
|
-
${{ a: { b: 1 } }} | ${{ a: { b: 2 } }} | ${false}
|
|
105
|
-
${1} | ${'1'} | ${false}
|
|
106
|
-
${[]} | ${{}} | ${false}
|
|
107
|
-
`('should compare $a and $b correctly', ({ a, b, expected }) => {
|
|
108
|
-
expect(deepCompareValue(a, b)).toBe(expected);
|
|
109
|
-
});
|
|
110
|
-
});
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
2
|
-
import { Keyboard } from 'react-native';
|
|
3
1
|
import type { SectionData, CombinedOptionsType, OptionType } from './types';
|
|
4
2
|
|
|
5
3
|
export const getKey = <V, T extends OptionType<V>>(
|
|
@@ -71,76 +69,3 @@ export const getScrollParams = <V, T extends OptionType<V>>(
|
|
|
71
69
|
itemIndex: itemIndex < 0 ? 0 : itemIndex,
|
|
72
70
|
};
|
|
73
71
|
};
|
|
74
|
-
|
|
75
|
-
export const useKeyboard = () => {
|
|
76
|
-
const [isKeyboardVisible, setKeyboardVisible] = useState(false);
|
|
77
|
-
const [keyboardHeight, setKeyboardHeight] = useState(0);
|
|
78
|
-
|
|
79
|
-
useEffect(() => {
|
|
80
|
-
const keyboardWillShowListener = Keyboard.addListener(
|
|
81
|
-
'keyboardWillShow',
|
|
82
|
-
(e) => {
|
|
83
|
-
setKeyboardVisible(true);
|
|
84
|
-
setKeyboardHeight(e.endCoordinates.height);
|
|
85
|
-
}
|
|
86
|
-
);
|
|
87
|
-
const keyboardWillHideListener = Keyboard.addListener(
|
|
88
|
-
'keyboardWillHide',
|
|
89
|
-
() => {
|
|
90
|
-
setKeyboardVisible(false);
|
|
91
|
-
}
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
return () => {
|
|
95
|
-
keyboardWillShowListener.remove();
|
|
96
|
-
keyboardWillHideListener.remove();
|
|
97
|
-
};
|
|
98
|
-
}, []);
|
|
99
|
-
|
|
100
|
-
return { isKeyboardVisible, keyboardHeight };
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
export const deepCompareValue = <V,>(a: V, b: V): boolean => {
|
|
104
|
-
// Handle strict equality first (handles primitives, null, undefined)
|
|
105
|
-
if (a === b) return true;
|
|
106
|
-
|
|
107
|
-
// Special handling for NaN (NaN !== NaN in JS)
|
|
108
|
-
if (
|
|
109
|
-
typeof a === 'number' &&
|
|
110
|
-
typeof b === 'number' &&
|
|
111
|
-
Number.isNaN(a) &&
|
|
112
|
-
Number.isNaN(b)
|
|
113
|
-
) {
|
|
114
|
-
return false;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// If either is null or undefined (but they are not strictly equal), return false
|
|
118
|
-
if (a == null || b == null) return false;
|
|
119
|
-
|
|
120
|
-
// If types don't match, they can't be equal
|
|
121
|
-
if (typeof a !== typeof b) return false;
|
|
122
|
-
|
|
123
|
-
// Handle array comparison
|
|
124
|
-
if (Array.isArray(a) && Array.isArray(b)) {
|
|
125
|
-
if (a.length !== b.length) return false;
|
|
126
|
-
return a.every((val, index) => deepCompareValue(val, b[index]));
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// If one is array and the other isn't, return false
|
|
130
|
-
if (Array.isArray(a) !== Array.isArray(b)) return false;
|
|
131
|
-
|
|
132
|
-
// Handle object comparison
|
|
133
|
-
if (typeof a === 'object' && typeof b === 'object') {
|
|
134
|
-
const keysA = Object.keys(a) as (keyof V)[];
|
|
135
|
-
const keysB = Object.keys(b) as (keyof V)[];
|
|
136
|
-
|
|
137
|
-
if (keysA.length !== keysB.length) return false;
|
|
138
|
-
|
|
139
|
-
return keysA.every(
|
|
140
|
-
(key) => keysB.includes(key) && deepCompareValue(a[key], b[key])
|
|
141
|
-
);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// If none of the above conditions matched, they're not equal
|
|
145
|
-
return false;
|
|
146
|
-
};
|
|
@@ -65,6 +65,7 @@ exports[`Option renders correctly when not selected 1`] = `
|
|
|
65
65
|
"width": 8,
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
|
+
testID="status-dot"
|
|
68
69
|
themeIntent="danger"
|
|
69
70
|
/>
|
|
70
71
|
</View>
|
|
@@ -164,6 +165,7 @@ exports[`Option renders correctly when selected 1`] = `
|
|
|
164
165
|
"width": 8,
|
|
165
166
|
}
|
|
166
167
|
}
|
|
168
|
+
testID="status-dot"
|
|
167
169
|
themeIntent="danger"
|
|
168
170
|
/>
|
|
169
171
|
</View>
|
|
@@ -285,6 +287,7 @@ exports[`OptionContent renders correctly when there is a badge 1`] = `
|
|
|
285
287
|
"width": 8,
|
|
286
288
|
}
|
|
287
289
|
}
|
|
290
|
+
testID="status-dot"
|
|
288
291
|
themeIntent="danger"
|
|
289
292
|
/>
|
|
290
293
|
</View>
|
|
@@ -570,6 +570,7 @@ exports[`Tabs.Scroll lazy not render lazy screen: xxx 1`] = `
|
|
|
570
570
|
"width": 8,
|
|
571
571
|
}
|
|
572
572
|
}
|
|
573
|
+
testID="status-dot"
|
|
573
574
|
themeIntent="danger"
|
|
574
575
|
/>
|
|
575
576
|
</View>
|
|
@@ -1502,6 +1503,7 @@ exports[`Tabs.Scroll renders correctly 1`] = `
|
|
|
1502
1503
|
"width": 8,
|
|
1503
1504
|
}
|
|
1504
1505
|
}
|
|
1506
|
+
testID="status-dot"
|
|
1505
1507
|
themeIntent="danger"
|
|
1506
1508
|
/>
|
|
1507
1509
|
</View>
|
|
@@ -2434,6 +2436,7 @@ exports[`useIsFocused renders correctly 1`] = `
|
|
|
2434
2436
|
"width": 8,
|
|
2435
2437
|
}
|
|
2436
2438
|
}
|
|
2439
|
+
testID="status-dot"
|
|
2437
2440
|
themeIntent="danger"
|
|
2438
2441
|
/>
|
|
2439
2442
|
</View>
|
|
@@ -463,6 +463,7 @@ exports[`ScrollableTabsHeader highlighted variant renders correctly 1`] = `
|
|
|
463
463
|
"width": 8,
|
|
464
464
|
}
|
|
465
465
|
}
|
|
466
|
+
testID="status-dot"
|
|
466
467
|
themeIntent="danger"
|
|
467
468
|
/>
|
|
468
469
|
</View>
|
|
@@ -1078,6 +1079,7 @@ exports[`ScrollableTabsHeader underlined variant renders correctly 1`] = `
|
|
|
1078
1079
|
"width": 8,
|
|
1079
1080
|
}
|
|
1080
1081
|
}
|
|
1082
|
+
testID="status-dot"
|
|
1081
1083
|
themeIntent="danger"
|
|
1082
1084
|
/>
|
|
1083
1085
|
</View>
|
|
@@ -350,6 +350,7 @@ exports[`Tabs renders correctly 1`] = `
|
|
|
350
350
|
"width": 8,
|
|
351
351
|
}
|
|
352
352
|
}
|
|
353
|
+
testID="status-dot"
|
|
353
354
|
themeIntent="danger"
|
|
354
355
|
/>
|
|
355
356
|
</View>
|
|
@@ -1026,6 +1027,7 @@ exports[`useIsFocused renders correctly 1`] = `
|
|
|
1026
1027
|
"width": 8,
|
|
1027
1028
|
}
|
|
1028
1029
|
}
|
|
1030
|
+
testID="status-dot"
|
|
1029
1031
|
themeIntent="danger"
|
|
1030
1032
|
/>
|
|
1031
1033
|
</View>
|
|
@@ -1702,6 +1704,7 @@ exports[`useIsFocused renders correctly: xxxxxx 1`] = `
|
|
|
1702
1704
|
"width": 8,
|
|
1703
1705
|
}
|
|
1704
1706
|
}
|
|
1707
|
+
testID="status-dot"
|
|
1705
1708
|
themeIntent="danger"
|
|
1706
1709
|
/>
|
|
1707
1710
|
</View>
|
package/src/index.ts
CHANGED
|
@@ -31,6 +31,7 @@ import Button from './components/Button';
|
|
|
31
31
|
import Calendar from './components/Calendar';
|
|
32
32
|
import Carousel from './components/Carousel';
|
|
33
33
|
import Card from './components/Card';
|
|
34
|
+
import Chart from './components/Chart';
|
|
34
35
|
import Chip from './components/Chip';
|
|
35
36
|
import Collapse from './components/Collapse';
|
|
36
37
|
import Checkbox from './components/Checkbox';
|
|
@@ -110,6 +111,7 @@ export {
|
|
|
110
111
|
Button,
|
|
111
112
|
Calendar,
|
|
112
113
|
Card,
|
|
114
|
+
Chart,
|
|
113
115
|
Carousel,
|
|
114
116
|
Chip,
|
|
115
117
|
Collapse,
|
|
@@ -428,6 +428,26 @@ exports[`theme returns correct theme object 1`] = `
|
|
|
428
428
|
"pageControlWrapperHeight": 48,
|
|
429
429
|
},
|
|
430
430
|
},
|
|
431
|
+
"chart": {
|
|
432
|
+
"colors": {
|
|
433
|
+
"gridStroke": "#e8e9ea",
|
|
434
|
+
},
|
|
435
|
+
"sizes": {
|
|
436
|
+
"defaultWebEmptyStateHeight": 24,
|
|
437
|
+
"defaultWebEmptyStateWidth": 176,
|
|
438
|
+
"xAxisDefaultTextHeight": 32,
|
|
439
|
+
"yAxisDefaultTextHeight": 8,
|
|
440
|
+
"yAxisDefaultTextWidth": 32,
|
|
441
|
+
},
|
|
442
|
+
"space": {
|
|
443
|
+
"headerMarginBottom": 16,
|
|
444
|
+
"xAxisGridTextMarginTop": 12,
|
|
445
|
+
"xAxisMarginLeft": 16,
|
|
446
|
+
"yAxisGridMarginTop": 8,
|
|
447
|
+
"yAxisGridTextMarginRight": 16,
|
|
448
|
+
"yAxisMarginBottom": 24,
|
|
449
|
+
},
|
|
450
|
+
},
|
|
431
451
|
"checkbox": {
|
|
432
452
|
"borderWidths": {
|
|
433
453
|
"icon": 2,
|
|
@@ -501,6 +521,14 @@ exports[`theme returns correct theme object 1`] = `
|
|
|
501
521
|
"wrapperVerticalPadding": 8,
|
|
502
522
|
},
|
|
503
523
|
},
|
|
524
|
+
"columnChart": {
|
|
525
|
+
"sizes": {
|
|
526
|
+
"columnWidth": 16,
|
|
527
|
+
},
|
|
528
|
+
"space": {
|
|
529
|
+
"segmentGap": 2,
|
|
530
|
+
},
|
|
531
|
+
},
|
|
504
532
|
"contentNavigator": {
|
|
505
533
|
"space": {
|
|
506
534
|
"valueHorizontalPadding": 8,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { GlobalTheme } from '../global';
|
|
2
|
+
|
|
3
|
+
const getChartTheme = (theme: GlobalTheme) => {
|
|
4
|
+
const space = {
|
|
5
|
+
xAxisMarginLeft: theme.space.medium,
|
|
6
|
+
xAxisGridTextMarginTop: theme.space.smallMedium,
|
|
7
|
+
yAxisMarginBottom: theme.space.large,
|
|
8
|
+
yAxisGridMarginTop: theme.space.small,
|
|
9
|
+
yAxisGridTextMarginRight: theme.space.medium,
|
|
10
|
+
headerMarginBottom: theme.space.medium,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const sizes = {
|
|
14
|
+
xAxisDefaultTextHeight: theme.sizes.xlarge,
|
|
15
|
+
yAxisDefaultTextHeight: theme.sizes.small,
|
|
16
|
+
yAxisDefaultTextWidth: theme.sizes.xlarge,
|
|
17
|
+
defaultWebEmptyStateWidth: theme.sizes['19xlarge'], // Only use for web doc
|
|
18
|
+
defaultWebEmptyStateHeight: theme.sizes.large, // Only use for web doc
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const colors = {
|
|
22
|
+
gridStroke: theme.colors.secondaryOutline,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
return { space, sizes, colors };
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export default getChartTheme;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { GlobalTheme } from '../global';
|
|
2
|
+
|
|
3
|
+
const getColumnChartTheme = (theme: GlobalTheme) => {
|
|
4
|
+
const sizes = {
|
|
5
|
+
columnWidth: theme.sizes.medium,
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const space = {
|
|
9
|
+
segmentGap: theme.space.xxsmall,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
return { sizes, space };
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default getColumnChartTheme;
|
package/src/theme/getTheme.ts
CHANGED
|
@@ -14,6 +14,8 @@ import getCarouselTheme, { CarouselThemeType } from './components/carousel';
|
|
|
14
14
|
import getCardCarouselTheme from './components/cardCarousel';
|
|
15
15
|
import getCheckboxTheme from './components/checkbox';
|
|
16
16
|
import getChipTheme from './components/chip';
|
|
17
|
+
import getChartTheme from './components/chart';
|
|
18
|
+
import getColumnChartTheme from './components/columnChart';
|
|
17
19
|
import getContentNavigatorTheme from './components/contentNavigator';
|
|
18
20
|
import getDatePickerTheme from './components/datePicker';
|
|
19
21
|
import getDividerTheme from './components/divider';
|
|
@@ -73,6 +75,8 @@ type Theme = GlobalTheme & {
|
|
|
73
75
|
cardCarousel: ReturnType<typeof getCardCarouselTheme>;
|
|
74
76
|
checkbox: ReturnType<typeof getCheckboxTheme>;
|
|
75
77
|
chip: ReturnType<typeof getChipTheme>;
|
|
78
|
+
chart: ReturnType<typeof getChartTheme>;
|
|
79
|
+
columnChart: ReturnType<typeof getColumnChartTheme>;
|
|
76
80
|
contentNavigator: ReturnType<typeof getContentNavigatorTheme>;
|
|
77
81
|
datePicker: ReturnType<typeof getDatePickerTheme>;
|
|
78
82
|
divider: ReturnType<typeof getDividerTheme>;
|
|
@@ -133,6 +137,8 @@ const getTheme = (
|
|
|
133
137
|
card: getCardTheme(globalTheme),
|
|
134
138
|
carousel: getCarouselTheme(globalTheme),
|
|
135
139
|
cardCarousel: getCardCarouselTheme(globalTheme),
|
|
140
|
+
chart: getChartTheme(globalTheme),
|
|
141
|
+
columnChart: getColumnChartTheme(globalTheme),
|
|
136
142
|
checkbox: getCheckboxTheme(globalTheme),
|
|
137
143
|
chip: getChipTheme(globalTheme),
|
|
138
144
|
contentNavigator: getContentNavigatorTheme(globalTheme),
|
package/src/types.ts
CHANGED
|
@@ -20,6 +20,8 @@ import { ActionGroupHandles } from './components/FAB/ActionGroup';
|
|
|
20
20
|
import type { SliderRangeValue } from './components/Slider/RangeSlider';
|
|
21
21
|
import type { CalendarDateRange } from './components/Calendar/CalendarRange';
|
|
22
22
|
import { LocaleCode, LocaleValues, DateTimeFormats } from './locales/types';
|
|
23
|
+
import type { ColumnChartProps } from './components/Chart/ColumnChart';
|
|
24
|
+
import { LineChartProps } from './components/Chart/Line';
|
|
23
25
|
|
|
24
26
|
export type {
|
|
25
27
|
BottomNavigationTabType,
|
|
@@ -44,4 +46,6 @@ export type {
|
|
|
44
46
|
LocaleCode,
|
|
45
47
|
LocaleValues,
|
|
46
48
|
DateTimeFormats,
|
|
49
|
+
ColumnChartProps,
|
|
50
|
+
LineChartProps,
|
|
47
51
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { omit, pick } from '../helpers';
|
|
1
|
+
import { deepCompareValue, omit, pick } from '../helpers';
|
|
2
2
|
|
|
3
3
|
describe('pick', () => {
|
|
4
4
|
it('works', () => {
|
|
@@ -43,3 +43,38 @@ describe('omit', () => {
|
|
|
43
43
|
});
|
|
44
44
|
});
|
|
45
45
|
});
|
|
46
|
+
|
|
47
|
+
describe('deepCompareValue', () => {
|
|
48
|
+
it.each`
|
|
49
|
+
a | b | expected
|
|
50
|
+
${1} | ${1} | ${true}
|
|
51
|
+
${'test'} | ${'test'} | ${true}
|
|
52
|
+
${true} | ${true} | ${true}
|
|
53
|
+
${null} | ${null} | ${true}
|
|
54
|
+
${undefined} | ${undefined} | ${true}
|
|
55
|
+
${1} | ${2} | ${false}
|
|
56
|
+
${'test'} | ${'other'} | ${false}
|
|
57
|
+
${true} | ${false} | ${false}
|
|
58
|
+
${null} | ${undefined} | ${false}
|
|
59
|
+
${NaN} | ${NaN} | ${false}
|
|
60
|
+
${1} | ${NaN} | ${false}
|
|
61
|
+
${[1, 2, 3]} | ${[1, 2, 3]} | ${true}
|
|
62
|
+
${['a', 'b']} | ${['a', 'b']} | ${true}
|
|
63
|
+
${[]} | ${[]} | ${true}
|
|
64
|
+
${[1, 2]} | ${[1, 2, 3]} | ${false}
|
|
65
|
+
${[1, 2]} | ${[2, 1]} | ${false}
|
|
66
|
+
${[1, [2, 3]]} | ${[1, [2, 3]]} | ${true}
|
|
67
|
+
${[1, [2, 3]]} | ${[1, [2, 4]]} | ${false}
|
|
68
|
+
${{ a: 1, b: 2 }} | ${{ a: 1, b: 2 }} | ${true}
|
|
69
|
+
${{}} | ${{}} | ${true}
|
|
70
|
+
${{ a: 1 }} | ${{ a: 2 }} | ${false}
|
|
71
|
+
${{ a: 1 }} | ${{ b: 1 }} | ${false}
|
|
72
|
+
${{ a: 1 }} | ${{ a: 1, b: 2 }} | ${false}
|
|
73
|
+
${{ a: { b: 1 } }} | ${{ a: { b: 1 } }} | ${true}
|
|
74
|
+
${{ a: { b: 1 } }} | ${{ a: { b: 2 } }} | ${false}
|
|
75
|
+
${1} | ${'1'} | ${false}
|
|
76
|
+
${[]} | ${{}} | ${false}
|
|
77
|
+
`('should compare $a and $b correctly', ({ a, b, expected }) => {
|
|
78
|
+
expect(deepCompareValue(a, b)).toBe(expected);
|
|
79
|
+
});
|
|
80
|
+
});
|
package/src/utils/helpers.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { Platform } from 'react-native';
|
|
1
|
+
import { Platform, Keyboard } from 'react-native';
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
2
4
|
|
|
3
5
|
export const isIOS = Platform.OS === 'ios';
|
|
4
6
|
export const isAndroid = Platform.OS === 'android';
|
|
@@ -36,3 +38,76 @@ export function hexToRgba(hex: string, a: number) {
|
|
|
36
38
|
const [r, g, b] = arrByte;
|
|
37
39
|
return `rgba(${r},${g},${b},${a})`;
|
|
38
40
|
}
|
|
41
|
+
|
|
42
|
+
export const deepCompareValue = <V>(a: V, b: V): boolean => {
|
|
43
|
+
// Handle strict equality first (handles primitives, null, undefined)
|
|
44
|
+
if (a === b) return true;
|
|
45
|
+
|
|
46
|
+
// Special handling for NaN (NaN !== NaN in JS)
|
|
47
|
+
if (
|
|
48
|
+
typeof a === 'number' &&
|
|
49
|
+
typeof b === 'number' &&
|
|
50
|
+
Number.isNaN(a) &&
|
|
51
|
+
Number.isNaN(b)
|
|
52
|
+
) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// If either is null or undefined (but they are not strictly equal), return false
|
|
57
|
+
if (a == null || b == null) return false;
|
|
58
|
+
|
|
59
|
+
// If types don't match, they can't be equal
|
|
60
|
+
if (typeof a !== typeof b) return false;
|
|
61
|
+
|
|
62
|
+
// Handle array comparison
|
|
63
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
64
|
+
if (a.length !== b.length) return false;
|
|
65
|
+
return a.every((val, index) => deepCompareValue(val, b[index]));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// If one is array and the other isn't, return false
|
|
69
|
+
if (Array.isArray(a) !== Array.isArray(b)) return false;
|
|
70
|
+
|
|
71
|
+
// Handle object comparison
|
|
72
|
+
if (typeof a === 'object' && typeof b === 'object') {
|
|
73
|
+
const keysA = Object.keys(a) as (keyof V)[];
|
|
74
|
+
const keysB = Object.keys(b) as (keyof V)[];
|
|
75
|
+
|
|
76
|
+
if (keysA.length !== keysB.length) return false;
|
|
77
|
+
|
|
78
|
+
return keysA.every(
|
|
79
|
+
(key) => keysB.includes(key) && deepCompareValue(a[key], b[key])
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// If none of the above conditions matched, they're not equal
|
|
84
|
+
return false;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const useKeyboard = () => {
|
|
88
|
+
const [isKeyboardVisible, setKeyboardVisible] = useState(false);
|
|
89
|
+
const [keyboardHeight, setKeyboardHeight] = useState(0);
|
|
90
|
+
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
const keyboardWillShowListener = Keyboard.addListener(
|
|
93
|
+
'keyboardWillShow',
|
|
94
|
+
(e) => {
|
|
95
|
+
setKeyboardVisible(true);
|
|
96
|
+
setKeyboardHeight(e.endCoordinates.height);
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
const keyboardWillHideListener = Keyboard.addListener(
|
|
100
|
+
'keyboardWillHide',
|
|
101
|
+
() => {
|
|
102
|
+
setKeyboardVisible(false);
|
|
103
|
+
}
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
return () => {
|
|
107
|
+
keyboardWillShowListener.remove();
|
|
108
|
+
keyboardWillHideListener.remove();
|
|
109
|
+
};
|
|
110
|
+
}, []);
|
|
111
|
+
|
|
112
|
+
return { isKeyboardVisible, keyboardHeight };
|
|
113
|
+
};
|