mirror of
https://github.com/mathuo/dockview
synced 2025-03-09 07:22:04 +00:00
feat: accept a wider range of React components
This commit is contained in:
parent
30c7fa2c6a
commit
874da1c7d9
@ -1,4 +1,4 @@
|
||||
import { ReactPart } from '../react';
|
||||
import { ReactPart, isReactComponent } from '../react';
|
||||
import * as React from 'react';
|
||||
import { render, screen, act } from '@testing-library/react';
|
||||
|
||||
@ -40,6 +40,25 @@ describe('react', () => {
|
||||
expect(screen.getByTestId('valueB').textContent).toBe('22');
|
||||
});
|
||||
});
|
||||
|
||||
describe('isReactElement', () => {
|
||||
test('functional component', () => {
|
||||
const FunctionalComponent: React.FC = () => <div />;
|
||||
expect(isReactComponent(FunctionalComponent)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('React.memo component', () => {
|
||||
const memoComponent = React.memo(() => <div />);
|
||||
expect(isReactComponent(memoComponent)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('forward ref component', () => {
|
||||
const ForwardRefComponent = React.forwardRef((props, ref) => (
|
||||
<div />
|
||||
));
|
||||
expect(isReactComponent(ForwardRefComponent)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const Component = (props: TestInterface) => {
|
||||
|
@ -102,14 +102,14 @@ export class ReactPart<P extends object, C extends object = {}>
|
||||
throw new Error('invalid operation: resource is already disposed');
|
||||
}
|
||||
|
||||
if (typeof this.component !== 'function') {
|
||||
if (!isReactComponent(this.component)) {
|
||||
/**
|
||||
* we know this isn't a React.FunctionComponent so throw an error here.
|
||||
* if we do not intercept this the React library will throw a very obsure error
|
||||
* for the same reason, at least at this point we will emit a sensible stacktrace.
|
||||
* if we do not intercept then React library will throw a very obsure error
|
||||
* for the same reason... at least at this point we will emit a sensible stacktrace.
|
||||
*/
|
||||
throw new Error(
|
||||
'Invalid Operation. dockview only supports React Functional Components.'
|
||||
'Dockview: Only React.memo(...), React.ForwardRef(...) and functional components are accepted as components'
|
||||
);
|
||||
}
|
||||
|
||||
@ -192,9 +192,15 @@ export const usePortalsLifecycle: PortalLifecycleHook = () => {
|
||||
return [portals, addPortal];
|
||||
};
|
||||
|
||||
// it does the job...
|
||||
export function isReactElement(
|
||||
element: unknown
|
||||
): element is React.ReactElement {
|
||||
return !!(element as React.ReactElement)?.type;
|
||||
|
||||
export function isReactComponent(component: any): boolean {
|
||||
/**
|
||||
* Yes, we could use "react-is" but that would introduce an unwanted peer dependency
|
||||
* so for now we will check in a rather crude fashion...
|
||||
*/
|
||||
return (
|
||||
typeof component === 'function' /** Functional Componnts */ ||
|
||||
!!(component as React.ExoticComponent)
|
||||
?.$$typeof /** React.memo(...) Components */
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user