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
package/src/types.ts
CHANGED
|
@@ -1,129 +1,381 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
|
+
import type { StyleProp, ViewStyle, TextStyle } from 'react-native';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
4
|
+
// ── Tick System Types ────────────────────────────────────────────────────────
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Context provided to each tick rule during evaluation.
|
|
8
|
+
*/
|
|
9
|
+
export interface TickContext {
|
|
10
|
+
/** The Date represented by this tick */
|
|
11
|
+
date: Date;
|
|
12
|
+
/** Day offset relative to reference time (0 = today) */
|
|
13
|
+
offset: number;
|
|
14
|
+
/** True if this date is today */
|
|
15
|
+
isToday: boolean;
|
|
16
|
+
/** True if this date matches the currently selected date */
|
|
17
|
+
isSelected: boolean;
|
|
18
|
+
/** True if this date falls within the selected range (range picker mode) */
|
|
19
|
+
isInRange?: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Predicate condition determining when a tick rule matches.
|
|
24
|
+
*/
|
|
25
|
+
export type TickCondition =
|
|
26
|
+
| 'daily' // Matches every day (base / fallback)
|
|
27
|
+
| 'weekly' // Every 7th day relative to reference
|
|
28
|
+
| 'monthly' // 1st day of each month
|
|
29
|
+
| 'yearly' // Jan 1st of each year
|
|
30
|
+
| { interval: number } // Every N days (offset % interval === 0)
|
|
31
|
+
| { dayOfWeek: number[] } // Days of week: 0 = Sun, 1 = Mon, ..., 6 = Sat
|
|
32
|
+
| ((ctx: TickContext) => boolean); // Custom predicate callback
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Configuration for tick date labels.
|
|
36
|
+
*/
|
|
37
|
+
export interface TickLabelConfig {
|
|
38
|
+
/** Custom label text formatter */
|
|
39
|
+
format?: (date: Date, ctx: TickContext) => string;
|
|
40
|
+
/** Text color override */
|
|
41
|
+
color?: string;
|
|
42
|
+
/** Font size in pixels (default: 10) */
|
|
43
|
+
fontSize?: number;
|
|
44
|
+
/** Font weight */
|
|
45
|
+
fontWeight?: TextStyle['fontWeight'];
|
|
46
|
+
}
|
|
16
47
|
|
|
17
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Configuration for the dot indicator (e.g. today dot or milestone badge).
|
|
50
|
+
*/
|
|
51
|
+
export interface TickDotConfig {
|
|
52
|
+
/** Dot diameter in pixels (default: 6) */
|
|
53
|
+
size?: number;
|
|
54
|
+
/** Dot fill color */
|
|
55
|
+
color?: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Complete declarative definition for a tick variant.
|
|
60
|
+
* Evaluated top-to-bottom; first matching rule is applied.
|
|
61
|
+
*/
|
|
62
|
+
export interface TickRule {
|
|
18
63
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* - `'weekly'` (default) — every 7th day
|
|
22
|
-
* - `'monthly'` — 1st of each month
|
|
23
|
-
* - `(date: Date) => boolean` — custom callback
|
|
64
|
+
* When this rule applies.
|
|
65
|
+
* If omitted, this rule matches unconditionally (serves as the fallback).
|
|
24
66
|
*/
|
|
25
|
-
|
|
26
|
-
/** Days of the week to visually highlight. 0 = Sunday, 6 = Saturday. e.g. [0, 6] for weekends. */
|
|
27
|
-
highlightDays?: number[];
|
|
67
|
+
condition?: TickCondition;
|
|
28
68
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
69
|
+
/** Height of the tick bar in pixels */
|
|
70
|
+
height: number;
|
|
71
|
+
|
|
72
|
+
/** Width/thickness of the tick bar in pixels (defaults to tickWidth or 3) */
|
|
73
|
+
width?: number;
|
|
74
|
+
|
|
75
|
+
/** Color of the tick bar */
|
|
76
|
+
color?: string;
|
|
77
|
+
|
|
78
|
+
/** Label configuration or boolean (true uses day number) */
|
|
79
|
+
label?: boolean | TickLabelConfig;
|
|
80
|
+
|
|
81
|
+
/** Dot badge indicator (e.g., today marker) */
|
|
82
|
+
dot?: boolean | TickDotConfig;
|
|
83
|
+
|
|
84
|
+
/** Custom React component render override for this tick */
|
|
85
|
+
render?: (ctx: TickContext) => React.ReactNode;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Resolved visual attributes for rendering a single tick.
|
|
90
|
+
*/
|
|
91
|
+
export interface ResolvedTick {
|
|
92
|
+
offset: number;
|
|
93
|
+
date: Date;
|
|
94
|
+
dateStr: string;
|
|
95
|
+
height: number;
|
|
96
|
+
width: number;
|
|
97
|
+
color: string;
|
|
98
|
+
labelText?: string;
|
|
99
|
+
labelColor: string;
|
|
100
|
+
labelFontSize: number;
|
|
101
|
+
labelFontWeight: TextStyle['fontWeight'];
|
|
102
|
+
hasDot: boolean;
|
|
103
|
+
dotSize: number;
|
|
104
|
+
dotColor: string;
|
|
105
|
+
customRender?: (ctx: TickContext) => React.ReactNode;
|
|
106
|
+
isToday: boolean;
|
|
107
|
+
isSelected: boolean;
|
|
108
|
+
isInRange: boolean;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ── Theming & Styling ────────────────────────────────────────────────────────
|
|
112
|
+
|
|
113
|
+
export interface RulerTheme {
|
|
114
|
+
/** Background color of the picker component */
|
|
115
|
+
background?: string;
|
|
116
|
+
/** Color of the center selection needle */
|
|
51
117
|
indicatorColor?: string;
|
|
52
|
-
/**
|
|
53
|
-
|
|
118
|
+
/** Primary accent color (used for today dot, active labels, etc.) */
|
|
119
|
+
accentColor?: string;
|
|
120
|
+
/** Default label text color */
|
|
121
|
+
labelColor?: string;
|
|
122
|
+
/** Default tick bar color when not overridden by a rule */
|
|
123
|
+
defaultTickColor?: string;
|
|
124
|
+
/** Color for range selection connecting bar in range mode */
|
|
125
|
+
rangeHighlightColor?: string;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export type ResolvedRulerTheme = Required<RulerTheme>;
|
|
129
|
+
|
|
130
|
+
// ── Single Picker Props ──────────────────────────────────────────────────────
|
|
54
131
|
|
|
55
|
-
|
|
56
|
-
|
|
132
|
+
/**
|
|
133
|
+
* Configuration for the center alignment needle indicator.
|
|
134
|
+
*/
|
|
135
|
+
export interface IndicatorConfig {
|
|
136
|
+
/** Width of the center indicator needle in pixels (default: 2) */
|
|
137
|
+
width?: number;
|
|
138
|
+
/** Height of the center indicator needle in pixels (default: 40) */
|
|
57
139
|
height?: number;
|
|
58
|
-
/**
|
|
59
|
-
|
|
60
|
-
/** Width of the center selection indicator bar in pixels. Default: 2 */
|
|
61
|
-
indicatorWidth?: number;
|
|
62
|
-
/** Height of the center selection indicator bar in pixels. Default: 40 */
|
|
63
|
-
indicatorHeight?: number;
|
|
64
|
-
/** Diameter of the today dot indicator in pixels. Default: 6 */
|
|
65
|
-
todayDotSize?: number;
|
|
66
|
-
/** Font size of tick date labels in pixels. Default: 10 */
|
|
67
|
-
labelFontSize?: number;
|
|
68
|
-
|
|
69
|
-
// ── Performance Tuning ────────────────────────────────────
|
|
70
|
-
/** Number of off-screen ticks to render as buffer on each side. Default: 10 */
|
|
71
|
-
bufferTicks?: number;
|
|
72
|
-
/** Debounce interval in ms before calling onSelectDate. Default: 100 */
|
|
73
|
-
updateDebounceMs?: number;
|
|
74
|
-
|
|
75
|
-
// ── Haptic Tuning ─────────────────────────────────────────
|
|
76
|
-
/** Enable or disable haptic feedback. Default: true */
|
|
77
|
-
enableHaptics?: boolean;
|
|
140
|
+
/** Color of the center indicator needle */
|
|
141
|
+
color?: string;
|
|
78
142
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* - `'tick'` — single discrete haptic (slow scrolling)
|
|
82
|
-
* - `'continuous'` — continuous buzz (fast scrolling)
|
|
143
|
+
* Offset [x, y] in pixels of the center needle pointer.
|
|
144
|
+
* Default: [0, 0] (anchored to bottom).
|
|
83
145
|
*/
|
|
84
|
-
|
|
85
|
-
/**
|
|
146
|
+
offset?: [number, number];
|
|
147
|
+
/** Custom style for the center indicator needle */
|
|
148
|
+
style?: StyleProp<ViewStyle>;
|
|
149
|
+
/** Custom renderer for the center indicator */
|
|
150
|
+
render?: () => React.ReactNode;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Configuration for the date picker header.
|
|
155
|
+
*/
|
|
156
|
+
export interface HeaderConfig {
|
|
157
|
+
/** Show "Today" reset button when not on today (default: false) */
|
|
158
|
+
showResetToToday?: boolean;
|
|
159
|
+
/** Text label for the reset button (default: 'Today') */
|
|
160
|
+
resetLabel?: string;
|
|
161
|
+
/** Header container style */
|
|
162
|
+
style?: StyleProp<ViewStyle>;
|
|
163
|
+
/** Header date label style */
|
|
164
|
+
dateStyle?: StyleProp<TextStyle>;
|
|
165
|
+
/** Header year label style */
|
|
166
|
+
yearStyle?: StyleProp<TextStyle>;
|
|
167
|
+
/** Custom date format function for the header text */
|
|
168
|
+
format?: (date: Date) => string;
|
|
169
|
+
/** Custom header renderer replacing the default header */
|
|
170
|
+
render?: (
|
|
171
|
+
selectedDate: Date,
|
|
172
|
+
isToday: boolean,
|
|
173
|
+
resetToToday: () => void
|
|
174
|
+
) => React.ReactNode;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Configuration for tactile haptic feedback.
|
|
179
|
+
*/
|
|
180
|
+
export interface HapticConfig {
|
|
181
|
+
/** Whether haptics are enabled (default: true) */
|
|
182
|
+
enabled?: boolean;
|
|
183
|
+
/** Custom haptic callback (e.g. for Expo Haptics) */
|
|
184
|
+
onTrigger?: (mode: 'tick' | 'continuous') => void;
|
|
185
|
+
/** Speed threshold (ticks/frame) to trigger continuous buzz mode (default: 1) */
|
|
86
186
|
fastSwipeTickThreshold?: number;
|
|
87
|
-
/**
|
|
187
|
+
/** Pulse interval in ms during continuous haptic mode (default: 20) */
|
|
88
188
|
continuousHapticIntervalMs?: number;
|
|
189
|
+
}
|
|
89
190
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
191
|
+
export interface RulerDatePickerProps {
|
|
192
|
+
// ── Value & Selection ──
|
|
193
|
+
/** Currently selected date (controlled). Accepts Date or YYYY-MM-DD string. */
|
|
194
|
+
value?: Date | string;
|
|
195
|
+
/** Initial selected date (uncontrolled). Accepts Date or YYYY-MM-DD string. */
|
|
196
|
+
defaultValue?: Date | string;
|
|
197
|
+
/** Called when user scrolls to a date */
|
|
198
|
+
onChange?: (date: Date, dateString: string) => void;
|
|
199
|
+
/** Minimum selectable date */
|
|
200
|
+
minDate?: Date | string;
|
|
201
|
+
/** Maximum selectable date */
|
|
202
|
+
maxDate?: Date | string;
|
|
203
|
+
/** BCP 47 locale string for date formatting (default: system 'default') */
|
|
204
|
+
locale?: string;
|
|
205
|
+
|
|
206
|
+
// ── Tick Configuration ──
|
|
207
|
+
/** Array of tick rules or a preset name ('calendar' | 'metric' | 'minimal') */
|
|
208
|
+
ticks?: TickRule[] | 'calendar' | 'metric' | 'minimal';
|
|
209
|
+
/** Distance in pixels between tick centers (default: 24) */
|
|
210
|
+
tickSpacing?: number;
|
|
211
|
+
/** Base width of tick bars in pixels (default: 3) */
|
|
212
|
+
tickWidth?: number;
|
|
213
|
+
|
|
214
|
+
// ── Dimensions & Theming ──
|
|
215
|
+
/** Width of the ruler viewport track in pixels (default: window width) */
|
|
216
|
+
width?: number;
|
|
217
|
+
/** Height of the ruler track area in pixels (default: 60) */
|
|
218
|
+
rulerHeight?: number;
|
|
219
|
+
/** Color theme overrides (background, indicatorColor, accentColor, labelColor, etc.) */
|
|
220
|
+
theme?: RulerTheme;
|
|
221
|
+
/** Container style */
|
|
222
|
+
style?: StyleProp<ViewStyle>;
|
|
93
223
|
|
|
94
|
-
// ──
|
|
224
|
+
// ── Indicator, Header, & Haptics (Consolidated APIs) ──
|
|
225
|
+
/** Center indicator needle configuration or boolean toggle (default: true) */
|
|
226
|
+
indicator?: boolean | IndicatorConfig;
|
|
227
|
+
/** Header configuration or boolean toggle (default: true) */
|
|
228
|
+
header?: boolean | HeaderConfig;
|
|
229
|
+
/** Haptics configuration or boolean toggle (default: true) */
|
|
230
|
+
haptics?: boolean | HapticConfig;
|
|
231
|
+
|
|
232
|
+
// ── Fisheye Lens Effect ──
|
|
95
233
|
/**
|
|
96
|
-
*
|
|
97
|
-
*
|
|
234
|
+
* Enable non-linear fisheye lens distortion where tick spacing is wider near the center
|
|
235
|
+
* needle and gradually flattens out to standard spacing away from the center.
|
|
236
|
+
* Can be true (for default configuration) or a custom LensConfig object.
|
|
98
237
|
*/
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
238
|
+
lensEffect?: boolean | LensConfig;
|
|
239
|
+
|
|
240
|
+
// ── Performance ──
|
|
241
|
+
/** Debounce ms for onChange during scrolling (default: 100) */
|
|
242
|
+
debounceMs?: number;
|
|
243
|
+
|
|
244
|
+
/** Test ID for automated tests */
|
|
245
|
+
testID?: string;
|
|
246
|
+
/** Accessibility label for assistive technologies / screen readers */
|
|
247
|
+
accessibilityLabel?: string;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// ── Fisheye Lens Types ───────────────────────────────────────────────────────
|
|
251
|
+
|
|
252
|
+
export interface LensConfig {
|
|
253
|
+
/**
|
|
254
|
+
* Spacing magnification factor at the center needle.
|
|
255
|
+
* (e.g. 1.6 means 60% wider spacing at the needle).
|
|
256
|
+
* Default: 1.6
|
|
257
|
+
*/
|
|
258
|
+
magnification?: number;
|
|
259
|
+
/**
|
|
260
|
+
* Radius in pixels around the center needle over which the magnification
|
|
261
|
+
* smoothly transitions back to standard linear spacing.
|
|
262
|
+
* Default: 60
|
|
263
|
+
*/
|
|
264
|
+
radius?: number;
|
|
265
|
+
/**
|
|
266
|
+
* Whether to subtly scale tick bar height and label prominence near the center.
|
|
267
|
+
* Default: true
|
|
268
|
+
*/
|
|
269
|
+
scaleTicks?: boolean;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// ── Range Picker Types [EXPERIMENTAL] ────────────────────────────────────────
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Date range boundaries representation.
|
|
276
|
+
*
|
|
277
|
+
* @experimental
|
|
278
|
+
*/
|
|
279
|
+
export interface DateRange {
|
|
280
|
+
start: Date | string;
|
|
281
|
+
end: Date | string;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Payload delivered to onChange when range selection changes.
|
|
286
|
+
*
|
|
287
|
+
* @experimental
|
|
288
|
+
*/
|
|
289
|
+
export interface DateRangeChangePayload {
|
|
290
|
+
start: Date;
|
|
291
|
+
end: Date;
|
|
292
|
+
startDate: Date;
|
|
293
|
+
endDate: Date;
|
|
294
|
+
startString: string;
|
|
295
|
+
endString: string;
|
|
296
|
+
spanDays: number;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Context provided to custom range header render callbacks.
|
|
301
|
+
*
|
|
302
|
+
* @experimental
|
|
303
|
+
*/
|
|
304
|
+
export interface RangeHeaderContext {
|
|
305
|
+
start: Date;
|
|
306
|
+
end: Date;
|
|
307
|
+
spanDays: number;
|
|
308
|
+
activeHandle: 'start' | 'end';
|
|
309
|
+
scrollToHandle: (handle: 'start' | 'end', animated?: boolean) => void;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Configuration options for the range header.
|
|
314
|
+
*
|
|
315
|
+
* @experimental
|
|
316
|
+
*/
|
|
317
|
+
export interface RangeHeaderConfig {
|
|
318
|
+
/** Header container style */
|
|
319
|
+
style?: StyleProp<ViewStyle>;
|
|
320
|
+
/** Header date label style */
|
|
321
|
+
dateStyle?: StyleProp<TextStyle>;
|
|
322
|
+
/** Custom date format function for start/end labels */
|
|
323
|
+
format?: (date: Date) => string;
|
|
324
|
+
/** Custom header renderer replacing default range header */
|
|
325
|
+
render?: (context: RangeHeaderContext) => React.ReactNode;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Configuration for the date range highlight span connecting the handles.
|
|
330
|
+
*
|
|
331
|
+
* @experimental
|
|
332
|
+
*/
|
|
333
|
+
export interface RangeHighlightConfig {
|
|
334
|
+
/** Color of the range connecting highlight strip (default: theme.rangeHighlightColor) */
|
|
335
|
+
color?: string;
|
|
336
|
+
/** Custom style for the range highlight span */
|
|
337
|
+
style?: StyleProp<ViewStyle>;
|
|
338
|
+
/** Custom renderer for the range highlight span */
|
|
339
|
+
render?: (
|
|
340
|
+
startOffset: number,
|
|
341
|
+
endOffset: number,
|
|
342
|
+
tickSpacing: number
|
|
103
343
|
) => React.ReactNode;
|
|
104
344
|
}
|
|
105
345
|
|
|
106
346
|
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
347
|
+
* Configuration for the center indicator needle in range mode.
|
|
348
|
+
*
|
|
349
|
+
* @experimental
|
|
109
350
|
*/
|
|
110
|
-
export interface
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
labelColor: string;
|
|
114
|
-
accentColor: string;
|
|
115
|
-
indicatorColor: string;
|
|
116
|
-
backgroundColor: string;
|
|
351
|
+
export interface RangeIndicatorConfig extends Omit<IndicatorConfig, 'render'> {
|
|
352
|
+
/** Custom renderer for range needle indicator receiving active handle and date */
|
|
353
|
+
render?: (handle: 'start' | 'end', date: Date) => React.ReactNode;
|
|
117
354
|
}
|
|
118
355
|
|
|
119
356
|
/**
|
|
120
|
-
*
|
|
121
|
-
*
|
|
357
|
+
* Props for `RulerDateRangePicker`.
|
|
358
|
+
*
|
|
359
|
+
* @experimental This component and its props are experimental. The API may
|
|
360
|
+
* undergo breaking changes in future minor versions.
|
|
122
361
|
*/
|
|
123
|
-
export interface
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
362
|
+
export interface RulerDateRangePickerProps
|
|
363
|
+
extends Omit<RulerDatePickerProps, 'value' | 'defaultValue' | 'onChange' | 'header' | 'indicator'> {
|
|
364
|
+
/** Currently selected date range (controlled) */
|
|
365
|
+
value?: DateRange;
|
|
366
|
+
/** Initial selected date range (uncontrolled) */
|
|
367
|
+
defaultValue?: DateRange;
|
|
368
|
+
/** Called when the selected range changes */
|
|
369
|
+
onChange?: (range: DateRangeChangePayload) => void;
|
|
370
|
+
/** Header configuration or boolean toggle (default: true) */
|
|
371
|
+
header?: boolean | RangeHeaderConfig;
|
|
372
|
+
/** Center indicator needle configuration or boolean toggle (default: true) */
|
|
373
|
+
indicator?: boolean | RangeIndicatorConfig;
|
|
374
|
+
/** Range connecting highlight strip configuration or boolean toggle (default: true) */
|
|
375
|
+
highlight?: boolean | RangeHighlightConfig;
|
|
376
|
+
|
|
377
|
+
/** Minimum selectable span in days (default: 1) */
|
|
378
|
+
minSpanDays?: number;
|
|
379
|
+
/** Maximum selectable span in days */
|
|
380
|
+
maxSpanDays?: number;
|
|
129
381
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { useCallback, useRef } from 'react';
|
|
2
|
+
import { DEFAULTS } from './defaults';
|
|
3
|
+
|
|
4
|
+
interface UseHapticsOptions {
|
|
5
|
+
enableHaptics: boolean;
|
|
6
|
+
onHapticTrigger?: (mode: 'tick' | 'continuous') => void;
|
|
7
|
+
continuousHapticIntervalMs?: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface HapticsAPI {
|
|
11
|
+
fireDiscreteHaptic: () => void;
|
|
12
|
+
startContinuousHaptic: () => void;
|
|
13
|
+
stopContinuousHaptic: () => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Haptics hook implementation for Web environments.
|
|
18
|
+
* Delegates to onHapticTrigger if provided, otherwise gracefully no-ops without requiring expo-haptics.
|
|
19
|
+
*/
|
|
20
|
+
export function useHaptics({
|
|
21
|
+
enableHaptics,
|
|
22
|
+
onHapticTrigger,
|
|
23
|
+
continuousHapticIntervalMs = DEFAULTS.continuousHapticIntervalMs,
|
|
24
|
+
}: UseHapticsOptions): HapticsAPI {
|
|
25
|
+
const hapticIntervalRef = useRef<ReturnType<typeof setInterval> | null>(
|
|
26
|
+
null
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const fireDiscreteHaptic = useCallback(() => {
|
|
30
|
+
if (!enableHaptics || !onHapticTrigger) return;
|
|
31
|
+
onHapticTrigger('tick');
|
|
32
|
+
}, [enableHaptics, onHapticTrigger]);
|
|
33
|
+
|
|
34
|
+
const startContinuousHaptic = useCallback(() => {
|
|
35
|
+
if (!enableHaptics || !onHapticTrigger) return;
|
|
36
|
+
if (hapticIntervalRef.current) return;
|
|
37
|
+
onHapticTrigger('continuous');
|
|
38
|
+
hapticIntervalRef.current = setInterval(() => {
|
|
39
|
+
onHapticTrigger('continuous');
|
|
40
|
+
}, continuousHapticIntervalMs);
|
|
41
|
+
}, [enableHaptics, onHapticTrigger, continuousHapticIntervalMs]);
|
|
42
|
+
|
|
43
|
+
const stopContinuousHaptic = useCallback(() => {
|
|
44
|
+
if (hapticIntervalRef.current) {
|
|
45
|
+
clearInterval(hapticIntervalRef.current);
|
|
46
|
+
hapticIntervalRef.current = null;
|
|
47
|
+
}
|
|
48
|
+
}, []);
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
fireDiscreteHaptic,
|
|
52
|
+
startContinuousHaptic,
|
|
53
|
+
stopContinuousHaptic,
|
|
54
|
+
};
|
|
55
|
+
}
|