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

Update react monorepo to v19 (major) #290

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
"@tsconfig/vite-react": "^3.0.0",
"@types/eslint": "^9.0.0",
"@types/node": "^22.0.0",
"@types/react": "^18.2.21",
"@types/react": "^19.0.0",
"@typescript-eslint/eslint-plugin": "^8.0.0",
"@typescript-eslint/parser": "^8.0.0",
"@vector-im/compound-design-tokens": "^2.0.0",
Expand All @@ -86,8 +86,8 @@
"eslint-plugin-storybook": "^0.11.0",
"jsdom": "^25.0.0",
"prettier": "3.4.2",
"react": "^18.2.0",
"react-dom": "^18.3.1",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"resize-observer-polyfill": "^1.5.1",
"rimraf": "^6.0.0",
"serve": "^14.2.1",
Expand All @@ -111,15 +111,14 @@
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slot": "^1.1.0",
"classnames": "^2.5.1",
"ts-xor": "^1.3.0",
"vaul": "^1.0.0"
},
"peerDependencies": {
"@fontsource/inconsolata": "^5",
"@fontsource/inter": "^5",
"@types/react": "*",
"@vector-im/compound-design-tokens": ">=1.6.1 <3.0.0",
"react": "^18"
"react": "^18 || ^19.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
Expand Down
12 changes: 4 additions & 8 deletions src/components/Avatar/Avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,16 @@ limitations under the License.
*/

import classnames from "classnames";
import React, { forwardRef } from "react";
import React, { ComponentProps, forwardRef } from "react";
import { getInitialLetter } from "../../utils/string";
import { SuspenseImg } from "../../utils/SuspenseImg";
import styles from "./Avatar.module.css";
import { useIdColorHash } from "./useIdColorHash";

type AvatarProps = (
| JSX.IntrinsicElements["button"]
| JSX.IntrinsicElements["span"]
) & {
type AvatarProps = (ComponentProps<"button"> | ComponentProps<"span">) & {
/**
* The avatar image URL, if any.
*/
src?: React.ComponentProps<typeof SuspenseImg>["src"];
src?: React.ComponentProps<"img">["src"];
/**
* The Matrix ID, Room ID, or Alias to generate the color when no image source
* is provided. Also used as a fallback when name is empty.
Expand Down Expand Up @@ -62,7 +58,7 @@ type AvatarProps = (
/**
* Callback when the image has failed to load.
*/
onError?: React.ComponentProps<typeof SuspenseImg>["onError"];
onError?: React.ComponentProps<"img">["onError"];
};

/**
Expand Down
2 changes: 1 addition & 1 deletion src/components/Button/IconButton/IconButton.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export const WithSubtleBackground: Story = {

export const WithLabel: Story = {
args: {
label: "label",
tooltip: "label",
},
};

Expand Down
4 changes: 1 addition & 3 deletions src/components/Button/IconButton/IconButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ import React, { PropsWithChildren, forwardRef } from "react";
import classnames from "classnames";

import styles from "./IconButton.module.css";
import { UnstyledButton } from "../UnstyledButton";
import { UnstyledButtonPropsFor } from "../UnstyledButton";
import { UnstyledButton, UnstyledButtonPropsFor } from "../UnstyledButton";
import { IndicatorIcon } from "../../Icon/IndicatorIcon/IndicatorIcon";
import { Tooltip } from "../../Tooltip/Tooltip";

Expand Down Expand Up @@ -53,7 +52,6 @@ type IconButtonProps = UnstyledButtonPropsFor<"button"> & {
*/
tooltip?: string;
subtleBackground?: boolean;
label?: string;
};

/**
Expand Down
4 changes: 2 additions & 2 deletions src/components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -268,10 +268,10 @@ const DropdownItem = memo(function DropdownItem({
function useOpen(): [
boolean,
Dispatch<SetStateAction<boolean>>,
RefObject<HTMLDivElement>,
RefObject<HTMLDivElement | null>,
] {
const [open, setOpen] = useState(false);
const ref = useRef<HTMLDivElement>(null);
const ref = useRef<HTMLDivElement | null>(null);

// If the user clicks outside the dropdown, close it
useEffect(() => {
Expand Down
4 changes: 3 additions & 1 deletion src/components/Form/Controls/EditInPlace/EditInPlace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,9 @@ export const EditInPlace = forwardRef<HTMLInputElement, Props>(
const shouldShowSaveButton =
state === State.Dirty || state === State.Saving || isFocusWithin;

const hideTimer = useRef<ReturnType<typeof setTimeout>>();
const hideTimer = useRef<ReturnType<typeof setTimeout> | undefined>(
undefined,
);

useEffect(() => {
// Start a timer when we switch to the saved state
Expand Down
2 changes: 1 addition & 1 deletion src/components/Menu/MenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export const MenuItem = <C extends MenuItemElement = "button">({
onClick: onClickProp,
disabled,
...props
}: Props<C>): JSX.Element => {
}: Props<C>): React.ReactElement => {
const Component = as ?? ("button" as ElementType);
const context = useContext(MenuContext);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,10 @@ function ReleaseAnnouncementAnchor({
children,
context.getReferenceProps({
ref,
...children.props,
Copy link
Member

Choose a reason for hiding this comment

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

cloneElement will anyway keep the existing props

// If the ReleaseAnnouncement is open, we need manually aria-describedby.
// The RA has the dialog role and it's not adding automatically the aria-describedby.
...(context.open && {
"aria-describedby": context.getFloatingProps().id,
"aria-describedby": context.getFloatingProps().id as string,
Copy link
Member

Choose a reason for hiding this comment

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

getFloatingProps returns Record<string, unknown>, but we know this is a string

}),
}),
);
Expand Down
4 changes: 3 additions & 1 deletion src/components/Tooltip/Tooltip.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,16 @@ const meta = {
args: {
// needed, to prevent the tooltip to be in controlled mode
onOpenChange: undefined,
description: undefined,
label: undefined,
children: (
<IconButton>
<UserIcon />
</IconButton>
),
},
decorators: [
(Story: StoryFn) => (
(Story) => (
<div style={{ padding: 100 }}>
<TooltipProvider>
<Story />
Expand Down
7 changes: 3 additions & 4 deletions src/components/Tooltip/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,11 @@ import {
TooltipLabel,
useTooltip,
} from "./useTooltip";
import { XOR } from "ts-xor";

// Unfortunately Omit doesn't distribute nicely over sum types, so we have to
// piece together the useTooltip options type by hand
type TooltipProps = Omit<CommonUseTooltipProps, "isTriggerInteractive"> &
XOR<TooltipLabel, TooltipDescription> & {
(TooltipLabel | TooltipDescription) & {
Copy link
Member

Choose a reason for hiding this comment

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

ts-xor really makes it impossible to use in some context, especially stories, so I removed it

/**
* Whether the trigger element is interactive.
* When trigger is interactive:
Expand Down Expand Up @@ -184,7 +183,7 @@ const TooltipAnchor: FC<TooltipAnchorProps> = ({
if (!isValidElement(children)) return;

if (isTriggerInteractive) {
const props = context.getReferenceProps({ ref, ...children.props });
const props = context.getReferenceProps({ ref });
return cloneElement(children, props);
} else {
// For a non-interactive trigger, we want most of the props to go on the
Expand All @@ -202,7 +201,7 @@ const TooltipAnchor: FC<TooltipAnchorProps> = ({
} = props;
return (
<span tabIndex={nonInteractiveTriggerTabIndex} {...spanProps}>
{cloneElement(children as ReactElement, {
{cloneElement(children as ReactElement<Record<string, unknown>>, {
"aria-labelledby": labelId,
"aria-describedby": descriptionId,
})}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Tooltip/useTooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ export function useTooltip({
});

// On touch screens, show the tooltip on a long press
const pressTimer = useRef<number>();
const pressTimer = useRef<number | undefined>(undefined);
useEffect(() => () => window.clearTimeout(pressTimer.current), []);
const press = useMemo(() => {
const onTouchEnd = () => {
Expand Down
98 changes: 0 additions & 98 deletions src/utils/SuspenseImg.tsx
Copy link
Member

Choose a reason for hiding this comment

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

That file wasn't used

This file was deleted.

40 changes: 23 additions & 17 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1569,17 +1569,11 @@
dependencies:
undici-types "~6.20.0"

"@types/prop-types@*":
version "15.7.14"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.14.tgz#1433419d73b2a7ebfc6918dcefd2ec0d5cd698f2"
integrity sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==

"@types/react@^18.2.21":
version "18.3.14"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.14.tgz#7ce43bbca0e15e1c4f67ad33ea3f83d75aa6756b"
integrity sha512-NzahNKvjNhVjuPBQ+2G7WlxstQ+47kXZNHlUvFakDViuIEfGY926GqhMueQFZ7woG+sPiQKlF36XfrIUVSUfFg==
"@types/react@^19.0.0":
version "19.0.1"
resolved "https://registry.yarnpkg.com/@types/react/-/react-19.0.1.tgz#a000d5b78f473732a08cecbead0f3751e550b3df"
integrity sha512-YW6614BDhqbpR5KtUYzTA+zlA7nayzJRA9ljz9CQoxthR0sDisYZLuvSMsil36t4EH/uAt8T52Xb4sVw17G+SQ==
dependencies:
"@types/prop-types" "*"
csstype "^3.0.2"

"@types/resolve@^1.20.2":
Expand Down Expand Up @@ -4700,14 +4694,21 @@ react-docgen@^7.0.0:
resolve "^1.22.1"
strip-indent "^4.0.0"

"react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", react-dom@^18.3.1:
"react-dom@^16.8.0 || ^17.0.0 || ^18.0.0":
version "18.3.1"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4"
integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==
dependencies:
loose-envify "^1.1.0"
scheduler "^0.23.2"

react-dom@^19.0.0:
version "19.0.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.0.0.tgz#43446f1f01c65a4cd7f7588083e686a6726cfb57"
integrity sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==
dependencies:
scheduler "^0.25.0"

react-is@^16.13.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
Expand Down Expand Up @@ -4751,13 +4752,18 @@ react-style-singleton@^2.2.1:
invariant "^2.2.4"
tslib "^2.0.0"

"react@^16.8.0 || ^17.0.0 || ^18.0.0", react@^18.2.0:
"react@^16.8.0 || ^17.0.0 || ^18.0.0":
version "18.3.1"
resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891"
integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==
dependencies:
loose-envify "^1.1.0"

react@^19.0.0:
version "19.0.0"
resolved "https://registry.yarnpkg.com/react/-/react-19.0.0.tgz#6e1969251b9f108870aa4bff37a0ce9ddfaaabdd"
integrity sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==

recast@^0.23.5:
version "0.23.9"
resolved "https://registry.yarnpkg.com/recast/-/recast-0.23.9.tgz#587c5d3a77c2cfcb0c18ccce6da4361528c2587b"
Expand Down Expand Up @@ -4965,6 +4971,11 @@ scheduler@^0.23.2:
dependencies:
loose-envify "^1.1.0"

scheduler@^0.25.0:
version "0.25.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.25.0.tgz#336cd9768e8cceebf52d3c80e3dcf5de23e7e015"
integrity sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==

semver@^6.3.1:
version "6.3.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
Expand Down Expand Up @@ -5480,11 +5491,6 @@ ts-dedent@^2.0.0, ts-dedent@^2.2.0:
resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5"
integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==

ts-xor@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/ts-xor/-/ts-xor-1.3.0.tgz#3e59f24f0321f9f10f350e0cee3b534b89a2c70b"
integrity sha512-RLXVjliCzc1gfKQFLRpfeD0rrWmjnSTgj7+RFhoq3KRkUYa8LE/TIidYOzM5h+IdFBDSjjSgk9Lto9sdMfDFEA==

tsconfig-paths@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c"
Expand Down
Loading