Skip to content

Commit

Permalink
Add calendar feature for multi , range and single selection (#19)
Browse files Browse the repository at this point in the history
* add DS_Store in gitignore

* add new calendar component

* update text with allowfontscaling property

* updates

* remove showdate prop

* updates

* update font color style

* add a funtion to get full date

* add left and right arrow in a stylesheet

* updates

* updates for calendar with memoization

* updates in calendar component

* refactor

* refactor code

* update style in header component

* changes in calendar

* add theme package

* merge with origin

* Update theme accessor to sharingapples

* resolve issue #5

* Resolve issue Unnecessary object initializations #2

* remove unused assets

* resolve issue #3 https://github.com/sharingapples/react-native-calendar/issues/3

* resolve issue #1 assets

* resolve issue #6 Make calendar a controlled component #6

* remove date if selected and pressed again

* add memoization to convert array to object

* update for typo

* showcase updates

* add remove multiple select option

* add calendar packages

* update access to calendar component

* updates for calendar packages

* updates for calendar with theme

* update index file to provide disabled value

* update readme and add readme to calendar package

* add link to package

* add a case for null prev date

* refactor code

* remove unused folder

* update calendar for year select

* add provision for universal screen in ios

* updates

* remove magic number

* add TouchableOpacity and comments along with new width check

* update color access in Day

* add new folder to Contain Calndar View

* update project structure

* update package name

* updates for calendar component

* quick bug fix

* updates in calendar

* remove unused props

* review updates

* style update

* review updates

* add travis

* add comment

* add wizard package

* add wizard usecase

* add spacing for footer

* form issue fix

* wizard package update

* remove style from Root View

* updates in form page

* add type prop in calendar

* remove travis

* remove unused files

* change prop value

* fix lint issues
  • Loading branch information
karkipy authored and syaau committed May 17, 2019
1 parent 434b5aa commit 39f84c5
Show file tree
Hide file tree
Showing 27 changed files with 778 additions and 279 deletions.
2 changes: 2 additions & 0 deletions ios/WidgetsShowcase.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1325,6 +1325,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = WidgetsShowcase;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
Expand All @@ -1348,6 +1349,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = WidgetsShowcase;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
Expand Down
107 changes: 107 additions & 0 deletions packages/Calendar/src/Calendar/CalendarView.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// @flow
import React, { useContext, useCallback } from 'react';
import { View, StyleSheet } from 'react-native';
import Month from './Month';

import CalendarContext from '../common/CalendarContext';
import { primaryColor } from '../theme';
import Header from '../common/Header';


const styles = StyleSheet.create({
container: {
flex: 1,
padding: 5,
},
clearTextContainer: {
marginLeft: 15,
},
clearText: {
fontSize: 14,
color: primaryColor,
},
row: {
flexDirection: 'row',
},
});

type Props = {
renderDate: (date: Date) => React.Node,
setValue: number => void,
value: ?Date,
setView: React.Node => void,
type: 'multi' | 'range' | 'single',
}

function dateRange(date1, date2) {
const diffTime = date2.getTime() - date1.getTime();
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
const startDate = diffDays < 0 ? date2 : date1;
const dates = Array(Math.abs(diffDays)).fill(new Date(startDate)).map(m => new Date(m.setDate(m.getDate() + 1)));
return [startDate, ...dates];
}

function CalendarView({
renderDate, setValue, value, setView, type,
}: Props) {
const [months, setMonths] = useContext(CalendarContext);

const shift = useCallback((val) => {
setMonths(mnths => mnths.map(d => new Date(
d.getFullYear(),
d.getMonth() + val,
1
)));
}, []);

const selectDate = useCallback((d, long) => {
setValue((prev) => {
if (type === 'multi') {
if (Array.isArray(prev)) {
// logic to remove the date if already Selected
const isAlreadySelected = prev.filter(dates => dates.toDateString() === d.toDateString());
return isAlreadySelected.length > 0
? [...prev.filter(dates => dates.toDateString() !== d.toDateString())]
: [...prev, d];
}
if (long) {
return prev ? [prev, d] : [d];
}
} else if (type === 'range') {
if (Array.isArray(prev)) {
return d;
}
if (prev) {
return dateRange(prev, d);
}
return d;
}
return d;
});
}, []);

function clearSelect() {
setValue(null);
}

clearSelect.title = 'Clear';
return (
<>
{months.map(month => (
<View key={month} style={styles.container}>
<Month
date={month}
value={value}
renderDate={renderDate}
selectDate={selectDate}
setView={setView}
/>
</View>
))}
<Header shift={shift} action={Array.isArray(value) && clearSelect} />
</>
);
}


export default CalendarView;
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
// @flow
import React from 'react';
import { View, TouchableOpacity, Text, StyleSheet } from 'react-native';
import { getTheme } from '@sharingapples/theme';
import { textColor, backgroundColor, primaryFontColor, primaryColor, disabledFontColor } from '../theme';

const theme = getTheme();
const calendarTheme = theme.onCalendar || theme;
const textColor = calendarTheme.onBackground;
const backgroundColor = calendarTheme.background;
const primaryFontColor = theme.onPrimary;
const disabledFontColor = theme.disabled;

const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
paddingHorizontal: 3,
paddingVertical: 3,
borderLeftWidth: 1,
borderRightWidth: 1,
borderTopWidth: 1,
borderBottomWidth: 1,
margin: -1,
borderWidth: StyleSheet.hairlineWidth,
margin: -StyleSheet.hairlineWidth,
// because of inconsistency in android for border each has to be defined
borderLeftColor: 'transparent',
borderRightColor: 'transparent',
borderTopColor: 'transparent',
borderBottomColor: 'transparent',
},
textContainer: {
paddingHorizontal: 6,
Expand All @@ -31,6 +27,9 @@ const styles = StyleSheet.create({
width: 30,
height: 30,
},
text: {
fontSize: 14,
},
});

