Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
"@parcel/reporter-bundle-analyzer": "^2.16.3",
"@parcel/reporter-cli": "^2.16.3",
"@parcel/resolver-glob": "^2.16.3",
"@parcel/rust": "^2.16.3",
"@parcel/transformer-inline": "^2.16.3",
"@parcel/transformer-inline-string": "^2.16.3",
"@parcel/transformer-react-static": "^2.16.3",
Expand Down Expand Up @@ -172,6 +173,7 @@
"jest-environment-jsdom": "^29.5.0",
"jest-junit": "^15.0.0",
"jest-matchmedia-mock": "^1.1.0",
"json5": "^2.2.3",
"lerna": "^3.13.2",
"lucide-react": "^0.517.0",
"md5": "^2.2.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ export class EthiopicCalendar implements Calendar {
return 365 + getLeapDay(date.year);
}

getMaximumMonthsInYear(): number {
return 13;
}

getMaximumDaysInMonth(): number {
return 30;
}

getYearsInEra(date: AnyCalendarDate): number {
// 9999-12-31 gregorian is 9992-20-02 ethiopic.
// Round down to 9991 for the last full year.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,14 @@ export class GregorianCalendar implements Calendar {
return isLeapYear(date.year) ? 366 : 365;
}

getMaximumMonthsInYear(): number {
return 12;
}

getMaximumDaysInMonth(): number {
return 31;
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
getYearsInEra(date: AnyCalendarDate): number {
return 9999;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,14 @@ export class HebrewCalendar implements Calendar {
return getDaysInYear(date.year);
}

getMaximumMonthsInYear(): number {
return 13;
}

getMaximumDaysInMonth(): number {
return 30;
}

getYearsInEra(): number {
// 6239 gregorian
return 9999;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ export class IslamicCivilCalendar implements Calendar {
return isLeapYear(date.year) ? 355 : 354;
}

getMaximumMonthsInYear(): number {
return 12;
}

getMaximumDaysInMonth(): number {
return 30;
}

getYearsInEra(): number {
// 9999 gregorian
return 9665;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ export class PersianCalendar implements Calendar {
return isLeapYear ? 30 : 29;
}

getMaximumMonthsInYear(): number {
return 12;
}

getMaximumDaysInMonth(): number {
return 31;
}

getEras(): string[] {
return ['AP'];
}
Expand Down
4 changes: 4 additions & 0 deletions packages/@internationalized/date/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ export interface Calendar {
* eras may begin in the middle of a month.
*/
getMinimumDayInMonth?(date: AnyCalendarDate): number,
/** Returns the maximum months across all years. */
getMaximumMonthsInYear(): number,
/** Returns the maximum days across all months. */
getMaximumDaysInMonth(): number,
/**
* Returns a date that is the first day of the month for the given date.
* This is used to determine the month that the given date falls in, if
Expand Down
44 changes: 8 additions & 36 deletions packages/@react-aria/datepicker/src/useDateSegment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export function useDateSegment(segment: DateSegment, state: DateFieldState, ref:
// The ARIA spec says aria-valuenow is optional if there's no value, but aXe seems to require it.
// This doesn't seem to have any negative effects with real AT since we also use aria-valuetext.
// https://github.com/dequelabs/axe-core/issues/3505
value: segment.value,
value: segment.value ?? undefined,
textValue,
minValue: segment.minValue,
maxValue: segment.maxValue,
Expand All @@ -82,15 +82,11 @@ export function useDateSegment(segment: DateSegment, state: DateFieldState, ref:
},
onIncrementToMax: () => {
enteredKeys.current = '';
if (segment.maxValue !== undefined) {
state.setSegment(segment.type, segment.maxValue);
}
state.incrementToMax(segment.type);
},
onDecrementToMin: () => {
enteredKeys.current = '';
if (segment.minValue !== undefined) {
state.setSegment(segment.type, segment.minValue);
}
state.decrementToMin(segment.type);
}
});

Expand All @@ -110,7 +106,7 @@ export function useDateSegment(segment: DateSegment, state: DateFieldState, ref:
state.setSegment(segment.type, parsed);
}
enteredKeys.current = newValue;
} else if (segment.type === 'dayPeriod') {
} else if (segment.type === 'dayPeriod' || segment.type === 'era') {
state.clearSegment(segment.type);
}
};
Expand Down Expand Up @@ -193,7 +189,7 @@ export function useDateSegment(segment: DateSegment, state: DateFieldState, ref:
if (startsWith(am, key)) {
state.setSegment('dayPeriod', 0);
} else if (startsWith(pm, key)) {
state.setSegment('dayPeriod', 12);
state.setSegment('dayPeriod', 1);
} else {
break;
}
Expand All @@ -219,43 +215,19 @@ export function useDateSegment(segment: DateSegment, state: DateFieldState, ref:

let numberValue = parser.parse(newValue);
let segmentValue = numberValue;
let allowsZero = segment.minValue === 0;
if (segment.type === 'hour' && state.dateFormatter.resolvedOptions().hour12) {
switch (state.dateFormatter.resolvedOptions().hourCycle) {
case 'h11':
if (numberValue > 11) {
segmentValue = parser.parse(key);
}
break;
case 'h12':
allowsZero = false;
if (numberValue > 12) {
segmentValue = parser.parse(key);
}
break;
}

if (segment.value !== undefined && segment.value >= 12 && numberValue > 1) {
numberValue += 12;
}
} else if (segment.maxValue !== undefined && numberValue > segment.maxValue) {
if (segment.maxValue !== undefined && numberValue > segment.maxValue) {
segmentValue = parser.parse(key);
}

if (isNaN(numberValue)) {
return;
}

let shouldSetValue = segmentValue !== 0 || allowsZero;
if (shouldSetValue) {
state.setSegment(segment.type, segmentValue);
}
state.setSegment(segment.type, segmentValue);

if (segment.maxValue !== undefined && (Number(numberValue + '0') > segment.maxValue || newValue.length >= String(segment.maxValue).length)) {
enteredKeys.current = '';
if (shouldSetValue) {
focusManager.focusNext();
}
focusManager.focusNext();
} else {
enteredKeys.current = newValue;
}
Expand Down
Loading
Loading