DEV Community

Ramu Narasinga
Ramu Narasinga

Posted on • Edited on • Originally published at thinkthroo.com

__useInternal() in Grida codebase.

In this article, we will review the __useInternal() function in Grida codebase.

function __useInternal() {
  const state = useContext(DocumentContext);
  if (!state) {
    throw new Error(
      "useDocument must be used within a StandaloneDocumentEditor"
    );
  }

  const dispatch = __useDispatch();

  return useMemo(() => [state, dispatch] as const, [state, dispatch]);
}
Enter fullscreen mode Exit fullscreen mode

How did I come across this function? In the previous articles, I wrote Toolbar component and a function called setCursorMode.

Image description

In the useEventTarget function, state and dispatch are destructured from this function, __useInternal().

export function useEventTarget() {
  const [state, dispatch] = __useInternal();
Enter fullscreen mode Exit fullscreen mode

DocumentContext

DocumentContext is created at line number 41 in provider.tsx.

const DocumentContext = createContext<IDocumentEditorState | null>(null);
Enter fullscreen mode Exit fullscreen mode

DocumentContext.Provider

You will find DocumentContext.Provider in StandaloneDocumentEditor component at line 102.

return (
    <DocumentContext.Provider value={state}>
      <DocumentDispatcherContext.Provider value={__dispatch}>
        <ProgramDataContextHost>
          <DataProvider data={{ props: shallowRootProps }}>
            <EditorGoogleFontsManager>
              {/*  */}
              {children}
            </EditorGoogleFontsManager>
          </DataProvider>
        </ProgramDataContextHost>
      </DocumentDispatcherContext.Provider>
    </DocumentContext.Provider>
  );
Enter fullscreen mode Exit fullscreen mode

This is where value is initialised to state.

state

The below code is picked from line 71 in provider.tsx

const state = useMemo(
  () => initDocumentEditorState({ ...initial, editable, debug }),
  [initial, editable, debug]
);
Enter fullscreen mode Exit fullscreen mode

Let’s just follow along the code as this is about state that used in the canvas. I would find out how initDocumentEditorState looks like.

initDocumentEditorState

This function is defined in grida-react-canvas/state.ts at line 600

export function initDocumentEditorState({
  debug,
  ...init
}: Omit<IDocumentEditorInit, "debug"> & {
  debug?: boolean;
}): IDocumentEditorState {
  const s = new document.DocumentState(init.document);

  // console.log("i", init["transform"]);

  return {
    transform: cmath.transform.identity,
    debug: debug ?? false,
    selection: [],
    hovered_node_id: null,
    hovered_vertex_idx: null,
    pointer: {
      position: cmath.vector2.zero,
    },
    history: {
      future: [],
      past: [],
    },
    gesture: { type: "idle" },
    gesture_modifiers: {
      translate_with_hierarchy_change: "on",
      translate_with_clone: "off",
      tarnslate_with_axis_lock: "off",
      transform_with_center_origin: "off",
      transform_with_preserve_aspect_ratio: "off",
      rotate_with_quantize: "off",
    },
    document_ctx: document.Context.from(init.document).snapshot(),
    // history: initialHistoryState(init),
    surface_raycast_targeting: DEFAULT_RAY_TARGETING,
    surface_measurement_targeting: "off",
    surface_measurement_targeting_locked: false,
    surface_raycast_detected_node_ids: [],
    googlefonts: s.fonts().map((family) => ({ family })),
    cursor_mode: { type: "cursor" },
    ...init,
  };
}
Enter fullscreen mode Exit fullscreen mode

This function is used in playground.tsx

playground.tsx

const [state, dispatch] = useReducer(
    standaloneDocumentReducer,
    initDocumentEditorState({
      editable: true,
      debug: pref.debug,
      document: {
        nodes: {
          root: {
            id: "root",
            name: "root",
            active: true,
            locked: false,
            type: "container",
            children: [],
            width: 800,
            height: 600,
            position: "relative",
            style: {},
            opacity: 1,
            zIndex: 0,
            rotation: 0,
            expanded: false,
            cornerRadius: 0,
            padding: 0,
            layout: "flow",
            direction: "horizontal",
            mainAxisAlignment: "start",
            crossAxisAlignment: "start",
            mainAxisGap: 0,
            crossAxisGap: 0,
          },
        },
        root_id: "root",
      },
    })
Enter fullscreen mode Exit fullscreen mode

About me:

Hey, my name is Ramu Narasinga. I study large open-source projects and create content about their codebase architecture and best practices, sharing it through articles, videos.

I am open to work on interesting projects. Send me an email at ramu.narasinga@gmail.com

My Github — https://github.com/ramu-narasinga

My website — https://ramunarasinga.com

My Youtube channel — https://www.youtube.com/@thinkthroo

Learning platform — https://thinkthroo.com

Codebase Architecture — https://app.thinkthroo.com/architecture

Best practices — https://app.thinkthroo.com/best-practices

Production-grade projects — https://app.thinkthroo.com/production-grade-projects

References:

  1. https://github.com/gridaco/grida/blob/main/apps/forms/grida-react-canvas/provider.tsx#L2087

  2. https://github.com/gridaco/grida/blob/main/apps/forms/grida-react-canvas/provider.tsx#L133C1-L144C2

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

Top comments (0)