👋 Next.js Conf 2024: Come build, party, run, and connect with us! See all events

How to get a field's parent in a custom input component in Sanity

7 replies
Last updated: Sep 28, 2021
Another one… Getting a field’s
parent
is super helpful on the new conditional hidden fields. I need to do something similar with a custom input component, but it’s not available in the props. Is there something similar to
withDocument
i.e.
withParent
? Or another way to get this prop in? more in thread ->
Sep 28, 2021, 1:19 AM
Looking at the React Components dev tools, here are the props passed into my custom input component:
Sep 28, 2021, 1:19 AM
If I go up a few components to the
ObjectInputField
, I see the
parent
prop that I need:
Sep 28, 2021, 1:20 AM
Found a hacky way to do this by consuming the
ChangeIndicatorContext
:
Sep 28, 2021, 1:38 AM
import { ChangeIndicatorContext } from '@sanity/base/change-indicators';
// other imports

interface ModelHighlightedFieldsInputProps
  extends CustomInputComponentProps<string> {
  document: Sanity.Schema.Article;
}

type FullPath = Array<string | { _key: string }>;

interface ChangeIndicatorContextValue {
  fullPath: FullPath;
}

export const useChangeIndicator = () => {
  const ctx = React.useContext(ChangeIndicatorContext);
  if (!ctx)
    throw new Error('useSearchContext must be used within a ThemeProvider');
  return ctx as ChangeIndicatorContextValue;
};

const getParent = (
  document: Sanity.Schema.Article,
  fullPath: FullPath,
): Sanity.Schema.ModelReference => {
  return fullPath.slice(0, -1).reduce((prevValue, pathNode) => {
    if (typeof pathNode === 'string') return prevValue[pathNode];
    if (Array.isArray(prevValue)) {
      return prevValue.find((item) => item._key === pathNode._key);
    }
    throw new Error('Not sure how we got here');
  }, document);
};

const ModelHighlightedFieldsInputBase: React.FC<ModelHighlightedFieldsInputProps> =
  (props, ref) => {
    const { fullPath } = useChangeIndicator();
    const { document, type } = props;
    const parent = getParent(document, fullPath);
    // the rest of my component
  }
Sep 28, 2021, 1:39 AM
There’s a
withValuePath
you can use in combination with
withDocument
to get the necessary data — checkout the slug input component to see usage example
Sep 28, 2021, 6:19 AM
Thank you!
Sep 28, 2021, 5:00 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?