react-native-smart-date-picker 0.1.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 +163 -0
- package/lib/components/DateColumn.d.ts +3 -0
- package/lib/components/DateColumn.d.ts.map +1 -0
- package/lib/components/DateColumn.js +12 -0
- package/lib/components/HourColumn.d.ts +3 -0
- package/lib/components/HourColumn.d.ts.map +1 -0
- package/lib/components/HourColumn.js +12 -0
- package/lib/components/MinuteColumn.d.ts +3 -0
- package/lib/components/MinuteColumn.d.ts.map +1 -0
- package/lib/components/MinuteColumn.js +12 -0
- package/lib/components/MonthColumn.d.ts +3 -0
- package/lib/components/MonthColumn.d.ts.map +1 -0
- package/lib/components/MonthColumn.js +12 -0
- package/lib/components/PickerModal.d.ts +10 -0
- package/lib/components/PickerModal.d.ts.map +1 -0
- package/lib/components/PickerModal.js +27 -0
- package/lib/components/SelectionOverlay.d.ts +10 -0
- package/lib/components/SelectionOverlay.d.ts.map +1 -0
- package/lib/components/SelectionOverlay.js +26 -0
- package/lib/components/SmartDatePicker.d.ts +4 -0
- package/lib/components/SmartDatePicker.d.ts.map +1 -0
- package/lib/components/SmartDatePicker.js +154 -0
- package/lib/components/WheelColumn.d.ts +17 -0
- package/lib/components/WheelColumn.d.ts.map +1 -0
- package/lib/components/WheelColumn.js +126 -0
- package/lib/components/YearColumn.d.ts +3 -0
- package/lib/components/YearColumn.d.ts.map +1 -0
- package/lib/components/YearColumn.js +12 -0
- package/lib/hooks/useDatePicker.d.ts +13 -0
- package/lib/hooks/useDatePicker.d.ts.map +1 -0
- package/lib/hooks/useDatePicker.js +31 -0
- package/lib/hooks/useTheme.d.ts +13 -0
- package/lib/hooks/useTheme.d.ts.map +1 -0
- package/lib/hooks/useTheme.js +7 -0
- package/lib/hooks/useWheel.d.ts +5 -0
- package/lib/hooks/useWheel.d.ts.map +1 -0
- package/lib/hooks/useWheel.js +12 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +23 -0
- package/lib/types/index.d.ts +59 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +2 -0
- package/lib/utils/constants.d.ts +4 -0
- package/lib/utils/constants.d.ts.map +1 -0
- package/lib/utils/constants.js +19 -0
- package/lib/utils/dateUtils.d.ts +4 -0
- package/lib/utils/dateUtils.d.ts.map +1 -0
- package/lib/utils/dateUtils.js +21 -0
- package/lib/utils/generateData.d.ts +21 -0
- package/lib/utils/generateData.d.ts.map +1 -0
- package/lib/utils/generateData.js +95 -0
- package/lib/utils/validateDOB.d.ts +2 -0
- package/lib/utils/validateDOB.d.ts.map +1 -0
- package/lib/utils/validateDOB.js +17 -0
- package/package.json +54 -0
- package/src/components/DateColumn.tsx +14 -0
- package/src/components/HourColumn.tsx +14 -0
- package/src/components/MinuteColumn.tsx +14 -0
- package/src/components/MonthColumn.tsx +14 -0
- package/src/components/PickerModal.tsx +60 -0
- package/src/components/SelectionOverlay.tsx +45 -0
- package/src/components/SmartDatePicker.tsx +318 -0
- package/src/components/WheelColumn.tsx +231 -0
- package/src/components/YearColumn.tsx +14 -0
- package/src/hooks/useDatePicker.ts +47 -0
- package/src/hooks/useTheme.ts +18 -0
- package/src/hooks/useWheel.ts +13 -0
- package/src/index.ts +3 -0
- package/src/types/index.ts +77 -0
- package/src/utils/constants.ts +17 -0
- package/src/utils/dateUtils.ts +38 -0
- package/src/utils/generateData.ts +134 -0
- package/src/utils/validateDOB.ts +24 -0
package/README.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# react-native-smart-date-picker
|
|
2
|
+
|
|
3
|
+
A lightweight, customizable React Native wheel-style date and datetime picker with a consistent UI on iOS and Android.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Wheel columns for day, month, year, hour, and minute
|
|
8
|
+
- Modes: `date`, `time`, `datetime` (date then time)
|
|
9
|
+
- Optional center selection overlay row
|
|
10
|
+
- Initial value support and min/max date clamping
|
|
11
|
+
- Theme and style customization via props
|
|
12
|
+
- Custom row height with `itemHeight`
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
Install in your React Native project:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install react-native-smart-date-picker
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Peer dependencies: `react` and `react-native` (see package.json).
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
Basic example (date then time flow):
|
|
27
|
+
|
|
28
|
+
```jsx
|
|
29
|
+
import React, { useState } from 'react';
|
|
30
|
+
import SmartDatePicker from 'react-native-smart-date-picker';
|
|
31
|
+
|
|
32
|
+
function Example() {
|
|
33
|
+
const [pickerVisible, setPickerVisible] = useState(false);
|
|
34
|
+
const [selectedDate, setSelectedDate] = useState(new Date());
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<>
|
|
38
|
+
<Button title="Open" onPress={() => setPickerVisible(true)} />
|
|
39
|
+
|
|
40
|
+
<SmartDatePicker
|
|
41
|
+
visible={pickerVisible}
|
|
42
|
+
value={selectedDate}
|
|
43
|
+
mode="datetime" // "date" | "time" | "datetime"
|
|
44
|
+
onCancel={() => setPickerVisible(false)}
|
|
45
|
+
onConfirm={(date) => {
|
|
46
|
+
setSelectedDate(date);
|
|
47
|
+
setPickerVisible(false);
|
|
48
|
+
console.log('Selected Date:', date);
|
|
49
|
+
}}
|
|
50
|
+
/>
|
|
51
|
+
</>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Time-only example
|
|
57
|
+
|
|
58
|
+
```jsx
|
|
59
|
+
<SmartDatePicker visible={true} mode="time" onConfirm={...} onCancel={...} />
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Date-only example
|
|
63
|
+
|
|
64
|
+
```jsx
|
|
65
|
+
<SmartDatePicker visible={true} mode="date" onConfirm={...} onCancel={...} />
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Theme example
|
|
69
|
+
|
|
70
|
+
```jsx
|
|
71
|
+
<SmartDatePicker
|
|
72
|
+
visible={pickerVisible}
|
|
73
|
+
value={selectedDate}
|
|
74
|
+
mode="datetime"
|
|
75
|
+
theme={{
|
|
76
|
+
primaryColor: '#0f766e',
|
|
77
|
+
backgroundColor: '#f8fafc',
|
|
78
|
+
wheelBackgroundColor: '#ffffff',
|
|
79
|
+
textColor: '#111827',
|
|
80
|
+
buttonTextColor: '#0f766e',
|
|
81
|
+
}}
|
|
82
|
+
onCancel={() => setPickerVisible(false)}
|
|
83
|
+
onConfirm={(date) => {
|
|
84
|
+
setSelectedDate(date);
|
|
85
|
+
setPickerVisible(false);
|
|
86
|
+
}}
|
|
87
|
+
/>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Behavior
|
|
91
|
+
|
|
92
|
+
- In `datetime` mode, the picker shows the date wheels first and then transitions to time selection.
|
|
93
|
+
- In `date` mode, the picker renders day/month/year wheels only.
|
|
94
|
+
- In `time` mode, the picker renders hour/minute wheels only.
|
|
95
|
+
- `value` is clamped to `minimumDate` / `maximumDate` before confirmation.
|
|
96
|
+
- `showSelectionOverlay` defaults to `true` and renders a centered highlight bar.
|
|
97
|
+
- The modal slides up from the bottom using React Native `Modal`.
|
|
98
|
+
|
|
99
|
+
## Props
|
|
100
|
+
|
|
101
|
+
### Required
|
|
102
|
+
|
|
103
|
+
- `visible: boolean` — whether the picker is visible
|
|
104
|
+
- `onConfirm: (date: Date) => void` — called when the user taps Done
|
|
105
|
+
- `onCancel: () => void` — called when the user taps Cancel
|
|
106
|
+
|
|
107
|
+
### Core picker props
|
|
108
|
+
|
|
109
|
+
- `mode?: 'date' | 'time' | 'datetime'` — which wheel UI to show (default: `datetime`)
|
|
110
|
+
- `value?: Date` — initial selected date/time (defaults to `new Date()`)
|
|
111
|
+
- `minimumDate?: Date` — earliest selectable date/time
|
|
112
|
+
- `maximumDate?: Date` — latest selectable date/time
|
|
113
|
+
- `showSelectionOverlay?: boolean` — display the center selection overlay row (default: `true`)
|
|
114
|
+
- `itemHeight?: number` — custom row height for wheel items
|
|
115
|
+
|
|
116
|
+
### Theme and styling
|
|
117
|
+
|
|
118
|
+
- `theme?: Partial<SmartDatePickerTheme>` — partial theme object for colors
|
|
119
|
+
- `customTheme?: SmartDatePickerTheme` — full theme object replacing default theme values
|
|
120
|
+
- `minDateTheme?: Partial<SmartDatePickerTheme>` — theme overrides when the selected date equals `minimumDate`
|
|
121
|
+
- `maxDateTheme?: Partial<SmartDatePickerTheme>` — theme overrides when the selected date equals `maximumDate`
|
|
122
|
+
- `primaryColor?: string`
|
|
123
|
+
- `backgroundColor?: string`
|
|
124
|
+
- `textColor?: string`
|
|
125
|
+
- `buttonTextColor?: string`
|
|
126
|
+
- `overlayBorderColor?: string`
|
|
127
|
+
- `disabledTextColor?: string`
|
|
128
|
+
- `selectionOverlayColor?: string`
|
|
129
|
+
- `headerBackgroundColor?: string`
|
|
130
|
+
- `wheelBackgroundColor?: string`
|
|
131
|
+
|
|
132
|
+
### Style overrides
|
|
133
|
+
|
|
134
|
+
- `containerStyle?: ViewStyle` — style for the modal container
|
|
135
|
+
- `wheelStyle?: ViewStyle` — style for the wheel columns
|
|
136
|
+
- `overlayStyle?: ViewStyle` — style for the picker panel / overlay
|
|
137
|
+
- `textStyle?: TextStyle` — style for all wheel labels
|
|
138
|
+
- `selectedTextStyle?: TextStyle` — style for the selected wheel label
|
|
139
|
+
|
|
140
|
+
See `src/types/index.ts` for the full TypeScript interface.
|
|
141
|
+
|
|
142
|
+
## Development
|
|
143
|
+
|
|
144
|
+
Build the library locally:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
npm install
|
|
148
|
+
npm run build
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
For development with live compile:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
npm run watch
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### TypeScript / Editor notes
|
|
158
|
+
|
|
159
|
+
- If your editor shows "Cannot use JSX unless the '--jsx' flag is provided", ensure `tsconfig.json` contains `"jsx": "react-jsx"` and restart the TypeScript server in VS Code: Command Palette → `TypeScript: Restart TS Server`.
|
|
160
|
+
|
|
161
|
+
## License
|
|
162
|
+
|
|
163
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DateColumn.d.ts","sourceRoot":"","sources":["../../src/components/DateColumn.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,CAAC,OAAO,UAAU,UAAU,CAC9B,KAAK,EAAE,GAAG,qBAQb"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = DateColumn;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const WheelColumn_1 = __importDefault(require("./WheelColumn"));
|
|
9
|
+
const generateData_1 = require("../utils/generateData");
|
|
10
|
+
function DateColumn(props) {
|
|
11
|
+
return ((0, jsx_runtime_1.jsx)(WheelColumn_1.default, Object.assign({ data: (0, generateData_1.generateDays)() }, props)));
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HourColumn.d.ts","sourceRoot":"","sources":["../../src/components/HourColumn.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,CAAC,OAAO,UAAU,UAAU,CAC9B,KAAK,EAAE,GAAG,qBAQb"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = HourColumn;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const WheelColumn_1 = __importDefault(require("./WheelColumn"));
|
|
9
|
+
const generateData_1 = require("../utils/generateData");
|
|
10
|
+
function HourColumn(props) {
|
|
11
|
+
return ((0, jsx_runtime_1.jsx)(WheelColumn_1.default, Object.assign({ data: (0, generateData_1.generateHours)() }, props)));
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MinuteColumn.d.ts","sourceRoot":"","sources":["../../src/components/MinuteColumn.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,CAAC,OAAO,UAAU,YAAY,CAChC,KAAK,EAAE,GAAG,qBAQb"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = MinuteColumn;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const WheelColumn_1 = __importDefault(require("./WheelColumn"));
|
|
9
|
+
const generateData_1 = require("../utils/generateData");
|
|
10
|
+
function MinuteColumn(props) {
|
|
11
|
+
return ((0, jsx_runtime_1.jsx)(WheelColumn_1.default, Object.assign({ data: (0, generateData_1.generateMinutes)() }, props)));
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MonthColumn.d.ts","sourceRoot":"","sources":["../../src/components/MonthColumn.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,CAAC,OAAO,UAAU,WAAW,CAC/B,KAAK,EAAE,GAAG,qBAQb"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = MonthColumn;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const WheelColumn_1 = __importDefault(require("./WheelColumn"));
|
|
9
|
+
const generateData_1 = require("../utils/generateData");
|
|
10
|
+
function MonthColumn(props) {
|
|
11
|
+
return ((0, jsx_runtime_1.jsx)(WheelColumn_1.default, Object.assign({ data: (0, generateData_1.generateMonths)() }, props)));
|
|
12
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ViewStyle } from "react-native";
|
|
3
|
+
export default function PickerModal({ visible, children, backgroundColor, containerStyle, overlayStyle, }: {
|
|
4
|
+
visible: boolean;
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
backgroundColor?: string;
|
|
7
|
+
containerStyle?: ViewStyle;
|
|
8
|
+
overlayStyle?: ViewStyle;
|
|
9
|
+
}): React.JSX.Element;
|
|
10
|
+
//# sourceMappingURL=PickerModal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PickerModal.d.ts","sourceRoot":"","sources":["../../src/components/PickerModal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAIH,SAAS,EACZ,MAAM,cAAc,CAAC;AAEtB,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAChC,OAAO,EACP,QAAQ,EACR,eAAe,EACf,cAAc,EACd,YAAY,GACf,EAAE;IACC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3B,YAAY,CAAC,EAAE,SAAS,CAAC;CAC5B,qBAuBA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = PickerModal;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_native_1 = require("react-native");
|
|
6
|
+
function PickerModal({ visible, children, backgroundColor, containerStyle, overlayStyle, }) {
|
|
7
|
+
return ((0, jsx_runtime_1.jsx)(react_native_1.Modal, { transparent: true, visible: visible, animationType: "slide", children: (0, jsx_runtime_1.jsx)(react_native_1.View, { style: [styles.container, containerStyle], children: (0, jsx_runtime_1.jsx)(react_native_1.View, { style: [
|
|
8
|
+
styles.content,
|
|
9
|
+
overlayStyle,
|
|
10
|
+
{
|
|
11
|
+
backgroundColor: backgroundColor || "#fff",
|
|
12
|
+
},
|
|
13
|
+
], children: children }) }) }));
|
|
14
|
+
}
|
|
15
|
+
const styles = react_native_1.StyleSheet.create({
|
|
16
|
+
container: {
|
|
17
|
+
flex: 1,
|
|
18
|
+
justifyContent: "flex-end",
|
|
19
|
+
backgroundColor: "rgba(0,0,0,0.4)",
|
|
20
|
+
},
|
|
21
|
+
content: {
|
|
22
|
+
height: 320,
|
|
23
|
+
backgroundColor: "#fff",
|
|
24
|
+
borderTopLeftRadius: 20,
|
|
25
|
+
borderTopRightRadius: 20,
|
|
26
|
+
},
|
|
27
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
interface Props {
|
|
3
|
+
itemHeight?: number;
|
|
4
|
+
borderColor?: string;
|
|
5
|
+
selectionOverlayColor?: string;
|
|
6
|
+
overlayStyle?: any;
|
|
7
|
+
}
|
|
8
|
+
export default function SelectionOverlay({ itemHeight, borderColor, selectionOverlayColor, overlayStyle, }: Props): React.JSX.Element;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=SelectionOverlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectionOverlay.d.ts","sourceRoot":"","sources":["../../src/components/SelectionOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,UAAU,KAAK;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,YAAY,CAAC,EAAE,GAAG,CAAC;CACtB;AAED,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EACrC,UAAe,EACf,WAAuB,EACvB,qBAAqC,EACrC,YAAY,GACf,EAAE,KAAK,qBAgBP"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = SelectionOverlay;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_native_1 = require("react-native");
|
|
6
|
+
function SelectionOverlay({ itemHeight = 44, borderColor = "#D1D5DB", selectionOverlayColor = "transparent", overlayStyle, }) {
|
|
7
|
+
return ((0, jsx_runtime_1.jsx)(react_native_1.View, { pointerEvents: "none", style: [
|
|
8
|
+
styles.overlay,
|
|
9
|
+
overlayStyle,
|
|
10
|
+
{
|
|
11
|
+
top: itemHeight * 2,
|
|
12
|
+
height: itemHeight,
|
|
13
|
+
borderColor,
|
|
14
|
+
backgroundColor: selectionOverlayColor,
|
|
15
|
+
},
|
|
16
|
+
] }));
|
|
17
|
+
}
|
|
18
|
+
const styles = react_native_1.StyleSheet.create({
|
|
19
|
+
overlay: {
|
|
20
|
+
position: "absolute",
|
|
21
|
+
left: 0,
|
|
22
|
+
right: 0,
|
|
23
|
+
borderTopWidth: 1,
|
|
24
|
+
borderBottomWidth: 1,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { SmartDatePickerProps } from "../types";
|
|
3
|
+
export default function SmartDatePicker({ visible, value, onConfirm, onCancel, mode, showSelectionOverlay, minimumDate, maximumDate, primaryColor, backgroundColor, textColor, buttonTextColor, overlayBorderColor, disabledTextColor, selectionOverlayColor, headerBackgroundColor, wheelBackgroundColor, theme, customTheme, minDateTheme, maxDateTheme, containerStyle, wheelStyle, overlayStyle, textStyle, selectedTextStyle, itemHeight, }: SmartDatePickerProps): React.JSX.Element;
|
|
4
|
+
//# sourceMappingURL=SmartDatePicker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SmartDatePicker.d.ts","sourceRoot":"","sources":["../../src/components/SmartDatePicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAiBjD,OAAO,EACH,oBAAoB,EACvB,MAAM,UAAU,CAAC;AAOlB,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EACpC,OAAO,EACP,KAAkB,EAClB,SAAS,EACT,QAAQ,EACR,IAAiB,EACjB,oBAA2B,EAC3B,WAAW,EACX,WAAW,EACX,YAAY,EACZ,eAAe,EACf,SAAS,EACT,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,KAAK,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EAEZ,cAAc,EACd,UAAU,EACV,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,UAAU,GACb,EAAE,oBAAoB,qBA0OtB"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.default = SmartDatePicker;
|
|
40
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
41
|
+
const react_1 = __importStar(require("react"));
|
|
42
|
+
const react_native_1 = require("react-native");
|
|
43
|
+
const PickerModal_1 = __importDefault(require("./PickerModal"));
|
|
44
|
+
const DateColumn_1 = __importDefault(require("./DateColumn"));
|
|
45
|
+
const MonthColumn_1 = __importDefault(require("./MonthColumn"));
|
|
46
|
+
const YearColumn_1 = __importDefault(require("./YearColumn"));
|
|
47
|
+
const HourColumn_1 = __importDefault(require("./HourColumn"));
|
|
48
|
+
const MinuteColumn_1 = __importDefault(require("./MinuteColumn"));
|
|
49
|
+
const SelectionOverlay_1 = __importDefault(require("./SelectionOverlay"));
|
|
50
|
+
const useDatePicker_1 = require("../hooks/useDatePicker");
|
|
51
|
+
const useTheme_1 = require("../hooks/useTheme");
|
|
52
|
+
const dateUtils_1 = require("../utils/dateUtils");
|
|
53
|
+
function SmartDatePicker({ visible, value = new Date(), onConfirm, onCancel, mode = "datetime", showSelectionOverlay = true, minimumDate, maximumDate, primaryColor, backgroundColor, textColor, buttonTextColor, overlayBorderColor, disabledTextColor, selectionOverlayColor, headerBackgroundColor, wheelBackgroundColor, theme, customTheme, minDateTheme, maxDateTheme,
|
|
54
|
+
// style overrides
|
|
55
|
+
containerStyle, wheelStyle, overlayStyle, textStyle, selectedTextStyle, itemHeight, }) {
|
|
56
|
+
const boundedValue = (0, react_1.useMemo)(() => (0, dateUtils_1.clampDate)(value, minimumDate, maximumDate), [value, minimumDate, maximumDate]);
|
|
57
|
+
const picker = (0, useDatePicker_1.useDatePicker)(boundedValue);
|
|
58
|
+
// view toggles between 'date' and 'time' when mode is 'datetime'
|
|
59
|
+
const [view, setView] = (0, react_1.useState)(mode === "time" ? "time" : "date");
|
|
60
|
+
react_1.default.useEffect(() => {
|
|
61
|
+
if (!visible)
|
|
62
|
+
return;
|
|
63
|
+
setView(mode === "time" ? "time" : "date");
|
|
64
|
+
}, [visible, mode]);
|
|
65
|
+
const selectedDate = (0, dateUtils_1.buildDate)(picker.day, picker.month, picker.year, picker.hour, picker.minute);
|
|
66
|
+
const effectiveDate = (0, dateUtils_1.clampDate)(selectedDate, minimumDate, maximumDate);
|
|
67
|
+
const selectedBoundaryTheme = (0, react_1.useMemo)(() => {
|
|
68
|
+
if (minimumDate &&
|
|
69
|
+
effectiveDate.getTime() === minimumDate.getTime()) {
|
|
70
|
+
return minDateTheme;
|
|
71
|
+
}
|
|
72
|
+
if (maximumDate &&
|
|
73
|
+
effectiveDate.getTime() === maximumDate.getTime()) {
|
|
74
|
+
return maxDateTheme;
|
|
75
|
+
}
|
|
76
|
+
return undefined;
|
|
77
|
+
}, [effectiveDate, minimumDate, maximumDate, minDateTheme, maxDateTheme]);
|
|
78
|
+
const themeObj = customTheme !== null && customTheme !== void 0 ? customTheme : (typeof theme === "object" ? theme : undefined);
|
|
79
|
+
const activeTheme = (0, useTheme_1.useTheme)(Object.assign(Object.assign(Object.assign({}, themeObj), selectedBoundaryTheme), { primaryColor,
|
|
80
|
+
backgroundColor,
|
|
81
|
+
textColor,
|
|
82
|
+
buttonTextColor,
|
|
83
|
+
overlayBorderColor,
|
|
84
|
+
disabledTextColor,
|
|
85
|
+
selectionOverlayColor,
|
|
86
|
+
headerBackgroundColor,
|
|
87
|
+
wheelBackgroundColor }));
|
|
88
|
+
const handleDone = () => {
|
|
89
|
+
onConfirm(effectiveDate);
|
|
90
|
+
};
|
|
91
|
+
const handleNext = () => setView("time");
|
|
92
|
+
const renderDateColumns = () => ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(DateColumn_1.default, { selected: picker.day, onChange: picker.setDay, textColor: activeTheme.textColor, selectedTextColor: activeTheme.primaryColor, wheelBackgroundColor: activeTheme.wheelBackgroundColor, wheelStyle: wheelStyle, textStyle: textStyle, selectedTextStyle: selectedTextStyle }), (0, jsx_runtime_1.jsx)(MonthColumn_1.default, { selected: picker.month, onChange: picker.setMonth, textColor: activeTheme.textColor, selectedTextColor: activeTheme.primaryColor, wheelBackgroundColor: activeTheme.wheelBackgroundColor, wheelStyle: wheelStyle, textStyle: textStyle, selectedTextStyle: selectedTextStyle }), (0, jsx_runtime_1.jsx)(YearColumn_1.default, { selected: picker.year, onChange: picker.setYear, textColor: activeTheme.textColor, selectedTextColor: activeTheme.primaryColor, wheelBackgroundColor: activeTheme.wheelBackgroundColor, wheelStyle: wheelStyle, textStyle: textStyle, selectedTextStyle: selectedTextStyle })] }));
|
|
93
|
+
const renderTimeColumns = () => ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(HourColumn_1.default, { selected: picker.hour, onChange: picker.setHour, textColor: activeTheme.textColor, selectedTextColor: activeTheme.primaryColor, wheelBackgroundColor: activeTheme.wheelBackgroundColor, wheelStyle: wheelStyle, textStyle: textStyle, selectedTextStyle: selectedTextStyle }), (0, jsx_runtime_1.jsx)(MinuteColumn_1.default, { selected: picker.minute, onChange: picker.setMinute, textColor: activeTheme.textColor, selectedTextColor: activeTheme.primaryColor, wheelBackgroundColor: activeTheme.wheelBackgroundColor, wheelStyle: wheelStyle, textStyle: textStyle, selectedTextStyle: selectedTextStyle })] }));
|
|
94
|
+
const selectedText = view === "time"
|
|
95
|
+
? selectedDate.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
|
|
96
|
+
: selectedDate.toLocaleDateString();
|
|
97
|
+
return ((0, jsx_runtime_1.jsxs)(PickerModal_1.default, { visible: visible, backgroundColor: activeTheme.backgroundColor, containerStyle: containerStyle, overlayStyle: overlayStyle, children: [(0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [
|
|
98
|
+
styles.header,
|
|
99
|
+
{
|
|
100
|
+
backgroundColor: activeTheme.headerBackgroundColor,
|
|
101
|
+
},
|
|
102
|
+
], children: [(0, jsx_runtime_1.jsxs)(react_native_1.View, { children: [(0, jsx_runtime_1.jsx)(react_native_1.TouchableOpacity, { onPress: onCancel, children: (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [
|
|
103
|
+
styles.buttonText,
|
|
104
|
+
{
|
|
105
|
+
color: activeTheme.buttonTextColor ||
|
|
106
|
+
activeTheme.primaryColor,
|
|
107
|
+
},
|
|
108
|
+
], children: "Cancel" }) }), (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [
|
|
109
|
+
styles.previewText,
|
|
110
|
+
{
|
|
111
|
+
color: activeTheme.textColor,
|
|
112
|
+
},
|
|
113
|
+
], children: selectedText })] }), mode === "datetime" && view === "date" ? ((0, jsx_runtime_1.jsx)(react_native_1.TouchableOpacity, { onPress: handleNext, children: (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [
|
|
114
|
+
styles.buttonText,
|
|
115
|
+
{
|
|
116
|
+
color: activeTheme.buttonTextColor ||
|
|
117
|
+
activeTheme.primaryColor,
|
|
118
|
+
},
|
|
119
|
+
], children: "Next" }) })) : ((0, jsx_runtime_1.jsx)(react_native_1.TouchableOpacity, { onPress: handleDone, children: (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [
|
|
120
|
+
styles.buttonText,
|
|
121
|
+
{
|
|
122
|
+
color: activeTheme.buttonTextColor ||
|
|
123
|
+
activeTheme.primaryColor,
|
|
124
|
+
},
|
|
125
|
+
], children: "Done" }) }))] }), (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [
|
|
126
|
+
styles.row,
|
|
127
|
+
{
|
|
128
|
+
backgroundColor: activeTheme.wheelBackgroundColor,
|
|
129
|
+
},
|
|
130
|
+
], children: [view === "date" ? renderDateColumns() : renderTimeColumns(), showSelectionOverlay && ((0, jsx_runtime_1.jsx)(SelectionOverlay_1.default, { itemHeight: itemHeight, borderColor: activeTheme.overlayBorderColor, selectionOverlayColor: activeTheme.selectionOverlayColor, overlayStyle: overlayStyle }))] })] }));
|
|
131
|
+
}
|
|
132
|
+
const styles = react_native_1.StyleSheet.create({
|
|
133
|
+
header: {
|
|
134
|
+
height: 50,
|
|
135
|
+
paddingHorizontal: 20,
|
|
136
|
+
justifyContent: "space-between",
|
|
137
|
+
alignItems: "center",
|
|
138
|
+
flexDirection: "row",
|
|
139
|
+
},
|
|
140
|
+
row: {
|
|
141
|
+
flex: 1,
|
|
142
|
+
flexDirection: "row",
|
|
143
|
+
position: "relative",
|
|
144
|
+
},
|
|
145
|
+
buttonText: {
|
|
146
|
+
fontSize: 16,
|
|
147
|
+
fontWeight: "600",
|
|
148
|
+
},
|
|
149
|
+
previewText: {
|
|
150
|
+
marginTop: 6,
|
|
151
|
+
fontSize: 12,
|
|
152
|
+
color: "#666",
|
|
153
|
+
},
|
|
154
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { TextStyle, ViewStyle } from "react-native";
|
|
3
|
+
interface Props {
|
|
4
|
+
data: any[];
|
|
5
|
+
selected: any;
|
|
6
|
+
onChange: (v: any) => void;
|
|
7
|
+
textColor?: string;
|
|
8
|
+
selectedTextColor?: string;
|
|
9
|
+
wheelBackgroundColor?: string;
|
|
10
|
+
selectedFontSize?: number;
|
|
11
|
+
textStyle?: TextStyle;
|
|
12
|
+
selectedTextStyle?: TextStyle;
|
|
13
|
+
wheelStyle?: ViewStyle;
|
|
14
|
+
}
|
|
15
|
+
export default function WheelColumn({ data, selected, onChange, textColor, selectedTextColor, wheelBackgroundColor, selectedFontSize, textStyle, selectedTextStyle, wheelStyle, }: Props): React.JSX.Element;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=WheelColumn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WheelColumn.d.ts","sourceRoot":"","sources":["../../src/components/WheelColumn.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAC1D,OAAO,EAOH,SAAS,EACT,SAAS,EACZ,MAAM,cAAc,CAAC;AAEtB,UAAU,KAAK;IACX,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,QAAQ,EAAE,GAAG,CAAC;IACd,QAAQ,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,UAAU,CAAC,EAAE,SAAS,CAAC;CAC1B;AAMD,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAChC,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,EAEhB,SAAS,EACT,iBAAiB,EACjB,UAAU,GACb,EAAE,KAAK,qBA+KP"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = WheelColumn;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const react_native_1 = require("react-native");
|
|
7
|
+
const ITEM_HEIGHT = 44;
|
|
8
|
+
const VISIBLE_ROWS = 5;
|
|
9
|
+
const WHEEL_HEIGHT = ITEM_HEIGHT * VISIBLE_ROWS;
|
|
10
|
+
function WheelColumn({ data, selected, onChange, textColor, selectedTextColor, wheelBackgroundColor, selectedFontSize,
|
|
11
|
+
// forwarded style props
|
|
12
|
+
textStyle, selectedTextStyle, wheelStyle, }) {
|
|
13
|
+
const listRef = (0, react_1.useRef)(null);
|
|
14
|
+
// Repeat data for infinite effect
|
|
15
|
+
const repeatedData = data;
|
|
16
|
+
// const repeatedData = useMemo(
|
|
17
|
+
// () => [...data, ...data, ...data, ...data, ...data],
|
|
18
|
+
// [data]
|
|
19
|
+
// );
|
|
20
|
+
const selectedIndex = data.findIndex((item) => item.value === selected);
|
|
21
|
+
const middleIndex = selectedIndex >= 0
|
|
22
|
+
? selectedIndex
|
|
23
|
+
: 0;
|
|
24
|
+
// const middleIndex =
|
|
25
|
+
// selectedIndex >= 0
|
|
26
|
+
// ? selectedIndex + data.length * 2
|
|
27
|
+
// : data.length * 2;
|
|
28
|
+
(0, react_1.useEffect)(() => {
|
|
29
|
+
setTimeout(() => {
|
|
30
|
+
var _a;
|
|
31
|
+
(_a = listRef.current) === null || _a === void 0 ? void 0 : _a.scrollToOffset({
|
|
32
|
+
offset: middleIndex * ITEM_HEIGHT,
|
|
33
|
+
animated: false,
|
|
34
|
+
});
|
|
35
|
+
}, 50);
|
|
36
|
+
}, []);
|
|
37
|
+
// const handleScrollEnd = (
|
|
38
|
+
// e: NativeSyntheticEvent<NativeScrollEvent>
|
|
39
|
+
// ) => {
|
|
40
|
+
// const offsetY =
|
|
41
|
+
// e.nativeEvent.contentOffset.y;
|
|
42
|
+
// const index = Math.round(
|
|
43
|
+
// offsetY / ITEM_HEIGHT
|
|
44
|
+
// );
|
|
45
|
+
// const clampedIndex = Math.max(
|
|
46
|
+
// 0,
|
|
47
|
+
// Math.min(index, data.length - 1)
|
|
48
|
+
// );
|
|
49
|
+
// listRef.current?.scrollToOffset({
|
|
50
|
+
// offset:
|
|
51
|
+
// clampedIndex * ITEM_HEIGHT,
|
|
52
|
+
// animated: true,
|
|
53
|
+
// });
|
|
54
|
+
// const item = data[clampedIndex];
|
|
55
|
+
// if (item) {
|
|
56
|
+
// onChange(item.value);
|
|
57
|
+
// }
|
|
58
|
+
// };
|
|
59
|
+
const handleScrollEnd = (e) => {
|
|
60
|
+
var _a;
|
|
61
|
+
const offsetY = e.nativeEvent.contentOffset.y;
|
|
62
|
+
const index = Math.round(offsetY / ITEM_HEIGHT);
|
|
63
|
+
const clampedIndex = Math.max(0, Math.min(index, data.length - 1));
|
|
64
|
+
(_a = listRef.current) === null || _a === void 0 ? void 0 : _a.scrollToOffset({
|
|
65
|
+
offset: clampedIndex * ITEM_HEIGHT,
|
|
66
|
+
animated: false,
|
|
67
|
+
});
|
|
68
|
+
const item = data[clampedIndex];
|
|
69
|
+
if (item) {
|
|
70
|
+
onChange(item.value);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
return ((0, jsx_runtime_1.jsx)(react_native_1.FlatList, { ref: listRef, data: repeatedData, keyExtractor: (_, index) => index.toString(), style: [
|
|
74
|
+
{
|
|
75
|
+
height: WHEEL_HEIGHT,
|
|
76
|
+
backgroundColor: wheelBackgroundColor || "transparent",
|
|
77
|
+
},
|
|
78
|
+
wheelStyle,
|
|
79
|
+
], showsVerticalScrollIndicator: false, bounces: false, removeClippedSubviews: false, disableIntervalMomentum: true, snapToInterval: ITEM_HEIGHT, snapToAlignment: "center", decelerationRate: "fast", onMomentumScrollEnd: handleScrollEnd, getItemLayout: (_, index) => ({
|
|
80
|
+
length: ITEM_HEIGHT,
|
|
81
|
+
offset: ITEM_HEIGHT * index,
|
|
82
|
+
index,
|
|
83
|
+
}), renderItem: ({ item }) => ((0, jsx_runtime_1.jsx)(react_native_1.TouchableOpacity, { style: styles.item, onPress: () => {
|
|
84
|
+
var _a;
|
|
85
|
+
const index = data.findIndex((d) => d.value === item.value);
|
|
86
|
+
(_a = listRef.current) === null || _a === void 0 ? void 0 : _a.scrollToOffset({
|
|
87
|
+
offset: index * ITEM_HEIGHT,
|
|
88
|
+
animated: true,
|
|
89
|
+
});
|
|
90
|
+
onChange(item.value);
|
|
91
|
+
}, children: (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [
|
|
92
|
+
styles.text,
|
|
93
|
+
textStyle,
|
|
94
|
+
{
|
|
95
|
+
color: selectedTextColor ||
|
|
96
|
+
textColor ||
|
|
97
|
+
styles.text.color,
|
|
98
|
+
},
|
|
99
|
+
selected === item.value && [
|
|
100
|
+
{
|
|
101
|
+
fontWeight: "700",
|
|
102
|
+
fontSize: selectedFontSize || 20,
|
|
103
|
+
color: selectedTextColor ||
|
|
104
|
+
textColor ||
|
|
105
|
+
styles.text.color,
|
|
106
|
+
},
|
|
107
|
+
selectedTextStyle,
|
|
108
|
+
],
|
|
109
|
+
], children: item.label }) })), contentContainerStyle: {
|
|
110
|
+
paddingTop: ((VISIBLE_ROWS - 1) / 2) *
|
|
111
|
+
ITEM_HEIGHT,
|
|
112
|
+
paddingBottom: ((VISIBLE_ROWS - 1) / 2) *
|
|
113
|
+
ITEM_HEIGHT,
|
|
114
|
+
} }));
|
|
115
|
+
}
|
|
116
|
+
const styles = react_native_1.StyleSheet.create({
|
|
117
|
+
item: {
|
|
118
|
+
height: ITEM_HEIGHT,
|
|
119
|
+
justifyContent: "center",
|
|
120
|
+
alignItems: "center",
|
|
121
|
+
},
|
|
122
|
+
text: {
|
|
123
|
+
fontSize: 18,
|
|
124
|
+
color: "#111827",
|
|
125
|
+
},
|
|
126
|
+
});
|