├── .gitignore ├── README.md ├── calendar.png ├── index.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | npm-debug.log -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-calendar 2 | Calendar component for ReactNative. It is stateless component. 3 | 4 | ![example](calendar.png) 5 | 6 | ## install 7 | ``` 8 | npm install --save react-native-calendar-component 9 | ``` 10 | 11 | ## props 12 | | prop | type | default value | 13 | |--------------------|----------|------------------------------| 14 | | date | Date | new Date() | 15 | | onDateSelect | function | null | 16 | | onPrevButtonPress | function | null | 17 | | onNextButtonPress | function | null | 18 | | dayNames | array | ["Sun", "Mon" ... ] | 19 | | monthNames | array | ["January", "February" ... ] | 20 | | weekFirstDay | number | 0 | 21 | 22 | ## usage 23 | 24 | ```javascript 25 | import React, { Component } from "react"; 26 | import Calendar from "react-native-calendar-component"; 27 | 28 | export default class CalendarTest extends Component { 29 | constructor(props) { 30 | super(props); 31 | 32 | this.state = { 33 | date: new Date() 34 | }; 35 | } 36 | 37 | handleNextButtonPress() { 38 | const date = new Date(this.state.date); 39 | date.setMonth(date.getMonth() + 1); 40 | this.setState({ 41 | date 42 | }); 43 | } 44 | 45 | handlePrevButtonPress() { 46 | const date = new Date(this.state.date); 47 | date.setMonth(date.getMonth() - 1); 48 | this.setState({ 49 | date 50 | }); 51 | } 52 | 53 | handleDateSelect(date) { 54 | alert(`clicked: ${this.state.date.toString()}`); 55 | } 56 | 57 | render() { 58 | return ( 59 | this.handlePrevButtonPress()} 62 | onNextButtonPress={() => this.handleNextButtonPress()} 63 | onDateSelect={(date) => this.handleDateSelect(date)} /> 64 | ); 65 | } 66 | } 67 | ``` 68 | -------------------------------------------------------------------------------- /calendar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikches/react-native-calendar/fe67d4998dc21a505830a5b6464fb1ada950b00b/calendar.png -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from "react"; 2 | 3 | import { 4 | StyleSheet, 5 | Text, 6 | View, 7 | TouchableOpacity, 8 | } from "react-native"; 9 | 10 | export default class Calendar extends PureComponent { 11 | 12 | static get defaultProps() { 13 | return { 14 | date: new Date(), 15 | onDateSelect: null, 16 | onPrevButtonPress: null, 17 | onNextButtonPress: null, 18 | weekFirstDay: 0, 19 | dayNames: [ 20 | "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", 21 | ], 22 | monthNames: [ 23 | "January", "February", "March", 24 | "April", "May", "June", 25 | "July", "August", "September", 26 | "October", "November", "December" 27 | ] 28 | }; 29 | } 30 | 31 | static get propTypes() { 32 | return { 33 | date: React.PropTypes.object, 34 | onDateSelect: React.PropTypes.func, 35 | onPrevButtonPress: React.PropTypes.func, 36 | onNextButtonPress: React.PropTypes.func, 37 | dayNames: React.PropTypes.array, 38 | monthNames: React.PropTypes.array, 39 | weekFirstDay: React.PropTypes.number, 40 | }; 41 | } 42 | 43 | handleNextButtonPress() { 44 | if (this.props.onNextButtonPress !== null) { 45 | this.props.onNextButtonPress(); 46 | } 47 | } 48 | 49 | handlePrevButtonPress() { 50 | if (this.props.onPrevButtonPress !== null) { 51 | this.props.onPrevButtonPress(); 52 | } 53 | } 54 | 55 | handleDayPress(dateNumber) { 56 | if (this.props.onDateSelect !== null) { 57 | const month = this.props.date.getMonth(); 58 | const year = this.props.date.getFullYear(); 59 | const selectedDate = new Date(year, month, dateNumber); 60 | 61 | this.props.onDateSelect(selectedDate); 62 | } 63 | } 64 | 65 | renderBar() { 66 | const month = this.props.date.getMonth(); 67 | const year = this.props.date.getFullYear(); 68 | const monthName = this.props.monthNames[month]; 69 | 70 | return ( 71 | 72 | this.handlePrevButtonPress()}> 73 | 74 | 75 | ← 76 | 77 | 78 | 79 | 80 | 81 | 82 | {monthName + " "} 83 | 84 | 85 | 86 | 87 | 88 | {year} 89 | 90 | 91 | 92 | this.handleNextButtonPress()}> 93 | 94 | 95 | → 96 | 97 | 98 | 99 | 100 | ); 101 | } 102 | 103 | renderDayNames() { 104 | const elements = []; 105 | 106 | for (let i = 0; i < 7; i++) { 107 | const dayIndex = (this.props.weekFirstDay + i) % 7; 108 | elements.push( 109 | 110 | 111 | {this.props.dayNames[dayIndex]} 112 | 113 | 114 | ); 115 | } 116 | 117 | return ( 118 | 119 | {elements} 120 | 121 | ); 122 | } 123 | 124 | renderCalendarDay(index, dateNumber) { 125 | const weekDay = (index + this.props.weekFirstDay) % 7; 126 | const isWeekend = weekDay === 0 || weekDay === 6; 127 | 128 | const today = new Date(); 129 | const isToday = this.props.date.getDate() === dateNumber && 130 | this.props.date.getMonth() === today.getMonth() && 131 | this.props.date.getFullYear() === today.getFullYear(); 132 | 133 | return ( 134 | 135 | this.handleDayPress(dateNumber)}> 136 | 137 | 138 | {dateNumber} 139 | 140 | 141 | 142 | 143 | ); 144 | } 145 | 146 | renderCalendarDayEmpty(dateNumber) { 147 | return ( 148 | 149 | 150 | 151 | 152 | 153 | ); 154 | } 155 | 156 | renderCalendarWeek(startDateNumber, weekOffset, daysLeft) { 157 | const days = []; 158 | const weekKey = startDateNumber; 159 | 160 | for (let i = 0; i < weekOffset; i++) { 161 | days.push(this.renderCalendarDayEmpty(- weekOffset + i)); 162 | } 163 | 164 | let i = weekOffset; 165 | for (; i < 7 && daysLeft > 0; i++) { 166 | days.push(this.renderCalendarDay(i, startDateNumber++)); 167 | daysLeft--; 168 | } 169 | 170 | for (; i < 7; i++) { 171 | days.push(this.renderCalendarDayEmpty(startDateNumber++)); 172 | } 173 | 174 | return ( 175 | 176 | {days} 177 | 178 | ); 179 | } 180 | 181 | render() { 182 | const date = this.props.date; 183 | let monthFirstDayOfWeek = new Date(date.getFullYear(), date.getMonth(), 1).getDay(); 184 | monthFirstDayOfWeek = (monthFirstDayOfWeek - this.props.weekFirstDay + 7) % 7; 185 | let daysInMonth = new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate(); 186 | let startDateNumber = 1; 187 | 188 | const weeks = []; 189 | 190 | if (monthFirstDayOfWeek !== 0) { 191 | weeks.push(this.renderCalendarWeek(startDateNumber, monthFirstDayOfWeek, daysInMonth)); 192 | daysInMonth -= (7 - monthFirstDayOfWeek) % 7; 193 | startDateNumber += (7 - monthFirstDayOfWeek) % 7; 194 | } 195 | 196 | while (daysInMonth > 0) { 197 | weeks.push(this.renderCalendarWeek(startDateNumber, 0, daysInMonth)); 198 | startDateNumber += 7; 199 | daysInMonth -= 7; 200 | } 201 | 202 | return ( 203 | 204 | {this.renderBar()} 205 | {this.renderDayNames()} 206 | {weeks} 207 | 208 | ); 209 | } 210 | } 211 | 212 | const styles = StyleSheet.create({ 213 | calendar: { 214 | borderBottomWidth: 1, 215 | borderStyle: "solid", 216 | borderBottomColor: "#BDBDBD", 217 | backgroundColor: "white", 218 | }, 219 | 220 | week: { 221 | flexDirection: "row", 222 | justifyContent: "space-around", 223 | alignItems: "center", 224 | }, 225 | 226 | dayOuter: { 227 | flex: 1, 228 | }, 229 | 230 | dayInner: { 231 | paddingTop: 12, 232 | paddingRight: 12, 233 | paddingBottom: 12, 234 | paddingLeft: 8, 235 | backgroundColor: "white", 236 | borderBottomWidth: 3, 237 | borderStyle: "solid", 238 | borderColor: "white", 239 | }, 240 | 241 | todayDayInner: { 242 | borderColor: "#BF360C" 243 | }, 244 | 245 | dayText: { 246 | textAlign: "right", 247 | }, 248 | 249 | dayWeekendText: { 250 | color: "#BF360C", 251 | }, 252 | 253 | bar: { 254 | backgroundColor: "white", 255 | flexDirection: "row", 256 | justifyContent: "space-between", 257 | alignItems: "center", 258 | }, 259 | 260 | barText: { 261 | color: "#424242", 262 | }, 263 | 264 | barButton: { 265 | backgroundColor: "white", 266 | padding: 10, 267 | }, 268 | 269 | schadedText: { 270 | color: "#AAAAAA", 271 | } 272 | }); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-calendar-component", 3 | "version": "0.1.2", 4 | "description": "Calendar component for ReactNative.", 5 | "main": "index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/nikches/react-native-calendar.git" 9 | }, 10 | "keywords": [ 11 | "ReactNative", 12 | "calendar" 13 | ], 14 | "author": "nikches", 15 | "license": "MIT", 16 | "bugs": { 17 | "url": "https://github.com/nikches/react-native-calendar/issues" 18 | }, 19 | "homepage": "https://github.com/nikches/react-native-calendar#readme" 20 | } 21 | --------------------------------------------------------------------------------