Source: react/hoc/WithReadOnlyWhenNeeded.js

import hoistNonReactStatic from "hoist-non-react-statics";
import { useFormStateIsLoaded } from "@/shared/helper/store";
import { useIsFormReadOnly } from "@/shared/helper/form/generic";
import { useIsViewer } from "@/shared/helper/user/generic";
import { forwardRef } from "@/import/react";
import { useStoreValues } from "@/shared/context/storeValues";

function getDisplayName(WrappedComponent) {
  return WrappedComponent.displayName || WrappedComponent.name || "Element";
}

/**
 * Enforce machined elements to be read-only if a declaration was submitted, the store was not loaded yet or the viewer has no edit rights
 * @param Component
 * @param {boolean} [enforceReadOnlyTillStoreIsInitialized=true] True: make all items read-only until the store is initialized, ensuring no quick clicks can alter a view that deviates from 'reality'
 * @returns {function({readOnly: *, [p: string]: *}): *}
 */
function withReadOnlyWhenNeeded(Component, { enforceReadOnlyTillStoreIsInitialized = true } = {}) {
  function WithReadOnlyWhenNeeded({ storeType, storeId, readOnly, ...props }, ref) {
    const isFormReadOnly = useIsFormReadOnly(storeType, storeId);
    const isStoreLoaded = useFormStateIsLoaded(storeType, storeId);
    const isUserViewer = useIsViewer();
    let adjustedReadOnly = readOnly;
    if (isFormReadOnly || (enforceReadOnlyTillStoreIsInitialized && !isStoreLoaded) || isUserViewer) {
      adjustedReadOnly = true;
    }

    return <Component {...props} readOnly={adjustedReadOnly} storeType={storeType} storeId={storeId} ref={ref} />;
  }

  if (process.env.NEXT_PUBLIC_ALLOW_EXPERIMENT_STORE_CONTEXT === "true") {
    hoistNonReactStatic(WithReadOnlyWhenNeeded, Component);
    const displayName = `WithReadOnlyWhenNeeded(${getDisplayName(Component)})`;
    WithReadOnlyWhenNeeded.displayName = displayName;
    const ForwardedWith = forwardRef(WithReadOnlyWhenNeeded);
    function CurrentHackyWorkaround(props, ref) {
      const { storeType, storeId } = useStoreValues();
      return <ForwardedWith storeId={storeId} storeType={storeType} {...props} ref={ref} />;
    }

    hoistNonReactStatic(CurrentHackyWorkaround, Component);
    CurrentHackyWorkaround.displayName = displayName;
    return forwardRef(CurrentHackyWorkaround);
  }
  hoistNonReactStatic(WithReadOnlyWhenNeeded, Component);
  WithReadOnlyWhenNeeded.displayName = `WithReadOnlyWhenNeeded(${getDisplayName(Component)})`;
  return forwardRef(WithReadOnlyWhenNeeded);
}

export default withReadOnlyWhenNeeded;