Skip to content

Commit 3d909f7

Browse files
authored
[example-studio] Add an example of a custom object input that renders its child fields (#152)
1 parent dd7edda commit 3d909f7

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import PropTypes from 'prop-types'
2+
import React from 'react'
3+
import FormField from 'part:@sanity/components/formfields/default'
4+
import {setIfMissing} from '@sanity/form-builder/PatchEvent'
5+
import {FormBuilderInput} from 'part:@sanity/form-builder'
6+
7+
export default class CustomObjectInput extends React.PureComponent {
8+
static propTypes = {
9+
type: PropTypes.shape({
10+
title: PropTypes.string,
11+
name: PropTypes.string
12+
}).isRequired,
13+
level: PropTypes.number,
14+
value: PropTypes.shape({
15+
_type: PropTypes.string
16+
}),
17+
onChange: PropTypes.func.isRequired
18+
}
19+
20+
handleFieldChange = (field, fieldPatchEvent) => {
21+
const {onChange, type} = this.props
22+
onChange(fieldPatchEvent
23+
.prefixAll(field.name)
24+
.prepend(
25+
setIfMissing({_type: type.name}),
26+
)
27+
)
28+
}
29+
30+
render() {
31+
const {type, value, level} = this.props
32+
return (
33+
<FormField
34+
label={type.title}
35+
level={level}
36+
description={type.description}
37+
>
38+
This is my custom object input with fields
39+
<fieldset style={{backgroundColor: 'lightblue'}}>
40+
{type.fields.map(field => (
41+
// Delegate to the generic FormBuilderInput. It will resolve and insert the actual input component
42+
// for the given field type
43+
<FormBuilderInput
44+
key={field.name}
45+
type={field.type}
46+
value={value && value[field.name]}
47+
onChange={patchEvent => this.handleFieldChange(field, patchEvent)}
48+
/>
49+
)
50+
)}
51+
</fieldset>
52+
</FormField>
53+
)
54+
}
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import CustomObjectInput from '../components/CustomObjectInput'
2+
3+
export default {
4+
type: 'object',
5+
name: 'customObject',
6+
title: 'Custom object',
7+
fields: [
8+
{
9+
name: 'identifier',
10+
type: 'string',
11+
title: 'Identifier'
12+
},
13+
{
14+
name: 'metadata',
15+
type: 'object',
16+
title: 'Some metadata',
17+
fields: [
18+
{name: 'name', type: 'string'},
19+
{name: 'title', type: 'string'}
20+
]
21+
},
22+
{
23+
name: 'image',
24+
type: 'image',
25+
title: 'Image',
26+
description: 'Some image'
27+
}
28+
],
29+
inputComponent: CustomObjectInput
30+
}

packages/example-studio/schemas/schema.js

+2
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ import videoEmbed from './videoEmbed'
77
import localeString from './localeString'
88
import localeSlug from './localeSlug'
99
import protein from './protein'
10+
import customObject from './customObject'
1011

1112
export default createSchema({
1213
name: 'example-blog',
1314
types: [
1415
blogpost,
1516
author,
1617
code,
18+
customObject,
1719
localeString,
1820
localeSlug,
1921
videoEmbed,

0 commit comments

Comments
 (0)