@codecademy/gamut
72.5.172.5.2-alpha.733b32.0
dist/DatePicker/DatePickerInput/utils/validation.js+
dist/DatePicker/DatePickerInput/utils/validation.jsNew file+106
Index: package/dist/DatePicker/DatePickerInput/utils/validation.js
===================================================================
--- package/dist/DatePicker/DatePickerInput/utils/validation.js
+++ package/dist/DatePicker/DatePickerInput/utils/validation.js
@@ -0,0 +1,106 @@
+import { rangeContainsDisabled } from '../../DatePickerCalendar/utils/dateSelect';
+import { parseSegmentsToDate } from '../Segment/utils';
+const detectValidationIssue = segments => {
+ const {
+ month,
+ day,
+ year
+ } = segments;
+ const monthNumber = parseInt(month, 10);
+ const dayNumber = parseInt(day, 10);
+ const yearNumber = parseInt(year, 10);
+ if (monthNumber < 1 || monthNumber > 12) return 'invalid-month';
+ const parsed = new Date(yearNumber, monthNumber - 1, dayNumber);
+ if (parsed.getFullYear() !== yearNumber || parsed.getMonth() !== monthNumber - 1) {
+ return 'date-rollover';
+ }
+ if (parsed.getDate() !== dayNumber) {
+ return 'invalid-day';
+ }
+ return null;
+};
+export const generateErrorMessage = (reason, segments, translations) => {
+ const {
+ month,
+ day
+ } = segments;
+ const monthNumber = parseInt(month, 10);
+ switch (reason) {
+ case 'incomplete':
+ return translations.invalidDateIncomplete;
+ case 'invalid-month':
+ return translations.invalidDateInvalidMonth;
+ case 'invalid-day':
+ case 'date-rollover':
+ {
+ const monthName = new Date(2024, monthNumber - 1, 1).toLocaleString('en-US', {
+ month: 'long'
+ });
+ const message = reason === 'invalid-day' ? translations.invalidDateInvalidDay : translations.invalidDateRollover;
+ return message.replace('{{month}}', monthName).replace('{{day}}', day);
+ }
+ case 'disabled-date':
+ return translations.invalidDateNotAvailable;
+ case 'range-contains-disabled-date':
+ return translations.invalidDateRangeContainsDisabledDate;
+ case 'invalid-date':
+ default:
+ return translations.invalidDate;
+ }
+};
+export const validateSegments = (segments, translations, disableDate) => {
+ const {
+ month,
+ day,
+ year
+ } = segments;
+ const hasCompleteYear = year.length === 4;
+ const hasMonthAndDay = month.length > 0 && day.length > 0;
+ if (!hasCompleteYear || !hasMonthAndDay) {
+ return {
+ isValid: false,
+ errorMessage: '',
+ reason: 'incomplete'
+ };
+ }
+ const parsed = parseSegmentsToDate(segments);
+ if (parsed) {
+ if (disableDate?.(parsed)) {
+ return {
+ isValid: false,
+ errorMessage: generateErrorMessage('disabled-date', segments, translations),
+ reason: 'disabled-date'
+ };
+ }
+ return {
+ isValid: true,
+ date: parsed
+ };
+ }
+ const reason = detectValidationIssue(segments) ?? 'invalid-date';
+ const errorMessage = generateErrorMessage(reason, segments, translations);
+ return {
+ isValid: false,
+ errorMessage,
+ reason
+ };
+};
+export const validateDateRange = (startDate, endDate, translations, disableDate) => {
+ if (!startDate || !endDate || !disableDate) return null;
+ if (rangeContainsDisabled({
+ startDate,
+ endDate,
+ disableDate
+ })) {
+ return {
+ isValid: false,
+ errorMessage: generateErrorMessage('range-contains-disabled-date', {
+ month: '',
+ day: '',
+ year: ''
+ }, translations),
+ reason: 'range-contains-disabled-date'
+ };
+ }
+ return null;
+};
\ No newline at end of file