type Props = {
Expand All @@ -55,10 +54,9 @@ function Day({
const dateObj = new Date(date);
const isCurrentMonth = currentMonth === dateObj.getMonth();
const isToday = dateObj.toDateString() === new Date().toDateString();

return (
<TouchableOpacity
style={[styles.container, borderStyle || { borderColor: 'transparent' }]}
style={[styles.container, borderStyle]}
onLongPress={() => {
// stack this to selected date
selectDate(dateObj, true);
Expand All @@ -70,15 +68,14 @@ function Day({
>

<View style={[
styles.textContainer, { backgroundColor: isToday ? theme.primary : backgroundColor },
styles.textContainer, { backgroundColor: isToday ? primaryColor : backgroundColor },
]}
>
<Text
allowFontScaling={false}
style={{
style={[styles.text, {
color: isToday ? primaryFontColor : getFontColor(isCurrentMonth),
fontSize: 14,
}}
}]}
>
{dateObj.getDate()}
</Text>
Expand Down
104 changes: 104 additions & 0 deletions packages/Calendar/src/Calendar/Month.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// @flow
import React from 'react';
import { View, StyleSheet, TouchableOpacity, Text } from 'react-native';
import Week from './Week';
import MonthSelection from '../MonthSelection';
import YearSelection from '../YearSelection';
import { WEEK_DAYS } from '../common/util';
import { textColor } from '../theme';

type Props = {
date: Date,
setView: React.Node => void,
}


const styles = StyleSheet.create({
header: {
flexDirection: 'row',
justifyContent: 'center',
paddingVertical: 5,
},
dateText: {
fontSize: 14,
color: textColor,
},
nav: {
paddingHorizontal: 5,
},
navText: {
fontSize: 14,
},
daysContainer: {
width: '100%',
flexDirection: 'row',
marginTop: 5,
paddingVertical: 5,
marginBottom: 5,
borderBottomColor: textColor,
borderBottomWidth: StyleSheet.hairlineWidth,
},
day: {
flex: 1,
alignItems: 'center',
},
dayText: {
fontSize: 14,
color: textColor,
},
});

const NUM_OF_WEEKS = 6;
const WEEK_DIFF = 7 * 86400 * 1000;

function getStartOfMonth(date) {
const first = new Date(date.getFullYear(), date.getMonth(), 1);
return first.getTime() - first.getDay() * 86400 * 1000;
}

function Month({ date, setView, ...other }: Props) {
const start = getStartOfMonth(date);
const dateString = date.toString();
const month = dateString.substr(4, 3);
const year = dateString.substr(11, 4);
const weeks = new Array(NUM_OF_WEEKS).fill(null).map((c, i) => start + i * WEEK_DIFF);
return (
<>
<View>
<View style={styles.header}>
<TouchableOpacity
onPress={() => setView(() => MonthSelection)}
style={styles.nav}
>
<Text style={styles.navText} allowFontScaling={false}>{month}</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => setView(() => YearSelection)}
style={styles.nav}
>
<Text style={styles.navText} allowFontScaling={false}>{year}</Text>
</TouchableOpacity>
</View>

<View style={styles.daysContainer}>
{WEEK_DAYS.map(d => (
<View key={d} style={styles.day}>
<Text allowFontScaling={false} style={styles.dayText}>{d}</Text>
</View>
))}
</View>
</View>

{weeks.map(week => (
<Week
key={week}
startOfWeek={week}
month={date.getMonth()}
{...other}
/>
))}
</>
);
}

export default Month;
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import React from 'react';
import { View, StyleSheet } from 'react-native';
import Day from './Day';
import { getDateBorderStyle, DAY_DIFF } from './util';
import { getDateBorderStyle, DAY_DIFF } from '../common/util';

const styles = StyleSheet.create({
container: {
Expand Down
3 changes: 3 additions & 0 deletions packages/Calendar/src/Calendar/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import CalendarView from './CalendarView';

export default CalendarView;
Loading

0 comments on commit 39f84c5

Please sign in to comment.