Skip to content
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

Support for React 19 #2387

Draft
wants to merge 12 commits into
base: r/react-transition-group-removal
Choose a base branch
from
4 changes: 2 additions & 2 deletions apps/react-workshop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
"cypress-image-diff-js": "1.30.1",
"eslint": "*",
"eslint-config-prettier": "^8.8.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"typescript": "*",
"vite": "*"
},
Expand Down
4 changes: 2 additions & 2 deletions apps/react-workshop/src/Table.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import React, { useCallback } from 'react';
import React, { useCallback, type JSX } from 'react';
import type {
CellProps,
CellRendererProps,
Expand Down Expand Up @@ -1065,7 +1065,7 @@ export const ControlledState = () => {
subRows: DemoData[];
};

const tableInstance = React.useRef<TableInstance<DemoData>>();
const tableInstance = React.useRef<TableInstance<DemoData>>(undefined);
const [selectedRows, setSelectedRows] = React.useState<DemoData[]>([]);
const [expandedRows, setExpandedRows] = React.useState<DemoData[]>([]);

Expand Down
2 changes: 1 addition & 1 deletion examples/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import * as React from 'react';
import { ThemeProvider } from '@itwin/itwinui-react';

const withThemeProvider = (Component: () => React.ReactElement) => () => {
const withThemeProvider = (Component: () => React.ReactElement<any>) => () => {
const [portalContainer, setPortalContainer] = React.useState<HTMLElement>();
React.useEffect(() => void setPortalContainer(document.body), []);

Expand Down
8 changes: 4 additions & 4 deletions minimal-sandbox/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
"dependencies": {
"@itwin/itwinui-react": "3",
"@itwin/itwinui-icons-react": "2",
"react": "18",
"react-dom": "18"
"react": "19",
"react-dom": "19"
},
"devDependencies": {
"@types/react": "18",
"@types/react-dom": "18",
"@types/react": "19",
"@types/react-dom": "19",
"@vitejs/plugin-react": "4",
"typescript": "5",
"vite": "5"
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@
"autoprefixer": "^10.4.17",
"semver": "^7.5.4",
"typescript": "~5.5.2",
"@types/react": "18.2.14",
"@types/react-dom": "18.2.18",
"@types/react": "^19.0.7",
"@types/react-dom": "^19.0.3",
"astro": "~4.16.3",
"cypress": "13.8.1",
"ws@8": "^8.17.1",
Expand Down
8 changes: 4 additions & 4 deletions packages/itwinui-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,15 @@
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-require-extensions": "^0.1.3",
"jsdom": "^24.0.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"typescript": "5",
"vite": "~5.1.8",
"vitest": "^1.2.1"
},
"peerDependencies": {
"react": ">=17.0.0 <19.0.0",
"react-dom": ">=17.0.0 <19.0.0"
"react": ">=17.0.0 <20.0.0",
"react-dom": ">=17.0.0 <20.0.0"
},
"lint-staged": {
"*.{tsx,ts,jsx,js}": [
Expand Down
1 change: 1 addition & 0 deletions packages/itwinui-react/src/core/Avatar/Avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import cx from 'classnames';
import * as React from 'react';
import type { JSX } from 'react';
import { Box, SoftBackgrounds, isSoftBackground } from '../../utils/index.js';
import type {
AnyString,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import type { JSX } from 'react';
import cx from 'classnames';
import { Box } from '../../utils/index.js';
import type { PolymorphicForwardRefComponent } from '../../utils/index.js';
Expand Down
1 change: 1 addition & 0 deletions packages/itwinui-react/src/core/Buttons/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import cx from 'classnames';
import * as React from 'react';
import type { JSX } from 'react';

import { Box, ButtonBase } from '../../utils/index.js';
import type { PolymorphicForwardRefComponent } from '../../utils/index.js';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import type { JSX } from 'react';
import cx from 'classnames';
import { Button } from './Button.js';
import type { ButtonProps } from './Button.js';
Expand Down
1 change: 1 addition & 0 deletions packages/itwinui-react/src/core/Buttons/SplitButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import cx from 'classnames';
import * as React from 'react';
import type { JSX } from 'react';
import { Button } from './Button.js';
import type { ButtonProps } from './Button.js';
import { IconButton } from './IconButton.js';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as React from 'react';
import cx from 'classnames';
import {
Box,
getReactVersionSafeInertProp,
mergeEventHandlers,
useIntersection,
useMergedRefs,
Expand Down Expand Up @@ -59,7 +60,7 @@ export const CarouselSlide = React.forwardRef((props, ref) => {
aria-roledescription='slide'
tabIndex={index === currentIndex ? 0 : undefined}
ref={refs}
{...{ inert: index !== currentIndex ? '' : undefined }}
{...getReactVersionSafeInertProp(index !== currentIndex)}
{...rest}
onKeyDown={mergeEventHandlers(props.onKeyDown, (event) => {
// prevent default browser scrolling on arrow keys because focus will get lost when slide switches
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import type { JSX } from 'react';
import cx from 'classnames';
import { CarouselContext } from './CarouselContext.js';
import {
Expand Down Expand Up @@ -71,7 +72,7 @@ export const CarouselSlider = React.forwardRef((props, ref) => {
});
};

const scrollTimeout = React.useRef<number>();
const scrollTimeout = React.useRef<number>(undefined);

// reset isManuallyUpdating.current to false after the last scroll event
const handleOnScroll = React.useCallback(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export const ColorBuilder = React.forwardRef((props, ref) => {
...rest
} = props;

const builderRef = React.useRef<HTMLDivElement>();
const builderRef = React.useRef<HTMLDivElement>(undefined);
const refs = useMergedRefs(builderRef, ref);

const {
Expand Down
1 change: 1 addition & 0 deletions packages/itwinui-react/src/core/ComboBox/ComboBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import type { JSX } from 'react';
import { MenuExtraContent } from '../Menu/MenuExtraContent.js';
import type { SelectOption } from '../Select/Select.js';
import { SelectTag } from '../Select/SelectTag.js';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import type { JSX } from 'react';
import { Input } from '../Input/Input.js';
import {
useSafeContext,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import type { JSX } from 'react';
import { StatusMessage } from '../StatusMessage/StatusMessage.js';
import {
InputContainer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import type { JSX } from 'react';
import cx from 'classnames';
import { Menu } from '../Menu/Menu.js';
import {
Expand Down
5 changes: 3 additions & 2 deletions packages/itwinui-react/src/core/ComboBox/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import type { JSX } from 'react';
import type { SelectOption } from '../Select/Select.js';
import type { usePopover } from '../Popover/Popover.js';

export const ComboBoxRefsContext = React.createContext<
| {
inputRef: React.RefObject<HTMLInputElement>;
menuRef: React.RefObject<HTMLElement>;
inputRef: React.RefObject<HTMLInputElement | null>;
menuRef: React.RefObject<HTMLElement | null>;
optionsExtraInfo: Record<string, { __originalIndex: number }>;
}
| undefined
Expand Down
2 changes: 1 addition & 1 deletion packages/itwinui-react/src/core/Dialog/DialogContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export type DialogContextProps = {
/**
* Dialog root ref. For internal use.
*/
dialogRootRef?: React.RefObject<HTMLDivElement>;
dialogRootRef?: React.RefObject<HTMLDivElement | null>;
/**
* Determines the positioning of Dialog on page.
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/itwinui-react/src/core/Dialog/DialogMain.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export const DialogMain = React.forwardRef((props, ref) => {

const dialogRef = React.useRef<HTMLDivElement>(null);
const hasBeenResized = React.useRef(false);
const previousFocusedElement = React.useRef<HTMLElement | null>();
const previousFocusedElement = React.useRef<HTMLElement>(undefined);

const originalBodyOverflow = React.useRef('');
React.useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import type { JSX } from 'react';
import { mergeEventHandlers, useControlledState } from '../../utils/index.js';
import type {
PolymorphicForwardRefComponent,
Expand Down
1 change: 1 addition & 0 deletions packages/itwinui-react/src/core/Fieldset/Fieldset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import type { JSX } from 'react';
import { FieldsetBase } from '../../utils/index.js';
import type { PolymorphicForwardRefComponent } from '../../utils/index.js';

Expand Down
1 change: 1 addition & 0 deletions packages/itwinui-react/src/core/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import cx from 'classnames';
import * as React from 'react';
import type { JSX } from 'react';
import { IconButton } from '../Buttons/IconButton.js';

import { SvgMoreVertical, Box } from '../../utils/index.js';
Expand Down
1 change: 1 addition & 0 deletions packages/itwinui-react/src/core/Header/HeaderLogo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import cx from 'classnames';
import * as React from 'react';
import type { JSX } from 'react';

import { Box } from '../../utils/index.js';
import type { PolymorphicForwardRefComponent } from '../../utils/index.js';
Expand Down
11 changes: 6 additions & 5 deletions packages/itwinui-react/src/core/InputGrid/InputGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ const useSetup = (children: React.ReactNode) => {
* Handles regular inputs, plus `InputWithDecorations`, `InputWithIcon`, `ComboBox` and `Select`.
*/
const handleCloningInputs = (
child: React.ReactElement,
child: React.ReactElement<any>,
{
labelId,
inputId,
Expand All @@ -225,7 +225,7 @@ const handleCloningInputs = (
};
};

const cloneInput = (child: React.ReactElement) => {
const cloneInput = (child: React.ReactElement<any>) => {
if (child.type === ComboBox) {
return cloneElementWithRef(child, (child) => ({
inputProps: inputProps(child.props.inputProps),
Expand Down Expand Up @@ -266,15 +266,16 @@ const handleCloningInputs = (
/** @returns true if `child` is a form element that can be associated with a label using id */
const isInput = (child: React.ReactNode): boolean => {
return (
React.isValidElement(child) &&
// contains ComboBox.inputProps
React.isValidElement(child) && // contains Select.triggerProps
(child.type === 'input' ||
child.type === 'textarea' ||
child.type === 'select' ||
child.type === Input ||
child.type === Textarea ||
child.type === InputWithDecorations.Input ||
child.type === Select || // contains Select.triggerProps
child.type === ComboBox) // contains ComboBox.inputProps
child.type === Select ||
child.type === ComboBox)
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import type { JSX } from 'react';
import { Input } from '../Input/Input.js';
import { InputWithIcon, StatusIconMap } from '../../utils/index.js';
import type { PolymorphicForwardRefComponent } from '../../utils/index.js';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import type { JSX } from 'react';

import { Select } from '../Select/Select.js';
import type { SelectProps } from '../Select/Select.js';
Expand Down
1 change: 1 addition & 0 deletions packages/itwinui-react/src/core/Menu/MenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import type { JSX } from 'react';
import {
SvgCaretRightSmall,
useMergedRefs,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import type { JSX } from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import { ErrorPage, type ErrorPageType } from './ErrorPage.js';
import {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import type { JSX } from 'react';
import { Button } from '../Buttons/Button.js';
import { NonIdealState } from './NonIdealState.js';
import { ProgressRadial } from '../ProgressIndicators/ProgressRadial.js';
Expand Down
8 changes: 6 additions & 2 deletions packages/itwinui-react/src/core/Overlay/Overlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import { Box, polymorphic } from '../../utils/index.js';
import {
Box,
getReactVersionSafeInertProp,
polymorphic,
} from '../../utils/index.js';
import type { PolymorphicForwardRefComponent } from '../../utils/index.js';

type OverlayComponentProps = {
Expand Down Expand Up @@ -40,7 +44,7 @@ if (process.env.NODE_ENV === 'development') {
const OverlayHiddenContent = React.forwardRef((props, ref) => {
const { children, ...rest } = props;
return (
<Box {...{ inert: '' }} ref={ref} {...rest}>
<Box {...getReactVersionSafeInertProp()} ref={ref} {...rest}>
{children}
</Box>
);
Expand Down
5 changes: 3 additions & 2 deletions packages/itwinui-react/src/core/Panels/Panels.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
useWarningLogger,
useLayoutEffect,
useLatestRef,
getReactVersionSafeInertProp,
} from '../../utils/index.js';
import type { PolymorphicForwardRefComponent } from '../../utils/index.js';
import { IconButton } from '../Buttons/IconButton.js';
Expand Down Expand Up @@ -221,7 +222,7 @@ const Panel = React.forwardRef((props, forwardedRef) => {
className={cx('iui-panel', className)}
aria-labelledby={`${id}-header-title`}
role='group'
{...{ inert: isInert ? '' : undefined }}
{...getReactVersionSafeInertProp(isInert)}
data-iui-transitioning={isTransitioning ? 'true' : undefined}
{...rest}
>
Expand Down Expand Up @@ -252,7 +253,7 @@ if (process.env.NODE_ENV === 'development') {

type PanelTriggerProps = {
for: string;
children: React.ReactElement;
children: React.ReactElement<any>;
};

const PanelTrigger = (props: PanelTriggerProps) => {
Expand Down
Loading
Loading