@nrk/sanity-plugin-nrkno-odd-utils
This lib expands on the principles of nrkno-sanity.
nrkno-odd-utils (odd = option driven design) contains a handful of utility functions and classes for working with Sanity custom components.
See docs about option driven design for more.
Installation
Yarn
yarn add @nrk/sanity-plugin-nrkno-odd-utils
npm
npm install --save @nrk/sanity-plugin-nrkno-odd-utils
Usage
Easily decorate and reuse built-in Sanity inputs by delegating to NestedFormBuilder. It is imperative that we unset the inputComponent in the type (or unset the option used by input-resolver.ts).
Functions available as module imports:
import {
unsetOption,
unsetInputComponent,
useUnsetOption,
useUnsetInputComponent,
NestedFormBuilder
} from '@nrk/sanity-plugin-nrkno-odd-utils'
Example - inputComponent
Given a schema with an input component:
const schemaOrField = {
name: 'schemaOrField',
inputComponent: CustomComponent,
}
We can decorate a custom heading over a standard sanity input (regardless of type), like so:
// CustomComponent.tsx
import React, {forwardRef, Ref} from 'react';
import {useUnsetInputComponent, NestedFormBuilder} from '@nrk/sanity-plugin-nrkno-odd-utils';
export const CustomComponent = forwardRef(function CustomComponent(props, ref) {
// IMPORTANT: leaving out will cause the browser to lock up in an infinite loop
const type = useUnsetInputComponent(props.type);
return <div>
<h4>A custom heading</h4>
<NestedFormBuilder {...props} ref={ref} type={type}/>
</div>;
});
Example - option
Given a schema with an option, and an input-resolver.js file defined in sanity.json:
// schema-file.js
const schemaOrField = {
name: 'schemaOrField',
option: {
custom: true
}
}
// input-resolver.js
function resolveInput(schema) {
if(schema.options?.custom) {
return CustomComponent
}
}
We can decorate a custom heading over a standard sanity input (regardless of type), like so:
// CustomComponent.tsx
import React, {forwardRef, Ref} from 'react';
import {useUnsetOption, NestedFormBuilder} from '@nrk/sanity-plugin-nrkno-odd-utils';
export const CustomComponent = forwardRef(function CustomComponent(props, ref) {
// IMPORTANT: leaving out will cause the browser to lock up in an infinite loop
const type = useUnsetOption(props.type, 'custom');
return <div>
<h4>A custom heading</h4>
<NestedFormBuilder {...props} ref={ref} type={type}/>
</div>;
});
Unit testing components using NestedFormBuilder
NestedFormBuilder extends FormBuilderInput. FormBuilderInput is a Sanity component that uses
non-standard import syntax that does not play well with Jest (import x from 'part:xyz'
).
See NestedFormBuilder.test.ts for examples on how to mock FormBuilderInput, and check which props passed to FormBuilderInput during render.
This is useful when unit-testing that props.type was modified correctly for instance.
Develop
This plugin is built with sanipack.
Test the build
Inside this directory run
npm run build
yarn link
Then
cd /path/to/sanity-studio
yarn link @nrk/sanity-plugin-nrkno-odd-utils
The change to yarn is intentional , since that is what Sanity Studio uses.