aekimena-month-year-picker
Version:
Sleek, customizable month-year-picker for React Native applications
224 lines (213 loc) • 10.1 kB
JavaScript
import { StyleSheet, View, FlatList, Text, TouchableOpacity, Modal, Pressable } from 'react-native';
import React, { useState } from 'react';
var styles = StyleSheet.create({
modalContainer: {
width: "100%",
justifyContent: "flex-end",
alignItems: "center",
zIndex: 5,
position: "absolute",
bottom: 30,
},
containerStyle: {
width: "90%",
backgroundColor: "#fff",
borderRadius: 15,
overflow: "hidden",
},
ConfirmButtonStyle: {
paddingVertical: 10,
paddingHorizontal: 20,
alignItems: "center",
justifyContent: "center",
backgroundColor: "#000",
borderRadius: 10,
top: 10,
},
buttonTextStyle: {
fontSize: 16,
color: "#fff",
},
innerContainer: {
flex: 1,
flexDirection: "row",
justifyContent: "center",
},
highlighter: {
height: 50,
top: 100,
width: "100%",
backgroundColor: "rgba(0,0,0,0.1)",
position: "absolute",
zIndex: -1,
},
itemContainer: {
height: 50,
justifyContent: "center",
alignItems: "center",
width: "100%",
},
itemText: {
fontSize: 16,
color: "#000",
},
listContainer: {
paddingBottom: 100,
paddingTop: 100,
},
absolutePressItem: { position: "absolute", height: "100%", width: "100%" },
});
function getYears(_a) {
var minDate = _a.minDate, maxDate = _a.maxDate;
var startYear = new Date(minDate).getFullYear();
var endYear = new Date(maxDate).getFullYear();
var years = [];
for (var year = startYear; year <= endYear; year++) {
years.push(year);
}
return years;
}
function getDaysInMonth(_a) {
var month = _a.month, year = _a.year;
var date = new Date(year, month, 1);
var days = [];
while (date.getMonth() === month) {
days.push(date.getDate());
date.setDate(date.getDate() + 1);
}
return days;
}
function getDateDateString(_a) {
var year = _a.year, month = _a.month, day = _a.day;
// Create a new Date object with the provided year and month (zero-based index)
var date;
// If day is provided, create a date with day
if (day !== undefined) {
date = new Date(year, month, day);
}
else {
// If no day is provided, create a date with the first day of the month
date = new Date(year, month, 1);
}
// Return the date string in the format 'YYYY-MM-DD'
return date.toISOString();
}
var monthsArr = [
"Jan",
"Feb",
"Mar",
"Api",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
];
var DateFlatList = function (_a) {
var data = _a.data, onScrollToIndex = _a.onScrollToIndex, yScrollOffset = _a.yScrollOffset, highlightedItem = _a.highlightedItem, itemTextStyle = _a.itemTextStyle, itemContainerStyle = _a.itemContainerStyle;
return (React.createElement(View, { style: { flex: 1 } },
React.createElement(FlatList, { onScroll: function (event) {
var scrollOffset = event.nativeEvent.contentOffset.y;
onScrollToIndex(Math.round(scrollOffset / 50));
}, contentOffset: { x: 0, y: yScrollOffset }, data: data, contentContainerStyle: styles.listContainer, keyExtractor: function (item) { return item.toString(); }, renderItem: function (_a) {
var item = _a.item;
return (React.createElement(View, { style: [styles.itemContainer, itemContainerStyle, { height: 50 }] },
React.createElement(Text, { style: [
styles.itemText,
highlightedItem == item && {
fontSize: 20,
fontWeight: "500",
},
itemTextStyle,
] }, typeof item == "number" && item < 10 ? "0" + item : item)));
}, getItemLayout: function (data, index) { return ({
length: 50,
offset: 50 * index,
index: index,
}); }, showsVerticalScrollIndicator: false, snapToInterval: 50, decelerationRate: "fast" })));
};
var Highlighter = function (_a) {
var highlighterStyle = _a.highlighterStyle;
return (React.createElement(View, { style: [styles.highlighter, highlighterStyle, { height: 50 }] }));
};
var ConfirmButton = function (_a) {
var buttonText = _a.buttonText, buttonStyle = _a.buttonStyle, buttonTextStyle = _a.buttonTextStyle, onConfirm = _a.onConfirm;
return (React.createElement(TouchableOpacity, { onPress: onConfirm, style: [styles.ConfirmButtonStyle, buttonStyle], activeOpacity: 0.5 },
React.createElement(Text, { style: [styles.buttonTextStyle, buttonTextStyle] }, buttonText)));
};
var currentDate = new Date();
var MonthYearPicker = function (_a) {
var _b = _a.visible, visible = _b === void 0 ? false : _b, _c = _a.animationType, animationType = _c === void 0 ? "fade" : _c, _d = _a.transparent, transparent = _d === void 0 ? true : _d, onRequestClose = _a.onRequestClose, onBackgroundPress = _a.onBackgroundPress, _e = _a.opacity, opacity = _e === void 0 ? 0.5 : _e, containerStyle = _a.containerStyle, _f = _a.maxDate, maxDate = _f === void 0 ? "2024-12-1" : _f, _g = _a.minDate, minDate = _g === void 0 ? "1970-12-1" : _g, onConfirm = _a.onConfirm, _h = _a.showDays, showDays = _h === void 0 ? true : _h, highlighterStyle = _a.highlighterStyle, itemContainerStyle = _a.itemContainerStyle, itemTextStyle = _a.itemTextStyle, buttonStyle = _a.buttonStyle, buttonTextStyle = _a.buttonTextStyle, _j = _a.buttonText, buttonText = _j === void 0 ? "Confirm" : _j, _k = _a.disableFutureMonths, disableFutureMonths = _k === void 0 ? false : _k;
// years array
var yearsData = getYears({ maxDate: maxDate, minDate: minDate });
// months array
var monthsData = monthsArr;
// highlighted year
var _l = useState(yearsData.indexOf(currentDate.getFullYear())), higlightedYear = _l[0], setHighlightedYear = _l[1];
// highlighted month
var _m = useState(monthsData.indexOf(monthsData[currentDate.getMonth()])), highlightedMonth = _m[0], setHighlightedMonth = _m[1];
// days array
var daysData = getDaysInMonth({
month: highlightedMonth,
year: higlightedYear,
});
// highlighted day
var _o = useState(daysData.indexOf(currentDate.getDate())), highlightedMonthDay = _o[0], setHighlightedMonthDay = _o[1];
// Check if the provided date is a valid date type
var maxDateToCheck = new Date(maxDate);
var minDateToCheck = new Date(minDate);
if (isNaN(maxDateToCheck.getTime()) || isNaN(minDateToCheck.getTime())) {
throw new Error("Date must be a valid date type");
}
// Check if the provided date is less/greater than the current date
if (maxDateToCheck < currentDate) {
throw new Error("Max date must be greater than or equal to the current date");
}
if (minDateToCheck >= currentDate) {
throw new Error("Min date must be less than the current date");
}
// check for opacity error
if (typeof opacity !== "number") {
throw new Error("Opacity must be of type number");
}
// functions
// get months array to display
function getMonthsData() {
if (disableFutureMonths) {
return yearsData[higlightedYear] == currentDate.getFullYear()
? monthsData.slice(0, currentDate.getMonth() + 1)
: monthsData;
}
return monthsData;
}
return (React.createElement(Modal, { visible: visible, animationType: animationType, transparent: transparent, statusBarTranslucent: true, onRequestClose: onRequestClose },
React.createElement(View, { style: [styles.modalContainer] },
React.createElement(View, { style: [styles.containerStyle, containerStyle, { height: 250 }] },
React.createElement(View, { style: styles.innerContainer },
showDays == true && (React.createElement(DateFlatList, { data: daysData, onScrollToIndex: setHighlightedMonthDay, highlightedItem: daysData[highlightedMonthDay], yScrollOffset: daysData.indexOf(currentDate.getDate()) * 50, itemContainerStyle: itemContainerStyle, itemTextStyle: itemTextStyle })),
React.createElement(DateFlatList, { data: getMonthsData(), onScrollToIndex: function (num) {
setHighlightedMonth(num);
}, highlightedItem: monthsData[highlightedMonth], yScrollOffset: monthsData.indexOf(monthsData[currentDate.getMonth()]) * 50, itemContainerStyle: itemContainerStyle, itemTextStyle: itemTextStyle }),
React.createElement(DateFlatList, { data: yearsData, onScrollToIndex: setHighlightedYear, highlightedItem: yearsData[higlightedYear], yScrollOffset: yearsData.indexOf(currentDate.getFullYear()) * 50, itemContainerStyle: itemContainerStyle, itemTextStyle: itemTextStyle }),
React.createElement(Highlighter, { highlighterStyle: highlighterStyle }))),
React.createElement(ConfirmButton, { buttonStyle: buttonStyle, buttonTextStyle: buttonTextStyle, buttonText: buttonText, onConfirm: function () {
onConfirm(getDateDateString({
year: yearsData[higlightedYear],
month: highlightedMonth,
day: showDays == false
? undefined
: daysData[highlightedMonthDay + 1],
}));
} })),
React.createElement(Pressable, { onPress: onBackgroundPress, style: [
styles.absolutePressItem,
{
backgroundColor: "rgba(0,0,0, ".concat(opacity > 100 ? 1 : opacity < 0 ? 0 : opacity, ")"),
},
] })));
};
export { MonthYearPicker as default };
//# sourceMappingURL=index.esm.js.map