diff --git a/packages/@react-aria/test-utils/package.json b/packages/@react-aria/test-utils/package.json index 2b79e0b7bfe..d79d87e6483 100644 --- a/packages/@react-aria/test-utils/package.json +++ b/packages/@react-aria/test-utils/package.json @@ -26,7 +26,6 @@ "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "@testing-library/dom": "^10.1.0", "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.0.0", "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", diff --git a/packages/@react-aria/test-utils/src/act.ts b/packages/@react-aria/test-utils/src/act.ts deleted file mode 100644 index e4f35719b89..00000000000 --- a/packages/@react-aria/test-utils/src/act.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2025 Adobe. All rights reserved. - * This file is licensed to you under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. You may obtain a copy - * of the License at http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - * OF ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - */ - -import * as React from 'react'; -import * as ReactDOMTestUtils from 'react-dom/test-utils'; - -let actImpl: typeof ReactDOMTestUtils.act; -if (typeof React.act === 'function') { - actImpl = React.act; -} else { - actImpl = ReactDOMTestUtils.act; -} - -export const act = actImpl; diff --git a/packages/@react-aria/test-utils/src/checkboxgroup.ts b/packages/@react-aria/test-utils/src/checkboxgroup.ts index 6843d4ff9a0..54e436a5cab 100644 --- a/packages/@react-aria/test-utils/src/checkboxgroup.ts +++ b/packages/@react-aria/test-utils/src/checkboxgroup.ts @@ -10,10 +10,9 @@ * governing permissions and limitations under the License. */ -import {act} from './act'; +import {act, within} from '@testing-library/react'; import {CheckboxGroupTesterOpts, UserOpts} from './types'; import {pressElement} from './events'; -import {within} from '@testing-library/dom'; interface TriggerCheckboxOptions { /** diff --git a/packages/@react-aria/test-utils/src/combobox.ts b/packages/@react-aria/test-utils/src/combobox.ts index 5d458fcd933..d95ac6f5711 100644 --- a/packages/@react-aria/test-utils/src/combobox.ts +++ b/packages/@react-aria/test-utils/src/combobox.ts @@ -10,9 +10,8 @@ * governing permissions and limitations under the License. */ -import {act} from './act'; +import {act, waitFor, within} from '@testing-library/react'; import {ComboBoxTesterOpts, UserOpts} from './types'; -import {waitFor, within} from '@testing-library/dom'; interface ComboBoxOpenOpts { /** diff --git a/packages/@react-aria/test-utils/src/dialog.ts b/packages/@react-aria/test-utils/src/dialog.ts index 0c0dd85605c..213c86c2b1a 100644 --- a/packages/@react-aria/test-utils/src/dialog.ts +++ b/packages/@react-aria/test-utils/src/dialog.ts @@ -10,9 +10,8 @@ * governing permissions and limitations under the License. */ -import {act} from './act'; +import {act, waitFor, within} from '@testing-library/react'; import {DialogTesterOpts, UserOpts} from './types'; -import {waitFor, within} from '@testing-library/dom'; interface DialogOpenOpts { /** diff --git a/packages/@react-aria/test-utils/src/events.ts b/packages/@react-aria/test-utils/src/events.ts index 28364b4d464..e603111d3ea 100644 --- a/packages/@react-aria/test-utils/src/events.ts +++ b/packages/@react-aria/test-utils/src/events.ts @@ -10,8 +10,7 @@ * governing permissions and limitations under the License. */ -import {act} from './act'; -import {fireEvent} from '@testing-library/dom'; +import {act, fireEvent} from '@testing-library/react'; import {UserOpts} from './types'; export const DEFAULT_LONG_PRESS_TIME = 500; diff --git a/packages/@react-aria/test-utils/src/gridlist.ts b/packages/@react-aria/test-utils/src/gridlist.ts index 55012e3f1a1..d5d1c21e082 100644 --- a/packages/@react-aria/test-utils/src/gridlist.ts +++ b/packages/@react-aria/test-utils/src/gridlist.ts @@ -10,10 +10,9 @@ * governing permissions and limitations under the License. */ -import {act} from './act'; +import {act, within} from '@testing-library/react'; import {getAltKey, getMetaKey, pressElement, triggerLongPress} from './events'; import {GridListTesterOpts, GridRowActionOpts, ToggleGridRowOpts, UserOpts} from './types'; -import {within} from '@testing-library/dom'; interface GridListToggleRowOpts extends ToggleGridRowOpts {} interface GridListRowActionOpts extends GridRowActionOpts {} diff --git a/packages/@react-aria/test-utils/src/listbox.ts b/packages/@react-aria/test-utils/src/listbox.ts index fa3649c27e8..cac8d9d78bc 100644 --- a/packages/@react-aria/test-utils/src/listbox.ts +++ b/packages/@react-aria/test-utils/src/listbox.ts @@ -10,10 +10,9 @@ * governing permissions and limitations under the License. */ -import {act} from './act'; +import {act, within} from '@testing-library/react'; import {getAltKey, getMetaKey, pressElement, triggerLongPress} from './events'; import {ListBoxTesterOpts, UserOpts} from './types'; -import {within} from '@testing-library/dom'; interface ListBoxToggleOptionOpts { /** diff --git a/packages/@react-aria/test-utils/src/menu.ts b/packages/@react-aria/test-utils/src/menu.ts index 1badcd3f539..87af5c11fd0 100644 --- a/packages/@react-aria/test-utils/src/menu.ts +++ b/packages/@react-aria/test-utils/src/menu.ts @@ -10,10 +10,9 @@ * governing permissions and limitations under the License. */ -import {act} from './act'; +import {act, waitFor, within} from '@testing-library/react'; import {MenuTesterOpts, UserOpts} from './types'; import {triggerLongPress} from './events'; -import {waitFor, within} from '@testing-library/dom'; interface MenuOpenOpts { /** diff --git a/packages/@react-aria/test-utils/src/radiogroup.ts b/packages/@react-aria/test-utils/src/radiogroup.ts index fc94e187c8f..6c1d0e38c9e 100644 --- a/packages/@react-aria/test-utils/src/radiogroup.ts +++ b/packages/@react-aria/test-utils/src/radiogroup.ts @@ -10,10 +10,9 @@ * governing permissions and limitations under the License. */ -import {act} from './act'; +import {act, within} from '@testing-library/react'; import {Direction, Orientation, RadioGroupTesterOpts, UserOpts} from './types'; import {pressElement} from './events'; -import {within} from '@testing-library/dom'; interface TriggerRadioOptions { /** diff --git a/packages/@react-aria/test-utils/src/select.ts b/packages/@react-aria/test-utils/src/select.ts index 66da8c85262..8399363b2bb 100644 --- a/packages/@react-aria/test-utils/src/select.ts +++ b/packages/@react-aria/test-utils/src/select.ts @@ -10,9 +10,8 @@ * governing permissions and limitations under the License. */ -import {act} from './act'; +import {act, waitFor, within} from '@testing-library/react'; import {SelectTesterOpts, UserOpts} from './types'; -import {waitFor, within} from '@testing-library/dom'; interface SelectOpenOpts { /** diff --git a/packages/@react-aria/test-utils/src/table.ts b/packages/@react-aria/test-utils/src/table.ts index 661fdd4a5dc..2401beeed1b 100644 --- a/packages/@react-aria/test-utils/src/table.ts +++ b/packages/@react-aria/test-utils/src/table.ts @@ -10,10 +10,9 @@ * governing permissions and limitations under the License. */ -import {act} from './act'; +import {act, waitFor, within} from '@testing-library/react'; import {BaseGridRowInteractionOpts, GridRowActionOpts, TableTesterOpts, ToggleGridRowOpts, UserOpts} from './types'; import {getAltKey, getMetaKey, pressElement, triggerLongPress} from './events'; -import {waitFor, within} from '@testing-library/dom'; interface TableToggleRowOpts extends ToggleGridRowOpts {} interface TableToggleExpansionOpts extends BaseGridRowInteractionOpts {} diff --git a/packages/@react-aria/test-utils/src/tabs.ts b/packages/@react-aria/test-utils/src/tabs.ts index 9647b8c8937..c26da3e7656 100644 --- a/packages/@react-aria/test-utils/src/tabs.ts +++ b/packages/@react-aria/test-utils/src/tabs.ts @@ -10,10 +10,9 @@ * governing permissions and limitations under the License. */ -import {act} from './act'; +import {act, within} from '@testing-library/react'; import {Direction, Orientation, TabsTesterOpts, UserOpts} from './types'; import {pressElement} from './events'; -import {within} from '@testing-library/dom'; interface TriggerTabOptions { /** diff --git a/packages/@react-aria/test-utils/src/tree.ts b/packages/@react-aria/test-utils/src/tree.ts index 6270ca5d572..cadcf52b72a 100644 --- a/packages/@react-aria/test-utils/src/tree.ts +++ b/packages/@react-aria/test-utils/src/tree.ts @@ -10,10 +10,9 @@ * governing permissions and limitations under the License. */ -import {act} from './act'; +import {act, within} from '@testing-library/react'; import {BaseGridRowInteractionOpts, GridRowActionOpts, ToggleGridRowOpts, TreeTesterOpts, UserOpts} from './types'; import {getAltKey, getMetaKey, pressElement, triggerLongPress} from './events'; -import {within} from '@testing-library/dom'; interface TreeToggleExpansionOpts extends BaseGridRowInteractionOpts {} interface TreeToggleRowOpts extends ToggleGridRowOpts {} diff --git a/packages/@react-spectrum/s2/src/DatePicker.tsx b/packages/@react-spectrum/s2/src/DatePicker.tsx index 53fc414a646..fdb752460e2 100644 --- a/packages/@react-spectrum/s2/src/DatePicker.tsx +++ b/packages/@react-spectrum/s2/src/DatePicker.tsx @@ -52,11 +52,7 @@ export interface DatePickerProps extends * The maximum number of months to display at once in the calendar popover, if screen space permits. * @default 1 */ - maxVisibleMonths?: number, - /** - * The error message to display when the calendar is invalid. - */ - errorMessage?: ReactNode + maxVisibleMonths?: number } export const DatePickerContext = createContext>, HTMLDivElement>>(null); @@ -167,6 +163,10 @@ export const DatePicker = /*#__PURE__*/ (forwardRef as forwardRefType)(function let timeMaxValue = props.maxValue && 'hour' in props.maxValue ? props.maxValue : undefined; let timeGranularity = state.granularity === 'hour' || state.granularity === 'minute' || state.granularity === 'second' ? state.granularity : undefined; let showTimeField = !!timeGranularity; + + // Ideally, we could omit errorMessage here and let S2 Calendar read it from RAC's CalendarContext which already contains the resolved value via calendarProps from useDatePicker. + // However, RAC's CalendarProps omits errorMessage, so reading it back from the context would require an unsafe cast. Instead, we resolve it here using the same logic as useDatePicker. + let resolvedErrorMessage = typeof errorMessage === 'function' ? errorMessage(state.displayValidation) : (errorMessage || state.displayValidation.validationErrors.join(' ')); return ( <> + errorMessage={resolvedErrorMessage} /> {showTimeField && (
- {errorMessage} + {resolvedErrorMessage} ); diff --git a/packages/@react-spectrum/s2/src/DateRangePicker.tsx b/packages/@react-spectrum/s2/src/DateRangePicker.tsx index 8124f178eb4..a35a16354e5 100644 --- a/packages/@react-spectrum/s2/src/DateRangePicker.tsx +++ b/packages/@react-spectrum/s2/src/DateRangePicker.tsx @@ -17,7 +17,7 @@ import { } from 'react-aria-components/DateRangePicker'; import {CalendarButton, CalendarPopover, timeField} from './DatePicker'; import {ContextValue} from 'react-aria-components/slots'; -import {createContext, forwardRef, ReactElement, ReactNode, Ref, useContext, useState} from 'react'; +import {createContext, forwardRef, ReactElement, Ref, useContext, useState} from 'react'; import {DateInput, DateInputContainer, InvalidIndicator} from './DateField'; import {field, fieldInput, getAllowedOverrides, StyleProps} from './style-utils' with {type: 'macro'}; import {FieldGroup, FieldLabel, HelpText} from './Field'; @@ -50,11 +50,7 @@ export interface DateRangePickerProps extends * The maximum number of months to display at once in the calendar popover, if screen space permits. * @default 1 */ - maxVisibleMonths?: number, - /** - * The error message to display when the calendar is invalid. - */ - errorMessage?: ReactNode + maxVisibleMonths?: number } export const DateRangePickerContext = createContext>, HTMLDivElement>>(null); @@ -111,6 +107,10 @@ export const DateRangePicker = /*#__PURE__*/ (forwardRef as forwardRefType)(func || state.granularity === 'second' ? state.granularity : undefined; let showTimeField = !!timeGranularity; + + // Ideally, we could omit errorMessage here and let S2 Calendar read it from RAC's CalendarContext which already contains the resolved value via calendarProps from useDatePicker. + // However, RAC's CalendarProps omits errorMessage, so reading it back from the context would require an unsafe cast. Instead, we resolve it here using the same logic as useDatePicker. + let resolvedErrorMessage = typeof errorMessage === 'function' ? errorMessage(state.displayValidation) : (errorMessage || state.displayValidation.validationErrors.join(' ')); return ( <> + errorMessage={resolvedErrorMessage} /> {showTimeField && (
- {errorMessage} + {resolvedErrorMessage} ); diff --git a/packages/@react-spectrum/test-utils/package.json b/packages/@react-spectrum/test-utils/package.json index e86b0c3775e..7f56ee3bbb7 100644 --- a/packages/@react-spectrum/test-utils/package.json +++ b/packages/@react-spectrum/test-utils/package.json @@ -29,7 +29,6 @@ "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "@testing-library/dom": "^10.1.0", "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.0.0", "jest": "^29.5.0", diff --git a/yarn.lock b/yarn.lock index 42216ae15c6..c7f92c4e854 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6428,7 +6428,6 @@ __metadata: dependencies: "@swc/helpers": "npm:^0.5.0" peerDependencies: - "@testing-library/dom": ^10.1.0 "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 @@ -7393,7 +7392,6 @@ __metadata: "@react-aria/test-utils": "npm:1.0.0-beta.2" "@swc/helpers": "npm:^0.5.0" peerDependencies: - "@testing-library/dom": ^10.1.0 "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 jest: ^29.5.0