UI Extensions: Allow React.memo() objects as component extensions (#76098)

fix: support the sandbox with component ui extensions
This commit is contained in:
Levente Balogh 2023-10-06 10:00:09 +02:00 committed by GitHub
parent e2dcd5184a
commit 0081d6baf3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 1 deletions

View File

@ -272,6 +272,18 @@ describe('Plugin Extension Validators', () => {
expect(isReactComponent(() => <div>Some text</div>)).toBe(true);
});
it('should return TRUE if we pass in a component wrapped with React.memo()', () => {
const Component = () => <div>Some text</div>;
const wrapped = React.memo(() => (
<div>
<Component />
</div>
));
wrapped.displayName = 'MyComponent';
expect(isReactComponent(wrapped)).toBe(true);
});
it('should return FALSE if we pass in a valid React component', () => {
expect(isReactComponent('Foo bar')).toBe(false);
expect(isReactComponent(123)).toBe(false);

View File

@ -129,7 +129,14 @@ export function isPromise(value: unknown): value is Promise<unknown> {
}
export function isReactComponent(component: unknown): component is React.ComponentType {
const hasReactTypeProp = (obj: unknown): obj is { $$typeof: Symbol } =>
typeof obj === 'object' && obj !== null && '$$typeof' in obj;
// The sandbox wraps the plugin components with React.memo.
const isReactMemoObject = (obj: unknown): boolean =>
hasReactTypeProp(obj) && obj.$$typeof === Symbol.for('react.memo');
// We currently don't have any strict runtime-checking for this.
// (The main reason is that we don't want to start depending on React implementation details.)
return typeof component === 'function';
return typeof component === 'function' || isReactMemoObject(component);
}