UNPKG

6.13 kBJavaScriptView Raw
1/**
2 * @prettier
3 * @flow
4 * */
5
6import React from 'react'
7import { View, StyleSheet } from 'react-native'
8import WheelPicker from './WheelPicker'
9import {
10 hourTo24Format,
11 hourTo12Format,
12 pickerDateArray,
13 getHoursArray,
14 increaseDateByDays,
15 getFiveMinutesArray,
16 getAmArray,
17} from './Utils'
18
19const millisecondsPerDay = 1000 * 60 * 60 * 24
20const HOUR = 60
21
22type Props = {
23 initDate: string,
24 hours: Array<number>,
25 minutes: Array<string>,
26 onDateSelected: Date => void,
27 startDate: string,
28 daysCount: number,
29 days: Array<number>,
30 hideDate?: boolean,
31 hideHours?: boolean,
32 hideMinutes?: boolean,
33 hideAM?: boolean,
34}
35
36type State = {
37 selectedDate: Date,
38 daysAfterSelectedDate: number,
39 initDayInex: number,
40 initHourInex: number,
41 initMinuteInex: number,
42 initAmInex: number,
43}
44
45export default class DatePicker extends React.Component<Props, State> {
46 constructor(props: Props) {
47 super(props)
48 const { startDate, minutes } = props
49 const selectedDate = this.props.initDate
50 ? new Date(this.props.initDate)
51 : new Date()
52 const time12format = hourTo12Format(selectedDate.getHours())
53 const time24format = selectedDate.getHours()
54 const millisBetween = selectedDate.getTime() - new Date().getTime()
55 let millisBetweenStartDate
56 let daysStartDate = 0
57 if (startDate) {
58 millisBetweenStartDate =
59 new Date(startDate).getTime() - new Date().getTime()
60 daysStartDate = millisBetweenStartDate / millisecondsPerDay
61 }
62 const days = millisBetween / millisecondsPerDay
63 const daysAfterSelectedDate = Math.round(daysStartDate)
64 const initDayInex = startDate
65 ? Math.round(days) - Math.round(daysStartDate)
66 : Math.round(days)
67 const initHourInex = this.props.format24
68 ? time24format
69 : Number(time12format[0]) - 1
70 const minutesCount = minutes ? minutes.length : 12
71 const initMinuteInex = Math.round(
72 selectedDate.getMinutes() / (HOUR / minutesCount)
73 )
74
75 const initAmInex = time12format[1] === 'AM' ? 0 : 1
76
77 this.state = {
78 daysAfterSelectedDate,
79 initDayInex,
80 selectedDate,
81 initHourInex,
82 initMinuteInex,
83 initAmInex,
84 }
85 }
86
87 render() {
88 const {
89 startDate,
90 days,
91 daysCount,
92 hours,
93 minutes,
94 format24,
95 backgroundColor,
96 hideDate,
97 hideHours,
98 hideMinutes,
99 hideAM,
100 } = this.props
101 const { initHourInex, initDayInex, initMinuteInex } = this.state
102 return (
103 <View style={[styles.container, { backgroundColor }]}>
104 {!hideDate && <WheelPicker
105 style={styles.dateWheelPicker}
106 {...this.props}
107 data={days || pickerDateArray(startDate, daysCount)}
108 onItemSelected={this.onDaySelected}
109 initPosition={initDayInex}
110 />}
111 {!hideHours && <WheelPicker
112 style={styles.wheelPicker}
113 {...this.props}
114 isCyclic
115 data={hours || getHoursArray(format24)}
116 onItemSelected={this.onHourSelected}
117 initPosition={initHourInex}
118 />}
119 {!hideMinutes && <WheelPicker
120 style={styles.wheelPicker}
121 {...this.props}
122 isCyclic
123 data={minutes || getFiveMinutesArray()}
124 onItemSelected={this.onMinuteSelected}
125 initPosition={initMinuteInex}
126 />}
127 {!this.props.format24 && !hideAM && this.renderAm()}
128 </View>
129 )
130 }
131
132 renderAm() {
133 const { initAmInex } = this.state
134 return (
135 <WheelPicker
136 style={styles.wheelPicker}
137 {...this.props}
138 data={getAmArray()}
139 onItemSelected={this.onAmSelected}
140 initPosition={initAmInex}
141 />
142 )
143 }
144
145 onDaySelected = (position: number) => {
146 let selectedDate = this.state.selectedDate
147 const daysAfterSelectedDate = this.state.daysAfterSelectedDate
148 const hours = selectedDate.getHours()
149 const minutes = selectedDate.getMinutes()
150
151 const {
152 startDate,
153 days,
154 daysCount
155 } = this.props
156 const data = days || pickerDateArray(startDate, daysCount)
157 if (data[position] === 'Today') {
158 selectedDate = new Date()
159 } else {
160 selectedDate = increaseDateByDays(
161 new Date(),
162 this.props.startDate
163 ? daysAfterSelectedDate + position
164 : position
165 )
166 }
167 selectedDate.setHours(hours)
168 selectedDate.setMinutes(minutes)
169 this.onDateSelected(selectedDate)
170 }
171
172 onHourSelected = (position: number) => {
173 const selectedDate = this.state.selectedDate
174 const { hours, format24 } = this.props
175 const data = hours || getHoursArray(format24)
176 if (this.props.format24) {
177 selectedDate.setHours(Number(data[position]))
178 } else {
179 const time12format = hourTo12Format(selectedDate.getHours())
180 const newTime12Format = `${data[position]} ${time12format[1]}`
181 const selectedHour24format = hourTo24Format(newTime12Format)
182 selectedDate.setHours(selectedHour24format)
183 }
184 this.onDateSelected(selectedDate)
185 }
186
187 onMinuteSelected = (position: number) => {
188 const selectedDate = this.state.selectedDate
189 const { minutes } = this.props
190 const data = minutes || getFiveMinutesArray()
191 selectedDate.setMinutes(Number(data[position]))
192 this.onDateSelected(selectedDate)
193 }
194
195 onAmSelected = (position: number) => {
196 const selectedDate = this.state.selectedDate
197 const time12format = hourTo12Format(selectedDate.getHours())
198 const newTime12Format = `${time12format[0]} ${getAmArray()[position]}`
199 const selectedHour24format = hourTo24Format(newTime12Format)
200 selectedDate.setHours(selectedHour24format)
201 this.onDateSelected(selectedDate)
202 }
203
204 onDateSelected(selectedDate: Date) {
205 this.setState({ selectedDate })
206 if (this.props.onDateSelected) {
207 this.props.onDateSelected(selectedDate)
208 }
209 }
210}
211
212let styles = StyleSheet.create({
213 container: {
214 alignItems: 'center',
215 flexDirection: 'row',
216 },
217 wheelPicker: {
218 height: 150,
219 width: null,
220 flex: 1,
221 },
222 dateWheelPicker: {
223 height: 150,
224 width: null,
225 flex: 3,
226 },
227})