diff --git a/.gitignore b/.gitignore index 158b5d1..cc3402c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,8 @@ node_modules/**/* example/node_modules/ example/CalendarPicker/ example/package-lock.json - +*.apk +*.aab # Xcode build/ *.pbxuser diff --git a/CalendarPicker/Day.js b/CalendarPicker/Day.js index f79b618..649f690 100644 --- a/CalendarPicker/Day.js +++ b/CalendarPicker/Day.js @@ -1,13 +1,10 @@ -import React from 'react'; -import { - View, - Text, - TouchableOpacity -} from 'react-native'; -import PropTypes from 'prop-types'; -import moment from 'moment'; +import React, { useEffect, useState } from "react"; +import { View, Text, TouchableOpacity, Platform } from "react-native"; +import PropTypes from "prop-types"; +import moment from "moment"; -export default function Day(props) { +function Day(props) { + const [CurrentMonthDays, setCurrentMonthDays] = useState([]); const { day, month, @@ -35,12 +32,29 @@ export default function Day(props) { disabledDatesTextStyle, minRangeDuration, maxRangeDuration, - enableDateChange + enableDateChange, + dotsData, + monthDays, + monthDates, } = props; + const thisDay = moment({ year, month, day, hour: 12 }); + useEffect(() => { + function getDatesArrayForCurrentMonth() { + const daysInMonth = moment({ year: year, month: month }).daysInMonth(); + const datesArray = []; - const thisDay = moment({year, month, day, hour: 12 }); - const today = moment(); + for (let day = 1; day <= daysInMonth; day++) { + datesArray.push(moment({ year: year, month: month, day })); + } + monthDates && monthDates(datesArray); + return datesArray; + } + + getDatesArrayForCurrentMonth(); + }, []); + // monthDays(CurrentMonthDays) + const today = moment(); let dateOutOfRange; let computedSelectedDayStyle = styles.dayButton; // may be overridden depending on state let selectedDayTextStyle = {}; @@ -56,43 +70,49 @@ export default function Day(props) { // Check whether props maxDate / minDate are defined. If not supplied, // don't restrict dates. if (maxDate) { - dateIsAfterMax = thisDay.isAfter(maxDate, 'day'); + dateIsAfterMax = thisDay.isAfter(maxDate, "day"); } if (minDate) { - dateIsBeforeMin = thisDay.isBefore(minDate, 'day'); + dateIsBeforeMin = thisDay.isBefore(minDate, "day"); } if (disabledDates) { - if (Array.isArray(disabledDates) && disabledDates.indexOf(thisDay.valueOf()) >= 0) { + if ( + Array.isArray(disabledDates) && + disabledDates.indexOf(thisDay.valueOf()) >= 0 + ) { dateIsDisabled = true; - } - else if (disabledDates instanceof Function) { + } else if (disabledDates instanceof Function) { dateIsDisabled = disabledDates(thisDay); } } if (allowRangeSelection && selectedStartDate && !selectedEndDate) { - let daysDiff = thisDay.diff(selectedStartDate, 'days'); // may be + or - + let daysDiff = thisDay.diff(selectedStartDate, "days"); // may be + or - daysDiff = allowBackwardRangeSelect ? Math.abs(daysDiff) : daysDiff; if (maxRangeDuration) { if (Array.isArray(maxRangeDuration)) { - let maxRangeEntry = maxRangeDuration.find(mrd => selectedStartDate.isSame(mrd.date, 'day') ); + let maxRangeEntry = maxRangeDuration.find((mrd) => + selectedStartDate.isSame(mrd.date, "day") + ); if (maxRangeEntry && daysDiff > maxRangeEntry.maxDuration) { dateRangeGreaterThanMax = true; } - } else if(daysDiff > maxRangeDuration) { + } else if (daysDiff > maxRangeDuration) { dateRangeGreaterThanMax = true; } } if (minRangeDuration) { if (Array.isArray(minRangeDuration)) { - let minRangeEntry = minRangeDuration.find(mrd => selectedStartDate.isSame(mrd.date, 'day') ); + let minRangeEntry = minRangeDuration.find((mrd) => + selectedStartDate.isSame(mrd.date, "day") + ); if (minRangeEntry && daysDiff < minRangeEntry.minDuration) { dateRangeLessThanMin = true; } - } else if(daysDiff < minRangeDuration) { + } else if (daysDiff < minRangeDuration) { dateRangeLessThanMin = true; } } @@ -101,27 +121,43 @@ export default function Day(props) { dateRangeLessThanMin = true; } } + const matchingDots = dotsData?.filter( + (dot) => dot.day === day && dot.month === month && dot.year === year + ); - dateOutOfRange = dateIsAfterMax || dateIsBeforeMin || dateIsDisabled || dateRangeLessThanMin || dateRangeGreaterThanMax; + dateOutOfRange = + dateIsAfterMax || + dateIsBeforeMin || + dateIsDisabled || + dateRangeLessThanMin || + dateRangeGreaterThanMax; - let isThisDaySameAsSelectedStart = thisDay.isSame(selectedStartDate, 'day'); - let isThisDaySameAsSelectedEnd = thisDay.isSame(selectedEndDate, 'day'); + let isThisDaySameAsSelectedStart = thisDay.isSame(selectedStartDate, "day"); + let isThisDaySameAsSelectedEnd = thisDay.isSame(selectedEndDate, "day"); let isThisDateInSelectedRange = - selectedStartDate - && selectedEndDate - && thisDay.isBetween(selectedStartDate, selectedEndDate,'day','[]'); + selectedStartDate && + selectedEndDate && + thisDay.isBetween(selectedStartDate, selectedEndDate, "day", "[]"); // If date is in range let's apply styles - if (!dateOutOfRange || isThisDaySameAsSelectedStart || isThisDaySameAsSelectedEnd || isThisDateInSelectedRange) { + if ( + !dateOutOfRange || + isThisDaySameAsSelectedStart || + isThisDaySameAsSelectedEnd || + isThisDateInSelectedRange + ) { // set today's style - let isToday = thisDay.isSame(today, 'day'); + let isToday = thisDay.isSame(today, "day"); if (isToday) { computedSelectedDayStyle = styles.selectedToday; // todayTextStyle prop overrides selectedDayTextColor (created via makeStyles) - selectedDayTextStyle = [todayTextStyle || styles.selectedDayLabel, propSelectedDayTextStyle]; + selectedDayTextStyle = [ + todayTextStyle || styles.selectedDayLabel, + propSelectedDayTextStyle, + ]; } - const custom = getCustomDateStyle({customDatesStyles, date: thisDay}); + const custom = getCustomDateStyle({ customDatesStyles, date: thisDay }); if (isToday && custom.style) { // Custom date style overrides 'today' style. It may be reset below @@ -130,12 +166,17 @@ export default function Day(props) { } // set selected day style - if (!allowRangeSelection && - selectedStartDate && - isThisDaySameAsSelectedStart) - { + if ( + !allowRangeSelection && + selectedStartDate && + isThisDaySameAsSelectedStart + ) { computedSelectedDayStyle = styles.selectedDay; - selectedDayTextStyle = [styles.selectedDayLabel, isToday && todayTextStyle, propSelectedDayTextStyle]; + selectedDayTextStyle = [ + styles.selectedDayLabel, + isToday && todayTextStyle, + propSelectedDayTextStyle, + ]; // selectedDayStyle prop overrides selectedDayColor (created via makeStyles) selectedDayStyle = propSelectedDayStyle || styles.selectedDayBackground; } @@ -145,73 +186,183 @@ export default function Day(props) { if (selectedStartDate && selectedEndDate) { // Apply style for start date if (isThisDaySameAsSelectedStart) { - computedSelectedDayStyle = [styles.startDayWrapper, selectedRangeStyle, selectedRangeStartStyle]; - selectedDayTextStyle = [styles.selectedDayLabel, propSelectedDayTextStyle, selectedRangeStartTextStyle]; + computedSelectedDayStyle = [ + styles.startDayWrapper, + selectedRangeStyle, + selectedRangeStartStyle, + ]; + selectedDayTextStyle = [ + styles.selectedDayLabel, + propSelectedDayTextStyle, + selectedRangeStartTextStyle, + ]; } // Apply style for end date if (isThisDaySameAsSelectedEnd) { - computedSelectedDayStyle = [styles.endDayWrapper, selectedRangeStyle, selectedRangeEndStyle]; - selectedDayTextStyle = [styles.selectedDayLabel, propSelectedDayTextStyle, selectedRangeEndTextStyle]; + computedSelectedDayStyle = [ + styles.endDayWrapper, + selectedRangeStyle, + selectedRangeEndStyle, + ]; + selectedDayTextStyle = [ + styles.selectedDayLabel, + propSelectedDayTextStyle, + selectedRangeEndTextStyle, + ]; } // Apply style if start date is the same as end date - if (isThisDaySameAsSelectedEnd && - isThisDaySameAsSelectedStart && - selectedEndDate.isSame(selectedStartDate, 'day')) - { - computedSelectedDayStyle = [styles.selectedDay, styles.selectedDayBackground, selectedRangeStyle]; - selectedDayTextStyle = [styles.selectedDayLabel, propSelectedDayTextStyle, selectedRangeStartTextStyle]; + if ( + isThisDaySameAsSelectedEnd && + isThisDaySameAsSelectedStart && + selectedEndDate.isSame(selectedStartDate, "day") + ) { + computedSelectedDayStyle = [ + styles.selectedDay, + styles.selectedDayBackground, + selectedRangeStyle, + ]; + selectedDayTextStyle = [ + styles.selectedDayLabel, + propSelectedDayTextStyle, + selectedRangeStartTextStyle, + ]; } // Apply style for days inside of range, excluding start & end dates. - if (thisDay.isBetween(selectedStartDate, selectedEndDate, 'day', '()')) { + if ( + thisDay.isBetween(selectedStartDate, selectedEndDate, "day", "()") + ) { computedSelectedDayStyle = [styles.inRangeDay, selectedRangeStyle]; - selectedDayTextStyle = [styles.selectedDayLabel, propSelectedDayTextStyle]; + selectedDayTextStyle = [ + styles.selectedDayLabel, + propSelectedDayTextStyle, + ]; } } // Apply style if start date has been selected but end date has not - if (selectedStartDate && - !selectedEndDate && - isThisDaySameAsSelectedStart) - { - computedSelectedDayStyle = [styles.startDayWrapper, selectedRangeStyle, selectedRangeStartStyle]; - selectedDayTextStyle = [styles.selectedDayLabel, propSelectedDayTextStyle, selectedRangeStartTextStyle]; + if ( + selectedStartDate && + !selectedEndDate && + isThisDaySameAsSelectedStart + ) { + computedSelectedDayStyle = [ + styles.startDayWrapper, + selectedRangeStyle, + selectedRangeStartStyle, + ]; + selectedDayTextStyle = [ + styles.selectedDayLabel, + propSelectedDayTextStyle, + selectedRangeStartTextStyle, + ]; // Override out of range start day text style when minRangeDuration = 1. // This allows selected start date's text to be styled by selectedRangeStartTextStyle // even when it's below minRangeDuration. overrideOutOfRangeTextStyle = selectedRangeStartTextStyle; } } - - if (dateOutOfRange) { // start or end date selected, and this date outside of range. + if (dateOutOfRange) { + // start or end date selected, and this date outside of range. return ( - - - { day } + + + {day} + {matchingDots?.length > 0 && ( + + {matchingDots[0].colors + .slice(0, matchingDots[0].value) + .map((color, index) => ( + + ))} + + )} ); } else { return ( - + onPressDay({year, month, day}) }> - - { day } + style={[custom.style, computedSelectedDayStyle, selectedDayStyle]} + onPress={() => onPressDay({ year, month, day })} + > + + {day} + + {matchingDots?.length > 0 && ( + + {matchingDots[0].colors + .slice(0, matchingDots[0].value) + .map((color, index) => ( + + ))} + + )} ); } - } - else { // dateOutOfRange = true, and no selected start or end date. - const custom = getCustomDateStyle({customDatesStyles, date: thisDay}); + } else { + // dateOutOfRange = true, and no selected start or end date. + const custom = getCustomDateStyle({ customDatesStyles, date: thisDay }); // Allow customDatesStyles to override disabled dates if allowDisabled set if (!custom.allowDisabled) { custom.containerStyle = null; @@ -221,32 +372,60 @@ export default function Day(props) { return ( - - { day } + + {day} + {matchingDots?.length > 0 && ( + + {matchingDots[0].colors + .slice(0, matchingDots[0].value) + .map((color, index) => ( + + ))} + + )} ); } } -function getCustomDateStyle({customDatesStyles, date}) { +function getCustomDateStyle({ customDatesStyles, date }) { if (Array.isArray(customDatesStyles)) { for (let cds of customDatesStyles) { - if (date.isSame(moment(cds.date), 'day')) { - return {...cds}; + if (date.isSame(moment(cds.date), "day")) { + return { ...cds }; } } - } - else if (customDatesStyles instanceof Function) { + } else if (customDatesStyles instanceof Function) { let cds = customDatesStyles(date) || {}; - return {...cds}; + return { ...cds }; } return {}; } Day.defaultProps = { customDatesStyles: [], + dotsData: [], + monthDates: (item) => { + console.log("item==="); + }, }; Day.propTypes = { @@ -257,3 +436,4 @@ Day.propTypes = { minRangeDuration: PropTypes.oneOfType([PropTypes.array, PropTypes.number]), maxRangeDuration: PropTypes.oneOfType([PropTypes.array, PropTypes.number]), }; +export default Day; diff --git a/CalendarPicker/DaysGridView.js b/CalendarPicker/DaysGridView.js index 7222334..1ff614a 100644 --- a/CalendarPicker/DaysGridView.js +++ b/CalendarPicker/DaysGridView.js @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import { View } from 'react-native'; +import { Text, View } from 'react-native'; import PropTypes from 'prop-types'; import { stylePropType } from './localPropTypes'; import Day from './Day'; @@ -86,7 +86,7 @@ export default class DaysGridView extends Component { !Utils.compareDates(selectedEndDate, prevSelEnd, 'day'); // Check that selected date(s) match this month. if (isSelectedDiff && ( - Utils.compareDates(selectedStartDate, firstDayOfMonth, 'month') || + Utils.compareDates(selectedStartDate, firstDayOfMonth, 'month') || Utils.compareDates(selectedEndDate, firstDayOfMonth, 'month') || Utils.compareDates(prevSelStart, firstDayOfMonth, 'month') || Utils.compareDates(prevSelEnd, firstDayOfMonth, 'month') )) @@ -121,21 +121,26 @@ export default class DaysGridView extends Component { } } } - - renderDayInCurrentMonth(day) { - return ({ + + renderDayInCurrentMonth(day) { + return { day, month: this.props.month, component: ( - + + + + ), - }); + }; + + } - + renderEmptyDay(key) { return ({ component: ( @@ -227,16 +232,15 @@ export default class DaysGridView extends Component { const { daysGrid } = this.state; const renderedDaysGrid = daysGrid.map((weekRow, i) => ( - { weekRow.map(day => day.component ) } + {weekRow.map(day => day.component)} )); - + return ( - { renderedDaysGrid } + {renderedDaysGrid} - ); - } + );} } DaysGridView.propTypes = { @@ -268,4 +272,5 @@ DaysGridView.propTypes = { disabledDatesTextStyle: stylePropType, minRangeDuration: PropTypes.oneOfType([PropTypes.array, PropTypes.number]), maxRangeDuration: PropTypes.oneOfType([PropTypes.array, PropTypes.number]), + }; diff --git a/CalendarPicker/__tests__/CalendarPicker-test.js b/CalendarPicker/__tests__/CalendarPicker-test.js index 4a30e31..849a59c 100644 --- a/CalendarPicker/__tests__/CalendarPicker-test.js +++ b/CalendarPicker/__tests__/CalendarPicker-test.js @@ -28,6 +28,7 @@ describe('CalendarPicker', function() { selectedDayColor="#7300e6" selectedDayTextColor="#FFFFFF" onDateChange={() => {}} + /> ).toJSON(); expect(CalendarPicker).toBeTruthy(); diff --git a/CalendarPicker/index.js b/CalendarPicker/index.js index 0d30414..5961cc7 100644 --- a/CalendarPicker/index.js +++ b/CalendarPicker/index.js @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import { View, Dimensions } from 'react-native'; +import { View, Dimensions, Text } from 'react-native'; import { makeStyles } from './makeStyles'; import { Utils } from './Utils'; import HeaderControls from './HeaderControls'; @@ -220,7 +220,6 @@ export default class CalendarPicker extends Component { } return {minRangeDuration, maxRangeDuration}; } - handleOnPressDay = ({year, month, day}) => { const { selectedStartDate: prevSelectedStartDate, @@ -437,20 +436,28 @@ export default class CalendarPicker extends Component { } monthsList.push(month); } - return { + monthsList, initialScrollerIndex, }; } - + + renderMonth(props) { return ( - + + ); } render() { + const { currentView, currentMonth, @@ -489,10 +496,12 @@ export default class CalendarPicker extends Component { onMonthChange, scrollable, horizontal, + } = this.props; - let content; - switch (currentView) { + switch (currentView) + + { case 'months': content = ( + + { scrollable ? this.scroller = scroller} @@ -584,7 +595,10 @@ export default class CalendarPicker extends Component { updateMonthYear={this.updateMonthYear} onMonthChange={onMonthChange} horizontal={horizontal} + + /> + : this.renderMonth(renderMonthParams) } diff --git a/CalendarPicker/makeStyles.js b/CalendarPicker/makeStyles.js index 50b6bce..95a74b7 100644 --- a/CalendarPicker/makeStyles.js +++ b/CalendarPicker/makeStyles.js @@ -1,11 +1,13 @@ +import { color } from "react-native-reanimated"; + /** * Calendar Picker Component * * Copyright 2016 Yahoo Inc. * Licensed under the terms of the MIT license. See LICENSE file in the project root for terms. */ -const DEFAULT_SELECTED_BACKGROUND_COLOR = '#5ce600'; -const DEFAULT_SELECTED_TEXT_COLOR = '#000000'; +const DEFAULT_SELECTED_BACKGROUND_COLOR = '#000666'; +const DEFAULT_SELECTED_TEXT_COLOR = 'pink'; const DEFAULT_TODAY_BACKGROUND_COLOR = '#CCCCCC'; function getBorderRadiusByShape(scaler, dayShape) { @@ -43,7 +45,7 @@ export function makeStyles(params) { dayButton: { width: 30*scaler, height: 30*scaler, - borderRadius: getBorderRadiusByShape(scaler, dayShape), + // borderRadius: getBorderRadiusByShape(scaler, dayShape), alignSelf: 'center', justifyContent: 'center' }, @@ -51,7 +53,7 @@ export function makeStyles(params) { dayLabel: { fontSize: 14*scaler, color: '#000', - alignSelf: 'center' + alignSelf: 'center', }, selectedDayLabel: { @@ -60,8 +62,8 @@ export function makeStyles(params) { dayLabelsWrapper: { flexDirection: 'row', - borderBottomWidth: 1, - borderTopWidth: 1, + // borderBottomWidth: 1, + // borderTopWidth: 1, paddingTop: 10*scaler, paddingBottom: 10*scaler, alignSelf: 'center', @@ -69,23 +71,23 @@ export function makeStyles(params) { backgroundColor: 'rgba(0,0,0,0.0)', borderColor: 'rgba(0,0,0,0.2)' }, - daysWrapper: { alignSelf: 'center', - justifyContent: 'center' + justifyContent: 'center', + color:"#000666" }, dayLabels: { width: 50*scaler, fontSize: 12*scaler, - color: '#000', + color: '#000066', textAlign: 'center' }, selectedDay: { width: 30*scaler, height:30*scaler, - borderRadius: getBorderRadiusByShape(scaler, dayShape), + // borderRadius: getBorderRadiusByShape(scaler, dayShape), alignSelf: 'center', justifyContent: 'center' }, @@ -95,12 +97,13 @@ export function makeStyles(params) { }, selectedToday: { - width: 30*scaler, - height:30*scaler, + width: 35*scaler, + height:35*scaler, backgroundColor: TODAY_BG_COLOR, - borderRadius: getBorderRadiusByShape(scaler, dayShape), + borderRadius:5, + // borderRadius: getBorderRadiusByShape(scaler, dayShape), alignSelf: 'center', - justifyContent: 'center' + justifyContent: 'center', }, dayWrapper: { @@ -108,15 +111,18 @@ export function makeStyles(params) { justifyContent: 'center', width: 50*scaler, height: 40*scaler, - backgroundColor: 'rgba(0,0,0,0.0)' + backgroundColor: 'rgba(0,0,0,0.0)', + color:"#000666" }, startDayWrapper: { width: 50*scaler, height: 30*scaler, - borderTopLeftRadius: 20*scaler, - borderBottomLeftRadius: 20*scaler, + borderTopLeftRadius: 5, + borderBottomLeftRadius: 5, backgroundColor: SELECTED_BG_COLOR, + color:"white", + alignSelf: 'center', justifyContent: 'center' }, @@ -124,9 +130,11 @@ export function makeStyles(params) { endDayWrapper: { width: 50*scaler, height: 30*scaler, - borderTopRightRadius: 20*scaler, - borderBottomRightRadius: 20*scaler, + borderTopRightRadius: 5, + borderBottomRightRadius:5, backgroundColor: SELECTED_BG_COLOR, + color:"white", + alignSelf: 'center', justifyContent: 'center' }, @@ -134,7 +142,7 @@ export function makeStyles(params) { inRangeDay: { width: 50*scaler, height: 30*scaler, - backgroundColor: SELECTED_BG_COLOR, + backgroundColor: '#D4D4FF', alignSelf: 'center', justifyContent: 'center' }, @@ -203,7 +211,7 @@ export function makeStyles(params) { monthButton: { width: 30*scaler, height: 30*scaler, - borderRadius: 30*scaler, + // borderRadius: 30*scaler, alignSelf: 'center', justifyContent: 'center' },