ChemPal Documentation - v1.15.1
    Preparing search index...
    • A full-screen loading overlay component with a stop button, shown while a search runs.

      The panel shows the query at the top, then the graphic with the status line laid over it. The graphic is the molecule being searched for, fetched from PubChem and slowly rotated (see MoleculeSpinner), dimmed so it reads as a backdrop to the text. The three graphic states are mutually exclusive, so one is never swapped for another mid-search: while the structure is still resolving the slot is empty and only the status text shows; once drawn, the molecule holds it; and the generic cubane loader appears only for a query PubChem has no structure for.

      Parameters

      • props: LoadingBackdropProps

        Component properties containing:

        • open: Controls the visibility of the backdrop
        • query: The query being searched for, depicted as a rotating molecule when resolvable
        • onClick: Callback function triggered when the stop button is clicked

      Returns Element

      A loading backdrop component

      <LoadingBackdrop
      open={isLoading}
      onClick={handleStopLoading}
      />

      Future improvements:

      • Implement a Suspense component instead of manual loading state
      • Add a timer to show the Stop Search button after a delay
      export default function LoadingBackdrop(props: LoadingBackdropProps) {
      const [noStructure, setNoStructure] = useState(false);

      // Stable identity: MoleculeSpinner is memoized, and this component re-renders on
      // every result-count tick.
      const handleStatusChange = useCallback((status: MoleculeSpinnerStatus) => {
      setNoStructure(status.state === 'unavailable');
      }, []);

      // Derived from the query itself rather than the callback, so a search that will show a
      // molecule never renders a cube frame first. The cube is only for queries that have
      // settled with nothing to draw.
      //
      // Nothing is rendered in the graphic slot while resolving — no `pending` node — so the
      // panel sits tight around the status line and then grows once the structure arrives.
      const query = (props.query ?? '').trim();
      const showCube = query === '' || noStructure;

      const spinnerBoxClass = showCube
      ? styles['spinner-box']
      : `${styles['spinner-box']} ${styles['as-backdrop']}`;

      return (
      <>
      <Backdrop
      open={props.open}
      id="loading-backdrop"
      role="status"
      aria-label={i18n('loading_aria')}
      >
      <Box className={styles['loading-backdrop-box']} sx={PANEL_SX}>
      {query !== '' && (
      <span className={styles['query-text']} title={query}>
      {query}
      </span>
      )}
      <Box className={spinnerBoxClass}>
      <MoleculeSpinner
      query={query}
      size={MOLECULE_SIZE}
      fallback={CUBE_FALLBACK}
      onStatusChange={handleStatusChange}
      />
      </Box>
      <span className={styles['status-text']}>{formatResultsText(props)}</span>
      <Button
      className={styles['abort-button']}
      onClick={props.onClick}
      disabled={props.isAborting}
      >
      {i18n('loading_cancel')}
      </Button>
      </Box>
      </Backdrop>
      </>
      );
      }