├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── android
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── chymtt
│ │ └── reactnativecalendar
│ │ ├── Calendar.java
│ │ ├── CalendarEvent.java
│ │ ├── CalendarManager.java
│ │ └── CalendarPackage.java
│ └── res
│ └── values
│ └── styles.xml
├── package.json
└── src
└── Calendar.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | project.xcworkspace
24 |
25 | # Android/IJ
26 | #
27 | .idea
28 | .gradle
29 | local.properties
30 |
31 | # node.js
32 | #
33 | node_modules/
34 | npm-debug.log
35 |
36 | *.iml
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # Android/IJ
2 | .idea/workspace.xml
3 | .idea/libraries
4 | local.properties
5 | *.iml
6 | build
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 chymtt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-native-calendar-android
2 |
3 | A simple material-themed calendar for react native android
4 |
5 |
6 |
7 | ## Installation Android
8 | 1. `npm install --save react-native-calendar-android`
9 |
10 | _Note_: Since react-native-calendar-android@0.0.3, you should use react-native@0.19.0 and above
11 |
12 | 2. In `android/settings.gradle`
13 |
14 | ```gradle
15 | ...
16 | include ':ReactNativeCalendarAndroid', ':app'
17 | project(':ReactNativeCalendarAndroid').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-calendar-android/android')
18 | ```
19 |
20 | 3. In `android/app/build.gradle`
21 |
22 | ```gradle
23 | ...
24 | dependencies {
25 | ...
26 | compile project(':ReactNativeCalendarAndroid')
27 | }
28 | ```
29 |
30 | 4. Register module (in MainActivity.java)
31 |
32 | 4.1. With RN < 0.19.0
33 |
34 | ```java
35 | import com.chymtt.reactnativecalendar.CalendarPackage; // <----- import
36 |
37 | public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {
38 | ......
39 |
40 | @Override
41 | protected void onCreate(Bundle savedInstanceState) {
42 | super.onCreate(savedInstanceState);
43 | mReactRootView = new ReactRootView(this);
44 |
45 | mReactInstanceManager = ReactInstanceManager.builder()
46 | .setApplication(getApplication())
47 | .setBundleAssetName("index.android.bundle")
48 | .setJSMainModuleName("index.android")
49 | .addPackage(new MainReactPackage())
50 | .addPackage(new CalendarPackage()) // <------ add here
51 | .setUseDeveloperSupport(BuildConfig.DEBUG)
52 | .setInitialLifecycleState(LifecycleState.RESUMED)
53 | .build();
54 |
55 | mReactRootView.startReactApplication(mReactInstanceManager, "ExampleRN", null);
56 |
57 | setContentView(mReactRootView);
58 | }
59 | ......
60 | }
61 | ```
62 |
63 | 4.2. With RN >= 0.19.0
64 |
65 | ```java
66 | import com.chymtt.reactnativecalendar.CalendarPackage; // <----- import
67 |
68 | public class MainActivity extends ReactActivity {
69 | ...
70 |
71 | @Override
72 | protected List getPackages() {
73 | return Arrays.asList(
74 | new MainReactPackage(),
75 | new CalendarPackage() // <------ add here
76 | );
77 | }
78 | }
79 | ```
80 |
81 | ## Usage
82 |
83 | ```js
84 |
85 | var Calendar = require('react-native-calendar-android');
86 | ...
87 |
88 | render() {
89 | return (
90 | {
101 | console.log(data);
102 | }} />
103 | );
104 | }
105 | ```
106 |
107 | ## Notes
108 |
109 | The view is a grid with 7 tiles wide and 8 tiles high (with ```topbarVisible=true```), or 7 tiles high (with ```topbarVisible=false```)
110 |
111 | The size of each tile is automatically calculated based on the provided width.
112 |
113 | ## Props
114 |
115 | ### int width (required)
116 |
117 | Provide the width of the calendar. The height will be calculated based on width and ```topbarVisible```.
118 |
119 | ### boolean topbarVisible (default = true)
120 |
121 | Show/hide the top bar which contains the month's title and arrows to go to previous or next months.
122 |
123 | ### string arrowColor
124 |
125 | A string color in the format #RRGGBB or #AARRGGBB. It changes color of the top bar's arrows accordingly.
126 |
127 | ### enum firstDayOfWeek (default = 'sunday')
128 |
129 | enum [ 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday' ]
130 |
131 | Set the first day of the week.
132 |
133 | ### enum showDate (default = 'current')
134 |
135 | enum [ 'all', 'current' ]
136 |
137 | If set to ```current```, only show dates within current month. If set to ```all```, show dates from previous and current months too.
138 |
139 | ### array currentDate
140 |
141 | Set the focus of the calendar. Due to some limitations, you must provide an array with only one element, which is the currentDate. currentDate can be a string in the format ```yyyy/mm/dd``` or a timestamp.
142 |
143 | ### enum selectionMode (default = 'single')
144 |
145 | enum [ 'none', 'single', 'multiple' ]
146 |
147 | Set the selection mode.
148 |
149 | - none: you cannot select date
150 | - single: you can only select one date at a time
151 | - multiple: you can select multiple dates
152 |
153 | ### string selectionColor
154 |
155 | Set the color of the selection circle. Should be a color in the format #RRGGBB or #AARRGGBB.
156 |
157 | ### array selectedDates
158 |
159 | An array of dates in the format ```yyyy/mm/dd``` or timestamp. Set the selected dates on the calendar.
160 |
161 | ## Event
162 |
163 | ### onDateChange(data)
164 |
165 | Called when user select/deselect a date. The returned data is { date: 'yyyy/mm/dd', selected: boolean }
166 |
167 | ## Questions or suggestions?
168 |
169 | Feel free to [open an issue](https://github.com/chymtt/ReactNativeCalendarAndroid/issues)
170 | [Pull requests](https://github.com/chymtt/ReactNativeCalendarAndroid/pulls) are also welcome
171 |
172 | ## Credit
173 |
174 | Big thanks to @prolificinteractive for their awesome [Material Calendar View](https://github.com/prolificinteractive/material-calendarview)
175 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.1"
6 |
7 | defaultConfig {
8 | minSdkVersion 16
9 | targetSdkVersion 22
10 | versionCode 1
11 | versionName "1.0"
12 | ndk {
13 | abiFilters "armeabi-v7a", "x86"
14 | }
15 | }
16 | }
17 |
18 | dependencies {
19 | compile 'com.android.support:appcompat-v7:23.0.0'
20 | compile 'com.facebook.react:react-native:0.32.+'
21 | compile 'com.prolificinteractive:material-calendarview:1.4.0'
22 | }
23 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/android/src/main/java/com/chymtt/reactnativecalendar/Calendar.java:
--------------------------------------------------------------------------------
1 | package com.chymtt.reactnativecalendar;
2 |
3 | import android.view.ViewGroup;
4 |
5 | import com.facebook.react.uimanager.ThemedReactContext;
6 | import com.prolificinteractive.materialcalendarview.MaterialCalendarView;
7 |
8 | /**
9 | * Created by Chym on 29/11/15.
10 | */
11 | public class Calendar extends MaterialCalendarView {
12 |
13 | public Calendar(ThemedReactContext context) {
14 | super(context);
15 | setLayoutParams(new ViewGroup.LayoutParams(
16 | ViewGroup.LayoutParams.MATCH_PARENT,
17 | ViewGroup.LayoutParams.WRAP_CONTENT
18 | ));
19 | }
20 |
21 | private final Runnable mLayoutRunnable = new Runnable() {
22 | @Override
23 | public void run() {
24 | measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
25 | MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
26 | layout(getLeft(), getTop(), getRight(), getBottom());
27 | }
28 | };
29 |
30 | @Override
31 | public void requestLayout() {
32 | super.requestLayout();
33 | post(mLayoutRunnable);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/android/src/main/java/com/chymtt/reactnativecalendar/CalendarEvent.java:
--------------------------------------------------------------------------------
1 | package com.chymtt.reactnativecalendar;
2 |
3 | import android.util.Log;
4 |
5 | import com.facebook.react.bridge.Arguments;
6 | import com.facebook.react.bridge.WritableMap;
7 | import com.facebook.react.uimanager.events.Event;
8 | import com.facebook.react.uimanager.events.RCTEventEmitter;
9 | import com.prolificinteractive.materialcalendarview.CalendarDay;
10 |
11 | import java.text.DateFormat;
12 | import java.text.SimpleDateFormat;
13 |
14 | /**
15 | * Created by Chym on 29/11/15.
16 | */
17 | public class CalendarEvent extends Event{
18 | public static final String EVENT_NAME = "topDateChange";
19 |
20 | private static final String DATE_FORMAT = "yyyy/MM/dd";
21 | private static final DateFormat dateFormat;
22 | static {
23 | dateFormat = new SimpleDateFormat(DATE_FORMAT);
24 | }
25 |
26 | private final CalendarDay date;
27 | private final boolean selected;
28 |
29 | public CalendarEvent(int viewId, CalendarDay date, boolean selected) {
30 | super(viewId);
31 | this.date = date;
32 | this.selected = selected;
33 | }
34 |
35 | public String getDate() {
36 | return dateFormat.format(date.getDate());
37 | }
38 |
39 | public boolean isSelected() {
40 | return selected;
41 | }
42 |
43 | @Override
44 | public String getEventName() {
45 | return EVENT_NAME;
46 | }
47 |
48 | @Override
49 | public short getCoalescingKey() {
50 | return 0;
51 | }
52 |
53 | @Override
54 | public void dispatch(RCTEventEmitter rctEventEmitter) {
55 | rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData());
56 | }
57 |
58 | private WritableMap serializeEventData() {
59 | WritableMap eventData = Arguments.createMap();
60 | eventData.putString("date", getDate());
61 | eventData.putBoolean("selected", isSelected());
62 | return eventData;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/android/src/main/java/com/chymtt/reactnativecalendar/CalendarManager.java:
--------------------------------------------------------------------------------
1 | package com.chymtt.reactnativecalendar;
2 |
3 | import android.graphics.Color;
4 | import android.os.SystemClock;
5 |
6 | import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
7 | import com.facebook.react.bridge.ReadableArray;
8 | import com.facebook.react.common.MapBuilder;
9 | import com.facebook.react.uimanager.annotations.ReactProp;
10 | import com.facebook.react.uimanager.SimpleViewManager;
11 | import com.facebook.react.uimanager.ThemedReactContext;
12 | import com.facebook.react.uimanager.UIManagerModule;
13 | import com.prolificinteractive.materialcalendarview.CalendarDay;
14 | import com.prolificinteractive.materialcalendarview.MaterialCalendarView;
15 | import com.prolificinteractive.materialcalendarview.OnDateSelectedListener;
16 |
17 | import java.text.DateFormat;
18 | import java.text.ParseException;
19 | import java.text.SimpleDateFormat;
20 | import java.util.ArrayList;
21 | import java.util.Date;
22 | import java.util.Map;
23 |
24 | import javax.annotation.Nullable;
25 |
26 | /**
27 | * Created by Chym on 29/11/15.
28 | */
29 | public class CalendarManager extends SimpleViewManager {
30 | public static final String REACT_CLASS = "CalendarAndroid";
31 |
32 | private static final String DATE_FORMAT = "yyyy/MM/dd";
33 | private static final DateFormat dateFormat;
34 | static {
35 | dateFormat = new SimpleDateFormat(DATE_FORMAT);
36 | }
37 |
38 | private static final String COLOR_REGEX = "^#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$";
39 |
40 | @Override
41 | public String getName() {
42 | return REACT_CLASS;
43 | }
44 |
45 | @Override
46 | protected Calendar createViewInstance(ThemedReactContext context) {
47 | return new Calendar(context);
48 | }
49 |
50 | @Nullable
51 | @Override
52 | public Map getExportedCustomBubblingEventTypeConstants() {
53 | return MapBuilder.builder()
54 | .put(
55 | "topDateChange",
56 | MapBuilder.of(
57 | "phasedRegistrationNames",
58 | MapBuilder.of(
59 | "bubbled", "onDateChange", "captured", "onDateChangeCapture")))
60 | .build();
61 | }
62 |
63 | @Override
64 | protected void addEventEmitters(final ThemedReactContext reactContext, final Calendar view) {
65 | view.setOnDateChangedListener(new OnDateSelectedListener() {
66 | @Override
67 | public void onDateSelected(MaterialCalendarView widget, CalendarDay date, boolean selected) {
68 | reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher()
69 | .dispatchEvent(new CalendarEvent(
70 | view.getId(),
71 | date,
72 | selected));
73 | }
74 | });
75 | }
76 |
77 | @ReactProp(name = "topbarVisible")
78 | public void setTopbarVisible(Calendar view, boolean topbarVisible) {
79 | view.setTopbarVisible(topbarVisible);
80 | }
81 |
82 | @ReactProp(name = "arrowColor")
83 | public void setArrowColor(Calendar view, String color) {
84 | if (color != null) {
85 | if (color.matches(COLOR_REGEX)) {
86 | view.setArrowColor(Color.parseColor(color));
87 | } else {
88 | throw new JSApplicationIllegalArgumentException("Invalid arrowColor property: " + color);
89 | }
90 | }
91 | }
92 |
93 | @ReactProp(name = "firstDayOfWeek")
94 | public void setFirstDayOfWeek(Calendar view, String firstDayOfWeek) {
95 | if (firstDayOfWeek != null) {
96 | view.state().edit()
97 | .setFirstDayOfWeek(getFirstDayOfWeekFromString(firstDayOfWeek))
98 | .commit();
99 | }
100 | }
101 |
102 | @ReactProp(name = "showDate")
103 | public void setShowDate(Calendar view, String showDate) {
104 | if (showDate != null) {
105 | if (showDate.equals("all")) {
106 | view.setShowOtherDates(MaterialCalendarView.SHOW_OTHER_MONTHS);
107 | } else if (showDate.equals("current")) {
108 | view.setShowOtherDates(MaterialCalendarView.SHOW_DEFAULTS);
109 | } else {
110 | throw new JSApplicationIllegalArgumentException("Unknown showDate property: " + showDate);
111 | }
112 | }
113 | }
114 |
115 | @ReactProp(name = "currentDate")
116 | public void setCurrentDate(Calendar view, ReadableArray data) {
117 | String type = data.getType(0).name();
118 | if ("String".equals(type)) {
119 | try {
120 | Date date = dateFormat.parse(data.getString(0));
121 | view.setCurrentDate(date);
122 | } catch (ParseException e) {
123 | throw new JSApplicationIllegalArgumentException("Invalid date format: " + data.getString(0));
124 | }
125 | } else if ("Number".equals(type)) {
126 | Double value = data.getDouble(0);
127 | Date date = new Date(value.longValue());
128 | view.setCurrentDate(date);
129 | } else {
130 | throw new JSApplicationIllegalArgumentException("Invalid date format: " + data.getString(0));
131 | }
132 | }
133 |
134 | @ReactProp(name = "minimumDate")
135 | public void setMinimumDate(Calendar view, ReadableArray data) {
136 | String type = data.getType(0).name();
137 | if ("String".equals(type)) {
138 | try {
139 | Date date = dateFormat.parse(data.getString(0));
140 | if (shouldUpdateMinMaxDate(view.getMinimumDate(), date)) {
141 | view.state().edit()
142 | .setMinimumDate(date)
143 | .commit();
144 | }
145 | } catch (ParseException e) {
146 | throw new JSApplicationIllegalArgumentException("Invalid date format: " + data.getString(0));
147 | }
148 | } else if ("Number".equals(type)) {
149 | Double value = data.getDouble(0);
150 | Date date = new Date(value.longValue());
151 | if (shouldUpdateMinMaxDate(view.getMinimumDate(), date)) {
152 | view.state().edit()
153 | .setMinimumDate(date)
154 | .commit();
155 | }
156 | } else {
157 | throw new JSApplicationIllegalArgumentException("Invalid date format: " + data.getString(0));
158 | }
159 | }
160 |
161 | @ReactProp(name = "maximumDate")
162 | public void setMaximumDate(Calendar view, ReadableArray data) {
163 | String type = data.getType(0).name();
164 |
165 | if ("String".equals(type)) {
166 | try {
167 | Date date = dateFormat.parse(data.getString(0));
168 | if (shouldUpdateMinMaxDate(view.getMaximumDate(), date)) {
169 | view.state().edit()
170 | .setMaximumDate(date)
171 | .commit();
172 | }
173 | } catch (ParseException e) {
174 | throw new JSApplicationIllegalArgumentException("Invalid date format: " + data.getString(0));
175 | }
176 | } else if ("Number".equals(type)) {
177 | Double value = data.getDouble(0);
178 | Date date = new Date(value.longValue());
179 |
180 | if (shouldUpdateMinMaxDate(view.getMaximumDate(), date)) {
181 | view.state().edit()
182 | .setMaximumDate(date)
183 | .commit();
184 | }
185 | } else {
186 | throw new JSApplicationIllegalArgumentException("Invalid date format: " + data.getString(0));
187 | }
188 | }
189 |
190 | @ReactProp(name = "selectionMode")
191 | public void setSelectionMode(Calendar view, String mode) {
192 | if (mode != null) {
193 | if (mode.equals("none")) {
194 | view.setSelectionMode(MaterialCalendarView.SELECTION_MODE_NONE);
195 | } else if (mode.equals("single")) {
196 | view.setSelectionMode(MaterialCalendarView.SELECTION_MODE_SINGLE);
197 | } else if (mode.equals("multiple")) {
198 | view.setSelectionMode(MaterialCalendarView.SELECTION_MODE_MULTIPLE);
199 | } else {
200 | throw new JSApplicationIllegalArgumentException("Unknown selectionMode property: " + mode);
201 | }
202 | }
203 | }
204 |
205 | @ReactProp(name = "selectionColor")
206 | public void setSelectionColor(Calendar view, String color) {
207 | if (color != null) {
208 | if (color.matches(COLOR_REGEX)) {
209 | view.setSelectionColor(Color.parseColor(color));
210 | } else {
211 | throw new JSApplicationIllegalArgumentException("Invalid selectionColor property: " + color);
212 | }
213 | }
214 | }
215 |
216 | @ReactProp(name = "selectedDates")
217 | public void setSelectedDates(Calendar view, ReadableArray dates) {
218 | ArrayList selectedDates = new ArrayList();
219 | for (int i = 0; i < dates.size(); i++) {
220 | String type = dates.getType(i).name();
221 | if ("String".equals(type)) {
222 | try {
223 | Date date = dateFormat.parse(dates.getString(i));
224 | selectedDates.add(date);
225 | } catch (ParseException e) {
226 | throw new JSApplicationIllegalArgumentException("Invalid date format: " + dates.getString(i));
227 | }
228 | } else if ("Number".equals(type)) {
229 | Double value = dates.getDouble(i);
230 | Date date = new Date(value.longValue());
231 | selectedDates.add(date);
232 | } else {
233 | throw new JSApplicationIllegalArgumentException("Invalid date format: " + dates.getString(i));
234 | }
235 | }
236 | for (Date date : selectedDates) {
237 | view.setDateSelected(date, true);
238 | }
239 | }
240 |
241 | private int getFirstDayOfWeekFromString(String firstDayOfWeek) {
242 | if (firstDayOfWeek.equals("monday")) {
243 | return java.util.Calendar.MONDAY;
244 | } else if (firstDayOfWeek.equals("tuesday")) {
245 | return java.util.Calendar.TUESDAY;
246 | } else if (firstDayOfWeek.equals("wednesday")) {
247 | return java.util.Calendar.WEDNESDAY;
248 | } else if (firstDayOfWeek.equals("thursday")) {
249 | return java.util.Calendar.THURSDAY;
250 | } else if (firstDayOfWeek.equals("friday")) {
251 | return java.util.Calendar.FRIDAY;
252 | } else if (firstDayOfWeek.equals("saturday")) {
253 | return java.util.Calendar.SATURDAY;
254 | } else if (firstDayOfWeek.equals("sunday")) {
255 | return java.util.Calendar.SUNDAY;
256 | } else {
257 | throw new JSApplicationIllegalArgumentException("Unknown firstDayOfWeek property: " + firstDayOfWeek);
258 | }
259 | }
260 |
261 | /**
262 | * Should update new value of minimum or maximum date
263 | *
264 | * Check if the new min or max date is different from the previous one, if yes we update otherwise we don't.
265 | *
266 | * @param minMaxDate
267 | * @param newDate
268 | * @return boolean
269 | */
270 | private boolean shouldUpdateMinMaxDate(CalendarDay minMaxDate, Date newDate) {
271 | if (minMaxDate == null) {
272 | return true;
273 | }
274 |
275 | java.util.Calendar newDateCalendar = java.util.Calendar.getInstance();
276 | newDateCalendar.setTimeInMillis(newDate.getTime());
277 |
278 | return (minMaxDate.getYear() != newDateCalendar.get(java.util.Calendar.YEAR) &&
279 | minMaxDate.getMonth() != newDateCalendar.get(java.util.Calendar.MONTH) &&
280 | minMaxDate.getDay() != newDateCalendar.get(java.util.Calendar.DAY_OF_MONTH));
281 | }
282 | }
283 |
--------------------------------------------------------------------------------
/android/src/main/java/com/chymtt/reactnativecalendar/CalendarPackage.java:
--------------------------------------------------------------------------------
1 | package com.chymtt.reactnativecalendar;
2 |
3 | import com.facebook.react.ReactPackage;
4 | import com.facebook.react.bridge.JavaScriptModule;
5 | import com.facebook.react.bridge.NativeModule;
6 | import com.facebook.react.bridge.ReactApplicationContext;
7 | import com.facebook.react.uimanager.ViewManager;
8 |
9 | import java.util.ArrayList;
10 | import java.util.Arrays;
11 | import java.util.List;
12 |
13 | /**
14 | * Created by Chym on 29/11/15.
15 | */
16 | public class CalendarPackage implements ReactPackage {
17 | @Override
18 | public List createNativeModules(ReactApplicationContext reactApplicationContext) {
19 | return new ArrayList();
20 | }
21 |
22 | @Override
23 | public List createViewManagers(ReactApplicationContext reactApplicationContext) {
24 | return Arrays.asList(
25 | new CalendarManager()
26 | );
27 | }
28 |
29 | @Override
30 | public List> createJSModules() {
31 | return Arrays.asList();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/android/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-calendar-android",
3 | "version": "0.0.6",
4 | "description": "A simple material-themed calendar for react native android",
5 | "main": "src/Calendar.js",
6 | "repository": {
7 | "type": "git",
8 | "url": "https://github.com/chymtt/ReactNativeCalendarAndroid"
9 | },
10 | "keywords": [
11 | "react-component",
12 | "react-native",
13 | "android",
14 | "material",
15 | "material-design",
16 | "calendar"
17 | ],
18 | "author": "Do Anh Tu ",
19 | "license": "MIT",
20 | "bugs": {
21 | "url": "https://github.com/chymtt/ReactNativeCalendarAndroid/issues"
22 | },
23 | "homepage": "https://github.com/chymtt/ReactNativeCalendarAndroid"
24 | }
25 |
--------------------------------------------------------------------------------
/src/Calendar.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var React = require('react');
4 | var ReactNative = require('react-native');
5 | var { requireNativeComponent, PropTypes, View } = ReactNative;
6 |
7 | var NativeCalendar = requireNativeComponent('CalendarAndroid', Calendar);
8 |
9 | var FIRST_DAY_OF_WEEK = [
10 | 'monday',
11 | 'tuesday',
12 | 'wednesday',
13 | 'thursday',
14 | 'friday',
15 | 'saturday',
16 | 'sunday'
17 | ];
18 |
19 | var SHOWING_DATE = [
20 | 'all',
21 | 'current'
22 | ];
23 |
24 | var SELECTION_MODES = [
25 | 'none',
26 | 'single',
27 | 'multiple'
28 | ];
29 |
30 | var colorType = function (props, propName, componentName) {
31 | var checker = function() {
32 | var color = props[propName];
33 | var regex = /^#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/;
34 | if (!regex.test(color)) {
35 | return new Error('Only accept color formats: #RRGGBB and #AARRGGBB');
36 | }
37 | };
38 |
39 | return PropTypes.string(props, propName, componentName) || checker();
40 | }
41 |
42 | class Calendar extends React.Component {
43 | constructor() {
44 | super();
45 | this._onDateChange = this._onDateChange.bind(this);
46 | }
47 |
48 | _onDateChange(event) {
49 | this.props.onDateChange && this.props.onDateChange(event.nativeEvent);
50 | }
51 |
52 | render() {
53 | var { style, ...rest } = this.props,
54 | width = rest.width,
55 | height = rest.topbarVisible ? width / 7 * 8 : width;
56 |
57 | style = {
58 | ...style,
59 | width,
60 | height
61 | };
62 |
63 | return (
64 |
68 | );
69 | }
70 | }
71 |
72 | Calendar.propTypes = {
73 | ...View.propTypes,
74 | width: PropTypes.number.isRequired,
75 | topbarVisible: PropTypes.bool,
76 | arrowColor: colorType,
77 | firstDayOfWeek: PropTypes.oneOf(FIRST_DAY_OF_WEEK),
78 | showDate: PropTypes.oneOf(SHOWING_DATE),
79 | currentDate: PropTypes.arrayOf(PropTypes.oneOfType([ PropTypes.string, PropTypes.number ])),
80 | selectionMode: PropTypes.oneOf(SELECTION_MODES),
81 | selectionColor: colorType,
82 | selectedDates: PropTypes.arrayOf(PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]))
83 | };
84 |
85 | Calendar.defaultProps = {
86 | topbarVisible: true
87 | }
88 |
89 | module.exports = Calendar;
90 |
--------------------------------------------------------------------------------