react-native-ruler-date-picker 0.1.0 → 0.2.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/README.md +186 -60
- package/lib/commonjs/LensTick.js +83 -0
- package/lib/commonjs/LensTick.js.map +1 -0
- package/lib/commonjs/Ruler.js +38 -0
- package/lib/commonjs/Ruler.js.map +1 -0
- package/lib/commonjs/RulerContext.js +17 -0
- package/lib/commonjs/RulerContext.js.map +1 -0
- package/lib/commonjs/RulerDatePicker.js +38 -351
- package/lib/commonjs/RulerDatePicker.js.map +1 -1
- package/lib/commonjs/RulerDateRangePicker.js +56 -0
- package/lib/commonjs/RulerDateRangePicker.js.map +1 -0
- package/lib/commonjs/RulerHeader.js +106 -0
- package/lib/commonjs/RulerHeader.js.map +1 -0
- package/lib/commonjs/RulerIndicator.js +67 -0
- package/lib/commonjs/RulerIndicator.js.map +1 -0
- package/lib/commonjs/RulerLensTicks.js +55 -0
- package/lib/commonjs/RulerLensTicks.js.map +1 -0
- package/lib/commonjs/RulerLensTrack.js +52 -0
- package/lib/commonjs/RulerLensTrack.js.map +1 -0
- package/lib/commonjs/RulerRange.js +39 -0
- package/lib/commonjs/RulerRange.js.map +1 -0
- package/lib/commonjs/RulerRangeContext.js +17 -0
- package/lib/commonjs/RulerRangeContext.js.map +1 -0
- package/lib/commonjs/RulerRangeHeader.js +154 -0
- package/lib/commonjs/RulerRangeHeader.js.map +1 -0
- package/lib/commonjs/RulerRangeHighlight.js +50 -0
- package/lib/commonjs/RulerRangeHighlight.js.map +1 -0
- package/lib/commonjs/RulerRangeIndicator.js +71 -0
- package/lib/commonjs/RulerRangeIndicator.js.map +1 -0
- package/lib/commonjs/RulerRangeRoot.js +80 -0
- package/lib/commonjs/RulerRangeRoot.js.map +1 -0
- package/lib/commonjs/RulerRangeTicks.js +57 -0
- package/lib/commonjs/RulerRangeTicks.js.map +1 -0
- package/lib/commonjs/RulerRangeTrack.js +46 -0
- package/lib/commonjs/RulerRangeTrack.js.map +1 -0
- package/lib/commonjs/RulerResetButton.js +46 -0
- package/lib/commonjs/RulerResetButton.js.map +1 -0
- package/lib/commonjs/RulerRoot.js +87 -0
- package/lib/commonjs/RulerRoot.js.map +1 -0
- package/lib/commonjs/RulerTicks.js +51 -0
- package/lib/commonjs/RulerTicks.js.map +1 -0
- package/lib/commonjs/RulerTrack.js +46 -0
- package/lib/commonjs/RulerTrack.js.map +1 -0
- package/lib/commonjs/Tick.js +41 -36
- package/lib/commonjs/Tick.js.map +1 -1
- package/lib/commonjs/defaults.js +20 -19
- package/lib/commonjs/defaults.js.map +1 -1
- package/lib/commonjs/index.js +287 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/presets.js +108 -0
- package/lib/commonjs/presets.js.map +1 -0
- package/lib/commonjs/tickResolver.js +101 -0
- package/lib/commonjs/tickResolver.js.map +1 -0
- package/lib/commonjs/useHaptics.js +1 -1
- package/lib/commonjs/useHaptics.web.js +43 -0
- package/lib/commonjs/useHaptics.web.js.map +1 -0
- package/lib/commonjs/useRulerDatePicker.js +264 -0
- package/lib/commonjs/useRulerDatePicker.js.map +1 -0
- package/lib/commonjs/useRulerDateRangePicker.js +313 -0
- package/lib/commonjs/useRulerDateRangePicker.js.map +1 -0
- package/lib/commonjs/utils.js +61 -47
- package/lib/commonjs/utils.js.map +1 -1
- package/lib/module/LensTick.js +77 -0
- package/lib/module/LensTick.js.map +1 -0
- package/lib/module/Ruler.js +35 -0
- package/lib/module/Ruler.js.map +1 -0
- package/lib/module/RulerContext.js +12 -0
- package/lib/module/RulerContext.js.map +1 -0
- package/lib/module/RulerDatePicker.js +38 -350
- package/lib/module/RulerDatePicker.js.map +1 -1
- package/lib/module/RulerDateRangePicker.js +52 -0
- package/lib/module/RulerDateRangePicker.js.map +1 -0
- package/lib/module/RulerHeader.js +101 -0
- package/lib/module/RulerHeader.js.map +1 -0
- package/lib/module/RulerIndicator.js +62 -0
- package/lib/module/RulerIndicator.js.map +1 -0
- package/lib/module/RulerLensTicks.js +50 -0
- package/lib/module/RulerLensTicks.js.map +1 -0
- package/lib/module/RulerLensTrack.js +47 -0
- package/lib/module/RulerLensTrack.js.map +1 -0
- package/lib/module/RulerRange.js +36 -0
- package/lib/module/RulerRange.js.map +1 -0
- package/lib/module/RulerRangeContext.js +12 -0
- package/lib/module/RulerRangeContext.js.map +1 -0
- package/lib/module/RulerRangeHeader.js +149 -0
- package/lib/module/RulerRangeHeader.js.map +1 -0
- package/lib/module/RulerRangeHighlight.js +45 -0
- package/lib/module/RulerRangeHighlight.js.map +1 -0
- package/lib/module/RulerRangeIndicator.js +66 -0
- package/lib/module/RulerRangeIndicator.js.map +1 -0
- package/lib/module/RulerRangeRoot.js +75 -0
- package/lib/module/RulerRangeRoot.js.map +1 -0
- package/lib/module/RulerRangeTicks.js +51 -0
- package/lib/module/RulerRangeTicks.js.map +1 -0
- package/lib/module/RulerRangeTrack.js +41 -0
- package/lib/module/RulerRangeTrack.js.map +1 -0
- package/lib/module/RulerResetButton.js +41 -0
- package/lib/module/RulerResetButton.js.map +1 -0
- package/lib/module/RulerRoot.js +82 -0
- package/lib/module/RulerRoot.js.map +1 -0
- package/lib/module/RulerTicks.js +45 -0
- package/lib/module/RulerTicks.js.map +1 -0
- package/lib/module/RulerTrack.js +41 -0
- package/lib/module/RulerTrack.js.map +1 -0
- package/lib/module/Tick.js +41 -36
- package/lib/module/Tick.js.map +1 -1
- package/lib/module/defaults.js +19 -18
- package/lib/module/defaults.js.map +1 -1
- package/lib/module/index.js +46 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/presets.js +103 -0
- package/lib/module/presets.js.map +1 -0
- package/lib/module/tickResolver.js +97 -0
- package/lib/module/tickResolver.js.map +1 -0
- package/lib/module/useHaptics.js +1 -1
- package/lib/module/useHaptics.js.map +1 -1
- package/lib/module/useHaptics.web.js +39 -0
- package/lib/module/useHaptics.web.js.map +1 -0
- package/lib/module/useRulerDatePicker.js +260 -0
- package/lib/module/useRulerDatePicker.js.map +1 -0
- package/lib/module/useRulerDateRangePicker.js +310 -0
- package/lib/module/useRulerDateRangePicker.js.map +1 -0
- package/lib/module/utils.js +59 -45
- package/lib/module/utils.js.map +1 -1
- package/lib/typescript/LensTick.d.ts +20 -0
- package/lib/typescript/LensTick.d.ts.map +1 -0
- package/lib/typescript/Ruler.d.ts +31 -0
- package/lib/typescript/Ruler.d.ts.map +1 -0
- package/lib/typescript/RulerContext.d.ts +11 -0
- package/lib/typescript/RulerContext.d.ts.map +1 -0
- package/lib/typescript/RulerDatePicker.d.ts +10 -7
- package/lib/typescript/RulerDatePicker.d.ts.map +1 -1
- package/lib/typescript/RulerDateRangePicker.d.ts +26 -0
- package/lib/typescript/RulerDateRangePicker.d.ts.map +1 -0
- package/lib/typescript/RulerHeader.d.ts +14 -0
- package/lib/typescript/RulerHeader.d.ts.map +1 -0
- package/lib/typescript/RulerIndicator.d.ts +17 -0
- package/lib/typescript/RulerIndicator.d.ts.map +1 -0
- package/lib/typescript/RulerLensTicks.d.ts +12 -0
- package/lib/typescript/RulerLensTicks.d.ts.map +1 -0
- package/lib/typescript/RulerLensTrack.d.ts +13 -0
- package/lib/typescript/RulerLensTrack.d.ts.map +1 -0
- package/lib/typescript/RulerRange.d.ts +32 -0
- package/lib/typescript/RulerRange.d.ts.map +1 -0
- package/lib/typescript/RulerRangeContext.d.ts +11 -0
- package/lib/typescript/RulerRangeContext.d.ts.map +1 -0
- package/lib/typescript/RulerRangeHeader.d.ts +12 -0
- package/lib/typescript/RulerRangeHeader.d.ts.map +1 -0
- package/lib/typescript/RulerRangeHighlight.d.ts +8 -0
- package/lib/typescript/RulerRangeHighlight.d.ts.map +1 -0
- package/lib/typescript/RulerRangeIndicator.d.ts +17 -0
- package/lib/typescript/RulerRangeIndicator.d.ts.map +1 -0
- package/lib/typescript/RulerRangeRoot.d.ts +7 -0
- package/lib/typescript/RulerRangeRoot.d.ts.map +1 -0
- package/lib/typescript/RulerRangeTicks.d.ts +14 -0
- package/lib/typescript/RulerRangeTicks.d.ts.map +1 -0
- package/lib/typescript/RulerRangeTrack.d.ts +8 -0
- package/lib/typescript/RulerRangeTrack.d.ts.map +1 -0
- package/lib/typescript/RulerResetButton.d.ts +10 -0
- package/lib/typescript/RulerResetButton.d.ts.map +1 -0
- package/lib/typescript/RulerRoot.d.ts +7 -0
- package/lib/typescript/RulerRoot.d.ts.map +1 -0
- package/lib/typescript/RulerTicks.d.ts +9 -0
- package/lib/typescript/RulerTicks.d.ts.map +1 -0
- package/lib/typescript/RulerTrack.d.ts +8 -0
- package/lib/typescript/RulerTrack.d.ts.map +1 -0
- package/lib/typescript/Tick.d.ts +3 -16
- package/lib/typescript/Tick.d.ts.map +1 -1
- package/lib/typescript/defaults.d.ts +6 -9
- package/lib/typescript/defaults.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +37 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/presets.d.ts +27 -0
- package/lib/typescript/presets.d.ts.map +1 -0
- package/lib/typescript/tickResolver.d.ts +10 -0
- package/lib/typescript/tickResolver.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +302 -85
- package/lib/typescript/types.d.ts.map +1 -1
- package/lib/typescript/useHaptics.web.d.ts +17 -0
- package/lib/typescript/useHaptics.web.d.ts.map +1 -0
- package/lib/typescript/useRulerDatePicker.d.ts +26 -0
- package/lib/typescript/useRulerDatePicker.d.ts.map +1 -0
- package/lib/typescript/useRulerDateRangePicker.d.ts +40 -0
- package/lib/typescript/useRulerDateRangePicker.d.ts.map +1 -0
- package/lib/typescript/utils.d.ts +14 -12
- package/lib/typescript/utils.d.ts.map +1 -1
- package/package.json +25 -7
- package/src/LensTick.tsx +90 -0
- package/src/Ruler.ts +32 -0
- package/src/RulerContext.tsx +20 -0
- package/src/RulerDatePicker.tsx +41 -439
- package/src/RulerDateRangePicker.tsx +53 -0
- package/src/RulerHeader.tsx +125 -0
- package/src/RulerIndicator.tsx +84 -0
- package/src/RulerLensTicks.tsx +50 -0
- package/src/RulerLensTrack.tsx +45 -0
- package/src/RulerRange.ts +33 -0
- package/src/RulerRangeContext.tsx +20 -0
- package/src/RulerRangeHeader.tsx +180 -0
- package/src/RulerRangeHighlight.tsx +47 -0
- package/src/RulerRangeIndicator.tsx +85 -0
- package/src/RulerRangeRoot.tsx +87 -0
- package/src/RulerRangeTicks.tsx +68 -0
- package/src/RulerRangeTrack.tsx +39 -0
- package/src/RulerResetButton.tsx +59 -0
- package/src/RulerRoot.tsx +93 -0
- package/src/RulerTicks.tsx +57 -0
- package/src/RulerTrack.tsx +39 -0
- package/src/Tick.tsx +60 -49
- package/src/defaults.ts +21 -19
- package/src/index.ts +83 -1
- package/src/presets.ts +108 -0
- package/src/tickResolver.ts +123 -0
- package/src/types.ts +354 -102
- package/src/useHaptics.web.ts +55 -0
- package/src/useRulerDatePicker.ts +373 -0
- package/src/useRulerDateRangePicker.ts +468 -0
- package/src/utils.ts +67 -68
- package/lib/commonjs/package.json +0 -1
- package/lib/module/package.json +0 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View, StyleSheet, type StyleProp, type ViewStyle } from 'react-native';
|
|
3
|
+
import { GestureDetector } from 'react-native-gesture-handler';
|
|
4
|
+
import { useRulerRangeContext } from './RulerRangeContext';
|
|
5
|
+
import { RulerRangeIndicator } from './RulerRangeIndicator';
|
|
6
|
+
import { RulerRangeTicks } from './RulerRangeTicks';
|
|
7
|
+
|
|
8
|
+
export interface RulerRangeTrackProps {
|
|
9
|
+
style?: StyleProp<ViewStyle>;
|
|
10
|
+
children?: React.ReactNode;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function RulerRangeTrack({ style, children }: RulerRangeTrackProps = {}) {
|
|
14
|
+
const { panGesture, rulerHeight, width } = useRulerRangeContext();
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<GestureDetector gesture={panGesture}>
|
|
18
|
+
<View style={[styles.rulerContainer, { width, height: rulerHeight }, style]}>
|
|
19
|
+
{children ?? (
|
|
20
|
+
<>
|
|
21
|
+
<RulerRangeIndicator />
|
|
22
|
+
<RulerRangeTicks />
|
|
23
|
+
</>
|
|
24
|
+
)}
|
|
25
|
+
</View>
|
|
26
|
+
</GestureDetector>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const styles = StyleSheet.create({
|
|
31
|
+
rulerContainer: {
|
|
32
|
+
position: 'relative',
|
|
33
|
+
flexDirection: 'row',
|
|
34
|
+
alignItems: 'flex-end',
|
|
35
|
+
justifyContent: 'center',
|
|
36
|
+
overflow: 'hidden',
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
TouchableOpacity,
|
|
4
|
+
Text,
|
|
5
|
+
StyleSheet,
|
|
6
|
+
type StyleProp,
|
|
7
|
+
type ViewStyle,
|
|
8
|
+
type TextStyle,
|
|
9
|
+
} from 'react-native';
|
|
10
|
+
import { useRulerContext } from './RulerContext';
|
|
11
|
+
|
|
12
|
+
export interface RulerResetButtonProps {
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
style?: StyleProp<ViewStyle>;
|
|
15
|
+
textStyle?: StyleProp<TextStyle>;
|
|
16
|
+
label?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function RulerResetButton({
|
|
20
|
+
children,
|
|
21
|
+
style,
|
|
22
|
+
textStyle,
|
|
23
|
+
label = 'Today',
|
|
24
|
+
}: RulerResetButtonProps = {}) {
|
|
25
|
+
const { resetToToday, theme } = useRulerContext();
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<TouchableOpacity
|
|
29
|
+
activeOpacity={0.7}
|
|
30
|
+
onPress={() => resetToToday(true)}
|
|
31
|
+
style={[styles.resetBtn, style]}
|
|
32
|
+
>
|
|
33
|
+
{children ?? (
|
|
34
|
+
<Text
|
|
35
|
+
style={[
|
|
36
|
+
styles.resetText,
|
|
37
|
+
{ color: theme.accentColor },
|
|
38
|
+
textStyle,
|
|
39
|
+
]}
|
|
40
|
+
>
|
|
41
|
+
{label}
|
|
42
|
+
</Text>
|
|
43
|
+
)}
|
|
44
|
+
</TouchableOpacity>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const styles = StyleSheet.create({
|
|
49
|
+
resetBtn: {
|
|
50
|
+
paddingVertical: 6,
|
|
51
|
+
paddingHorizontal: 12,
|
|
52
|
+
borderRadius: 16,
|
|
53
|
+
backgroundColor: 'rgba(0,0,0,0.05)',
|
|
54
|
+
},
|
|
55
|
+
resetText: {
|
|
56
|
+
fontSize: 14,
|
|
57
|
+
fontWeight: '600',
|
|
58
|
+
},
|
|
59
|
+
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View, StyleSheet } from 'react-native';
|
|
3
|
+
import type { RulerDatePickerProps, IndicatorConfig } from './types';
|
|
4
|
+
import { useRulerDatePicker } from './useRulerDatePicker';
|
|
5
|
+
import { RulerContext } from './RulerContext';
|
|
6
|
+
import { DEFAULT_LENS_CONFIG } from './defaults';
|
|
7
|
+
|
|
8
|
+
export interface RulerRootProps extends RulerDatePickerProps {
|
|
9
|
+
children?: React.ReactNode;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function RulerRoot(props: RulerRootProps) {
|
|
13
|
+
const {
|
|
14
|
+
children,
|
|
15
|
+
style,
|
|
16
|
+
indicator,
|
|
17
|
+
lensEffect,
|
|
18
|
+
testID,
|
|
19
|
+
} = props;
|
|
20
|
+
|
|
21
|
+
const ruler = useRulerDatePicker(props);
|
|
22
|
+
|
|
23
|
+
const lensConfig = React.useMemo(() => {
|
|
24
|
+
if (!lensEffect) return null;
|
|
25
|
+
if (typeof lensEffect === 'object') {
|
|
26
|
+
return {
|
|
27
|
+
...DEFAULT_LENS_CONFIG,
|
|
28
|
+
...lensEffect,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return DEFAULT_LENS_CONFIG;
|
|
32
|
+
}, [lensEffect]);
|
|
33
|
+
|
|
34
|
+
const indicatorConfig: IndicatorConfig | undefined =
|
|
35
|
+
typeof indicator === 'object' ? indicator : undefined;
|
|
36
|
+
const headerConfig =
|
|
37
|
+
typeof props.header === 'object' ? props.header : undefined;
|
|
38
|
+
|
|
39
|
+
const contextValue = {
|
|
40
|
+
...ruler,
|
|
41
|
+
indicatorConfig,
|
|
42
|
+
headerConfig,
|
|
43
|
+
locale: props.locale,
|
|
44
|
+
lensConfig,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<RulerContext.Provider value={contextValue}>
|
|
49
|
+
<View
|
|
50
|
+
testID={testID}
|
|
51
|
+
accessible={true}
|
|
52
|
+
accessibilityRole="adjustable"
|
|
53
|
+
accessibilityLabel={props.accessibilityLabel ?? 'Date picker'}
|
|
54
|
+
accessibilityValue={{ text: ruler.selectedDateStr }}
|
|
55
|
+
accessibilityActions={[
|
|
56
|
+
{ name: 'increment', label: 'Next day' },
|
|
57
|
+
{ name: 'decrement', label: 'Previous day' },
|
|
58
|
+
]}
|
|
59
|
+
onAccessibilityAction={(event) => {
|
|
60
|
+
if (event.nativeEvent.actionName === 'increment') {
|
|
61
|
+
const next = new Date(ruler.selectedDate);
|
|
62
|
+
next.setDate(next.getDate() + 1);
|
|
63
|
+
ruler.scrollToDate(next, true);
|
|
64
|
+
} else if (event.nativeEvent.actionName === 'decrement') {
|
|
65
|
+
const prev = new Date(ruler.selectedDate);
|
|
66
|
+
prev.setDate(prev.getDate() - 1);
|
|
67
|
+
ruler.scrollToDate(prev, true);
|
|
68
|
+
}
|
|
69
|
+
}}
|
|
70
|
+
style={[
|
|
71
|
+
styles.container,
|
|
72
|
+
{
|
|
73
|
+
minHeight: ruler.height,
|
|
74
|
+
backgroundColor: ruler.theme.background,
|
|
75
|
+
},
|
|
76
|
+
style,
|
|
77
|
+
]}
|
|
78
|
+
>
|
|
79
|
+
{children}
|
|
80
|
+
</View>
|
|
81
|
+
</RulerContext.Provider>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const styles = StyleSheet.create({
|
|
86
|
+
container: {
|
|
87
|
+
justifyContent: 'center',
|
|
88
|
+
alignItems: 'center',
|
|
89
|
+
position: 'relative',
|
|
90
|
+
width: '100%',
|
|
91
|
+
paddingVertical: 8,
|
|
92
|
+
},
|
|
93
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StyleSheet, type StyleProp, type ViewStyle } from 'react-native';
|
|
3
|
+
import Animated, { useAnimatedStyle } from 'react-native-reanimated';
|
|
4
|
+
import { useRulerContext } from './RulerContext';
|
|
5
|
+
import { Tick } from './Tick';
|
|
6
|
+
import type { ResolvedTick } from './types';
|
|
7
|
+
|
|
8
|
+
export interface RulerTicksProps {
|
|
9
|
+
style?: StyleProp<ViewStyle>;
|
|
10
|
+
renderTick?: (tick: ResolvedTick, tickSpacing: number, rulerHeight: number) => React.ReactNode;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function RulerTicks({ style, renderTick }: RulerTicksProps = {}) {
|
|
14
|
+
const { translateX, visibleTicks, tickSpacing, rulerHeight, width } =
|
|
15
|
+
useRulerContext();
|
|
16
|
+
|
|
17
|
+
const animatedStyle = useAnimatedStyle(
|
|
18
|
+
() => ({
|
|
19
|
+
transform: [{ translateX: translateX.value }],
|
|
20
|
+
}),
|
|
21
|
+
[translateX]
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Animated.View
|
|
26
|
+
style={[
|
|
27
|
+
styles.ticksWrapper,
|
|
28
|
+
{ left: width / 2 },
|
|
29
|
+
animatedStyle,
|
|
30
|
+
style,
|
|
31
|
+
]}
|
|
32
|
+
>
|
|
33
|
+
{visibleTicks.map((tick) =>
|
|
34
|
+
renderTick ? (
|
|
35
|
+
<React.Fragment key={tick.offset}>
|
|
36
|
+
{renderTick(tick, tickSpacing, rulerHeight)}
|
|
37
|
+
</React.Fragment>
|
|
38
|
+
) : (
|
|
39
|
+
<Tick
|
|
40
|
+
key={tick.offset}
|
|
41
|
+
tick={tick}
|
|
42
|
+
tickSpacing={tickSpacing}
|
|
43
|
+
rulerHeight={rulerHeight}
|
|
44
|
+
/>
|
|
45
|
+
)
|
|
46
|
+
)}
|
|
47
|
+
</Animated.View>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const styles = StyleSheet.create({
|
|
52
|
+
ticksWrapper: {
|
|
53
|
+
position: 'absolute',
|
|
54
|
+
height: '100%',
|
|
55
|
+
width: 0,
|
|
56
|
+
},
|
|
57
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View, StyleSheet, type StyleProp, type ViewStyle } from 'react-native';
|
|
3
|
+
import { GestureDetector } from 'react-native-gesture-handler';
|
|
4
|
+
import { useRulerContext } from './RulerContext';
|
|
5
|
+
|
|
6
|
+
import { RulerIndicator } from './RulerIndicator';
|
|
7
|
+
import { RulerTicks } from './RulerTicks';
|
|
8
|
+
|
|
9
|
+
export interface RulerTrackProps {
|
|
10
|
+
children?: React.ReactNode;
|
|
11
|
+
style?: StyleProp<ViewStyle>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function RulerTrack({ children, style }: RulerTrackProps = {}) {
|
|
15
|
+
const { panGesture, rulerHeight, width } = useRulerContext();
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<GestureDetector gesture={panGesture}>
|
|
19
|
+
<View style={[styles.rulerContainer, { width, height: rulerHeight }, style]}>
|
|
20
|
+
{children ?? (
|
|
21
|
+
<>
|
|
22
|
+
<RulerIndicator />
|
|
23
|
+
<RulerTicks />
|
|
24
|
+
</>
|
|
25
|
+
)}
|
|
26
|
+
</View>
|
|
27
|
+
</GestureDetector>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const styles = StyleSheet.create({
|
|
32
|
+
rulerContainer: {
|
|
33
|
+
position: 'relative',
|
|
34
|
+
flexDirection: 'row',
|
|
35
|
+
alignItems: 'flex-end',
|
|
36
|
+
justifyContent: 'center',
|
|
37
|
+
overflow: 'hidden',
|
|
38
|
+
},
|
|
39
|
+
});
|
package/src/Tick.tsx
CHANGED
|
@@ -1,50 +1,45 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { View, Text, StyleSheet } from 'react-native';
|
|
3
|
-
import type {
|
|
3
|
+
import type { ResolvedTick } from './types';
|
|
4
4
|
|
|
5
5
|
export interface TickProps {
|
|
6
|
-
|
|
7
|
-
isLabeled: boolean;
|
|
8
|
-
isToday: boolean;
|
|
9
|
-
isHighlighted: boolean;
|
|
10
|
-
dateStr: string;
|
|
6
|
+
tick: ResolvedTick;
|
|
11
7
|
tickSpacing: number;
|
|
12
|
-
tickHeight: number;
|
|
13
|
-
tickTallHeight: number;
|
|
14
|
-
tickThickness: number;
|
|
15
|
-
tickColor: string;
|
|
16
|
-
tickTallColor: string;
|
|
17
|
-
labelColor: string;
|
|
18
|
-
accentColor: string;
|
|
19
|
-
todayDotSize: number;
|
|
20
|
-
labelFontSize: number;
|
|
21
8
|
rulerHeight: number;
|
|
22
9
|
}
|
|
23
10
|
|
|
24
11
|
/**
|
|
25
12
|
* Memoized single tick component.
|
|
26
|
-
* Renders a vertical bar with optional label
|
|
27
|
-
* Small and large ticks can be independently colored.
|
|
13
|
+
* Renders a vertical tick bar with optional label, dot indicator, or custom render element.
|
|
28
14
|
*/
|
|
29
15
|
export const Tick = React.memo(function Tick({
|
|
30
|
-
|
|
31
|
-
isLabeled,
|
|
32
|
-
isToday,
|
|
33
|
-
dateStr,
|
|
16
|
+
tick,
|
|
34
17
|
tickSpacing,
|
|
35
|
-
tickHeight,
|
|
36
|
-
tickTallHeight,
|
|
37
|
-
tickThickness,
|
|
38
|
-
tickColor,
|
|
39
|
-
tickTallColor,
|
|
40
|
-
labelColor,
|
|
41
|
-
accentColor,
|
|
42
|
-
todayDotSize,
|
|
43
|
-
labelFontSize,
|
|
44
18
|
rulerHeight,
|
|
45
19
|
}: TickProps) {
|
|
46
|
-
|
|
47
|
-
|
|
20
|
+
if (tick.customRender) {
|
|
21
|
+
return (
|
|
22
|
+
<View
|
|
23
|
+
style={[
|
|
24
|
+
styles.tickContainer,
|
|
25
|
+
{
|
|
26
|
+
width: tickSpacing,
|
|
27
|
+
height: rulerHeight,
|
|
28
|
+
position: 'absolute',
|
|
29
|
+
left: tick.offset * tickSpacing - tickSpacing / 2,
|
|
30
|
+
},
|
|
31
|
+
]}
|
|
32
|
+
>
|
|
33
|
+
{tick.customRender({
|
|
34
|
+
date: tick.date,
|
|
35
|
+
offset: tick.offset,
|
|
36
|
+
isToday: tick.isToday,
|
|
37
|
+
isSelected: tick.isSelected,
|
|
38
|
+
isInRange: tick.isInRange,
|
|
39
|
+
})}
|
|
40
|
+
</View>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
48
43
|
|
|
49
44
|
return (
|
|
50
45
|
<View
|
|
@@ -54,34 +49,50 @@ export const Tick = React.memo(function Tick({
|
|
|
54
49
|
width: tickSpacing,
|
|
55
50
|
height: rulerHeight,
|
|
56
51
|
position: 'absolute',
|
|
57
|
-
left: offset * tickSpacing - tickSpacing / 2,
|
|
52
|
+
left: tick.offset * tickSpacing - tickSpacing / 2,
|
|
58
53
|
},
|
|
59
54
|
]}
|
|
60
55
|
>
|
|
61
|
-
{
|
|
62
|
-
|
|
63
|
-
|
|
56
|
+
{/* Label */}
|
|
57
|
+
{tick.labelText !== undefined && (
|
|
58
|
+
<Text
|
|
59
|
+
numberOfLines={1}
|
|
60
|
+
style={[
|
|
61
|
+
styles.tickLabel,
|
|
62
|
+
{
|
|
63
|
+
color: tick.labelColor,
|
|
64
|
+
fontSize: tick.labelFontSize,
|
|
65
|
+
fontWeight: tick.labelFontWeight,
|
|
66
|
+
},
|
|
67
|
+
]}
|
|
68
|
+
>
|
|
69
|
+
{tick.labelText}
|
|
64
70
|
</Text>
|
|
65
71
|
)}
|
|
66
|
-
|
|
72
|
+
|
|
73
|
+
{/* Dot Badge */}
|
|
74
|
+
{tick.hasDot && (
|
|
67
75
|
<View
|
|
68
76
|
style={[
|
|
69
|
-
styles.
|
|
77
|
+
styles.dot,
|
|
70
78
|
{
|
|
71
|
-
backgroundColor:
|
|
72
|
-
width:
|
|
73
|
-
height:
|
|
74
|
-
borderRadius:
|
|
79
|
+
backgroundColor: tick.dotColor,
|
|
80
|
+
width: tick.dotSize,
|
|
81
|
+
height: tick.dotSize,
|
|
82
|
+
borderRadius: tick.dotSize / 2,
|
|
83
|
+
bottom: tick.height + 4,
|
|
75
84
|
},
|
|
76
85
|
]}
|
|
77
86
|
/>
|
|
78
87
|
)}
|
|
88
|
+
|
|
89
|
+
{/* Bar */}
|
|
79
90
|
<View
|
|
80
91
|
style={{
|
|
81
|
-
backgroundColor:
|
|
82
|
-
width:
|
|
83
|
-
height:
|
|
84
|
-
borderRadius:
|
|
92
|
+
backgroundColor: tick.color,
|
|
93
|
+
width: tick.width,
|
|
94
|
+
height: tick.height,
|
|
95
|
+
borderRadius: tick.width / 2,
|
|
85
96
|
}}
|
|
86
97
|
/>
|
|
87
98
|
</View>
|
|
@@ -95,10 +106,10 @@ const styles = StyleSheet.create({
|
|
|
95
106
|
},
|
|
96
107
|
tickLabel: {
|
|
97
108
|
position: 'absolute',
|
|
98
|
-
top:
|
|
109
|
+
top: 6,
|
|
110
|
+
textAlign: 'center',
|
|
99
111
|
},
|
|
100
|
-
|
|
112
|
+
dot: {
|
|
101
113
|
position: 'absolute',
|
|
102
|
-
top: 25,
|
|
103
114
|
},
|
|
104
115
|
});
|
package/src/defaults.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ResolvedRulerTheme, LensConfig } from './types';
|
|
2
2
|
|
|
3
3
|
// ── Internal constants (not user-configurable) ───────────────────────────
|
|
4
4
|
export const MS_PER_DAY = 86_400_000;
|
|
@@ -7,38 +7,40 @@ export const DEFAULT_DAY_RANGE = 365;
|
|
|
7
7
|
// ── User-configurable defaults ───────────────────────────────────────────
|
|
8
8
|
export const DEFAULTS = {
|
|
9
9
|
tickSpacing: 24,
|
|
10
|
-
|
|
11
|
-
tickTallHeight: 24,
|
|
12
|
-
tickThickness: 4,
|
|
10
|
+
tickWidth: 3,
|
|
13
11
|
height: 120,
|
|
14
12
|
rulerHeight: 60,
|
|
15
13
|
indicatorWidth: 2,
|
|
16
14
|
indicatorHeight: 40,
|
|
17
15
|
todayDotSize: 6,
|
|
18
|
-
labelFontSize: 10,
|
|
19
16
|
bufferTicks: 10,
|
|
20
|
-
|
|
17
|
+
debounceMs: 100,
|
|
21
18
|
fastSwipeTickThreshold: 1,
|
|
22
19
|
continuousHapticIntervalMs: 20,
|
|
23
|
-
enableHaptics: true,
|
|
24
20
|
showResetToToday: false,
|
|
25
21
|
} as const;
|
|
26
22
|
|
|
23
|
+
export const DEFAULT_LENS_CONFIG: Required<LensConfig> = {
|
|
24
|
+
magnification: 1.6,
|
|
25
|
+
radius: 60,
|
|
26
|
+
scaleTicks: true,
|
|
27
|
+
};
|
|
28
|
+
|
|
27
29
|
// ── Default color palettes ───────────────────────────────────────────────
|
|
28
|
-
export const
|
|
29
|
-
|
|
30
|
-
tickTallColor: '#9CA3AF',
|
|
31
|
-
labelColor: '#6B7280',
|
|
32
|
-
accentColor: '#3B82F6',
|
|
30
|
+
export const LIGHT_THEME: ResolvedRulerTheme = {
|
|
31
|
+
background: 'transparent',
|
|
33
32
|
indicatorColor: '#3B82F6',
|
|
34
|
-
|
|
33
|
+
accentColor: '#3B82F6',
|
|
34
|
+
labelColor: '#6B7280',
|
|
35
|
+
defaultTickColor: '#D1D5DB',
|
|
36
|
+
rangeHighlightColor: 'rgba(59, 130, 246, 0.15)',
|
|
35
37
|
};
|
|
36
38
|
|
|
37
|
-
export const
|
|
38
|
-
|
|
39
|
-
tickTallColor: '#6B7280',
|
|
40
|
-
labelColor: '#9CA3AF',
|
|
41
|
-
accentColor: '#60A5FA',
|
|
39
|
+
export const DARK_THEME: ResolvedRulerTheme = {
|
|
40
|
+
background: 'transparent',
|
|
42
41
|
indicatorColor: '#60A5FA',
|
|
43
|
-
|
|
42
|
+
accentColor: '#60A5FA',
|
|
43
|
+
labelColor: '#9CA3AF',
|
|
44
|
+
defaultTickColor: '#4B5563',
|
|
45
|
+
rangeHighlightColor: 'rgba(96, 165, 250, 0.2)',
|
|
44
46
|
};
|
package/src/index.ts
CHANGED
|
@@ -1,2 +1,84 @@
|
|
|
1
|
+
// ── Components ─────────────────────────────────────────────────────────────
|
|
1
2
|
export { RulerDatePicker } from './RulerDatePicker';
|
|
2
|
-
|
|
3
|
+
/** @experimental */
|
|
4
|
+
export { RulerDateRangePicker } from './RulerDateRangePicker';
|
|
5
|
+
export { Ruler } from './Ruler';
|
|
6
|
+
/** @experimental */
|
|
7
|
+
export { RulerRange } from './RulerRange';
|
|
8
|
+
export { Tick } from './Tick';
|
|
9
|
+
export { RulerLensTrack } from './RulerLensTrack';
|
|
10
|
+
export { RulerLensTicks } from './RulerLensTicks';
|
|
11
|
+
export { LensTick } from './LensTick';
|
|
12
|
+
|
|
13
|
+
// ── Compound Subcomponents ──────────────────────────────────────────────────
|
|
14
|
+
export { RulerRoot, type RulerRootProps } from './RulerRoot';
|
|
15
|
+
export { RulerTrack, type RulerTrackProps } from './RulerTrack';
|
|
16
|
+
export { RulerIndicator, type RulerIndicatorProps } from './RulerIndicator';
|
|
17
|
+
export { RulerTicks, type RulerTicksProps } from './RulerTicks';
|
|
18
|
+
export { RulerHeader, type RulerHeaderProps } from './RulerHeader';
|
|
19
|
+
export { RulerResetButton, type RulerResetButtonProps } from './RulerResetButton';
|
|
20
|
+
|
|
21
|
+
// ── Compound Subcomponents [EXPERIMENTAL] ───────────────────────────────────
|
|
22
|
+
export { RulerRangeRoot, type RulerRangeRootProps } from './RulerRangeRoot';
|
|
23
|
+
export { RulerRangeTrack, type RulerRangeTrackProps } from './RulerRangeTrack';
|
|
24
|
+
export { RulerRangeIndicator, type RulerRangeIndicatorProps } from './RulerRangeIndicator';
|
|
25
|
+
export { RulerRangeHeader, type RulerRangeHeaderProps } from './RulerRangeHeader';
|
|
26
|
+
export { RulerRangeHighlight, type RulerRangeHighlightProps } from './RulerRangeHighlight';
|
|
27
|
+
export { RulerRangeTicks, type RulerRangeTicksProps } from './RulerRangeTicks';
|
|
28
|
+
|
|
29
|
+
// ── Headless Hooks & Contexts ───────────────────────────────────────────────
|
|
30
|
+
export { useRulerDatePicker, type UseRulerDatePickerReturn } from './useRulerDatePicker';
|
|
31
|
+
/** @experimental */
|
|
32
|
+
export { useRulerDateRangePicker, type UseRulerDateRangePickerReturn } from './useRulerDateRangePicker';
|
|
33
|
+
export { useHaptics } from './useHaptics';
|
|
34
|
+
export { RulerContext, useRulerContext, type RulerContextValue } from './RulerContext';
|
|
35
|
+
/** @experimental */
|
|
36
|
+
export { RulerRangeContext, useRulerRangeContext, type RulerRangeContextValue } from './RulerRangeContext';
|
|
37
|
+
|
|
38
|
+
// ── Presets & Resolvers ───────────────────────────────────────────────────
|
|
39
|
+
export {
|
|
40
|
+
DEFAULT_CALENDAR_TICKS,
|
|
41
|
+
DEFAULT_METRIC_TICKS,
|
|
42
|
+
DEFAULT_MINIMAL_TICKS,
|
|
43
|
+
resolveTickRules,
|
|
44
|
+
} from './presets';
|
|
45
|
+
export { resolveTick, matchesCondition } from './tickResolver';
|
|
46
|
+
|
|
47
|
+
// ── Utilities & Constants ─────────────────────────────────────────────────
|
|
48
|
+
export {
|
|
49
|
+
formatDateString,
|
|
50
|
+
normalizeDate,
|
|
51
|
+
dateToDayOffset,
|
|
52
|
+
dayOffsetToDate,
|
|
53
|
+
computeDayRange,
|
|
54
|
+
useResolvedTheme,
|
|
55
|
+
} from './utils';
|
|
56
|
+
export { DEFAULTS, DEFAULT_LENS_CONFIG, LIGHT_THEME, DARK_THEME, MS_PER_DAY } from './defaults';
|
|
57
|
+
|
|
58
|
+
// ── Types ──────────────────────────────────────────────────────────────────
|
|
59
|
+
export type {
|
|
60
|
+
TickContext,
|
|
61
|
+
TickCondition,
|
|
62
|
+
TickLabelConfig,
|
|
63
|
+
TickDotConfig,
|
|
64
|
+
TickRule,
|
|
65
|
+
ResolvedTick,
|
|
66
|
+
RulerTheme,
|
|
67
|
+
ResolvedRulerTheme,
|
|
68
|
+
IndicatorConfig,
|
|
69
|
+
HeaderConfig,
|
|
70
|
+
RangeHeaderConfig,
|
|
71
|
+
RangeHeaderContext,
|
|
72
|
+
RangeHighlightConfig,
|
|
73
|
+
RangeIndicatorConfig,
|
|
74
|
+
HapticConfig,
|
|
75
|
+
RulerDatePickerProps,
|
|
76
|
+
LensConfig,
|
|
77
|
+
DateRange,
|
|
78
|
+
DateRangeChangePayload,
|
|
79
|
+
RulerDateRangePickerProps,
|
|
80
|
+
} from './types';
|
|
81
|
+
export type { LensTickProps } from './LensTick';
|
|
82
|
+
export type { RulerLensTrackProps } from './RulerLensTrack';
|
|
83
|
+
export type { RulerLensTicksProps } from './RulerLensTicks';
|
|
84
|
+
export type { TickProps } from './Tick';
|