mirror of
				https://github.com/excalidraw/excalidraw.git
				synced 2025-11-04 04:44:31 +01:00 
			
		
		
		
	refactor: Replace the useSubtypes selection hook with a generic useSubtype hook
				
					
				
			This commit is contained in:
		@@ -5,7 +5,7 @@ import { trackEvent } from "../src/analytics";
 | 
			
		||||
import { getDefaultAppState } from "../src/appState";
 | 
			
		||||
import { ErrorDialog } from "../src/components/ErrorDialog";
 | 
			
		||||
import { TopErrorBoundary } from "../src/components/TopErrorBoundary";
 | 
			
		||||
import { useSubtypes } from "../src/element/subtypes/use";
 | 
			
		||||
import { useMathSubtype } from "../src/element/subtypes/mathjax";
 | 
			
		||||
import {
 | 
			
		||||
  APP_NAME,
 | 
			
		||||
  EVENT,
 | 
			
		||||
@@ -304,7 +304,7 @@ const ExcalidrawWrapper = () => {
 | 
			
		||||
  const [excalidrawAPI, excalidrawRefCallback] =
 | 
			
		||||
    useCallbackRefState<ExcalidrawImperativeAPI>();
 | 
			
		||||
 | 
			
		||||
  useSubtypes(excalidrawAPI);
 | 
			
		||||
  useMathSubtype(excalidrawAPI);
 | 
			
		||||
 | 
			
		||||
  const [collabAPI] = useAtom(collabAPIAtom);
 | 
			
		||||
  const [, setCollabDialogShown] = useAtom(collabDialogShownAtom);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,8 @@
 | 
			
		||||
import { useEffect } from "react";
 | 
			
		||||
import { ExcalidrawElement, ExcalidrawTextElement, NonDeleted } from "../types";
 | 
			
		||||
import { getNonDeletedElements } from "../";
 | 
			
		||||
import { getSelectedElements } from "../../scene";
 | 
			
		||||
import { AppState } from "../../types";
 | 
			
		||||
import { AppState, ExcalidrawImperativeAPI } from "../../types";
 | 
			
		||||
import { registerAuxLangData } from "../../i18n";
 | 
			
		||||
 | 
			
		||||
import { Action, ActionName, ActionPredicateFn } from "../../actions/types";
 | 
			
		||||
@@ -472,3 +473,18 @@ export const checkRefreshOnSubtypeLoad = (
 | 
			
		||||
  scenes.forEach((scene) => scene.informMutation());
 | 
			
		||||
  return refreshNeeded;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const useSubtype = (
 | 
			
		||||
  api: ExcalidrawImperativeAPI | null,
 | 
			
		||||
  record: SubtypeRecord,
 | 
			
		||||
  subtypePrepFn: SubtypePrepFn,
 | 
			
		||||
) => {
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (api) {
 | 
			
		||||
      const prep = api.addSubtype(record, subtypePrepFn);
 | 
			
		||||
      if (prep) {
 | 
			
		||||
        addSubtypeMethods(record.subtype, prep.methods);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }, [api, record, subtypePrepFn]);
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
import { useEffect } from "react";
 | 
			
		||||
import { ExcalidrawImperativeAPI } from "../../../types";
 | 
			
		||||
import { addSubtypeMethods } from "../";
 | 
			
		||||
import { useSubtype } from "../";
 | 
			
		||||
import { getMathSubtypeRecord } from "./types";
 | 
			
		||||
import { prepareMathSubtype } from "./implementation";
 | 
			
		||||
 | 
			
		||||
@@ -10,24 +9,7 @@ declare global {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const MathJaxSubtype = "mathjax";
 | 
			
		||||
 | 
			
		||||
// The main hook to use the MathJax subtype
 | 
			
		||||
export const useMathJaxSubtype = (api: ExcalidrawImperativeAPI | null) => {
 | 
			
		||||
  const enabled = mathJaxEnabled;
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (enabled && api) {
 | 
			
		||||
      const prep = api.addSubtype(getMathSubtypeRecord(), prepareMathSubtype);
 | 
			
		||||
      if (prep) {
 | 
			
		||||
        addSubtypeMethods(getMathSubtypeRecord().subtype, prep.methods);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }, [enabled, api]);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Determine whether or not to do anything in `useMathJaxSubtype`
 | 
			
		||||
let mathJaxEnabled = false;
 | 
			
		||||
 | 
			
		||||
export const setMathJaxSubtypeEnabled = (enabled: boolean) => {
 | 
			
		||||
  mathJaxEnabled = enabled;
 | 
			
		||||
export const useMathSubtype = (api: ExcalidrawImperativeAPI | null) => {
 | 
			
		||||
  useSubtype(api, getMathSubtypeRecord(), prepareMathSubtype);
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -1,43 +0,0 @@
 | 
			
		||||
import { Subtype } from ".";
 | 
			
		||||
import { ExcalidrawImperativeAPI } from "../../types";
 | 
			
		||||
import {
 | 
			
		||||
  MathJaxSubtype,
 | 
			
		||||
  setMathJaxSubtypeEnabled,
 | 
			
		||||
  useMathJaxSubtype,
 | 
			
		||||
} from "./mathjax";
 | 
			
		||||
 | 
			
		||||
const validSubtypes: readonly Subtype[] = [MathJaxSubtype];
 | 
			
		||||
const subtypesUsed: Subtype[] = [];
 | 
			
		||||
 | 
			
		||||
// The main invocation hook for use in the UI
 | 
			
		||||
export const useSubtypes = (
 | 
			
		||||
  api: ExcalidrawImperativeAPI | null,
 | 
			
		||||
  subtypes?: Subtype[],
 | 
			
		||||
) => {
 | 
			
		||||
  selectSubtypesToEnable(subtypes);
 | 
			
		||||
  useMathJaxSubtype(api);
 | 
			
		||||
  // Put calls like `useThisSubtype(api);` here
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// This MUST be called before the `useSubtype` calls.
 | 
			
		||||
const selectSubtypesToEnable = (subtypes?: Subtype[]) => {
 | 
			
		||||
  const subtypeList: Subtype[] = [];
 | 
			
		||||
  if (subtypes === undefined) {
 | 
			
		||||
    subtypeList.push(...validSubtypes);
 | 
			
		||||
  } else {
 | 
			
		||||
    subtypes.forEach(
 | 
			
		||||
      (val) => validSubtypes.includes(val) && subtypeList.push(val),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
  while (subtypesUsed.length > 0) {
 | 
			
		||||
    subtypesUsed.pop();
 | 
			
		||||
  }
 | 
			
		||||
  subtypesUsed.push(...subtypeList);
 | 
			
		||||
  enableSelectedSubtypes();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const enableSelectedSubtypes = () => {
 | 
			
		||||
  setMathJaxSubtypeEnabled(subtypesUsed.includes(MathJaxSubtype));
 | 
			
		||||
  // Put lines here like
 | 
			
		||||
  // `setThisSubtypeEnabled(subtypesUsed.includes(ThisSubtype));`
 | 
			
		||||
};
 | 
			
		||||
		Reference in New Issue
	
	Block a user