diff --git a/.changeset/witty-dodos-peel.md b/.changeset/witty-dodos-peel.md new file mode 100644 index 0000000000..42e35dd2c0 --- /dev/null +++ b/.changeset/witty-dodos-peel.md @@ -0,0 +1,6 @@ +--- +'@rocket.chat/fuselage-hooks': minor +'@rocket.chat/fuselage': patch +--- + +Enables hooks' compatibility with React 18 diff --git a/packages/fuselage-hooks/jest.config.js b/packages/fuselage-hooks/jest.config.js deleted file mode 100644 index 385588fce8..0000000000 --- a/packages/fuselage-hooks/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - preset: 'ts-jest', - errorOnDeprecated: true, - testMatch: ['/src/**/*.spec.{ts,tsx}'], - testEnvironment: 'jsdom', - setupFilesAfterEnv: ['testing-utils/setup/noErrorsLogged'], -}; diff --git a/packages/fuselage-hooks/jest.config.ts b/packages/fuselage-hooks/jest.config.ts new file mode 100644 index 0000000000..e524d57a9c --- /dev/null +++ b/packages/fuselage-hooks/jest.config.ts @@ -0,0 +1,68 @@ +import type { Config } from 'jest'; + +export default { + projects: [ + { + displayName: 'React 17', + preset: 'ts-jest', + errorOnDeprecated: true, + testMatch: [ + '/src/**/*.spec.{ts,tsx}', + '!**/*.server.spec.{ts,tsx}', + ], + testEnvironment: 'jsdom', + setupFilesAfterEnv: ['testing-utils/setup/noErrorsLogged'], + moduleNameMapper: { + '^react($|/.+)': 'react$1', + '^react-dom/client$': 'react-dom$1', + '^react-dom($|/.+)': 'react-dom$1', + }, + }, + { + displayName: 'React 17 SSR', + preset: 'ts-jest', + errorOnDeprecated: true, + testMatch: ['/src/**/*.server.spec.{ts,tsx}'], + testEnvironment: 'node', + setupFilesAfterEnv: ['testing-utils/setup/noErrorsLogged'], + moduleNameMapper: { + '^react($|/.+)': 'react$1', + '^react-dom/client$': 'react-dom$1', + '^react-dom($|/.+)': 'react-dom$1', + }, + }, + { + displayName: 'React 18', + preset: 'ts-jest', + errorOnDeprecated: true, + testMatch: [ + '/src/**/*.spec.{ts,tsx}', + '!**/*.server.spec.{ts,tsx}', + ], + testEnvironment: 'jsdom', + setupFilesAfterEnv: [ + 'testing-utils/setup/noErrorsLogged', + '/src/jest-setup.ts', + ], + moduleNameMapper: { + '^react($|/.+)': 'react18$1', + '^react-dom($|/.+)': 'react-dom18$1', + }, + }, + { + displayName: 'React 18 SSR', + preset: 'ts-jest', + errorOnDeprecated: true, + testMatch: ['/src/**/*.server.spec.{ts,tsx}'], + testEnvironment: 'node', + setupFilesAfterEnv: [ + 'testing-utils/setup/noErrorsLogged', + '/src/jest-setup.ts', + ], + moduleNameMapper: { + '^react($|/.+)': 'react18$1', + '^react-dom($|/.+)': 'react-dom18$1', + }, + }, + ], +} satisfies Config; diff --git a/packages/fuselage-hooks/package.json b/packages/fuselage-hooks/package.json index df04fe1fb5..e16a734303 100644 --- a/packages/fuselage-hooks/package.json +++ b/packages/fuselage-hooks/package.json @@ -49,7 +49,7 @@ "@rollup/plugin-json": "~4.1.0", "@rollup/plugin-node-resolve": "~13.1.3", "@rollup/plugin-typescript": "~8.3.4", - "@testing-library/react-hooks": "~8.0.1", + "@testing-library/react": "~16.0.1", "@testing-library/user-event": "~14.5.2", "@types/jest": "~29.5.12", "@types/react": "~17.0.80", @@ -63,6 +63,9 @@ "npm-run-all": "^4.1.5", "prettier": "~3.3.3", "react": "^17.0.2", + "react-dom": "~17.0.2", + "react-dom18": "npm:react-dom@18", + "react18": "npm:react@18", "rimraf": "~5.0.0", "rollup": "~2.79.2", "rollup-plugin-terser": "~7.0.2", diff --git a/packages/fuselage-hooks/src/jest-setup.ts b/packages/fuselage-hooks/src/jest-setup.ts new file mode 100644 index 0000000000..838c2fefbe --- /dev/null +++ b/packages/fuselage-hooks/src/jest-setup.ts @@ -0,0 +1,3 @@ +import { configure } from '@testing-library/react'; + +configure({ reactStrictMode: true }); diff --git a/packages/fuselage-hooks/src/testing.ts b/packages/fuselage-hooks/src/testing.ts new file mode 100644 index 0000000000..ab0008b1ea --- /dev/null +++ b/packages/fuselage-hooks/src/testing.ts @@ -0,0 +1,45 @@ +import { + queries, + Queries, + RenderHookOptions, + RenderHookResult, + renderHook as _renderHook, +} from '@testing-library/react'; +import { createElement } from 'react'; +import * as ReactDOMClient from 'react-dom'; +import { renderToString } from 'react-dom/server'; + +type RendererableContainer = Element | Document | DocumentFragment; + +export function renderHook< + Result, + Props, + Q extends Queries = typeof queries, + Container extends RendererableContainer = HTMLElement, + BaseElement extends RendererableContainer = Container, +>( + render: (initialProps: Props) => Result, + options?: RenderHookOptions | undefined, +): RenderHookResult { + if (typeof document === 'undefined') { + let current: Result; + const TestComponent = () => { + current = render(options?.initialProps as any); + return null; + }; + + renderToString(createElement(TestComponent)); + + return { + result: { current: current! }, + rerender: () => undefined, + unmount: () => undefined, + }; + } + + if ('createRoot' in ReactDOMClient) return _renderHook(render, options); + + return _renderHook(render, { ...options, legacyRoot: true }); +} + +export { act } from '@testing-library/react'; diff --git a/packages/fuselage-hooks/src/useAutoFocus.spec.ts b/packages/fuselage-hooks/src/useAutoFocus.spec.ts index 629a15d17b..5fc7182398 100644 --- a/packages/fuselage-hooks/src/useAutoFocus.spec.ts +++ b/packages/fuselage-hooks/src/useAutoFocus.spec.ts @@ -1,6 +1,6 @@ -import { renderHook, act } from '@testing-library/react-hooks'; import { useImperativeHandle, useState } from 'react'; +import { renderHook, act } from './testing'; import { useAutoFocus } from './useAutoFocus'; const focus = jest.fn(); @@ -17,7 +17,7 @@ it('invokes focus', async () => { act(() => undefined); - expect(focus).toHaveBeenCalledTimes(1); + expect(focus).toHaveBeenCalled(); }); it('does not invoke focus if isFocused is false', () => { @@ -28,7 +28,7 @@ it('does not invoke focus if isFocused is false', () => { act(() => undefined); - expect(focus).toHaveBeenCalledTimes(0); + expect(focus).not.toHaveBeenCalled(); }); it('invokes focus if isFocused is toggled', () => { @@ -41,11 +41,11 @@ it('invokes focus if isFocused is toggled', () => { act(() => undefined); - expect(focus).toHaveBeenCalledTimes(0); + expect(focus).not.toHaveBeenCalled(); act(() => { result.current.setIsFocused(true); }); - expect(focus).toHaveBeenCalledTimes(1); + expect(focus).toHaveBeenCalled(); }); diff --git a/packages/fuselage-hooks/src/useAutoFocus.ts b/packages/fuselage-hooks/src/useAutoFocus.ts index 90ea6c808b..05ca082352 100644 --- a/packages/fuselage-hooks/src/useAutoFocus.ts +++ b/packages/fuselage-hooks/src/useAutoFocus.ts @@ -8,7 +8,7 @@ import { useEffect, useRef } from 'react'; * @param options - options of the focus request * @returns the ref which holds the element * @public - * @deprecated in favor of focus provided by react-hook-form + * @deprecated in favor of focus provided by react-hook-form or the `autoFocus` attribute */ export const useAutoFocus = < T extends { focus: (options?: FocusOptions) => void }, @@ -17,16 +17,14 @@ export const useAutoFocus = < options?: FocusOptions, ): Ref => { const elementRef = useRef(null); - - const { preventScroll } = options || {}; + const optionsRef = useRef(options); + optionsRef.current = options; useEffect(() => { if (isFocused && elementRef.current) { - elementRef.current.focus({ - preventScroll, - }); + elementRef.current.focus(optionsRef.current); } - }, [elementRef, isFocused, preventScroll]); + }, [elementRef, isFocused]); return elementRef; }; diff --git a/packages/fuselage-hooks/src/useBorderBoxSize.server.spec.ts b/packages/fuselage-hooks/src/useBorderBoxSize.server.spec.ts index 856addc389..ea5106030c 100644 --- a/packages/fuselage-hooks/src/useBorderBoxSize.server.spec.ts +++ b/packages/fuselage-hooks/src/useBorderBoxSize.server.spec.ts @@ -1,10 +1,6 @@ -/** - * @jest-environment node - */ - -import { renderHook } from '@testing-library/react-hooks/server'; import { useRef } from 'react'; +import { renderHook } from './testing'; import { useBorderBoxSize } from './useBorderBoxSize'; it('immediately returns zero size', () => { diff --git a/packages/fuselage-hooks/src/useBorderBoxSize.spec.ts b/packages/fuselage-hooks/src/useBorderBoxSize.spec.ts index 45241437b0..2bf5dc9fad 100644 --- a/packages/fuselage-hooks/src/useBorderBoxSize.spec.ts +++ b/packages/fuselage-hooks/src/useBorderBoxSize.spec.ts @@ -1,8 +1,8 @@ -import { renderHook, act } from '@testing-library/react-hooks'; import type { RefObject } from 'react'; import { useRef } from 'react'; import { withResizeObserverMock } from 'testing-utils/mocks/withResizeObserverMock'; +import { renderHook, act } from './testing'; import { useBorderBoxSize } from './useBorderBoxSize'; withResizeObserverMock(); diff --git a/packages/fuselage-hooks/src/useBreakpoints.spec.ts b/packages/fuselage-hooks/src/useBreakpoints.spec.ts index f1b04f2bd9..f51d781090 100644 --- a/packages/fuselage-hooks/src/useBreakpoints.spec.ts +++ b/packages/fuselage-hooks/src/useBreakpoints.spec.ts @@ -1,7 +1,7 @@ import breakpoints from '@rocket.chat/fuselage-tokens/breakpoints.json'; -import { renderHook, act } from '@testing-library/react-hooks'; import { withMatchMediaMock } from 'testing-utils/mocks/withMatchMediaMock'; +import { renderHook, act } from './testing'; import { useBreakpoints } from './useBreakpoints'; const setViewport = withMatchMediaMock(); diff --git a/packages/fuselage-hooks/src/useClipboard.server.spec.ts b/packages/fuselage-hooks/src/useClipboard.server.spec.ts index 70dee8343a..35677915c5 100644 --- a/packages/fuselage-hooks/src/useClipboard.server.spec.ts +++ b/packages/fuselage-hooks/src/useClipboard.server.spec.ts @@ -1,9 +1,4 @@ -/** - * @jest-environment node - */ - -import { renderHook } from '@testing-library/react-hooks/server'; - +import { renderHook } from './testing'; import { useClipboard } from './useClipboard'; it('has hasCopied and copy properties', () => { diff --git a/packages/fuselage-hooks/src/useClipboard.spec.ts b/packages/fuselage-hooks/src/useClipboard.spec.ts index d501ce0e44..38f6e0e8aa 100644 --- a/packages/fuselage-hooks/src/useClipboard.spec.ts +++ b/packages/fuselage-hooks/src/useClipboard.spec.ts @@ -1,6 +1,6 @@ -import { renderHook, act } from '@testing-library/react-hooks'; import { withClipboardMock } from 'testing-utils/mocks/withClipboardMock'; +import { renderHook, act } from './testing'; import { useClipboard } from './useClipboard'; let container: Element | undefined; @@ -87,8 +87,8 @@ it('runs only success function receiving event object', async () => { await copy(event); }); - expect(onCopySuccess).toBeCalledWith(event); - expect(onCopyError).toBeCalledTimes(0); + expect(onCopySuccess).toHaveBeenCalledWith(event); + expect(onCopyError).toHaveBeenCalledTimes(0); }); it('runs only error function receiving error object', async () => { @@ -112,6 +112,6 @@ it('runs only error function receiving error object', async () => { await copy(event); }); - expect(onCopySuccess).toBeCalledTimes(0); - expect(onCopyError).toBeCalledWith(rejection); + expect(onCopySuccess).toHaveBeenCalledTimes(0); + expect(onCopyError).toHaveBeenCalledWith(rejection); }); diff --git a/packages/fuselage-hooks/src/useContentBoxSize.server.spec.ts b/packages/fuselage-hooks/src/useContentBoxSize.server.spec.ts index ac054a22db..7778918c98 100644 --- a/packages/fuselage-hooks/src/useContentBoxSize.server.spec.ts +++ b/packages/fuselage-hooks/src/useContentBoxSize.server.spec.ts @@ -1,10 +1,6 @@ -/** - * @jest-environment node - */ - -import { renderHook } from '@testing-library/react-hooks/server'; import { useRef } from 'react'; +import { renderHook } from './testing'; import { useContentBoxSize } from './useContentBoxSize'; it('immediately returns zero size', () => { diff --git a/packages/fuselage-hooks/src/useContentBoxSize.spec.ts b/packages/fuselage-hooks/src/useContentBoxSize.spec.ts index e7a4a6fb92..08d2c9e1d5 100644 --- a/packages/fuselage-hooks/src/useContentBoxSize.spec.ts +++ b/packages/fuselage-hooks/src/useContentBoxSize.spec.ts @@ -1,8 +1,8 @@ -import { renderHook, act } from '@testing-library/react-hooks'; import type { RefObject } from 'react'; import { useRef } from 'react'; import { withResizeObserverMock } from 'testing-utils/mocks/withResizeObserverMock'; +import { renderHook, act } from './testing'; import { useContentBoxSize } from './useContentBoxSize'; withResizeObserverMock(); diff --git a/packages/fuselage-hooks/src/useDebouncedCallback.server.spec.ts b/packages/fuselage-hooks/src/useDebouncedCallback.server.spec.ts index eb49a9520f..f8bbbe7ac1 100644 --- a/packages/fuselage-hooks/src/useDebouncedCallback.server.spec.ts +++ b/packages/fuselage-hooks/src/useDebouncedCallback.server.spec.ts @@ -1,9 +1,4 @@ -/** - * @jest-environment node - */ - -import { renderHook } from '@testing-library/react-hooks/server'; - +import { renderHook } from './testing'; import { useDebouncedCallback } from './useDebouncedCallback'; beforeAll(() => { diff --git a/packages/fuselage-hooks/src/useDebouncedCallback.spec.ts b/packages/fuselage-hooks/src/useDebouncedCallback.spec.ts index 81244f3674..9e0bfd3cdc 100644 --- a/packages/fuselage-hooks/src/useDebouncedCallback.spec.ts +++ b/packages/fuselage-hooks/src/useDebouncedCallback.spec.ts @@ -1,6 +1,6 @@ -import { renderHook, act } from '@testing-library/react-hooks'; import { useState } from 'react'; +import { renderHook, act } from './testing'; import { useDebouncedCallback } from './useDebouncedCallback'; beforeAll(() => { diff --git a/packages/fuselage-hooks/src/useDebouncedCallback.ts b/packages/fuselage-hooks/src/useDebouncedCallback.ts index c97ed16de6..845ee706b0 100644 --- a/packages/fuselage-hooks/src/useDebouncedCallback.ts +++ b/packages/fuselage-hooks/src/useDebouncedCallback.ts @@ -18,8 +18,8 @@ export const useDebouncedCallback =

