🔮 Sanity Create is here. Writing is reinvented. Try now, no developer setup

Custom Components - Fixing a Form Builder Input Problem

5 replies
Last updated: Jul 19, 2022
Hi all, I'm having an issue with a very simple custom component. It's actually just a wrapper around a
FormBuilderInput
to work around the fact that the
object
field in Sanity always displays in an indented manner. This component solves this using some custom CSS.
This works, but the issue is that some fields are not working correctly anymore - an Array of Object items is no longer editable (the edit modal doesn't show). If I add the
focusPath
prop back it does work, but then I run into an infinite loop when used within a field group. Here's the code:
import React from "react";
import { FormBuilderInput } from "part:@sanity/form-builder";

const WrappedField = React.forwardRef((props, ref) => {
  const { inputComponent, ...usableType } = props.type;
  const noHeader = usableType.options?.header === false;
  // omit the focusPath to prevent infinite loop
  const { focusPath, ...properties } = props; 

  return (
    <div className={`tm-object tm-${noHeader ? "without" : "with"}-header`}>
      <FormBuilderInput {...properties} ref={ref} type={usableType} />
    </div>
  );
});

export default WrappedField;
Jul 19, 2022, 2:35 PM
Looks like this is a known issue, and Sanity is aware of this. There's a workaround that pops up in several repos on GH, most managed by Sanity staff: https://github.com/nrkno/nrkno-sanity-libs/blob/8723908ddba1628f3aa3954fb264a44dc0[…]ges/sanity-plugin-nrkno-odd-utils/src/lib/NestedFormBuilder.tsx -
user T
I saw you used this elsewhere too.
This solves my issue:


import React from "react";
import { NestedFormBuilder } from "./NestedFormBuilder";

const WrappedField = React.forwardRef((props, ref) => {
  const { inputComponent, ...usableType } = props.type;
  const noHeader = usableType.options?.header === false;

  return (
    <div className={`tm-object tm-${noHeader ? "without" : "with"}-header`}>
      <NestedFormBuilder {...props} ref={ref} type={usableType} />
    </div>
  );
});

export default WrappedField;
Jul 19, 2022, 2:49 PM
Correct. You can get an infinite loading loop when trying to decorate a built-in field. That’s what this hook does .
Jul 19, 2022, 3:32 PM
Thanks for confirming this! However, doesn't
const { inputComponent, ...usableType } = props.type;
take care of this already? I'm omitting
inputComponent
, but perhaps I'm misunderstanding the hook?
Jul 19, 2022, 3:37 PM
(To be clear I didn’t write this hook, another of our developers did, I just know it solved my issue 🙂 )
Jul 19, 2022, 3:39 PM
I see ... the main problems I faced were focus/interaction related, the infinite loop you mentioned did not occur - it was only when I passed on
focusPath
that things were recursing indefinitely.
Jul 19, 2022, 3:40 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?