summaryrefslogtreecommitdiff
path: root/frontend/src/components/WithSuspense.tsx
blob: 912362915a98de72e11f11475c1f4892fd40ce28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import { Focusable, SteamSpinner } from '@decky/ui';
import { FunctionComponent, ReactElement, ReactNode, Suspense } from 'react';

interface WithSuspenseProps {
  children: ReactNode;
  route?: boolean;
}

// Nice little wrapper around Suspense so we don't have to duplicate the styles and code for the loading spinner
const WithSuspense: FunctionComponent<WithSuspenseProps> = (props) => {
  const propsCopy = { ...props };
  delete propsCopy.children;
  (props.children as ReactElement)?.props && Object.assign((props.children as ReactElement).props, propsCopy); // There is probably a better way to do this but valve does it this way so ¯\_(ツ)_/¯
  return (
    <Suspense
      fallback={
        <Focusable
          // needed to enable focus ring so that the focus properly resets on load
          onActivate={() => {}}
          style={{
            overflowY: 'scroll',
            backgroundColor: 'transparent',
            ...(props.route && {
              marginTop: '40px',
              height: 'calc( 100% - 40px )',
            }),
          }}
        >
          <SteamSpinner />
        </Focusable>
      }
    >
      {props.children}
    </Suspense>
  );
};

export default WithSuspense;