( flush: () => void; cancel: () => void; } => { - // eslint-disable-next-line react-hooks/exhaustive-deps - const effectiveCallback = useMemo(() => callback, deps); + // eslint-disable-next-line react-hooks/exhaustive-deps, react-hooks/rules-of-hooks + const effectiveCallback = deps ? useMemo(() => callback, deps) : callback; const timerCallbackRef = useRef<() => void>(); const timerRef = useRef>(); diff --git a/packages/fuselage-hooks/src/useDebouncedReducer.spec.ts b/packages/fuselage-hooks/src/useDebouncedReducer.spec.ts index 33eec935e6..f60b90e81f 100644 --- a/packages/fuselage-hooks/src/useDebouncedReducer.spec.ts +++ b/packages/fuselage-hooks/src/useDebouncedReducer.spec.ts @@ -1,5 +1,4 @@ -import { renderHook, act } from '@testing-library/react-hooks'; - +import { renderHook, act } from './testing'; import { useDebouncedReducer } from './useDebouncedReducer'; beforeAll(() => { diff --git a/packages/fuselage-hooks/src/useDebouncedState.spec.ts b/packages/fuselage-hooks/src/useDebouncedState.spec.ts index d7ee11981b..a46cc9409c 100644 --- a/packages/fuselage-hooks/src/useDebouncedState.spec.ts +++ b/packages/fuselage-hooks/src/useDebouncedState.spec.ts @@ -1,5 +1,4 @@ -import { renderHook, act } from '@testing-library/react-hooks'; - +import { renderHook, act } from './testing'; import { useDebouncedState } from './useDebouncedState'; beforeAll(() => { diff --git a/packages/fuselage-hooks/src/useDebouncedUpdates.spec.ts b/packages/fuselage-hooks/src/useDebouncedUpdates.spec.ts index 0314ba548c..8bf4c524d1 100644 --- a/packages/fuselage-hooks/src/useDebouncedUpdates.spec.ts +++ b/packages/fuselage-hooks/src/useDebouncedUpdates.spec.ts @@ -1,6 +1,6 @@ -import { renderHook, act } from '@testing-library/react-hooks'; import { useState } from 'react'; +import { renderHook, act } from './testing'; import { useDebouncedUpdates } from './useDebouncedUpdates'; beforeAll(() => { diff --git a/packages/fuselage-hooks/src/useDebouncedValue.server.spec.ts b/packages/fuselage-hooks/src/useDebouncedValue.server.spec.ts index b1a6ec99e6..3b1215ed58 100644 --- a/packages/fuselage-hooks/src/useDebouncedValue.server.spec.ts +++ b/packages/fuselage-hooks/src/useDebouncedValue.server.spec.ts @@ -1,9 +1,4 @@ -/** - * @jest-environment node - */ - -import { renderHook } from '@testing-library/react-hooks/server'; - +import { renderHook } from './testing'; import { useDebouncedValue } from './useDebouncedValue'; const delay = 100; diff --git a/packages/fuselage-hooks/src/useDebouncedValue.spec.ts b/packages/fuselage-hooks/src/useDebouncedValue.spec.ts index 37fbefa971..a14c417e8b 100644 --- a/packages/fuselage-hooks/src/useDebouncedValue.spec.ts +++ b/packages/fuselage-hooks/src/useDebouncedValue.spec.ts @@ -1,6 +1,6 @@ -import { renderHook, act } from '@testing-library/react-hooks'; import { useReducer } from 'react'; +import { renderHook, act } from './testing'; import { useDebouncedValue } from './useDebouncedValue'; beforeAll(() => { diff --git a/packages/fuselage-hooks/src/useEffectEvent.server.spec.ts b/packages/fuselage-hooks/src/useEffectEvent.server.spec.ts index f29d0fe707..30ff58e706 100644 --- a/packages/fuselage-hooks/src/useEffectEvent.server.spec.ts +++ b/packages/fuselage-hooks/src/useEffectEvent.server.spec.ts @@ -1,9 +1,4 @@ -/** - * @jest-environment node - */ - -import { renderHook } from '@testing-library/react-hooks/server'; - +import { renderHook } from './testing'; import { useEffectEvent } from './useEffectEvent'; it('returns a callback that invokes the mutable one', () => { diff --git a/packages/fuselage-hooks/src/useEffectEvent.spec.ts b/packages/fuselage-hooks/src/useEffectEvent.spec.ts index bd36d5be87..773279e53b 100644 --- a/packages/fuselage-hooks/src/useEffectEvent.spec.ts +++ b/packages/fuselage-hooks/src/useEffectEvent.spec.ts @@ -1,6 +1,6 @@ -import { act, renderHook } from '@testing-library/react-hooks'; import { useState } from 'react'; +import { act, renderHook } from './testing'; import { useEffectEvent } from './useEffectEvent'; it('returns a stable callback', () => { @@ -8,9 +8,12 @@ it('returns a stable callback', () => { const { result, rerender } = renderHook(() => useEffectEvent(fn)); + const stableCallbackA = result.current; + rerender(); - const [stableCallbackA, stableCallbackB] = result.all; + const stableCallbackB = result.current; + expect(stableCallbackB).toBe(stableCallbackA); }); diff --git a/packages/fuselage-hooks/src/useIsomorphicLayoutEffect.server.spec.ts b/packages/fuselage-hooks/src/useIsomorphicLayoutEffect.server.spec.ts index cc3b4809d8..2103109989 100644 --- a/packages/fuselage-hooks/src/useIsomorphicLayoutEffect.server.spec.ts +++ b/packages/fuselage-hooks/src/useIsomorphicLayoutEffect.server.spec.ts @@ -1,9 +1,4 @@ -/** - * @jest-environment node - */ - -import { renderHook } from '@testing-library/react-hooks/server'; - +import { renderHook } from './testing'; import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'; it('performs a useEffect', () => { @@ -15,5 +10,5 @@ it('performs a useEffect', () => { }); }); - expect(watcher).toBeCalledTimes(0); + expect(watcher).toHaveBeenCalledTimes(0); }); diff --git a/packages/fuselage-hooks/src/useIsomorphicLayoutEffect.spec.ts b/packages/fuselage-hooks/src/useIsomorphicLayoutEffect.spec.ts index e0472c9d84..36bb99b175 100644 --- a/packages/fuselage-hooks/src/useIsomorphicLayoutEffect.spec.ts +++ b/packages/fuselage-hooks/src/useIsomorphicLayoutEffect.spec.ts @@ -1,15 +1,17 @@ -import { renderHook } from '@testing-library/react-hooks'; - +import { renderHook } from './testing'; import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'; it('performs a useLayoutEffect', () => { - const watcher = jest.fn(); + const cleanup = jest.fn(); + const effect = jest.fn(() => cleanup); - renderHook(() => { - useIsomorphicLayoutEffect(() => { - watcher(); - }); + const { unmount } = renderHook(() => { + useIsomorphicLayoutEffect(effect); }); - expect(watcher).toBeCalledTimes(1); + expect(effect).toHaveBeenCalled(); + + unmount(); + + expect(cleanup).toHaveBeenCalled(); }); diff --git a/packages/fuselage-hooks/src/useLazyRef.server.spec.ts b/packages/fuselage-hooks/src/useLazyRef.server.spec.ts index bc178227b6..d4b3badddd 100644 --- a/packages/fuselage-hooks/src/useLazyRef.server.spec.ts +++ b/packages/fuselage-hooks/src/useLazyRef.server.spec.ts @@ -1,9 +1,4 @@ -/** - * @jest-environment node - */ - -import { renderHook } from '@testing-library/react-hooks/server'; - +import { renderHook } from './testing'; import { useLazyRef } from './useLazyRef'; it('returns the computed value immediately', () => { diff --git a/packages/fuselage-hooks/src/useLazyRef.spec.ts b/packages/fuselage-hooks/src/useLazyRef.spec.ts index 64e77e9d30..6d394dbab3 100644 --- a/packages/fuselage-hooks/src/useLazyRef.spec.ts +++ b/packages/fuselage-hooks/src/useLazyRef.spec.ts @@ -1,5 +1,4 @@ -import { renderHook } from '@testing-library/react-hooks'; - +import { renderHook } from './testing'; import { useLazyRef } from './useLazyRef'; it('returns the computed value immediately', () => { diff --git a/packages/fuselage-hooks/src/useLocalStorage.server.spec.ts b/packages/fuselage-hooks/src/useLocalStorage.server.spec.ts index 04411b7ef0..2e7cb0159a 100644 --- a/packages/fuselage-hooks/src/useLocalStorage.server.spec.ts +++ b/packages/fuselage-hooks/src/useLocalStorage.server.spec.ts @@ -1,9 +1,4 @@ -/** - * @jest-environment node - */ - -import { renderHook } from '@testing-library/react-hooks/server'; - +import { renderHook } from './testing'; import { useLocalStorage } from './useStorage'; it('returns a default value', () => { diff --git a/packages/fuselage-hooks/src/useLocalStorage.spec.ts b/packages/fuselage-hooks/src/useLocalStorage.spec.ts index 78773b29e9..12b5b6a00e 100644 --- a/packages/fuselage-hooks/src/useLocalStorage.spec.ts +++ b/packages/fuselage-hooks/src/useLocalStorage.spec.ts @@ -1,5 +1,4 @@ -import { renderHook, act } from '@testing-library/react-hooks'; - +import { renderHook, act } from './testing'; import { useLocalStorage } from './useStorage'; it('returns a default value', () => { diff --git a/packages/fuselage-hooks/src/useMediaQueries.server.spec.ts b/packages/fuselage-hooks/src/useMediaQueries.server.spec.ts index 3ef5427f4e..5e68a71918 100644 --- a/packages/fuselage-hooks/src/useMediaQueries.server.spec.ts +++ b/packages/fuselage-hooks/src/useMediaQueries.server.spec.ts @@ -1,9 +1,4 @@ -/** - * @jest-environment node - */ - -import { renderHook } from '@testing-library/react-hooks/server'; - +import { renderHook } from './testing'; import { useMediaQueries } from './useMediaQueries'; it('returns empty array for undefined media query', () => { diff --git a/packages/fuselage-hooks/src/useMediaQueries.spec.ts b/packages/fuselage-hooks/src/useMediaQueries.spec.ts index 9f0d8acc72..ba05c604b2 100644 --- a/packages/fuselage-hooks/src/useMediaQueries.spec.ts +++ b/packages/fuselage-hooks/src/useMediaQueries.spec.ts @@ -1,6 +1,6 @@ -import { renderHook, act } from '@testing-library/react-hooks'; import { withMatchMediaMock } from 'testing-utils/mocks/withMatchMediaMock'; +import { renderHook, act } from './testing'; import { useMediaQueries } from './useMediaQueries'; const setViewport = withMatchMediaMock(); diff --git a/packages/fuselage-hooks/src/useMediaQueries.ts b/packages/fuselage-hooks/src/useMediaQueries.ts index 36c7803fa7..c6c9dd91e8 100644 --- a/packages/fuselage-hooks/src/useMediaQueries.ts +++ b/packages/fuselage-hooks/src/useMediaQueries.ts @@ -1,68 +1,70 @@ -import { useMemo } from 'react'; +import { useCallback, useRef } from 'react'; import { useSyncExternalStore } from 'use-sync-external-store/shim'; import { useStableArray } from './useStableArray'; -const createStore = (queries: string[]) => { - if ( - typeof window === 'undefined' || - typeof window.matchMedia !== 'function' - ) { - const snapshot = Array.from({ length: queries.length }, () => false); - return [() => () => undefined, () => snapshot] as const; - } +/** + * Hook to listen to a set of media queries. + * + * @param queries - the CSS3 expressions of media queries + * @returns a set of booleans expressing if the media queries match or not + * @public + */ +export const useMediaQueries = (...queries: string[]) => { + const stableQueries = useStableArray(queries); - const mediaQueryLists = queries.map((query) => window.matchMedia(query)); - let snapshot = mediaQueryLists.map( - (mediaQueryList) => mediaQueryList.matches, + const snapshotRef = useRef( + stableQueries.map((query) => + typeof window === 'undefined' || typeof window.matchMedia !== 'function' + ? false + : matchMedia(query).matches, + ), ); - return [ + const subscribe = useCallback( (onStoreChange: () => void) => { + if ( + typeof window === 'undefined' || + typeof window.matchMedia !== 'function' + ) { + return () => undefined; + } + + const mediaQueryLists = stableQueries.map((query) => matchMedia(query)); + const callback = () => { - snapshot = mediaQueryLists.map( + snapshotRef.current = mediaQueryLists.map( (mediaQueryList) => mediaQueryList.matches, ); onStoreChange(); }; - mediaQueryLists.forEach((mediaQueryList) => { + for (const mediaQueryList of mediaQueryLists) { if (typeof mediaQueryList.addEventListener === 'function') { mediaQueryList.addEventListener('change', callback); - return; + continue; } mediaQueryList.addListener(callback); - }); + } return () => { - mediaQueryLists.forEach((mediaQueryList) => { + for (const mediaQueryList of mediaQueryLists) { if (typeof mediaQueryList.removeEventListener === 'function') { mediaQueryList.removeEventListener('change', callback); - return; + continue; } mediaQueryList.removeListener(callback); - }); + } }; }, - () => snapshot, - ] as const; -}; - -/** - * Hook to listen to a set of media queries. - * - * @param queries - the CSS3 expressions of media queries - * @returns a set of booleans expressing if the media queries match or not - * @public - */ -export const useMediaQueries = (...queries: string[]): boolean[] => { - const stableQueries = useStableArray(queries); - const [subscribe, getSnapshot] = useMemo( - () => createStore(stableQueries), [stableQueries], ); - return useSyncExternalStore(subscribe, getSnapshot); + const getSnapshot = useCallback(() => snapshotRef.current!, []); + + const getServerSnapshot = useCallback(() => snapshotRef.current!, []); + + return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot); }; diff --git a/packages/fuselage-hooks/src/useMediaQuery.server.spec.ts b/packages/fuselage-hooks/src/useMediaQuery.server.spec.ts index 05f917a414..76d5390b43 100644 --- a/packages/fuselage-hooks/src/useMediaQuery.server.spec.ts +++ b/packages/fuselage-hooks/src/useMediaQuery.server.spec.ts @@ -1,9 +1,4 @@ -/** - * @jest-environment node - */ - -import { renderHook } from '@testing-library/react-hooks/server'; - +import { renderHook } from './testing'; import { useMediaQuery } from './useMediaQuery'; it('returns false for undefined media query', () => { diff --git a/packages/fuselage-hooks/src/useMediaQuery.spec.ts b/packages/fuselage-hooks/src/useMediaQuery.spec.ts index 501ae12e9b..016fc0a374 100644 --- a/packages/fuselage-hooks/src/useMediaQuery.spec.ts +++ b/packages/fuselage-hooks/src/useMediaQuery.spec.ts @@ -1,6 +1,6 @@ -import { renderHook, act } from '@testing-library/react-hooks'; import { withMatchMediaMock } from 'testing-utils/mocks/withMatchMediaMock'; +import { renderHook, act } from './testing'; import { useMediaQuery } from './useMediaQuery'; const setViewport = withMatchMediaMock(); diff --git a/packages/fuselage-hooks/src/useMergedRefs.server.spec.ts b/packages/fuselage-hooks/src/useMergedRefs.server.spec.ts index c7bda5e315..8924ca278d 100644 --- a/packages/fuselage-hooks/src/useMergedRefs.server.spec.ts +++ b/packages/fuselage-hooks/src/useMergedRefs.server.spec.ts @@ -1,10 +1,6 @@ -/** - * @jest-environment node - */ - -import { renderHook } from '@testing-library/react-hooks/server'; import { createRef } from 'react'; +import { renderHook } from './testing'; import { useMergedRefs } from './useMergedRefs'; it('returns a callback ref', () => { diff --git a/packages/fuselage-hooks/src/useMergedRefs.spec.ts b/packages/fuselage-hooks/src/useMergedRefs.spec.ts index 8e10ee954b..8924ca278d 100644 --- a/packages/fuselage-hooks/src/useMergedRefs.spec.ts +++ b/packages/fuselage-hooks/src/useMergedRefs.spec.ts @@ -1,6 +1,6 @@ -import { renderHook } from '@testing-library/react-hooks'; import { createRef } from 'react'; +import { renderHook } from './testing'; import { useMergedRefs } from './useMergedRefs'; it('returns a callback ref', () => { diff --git a/packages/fuselage-hooks/src/useOutsideClick.spec.ts b/packages/fuselage-hooks/src/useOutsideClick.spec.ts index d38ead6503..939673bf53 100644 --- a/packages/fuselage-hooks/src/useOutsideClick.spec.ts +++ b/packages/fuselage-hooks/src/useOutsideClick.spec.ts @@ -1,7 +1,7 @@ -import { renderHook } from '@testing-library/react-hooks'; import userEvent from '@testing-library/user-event'; import type { MutableRefObject } from 'react'; +import { renderHook } from './testing'; import { useOutsideClick } from './useOutsideClick'; it('it should call the callback when the user clicked outside the element', async () => { diff --git a/packages/fuselage-hooks/src/usePrefersColorScheme.server.spec.ts b/packages/fuselage-hooks/src/usePrefersColorScheme.server.spec.ts index 74ca2d7647..faa009e6aa 100644 --- a/packages/fuselage-hooks/src/usePrefersColorScheme.server.spec.ts +++ b/packages/fuselage-hooks/src/usePrefersColorScheme.server.spec.ts @@ -1,9 +1,4 @@ -/** - * @jest-environment node - */ - -import { renderHook } from '@testing-library/react-hooks/server'; - +import { renderHook } from './testing'; import { usePrefersColorScheme } from './usePrefersColorScheme'; it('should return false on the initial call', () => { diff --git a/packages/fuselage-hooks/src/usePrefersColorScheme.spec.ts b/packages/fuselage-hooks/src/usePrefersColorScheme.spec.ts index a221ee5a37..e1ab4065f2 100644 --- a/packages/fuselage-hooks/src/usePrefersColorScheme.spec.ts +++ b/packages/fuselage-hooks/src/usePrefersColorScheme.spec.ts @@ -1,6 +1,6 @@ -import { renderHook } from '@testing-library/react-hooks'; import { withMatchMediaMock } from 'testing-utils/mocks/withMatchMediaMock'; +import { renderHook } from './testing'; import { usePrefersColorScheme } from './usePrefersColorScheme'; const setViewport = withMatchMediaMock(); diff --git a/packages/fuselage-hooks/src/usePrefersReducedData.server.spec.ts b/packages/fuselage-hooks/src/usePrefersReducedData.server.spec.ts index a3ba5c45c0..42e8796bf2 100644 --- a/packages/fuselage-hooks/src/usePrefersReducedData.server.spec.ts +++ b/packages/fuselage-hooks/src/usePrefersReducedData.server.spec.ts @@ -1,9 +1,4 @@ -/** - * @jest-environment node - */ - -import { renderHook } from '@testing-library/react-hooks/server'; - +import { renderHook } from './testing'; import { usePrefersReducedData } from './usePrefersReducedData'; it('should return false on the initial call', () => { diff --git a/packages/fuselage-hooks/src/usePrefersReducedData.spec.ts b/packages/fuselage-hooks/src/usePrefersReducedData.spec.ts index 56bdf65c44..6aefc24e43 100644 --- a/packages/fuselage-hooks/src/usePrefersReducedData.spec.ts +++ b/packages/fuselage-hooks/src/usePrefersReducedData.spec.ts @@ -1,6 +1,6 @@ -import { renderHook } from '@testing-library/react-hooks'; import { withMatchMediaMock } from 'testing-utils/mocks/withMatchMediaMock'; +import { renderHook } from './testing'; import { usePrefersReducedData } from './usePrefersReducedData'; const setViewport = withMatchMediaMock(); diff --git a/packages/fuselage-hooks/src/usePrefersReducedMotion.server.spec.ts b/packages/fuselage-hooks/src/usePrefersReducedMotion.server.spec.ts index 9f86c8d074..45fb26724e 100644 --- a/packages/fuselage-hooks/src/usePrefersReducedMotion.server.spec.ts +++ b/packages/fuselage-hooks/src/usePrefersReducedMotion.server.spec.ts @@ -1,9 +1,4 @@ -/** - * @jest-environment node - */ - -import { renderHook } from '@testing-library/react-hooks/server'; - +import { renderHook } from './testing'; import { usePrefersReducedMotion } from './usePrefersReducedMotion'; it('should return false on the initial call', () => { diff --git a/packages/fuselage-hooks/src/usePrefersReducedMotion.spec.ts b/packages/fuselage-hooks/src/usePrefersReducedMotion.spec.ts index e4615e92b0..5dab7da52e 100644 --- a/packages/fuselage-hooks/src/usePrefersReducedMotion.spec.ts +++ b/packages/fuselage-hooks/src/usePrefersReducedMotion.spec.ts @@ -1,6 +1,6 @@ -import { renderHook } from '@testing-library/react-hooks'; import { withMatchMediaMock } from 'testing-utils/mocks/withMatchMediaMock'; +import { renderHook } from './testing'; import { usePrefersReducedMotion } from './usePrefersReducedMotion'; const setViewport = withMatchMediaMock(); diff --git a/packages/fuselage-hooks/src/usePrevious.spec.ts b/packages/fuselage-hooks/src/usePrevious.spec.ts index 7994740c80..64bbad8d54 100644 --- a/packages/fuselage-hooks/src/usePrevious.spec.ts +++ b/packages/fuselage-hooks/src/usePrevious.spec.ts @@ -1,6 +1,6 @@ -import { renderHook, act } from '@testing-library/react-hooks'; import { useReducer } from 'react'; +import { renderHook, act } from './testing'; import { usePrevious } from './usePrevious'; it('returns previous values', () => { diff --git a/packages/fuselage-hooks/src/useResizeObserver.server.spec.ts b/packages/fuselage-hooks/src/useResizeObserver.server.spec.ts index 11c6ea727c..22d34d79ff 100644 --- a/packages/fuselage-hooks/src/useResizeObserver.server.spec.ts +++ b/packages/fuselage-hooks/src/useResizeObserver.server.spec.ts @@ -1,9 +1,4 @@ -/** - * @jest-environment node - */ - -import { renderHook } from '@testing-library/react-hooks/server'; - +import { renderHook } from './testing'; import { useResizeObserver } from './useResizeObserver'; it('immediately returns undefined sizes', () => { diff --git a/packages/fuselage-hooks/src/useResizeObserver.spec.ts b/packages/fuselage-hooks/src/useResizeObserver.spec.ts index cca0c35353..f21ce51d1f 100644 --- a/packages/fuselage-hooks/src/useResizeObserver.spec.ts +++ b/packages/fuselage-hooks/src/useResizeObserver.spec.ts @@ -1,6 +1,6 @@ -import { renderHook, act } from '@testing-library/react-hooks'; import { withResizeObserverMock } from 'testing-utils/mocks/withResizeObserverMock'; +import { renderHook, act } from './testing'; import { useResizeObserver } from './useResizeObserver'; withResizeObserverMock(); diff --git a/packages/fuselage-hooks/src/useSafely.server.spec.ts b/packages/fuselage-hooks/src/useSafely.server.spec.ts index 1d25f3fa8a..967c876af0 100644 --- a/packages/fuselage-hooks/src/useSafely.server.spec.ts +++ b/packages/fuselage-hooks/src/useSafely.server.spec.ts @@ -1,9 +1,4 @@ -/** - * @jest-environment node - */ - -import { renderHook } from '@testing-library/react-hooks/server'; - +import { renderHook } from './testing'; import { useSafely } from './useSafely'; it('returns the initial state', () => { diff --git a/packages/fuselage-hooks/src/useSafely.spec.ts b/packages/fuselage-hooks/src/useSafely.spec.ts index cee7ebdd03..e21acd9cb1 100644 --- a/packages/fuselage-hooks/src/useSafely.spec.ts +++ b/packages/fuselage-hooks/src/useSafely.spec.ts @@ -1,7 +1,6 @@ -import { renderHook, act } from '@testing-library/react-hooks'; -import type { Dispatch } from 'react'; import { useState } from 'react'; +import { renderHook, act } from './testing'; import { useSafely } from './useSafely'; it('returns a new dispatcher that invokes the previous one', () => { @@ -38,13 +37,14 @@ it('returns a new dispatcher that mutates the state', () => { const { result } = renderHook(() => useSafely(useState(initialState)), ); - const [, newDispatcher] = result.current; + const [valueA, newDispatcher] = result.current; act(() => { newDispatcher(newState); }); - const [[valueA], [valueB]] = result.all as [symbol, Dispatch][]; + const [valueB] = result.current; + expect(valueA).toBe(initialState); expect(valueB).toBe(newState); }); diff --git a/packages/fuselage-hooks/src/useSafely.ts b/packages/fuselage-hooks/src/useSafely.ts index 5a4340cafc..315615e9e9 100644 --- a/packages/fuselage-hooks/src/useSafely.ts +++ b/packages/fuselage-hooks/src/useSafely.ts @@ -22,14 +22,14 @@ export function useSafely([state, dispatcher]: [ dispatcher, ); - useEffect( - () => () => { + useEffect(() => { + dispatcherRef.current = dispatcher; + return () => { dispatcherRef.current = undefined; - }, - [], - ); + }; + }, [dispatcher]); - const safeDispatcher = useCallback((action) => { + const safeDispatcher = useCallback((action?: unknown) => { const dispatcher = dispatcherRef.current; dispatcher?.(action); }, []); diff --git a/packages/fuselage-hooks/src/useSessionStorage.server.spec.ts b/packages/fuselage-hooks/src/useSessionStorage.server.spec.ts index 4c0b0296f7..d6d0e32fee 100644 --- a/packages/fuselage-hooks/src/useSessionStorage.server.spec.ts +++ b/packages/fuselage-hooks/src/useSessionStorage.server.spec.ts @@ -1,9 +1,4 @@ -/** - * @jest-environment node - */ - -import { renderHook } from '@testing-library/react-hooks/server'; - +import { renderHook } from './testing'; import { useSessionStorage } from './useStorage'; it('returns a default value', () => { diff --git a/packages/fuselage-hooks/src/useSessionStorage.spec.ts b/packages/fuselage-hooks/src/useSessionStorage.spec.ts index 3b54067b06..6c59f6535b 100644 --- a/packages/fuselage-hooks/src/useSessionStorage.spec.ts +++ b/packages/fuselage-hooks/src/useSessionStorage.spec.ts @@ -1,5 +1,4 @@ -import { renderHook, act } from '@testing-library/react-hooks'; - +import { renderHook, act } from './testing'; import { useSessionStorage } from './useStorage'; it('returns a default value', () => { diff --git a/packages/fuselage-hooks/src/useStableArray.spec.ts b/packages/fuselage-hooks/src/useStableArray.spec.ts index 025a20c958..e39e876aad 100644 --- a/packages/fuselage-hooks/src/useStableArray.spec.ts +++ b/packages/fuselage-hooks/src/useStableArray.spec.ts @@ -1,6 +1,6 @@ -import { renderHook, act } from '@testing-library/react-hooks'; import { useState } from 'react'; +import { renderHook, act } from './testing'; import { useStableArray } from './useStableArray'; it('uses same-value equality by default', () => { diff --git a/packages/fuselage-hooks/src/useToggle.server.spec.ts b/packages/fuselage-hooks/src/useToggle.server.spec.ts index b8417f285c..e8358afc6f 100644 --- a/packages/fuselage-hooks/src/useToggle.server.spec.ts +++ b/packages/fuselage-hooks/src/useToggle.server.spec.ts @@ -1,9 +1,4 @@ -/** - * @jest-environment node - */ - -import { renderHook } from '@testing-library/react-hooks/server'; - +import { renderHook } from './testing'; import { useToggle } from './useToggle'; it('has false value when an initial value is undefined', () => { diff --git a/packages/fuselage-hooks/src/useToggle.spec.ts b/packages/fuselage-hooks/src/useToggle.spec.ts index 515c736b83..5fc74a115d 100644 --- a/packages/fuselage-hooks/src/useToggle.spec.ts +++ b/packages/fuselage-hooks/src/useToggle.spec.ts @@ -1,5 +1,4 @@ -import { renderHook, act } from '@testing-library/react-hooks'; - +import { renderHook, act } from './testing'; import { useToggle } from './useToggle'; it('has false value when an initial value is undefined', () => { diff --git a/packages/fuselage-hooks/src/useUniqueId.server.spec.ts b/packages/fuselage-hooks/src/useUniqueId.server.spec.ts index ec33a83032..e984d31411 100644 --- a/packages/fuselage-hooks/src/useUniqueId.server.spec.ts +++ b/packages/fuselage-hooks/src/useUniqueId.server.spec.ts @@ -1,9 +1,4 @@ -/** - * @jest-environment node - */ - -import { renderHook } from '@testing-library/react-hooks/server'; - +import { renderHook } from './testing'; import { useUniqueId } from './useUniqueId'; it('returns a string', () => { diff --git a/packages/fuselage-hooks/src/useUniqueId.spec.ts b/packages/fuselage-hooks/src/useUniqueId.spec.ts index 2860350928..0609807370 100644 --- a/packages/fuselage-hooks/src/useUniqueId.spec.ts +++ b/packages/fuselage-hooks/src/useUniqueId.spec.ts @@ -1,5 +1,4 @@ -import { renderHook } from '@testing-library/react-hooks'; - +import { renderHook } from './testing'; import { useUniqueId } from './useUniqueId'; it('returns a string', () => { @@ -18,9 +17,12 @@ it('returns a unique ID', () => { it('returns the same ID on each render cycle', () => { const { result, rerender } = renderHook(() => useUniqueId()); + + const uniqueIdA = result.current; + rerender(); - const [uniqueIdA, uniqueIdB] = result.all; + const uniqueIdB = result.current; expect(uniqueIdA).toBe(uniqueIdB); }); diff --git a/packages/fuselage-hooks/tsconfig.build.json b/packages/fuselage-hooks/tsconfig.build.json index d7d529fb9a..6b551b781c 100644 --- a/packages/fuselage-hooks/tsconfig.build.json +++ b/packages/fuselage-hooks/tsconfig.build.json @@ -1,4 +1,7 @@ { "extends": "./tsconfig.json", + "compilerOptions": { + "rootDir": "./src" + }, "exclude": ["./src/**/*.spec.ts"] } diff --git a/packages/fuselage-hooks/tsconfig.json b/packages/fuselage-hooks/tsconfig.json index aadf6c69c7..5a36cc4aed 100644 --- a/packages/fuselage-hooks/tsconfig.json +++ b/packages/fuselage-hooks/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../../tsconfig.base.json", "compilerOptions": { - "rootDir": "./src", "module": "ESNext", "lib": ["DOM", "ES2015"], "declarationDir": "./dist", @@ -10,6 +9,6 @@ "esModuleInterop": true, "resolveJsonModule": true }, - "include": ["src"], + "include": ["src", "./jest.config.ts"], "exclude": ["dist", "node_modules"] } diff --git a/packages/fuselage/package.json b/packages/fuselage/package.json index c4da3c0d97..75d6e0c253 100644 --- a/packages/fuselage/package.json +++ b/packages/fuselage/package.json @@ -92,6 +92,8 @@ "@types/invariant": "^2.2.37", "@types/jest": "~29.5.12", "@types/jest-axe": "~3.5.9", + "@types/react": "~17.0.80", + "@types/react-dom": "~17.0.25", "autoprefixer": "~10.4.14", "babel-loader": "~9.1.2", "caniuse-lite": "~1.0.30001477", diff --git a/yarn.lock b/yarn.lock index fcdafb9188..7787c721a1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4103,7 +4103,7 @@ __metadata: "@rollup/plugin-json": "npm:~4.1.0" "@rollup/plugin-node-resolve": "npm:~13.1.3" "@rollup/plugin-typescript": "npm:~8.3.4" - "@testing-library/react-hooks": "npm:~8.0.1" + "@testing-library/react": "npm:~16.0.1" "@testing-library/user-event": "npm:~14.5.2" "@types/jest": "npm:~29.5.12" "@types/react": "npm:~17.0.80" @@ -4117,6 +4117,9 @@ __metadata: npm-run-all: "npm:^4.1.5" prettier: "npm:~3.3.3" react: "npm:^17.0.2" + react-dom: "npm:~17.0.2" + react-dom18: "npm:react-dom@18" + react18: "npm:react@18" rimraf: "npm:~5.0.0" rollup: "npm:~2.79.2" rollup-plugin-terser: "npm:~7.0.2" @@ -4273,6 +4276,8 @@ __metadata: "@types/invariant": "npm:^2.2.37" "@types/jest": "npm:~29.5.12" "@types/jest-axe": "npm:~3.5.9" + "@types/react": "npm:~17.0.80" + "@types/react-dom": "npm:~17.0.25" autoprefixer: "npm:~10.4.14" babel-loader: "npm:~9.1.2" caniuse-lite: "npm:~1.0.30001477" @@ -5547,31 +5552,29 @@ __metadata: languageName: node linkType: hard -"@testing-library/react-hooks@npm:~8.0.1": - version: 8.0.1 - resolution: "@testing-library/react-hooks@npm:8.0.1" +"@testing-library/react@npm:~16.0.0": + version: 16.0.0 + resolution: "@testing-library/react@npm:16.0.0" dependencies: "@babel/runtime": "npm:^7.12.5" - react-error-boundary: "npm:^3.1.0" peerDependencies: - "@types/react": ^16.9.0 || ^17.0.0 - react: ^16.9.0 || ^17.0.0 - react-dom: ^16.9.0 || ^17.0.0 - react-test-renderer: ^16.9.0 || ^17.0.0 + "@testing-library/dom": ^10.0.0 + "@types/react": ^18.0.0 + "@types/react-dom": ^18.0.0 + react: ^18.0.0 + react-dom: ^18.0.0 peerDependenciesMeta: "@types/react": optional: true - react-dom: - optional: true - react-test-renderer: + "@types/react-dom": optional: true - checksum: 10/f7b69373feebe99bc7d60595822cc5c00a1a5a4801bc4f99b597256a5c1d23c45a51f359051dd8a7bdffcc23b26f324c582e9433c25804934fd351a886812790 + checksum: 10/b32894be94e31276138decfa6bcea69dfebc0c37cf91499ff6c878f41eb1154a43a7df6eb1e72e7bede78468af6cb67ca59e4acd3206b41f3ecdae2c6efdf67e languageName: node linkType: hard -"@testing-library/react@npm:~16.0.0": - version: 16.0.0 - resolution: "@testing-library/react@npm:16.0.0" +"@testing-library/react@npm:~16.0.1": + version: 16.0.1 + resolution: "@testing-library/react@npm:16.0.1" dependencies: "@babel/runtime": "npm:^7.12.5" peerDependencies: @@ -5585,7 +5588,7 @@ __metadata: optional: true "@types/react-dom": optional: true - checksum: 10/b32894be94e31276138decfa6bcea69dfebc0c37cf91499ff6c878f41eb1154a43a7df6eb1e72e7bede78468af6cb67ca59e4acd3206b41f3ecdae2c6efdf67e + checksum: 10/904b48881cf5bd208e25899e168f5c99c78ed6d77389544838d9d861a038d2c5c5385863ee9a367436770cbf7d21c5e05a991b9e24a33806e9ac985df2448185 languageName: node linkType: hard @@ -16067,7 +16070,7 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:^16.8.0 || ^17.0.0 || ^18.0.0": +"react-dom18@npm:react-dom@18, react-dom@npm:^16.8.0 || ^17.0.0 || ^18.0.0": version: 18.3.1 resolution: "react-dom@npm:18.3.1" dependencies: @@ -16092,17 +16095,6 @@ __metadata: languageName: node linkType: hard -"react-error-boundary@npm:^3.1.0": - version: 3.1.4 - resolution: "react-error-boundary@npm:3.1.4" - dependencies: - "@babel/runtime": "npm:^7.12.5" - peerDependencies: - react: ">=16.13.1" - checksum: 10/7418637bf352b88f35ff3798e6faa094ee046df9d422fc08f54c017892c3c0738dac661ba3d64d97209464e7a60e7fbbeffdbeaee5edc38f3aaf5f1f4a8bf610 - languageName: node - linkType: hard - "react-hook-form@npm:~7.27.1": version: 7.27.1 resolution: "react-hook-form@npm:7.27.1" @@ -16216,7 +16208,7 @@ __metadata: languageName: node linkType: hard -"react@npm:^16.8.0 || ^17.0.0 || ^18.0.0": +"react18@npm:react@18, react@npm:^16.8.0 || ^17.0.0 || ^18.0.0": version: 18.3.1 resolution: "react@npm:18.3.1" dependencies: