Skip to content

Commit

Permalink
React 19 compatibility (#2934)
Browse files Browse the repository at this point in the history
* Access ref from props before element.ref

* Apply ref access fix to presence component

* adding react 19 to peer deps

* Upgrade to React 18.3.1

* Add missing React 19 peer deps

* Remove propTypes

* Update ReactDOM usage

* yarn

* Upgrade to React 19 and access refs in a backwards compatible way

* Recover Storybook

* Remove an outdated type

* Suppress a type error, tweak formatting

* Track version changes

* Don't throw in render, just log the error

* Update and upgrade tests

* Roll back tests deps changes

* ^ in react version affects tests?

* Upgrade testing-library and wrap FocusScope tests in act

* Upgrade @testing-library/react to 16.0

* Of cooooourse

* Remove unnecessary changes

* Refine getElementRef

* Upgrade start-server-and-test

* Flaky cypress test?

* Remove unnecessary changes

---------

Co-authored-by: Chung Wei <[email protected]>
Co-authored-by: Ben Hammond <[email protected]>
  • Loading branch information
3 people committed Jun 10, 2024
1 parent af1e3b4 commit 06de2d4
Show file tree
Hide file tree
Showing 105 changed files with 4,044 additions and 4,264 deletions.
59 changes: 59 additions & 0 deletions .yarn/versions/58957da5.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
releases:
"@radix-ui/react-accessible-icon": patch
"@radix-ui/react-accordion": patch
"@radix-ui/react-alert-dialog": patch
"@radix-ui/react-announce": patch
"@radix-ui/react-arrow": patch
"@radix-ui/react-aspect-ratio": patch
"@radix-ui/react-avatar": patch
"@radix-ui/react-checkbox": patch
"@radix-ui/react-collapsible": patch
"@radix-ui/react-collection": patch
"@radix-ui/react-compose-refs": patch
"@radix-ui/react-context": patch
"@radix-ui/react-context-menu": patch
"@radix-ui/react-dialog": patch
"@radix-ui/react-direction": patch
"@radix-ui/react-dismissable-layer": patch
"@radix-ui/react-dropdown-menu": patch
"@radix-ui/react-focus-guards": patch
"@radix-ui/react-focus-scope": patch
"@radix-ui/react-form": patch
"@radix-ui/react-hover-card": patch
"@radix-ui/react-id": patch
"@radix-ui/react-label": patch
"@radix-ui/react-menu": patch
"@radix-ui/react-menubar": patch
"@radix-ui/react-navigation-menu": patch
"@radix-ui/react-popover": patch
"@radix-ui/react-popper": patch
"@radix-ui/react-portal": patch
"@radix-ui/react-presence": minor
"@radix-ui/react-primitive": major
"@radix-ui/react-progress": patch
"@radix-ui/react-radio-group": patch
"@radix-ui/react-roving-focus": patch
"@radix-ui/react-scroll-area": patch
"@radix-ui/react-select": patch
"@radix-ui/react-separator": patch
"@radix-ui/react-slider": patch
"@radix-ui/react-slot": minor
"@radix-ui/react-switch": patch
"@radix-ui/react-tabs": patch
"@radix-ui/react-toast": patch
"@radix-ui/react-toggle": patch
"@radix-ui/react-toggle-group": patch
"@radix-ui/react-toolbar": patch
"@radix-ui/react-tooltip": patch
"@radix-ui/react-use-callback-ref": patch
"@radix-ui/react-use-controllable-state": patch
"@radix-ui/react-use-escape-keydown": patch
"@radix-ui/react-use-layout-effect": patch
"@radix-ui/react-use-previous": patch
"@radix-ui/react-use-rect": patch
"@radix-ui/react-use-size": patch
"@radix-ui/react-visually-hidden": patch

declined:
- primitives
- ssr-testing
1 change: 1 addition & 0 deletions cypress/integration/Form.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ describe('Form', () => {
});

function checkControlMessageAssociation() {
cy.get('@control').should('have.attr', 'aria-describedby');
cy.get('@control')
.invoke('attr', 'aria-describedby')
.then((ariaDescribedby) =>
Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
"bump:check": "yarn version check"
},
"dependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"devDependencies": {
"@stitches/core": "^1.2.8",
Expand All @@ -39,8 +39,9 @@
"@storybook/react-webpack5": "^7.6.17",
"@storybook/test": "^7.6.17",
"@testing-library/cypress": "^7.0.6",
"@testing-library/dom": "^10.1.0",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.0.1",
"@testing-library/react": "^16.0.0",
"@testing-library/user-event": "^14.1.0",
"@types/eslint": "^7.28.0",
"@types/fs-extra": "^11",
Expand Down Expand Up @@ -74,7 +75,7 @@
"pretty-quick": "^2.0.1",
"react-test-renderer": "^18.0.0",
"replace-in-files": "^3.0.0",
"start-server-and-test": "^1.12.5",
"start-server-and-test": "2.0.3",
"storybook": "^7.6.17",
"ts-jest": "^27.1.4",
"tsup": "8.0.2",
Expand Down
4 changes: 2 additions & 2 deletions packages/react/accessible-icon/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0"
},
"peerDependenciesMeta": {
"@types/react": {
Expand Down
4 changes: 2 additions & 2 deletions packages/react/accordion/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0"
},
"peerDependenciesMeta": {
"@types/react": {
Expand Down
33 changes: 5 additions & 28 deletions packages/react/accordion/src/Accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
import { createCollapsibleScope } from '@radix-ui/react-collapsible';
import { useId } from '@radix-ui/react-id';

import type * as Radix from '@radix-ui/react-primitive';
import type { Scope } from '@radix-ui/react-context';
import { useDirection } from '@radix-ui/react-direction';

Expand Down Expand Up @@ -59,28 +58,6 @@ const Accordion = React.forwardRef<AccordionElement, AccordionSingleProps | Acco

Accordion.displayName = ACCORDION_NAME;

Accordion.propTypes = {
type(props) {
const value = props.value || props.defaultValue;
if (props.type && !['single', 'multiple'].includes(props.type)) {
return new Error(
'Invalid prop `type` supplied to `Accordion`. Expected one of `single | multiple`.'
);
}
if (props.type === 'multiple' && typeof value === 'string') {
return new Error(
'Invalid prop `type` supplied to `Accordion`. Expected `single` when `defaultValue` or `value` is type `string`.'
);
}
if (props.type === 'single' && Array.isArray(value)) {
return new Error(
'Invalid prop `type` supplied to `Accordion`. Expected `multiple` when `defaultValue` or `value` is type `string[]`.'
);
}
return null;
},
};

/* -----------------------------------------------------------------------------------------------*/

type AccordionValueContextValue = {
Expand Down Expand Up @@ -223,7 +200,7 @@ const [AccordionImplProvider, useAccordionContext] =
createAccordionContext<AccordionImplContextValue>(ACCORDION_NAME);

type AccordionImplElement = React.ElementRef<typeof Primitive.div>;
type PrimitiveDivProps = Radix.ComponentPropsWithoutRef<typeof Primitive.div>;
type PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;
interface AccordionImplProps extends PrimitiveDivProps {
/**
* Whether or not an accordion is disabled from user interaction.
Expand Down Expand Up @@ -353,7 +330,7 @@ const [AccordionItemProvider, useAccordionItemContext] =
createAccordionContext<AccordionItemContextValue>(ITEM_NAME);

type AccordionItemElement = React.ElementRef<typeof CollapsiblePrimitive.Root>;
type CollapsibleProps = Radix.ComponentPropsWithoutRef<typeof CollapsiblePrimitive.Root>;
type CollapsibleProps = React.ComponentPropsWithoutRef<typeof CollapsiblePrimitive.Root>;
interface AccordionItemProps
extends Omit<CollapsibleProps, 'open' | 'defaultOpen' | 'onOpenChange'> {
/**
Expand Down Expand Up @@ -418,7 +395,7 @@ AccordionItem.displayName = ITEM_NAME;
const HEADER_NAME = 'AccordionHeader';

type AccordionHeaderElement = React.ElementRef<typeof Primitive.h3>;
type PrimitiveHeading3Props = Radix.ComponentPropsWithoutRef<typeof Primitive.h3>;
type PrimitiveHeading3Props = React.ComponentPropsWithoutRef<typeof Primitive.h3>;
interface AccordionHeaderProps extends PrimitiveHeading3Props {}

/**
Expand Down Expand Up @@ -451,7 +428,7 @@ AccordionHeader.displayName = HEADER_NAME;
const TRIGGER_NAME = 'AccordionTrigger';

type AccordionTriggerElement = React.ElementRef<typeof CollapsiblePrimitive.Trigger>;
type CollapsibleTriggerProps = Radix.ComponentPropsWithoutRef<typeof CollapsiblePrimitive.Trigger>;
type CollapsibleTriggerProps = React.ComponentPropsWithoutRef<typeof CollapsiblePrimitive.Trigger>;
interface AccordionTriggerProps extends CollapsibleTriggerProps {}

/**
Expand Down Expand Up @@ -489,7 +466,7 @@ AccordionTrigger.displayName = TRIGGER_NAME;
const CONTENT_NAME = 'AccordionContent';

type AccordionContentElement = React.ElementRef<typeof CollapsiblePrimitive.Content>;
type CollapsibleContentProps = Radix.ComponentPropsWithoutRef<typeof CollapsiblePrimitive.Content>;
type CollapsibleContentProps = React.ComponentPropsWithoutRef<typeof CollapsiblePrimitive.Content>;
interface AccordionContentProps extends CollapsibleContentProps {}

/**
Expand Down
4 changes: 2 additions & 2 deletions packages/react/alert-dialog/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0"
},
"peerDependenciesMeta": {
"@types/react": {
Expand Down
17 changes: 8 additions & 9 deletions packages/react/alert-dialog/src/AlertDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { createDialogScope } from '@radix-ui/react-dialog';
import { composeEventHandlers } from '@radix-ui/primitive';
import { Slottable } from '@radix-ui/react-slot';

import type * as Radix from '@radix-ui/react-primitive';
import type { Scope } from '@radix-ui/react-context';

/* -------------------------------------------------------------------------------------------------
Expand All @@ -21,7 +20,7 @@ const [createAlertDialogContext, createAlertDialogScope] = createContextScope(RO
]);
const useDialogScope = createDialogScope();

type DialogProps = Radix.ComponentPropsWithoutRef<typeof DialogPrimitive.Root>;
type DialogProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Root>;
interface AlertDialogProps extends Omit<DialogProps, 'modal'> {}

const AlertDialog: React.FC<AlertDialogProps> = (props: ScopedProps<AlertDialogProps>) => {
Expand All @@ -38,7 +37,7 @@ AlertDialog.displayName = ROOT_NAME;
const TRIGGER_NAME = 'AlertDialogTrigger';

type AlertDialogTriggerElement = React.ElementRef<typeof DialogPrimitive.Trigger>;
type DialogTriggerProps = Radix.ComponentPropsWithoutRef<typeof DialogPrimitive.Trigger>;
type DialogTriggerProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Trigger>;
interface AlertDialogTriggerProps extends DialogTriggerProps {}

const AlertDialogTrigger = React.forwardRef<AlertDialogTriggerElement, AlertDialogTriggerProps>(
Expand All @@ -57,7 +56,7 @@ AlertDialogTrigger.displayName = TRIGGER_NAME;

const PORTAL_NAME = 'AlertDialogPortal';

type DialogPortalProps = Radix.ComponentPropsWithoutRef<typeof DialogPrimitive.Portal>;
type DialogPortalProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Portal>;
interface AlertDialogPortalProps extends DialogPortalProps {}

const AlertDialogPortal: React.FC<AlertDialogPortalProps> = (
Expand All @@ -77,7 +76,7 @@ AlertDialogPortal.displayName = PORTAL_NAME;
const OVERLAY_NAME = 'AlertDialogOverlay';

type AlertDialogOverlayElement = React.ElementRef<typeof DialogPrimitive.Overlay>;
type DialogOverlayProps = Radix.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>;
type DialogOverlayProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>;
interface AlertDialogOverlayProps extends DialogOverlayProps {}

const AlertDialogOverlay = React.forwardRef<AlertDialogOverlayElement, AlertDialogOverlayProps>(
Expand All @@ -104,7 +103,7 @@ const [AlertDialogContentProvider, useAlertDialogContentContext] =
createAlertDialogContext<AlertDialogContentContextValue>(CONTENT_NAME);

type AlertDialogContentElement = React.ElementRef<typeof DialogPrimitive.Content>;
type DialogContentProps = Radix.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>;
type DialogContentProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>;
interface AlertDialogContentProps
extends Omit<DialogContentProps, 'onPointerDownOutside' | 'onInteractOutside'> {}

Expand Down Expand Up @@ -161,7 +160,7 @@ AlertDialogContent.displayName = CONTENT_NAME;
const TITLE_NAME = 'AlertDialogTitle';

type AlertDialogTitleElement = React.ElementRef<typeof DialogPrimitive.Title>;
type DialogTitleProps = Radix.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>;
type DialogTitleProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>;
interface AlertDialogTitleProps extends DialogTitleProps {}

const AlertDialogTitle = React.forwardRef<AlertDialogTitleElement, AlertDialogTitleProps>(
Expand All @@ -181,7 +180,7 @@ AlertDialogTitle.displayName = TITLE_NAME;
const DESCRIPTION_NAME = 'AlertDialogDescription';

type AlertDialogDescriptionElement = React.ElementRef<typeof DialogPrimitive.Description>;
type DialogDescriptionProps = Radix.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>;
type DialogDescriptionProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>;
interface AlertDialogDescriptionProps extends DialogDescriptionProps {}

const AlertDialogDescription = React.forwardRef<
Expand All @@ -202,7 +201,7 @@ AlertDialogDescription.displayName = DESCRIPTION_NAME;
const ACTION_NAME = 'AlertDialogAction';

type AlertDialogActionElement = React.ElementRef<typeof DialogPrimitive.Close>;
type DialogCloseProps = Radix.ComponentPropsWithoutRef<typeof DialogPrimitive.Close>;
type DialogCloseProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Close>;
interface AlertDialogActionProps extends DialogCloseProps {}

const AlertDialogAction = React.forwardRef<AlertDialogActionElement, AlertDialogActionProps>(
Expand Down
4 changes: 2 additions & 2 deletions packages/react/announce/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0"
},
"peerDependenciesMeta": {
"@types/react": {
Expand Down
4 changes: 1 addition & 3 deletions packages/react/announce/src/Announce.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import { useComposedRefs } from '@radix-ui/react-compose-refs';
import { Primitive } from '@radix-ui/react-primitive';
import { useLayoutEffect } from '@radix-ui/react-use-layout-effect';

import type * as Radix from '@radix-ui/react-primitive';

type RegionType = 'polite' | 'assertive' | 'off';
type RegionRole = 'status' | 'alert' | 'log' | 'none';

Expand All @@ -24,7 +22,7 @@ const listenerMap = new Map<Element, number>();
const NAME = 'Announce';

type AnnounceElement = React.ElementRef<typeof Primitive.div>;
type PrimitiveDivProps = Radix.ComponentPropsWithoutRef<typeof Primitive.div>;
type PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;
interface AnnounceProps extends PrimitiveDivProps {
/**
* Mirrors the `aria-atomic` DOM attribute for live regions. It is an optional attribute that
Expand Down
4 changes: 2 additions & 2 deletions packages/react/arrow/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0"
},
"peerDependenciesMeta": {
"@types/react": {
Expand Down
4 changes: 1 addition & 3 deletions packages/react/arrow/src/Arrow.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import * as React from 'react';
import { Primitive } from '@radix-ui/react-primitive';

import type * as Radix from '@radix-ui/react-primitive';

/* -------------------------------------------------------------------------------------------------
* Arrow
* -----------------------------------------------------------------------------------------------*/

const NAME = 'Arrow';

type ArrowElement = React.ElementRef<typeof Primitive.svg>;
type PrimitiveSvgProps = Radix.ComponentPropsWithoutRef<typeof Primitive.svg>;
type PrimitiveSvgProps = React.ComponentPropsWithoutRef<typeof Primitive.svg>;
interface ArrowProps extends PrimitiveSvgProps {}

const Arrow = React.forwardRef<ArrowElement, ArrowProps>((props, forwardedRef) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/react/aspect-ratio/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0"
},
"peerDependenciesMeta": {
"@types/react": {
Expand Down
4 changes: 1 addition & 3 deletions packages/react/aspect-ratio/src/AspectRatio.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import * as React from 'react';
import { Primitive } from '@radix-ui/react-primitive';

import type * as Radix from '@radix-ui/react-primitive';

/* -------------------------------------------------------------------------------------------------
* AspectRatio
* -----------------------------------------------------------------------------------------------*/

const NAME = 'AspectRatio';

type AspectRatioElement = React.ElementRef<typeof Primitive.div>;
type PrimitiveDivProps = Radix.ComponentPropsWithoutRef<typeof Primitive.div>;
type PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;
interface AspectRatioProps extends PrimitiveDivProps {
ratio?: number;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/react/avatar/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0"
},
"peerDependenciesMeta": {
"@types/react": {
Expand Down
Loading

0 comments on commit 06de2d4

Please sign in to comment.