Skip to content

fix: react types backwards compat #8099

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

snowystinger
Copy link
Member

Closes #8092

chore: Explicit module boundary types introduced some breaking changes for people using old versions of typescript or @types/react
This PR reverts v3 and RAC to match what was implicitly defined in our build, but now it's explicit about it.
You can compare the old build either by building locally before that PR or comparing https://unpkg.com/[email protected]/dist/types.d.ts

You can use a diff tool for before and after.

✅ Pull Request Checklist:

  • Included link to corresponding React Spectrum GitHub Issue.
  • Added/updated unit tests and storybook for this change (for new code or code which already has tests).
  • Filled out test instructions.
  • Updated documentation (if it already exists for this component).
  • Looked at the Accessibility Practices for this feature - Aria Practices

📝 Test Instructions:

🧢 Your Project:

@rspbot
Copy link

rspbot commented Apr 16, 2025

Copy link

@zachbwh zachbwh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this!

btw, to address the specific issues I raised here, I would expect to see more changes in the @react-aria packages, for example in @react-aria/overlays/DismissButton

@snowystinger
Copy link
Member Author

Ah, thank you for catching the react-aria packages, I'll update it tomorrow to include those

@snowystinger
Copy link
Member Author

@zachbwh thanks again, I've updated the PR

@rspbot
Copy link

rspbot commented Apr 16, 2025

