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

fix: support the sandbox with component ui extensions
pull/75336/head
Levente Balogh 2 years ago committed by GitHub
parent e2dcd5184a
commit 0081d6baf3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      public/app/features/plugins/extensions/validators.test.tsx
  2. 9
      public/app/features/plugins/extensions/validators.ts

@ -272,6 +272,18 @@ describe('Plugin Extension Validators', () => {
expect(isReactComponent(() => <div>Some text</div>)).toBe(true); 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', () => { it('should return FALSE if we pass in a valid React component', () => {
expect(isReactComponent('Foo bar')).toBe(false); expect(isReactComponent('Foo bar')).toBe(false);
expect(isReactComponent(123)).toBe(false); expect(isReactComponent(123)).toBe(false);

@ -129,7 +129,14 @@ export function isPromise(value: unknown): value is Promise<unknown> {
} }
export function isReactComponent(component: unknown): component is React.ComponentType { 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. // 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.) // (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);
} }

Loading…
Cancel
Save