withGlobalSelection.tsx 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import * as React from 'react';
  2. import GlobalSelectionStore from 'app/stores/globalSelectionStore';
  3. import {GlobalSelection} from 'app/types';
  4. import getDisplayName from 'app/utils/getDisplayName';
  5. type InjectedGlobalSelectionProps = {
  6. selection?: GlobalSelection;
  7. isGlobalSelectionReady?: boolean;
  8. };
  9. type State = {
  10. selection: GlobalSelection;
  11. isReady?: boolean;
  12. };
  13. /**
  14. * Higher order component that uses GlobalSelectionStore and provides the
  15. * active project
  16. */
  17. function withGlobalSelection<P extends InjectedGlobalSelectionProps>(
  18. WrappedComponent: React.ComponentType<P>
  19. ) {
  20. class WithGlobalSelection extends React.Component<
  21. Omit<P, keyof InjectedGlobalSelectionProps> & Partial<InjectedGlobalSelectionProps>,
  22. State
  23. > {
  24. static displayName = `withGlobalSelection(${getDisplayName(WrappedComponent)})`;
  25. state = GlobalSelectionStore.get();
  26. componentWillUnmount() {
  27. this.unsubscribe();
  28. }
  29. unsubscribe = GlobalSelectionStore.listen((selection: State) => {
  30. if (this.state !== selection) {
  31. this.setState(selection);
  32. }
  33. }, undefined);
  34. render() {
  35. const {isReady, selection} = this.state;
  36. return (
  37. <WrappedComponent
  38. selection={selection as GlobalSelection}
  39. isGlobalSelectionReady={isReady}
  40. {...(this.props as P)}
  41. />
  42. );
  43. }
  44. }
  45. return WithGlobalSelection;
  46. }
  47. export default withGlobalSelection;