From 6206fc3b21c2982e4a03c7b9aaa644e07d6c2f9f Mon Sep 17 00:00:00 2001 From: Daniel Lu Date: Wed, 27 May 2026 09:49:08 -0700 Subject: [PATCH 1/3] chore: Only export DragPreview from useDragAndDrop subpath (#10114) * remove in repo specific guidance from test util skills * only export DragPreview from useDragAndDrop subpath --- packages/@react-spectrum/s2/exports/ListView.ts | 2 -- packages/@react-spectrum/s2/exports/TableView.ts | 2 -- packages/@react-spectrum/s2/exports/TreeView.ts | 2 -- packages/@react-spectrum/s2/exports/useDragAndDrop.ts | 2 ++ packages/dev/s2-docs/pages/react-aria/dnd.mdx | 2 +- packages/dev/s2-docs/pages/s2/ListView.mdx | 4 ++-- packages/dev/s2-docs/pages/s2/TableView.mdx | 4 ++-- packages/dev/s2-docs/pages/s2/TreeView.mdx | 4 ++-- packages/dev/s2-docs/pages/s2/dnd.mdx | 6 ++---- .../dev/s2-docs/skills/react-aria/test-utils-guidance.md | 7 ++----- .../skills/react-spectrum-s2/test-utils-guidance.md | 5 +---- 11 files changed, 14 insertions(+), 26 deletions(-) diff --git a/packages/@react-spectrum/s2/exports/ListView.ts b/packages/@react-spectrum/s2/exports/ListView.ts index e1642fd93a9..43194cd57ba 100644 --- a/packages/@react-spectrum/s2/exports/ListView.ts +++ b/packages/@react-spectrum/s2/exports/ListView.ts @@ -1,8 +1,6 @@ export {ListView, ListViewContext, ListViewItem} from '../src/ListView'; -export {DragPreview} from '../src/DragPreview'; export {Collection} from 'react-aria/Collection'; export type {ListViewProps, ListViewItemProps} from '../src/ListView'; -export type {DragPreviewProps} from '../src/DragPreview'; export type {Selection, Key, SelectionMode} from '@react-types/shared'; export {Text} from '../src/Content'; diff --git a/packages/@react-spectrum/s2/exports/TableView.ts b/packages/@react-spectrum/s2/exports/TableView.ts index 5f109b88edb..7cf4ff66e35 100644 --- a/packages/@react-spectrum/s2/exports/TableView.ts +++ b/packages/@react-spectrum/s2/exports/TableView.ts @@ -9,7 +9,6 @@ export { EditableCell, TableFooter } from '../src/TableView'; -export {DragPreview} from '../src/DragPreview'; export {Collection} from 'react-aria/Collection'; export type { TableViewProps, @@ -20,7 +19,6 @@ export type { ColumnProps, TableFooterProps } from '../src/TableView'; -export type {DragPreviewProps} from '../src/DragPreview'; export type { Selection, Key, diff --git a/packages/@react-spectrum/s2/exports/TreeView.ts b/packages/@react-spectrum/s2/exports/TreeView.ts index 34e3e689064..3b63cf31323 100644 --- a/packages/@react-spectrum/s2/exports/TreeView.ts +++ b/packages/@react-spectrum/s2/exports/TreeView.ts @@ -1,5 +1,4 @@ export {TreeView, TreeViewItem, TreeViewItemContent, TreeViewLoadMoreItem} from '../src/TreeView'; -export {DragPreview} from '../src/DragPreview'; export {Collection} from 'react-aria/Collection'; export type { TreeViewProps, @@ -7,7 +6,6 @@ export type { TreeViewItemContentProps, TreeViewLoadMoreItemProps } from '../src/TreeView'; -export type {DragPreviewProps} from '../src/DragPreview'; export type {Selection, Key, SelectionMode} from '@react-types/shared'; export {Text} from '../src/Content'; diff --git a/packages/@react-spectrum/s2/exports/useDragAndDrop.ts b/packages/@react-spectrum/s2/exports/useDragAndDrop.ts index dbf89aacacd..c0243ff4d5d 100644 --- a/packages/@react-spectrum/s2/exports/useDragAndDrop.ts +++ b/packages/@react-spectrum/s2/exports/useDragAndDrop.ts @@ -5,6 +5,7 @@ export { isFileDropItem, isTextDropItem } from 'react-aria/useDrop'; +export {DragPreview} from '../src/DragPreview'; export type {DragAndDropHooks} from 'react-aria-components/useDragAndDrop'; export type { DirectoryDropItem, @@ -32,3 +33,4 @@ export type { } from '@react-types/shared'; export type {DragAndDropOptions} from '../src/useDragAndDrop'; export type {DragAndDrop} from 'react-aria-components/useDragAndDrop'; +export type {DragPreviewProps} from '../src/DragPreview'; diff --git a/packages/dev/s2-docs/pages/react-aria/dnd.mdx b/packages/dev/s2-docs/pages/react-aria/dnd.mdx index 938d212845e..96cc497e5f4 100644 --- a/packages/dev/s2-docs/pages/react-aria/dnd.mdx +++ b/packages/dev/s2-docs/pages/react-aria/dnd.mdx @@ -314,7 +314,7 @@ function DroppableTree() { Collection components such as [ListBox](ListBox), [Table](Table), [Tree](Tree), and [GridList](GridList) support multiple **drop positions**. -* The `"root"` drop position allows dropping on the collection as a whole. +* The `"root"` drop position allows dropping on the collection as a whole. * The `"on"` drop position allows dropping on individual collection items, such as a folder within a list. * The `"before"` and `"after"` drop positions allow the user to insert or move items between other items. This is displayed by rendering a **drop indicator** between items. diff --git a/packages/dev/s2-docs/pages/s2/ListView.mdx b/packages/dev/s2-docs/pages/s2/ListView.mdx index 54346bdc270..e28f1c36f2f 100644 --- a/packages/dev/s2-docs/pages/s2/ListView.mdx +++ b/packages/dev/s2-docs/pages/s2/ListView.mdx @@ -388,10 +388,10 @@ You can customize the drag preview by passing { diff --git a/packages/dev/s2-docs/skills/react-spectrum-s2/test-utils-guidance.md b/packages/dev/s2-docs/skills/react-spectrum-s2/test-utils-guidance.md index 74dad90b995..48a9066bcc2 100644 --- a/packages/dev/s2-docs/skills/react-spectrum-s2/test-utils-guidance.md +++ b/packages/dev/s2-docs/skills/react-spectrum-s2/test-utils-guidance.md @@ -10,10 +10,7 @@ npm install @react-spectrum/test-utils --save-dev ### Core pattern -External consumers import from `@react-spectrum/test-utils`. Tests inside the `packages/` monorepo should import everything from `@react-spectrum/test-utils-internal`, which re-exports `User` and all other test utilities: - ```ts -import {act, render, User} from '@react-spectrum/test-utils-internal'; -``` +External consumers import from `@react-spectrum/test-utils`. Initialize a `User` once per test file. Call `createTester` to get a tester for a specific ARIA pattern, then call tester methods to simulate interactions. From ed9170f4ba232cef9ae22eb5ede01f2affa071c9 Mon Sep 17 00:00:00 2001 From: Daniel Lu Date: Wed, 27 May 2026 10:49:06 -0700 Subject: [PATCH 2/3] fix: ensure Tableview and ListView render their dividers and borders with the proper colors in HCM (#10108) * fix: ensure Tableview and ListView render their dividers and borders with the proper colors in HCM * keep listview row borders in HCM for checkbox selection * fix text color when row is selected in highlight selection --- packages/@react-spectrum/s2/src/ListView.tsx | 19 ++++++++++-- packages/@react-spectrum/s2/src/TableView.tsx | 31 ++++++++++++++----- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/packages/@react-spectrum/s2/src/ListView.tsx b/packages/@react-spectrum/s2/src/ListView.tsx index 64a1fb8847a..27264264d8e 100644 --- a/packages/@react-spectrum/s2/src/ListView.tsx +++ b/packages/@react-spectrum/s2/src/ListView.tsx @@ -223,7 +223,10 @@ const listView = style extends Omit< @@ -1870,6 +1877,9 @@ const rowBackgroundColor = { default: 'gray-25', isQuiet: '--s2-container-bg' }, + forcedColors: { + default: 'Background' + }, isHovered: colorMix('gray-25', 'gray-900', 7), // table-row-hover-color isPressed: colorMix('gray-25', 'gray-900', 10), // table-row-hover-color isSelected: { @@ -1893,9 +1903,6 @@ const rowBackgroundColor = { } }, isInFooter: 'gray-200', - forcedColors: { - default: 'Background' - }, ':is([role="grid"][data-drop-target] *)': rootRowDropStyles, isDropTarget: rowDropStyles } as const; @@ -1903,7 +1910,14 @@ const rowBackgroundColor = { const rowTextColor = { default: baseColor('neutral-subdued'), isSelected: baseColor('neutral'), - forcedColors: 'ButtonText', + forcedColors: { + default: 'ButtonText', + isSelected: { + selectionStyle: { + highlight: 'HighlightText' + } + } + }, isDisabled: { default: 'disabled', forcedColors: 'GrayText' @@ -2030,7 +2044,10 @@ const row = style< borderColor: { selectionStyle: { highlight: 'transparent', - checkbox: 'gray-300' + checkbox: { + default: 'gray-300', + forcedColors: 'ButtonBorder' + } } }, '--borderColorGray': { From 2c18eb685a1b6a7ebe164b2a82439e70fd603d54 Mon Sep 17 00:00:00 2001 From: Robert Snow Date: Thu, 28 May 2026 04:06:58 +1000 Subject: [PATCH 3/3] fix: Custom 454 Calendar month (#10115) --- .../test/Calendar.test.js | 59 +++++++++++++++++++ .../src/calendar/useCalendarHeading.ts | 7 ++- .../src/calendar/useCalendarMonthPicker.ts | 7 ++- 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/packages/react-aria-components/test/Calendar.test.js b/packages/react-aria-components/test/Calendar.test.js index 4fc9d59418b..0cc6ba53786 100644 --- a/packages/react-aria-components/test/Calendar.test.js +++ b/packages/react-aria-components/test/Calendar.test.js @@ -34,7 +34,11 @@ import { startOfWeek, today } from '@internationalized/date'; +import {Custom454Calendar} from '@internationalized/date/tests/customCalendarImpl'; +import {ListBox, ListBoxItem} from '../src/ListBox'; +import {Popover} from '../src/Popover'; import React, {useContext, useState} from 'react'; +import {Select, SelectValue} from '../src/Select'; import userEvent from '@testing-library/user-event'; let TestCalendar = ({calendarProps, gridProps, cellProps}) => ( @@ -717,4 +721,59 @@ describe('Calendar', () => { ); expect(heading).toHaveTextContent('April 2026'); }); + + it('should use getFormattableMonth for CalendarHeading with a custom calendar', () => { + let tree = render( + new Custom454Calendar() + }} + /> + ); + let heading = tree.container.querySelector('.react-aria-CalendarHeading'); + expect(heading).toHaveTextContent('February 2022'); + }); + + it('should use getFormattableMonth for CalendarMonthPicker with a custom calendar', async () => { + // Jan 30, 2022 (Gregorian) is the first day of fiscal year 2022 in Custom454, + // so the focused date is month 1, day 1 + let tree = render( + new Custom454Calendar()}> +
+ + + {({items, value, onChange, 'aria-label': ariaLabel}) => ( + + )} + + +
+ {date => } +
+ ); + + let monthPicker = tree.getByLabelText('month'); + expect(monthPicker).toHaveTextContent('Feb'); + await user.click(monthPicker); + // The Custom454Calendar's fiscal year starts in February, so month 1 should + // display as "Feb" (Gregorian February), not "Jan". + expect( + within(tree.getByRole('listbox')) + .getAllByRole('option') + .map(o => o.textContent) + ).toEqual(['Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'Jan']); + }); }); diff --git a/packages/react-aria/src/calendar/useCalendarHeading.ts b/packages/react-aria/src/calendar/useCalendarHeading.ts index 48ae48a68fc..275497b906d 100644 --- a/packages/react-aria/src/calendar/useCalendarHeading.ts +++ b/packages/react-aria/src/calendar/useCalendarHeading.ts @@ -70,6 +70,11 @@ export function useCalendarHeading( ); } - return formatter.format(startDate.toDate(state.timeZone)); + // Custom calendars like the 4-5-4 fiscal calendar use getFormattableMonth to map + // their internal month back to the Gregorian month that should be displayed. + let displayDate = startDate.calendar.getFormattableMonth + ? startDate.calendar.getFormattableMonth(startDate) + : startDate; + return formatter.format(displayDate.toDate(state.timeZone)); }, [formatter, isDays, startDate, state.timeZone, state.visibleRange.end]); } diff --git a/packages/react-aria/src/calendar/useCalendarMonthPicker.ts b/packages/react-aria/src/calendar/useCalendarMonthPicker.ts index 6919432e0eb..fb99dd8ff7a 100644 --- a/packages/react-aria/src/calendar/useCalendarMonthPicker.ts +++ b/packages/react-aria/src/calendar/useCalendarMonthPicker.ts @@ -56,10 +56,15 @@ export function useCalendarMonthPicker( let numMonths = state.focusedDate.calendar.getMonthsInYear(state.focusedDate); for (let i = 1; i <= numMonths; i++) { let date = state.focusedDate.set({month: i}); + // Calendars like the 4-5-4 fiscal calendar use getFormattableMonth to map + // their internal month back to the Gregorian month that should be displayed. + let displayDate = date.calendar.getFormattableMonth + ? date.calendar.getFormattableMonth(date) + : date; months.push({ id: i, date, - formatted: formatter.format(date.toDate(state.timeZone)) + formatted: formatter.format(displayDate.toDate(state.timeZone)) }); }