Unlock seamless workflows and faster delivery with our latest releases - Join the deep dive

Helper function to add custom components above or below a native one.

Insert related components next to a native one

extendInput.tsx

import { Stack } from "@sanity/ui"
import { InputProps } from "sanity"

type ExtendPosition = "above" | "below"

/**
 * Props for the component that will be inserted above or below the native input.
 */
export type ExtendedInputProps<TInputProps extends InputProps = InputProps> = {
	inputProps: TInputProps
}

/**
 * Provide a component that will be inserted above or below a native input component.
 * The component specified will also receive all props from the native input.
 * @param Component The component to insert above or below the native component. Will receive all props from the native component.
 * @param position Whether to insert the given component above or below the native one (default below).
 * @returns An input component that can be placed directly on `components.input` on a native field.
 *
 * @example
 *
 * components: {
 *   input: extendInput(DecoratorComponent)
 * }
 */
export const extendInput = <TInputProps extends InputProps = InputProps>(
	Component: (props: ExtendedInputProps<TInputProps>) => JSX.Element,
	position: ExtendPosition = "below"
) => {
	const isBelow = position === "below"
	return (props: TInputProps) => {
		return (
			<Stack space={3}>
				{!isBelow && <Component inputProps={props} />}
				{props.renderDefault(props)}
				{isBelow && <Component inputProps={props} />}
			</Stack>
		)
	}
}

I had a need to add additional information around a native component and could not find a helper function that provided this functionality so I made one.

The extendInput function takes a component (and optionally a position) and inserts that component next to the natively rendered input. Your component also receives all props from the native one so that you can act on changes and modify the native field as needed.

Contributor