@@ -35,7 +35,7 @@ if (typeof HTMLTemplateElement !== 'undefined') {

export const HiddenContext = createContext<boolean>(false);

export function Hidden(props: {children: ReactNode}): ReactNode {
export function Hidden(props: {children: ReactNode}): JSX.Element {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why JSX.Element here but ReactElement in other places?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some of these, unpkg was down, so I relied on the ts inference
this one is internal, so doesn't matter too much

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, though it may have been inconsistent before as well. Just wondering which one we should use.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've double checked all the old ones and included direct links to the previously generated output

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

devongovett
devongovett previously approved these changes Apr 17, 2025
@@ -40,7 +40,7 @@ export interface FocusRingProps {
* Focus rings are visible only when the user is interacting with a keyboard,
* not with a mouse, touch, or other input methods.
*/
export function FocusRing(props: FocusRingProps): ReactNode {
export function FocusRing(props: FocusRingProps): JSX.Element {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just checked the unpkg for this one, apparently it was ReactElement, I'll update a few of the others
https://app.unpkg.com/@react-aria/[email protected]/files/dist/types.d.ts

@@ -26,7 +26,7 @@ const I18nContext = React.createContext<Locale | null>(null);
/**
* Provides the locale for the application to all child components.
*/
export function I18nProvider(props: I18nProviderProps): ReactNode {
export function I18nProvider(props: I18nProviderProps): JSX.Element {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -56,7 +56,7 @@ export const PressResponder = React.forwardRef(({children, ...props}: PressRespo
);
});

export function ClearPressResponder({children}: {children: ReactNode}): ReactNode {
export function ClearPressResponder({children}: {children: ReactNode}): JSX.Element {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -28,7 +28,7 @@ export interface DismissButtonProps extends AriaLabelingProps, DOMProps {
* users to dismiss a modal or popup when there is no visual
* affordance to do so.
*/
export function DismissButton(props: DismissButtonProps): ReactNode {
export function DismissButton(props: DismissButtonProps): JSX.Element {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -49,7 +49,7 @@ export const OverlayContext = React.createContext<{contain: boolean, setContain:
* A container which renders an overlay such as a popover or modal in a portal,
* and provides a focus scope for the child elements.
*/
export function Overlay(props: OverlayProps): ReactNode | null {
export function Overlay(props: OverlayProps): JSX.Element | null {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -26,7 +26,7 @@ export const PortalContext = createContext<PortalProviderContextValue>({});
/**
* Sets the portal container for all overlay elements rendered by its children.
*/
export function UNSAFE_PortalProvider(props: PortalProviderProps): ReactNode {
export function UNSAFE_PortalProvider(props: PortalProviderProps): JSX.Element {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -37,7 +37,7 @@ const Context = React.createContext<ModalContext | null>(null);
* subtree from screen readers. This is done using React context in order to account for things
* like portals, which can cause the React tree and the DOM tree to differ significantly in structure.
*/
export function ModalProvider(props: ModalProviderProps): ReactNode {
export function ModalProvider(props: ModalProviderProps): JSX.Element {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -101,7 +101,7 @@ function OverlayContainerDOM(props: ModalProviderProps) {
* if a modal or other overlay is opened. Only the top-most modal or
* overlay should be accessible at once.
*/
export function OverlayProvider(props: ModalProviderProps): ReactNode {
export function OverlayProvider(props: ModalProviderProps): JSX.Element {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -109,7 +109,7 @@ export function useHiddenSelect<T>(props: AriaHiddenSelectOptions, state: Select
* Renders a hidden native `<select>` element, which can be used to support browser
* form autofill, mobile form navigation, and native form submission.
*/
export function HiddenSelect<T>(props: HiddenSelectProps<T>): ReactNode | null {
export function HiddenSelect<T>(props: HiddenSelectProps<T>): JSX.Element | null {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -37,7 +37,7 @@ interface RouterProviderProps {
* A RouterProvider accepts a `navigate` function from a framework or client side router,
* and provides it to all nested React Aria links to enable client side navigation.
*/
export function RouterProvider(props: RouterProviderProps): ReactNode {
export function RouterProvider(props: RouterProviderProps): JSX.Element {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -24,7 +24,7 @@ interface VirtualizerItemProps extends Omit<VirtualizerItemOptions, 'ref'> {
children: ReactNode
}

export function VirtualizerItem(props: VirtualizerItemProps): ReactNode {
export function VirtualizerItem(props: VirtualizerItemProps): JSX.Element {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -86,7 +86,7 @@ export function useVisuallyHidden(props: VisuallyHiddenProps = {}): VisuallyHidd
* VisuallyHidden hides its children visually, while keeping content visible
* to screen readers.
*/
export function VisuallyHidden(props: VisuallyHiddenProps): ReactNode {
export function VisuallyHidden(props: VisuallyHiddenProps): JSX.Element {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -25,7 +25,7 @@ interface SpectrumBreadcrumbItemProps extends BreadcrumbItemProps {
isMenu?: boolean
}

export function BreadcrumbItem(props: SpectrumBreadcrumbItemProps): ReactNode {
export function BreadcrumbItem(props: SpectrumBreadcrumbItemProps): JSX.Element {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

internal type

@@ -38,7 +38,7 @@ interface CalendarBaseProps<T extends CalendarState | RangeCalendarState> extend
calendarRef: RefObject<HTMLDivElement | null>
}

export function CalendarBase<T extends CalendarState | RangeCalendarState>(props: CalendarBaseProps<T>): ReactNode {
export function CalendarBase<T extends CalendarState | RangeCalendarState>(props: CalendarBaseProps<T>): JSX.Element {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

internal type

@@ -27,7 +27,7 @@ interface CalendarCellProps extends AriaCalendarCellProps {
firstDayOfWeek?: 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat'
}

export function CalendarCell({state, currentMonth, firstDayOfWeek, ...props}: CalendarCellProps): ReactNode {
export function CalendarCell({state, currentMonth, firstDayOfWeek, ...props}: CalendarCellProps): JSX.Element {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

internal

@@ -25,7 +25,7 @@ interface CalendarMonthProps extends CalendarPropsBase, DOMProps, StyleProps {
startDate: CalendarDate
}

export function CalendarMonth(props: CalendarMonthProps): ReactNode {
export function CalendarMonth(props: CalendarMonthProps): JSX.Element {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

internal

@@ -26,7 +26,7 @@ interface DatePickerFieldProps<T extends DateValue> extends SpectrumDatePickerPr
maxGranularity?: SpectrumDatePickerProps<T>['granularity']
}

export function DatePickerField<T extends DateValue>(props: DatePickerFieldProps<T>): ReactNode {
export function DatePickerField<T extends DateValue>(props: DatePickerFieldProps<T>): JSX.Element {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

internal

@@ -21,7 +21,7 @@ import {useOverlayTriggerState} from '@react-stately/overlays';
* it in a modal. Useful in cases where there is no trigger element
* or when the trigger unmounts while the dialog is open.
*/
export function DialogContainer(props: SpectrumDialogContainerProps): ReactNode {
export function DialogContainer(props: SpectrumDialogContainerProps): JSX.Element {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -35,15 +35,15 @@ const OPEN_STATES = {
export function OpenTransition(
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
props
): ReactNode {
): JSX.Element | ReactElement<any, string | JSXElementConstructor<any>>[] {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was any https://app.unpkg.com/@react-spectrum/[email protected]/files/dist/types.d.ts#L19 but according to inference, this is more accurate

@@ -40,7 +40,7 @@ export interface FocusRingProps {
* Focus rings are visible only when the user is interacting with a keyboard,
* not with a mouse, touch, or other input methods.
*/
export function FocusRing(props: FocusRingProps): ReactNode {
export function FocusRing(props: FocusRingProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these are the defaults for the generic arguments right? So you don't need to include them?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'll double check, but for some reason our build previously expanded like this, so figured it was better to match that

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok but that's not necessarily the right thing

@rspbot
Copy link

rspbot commented Apr 18, 2025

@rspbot
Copy link

rspbot commented Apr 18, 2025

Copy link
Member

@devongovett devongovett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok whatever, but I don't think matching what we had previously is necessarily the goal here. 🤷

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Overlay components cannot be used as JSX components due to type errors
4 participants