diff --git a/src/Children/toArray.ts b/src/Children/toArray.ts index 37331cd6..ce3c2bd5 100644 --- a/src/Children/toArray.ts +++ b/src/Children/toArray.ts @@ -1,5 +1,5 @@ +import isFragment from '../React/isFragment'; import React from 'react'; -import { isFragment } from 'react-is'; export interface Option { keepEmpty?: boolean; diff --git a/src/React/isFragment.ts b/src/React/isFragment.ts new file mode 100644 index 00000000..514f1c00 --- /dev/null +++ b/src/React/isFragment.ts @@ -0,0 +1,19 @@ +const REACT_ELEMENT_TYPE_18 = Symbol.for('react.element'); +const REACT_ELEMENT_TYPE_19 = Symbol.for('react.transitional.element'); +const REACT_FRAGMENT_TYPE = Symbol.for('react.fragment'); + +/** + * Compatible with React 18 or 19 to check if node is a Fragment. + */ +export default function isFragment(object: any) { + return ( + // Base object type + object && + typeof object === 'object' && + // React Element type + (object.$$typeof === REACT_ELEMENT_TYPE_18 || + object.$$typeof === REACT_ELEMENT_TYPE_19) && + // React Fragment type + object.type === REACT_FRAGMENT_TYPE + ); +} diff --git a/src/ref.ts b/src/ref.ts index 35170714..a972dff3 100644 --- a/src/ref.ts +++ b/src/ref.ts @@ -1,7 +1,8 @@ import type * as React from 'react'; import { isValidElement } from 'react'; -import { ForwardRef, isFragment, isMemo } from 'react-is'; +import { ForwardRef, isMemo } from 'react-is'; import useMemo from './hooks/useMemo'; +import isFragment from './React/isFragment'; export const fillRef = (ref: React.Ref, node: T) => { if (typeof ref === 'function') { diff --git a/tests/toArray-19.test.tsx b/tests/toArray-19.test.tsx new file mode 100644 index 00000000..2d9f7a06 --- /dev/null +++ b/tests/toArray-19.test.tsx @@ -0,0 +1,57 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import toArray from '../src/Children/toArray'; + +jest.mock('react', () => { + const react19 = jest.requireActual('react-19'); + return react19; +}); + +jest.mock('react-dom', () => { + const reactDom19 = jest.requireActual('react-dom-19'); + return reactDom19; +}); + +jest.mock('react-dom/client', () => { + const reactDom19Client = jest.requireActual('react-dom-19/client'); + return reactDom19Client; +}); + +jest.mock('react-dom/test-utils', () => { + const reactDom19Test = jest.requireActual('react-dom-19/test-utils'); + return reactDom19Test; +}); + +class UL extends React.Component<{ + children?: React.ReactNode; +}> { + render() { + return ; + } +} + +describe('toArray', () => { + it('Fragment', () => { + const ulRef = React.createRef